aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore69
-rw-r--r--INSTALL-WIN32.md78
-rw-r--r--INSTALL.md3
-rw-r--r--Makefile.in5
-rw-r--r--bootstrap/bin/start.bootbin5328 -> 5330 bytes
-rw-r--r--bootstrap/bin/start.script8
-rw-r--r--bootstrap/bin/start_clean.bootbin5328 -> 5330 bytes
-rw-r--r--bootstrap/bin/start_clean.script8
-rw-r--r--bootstrap/lib/compiler/ebin/beam_asm.beambin9028 -> 9028 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_block.beambin12964 -> 13136 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_utils.beambin12776 -> 12848 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.app2
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.appup2
-rw-r--r--bootstrap/lib/compiler/ebin/core_lint.beambin10656 -> 10944 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_parse.beambin34380 -> 35236 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_codegen.beambin47904 -> 47932 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_core.beambin44984 -> 45376 bytes
-rw-r--r--bootstrap/lib/compiler/egen/core_parse.erl438
-rw-r--r--bootstrap/lib/kernel/ebin/code.beambin6292 -> 6352 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/dist_util.beambin9536 -> 9544 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_epmd.beambin7612 -> 6576 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file.beambin11360 -> 11488 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file_io_server.beambin13004 -> 13104 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/hipe_unified_loader.beambin11428 -> 11428 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet.beambin18036 -> 18176 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.app2
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.appup2
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.beambin3556 -> 3596 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/c.beambin12520 -> 12752 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets.beambin48304 -> 48440 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v8.beambin25116 -> 25132 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v9.beambin45764 -> 45776 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph.beambin7712 -> 7728 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/epp.beambin21908 -> 22132 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin76924 -> 77048 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_parse.beambin64988 -> 66176 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ets.beambin18124 -> 18312 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filelib.beambin6388 -> 6728 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filename.beambin8644 -> 11660 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ordsets.beambin1808 -> 1844 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.app2
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.appup2
-rw-r--r--bootstrap/lib/stdlib/ebin/string.beambin4324 -> 4328 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/supervisor.beambin14492 -> 14544 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/timer.beambin4840 -> 4876 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/unicode.beambin10808 -> 10848 bytes
-rw-r--r--bootstrap/lib/stdlib/egen/erl_parse.erl638
-rw-r--r--configure.in83
-rw-r--r--erts/Makefile.in8
-rw-r--r--erts/aclocal.m4218
-rwxr-xr-xerts/autoconf/win32.config.cache.static3
-rw-r--r--erts/configure.in225
-rw-r--r--erts/doc/src/driver.xml7
-rw-r--r--erts/doc/src/driver_entry.xml26
-rw-r--r--erts/doc/src/epmd.xml4
-rw-r--r--erts/doc/src/erl.xml46
-rw-r--r--erts/doc/src/erl_nif.xml23
-rw-r--r--erts/doc/src/erlang.xml57
-rw-r--r--erts/doc/src/erlc.xml46
-rw-r--r--erts/doc/src/escript.xml8
-rw-r--r--erts/doc/src/notes.xml315
-rw-r--r--erts/emulator/Makefile.in16
-rw-r--r--erts/emulator/beam/beam_bp.c4
-rw-r--r--erts/emulator/beam/beam_bp.h2
-rw-r--r--erts/emulator/beam/beam_debug.c119
-rw-r--r--erts/emulator/beam/beam_emu.c1280
-rw-r--r--erts/emulator/beam/beam_load.c554
-rw-r--r--erts/emulator/beam/bif.c21
-rw-r--r--erts/emulator/beam/bif.h3
-rw-r--r--erts/emulator/beam/bif.tab8
-rw-r--r--erts/emulator/beam/big.c8
-rw-r--r--erts/emulator/beam/big.h8
-rw-r--r--erts/emulator/beam/binary.c10
-rw-r--r--erts/emulator/beam/break.c10
-rw-r--r--erts/emulator/beam/copy.c113
-rw-r--r--erts/emulator/beam/dist.c254
-rw-r--r--erts/emulator/beam/dist.h11
-rw-r--r--erts/emulator/beam/erl_alloc.c38
-rw-r--r--erts/emulator/beam/erl_alloc.h7
-rw-r--r--erts/emulator/beam/erl_alloc.types7
-rw-r--r--erts/emulator/beam/erl_alloc_util.c34
-rw-r--r--erts/emulator/beam/erl_alloc_util.h5
-rw-r--r--erts/emulator/beam/erl_bif_binary.c2
-rw-r--r--erts/emulator/beam/erl_bif_ddll.c6
-rw-r--r--erts/emulator/beam/erl_bif_info.c40
-rw-r--r--erts/emulator/beam/erl_bif_lists.c4
-rw-r--r--erts/emulator/beam/erl_bif_port.c91
-rw-r--r--erts/emulator/beam/erl_bif_timer.c15
-rw-r--r--erts/emulator/beam/erl_binary.h21
-rw-r--r--erts/emulator/beam/erl_bits.c14
-rw-r--r--erts/emulator/beam/erl_cpu_topology.c2361
-rw-r--r--erts/emulator/beam/erl_cpu_topology.h105
-rw-r--r--erts/emulator/beam/erl_db.c221
-rw-r--r--erts/emulator/beam/erl_db.h6
-rw-r--r--erts/emulator/beam/erl_db_hash.c270
-rw-r--r--erts/emulator/beam/erl_db_tree.c509
-rw-r--r--erts/emulator/beam/erl_db_util.c1154
-rw-r--r--erts/emulator/beam/erl_db_util.h130
-rw-r--r--erts/emulator/beam/erl_driver.h53
-rw-r--r--erts/emulator/beam/erl_drv_thread.c62
-rw-r--r--erts/emulator/beam/erl_fun.c8
-rw-r--r--erts/emulator/beam/erl_gc.c2
-rw-r--r--erts/emulator/beam/erl_init.c163
-rw-r--r--erts/emulator/beam/erl_lock_check.c14
-rw-r--r--erts/emulator/beam/erl_lock_count.c14
-rw-r--r--erts/emulator/beam/erl_monitors.c18
-rw-r--r--erts/emulator/beam/erl_nif.c84
-rw-r--r--erts/emulator/beam/erl_nif.h14
-rw-r--r--erts/emulator/beam/erl_node_container_utils.h17
-rw-r--r--erts/emulator/beam/erl_node_tables.c20
-rw-r--r--erts/emulator/beam/erl_node_tables.h2
-rw-r--r--erts/emulator/beam/erl_port_task.c25
-rw-r--r--erts/emulator/beam/erl_port_task.h4
-rw-r--r--erts/emulator/beam/erl_process.c2719
-rw-r--r--erts/emulator/beam/erl_process.h111
-rw-r--r--erts/emulator/beam/erl_process_dump.c240
-rw-r--r--erts/emulator/beam/erl_process_lock.c16
-rw-r--r--erts/emulator/beam/erl_process_lock.h34
-rw-r--r--erts/emulator/beam/erl_smp.h401
-rw-r--r--erts/emulator/beam/erl_term.c49
-rw-r--r--erts/emulator/beam/erl_term.h174
-rw-r--r--erts/emulator/beam/erl_threads.h456
-rw-r--r--erts/emulator/beam/erl_time.h64
-rw-r--r--erts/emulator/beam/erl_time_sup.c19
-rw-r--r--erts/emulator/beam/erl_trace.c6
-rw-r--r--erts/emulator/beam/erl_unicode.c902
-rw-r--r--erts/emulator/beam/erl_unicode_normalize.h1687
-rw-r--r--erts/emulator/beam/erl_vm.h10
-rw-r--r--erts/emulator/beam/external.c329
-rw-r--r--erts/emulator/beam/external.h8
-rw-r--r--erts/emulator/beam/global.h160
-rw-r--r--erts/emulator/beam/io.c86
-rw-r--r--erts/emulator/beam/ops.tab269
-rw-r--r--erts/emulator/beam/packet_parser.c9
-rw-r--r--erts/emulator/beam/sys.h136
-rw-r--r--erts/emulator/beam/time.c289
-rw-r--r--erts/emulator/beam/utils.c322
-rw-r--r--erts/emulator/drivers/common/efile_drv.c263
-rw-r--r--erts/emulator/drivers/common/erl_efile.h10
-rw-r--r--erts/emulator/drivers/common/gzio.c56
-rw-r--r--erts/emulator/drivers/common/inet_drv.c1131
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c6
-rw-r--r--erts/emulator/drivers/win32/win_con.c12
-rwxr-xr-x[-rw-r--r--]erts/emulator/drivers/win32/win_efile.c551
-rw-r--r--erts/emulator/hipe/hipe_amd64_glue.S2
-rw-r--r--erts/emulator/hipe/hipe_ppc_glue.S2
-rw-r--r--erts/emulator/internal_doc/dec.dat942
-rw-r--r--erts/emulator/internal_doc/dec.erl237
-rw-r--r--erts/emulator/sys/common/erl_mseg.c626
-rw-r--r--erts/emulator/sys/common/erl_poll.c286
-rw-r--r--erts/emulator/sys/common/erl_sys_common_misc.c107
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys.h7
-rw-r--r--erts/emulator/sys/unix/sys.c318
-rw-r--r--erts/emulator/sys/unix/sys_float.c7
-rw-r--r--erts/emulator/sys/vxworks/sys.c2
-rw-r--r--erts/emulator/sys/win32/erl_poll.c382
-rw-r--r--erts/emulator/sys/win32/erl_win_dyn_driver.h12
-rw-r--r--erts/emulator/sys/win32/sys.c505
-rw-r--r--erts/emulator/sys/win32/sys_interrupt.c8
-rw-r--r--erts/emulator/test/Makefile1
-rw-r--r--erts/emulator/test/a_SUITE.erl29
-rw-r--r--erts/emulator/test/after_SUITE.erl37
-rw-r--r--erts/emulator/test/alloc_SUITE.erl41
-rw-r--r--erts/emulator/test/beam_SUITE.erl49
-rw-r--r--erts/emulator/test/beam_literals_SUITE.erl78
-rw-r--r--erts/emulator/test/beam_literals_SUITE_data/literal_case_expression.S80
-rw-r--r--erts/emulator/test/bif_SUITE.erl32
-rw-r--r--erts/emulator/test/big_SUITE.erl42
-rw-r--r--erts/emulator/test/binary_SUITE.erl63
-rw-r--r--erts/emulator/test/bs_bincomp_SUITE.erl31
-rw-r--r--erts/emulator/test/bs_bit_binaries_SUITE.erl34
-rw-r--r--erts/emulator/test/bs_construct_SUITE.erl50
-rw-r--r--erts/emulator/test/bs_match_bin_SUITE.erl30
-rw-r--r--erts/emulator/test/bs_match_int_SUITE.erl32
-rw-r--r--erts/emulator/test/bs_match_misc_SUITE.erl36
-rw-r--r--erts/emulator/test/bs_match_tail_SUITE.erl28
-rw-r--r--erts/emulator/test/bs_utf_SUITE.erl36
-rw-r--r--erts/emulator/test/busy_port_SUITE.erl33
-rw-r--r--erts/emulator/test/call_trace_SUITE.erl39
-rw-r--r--erts/emulator/test/code_SUITE.erl37
-rw-r--r--erts/emulator/test/crypto_SUITE.erl30
-rw-r--r--erts/emulator/test/crypto_reference.erl2
-rw-r--r--erts/emulator/test/ddll_SUITE.erl65
-rw-r--r--erts/emulator/test/decode_packet_SUITE.erl28
-rw-r--r--erts/emulator/test/dgawd_handler.erl2
-rw-r--r--erts/emulator/test/distribution_SUITE.erl466
-rw-r--r--erts/emulator/test/driver_SUITE.erl124
-rw-r--r--erts/emulator/test/driver_SUITE_data/chkio_drv.c15
-rw-r--r--erts/emulator/test/efile_SUITE.erl28
-rw-r--r--erts/emulator/test/emulator.spec2
-rw-r--r--erts/emulator/test/erl_drv_thread_SUITE.erl28
-rw-r--r--erts/emulator/test/erl_link_SUITE.erl43
-rw-r--r--erts/emulator/test/erts_debug_SUITE.erl40
-rw-r--r--erts/emulator/test/estone_SUITE.erl32
-rw-r--r--erts/emulator/test/evil_SUITE.erl47
-rw-r--r--erts/emulator/test/exception_SUITE.erl32
-rw-r--r--erts/emulator/test/float_SUITE.erl39
-rw-r--r--erts/emulator/test/fun_SUITE.erl36
-rw-r--r--erts/emulator/test/fun_r12_SUITE.erl29
-rw-r--r--erts/emulator/test/gc_SUITE.erl29
-rw-r--r--erts/emulator/test/guard_SUITE.erl29
-rw-r--r--erts/emulator/test/hash_SUITE.erl38
-rw-r--r--erts/emulator/test/hibernate_SUITE.erl33
-rw-r--r--[l---------]erts/emulator/test/ignore_cores.erl159
-rw-r--r--erts/emulator/test/list_bif_SUITE.erl33
-rw-r--r--erts/emulator/test/long_timers_test.erl2
-rw-r--r--erts/emulator/test/match_spec_SUITE.erl72
-rw-r--r--erts/emulator/test/module_info_SUITE.erl43
-rw-r--r--erts/emulator/test/monitor_SUITE.erl44
-rw-r--r--erts/emulator/test/mtx_SUITE.erl479
-rw-r--r--erts/emulator/test/mtx_SUITE_data/Makefile.src30
-rw-r--r--erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c692
-rw-r--r--erts/emulator/test/nested_SUITE.erl30
-rw-r--r--erts/emulator/test/nif_SUITE.erl73
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.erl2
-rw-r--r--erts/emulator/test/nif_SUITE_data/tester.erl2
-rw-r--r--erts/emulator/test/node_container_SUITE.erl56
-rw-r--r--erts/emulator/test/nofrag_SUITE.erl33
-rw-r--r--erts/emulator/test/num_bif_SUITE.erl36
-rw-r--r--erts/emulator/test/old_mod.erl2
-rw-r--r--erts/emulator/test/old_scheduler_SUITE.erl40
-rw-r--r--erts/emulator/test/op_SUITE.erl33
-rw-r--r--erts/emulator/test/port_SUITE.erl93
-rw-r--r--erts/emulator/test/port_SUITE_data/dead_port.c6
-rw-r--r--erts/emulator/test/port_bif_SUITE.erl44
-rw-r--r--erts/emulator/test/process_SUITE.erl88
-rw-r--r--erts/emulator/test/pseudoknot_SUITE.erl38
-rw-r--r--erts/emulator/test/random_iolist.erl2
-rw-r--r--erts/emulator/test/receive_SUITE.erl31
-rw-r--r--erts/emulator/test/ref_SUITE.erl31
-rw-r--r--erts/emulator/test/register_SUITE.erl31
-rw-r--r--erts/emulator/test/save_calls_SUITE.erl27
-rw-r--r--erts/emulator/test/scheduler_SUITE.erl125
-rw-r--r--erts/emulator/test/send_term_SUITE.erl33
-rw-r--r--erts/emulator/test/sensitive_SUITE.erl37
-rw-r--r--erts/emulator/test/signal_SUITE.erl45
-rw-r--r--erts/emulator/test/statistics_SUITE.erl46
-rw-r--r--erts/emulator/test/system_info_SUITE.erl32
-rw-r--r--erts/emulator/test/system_profile_SUITE.erl41
-rw-r--r--erts/emulator/test/time_SUITE.erl36
-rw-r--r--erts/emulator/test/timer_bif_SUITE.erl36
-rw-r--r--erts/emulator/test/trace_SUITE.erl42
-rw-r--r--erts/emulator/test/trace_bif_SUITE.erl34
-rw-r--r--erts/emulator/test/trace_call_count_SUITE.erl38
-rw-r--r--erts/emulator/test/trace_call_time_SUITE.erl46
-rw-r--r--erts/emulator/test/trace_local_SUITE.erl61
-rw-r--r--erts/emulator/test/trace_meta_SUITE.erl48
-rw-r--r--erts/emulator/test/trace_nif_SUITE.erl39
-rw-r--r--erts/emulator/test/trace_port_SUITE.erl45
-rw-r--r--erts/emulator/test/tuple_SUITE.erl37
-rw-r--r--erts/emulator/test/z_SUITE.erl38
-rwxr-xr-xerts/emulator/utils/beam_makeops118
-rwxr-xr-xerts/emulator/utils/count127
-rw-r--r--erts/emulator/utils/loaded44
-rw-r--r--erts/emulator/zlib/zutil.h1
-rw-r--r--erts/epmd/src/epmd_srv.c14
-rw-r--r--erts/epmd/test/epmd.spec2
-rw-r--r--erts/epmd/test/epmd_SUITE.erl73
-rw-r--r--erts/etc/common/Makefile.in22
-rw-r--r--erts/etc/common/ct_run.c (renamed from erts/etc/common/run_test.c)47
-rw-r--r--erts/etc/common/dialyzer.c10
-rw-r--r--erts/etc/common/erlc.c118
-rw-r--r--erts/etc/common/erlexec.c64
-rw-r--r--erts/etc/common/escript.c52
-rw-r--r--erts/etc/common/heart.c9
-rw-r--r--erts/etc/common/inet_gethost.c5
-rw-r--r--erts/etc/common/typer.c7
-rw-r--r--erts/etc/unix/Install.src5
-rw-r--r--erts/etc/unix/cerl.src33
-rw-r--r--erts/etc/unix/format_man_pages31
-rw-r--r--erts/etc/unix/run_erl.c33
-rw-r--r--erts/etc/win32/Install.c16
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/ld.sh5
-rw-r--r--erts/etc/win32/nsis/Makefile2
-rwxr-xr-xerts/etc/win32/nsis/dll_version_helper.sh12
-rw-r--r--erts/etc/win32/nsis/erlang20.nsi10
-rwxr-xr-xerts/etc/win32/nsis/find_redist.sh62
-rw-r--r--erts/include/internal/ethr_atomics.h726
-rw-r--r--erts/include/internal/ethr_mutex.h212
-rw-r--r--erts/include/internal/ethr_optimized_fallbacks.h74
-rw-r--r--erts/include/internal/ethread.h378
-rw-r--r--erts/include/internal/ethread_header_config.h.in36
-rw-r--r--erts/include/internal/gcc/ethr_atomic.h222
-rw-r--r--erts/include/internal/gcc/ethread.h10
-rw-r--r--erts/include/internal/i386/atomic.h211
-rw-r--r--erts/include/internal/i386/ethread.h7
-rw-r--r--erts/include/internal/libatomic_ops/ethr_atomic.h200
-rw-r--r--erts/include/internal/ppc32/atomic.h94
-rw-r--r--erts/include/internal/pthread/ethr_event.h54
-rw-r--r--erts/include/internal/sparc32/atomic.h187
-rw-r--r--erts/include/internal/sparc32/ethread.h7
-rw-r--r--erts/include/internal/tile/atomic.h104
-rw-r--r--erts/include/internal/win/ethr_atomic.h415
-rw-r--r--erts/include/internal/win/ethr_event.h16
-rw-r--r--erts/include/internal/win/ethread.h6
-rw-r--r--erts/lib_src/Makefile.in7
-rw-r--r--erts/lib_src/common/erl_misc_utils.c272
-rw-r--r--erts/lib_src/common/ethr_atomics.c402
-rw-r--r--erts/lib_src/common/ethr_aux.c202
-rw-r--r--erts/lib_src/common/ethr_mutex.c936
-rw-r--r--erts/lib_src/pthread/ethr_event.c34
-rw-r--r--erts/lib_src/pthread/ethread.c40
-rw-r--r--erts/lib_src/win/ethr_event.c7
-rw-r--r--erts/lib_src/win/ethread.c55
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin50384 -> 50384 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin24316 -> 24144 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin44348 -> 44876 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1428 -> 1432 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin30536 -> 31548 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin57268 -> 64888 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin22428 -> 22432 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin10612 -> 10616 bytes
-rw-r--r--erts/preloaded/src/erlang.erl16
-rw-r--r--erts/preloaded/src/init.erl71
-rw-r--r--erts/preloaded/src/prim_file.erl109
-rw-r--r--erts/preloaded/src/prim_inet.erl254
-rw-r--r--erts/test/autoimport_SUITE.erl28
-rw-r--r--erts/test/erl_print_SUITE.erl42
-rw-r--r--erts/test/erlc_SUITE.erl39
-rw-r--r--erts/test/erlexec_SUITE.erl49
-rw-r--r--erts/test/ethread_SUITE.erl67
-rw-r--r--erts/test/ethread_SUITE_data/ethread_tests.c65
-rw-r--r--erts/test/install_SUITE.erl42
-rw-r--r--erts/test/nt_SUITE.erl36
-rw-r--r--erts/test/otp_SUITE.erl23
-rw-r--r--erts/test/run_erl_SUITE.erl28
-rw-r--r--erts/test/system.spec2
-rw-r--r--erts/test/z_SUITE.erl31
-rw-r--r--erts/vsn.mk4
-rw-r--r--lib/.gitignore4
-rw-r--r--lib/Makefile2
-rw-r--r--lib/asn1/doc/src/notes.xml25
-rw-r--r--lib/asn1/src/asn1ct.erl118
-rw-r--r--lib/asn1/src/asn1ct_check.erl125
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl83
-rw-r--r--lib/asn1/src/asn1ct_gen.erl8
-rw-r--r--lib/asn1/src/asn1rt_ber_bin.erl7
-rw-r--r--lib/asn1/src/asn1rt_driver_handler.erl5
-rw-r--r--lib/asn1/test/Makefile2
-rw-r--r--lib/asn1/test/asn1.cover2
-rw-r--r--lib/asn1/test/asn1.spec4
-rw-r--r--lib/asn1/test/asn1_SUITE.erl2489
-rw-r--r--lib/asn1/test/asn1_SUITE.erl.src7
-rw-r--r--lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn5795
-rw-r--r--lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl76
-rw-r--r--lib/asn1/test/asn1_app_test.erl33
-rw-r--r--lib/asn1/test/asn1_appup_test.erl30
-rw-r--r--lib/asn1/test/asn1_bin_SUITE.erl2382
-rw-r--r--lib/asn1/test/asn1_bin_v2_SUITE.erl2474
-rw-r--r--lib/asn1/vsn.mk2
-rw-r--r--lib/common_test/doc/src/Makefile5
-rw-r--r--lib/common_test/doc/src/common_test_app.xml10
-rw-r--r--lib/common_test/doc/src/config_file_chapter.xml2
-rw-r--r--lib/common_test/doc/src/cover_chapter.xml4
-rw-r--r--lib/common_test/doc/src/ct_hooks.xml556
-rw-r--r--lib/common_test/doc/src/ct_hooks_chapter.xml401
-rw-r--r--lib/common_test/doc/src/ct_master_chapter.xml2
-rw-r--r--lib/common_test/doc/src/ct_run.xml (renamed from lib/common_test/doc/src/run_test.xml)34
-rw-r--r--lib/common_test/doc/src/ct_slave.xml139
-rw-r--r--lib/common_test/doc/src/event_handler_chapter.xml17
-rw-r--r--lib/common_test/doc/src/install_chapter.xml16
-rw-r--r--lib/common_test/doc/src/notes.xml51
-rw-r--r--lib/common_test/doc/src/part.xml1
-rw-r--r--lib/common_test/doc/src/ref_man.xml3
-rw-r--r--lib/common_test/doc/src/run_test_chapter.xml115
-rw-r--r--lib/common_test/doc/src/test_structure_chapter.xml2
-rw-r--r--lib/common_test/doc/src/write_test_chapter.xml1
-rw-r--r--lib/common_test/priv/Makefile.in4
-rw-r--r--lib/common_test/src/Makefile4
-rw-r--r--lib/common_test/src/ct.erl16
-rw-r--r--lib/common_test/src/ct_framework.erl224
-rw-r--r--lib/common_test/src/ct_hooks.erl305
-rw-r--r--lib/common_test/src/ct_hooks_lock.erl132
-rw-r--r--lib/common_test/src/ct_master.erl25
-rw-r--r--lib/common_test/src/ct_run.erl152
-rw-r--r--lib/common_test/src/ct_testspec.erl151
-rw-r--r--lib/common_test/src/ct_util.erl66
-rw-r--r--lib/common_test/src/ct_util.hrl4
-rw-r--r--lib/common_test/test/Makefile3
-rw-r--r--lib/common_test/test/common_test.spec2
-rw-r--r--lib/common_test/test/ct_config_SUITE.erl167
-rw-r--r--lib/common_test/test/ct_error_SUITE.erl47
-rw-r--r--lib/common_test/test/ct_event_handler_SUITE.erl17
-rw-r--r--lib/common_test/test/ct_groups_test_1_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_groups_test_2_SUITE.erl17
-rw-r--r--lib/common_test/test/ct_hooks_SUITE.erl1021
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_id_cth.erl34
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_init_cth.erl34
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_empty_SUITE.erl47
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl64
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_per_suite_SUITE.erl47
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_exit_in_init_scope_suite_cth_SUITE.erl50
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_cth_SUITE.erl56
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_state_cth_SUITE.erl56
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_cth_SUITE.erl47
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_state_cth_SUITE.erl47
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl110
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_cth_SUITE.erl50
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_state_cth_SUITE.erl50
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_update_config_SUITE.erl56
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl278
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl72
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl72
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/id_no_init_cth.erl32
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_cth.erl33
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl38
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl74
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl75
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl72
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl73
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl83
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl71
-rw-r--r--lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl82
-rw-r--r--lib/common_test/test/ct_master_SUITE.erl127
-rw-r--r--lib/common_test/test/ct_master_SUITE_data/master/include/test.hrl0
-rw-r--r--lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl1
-rw-r--r--lib/common_test/test/ct_misc_1_SUITE.erl77
-rw-r--r--lib/common_test/test/ct_repeat_1_SUITE.erl36
-rw-r--r--lib/common_test/test/ct_sequence_1_SUITE.erl19
-rw-r--r--lib/common_test/test/ct_skip_SUITE.erl22
-rw-r--r--lib/common_test/test/ct_smoke_test_SUITE.erl20
-rw-r--r--lib/common_test/test/ct_test_server_if_1_SUITE.erl21
-rw-r--r--lib/common_test/test/ct_test_support.erl112
-rw-r--r--lib/common_test/test/ct_testspec_1_SUITE.erl981
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/doc/src/compile.xml76
-rw-r--r--lib/compiler/doc/src/notes.xml50
-rw-r--r--lib/compiler/src/Makefile4
-rw-r--r--lib/compiler/src/beam_block.erl35
-rw-r--r--lib/compiler/src/beam_utils.erl36
-rw-r--r--lib/compiler/src/cerl.erl6
-rw-r--r--lib/compiler/src/compile.erl297
-rw-r--r--lib/compiler/src/core_lint.erl25
-rw-r--r--lib/compiler/src/v3_codegen.erl6
-rw-r--r--lib/compiler/src/v3_core.erl78
-rw-r--r--lib/compiler/src/v3_kernel.erl1
-rw-r--r--lib/compiler/src/v3_kernel_pp.erl55
-rw-r--r--lib/compiler/test/Makefile2
-rw-r--r--lib/compiler/test/andor_SUITE.erl31
-rw-r--r--lib/compiler/test/apply_SUITE.erl31
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl53
-rw-r--r--lib/compiler/test/bs_bincomp_SUITE.erl67
-rw-r--r--lib/compiler/test/bs_bit_binaries_SUITE.erl36
-rw-r--r--lib/compiler/test/bs_construct_SUITE.erl41
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl47
-rw-r--r--lib/compiler/test/bs_utf_SUITE.erl33
-rw-r--r--lib/compiler/test/compilation_SUITE.erl113
-rw-r--r--lib/compiler/test/compile_SUITE.erl118
-rw-r--r--lib/compiler/test/compile_SUITE_data/simple-basic1.mk1
-rw-r--r--lib/compiler/test/compile_SUITE_data/simple-basic2.mk1
-rw-r--r--lib/compiler/test/compile_SUITE_data/simple-missing.mk1
-rw-r--r--lib/compiler/test/compile_SUITE_data/simple-target1.mk1
-rw-r--r--lib/compiler/test/compile_SUITE_data/simple-target2.mk1
-rw-r--r--lib/compiler/test/compile_SUITE_data/simple.erl6
-rw-r--r--lib/compiler/test/compiler.cover4
-rw-r--r--lib/compiler/test/compiler.dynspec10
-rw-r--r--lib/compiler/test/compiler.spec2
-rw-r--r--lib/compiler/test/core_SUITE.erl34
-rw-r--r--lib/compiler/test/core_fold_SUITE.erl33
-rw-r--r--lib/compiler/test/error_SUITE.erl28
-rw-r--r--lib/compiler/test/float_SUITE.erl31
-rw-r--r--lib/compiler/test/fun_SUITE.erl31
-rw-r--r--lib/compiler/test/guard_SUITE.erl53
-rw-r--r--lib/compiler/test/inline_SUITE.erl33
-rw-r--r--lib/compiler/test/lc_SUITE.erl36
-rw-r--r--lib/compiler/test/match_SUITE.erl31
-rw-r--r--lib/compiler/test/misc_SUITE.erl35
-rw-r--r--lib/compiler/test/num_bif_SUITE.erl35
-rw-r--r--lib/compiler/test/parteval_SUITE.erl28
-rw-r--r--lib/compiler/test/pmod_SUITE.erl30
-rw-r--r--lib/compiler/test/receive_SUITE.erl54
-rw-r--r--lib/compiler/test/record_SUITE.erl35
-rw-r--r--lib/compiler/test/test_lib.erl18
-rw-r--r--lib/compiler/test/trycatch_SUITE.erl39
-rw-r--r--lib/compiler/test/warnings_SUITE.erl36
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/cosEvent/doc/src/notes.xml26
-rw-r--r--lib/cosEvent/src/cosEventApp.erl44
-rw-r--r--lib/cosEvent/test/Makefile3
-rw-r--r--lib/cosEvent/test/cosEvent.cover2
-rw-r--r--lib/cosEvent/test/cosEvent.spec20
-rw-r--r--lib/cosEvent/test/event_channel_SUITE.erl42
-rw-r--r--lib/cosEvent/test/event_test_PullC_impl.erl2
-rw-r--r--lib/cosEvent/test/event_test_PullS_impl.erl2
-rw-r--r--lib/cosEvent/test/event_test_PushC_impl.erl2
-rw-r--r--lib/cosEvent/test/event_test_PushS_impl.erl2
-rw-r--r--lib/cosEvent/test/generated_SUITE.erl53
-rw-r--r--lib/cosEvent/vsn.mk4
-rw-r--r--lib/cosEventDomain/doc/src/notes.xml20
-rw-r--r--lib/cosEventDomain/src/CosEventDomainAdmin_EventDomain_impl.erl24
-rw-r--r--lib/cosEventDomain/src/cosEventDomainApp.erl13
-rw-r--r--lib/cosEventDomain/test/Makefile3
-rw-r--r--lib/cosEventDomain/test/cosEventDomain.cover2
-rw-r--r--lib/cosEventDomain/test/cosEventDomain.spec20
-rw-r--r--lib/cosEventDomain/test/event_domain_SUITE.erl39
-rw-r--r--lib/cosEventDomain/test/generated_SUITE.erl51
-rw-r--r--lib/cosEventDomain/vsn.mk4
-rw-r--r--lib/cosFileTransfer/test/Makefile133
-rw-r--r--lib/cosFileTransfer/test/cosFileTransfer.cover2
-rw-r--r--lib/cosFileTransfer/test/cosFileTransfer.spec1
-rw-r--r--lib/cosFileTransfer/test/fileTransfer_SUITE.erl972
-rw-r--r--lib/cosNotification/doc/src/notes.xml86
-rw-r--r--lib/cosNotification/src/CosNotification_Common.erl46
-rw-r--r--lib/cosNotification/src/cosNotification_Filter.erl32
-rw-r--r--lib/cosNotification/test/Makefile3
-rw-r--r--lib/cosNotification/test/cosNotification.cover2
-rw-r--r--lib/cosNotification/test/cosNotification.spec20
-rw-r--r--lib/cosNotification/test/eventDB_SUITE.erl44
-rw-r--r--lib/cosNotification/test/generated_SUITE.erl156
-rw-r--r--lib/cosNotification/test/grammar_SUITE.erl43
-rw-r--r--lib/cosNotification/test/notification_SUITE.erl46
-rw-r--r--lib/cosNotification/test/notify_test_impl.erl2
-rw-r--r--lib/cosNotification/vsn.mk3
-rw-r--r--lib/cosProperty/doc/src/notes.xml30
-rw-r--r--lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl14
-rw-r--r--lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl14
-rw-r--r--lib/cosProperty/test/Makefile3
-rw-r--r--lib/cosProperty/test/cosProperty.cover2
-rw-r--r--lib/cosProperty/test/cosProperty.spec21
-rw-r--r--lib/cosProperty/test/generated_SUITE.erl70
-rw-r--r--lib/cosProperty/test/property_SUITE.erl43
-rw-r--r--lib/cosProperty/vsn.mk3
-rw-r--r--lib/cosTime/doc/src/notes.xml18
-rw-r--r--lib/cosTime/src/cosTime.erl60
-rw-r--r--lib/cosTime/test/Makefile3
-rw-r--r--lib/cosTime/test/cosTime.cover2
-rw-r--r--lib/cosTime/test/cosTime.spec20
-rw-r--r--lib/cosTime/test/generated_SUITE.erl38
-rw-r--r--lib/cosTime/test/time_SUITE.erl39
-rw-r--r--lib/cosTime/vsn.mk3
-rw-r--r--lib/cosTransactions/test/Makefile3
-rw-r--r--lib/cosTransactions/test/cosTransactions.cover2
-rw-r--r--lib/cosTransactions/test/cosTransactions.spec20
-rw-r--r--lib/cosTransactions/test/etrap_test_lib.erl2
-rw-r--r--lib/cosTransactions/test/generated_SUITE.erl64
-rw-r--r--lib/cosTransactions/test/transactions_SUITE.erl37
-rw-r--r--lib/crypto/c_src/crypto.c45
-rw-r--r--lib/crypto/doc/src/crypto.xml30
-rw-r--r--lib/crypto/doc/src/notes.xml15
-rw-r--r--lib/crypto/src/crypto.erl12
-rw-r--r--lib/crypto/test/Makefile2
-rw-r--r--lib/crypto/test/blowfish_SUITE.erl33
-rw-r--r--lib/crypto/test/crypto.cover2
-rw-r--r--lib/crypto/test/crypto.spec3
-rw-r--r--lib/crypto/test/crypto_SUITE.erl132
-rw-r--r--lib/crypto/vsn.mk2
-rw-r--r--lib/debugger/doc/src/notes.xml14
-rw-r--r--lib/debugger/test/Makefile2
-rw-r--r--lib/debugger/test/andor_SUITE.erl35
-rw-r--r--lib/debugger/test/bs_bincomp_SUITE.erl32
-rw-r--r--lib/debugger/test/bs_construct_SUITE.erl36
-rw-r--r--lib/debugger/test/bs_match_bin_SUITE.erl34
-rw-r--r--lib/debugger/test/bs_match_int_SUITE.erl34
-rw-r--r--lib/debugger/test/bs_match_misc_SUITE.erl34
-rw-r--r--lib/debugger/test/bs_match_tail_SUITE.erl34
-rw-r--r--lib/debugger/test/bs_utf_SUITE.erl37
-rw-r--r--lib/debugger/test/bug_SUITE.erl30
-rw-r--r--lib/debugger/test/cleanup.erl17
-rw-r--r--lib/debugger/test/dbg_ui_SUITE.erl71
-rw-r--r--lib/debugger/test/debugger.cover2
-rw-r--r--lib/debugger/test/debugger.spec2
-rw-r--r--lib/debugger/test/debugger_SUITE.erl31
-rw-r--r--lib/debugger/test/erl_eval_SUITE.erl40
-rw-r--r--lib/debugger/test/exception_SUITE.erl32
-rw-r--r--lib/debugger/test/fun_SUITE.erl33
-rw-r--r--lib/debugger/test/guard_SUITE.erl49
-rw-r--r--lib/debugger/test/int_SUITE.erl38
-rw-r--r--lib/debugger/test/int_break_SUITE.erl30
-rw-r--r--lib/debugger/test/int_eval_SUITE.erl46
-rw-r--r--lib/debugger/test/lc_SUITE.erl32
-rw-r--r--lib/debugger/test/record_SUITE.erl34
-rw-r--r--lib/debugger/test/trycatch_SUITE.erl38
-rw-r--r--lib/debugger/vsn.mk2
-rw-r--r--lib/dialyzer/RELEASE_NOTES27
-rw-r--r--lib/dialyzer/doc/manual.txt81
-rw-r--r--lib/dialyzer/doc/src/dialyzer.xml215
-rwxr-xr-xlib/dialyzer/doc/src/notes.xml34
-rw-r--r--lib/dialyzer/src/dialyzer.erl30
-rw-r--r--lib/dialyzer/src/dialyzer.hrl2
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl44
-rw-r--r--lib/dialyzer/src/dialyzer_cl.erl122
-rw-r--r--lib/dialyzer/src/dialyzer_cl_parse.erl95
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl29
-rw-r--r--lib/dialyzer/src/dialyzer_gui.erl14
-rw-r--r--lib/dialyzer/src/dialyzer_gui_wx.erl14
-rw-r--r--lib/dialyzer/src/dialyzer_options.erl19
-rw-r--r--lib/dialyzer/src/dialyzer_plt.erl73
-rw-r--r--lib/dialyzer/src/dialyzer_races.erl38
-rw-r--r--lib/dialyzer/src/dialyzer_typesig.erl29
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl12
-rw-r--r--lib/dialyzer/vsn.mk2
-rw-r--r--lib/docbuilder/doc/src/notes.xml15
-rw-r--r--lib/docbuilder/src/docb_main.erl29
-rw-r--r--lib/docbuilder/test/Makefile2
-rw-r--r--lib/docbuilder/test/docb.cover2
-rw-r--r--lib/docbuilder/test/docb_SUITE.erl25
-rw-r--r--lib/docbuilder/vsn.mk2
-rw-r--r--lib/edoc/doc/src/notes.xml15
-rw-r--r--lib/edoc/src/edoc_layout.erl2
-rw-r--r--lib/edoc/src/edoc_lib.erl18
-rw-r--r--lib/edoc/src/edoc_macros.erl10
-rw-r--r--lib/edoc/src/edoc_parser.yrl2
-rw-r--r--lib/edoc/src/edoc_refs.erl2
-rw-r--r--lib/edoc/src/edoc_tags.erl13
-rw-r--r--lib/edoc/src/edoc_types.erl2
-rw-r--r--lib/edoc/test/Makefile2
-rw-r--r--lib/edoc/test/edoc.cover2
-rw-r--r--lib/edoc/test/edoc.spec2
-rw-r--r--lib/edoc/test/edoc_SUITE.erl25
-rw-r--r--lib/edoc/vsn.mk2
-rw-r--r--lib/erl_docgen/Makefile19
-rw-r--r--lib/erl_docgen/doc/src/notes.xml31
-rw-r--r--lib/erl_docgen/ebin/.gitignore0
-rw-r--r--lib/erl_docgen/priv/bin/specs_gen.escript129
-rwxr-xr-xlib/erl_docgen/priv/bin/xref_mod_app.escript107
-rw-r--r--lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd7
-rw-r--r--lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd2
-rw-r--r--lib/erl_docgen/priv/dtd_man_entities/xhtml-lat1.ent128
-rw-r--r--lib/erl_docgen/priv/xsl/db_html.xsl626
-rw-r--r--lib/erl_docgen/priv/xsl/db_man.xsl345
-rw-r--r--lib/erl_docgen/priv/xsl/db_pdf.xsl486
-rw-r--r--lib/erl_docgen/src/Makefile96
-rw-r--r--lib/erl_docgen/src/erl_docgen.app.src12
-rw-r--r--lib/erl_docgen/src/erl_docgen.appup.src1
-rw-r--r--lib/erl_docgen/src/otp_specs.erl701
-rw-r--r--lib/erl_docgen/vsn.mk2
-rw-r--r--lib/erl_interface/doc/src/ei.xml2
-rw-r--r--lib/erl_interface/doc/src/notes.xml64
-rw-r--r--lib/erl_interface/include/ei.h29
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c4
-rw-r--r--lib/erl_interface/src/connect/eirecv.c20
-rw-r--r--lib/erl_interface/src/connect/send.c3
-rw-r--r--lib/erl_interface/src/connect/send_exit.c3
-rw-r--r--lib/erl_interface/src/connect/send_reg.c3
-rw-r--r--lib/erl_interface/src/decode/decode_atom.c2
-rw-r--r--lib/erl_interface/src/decode/decode_big.c2
-rw-r--r--lib/erl_interface/src/decode/decode_pid.c2
-rw-r--r--lib/erl_interface/src/decode/decode_port.c2
-rw-r--r--lib/erl_interface/src/decode/decode_ref.c3
-rw-r--r--lib/erl_interface/src/epmd/epmd_publish.c6
-rw-r--r--lib/erl_interface/src/epmd/epmd_unpublish.c5
-rw-r--r--lib/erl_interface/src/legacy/erl_connect.c7
-rw-r--r--lib/erl_interface/src/legacy/erl_format.c2
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.c42
-rw-r--r--lib/erl_interface/src/legacy/erl_timeout.c2
-rw-r--r--lib/erl_interface/src/legacy/global_register.c12
-rw-r--r--lib/erl_interface/src/legacy/global_unregister.c12
-rw-r--r--lib/erl_interface/src/misc/ei_decode_term.c5
-rw-r--r--lib/erl_interface/src/misc/ei_format.c22
-rw-r--r--lib/erl_interface/src/misc/ei_portio.c3
-rw-r--r--lib/erl_interface/src/misc/ei_printterm.c3
-rw-r--r--lib/erl_interface/src/misc/show_msg.c9
-rw-r--r--lib/erl_interface/src/prog/erl_call.c31
-rw-r--r--lib/erl_interface/src/registry/reg_dump.c4
-rw-r--r--lib/erl_interface/src/registry/reg_restore.c2
-rw-r--r--lib/erl_interface/test/Makefile9
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE.erl29
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE.erl71
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c23
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE.erl40
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE.erl31
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE.erl38
-rw-r--r--lib/erl_interface/test/ei_format_SUITE.erl44
-rw-r--r--lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c2
-rw-r--r--lib/erl_interface/test/ei_print_SUITE.erl29
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE.erl31
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE.erl32
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE.erl72
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c20
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE.erl45
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c12
-rw-r--r--lib/erl_interface/test/erl_format_SUITE.erl28
-rw-r--r--lib/erl_interface/test/erl_global_SUITE.erl142
-rw-r--r--lib/erl_interface/test/erl_global_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_global_SUITE_data/Makefile.src41
-rw-r--r--lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c263
-rw-r--r--lib/erl_interface/test/erl_interface.cover2
-rw-r--r--lib/erl_interface/test/erl_interface.spec3
-rw-r--r--lib/erl_interface/test/erl_match_SUITE.erl31
-rw-r--r--lib/erl_interface/test/port_call_SUITE.erl30
-rw-r--r--lib/erl_interface/test/runner.erl2
-rw-r--r--lib/erl_interface/vsn.mk2
-rw-r--r--lib/et/doc/src/notes.xml15
-rw-r--r--lib/et/src/et_selector.erl4
-rw-r--r--lib/et/test/Makefile2
-rw-r--r--lib/et/test/et.cover2
-rw-r--r--lib/et/test/et.spec3
-rw-r--r--lib/et/test/et_test_lib.erl8
-rw-r--r--lib/et/test/et_wx_SUITE.erl27
-rw-r--r--lib/et/vsn.mk2
-rw-r--r--lib/eunit/doc/src/Makefile2
-rw-r--r--lib/eunit/doc/src/notes.xml15
-rw-r--r--lib/eunit/src/eunit.erl2
-rw-r--r--lib/eunit/src/eunit_surefire.erl2
-rw-r--r--lib/eunit/test/Makefile2
-rw-r--r--lib/eunit/test/eunit.cover4
-rw-r--r--lib/eunit/test/eunit.dynspec6
-rw-r--r--lib/eunit/test/eunit.spec3
-rw-r--r--lib/eunit/test/eunit_SUITE.erl27
-rw-r--r--lib/eunit/vsn.mk2
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl239
-rw-r--r--lib/hipe/cerl/erl_types.erl441
-rw-r--r--lib/hipe/doc/src/notes.xml33
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl10
-rw-r--r--lib/hipe/icode/hipe_icode_callgraph.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_primops.erl13
-rw-r--r--lib/hipe/icode/hipe_icode_range.erl4
-rw-r--r--lib/hipe/icode/hipe_icode_type.erl22
-rw-r--r--lib/hipe/main/hipe.erl27
-rw-r--r--lib/hipe/main/hipe_main.erl12
-rw-r--r--lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl52
-rw-r--r--lib/hipe/rtl/hipe_rtl.erl5
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith.inc7
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl43
-rw-r--r--lib/hipe/tools/hipe_tool.erl40
-rw-r--r--lib/hipe/vsn.mk2
-rw-r--r--lib/hipe/x86/hipe_x86_spill_restore.erl40
-rw-r--r--lib/ic/doc/src/notes.xml20
-rw-r--r--lib/ic/src/ic_forms.erl6
-rw-r--r--lib/ic/src/ic_pragma.erl12
-rw-r--r--lib/ic/src/ic_symtab.erl4
-rw-r--r--lib/ic/src/icforms.hrl3
-rw-r--r--lib/ic/src/icparse.yrl22
-rw-r--r--lib/ic/src/ictype.erl41
-rw-r--r--lib/ic/test/Makefile4
-rw-r--r--lib/ic/test/c_client_erl_server_SUITE.erl51
-rw-r--r--lib/ic/test/c_client_erl_server_proto_SUITE.erl51
-rw-r--r--lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl53
-rw-r--r--lib/ic/test/erl_client_c_server_SUITE.erl48
-rw-r--r--lib/ic/test/erl_client_c_server_proto_SUITE.erl48
-rw-r--r--lib/ic/test/ic.cover2
-rw-r--r--lib/ic/test/ic.spec2
-rw-r--r--lib/ic/test/ic_SUITE.erl99
-rw-r--r--lib/ic/test/ic_be_SUITE.erl28
-rw-r--r--lib/ic/test/ic_pp_SUITE.erl107
-rw-r--r--lib/ic/test/ic_pragma_SUITE.erl33
-rw-r--r--lib/ic/test/ic_register_SUITE.erl36
-rw-r--r--lib/ic/test/java_client_erl_server_SUITE.erl42
-rw-r--r--lib/ic/vsn.mk2
-rw-r--r--lib/inets/doc/src/ftp.xml2
-rw-r--r--lib/inets/doc/src/http_client.xml12
-rw-r--r--lib/inets/doc/src/http_server.xml4
-rw-r--r--lib/inets/doc/src/httpc.xml117
-rw-r--r--lib/inets/doc/src/httpd.xml12
-rw-r--r--lib/inets/doc/src/mod_auth.xml3
-rw-r--r--lib/inets/doc/src/notes.xml45
-rw-r--r--lib/inets/include/httpd.hrl41
-rw-r--r--lib/inets/include/mod_auth.hrl33
-rw-r--r--lib/inets/src/http_client/Makefile1
-rw-r--r--lib/inets/src/http_client/httpc.erl51
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl119
-rw-r--r--lib/inets/src/http_client/httpc_internal.hrl6
-rw-r--r--lib/inets/src/http_client/httpc_manager.erl9
-rw-r--r--lib/inets/src/http_lib/Makefile3
-rw-r--r--lib/inets/src/http_lib/http_transport.erl9
-rw-r--r--lib/inets/src/http_lib/http_uri.erl (renamed from lib/inets/src/http_client/http_uri.erl)50
-rw-r--r--lib/inets/src/http_server/Makefile5
-rw-r--r--lib/inets/src/http_server/httpd.erl5
-rw-r--r--lib/inets/src/http_server/httpd.hrl77
-rw-r--r--lib/inets/src/http_server/httpd_acceptor.erl1
-rw-r--r--lib/inets/src/http_server/httpd_conf.erl2
-rw-r--r--lib/inets/src/http_server/httpd_file.erl12
-rw-r--r--lib/inets/src/http_server/httpd_internal.hrl45
-rw-r--r--lib/inets/src/http_server/httpd_request.erl4
-rw-r--r--lib/inets/src/http_server/httpd_script_env.erl3
-rw-r--r--lib/inets/src/http_server/httpd_sup.erl2
-rw-r--r--lib/inets/src/http_server/httpd_util.erl55
-rw-r--r--lib/inets/src/http_server/mod_actions.erl3
-rw-r--r--lib/inets/src/http_server/mod_alias.erl1
-rw-r--r--lib/inets/src/http_server/mod_auth.erl3
-rw-r--r--lib/inets/src/http_server/mod_auth.hrl26
-rw-r--r--lib/inets/src/http_server/mod_auth_dets.erl3
-rw-r--r--lib/inets/src/http_server/mod_auth_plain.erl4
-rw-r--r--lib/inets/src/http_server/mod_auth_server.erl3
-rw-r--r--lib/inets/src/http_server/mod_cgi.erl1
-rw-r--r--lib/inets/src/http_server/mod_dir.erl8
-rw-r--r--lib/inets/src/http_server/mod_disk_log.erl4
-rw-r--r--lib/inets/src/http_server/mod_esi.erl1
-rw-r--r--lib/inets/src/http_server/mod_get.erl4
-rw-r--r--lib/inets/src/http_server/mod_head.erl2
-rw-r--r--lib/inets/src/http_server/mod_htaccess.erl3
-rw-r--r--lib/inets/src/http_server/mod_include.erl7
-rw-r--r--lib/inets/src/http_server/mod_log.erl3
-rw-r--r--lib/inets/src/http_server/mod_range.erl4
-rw-r--r--lib/inets/src/http_server/mod_responsecontrol.erl3
-rw-r--r--lib/inets/src/http_server/mod_security.erl3
-rw-r--r--lib/inets/src/http_server/mod_security_server.erl3
-rw-r--r--lib/inets/src/http_server/mod_trace.erl2
-rw-r--r--lib/inets/src/inets_app/Makefile11
-rw-r--r--lib/inets/src/inets_app/inets.appup.src10
-rw-r--r--lib/inets/test/Makefile31
-rw-r--r--lib/inets/test/ftp_SUITE.erl105
-rw-r--r--lib/inets/test/ftp_format_SUITE.erl51
-rw-r--r--lib/inets/test/ftp_freebsd_x86_test.erl27
-rw-r--r--lib/inets/test/ftp_linux_ppc_test.erl27
-rw-r--r--lib/inets/test/ftp_linux_x86_test.erl36
-rw-r--r--lib/inets/test/ftp_macosx_ppc_test.erl27
-rw-r--r--lib/inets/test/ftp_macosx_x86_test.erl25
-rw-r--r--lib/inets/test/ftp_netbsd_x86_test.erl27
-rw-r--r--lib/inets/test/ftp_openbsd_x86_test.erl27
-rw-r--r--lib/inets/test/ftp_solaris10_sparc_test.erl27
-rw-r--r--lib/inets/test/ftp_solaris10_x86_test.erl27
-rw-r--r--lib/inets/test/ftp_solaris8_sparc_test.erl27
-rw-r--r--lib/inets/test/ftp_solaris9_sparc_test.erl27
-rw-r--r--lib/inets/test/ftp_suite_lib.erl8
-rw-r--r--lib/inets/test/ftp_ticket_test.erl20
-rw-r--r--lib/inets/test/ftp_windows_2003_server_test.erl27
-rw-r--r--lib/inets/test/ftp_windows_xp_test.erl27
-rw-r--r--lib/inets/test/http_format_SUITE.erl65
-rw-r--r--lib/inets/test/httpc_SUITE.erl185
-rw-r--r--lib/inets/test/httpc_cookie_SUITE.erl43
-rw-r--r--lib/inets/test/httpd_1_1.erl2
-rw-r--r--lib/inets/test/httpd_SUITE.erl327
-rw-r--r--lib/inets/test/httpd_basic_SUITE.erl55
-rw-r--r--lib/inets/test/httpd_load.erl2
-rw-r--r--lib/inets/test/inets.cover2
-rw-r--r--lib/inets/test/inets.spec3
-rw-r--r--lib/inets/test/inets_SUITE.erl41
-rw-r--r--lib/inets/test/inets_app_test.erl39
-rw-r--r--lib/inets/test/inets_appup_test.erl41
-rw-r--r--lib/inets/test/inets_sup_SUITE.erl27
-rw-r--r--lib/inets/test/inets_test_lib.erl3
-rw-r--r--lib/inets/test/tftp_SUITE.erl38
-rw-r--r--lib/inets/test/tftp_test_lib.erl6
-rw-r--r--lib/inets/vsn.mk21
-rw-r--r--lib/inviso/test/Makefile2
-rw-r--r--lib/inviso/test/inviso.cover2
-rw-r--r--lib/inviso/test/inviso.spec2
-rw-r--r--lib/inviso/test/inviso_tool_SUITE.erl61
-rw-r--r--lib/jinterface/doc/src/notes.xml16
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java7
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java3
-rw-r--r--lib/jinterface/test/Makefile5
-rw-r--r--lib/jinterface/test/jinterface.cover2
-rw-r--r--lib/jinterface/test/jinterface.spec (renamed from lib/jinterface/test/jinterface.dynspec)14
-rw-r--r--lib/jinterface/test/jinterface_SUITE.erl46
-rw-r--r--lib/jinterface/test/nc_SUITE.erl46
-rw-r--r--lib/jinterface/vsn.mk2
-rw-r--r--lib/kernel/doc/src/file.xml76
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml1
-rw-r--r--lib/kernel/doc/src/inet.xml63
-rw-r--r--lib/kernel/doc/src/notes.xml62
-rw-r--r--lib/kernel/src/code.erl12
-rw-r--r--lib/kernel/src/error_handler.erl5
-rw-r--r--lib/kernel/src/file.erl72
-rw-r--r--lib/kernel/src/file_io_server.erl4
-rw-r--r--lib/kernel/src/inet.erl12
-rw-r--r--lib/kernel/src/inet6_tcp_dist.erl6
-rw-r--r--lib/kernel/src/inet_int.hrl3
-rw-r--r--lib/kernel/src/kernel.erl9
-rw-r--r--lib/kernel/src/net_kernel.erl31
-rw-r--r--lib/kernel/src/os.erl31
-rw-r--r--lib/kernel/test/Makefile3
-rw-r--r--lib/kernel/test/appinc1.erl2
-rw-r--r--lib/kernel/test/appinc1x.erl2
-rw-r--r--lib/kernel/test/appinc2.erl2
-rw-r--r--lib/kernel/test/appinc2A.erl2
-rw-r--r--lib/kernel/test/appinc2B.erl2
-rw-r--r--lib/kernel/test/appinc2top.erl2
-rw-r--r--lib/kernel/test/application_SUITE.erl53
-rw-r--r--lib/kernel/test/bif_SUITE.erl48
-rw-r--r--lib/kernel/test/ch.erl2
-rw-r--r--lib/kernel/test/ch_sup.erl2
-rw-r--r--lib/kernel/test/cleanup.erl17
-rw-r--r--lib/kernel/test/code_SUITE.erl178
-rw-r--r--lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl9
-rw-r--r--lib/kernel/test/code_a_test.erl2
-rw-r--r--lib/kernel/test/code_b_test.erl2
-rw-r--r--lib/kernel/test/disk_log_SUITE.erl125
-rw-r--r--lib/kernel/test/erl_boot_server_SUITE.erl26
-rw-r--r--lib/kernel/test/erl_distribution_SUITE.erl79
-rw-r--r--lib/kernel/test/erl_distribution_wb_SUITE.erl33
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE.erl48
-rw-r--r--lib/kernel/test/error_logger_SUITE.erl30
-rw-r--r--lib/kernel/test/error_logger_warn_SUITE.erl36
-rw-r--r--lib/kernel/test/file_SUITE.erl125
-rw-r--r--lib/kernel/test/file_name_SUITE.erl1756
-rw-r--r--lib/kernel/test/gen_sctp_SUITE.erl46
-rw-r--r--lib/kernel/test/gen_tcp_api_SUITE.erl44
-rw-r--r--lib/kernel/test/gen_tcp_echo_SUITE.erl36
-rw-r--r--lib/kernel/test/gen_tcp_misc_SUITE.erl65
-rw-r--r--lib/kernel/test/gen_udp_SUITE.erl41
-rw-r--r--lib/kernel/test/global_SUITE.erl96
-rw-r--r--lib/kernel/test/global_group_SUITE.erl64
-rw-r--r--lib/kernel/test/heart_SUITE.erl33
-rw-r--r--lib/kernel/test/inet_SUITE.erl255
-rw-r--r--lib/kernel/test/inet_res_SUITE.erl51
-rw-r--r--lib/kernel/test/inet_sockopt_SUITE.erl35
-rw-r--r--lib/kernel/test/init_SUITE.erl37
-rw-r--r--lib/kernel/test/interactive_shell_SUITE.erl30
-rw-r--r--lib/kernel/test/kernel.cover3
-rw-r--r--lib/kernel/test/kernel.dynspec57
-rw-r--r--lib/kernel/test/kernel.spec4
-rw-r--r--lib/kernel/test/kernel.spec.wxworks63
-rw-r--r--lib/kernel/test/kernel_SUITE.erl31
-rw-r--r--lib/kernel/test/kernel_config_SUITE.erl34
-rw-r--r--lib/kernel/test/myApp.erl2
-rw-r--r--lib/kernel/test/os_SUITE.erl49
-rw-r--r--lib/kernel/test/pdict_SUITE.erl29
-rw-r--r--lib/kernel/test/pg2_SUITE.erl37
-rw-r--r--lib/kernel/test/prim_file_SUITE.erl112
-rw-r--r--lib/kernel/test/ram_file_SUITE.erl31
-rw-r--r--lib/kernel/test/rpc_SUITE.erl33
-rw-r--r--lib/kernel/test/seq_trace_SUITE.erl37
-rw-r--r--lib/kernel/test/topApp.erl2
-rw-r--r--lib/kernel/test/topApp2.erl2
-rw-r--r--lib/kernel/test/topApp3.erl2
-rw-r--r--lib/kernel/test/wrap_log_reader_SUITE.erl50
-rw-r--r--lib/kernel/test/zlib_SUITE.erl81
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/megaco/Makefile34
-rw-r--r--lib/megaco/doc/src/notes.xml86
-rw-r--r--lib/megaco/src/app/megaco.app.src3
-rw-r--r--lib/megaco/src/app/megaco.appup.src50
-rw-r--r--lib/megaco/src/binary/megaco_binary_encoder_lib.erl31
-rw-r--r--lib/megaco/src/engine/depend.mk4
-rw-r--r--lib/megaco/src/engine/megaco_config.erl156
-rw-r--r--lib/megaco/src/engine/megaco_config_misc.erl113
-rw-r--r--lib/megaco/src/engine/megaco_filter.erl33
-rw-r--r--lib/megaco/src/engine/megaco_sdp.erl6
-rw-r--r--lib/megaco/src/engine/megaco_timer.erl14
-rw-r--r--lib/megaco/src/engine/modules.mk3
-rw-r--r--lib/megaco/src/flex/megaco_flex_scanner.erl18
-rw-r--r--lib/megaco/test/megaco.cover4
-rw-r--r--lib/megaco/test/megaco.spec7
-rw-r--r--lib/megaco/test/megaco_SUITE.erl137
-rw-r--r--lib/megaco/test/megaco_actions_test.erl33
-rw-r--r--lib/megaco/test/megaco_app_test.erl48
-rw-r--r--lib/megaco/test/megaco_appup_mg.erl2
-rw-r--r--lib/megaco/test/megaco_appup_mgc.erl2
-rw-r--r--lib/megaco/test/megaco_appup_test.erl37
-rw-r--r--lib/megaco/test/megaco_binary_term_id_test.erl39
-rw-r--r--lib/megaco/test/megaco_call_flow_test.erl38
-rw-r--r--lib/megaco/test/megaco_codec_flex_lib.erl2
-rw-r--r--lib/megaco/test/megaco_codec_mini_test.erl82
-rw-r--r--lib/megaco/test/megaco_codec_prev3a_test.erl469
-rw-r--r--lib/megaco/test/megaco_codec_prev3b_test.erl481
-rw-r--r--lib/megaco/test/megaco_codec_prev3c_test.erl485
-rw-r--r--lib/megaco/test/megaco_codec_test.erl39
-rw-r--r--lib/megaco/test/megaco_codec_test_lib.erl2
-rw-r--r--lib/megaco/test/megaco_codec_v1_test.erl508
-rw-r--r--lib/megaco/test/megaco_codec_v2_test.erl484
-rw-r--r--lib/megaco/test/megaco_codec_v3_test.erl478
-rw-r--r--lib/megaco/test/megaco_config_test.erl38
-rw-r--r--lib/megaco/test/megaco_digit_map_test.erl67
-rw-r--r--lib/megaco/test/megaco_examples_test.erl25
-rw-r--r--lib/megaco/test/megaco_flex_test.erl45
-rw-r--r--lib/megaco/test/megaco_load_test.erl35
-rw-r--r--lib/megaco/test/megaco_mess_otp8212_test.erl2
-rw-r--r--lib/megaco/test/megaco_mess_test.erl129
-rw-r--r--lib/megaco/test/megaco_mess_user_test.erl2
-rw-r--r--lib/megaco/test/megaco_mib_test.erl26
-rw-r--r--lib/megaco/test/megaco_mreq_test.erl26
-rw-r--r--lib/megaco/test/megaco_pending_limit_test.erl60
-rw-r--r--lib/megaco/test/megaco_profile.erl2
-rw-r--r--lib/megaco/test/megaco_sdp_test.erl32
-rw-r--r--lib/megaco/test/megaco_segment_test.erl70
-rw-r--r--lib/megaco/test/megaco_tc_controller.erl2
-rw-r--r--lib/megaco/test/megaco_tcp_test.erl62
-rw-r--r--lib/megaco/test/megaco_test_deliver.erl2
-rw-r--r--lib/megaco/test/megaco_test_generator.erl6
-rw-r--r--lib/megaco/test/megaco_test_generator_lib.erl2
-rw-r--r--lib/megaco/test/megaco_test_generic_transport.erl2
-rw-r--r--lib/megaco/test/megaco_test_lib.erl244
-rw-r--r--lib/megaco/test/megaco_test_megaco_generator.erl4
-rw-r--r--lib/megaco/test/megaco_test_mg.erl2
-rw-r--r--lib/megaco/test/megaco_test_mgc.erl2
-rw-r--r--lib/megaco/test/megaco_test_msg_prev3a_lib.erl6
-rw-r--r--lib/megaco/test/megaco_test_msg_prev3b_lib.erl6
-rw-r--r--lib/megaco/test/megaco_test_msg_prev3c_lib.erl6
-rw-r--r--lib/megaco/test/megaco_test_msg_v1_lib.erl6
-rw-r--r--lib/megaco/test/megaco_test_msg_v2_lib.erl6
-rw-r--r--lib/megaco/test/megaco_test_msg_v3_lib.erl6
-rw-r--r--lib/megaco/test/megaco_test_tcp_generator.erl4
-rw-r--r--lib/megaco/test/megaco_timer_test.erl65
-rw-r--r--lib/megaco/test/megaco_trans_test.erl107
-rw-r--r--lib/megaco/test/megaco_udp_test.erl53
-rw-r--r--lib/megaco/vsn.mk25
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap2.xmlsrc12
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap3.xml6
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap4.xmlsrc4
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap5.xmlsrc18
-rw-r--r--lib/mnesia/doc/src/mnesia.xml28
-rw-r--r--lib/mnesia/doc/src/notes.xml31
-rw-r--r--lib/mnesia/src/mnesia.appup.src6
-rw-r--r--lib/mnesia/src/mnesia_dumper.erl4
-rw-r--r--lib/mnesia/test/Makefile2
-rw-r--r--lib/mnesia/test/mnesia.cover2
-rw-r--r--lib/mnesia/test/mnesia.spec99
-rw-r--r--lib/mnesia/test/mnesia_SUITE.erl259
-rw-r--r--lib/mnesia/test/mnesia_atomicity_test.erl131
-rw-r--r--lib/mnesia/test/mnesia_config_backup.erl2
-rw-r--r--lib/mnesia/test/mnesia_config_event.erl2
-rw-r--r--lib/mnesia/test/mnesia_config_test.erl116
-rw-r--r--lib/mnesia/test/mnesia_consistency_test.erl322
-rw-r--r--lib/mnesia/test/mnesia_cost.erl2
-rw-r--r--lib/mnesia/test/mnesia_dirty_access_test.erl167
-rw-r--r--lib/mnesia/test/mnesia_durability_test.erl103
-rw-r--r--lib/mnesia/test/mnesia_evil_backup.erl52
-rw-r--r--lib/mnesia/test/mnesia_evil_coverage_test.erl144
-rw-r--r--lib/mnesia/test/mnesia_examples_test.erl42
-rw-r--r--lib/mnesia/test/mnesia_frag_test.erl60
-rw-r--r--lib/mnesia/test/mnesia_inconsistent_database_test.erl2
-rw-r--r--lib/mnesia/test/mnesia_install_test.erl49
-rw-r--r--lib/mnesia/test/mnesia_isolation_test.erl152
-rw-r--r--lib/mnesia/test/mnesia_measure_test.erl149
-rw-r--r--lib/mnesia/test/mnesia_nice_coverage_test.erl22
-rw-r--r--lib/mnesia/test/mnesia_qlc_test.erl48
-rw-r--r--lib/mnesia/test/mnesia_recovery_test.erl245
-rw-r--r--lib/mnesia/test/mnesia_registry_test.erl23
-rw-r--r--lib/mnesia/test/mnesia_schema_recovery_test.erl166
-rw-r--r--lib/mnesia/test/mnesia_test_lib.erl10
-rw-r--r--lib/mnesia/test/mnesia_tpcb.erl2
-rw-r--r--lib/mnesia/test/mnesia_trans_access_test.erl97
-rw-r--r--lib/mnesia/vsn.mk2
-rw-r--r--lib/observer/doc/src/notes.xml17
-rw-r--r--lib/observer/test/Makefile2
-rw-r--r--lib/observer/test/crashdump_viewer_SUITE.erl23
-rw-r--r--lib/observer/test/etop_SUITE.erl30
-rw-r--r--lib/observer/test/observer.cover6
-rw-r--r--lib/observer/test/observer.spec3
-rw-r--r--lib/observer/test/observer_SUITE.erl25
-rw-r--r--lib/observer/test/ttb_SUITE.erl37
-rw-r--r--lib/observer/vsn.mk2
-rw-r--r--lib/odbc/c_src/odbcserver.c100
-rw-r--r--lib/odbc/c_src/odbcserver.h1
-rw-r--r--lib/odbc/configure.in9
-rw-r--r--lib/odbc/doc/src/notes.xml26
-rw-r--r--lib/odbc/src/odbc.appup.src9
-rw-r--r--lib/odbc/src/odbc.erl6
-rw-r--r--lib/odbc/test/Makefile6
-rw-r--r--lib/odbc/test/odbc.cover2
-rw-r--r--lib/odbc/test/odbc.spec34
-rw-r--r--lib/odbc/test/odbc_connect_SUITE.erl43
-rw-r--r--lib/odbc/test/odbc_data_type_SUITE.erl81
-rw-r--r--lib/odbc/test/odbc_query_SUITE.erl78
-rw-r--r--lib/odbc/test/odbc_start_SUITE.erl22
-rw-r--r--lib/odbc/test/odbc_test_lib.erl2
-rw-r--r--lib/odbc/vsn.mk2
-rw-r--r--lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl13
-rw-r--r--lib/orber/doc/src/ch_idl_to_erlang_mapping.xml37
-rw-r--r--lib/orber/doc/src/notes.xml101
-rw-r--r--lib/orber/include/ifr_types.hrl6
-rw-r--r--lib/orber/src/cdr_decode.erl78
-rw-r--r--lib/orber/src/cdr_encode.erl30
-rw-r--r--lib/orber/src/corba.erl6
-rw-r--r--lib/orber/src/orber.app.src2
-rw-r--r--lib/orber/src/orber.erl18
-rw-r--r--lib/orber/src/orber_socket.erl28
-rw-r--r--lib/orber/test/Makefile9
-rw-r--r--lib/orber/test/cdrcoding_10_SUITE.erl43
-rw-r--r--lib/orber/test/cdrcoding_11_SUITE.erl43
-rw-r--r--lib/orber/test/cdrcoding_12_SUITE.erl43
-rw-r--r--lib/orber/test/cdrlib_SUITE.erl35
-rw-r--r--lib/orber/test/corba_SUITE.erl45
-rw-r--r--lib/orber/test/csiv2_SUITE.erl85
-rw-r--r--lib/orber/test/data_types_SUITE.erl31
-rw-r--r--lib/orber/test/generated_SUITE.erl50
-rw-r--r--lib/orber/test/iiop_module_do_test_impl.erl2
-rw-r--r--lib/orber/test/iiop_module_test_impl.erl2
-rw-r--r--lib/orber/test/iiop_test_impl.erl2
-rw-r--r--lib/orber/test/interceptors_SUITE.erl30
-rw-r--r--lib/orber/test/iop_ior_10_SUITE.erl28
-rw-r--r--lib/orber/test/iop_ior_11_SUITE.erl28
-rw-r--r--lib/orber/test/iop_ior_12_SUITE.erl28
-rw-r--r--lib/orber/test/lname_SUITE.erl30
-rw-r--r--lib/orber/test/multi_ORB_SUITE.erl324
-rw-r--r--lib/orber/test/naming_context_SUITE.erl35
-rw-r--r--lib/orber/test/orber.cover2
-rw-r--r--lib/orber/test/orber.spec20
-rw-r--r--lib/orber/test/orber_SUITE.erl37
-rw-r--r--lib/orber/test/orber_acl_SUITE.erl25
-rw-r--r--lib/orber/test/orber_firewall_ipv4_in_SUITE.erl40
-rw-r--r--lib/orber/test/orber_firewall_ipv4_out_SUITE.erl35
-rw-r--r--lib/orber/test/orber_firewall_ipv6_in_SUITE.erl39
-rw-r--r--lib/orber/test/orber_firewall_ipv6_out_SUITE.erl35
-rw-r--r--lib/orber/test/orber_nat_SUITE.erl255
-rw-r--r--lib/orber/test/orber_test_lib.erl60
-rw-r--r--lib/orber/test/orber_test_server.idl25
-rw-r--r--lib/orber/test/orber_test_server_impl.erl15
-rw-r--r--lib/orber/test/orber_test_timeout_server_impl.erl2
-rw-r--r--lib/orber/test/orber_web_SUITE.erl36
-rw-r--r--lib/orber/test/tc_SUITE.erl45
-rw-r--r--lib/orber/vsn.mk4
-rw-r--r--lib/os_mon/test/Makefile2
-rw-r--r--lib/os_mon/test/cpu_sup_SUITE.erl38
-rw-r--r--lib/os_mon/test/disksup_SUITE.erl32
-rw-r--r--lib/os_mon/test/memsup_SUITE.erl27
-rw-r--r--lib/os_mon/test/os_mon.cover2
-rw-r--r--lib/os_mon/test/os_mon.spec2
-rw-r--r--lib/os_mon/test/os_mon_SUITE.erl31
-rw-r--r--lib/os_mon/test/os_mon_mib_SUITE.erl62
-rw-r--r--lib/os_mon/test/os_sup_SUITE.erl29
-rw-r--r--lib/parsetools/doc/src/notes.xml15
-rw-r--r--lib/parsetools/include/yeccpre.hrl2
-rw-r--r--lib/parsetools/test/Makefile2
-rw-r--r--lib/parsetools/test/leex_SUITE.erl44
-rw-r--r--lib/parsetools/test/parsetools.cover2
-rw-r--r--lib/parsetools/test/parsetools.spec2
-rw-r--r--lib/parsetools/test/yecc_SUITE.erl73
-rw-r--r--lib/parsetools/vsn.mk2
-rw-r--r--lib/percept/src/egd.erl1
-rw-r--r--lib/percept/src/percept.erl32
-rw-r--r--lib/percept/src/percept_db.erl49
-rw-r--r--lib/percept/test/Makefile2
-rw-r--r--lib/percept/test/egd_SUITE.erl30
-rw-r--r--lib/percept/test/percept.cover2
-rw-r--r--lib/percept/test/percept.spec3
-rw-r--r--lib/percept/test/percept_SUITE.erl30
-rw-r--r--lib/percept/test/percept_db_SUITE.erl76
-rw-r--r--lib/public_key/doc/src/notes.xml68
-rw-r--r--lib/public_key/doc/src/public_key.xml21
-rw-r--r--lib/public_key/include/public_key.hrl7
-rw-r--r--lib/public_key/src/pubkey_cert.erl17
-rw-r--r--lib/public_key/src/pubkey_cert_records.erl16
-rw-r--r--lib/public_key/src/pubkey_pem.erl25
-rw-r--r--lib/public_key/src/public_key.appup.src46
-rw-r--r--lib/public_key/src/public_key.erl68
-rw-r--r--lib/public_key/test/pkits_SUITE.erl52
-rw-r--r--lib/public_key/test/public_key.cover4
-rw-r--r--lib/public_key/test/public_key.spec3
-rw-r--r--lib/public_key/test/public_key_SUITE.erl88
-rw-r--r--lib/public_key/test/public_key_SUITE_data/dsa_pub.pem12
-rw-r--r--lib/public_key/test/public_key_SUITE_data/rsa_pub.pem4
-rw-r--r--lib/public_key/test/public_key_SUITE_data/rsa_pub_key.pem4
-rw-r--r--lib/public_key/vsn.mk2
-rw-r--r--lib/reltool/test/Makefile2
-rw-r--r--lib/reltool/test/reltool.cover2
-rw-r--r--lib/reltool/test/reltool.spec3
-rw-r--r--lib/reltool/test/reltool_app_SUITE.erl28
-rw-r--r--lib/reltool/test/reltool_server_SUITE.erl36
-rw-r--r--lib/reltool/test/reltool_test_lib.erl8
-rw-r--r--lib/reltool/test/reltool_wx_SUITE.erl29
-rw-r--r--lib/reltool/test/rtt.erl2
-rw-r--r--lib/runtime_tools/test/Makefile2
-rw-r--r--lib/runtime_tools/test/dbg_SUITE.erl37
-rw-r--r--lib/runtime_tools/test/erts_alloc_config_SUITE.erl30
-rw-r--r--lib/runtime_tools/test/inviso_SUITE.erl75
-rw-r--r--lib/runtime_tools/test/runtime_tools.cover4
-rw-r--r--lib/runtime_tools/test/runtime_tools.spec2
-rw-r--r--lib/runtime_tools/test/runtime_tools_SUITE.erl25
-rw-r--r--lib/snmp/doc/man1/.gitignore0
-rw-r--r--lib/snmp/doc/src/Makefile32
-rw-r--r--lib/snmp/doc/src/depend.mk1
-rw-r--r--lib/snmp/doc/src/files.mk16
-rw-r--r--lib/snmp/doc/src/make.dep2
-rw-r--r--lib/snmp/doc/src/notes.xml137
-rw-r--r--lib/snmp/doc/src/ref_man.xml3
-rw-r--r--lib/snmp/doc/src/snmp_agent_config_files.xml11
-rw-r--r--lib/snmp/doc/src/snmp_config.xml42
-rw-r--r--lib/snmp/doc/src/snmp_view_based_acm_mib.xml74
-rw-r--r--lib/snmp/doc/src/snmpa.xml37
-rw-r--r--lib/snmp/doc/src/snmpa_error.xml7
-rw-r--r--lib/snmp/doc/src/snmpc.xml45
-rw-r--r--lib/snmp/include/snmp_types.hrl4
-rw-r--r--lib/snmp/mibs/Makefile.in26
-rw-r--r--lib/snmp/src/agent/snmp_community_mib.erl4
-rw-r--r--lib/snmp/src/agent/snmp_framework_mib.erl12
-rw-r--r--lib/snmp/src/agent/snmp_standard_mib.erl275
-rw-r--r--lib/snmp/src/agent/snmp_target_mib.erl13
-rw-r--r--lib/snmp/src/agent/snmp_user_based_sm_mib.erl60
-rw-r--r--lib/snmp/src/agent/snmp_view_based_acm_mib.erl234
-rw-r--r--lib/snmp/src/agent/snmpa.erl182
-rw-r--r--lib/snmp/src/agent/snmpa_mib_lib.erl57
-rw-r--r--lib/snmp/src/agent/snmpa_vacm.erl9
-rw-r--r--lib/snmp/src/app/snmp.appup.src120
-rw-r--r--lib/snmp/src/compile/Makefile14
-rw-r--r--lib/snmp/src/compile/depend.mk3
-rw-r--r--lib/snmp/src/compile/modules.mk3
-rw-r--r--lib/snmp/src/compile/snmpc.erl138
-rw-r--r--lib/snmp/src/compile/snmpc.hrl63
-rw-r--r--lib/snmp/src/compile/snmpc.src381
-rw-r--r--lib/snmp/src/compile/snmpc_lib.erl5
-rw-r--r--lib/snmp/src/compile/snmpc_mib_gram.yrl330
-rw-r--r--lib/snmp/src/compile/snmpc_mib_to_hrl.erl3
-rw-r--r--lib/snmp/src/compile/snmpc_tok.erl9
-rw-r--r--lib/snmp/test/klas3.erl2
-rw-r--r--lib/snmp/test/modules.mk4
-rw-r--r--lib/snmp/test/sa.erl2
-rw-r--r--lib/snmp/test/snmp.cover4
-rw-r--r--lib/snmp/test/snmp.spec2
-rw-r--r--lib/snmp/test/snmp_SUITE.erl171
-rw-r--r--lib/snmp/test/snmp_agent_bl_test.erl4
-rw-r--r--lib/snmp/test/snmp_agent_mibs_test.erl59
-rw-r--r--lib/snmp/test/snmp_agent_ms_test.erl478
-rw-r--r--lib/snmp/test/snmp_agent_mt_test.erl478
-rw-r--r--lib/snmp/test/snmp_agent_nfilter_test.erl14
-rw-r--r--lib/snmp/test/snmp_agent_test.erl658
-rw-r--r--lib/snmp/test/snmp_agent_v1_test.erl4
-rw-r--r--lib/snmp/test/snmp_agent_v2_test.erl478
-rw-r--r--lib/snmp/test/snmp_agent_v3_test.erl478
-rw-r--r--lib/snmp/test/snmp_app_test.erl108
-rw-r--r--lib/snmp/test/snmp_appup_mgr.erl2
-rw-r--r--lib/snmp/test/snmp_appup_test.erl40
-rw-r--r--lib/snmp/test/snmp_compiler_test.erl128
-rw-r--r--lib/snmp/test/snmp_conf_test.erl46
-rw-r--r--lib/snmp/test/snmp_log_test.erl69
-rw-r--r--lib/snmp/test/snmp_manager_config_test.erl206
-rw-r--r--lib/snmp/test/snmp_manager_test.erl210
-rw-r--r--lib/snmp/test/snmp_manager_user.erl2
-rwxr-xr-xlib/snmp/test/snmp_manager_user_old.erl2
-rw-r--r--lib/snmp/test/snmp_manager_user_test.erl85
-rw-r--r--lib/snmp/test/snmp_manager_user_test_lib.erl2
-rw-r--r--lib/snmp/test/snmp_note_store_test.erl30
-rw-r--r--lib/snmp/test/snmp_pdus_test.erl33
-rw-r--r--lib/snmp/test/snmp_test_data/AC-TEST-MIB.mib131
-rw-r--r--lib/snmp/test/snmp_test_data/MC-TEST-MIB.mib173
-rw-r--r--lib/snmp/test/snmp_test_manager.erl2
-rw-r--r--lib/snmp/test/snmp_test_mgr_misc.erl4
-rw-r--r--lib/snmp/test/snmp_test_server.erl8
-rw-r--r--lib/snmp/test/snmp_test_suite.erl4
-rw-r--r--lib/snmp/test/test1.erl2
-rw-r--r--lib/snmp/test/test2.erl2
-rw-r--r--lib/snmp/test/test_config/.gitignore19
-rw-r--r--lib/snmp/test/test_config/Makefile199
-rw-r--r--lib/snmp/test/test_config/agent/agent.conf.src19
-rw-r--r--lib/snmp/test/test_config/agent/community.conf.src15
-rw-r--r--lib/snmp/test/test_config/agent/context.conf.src14
-rw-r--r--lib/snmp/test/test_config/agent/notify.conf.src13
-rw-r--r--lib/snmp/test/test_config/agent/standard.conf.src21
-rw-r--r--lib/snmp/test/test_config/agent/target_addr.conf.src21
-rw-r--r--lib/snmp/test/test_config/agent/target_params.conf.src11
-rw-r--r--lib/snmp/test/test_config/agent/usm.conf.src17
-rw-r--r--lib/snmp/test/test_config/agent/vacm.conf.src27
-rw-r--r--lib/snmp/test/test_config/manager/manager.conf.src16
-rw-r--r--lib/snmp/test/test_config/manager/usm.conf.src9
-rw-r--r--lib/snmp/test/test_config/modules.mk41
-rw-r--r--lib/snmp/test/test_config/snmp_test_config.erl32
-rw-r--r--lib/snmp/test/test_config/sys-agent.config.src43
-rw-r--r--lib/snmp/test/test_config/sys-manager.config.src35
-rw-r--r--lib/snmp/test/test_config/sys.config.src68
-rw-r--r--lib/snmp/vsn.mk21
-rw-r--r--lib/ssh/doc/src/notes.xml87
-rw-r--r--lib/ssh/doc/src/ssh.xml32
-rw-r--r--lib/ssh/src/ssh.appup.src30
-rw-r--r--lib/ssh/src/ssh.erl49
-rw-r--r--lib/ssh/src/ssh_acceptor.erl6
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl16
-rw-r--r--lib/ssh/src/ssh_connection_manager.erl6
-rwxr-xr-xlib/ssh/src/ssh_file.erl40
-rwxr-xr-xlib/ssh/src/ssh_rsa.erl3
-rw-r--r--lib/ssh/src/ssh_system_sup.erl2
-rw-r--r--lib/ssh/src/ssh_transport.erl4
-rw-r--r--lib/ssh/vsn.mk3
-rw-r--r--lib/ssl/doc/src/notes.xml129
-rw-r--r--lib/ssl/doc/src/ssl.xml68
-rw-r--r--lib/ssl/src/inet_ssl_dist.erl29
-rw-r--r--lib/ssl/src/ssl.appup.src33
-rw-r--r--lib/ssl/src/ssl.erl67
-rw-r--r--lib/ssl/src/ssl_certificate.erl17
-rw-r--r--lib/ssl/src/ssl_certificate_db.erl64
-rw-r--r--lib/ssl/src/ssl_cipher.erl138
-rw-r--r--lib/ssl/src/ssl_connection.erl263
-rw-r--r--lib/ssl/src/ssl_handshake.erl161
-rw-r--r--lib/ssl/src/ssl_handshake.hrl8
-rw-r--r--lib/ssl/src/ssl_internal.hrl43
-rw-r--r--lib/ssl/src/ssl_manager.erl89
-rw-r--r--lib/ssl/src/ssl_record.erl3
-rw-r--r--lib/ssl/src/ssl_session.erl30
-rw-r--r--lib/ssl/src/ssl_ssl3.erl30
-rw-r--r--lib/ssl/src/ssl_tls1.erl16
-rw-r--r--lib/ssl/test/Makefile3
-rw-r--r--lib/ssl/test/make_certs.erl2
-rw-r--r--lib/ssl/test/old_ssl_active_SUITE.erl82
-rw-r--r--lib/ssl/test/old_ssl_active_once_SUITE.erl84
-rw-r--r--lib/ssl/test/old_ssl_dist_SUITE.erl24
-rw-r--r--lib/ssl/test/old_ssl_misc_SUITE.erl68
-rw-r--r--lib/ssl/test/old_ssl_passive_SUITE.erl82
-rw-r--r--lib/ssl/test/old_ssl_peer_cert_SUITE.erl71
-rw-r--r--lib/ssl/test/old_ssl_protocol_SUITE.erl68
-rw-r--r--lib/ssl/test/old_ssl_verify_SUITE.erl68
-rw-r--r--lib/ssl/test/old_transport_accept_SUITE.erl31
-rw-r--r--lib/ssl/test/ssl.cover36
-rw-r--r--lib/ssl/test/ssl.spec2
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl653
-rw-r--r--lib/ssl/test/ssl_packet_SUITE.erl115
-rw-r--r--lib/ssl/test/ssl_payload_SUITE.erl63
-rw-r--r--lib/ssl/test/ssl_session_cache_SUITE.erl317
-rw-r--r--lib/ssl/test/ssl_test_lib.erl130
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl83
-rw-r--r--lib/ssl/vsn.mk3
-rw-r--r--lib/stdlib/doc/src/calendar.xml32
-rw-r--r--lib/stdlib/doc/src/dets.xml4
-rw-r--r--lib/stdlib/doc/src/dict.xml8
-rw-r--r--lib/stdlib/doc/src/ets.xml39
-rw-r--r--lib/stdlib/doc/src/filelib.xml35
-rw-r--r--lib/stdlib/doc/src/filename.xml15
-rw-r--r--lib/stdlib/doc/src/notes.xml138
-rw-r--r--lib/stdlib/doc/src/orddict.xml8
-rw-r--r--lib/stdlib/doc/src/re.xml141
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml44
-rw-r--r--lib/stdlib/src/base64.erl113
-rw-r--r--lib/stdlib/src/c.erl74
-rw-r--r--lib/stdlib/src/calendar.erl53
-rw-r--r--lib/stdlib/src/dets.erl111
-rw-r--r--lib/stdlib/src/dets.hrl4
-rw-r--r--lib/stdlib/src/dets_v8.erl2
-rw-r--r--lib/stdlib/src/dets_v9.erl5
-rw-r--r--lib/stdlib/src/digraph.erl2
-rw-r--r--lib/stdlib/src/epp.erl43
-rw-r--r--lib/stdlib/src/erl_lint.erl36
-rw-r--r--lib/stdlib/src/erl_posix_msg.erl285
-rw-r--r--lib/stdlib/src/escript.erl22
-rw-r--r--lib/stdlib/src/ets.erl45
-rw-r--r--lib/stdlib/src/filelib.erl60
-rw-r--r--lib/stdlib/src/filename.erl434
-rw-r--r--lib/stdlib/src/gb_sets.erl2
-rw-r--r--lib/stdlib/src/io.erl38
-rw-r--r--lib/stdlib/src/lists.erl68
-rw-r--r--lib/stdlib/src/orddict.erl2
-rw-r--r--lib/stdlib/src/ordsets.erl18
-rw-r--r--lib/stdlib/src/re.erl42
-rw-r--r--lib/stdlib/src/string.erl2
-rw-r--r--lib/stdlib/src/supervisor.erl146
-rw-r--r--lib/stdlib/src/timer.erl3
-rw-r--r--lib/stdlib/src/unicode.erl11
-rw-r--r--lib/stdlib/test/Makefile2
-rw-r--r--lib/stdlib/test/array_SUITE.erl57
-rw-r--r--lib/stdlib/test/base64_SUITE.erl118
-rw-r--r--lib/stdlib/test/beam_lib_SUITE.erl47
-rw-r--r--lib/stdlib/test/binary_module_SUITE.erl56
-rw-r--r--lib/stdlib/test/c_SUITE.erl28
-rw-r--r--lib/stdlib/test/calendar_SUITE.erl52
-rw-r--r--lib/stdlib/test/dets_SUITE.erl208
-rw-r--r--lib/stdlib/test/dict_SUITE.erl32
-rw-r--r--lib/stdlib/test/dict_test_lib.erl2
-rw-r--r--lib/stdlib/test/digraph_SUITE.erl36
-rw-r--r--lib/stdlib/test/digraph_utils_SUITE.erl30
-rw-r--r--lib/stdlib/test/dummy_h.erl2
-rw-r--r--lib/stdlib/test/edlin_expand_SUITE.erl35
-rw-r--r--lib/stdlib/test/epp_SUITE.erl87
-rw-r--r--lib/stdlib/test/erl_eval_SUITE.erl52
-rw-r--r--lib/stdlib/test/erl_eval_helper.erl2
-rw-r--r--lib/stdlib/test/erl_expand_records_SUITE.erl39
-rw-r--r--lib/stdlib/test/erl_internal_SUITE.erl32
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl114
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl66
-rw-r--r--lib/stdlib/test/erl_scan_SUITE.erl39
-rw-r--r--lib/stdlib/test/error_logger_forwarder.erl2
-rw-r--r--lib/stdlib/test/escript_SUITE.erl55
-rwxr-xr-xlib/stdlib/test/escript_SUITE_data/arg_overflow5
-rwxr-xr-xlib/stdlib/test/escript_SUITE_data/linebuf_overflow5
-rw-r--r--lib/stdlib/test/ets_SUITE.erl1244
-rw-r--r--lib/stdlib/test/ets_tough_SUITE.erl30
-rw-r--r--lib/stdlib/test/file_sorter_SUITE.erl49
-rw-r--r--lib/stdlib/test/filelib_SUITE.erl39
-rw-r--r--lib/stdlib/test/filename_SUITE.erl341
-rw-r--r--lib/stdlib/test/fixtable_SUITE.erl35
-rw-r--r--lib/stdlib/test/format_SUITE.erl31
-rw-r--r--lib/stdlib/test/gen_event_SUITE.erl36
-rw-r--r--lib/stdlib/test/gen_fsm_SUITE.erl41
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl73
-rw-r--r--lib/stdlib/test/id_transform_SUITE.erl30
-rw-r--r--lib/stdlib/test/io_SUITE.erl41
-rw-r--r--lib/stdlib/test/io_proto_SUITE.erl47
-rw-r--r--lib/stdlib/test/lists_SUITE.erl139
-rw-r--r--lib/stdlib/test/log_mf_h_SUITE.erl28
-rw-r--r--lib/stdlib/test/ms_transform_SUITE.erl38
-rw-r--r--lib/stdlib/test/naughty_child.erl2
-rw-r--r--lib/stdlib/test/proc_lib_SUITE.erl35
-rw-r--r--lib/stdlib/test/qlc_SUITE.erl106
-rw-r--r--lib/stdlib/test/queue_SUITE.erl31
-rw-r--r--lib/stdlib/test/random_SUITE.erl33
-rw-r--r--lib/stdlib/test/random_iolist.erl2
-rw-r--r--lib/stdlib/test/random_unicode_list.erl2
-rw-r--r--lib/stdlib/test/re_SUITE.erl35
-rw-r--r--lib/stdlib/test/select_SUITE.erl34
-rw-r--r--lib/stdlib/test/sets_SUITE.erl36
-rw-r--r--lib/stdlib/test/sets_test_lib.erl2
-rw-r--r--lib/stdlib/test/shell_SUITE.erl86
-rw-r--r--lib/stdlib/test/slave_SUITE.erl25
-rw-r--r--lib/stdlib/test/sofs_SUITE.erl73
-rw-r--r--lib/stdlib/test/stdlib.cover25
-rw-r--r--lib/stdlib/test/stdlib.spec5
-rw-r--r--lib/stdlib/test/stdlib_SUITE.erl37
-rw-r--r--lib/stdlib/test/string_SUITE.erl45
-rw-r--r--lib/stdlib/test/supervisor_1.erl2
-rw-r--r--lib/stdlib/test/supervisor_SUITE.erl277
-rw-r--r--lib/stdlib/test/supervisor_bridge_SUITE.erl29
-rw-r--r--lib/stdlib/test/sys_SUITE.erl29
-rw-r--r--lib/stdlib/test/tar_SUITE.erl34
-rw-r--r--lib/stdlib/test/timer_SUITE.erl25
-rw-r--r--lib/stdlib/test/timer_simple_SUITE.erl51
-rw-r--r--lib/stdlib/test/unicode_SUITE.erl33
-rw-r--r--lib/stdlib/test/win32reg_SUITE.erl26
-rw-r--r--lib/stdlib/test/y2k_SUITE.erl44
-rw-r--r--lib/stdlib/test/zip_SUITE.erl35
-rw-r--r--lib/stdlib/vsn.mk2
-rw-r--r--lib/syntax_tools/doc/src/notes.xml14
-rw-r--r--lib/syntax_tools/src/erl_prettypr.erl16
-rw-r--r--lib/syntax_tools/src/erl_recomment.erl5
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl4
-rw-r--r--lib/syntax_tools/src/erl_syntax_lib.erl32
-rw-r--r--lib/syntax_tools/src/erl_tidy.erl15
-rw-r--r--lib/syntax_tools/src/igor.erl52
-rw-r--r--lib/syntax_tools/test/Makefile2
-rw-r--r--lib/syntax_tools/test/syntax_tools.cover2
-rw-r--r--lib/syntax_tools/test/syntax_tools.dynspec5
-rw-r--r--lib/syntax_tools/test/syntax_tools.spec2
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE.erl25
-rw-r--r--lib/syntax_tools/vsn.mk2
-rw-r--r--lib/test_server/doc/src/notes.xml14
-rw-r--r--lib/test_server/src/Makefile7
-rw-r--r--lib/test_server/src/test_server.erl149
-rw-r--r--lib/test_server/src/test_server_ctrl.erl16
-rw-r--r--lib/test_server/src/test_server_node.erl2
-rw-r--r--lib/test_server/src/test_server_sup.erl3
-rw-r--r--lib/test_server/src/ts.config83
-rw-r--r--lib/test_server/src/ts.erl34
-rw-r--r--lib/test_server/src/ts.unix.config2
-rw-r--r--lib/test_server/src/ts.vxworks.config19
-rw-r--r--lib/test_server/src/ts.win32.config15
-rw-r--r--lib/test_server/src/ts_install.erl8
-rw-r--r--lib/test_server/src/ts_install_cth.erl286
-rw-r--r--lib/test_server/src/ts_run.erl457
-rw-r--r--lib/test_server/test/Makefile9
-rw-r--r--lib/test_server/test/test_server.cover34
-rw-r--r--lib/test_server/test/test_server.spec3
-rw-r--r--lib/test_server/test/test_server_SUITE.erl656
-rw-r--r--lib/test_server/test/test_server_SUITE_data/Makefile.src2
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl554
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_SUITE_data/dummy_file (renamed from lib/test_server/test/test_server_SUITE_data/dummy_file)0
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl (renamed from lib/test_server/test/test_server_conf01_SUITE.erl)0
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl (renamed from lib/test_server/test/test_server_conf02_SUITE.erl)0
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl (renamed from lib/test_server/test/test_server_parallel01_SUITE.erl)0
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl (renamed from lib/test_server/test/test_server_shuffle01_SUITE.erl)0
-rw-r--r--lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl (renamed from lib/test_server/test/test_server_skip_SUITE.erl)0
-rw-r--r--lib/test_server/test/test_server_line_SUITE.erl19
-rw-r--r--lib/test_server/test/test_server_test_lib.erl191
-rw-r--r--lib/test_server/test/test_server_test_lib.hrl23
-rw-r--r--lib/test_server/vsn.mk2
-rw-r--r--lib/tools/doc/src/cover.xml29
-rw-r--r--lib/tools/doc/src/cover_chapter.xml7
-rw-r--r--lib/tools/doc/src/notes.xml20
-rw-r--r--lib/tools/emacs/erlang.el18
-rw-r--r--lib/tools/src/cover.erl583
-rw-r--r--lib/tools/src/eprof.erl15
-rw-r--r--lib/tools/test/Makefile6
-rw-r--r--lib/tools/test/cover_SUITE.erl57
-rw-r--r--lib/tools/test/cprof_SUITE.erl35
-rw-r--r--lib/tools/test/emem_SUITE.erl38
-rw-r--r--lib/tools/test/eprof_SUITE.erl26
-rw-r--r--lib/tools/test/fprof_SUITE.erl32
-rw-r--r--[l---------]lib/tools/test/ignore_cores.erl159
-rw-r--r--lib/tools/test/instrument_SUITE.erl29
-rw-r--r--lib/tools/test/lcnt_SUITE.erl19
-rw-r--r--lib/tools/test/make_SUITE.erl31
-rw-r--r--lib/tools/test/tools.cover2
-rw-r--r--lib/tools/test/tools.spec2
-rw-r--r--lib/tools/test/tools_SUITE.erl31
-rw-r--r--lib/tools/test/xref_SUITE.erl58
-rw-r--r--lib/tools/vsn.mk2
-rw-r--r--lib/wx/Makefile4
-rw-r--r--lib/wx/api_gen/Makefile13
-rw-r--r--lib/wx/api_gen/gen_util.erl12
-rw-r--r--lib/wx/api_gen/gl_gen.erl26
-rw-r--r--lib/wx/api_gen/gl_gen_c.erl185
-rw-r--r--lib/wx/api_gen/gl_gen_erl.erl158
-rw-r--r--lib/wx/api_gen/glapi.conf203
-rw-r--r--lib/wx/api_gen/wx_gen.erl2
-rw-r--r--lib/wx/api_gen/wx_gen.hrl6
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl12
-rw-r--r--lib/wx/api_gen/wx_gen_erl.erl17
-rw-r--r--lib/wx/api_gen/wxapi.conf47
-rw-r--r--lib/wx/c_src/Makefile.in72
-rw-r--r--lib/wx/c_src/egl_impl.cpp306
-rw-r--r--lib/wx/c_src/egl_impl.h149
-rw-r--r--lib/wx/c_src/gen/gl_fdefs.h419
-rw-r--r--lib/wx/c_src/gen/gl_finit.h213
-rw-r--r--lib/wx/c_src/gen/gl_funcs.cpp2991
-rw-r--r--lib/wx/c_src/gen/wxe_funcs.cpp10
-rw-r--r--lib/wx/c_src/wxe_driver.c6
-rw-r--r--lib/wx/c_src/wxe_driver.h5
-rw-r--r--lib/wx/c_src/wxe_gl.cpp361
-rw-r--r--lib/wx/c_src/wxe_gl.h119
-rw-r--r--lib/wx/c_src/wxe_impl.cpp42
-rw-r--r--lib/wx/c_src/wxe_ps_init.c2
-rw-r--r--lib/wx/c_src/wxe_return.cpp3
-rwxr-xr-xlib/wx/configure.in53
-rw-r--r--lib/wx/doc/src/notes.xml19
-rw-r--r--lib/wx/include/gl.hrl578
-rw-r--r--lib/wx/src/Makefile1
-rw-r--r--lib/wx/src/gen/gl.erl3932
-rw-r--r--lib/wx/src/gen/gl_debug.hrl697
-rw-r--r--lib/wx/src/gen/glu.erl129
-rw-r--r--lib/wx/src/gen/wxGLCanvas.erl6
-rw-r--r--lib/wx/src/gen/wxSystemSettings.erl79
-rw-r--r--lib/wx/src/wx.erl10
-rw-r--r--lib/wx/src/wxe.hrl8
-rw-r--r--lib/wx/src/wxe_master.erl142
-rw-r--r--lib/wx/src/wxe_util.erl49
-rw-r--r--lib/wx/test/Makefile2
-rw-r--r--lib/wx/test/wx.cover2
-rw-r--r--lib/wx/test/wx.spec3
-rw-r--r--lib/wx/test/wx_app_SUITE.erl34
-rw-r--r--lib/wx/test/wx_basic_SUITE.erl34
-rw-r--r--lib/wx/test/wx_class_SUITE.erl50
-rw-r--r--lib/wx/test/wx_event_SUITE.erl36
-rw-r--r--lib/wx/test/wx_opengl_SUITE.erl54
-rw-r--r--lib/wx/test/wx_test_lib.erl10
-rw-r--r--lib/wx/test/wx_xtra_SUITE.erl31
-rw-r--r--lib/wx/vsn.mk2
-rw-r--r--lib/xmerl/doc/src/notes.xml34
-rw-r--r--lib/xmerl/src/xmerl_lib.erl7
-rw-r--r--lib/xmerl/src/xmerl_sax_parser_base.erlsrc41
-rw-r--r--lib/xmerl/src/xmerl_scan.erl2
-rw-r--r--lib/xmerl/src/xmerl_xpath.erl4
-rw-r--r--lib/xmerl/src/xmerl_xsd.erl3
-rw-r--r--lib/xmerl/vsn.mk2
-rw-r--r--make/emd2exml.in3
-rw-r--r--make/otp.mk.in29
-rw-r--r--make/otp_release_targets.mk44
-rw-r--r--system/doc/efficiency_guide/advanced.xml4
-rw-r--r--system/doc/top/Makefile2
-rw-r--r--system/doc/top/src/erl_html_tools.erl3
1515 files changed, 85682 insertions, 34786 deletions
diff --git a/.gitignore b/.gitignore
index 6034a21f87..54bfadea9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,10 @@
# Match at any level.
+
+# emacs
*~
+# vim
+.*.sw[a-z]
+
autom4te.cache
*.beam
*.asn1db
@@ -27,6 +32,65 @@ powerpc-unknown-linux-gnu
# Mac OS X
a.out.dSYM/
+# Windows
+*.pdb
+tcltk85_win32_bin.tar.gz
+erts/autoconf/win32.config.cache
+erts/emulator/obj/
+erts/emulator/pcre/obj/
+erts/emulator/pcre/win32/
+erts/emulator/win32/
+erts/emulator/zlib/obj/
+erts/emulator/zlib/win32/
+erts/epmd/src/win32/
+erts/etc/common/Install.ini
+erts/etc/common/win32/
+erts/etc/win32/cygwin_tools/vc/coffix.exe
+erts/include/internal/win32/
+erts/include/win32/
+erts/lib/internal/win32/
+erts/lib/win32/
+erts/lib_src/obj/
+erts/lib_src/win32/
+erts/obj/win32/
+erts/win32/
+erts/etc/win32/nsis/erlang.nsh
+lib/asn1/priv/lib/
+lib/asn1/priv/obj/
+lib/common_test/priv/win32/
+lib/crypto/c_src/win32/
+lib/crypto/priv/lib/
+lib/crypto/priv/obj/
+lib/erl_interface/obj.md/
+lib/erl_interface/obj.mdd/
+lib/erl_interface/src/win32/
+lib/gs/priv/tcl/
+lib/gs/tcl/binaries/
+lib/ic/c_src/win32/
+lib/ic/priv/lib/win32/
+lib/ic/priv/obj/win32/
+lib/megaco/src/flex/win32/
+lib/odbc/c_src/win32/
+lib/odbc/priv/bin/odbcserver.exe
+lib/odbc/priv/obj/win32/odbcserver.o
+lib/orber/c_src/win32/
+lib/os_mon/c_src/win32/
+lib/os_mon/priv/bin/win32/
+lib/os_mon/priv/obj/win32/
+lib/runtime_tools/c_src/win32/
+lib/runtime_tools/priv/lib/
+lib/runtime_tools/priv/obj/
+lib/ssl/c_src/win32/
+lib/ssl/priv/bin/win32/
+lib/ssl/priv/obj/win32/
+lib/tools/bin/win32/
+lib/tools/c_src/win32/
+lib/tools/obj/win32/
+lib/wx/c_src/win32/
+lib/wx/priv/win32/
+lib/wx/win32/
+make/win32/
+
# Anchored from $ERL_TOP
/bin
/config.log
@@ -103,6 +167,7 @@ a.out.dSYM/
/erts/emulator/test/*_SUITE_make.erl
/erts/emulator/test/*_SUITE_data/Makefile
/erts/test/install_SUITE_data/install_bin
+/erts/test/autoimport_SUITE_data/erlang.xml
# asn1
@@ -286,10 +351,12 @@ a.out.dSYM/
/lib/wx/api_gen/wx_xml/*
/lib/wx/api_gen/gl_xml/*
/lib/wx/api_gen/??_doxygen
-/lib/wx/api_gen/??xml_generated
+/lib/wx/api_gen/*_generated
/lib/wx/wx-*.ez
/lib/wx/CONF_INFO
/lib/wx/doc/src/wx*.xml
+/lib/wx/priv/wxe_driver.*
+/lib/wx/priv/erl_gl.*
# xmerl
diff --git a/INSTALL-WIN32.md b/INSTALL-WIN32.md
index 6481ca1b06..59b9086c39 100644
--- a/INSTALL-WIN32.md
+++ b/INSTALL-WIN32.md
@@ -92,7 +92,9 @@ Frequently Asked Questions
A: The SMP version of Erlang needs features in the Visual Studio 2005.
Can't live without them. Besides the new compiler gives the Erlang
- emulator a ~40% performance boost(!)
+ emulator a ~40% performance boost(!). Alternatively you can build Erlang
+ successfully using the free (proprietary) Visual Studio 2008 Express
+ edition C++ compiler.
* Q: Can/will I build a Cygwin binary with the procedure you describe?
@@ -208,20 +210,15 @@ Frequently Asked Questions
* (Buy and) Install Microsoft Visual studio 2005 and SP1 (or higher)
- * Get and install Sun's JDK 1.4.2
+ * Alternatively install the free MS Visual Studio 2008 Express [msvc++]
+ and the Windows SDK [32bit-SDK] or [64bit-SDK] depending on the Windows
+ platform you are running.
- * Get and install NSIS 2.01 or higher (up to 2.30 tried and working)
+ * Get and install Sun's JDK 1.4.2
- * Get and install OpenSSL 0.9.7c or higher
+ * Get and install NSIS 2.01 or higher (up to 2.46 tried and working)
- * Get and unpack wxWidgets-2.8.9 or higher to `/opt/local/pgm` inside
- cygwin.
- * Open `/cygwin/opt/local/pgm/wxWidgets-2.8.9/build/msw/wx.dsw`
- * Enable `wxUSE_GLCANVAS`, `wxUSE_POSTSCRIPT` and
- `wxUSE_GRAPHICS_CONTEXT` in `include/wx/msw/setup.h`
- * Build all unicode release (and unicode debug) packages
- * Open `/cygwin/opt/local/pgm/wxWidgets-2.8.9/contrib/build/stc/stc.dsw`
- * Build the unicode release (and unicode debug) packages
+ * Get and install OpenSSL 0.9.7c or higher (up to 1.0.0a tried & working)
* Get the Erlang source distribution (from
<http://www.erlang.org/download.html>) and unpack with Cygwin's `tar`.
@@ -363,6 +360,15 @@ Well' here's the list:
your `PATH` to allow the environment to find mc.exe. The next Visual Studio
(2010) is expected to include this tool.
+ Alternatively install the free MS Visual Studio 2008 Express [msvc++] and
+ the Windows SDK [32bit-SDK] or [64bit-SDK] depending on the Windows
+ platform you are running, which includes the missing mc.exe message
+ compiler.
+
+[msvc++]: http://download.microsoft.com/download/E/8/E/E8EEB394-7F42-4963-A2D8-29559B738298/VS2008ExpressWithSP1ENUX1504728.iso
+[32bit-SDK]: http://download.microsoft.com/download/2/E/9/2E911956-F90F-4BFB-8231-E292A7B6F287/GRMSDK_EN_DVD.iso
+[64bit-SDK]: http://download.microsoft.com/download/2/E/9/2E911956-F90F-4BFB-8231-E292A7B6F287/GRMSDKX_EN_DVD.iso
+
* Sun's Java JDK 1.5.0 or higher. Our Java code (jinterface, ic) is
written for JDK 1.5.0. Get it for Windows and install it, the JRE is
not enough. If you don't care about Java, you can skip this step, the
@@ -401,9 +407,10 @@ Well' here's the list:
on the `Related` link and then on the `Binaries` link (upper right
corner of the page last time I looked), you can then reach the
"Shining Lights Productions" Web site for Windows binaries
- distributions. Get the latest or 0.9.7c if you get trouble with the
- latest. It's a nifty installer. The rest should be handled by
- `configure`, you needn't put anything in the path or anything.
+ distributions. Get the latest 32-bit installer, or use 0.9.7c if you get
+ trouble with the latest, and install to C:\OpenSSL which is where the
+ Makefiles are expecting to find it. It's a nifty installer. The rest should
+ be handled by `configure`, you needn't put anything in the path or anything.
If you want to build openssl for windows yourself (which might be
possible, as you wouldn't be reading this if you weren't a
@@ -422,18 +429,51 @@ Well' here's the list:
release (2.9.\* is a developer release which currently does not work
with wxErlang).
- Install or unpack it to `DRIVE:/PATH/cygwin/opt/local/pgm`
+ Install or unpack it to `DRIVE:/PATH/cygwin/opt/local/pgm`.
Open from explorer (i.e. by double clicking the file)
- `C:\cygwin\opt\local\pgm\wxMSW-2.8.10\build\msw\wx.dsw`
+ `C:\cygwin\opt\local\pgm\wxMSW-2.8.11\build\msw\wx.dsw`
In Microsoft Visual Studio, click File/Open/File, locate and
- open: `C:\cygwin\opt\local\pgm\wxMSW-2.8.10\include\wx\msw\setup.h`
+ open: `C:\cygwin\opt\local\pgm\wxMSW-2.8.11\include\wx\msw\setup.h`
enable `wxUSE_GLCANVAS`, `wxUSE_POSTSCRIPT` and `wxUSE_GRAPHICS_CONTEXT`
Build it by clicking Build/Batch Build and select all unicode release
(and unicode debug) packages.
- Open `C:\cygwin\opt\local\pgm\wxMSW-2.8.10\contrib/build/stc/stc.dsw`
+ Open `C:\cygwin\opt\local\pgm\wxMSW-2.8.11\contrib/build/stc/stc.dsw`
and batch build all unicode packages.
+ If you are using Visual C++ 9.0 or higher (Visual Studio 2008 onwards) you
+ will also need to convert and re-create the project dependencies in the new
+ .sln "Solution" format.
+
+ * Open VSC++ & the project `wxMSW-2.8.11\build\msw\wx.dsw`, accepting the
+ automatic conversion to the newer VC++ format and save as
+ `\wxMSW-2.8.11\build\msw\wx.sln`
+
+ * right-click on the project, and set up the project dependencies for
+ `wx.dsw` to achieve the below build order
+
+ jpeg, png, tiff, zlib, regex, expat, base, net, odbc, core,
+ gl, html, media, qa, adv, dbgrid, xrc, aui, richtext, xml
+
+ Build all unicode release (and unicode debug) packages either from the
+ GUI or alternatively launch a new prompt from somewhere like Start ->
+ Programs -> Microsoft Visual C++ -> Visual Studio Tools -> VS2008 Cmd Prompt
+ and cd to where you unpacked wxMSW
+
+ pushd c:\wxMSW*\build\msw
+ vcbuild /useenv /platform:Win32 /M4 wx.sln "Unicode Release|Win32"
+ vcbuild /useenv /platform:Win32 /M4 wx.sln "Unicode Debug|Win32"
+
+ Open VSC++ & convert `C:\wxMSW-2.8.11\contrib\build\stc\stc.dsw` to
+ `C:\wxMSW-2.8.11\contrib\build\stc\stc.sln`
+
+ * build the unicode release (and unicode debug) packages from the GUI or
+ alternatively open a VS2008 Cmd Prompt and cd to where you unpacked wxMSW
+
+ pushd c:\wxMSW*\contrib\build\stc
+ vcbuild /useenv /platform:Win32 /M4 stc.sln "Unicode Release|Win32"
+ vcbuild /useenv /platform:Win32 /M4 stc.sln "Unicode Debug|Win32"
+
* The Erlang source distribution (from <http://www.erlang.org/download.html>).
The same as for Unix platforms. Preferably use tar from within Cygwin to
unpack the source tar.gz (`tar zxf otp_src_%OTP-REL%.tar.gz`).
diff --git a/INSTALL.md b/INSTALL.md
index 2567b791e5..1061c5187a 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -277,7 +277,8 @@ Some of the available `configure` options are:
x86 processors before pentium 4 (back to 486) in the ethread library. If
not passed the ethread library (part of the runtime system) will use
instructions that first appeared on the pentium 4 processor when building
- for x86.
+ for x86. This option will be automatically enabled if required on the
+ build machine.
* `--with-libatomic_ops=PATH` - Use the `libatomic_ops` library for atomic
memory accesses. If `configure` should inform you about no native atomic
implementation available, you typically want to try using the
diff --git a/Makefile.in b/Makefile.in
index 4b6e2e1190..ca92bf604d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -393,7 +393,7 @@ endif
# ---------------------------------------------------------------
# Target only used when building commercial ERTS patches
# ---------------------------------------------------------------
-release_docs docs:
+release_docs docs: mod2app
ifeq ($(OTP_SMALL_BUILD),true)
cd $(ERL_TOP)/lib && \
ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
@@ -408,6 +408,9 @@ endif
cd $(ERL_TOP)/system/doc && \
ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
+mod2app:
+ $(ERL_TOP)/lib/erl_docgen/priv/bin/xref_mod_app.escript -topdir $(ERL_TOP) -outfile $(ERL_TOP)/make/$(TARGET)/mod2app.xml
+
# ----------------------------------------------------------------------
ERLANG_EARS=$(BOOTSTRAP_ROOT)/bootstrap/erts
ELINK=$(BOOTSTRAP_ROOT)/bootstrap/erts/bin/elink
diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot
index e09d7405b2..c7f5785eee 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 0ed5340fe2..c5106e3709 100644
--- a/bootstrap/bin/start.script
+++ b/bootstrap/bin/start.script
@@ -1,6 +1,6 @@
-%% script generated at {2010,9,10} {14,53,47}
+%% script generated at {2010,12,3} {17,41,47}
{script,
- {"OTP APN 181 01","R14B"},
+ {"OTP APN 181 01","R14B01"},
[{preLoaded,
[erl_prim_loader,erlang,init,otp_ring0,prim_file,prim_inet,prim_zip,
zlib]},
@@ -43,7 +43,7 @@
{application_controller,start,
[{application,kernel,
[{description,"ERTS CXC 138 10"},
- {vsn,"2.14.1"},
+ {vsn,"2.14.2"},
{id,[]},
{modules,
[application,application_controller,application_master,
@@ -80,7 +80,7 @@
{application,load,
[{application,stdlib,
[{description,"ERTS CXC 138 10"},
- {vsn,"1.17.1"},
+ {vsn,"1.17.2"},
{id,[]},
{modules,
[array,base64,beam_lib,binary,c,calendar,dets,
diff --git a/bootstrap/bin/start_clean.boot b/bootstrap/bin/start_clean.boot
index e09d7405b2..c7f5785eee 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 0ed5340fe2..c5106e3709 100644
--- a/bootstrap/bin/start_clean.script
+++ b/bootstrap/bin/start_clean.script
@@ -1,6 +1,6 @@
-%% script generated at {2010,9,10} {14,53,47}
+%% script generated at {2010,12,3} {17,41,47}
{script,
- {"OTP APN 181 01","R14B"},
+ {"OTP APN 181 01","R14B01"},
[{preLoaded,
[erl_prim_loader,erlang,init,otp_ring0,prim_file,prim_inet,prim_zip,
zlib]},
@@ -43,7 +43,7 @@
{application_controller,start,
[{application,kernel,
[{description,"ERTS CXC 138 10"},
- {vsn,"2.14.1"},
+ {vsn,"2.14.2"},
{id,[]},
{modules,
[application,application_controller,application_master,
@@ -80,7 +80,7 @@
{application,load,
[{application,stdlib,
[{description,"ERTS CXC 138 10"},
- {vsn,"1.17.1"},
+ {vsn,"1.17.2"},
{id,[]},
{modules,
[array,base64,beam_lib,binary,c,calendar,dets,
diff --git a/bootstrap/lib/compiler/ebin/beam_asm.beam b/bootstrap/lib/compiler/ebin/beam_asm.beam
index 75c6383ba3..7a40486b42 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 4d71b65e23..41be7667fc 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_utils.beam b/bootstrap/lib/compiler/ebin/beam_utils.beam
index 7b9c08439e..c335748e8a 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/compiler.app b/bootstrap/lib/compiler/ebin/compiler.app
index d201d5fd0d..3fd5add16b 100644
--- a/bootstrap/lib/compiler/ebin/compiler.app
+++ b/bootstrap/lib/compiler/ebin/compiler.app
@@ -18,7 +18,7 @@
{application, compiler,
[{description, "ERTS CXC 138 10"},
- {vsn, "4.7"},
+ {vsn, "4.7.1"},
{modules, [
beam_asm,
beam_block,
diff --git a/bootstrap/lib/compiler/ebin/compiler.appup b/bootstrap/lib/compiler/ebin/compiler.appup
index 99b234c847..10c9fd3dde 100644
--- a/bootstrap/lib/compiler/ebin/compiler.appup
+++ b/bootstrap/lib/compiler/ebin/compiler.appup
@@ -1 +1 @@
-{"4.6.5",[],[]}.
+{"4.7.1",[],[]}.
diff --git a/bootstrap/lib/compiler/ebin/core_lint.beam b/bootstrap/lib/compiler/ebin/core_lint.beam
index e7db1d3f72..813c444d9c 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 631c5d6aba..5e39a05dc5 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/v3_codegen.beam b/bootstrap/lib/compiler/ebin/v3_codegen.beam
index 5555d01b2a..7cdb5fe92a 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 5d889ea4f3..7a60d7b23d 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/egen/core_parse.erl b/bootstrap/lib/compiler/egen/core_parse.erl
index 80fed200ae..6e3fead4a3 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_product/releases/sles10_64_R14A_patched/lib/parsetools-2.0.3/include/yeccpre.hrl", 0).
+-file("/usr/local/otp/releases/sles10_64_R14B_patched/lib/parsetools-2.0.4/include/yeccpre.hrl", 0).
%%
%% %CopyrightBegin%
%%
@@ -42,8 +42,8 @@ tok_line(T) -> element(2, T).
parse(Tokens) ->
yeccpars0(Tokens, {no_func, no_line}, 0, [], []).
--spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) ->
- yecc_ret().
+-spec parse_and_scan({function() | {atom(), atom()}, [_]}
+ | {atom(), atom(), [_]}) -> yecc_ret().
parse_and_scan({F, A}) -> % Fun or {M, F}
yeccpars0([], {{F, A}, no_line}, 0, [], []);
parse_and_scan({M, F, A}) ->
@@ -60,7 +60,7 @@ format_error(Message) ->
%% 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}}).
+-compile({nowarn_unused_function, return_error/2}).
-spec return_error(integer(), any()) -> no_return().
return_error(Line, Message) ->
throw({error, {Line, ?MODULE, Message}}).
@@ -73,10 +73,7 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) ->
error: Error ->
Stacktrace = erlang:get_stacktrace(),
try yecc_error_type(Error, Stacktrace) of
- {syntax_error, Token} ->
- yeccerror(Token);
- {missing_in_goto_table=Tag, Symbol, State} ->
- Desc = {Symbol, State, Tag},
+ Desc ->
erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc},
Stacktrace)
catch _:_ -> erlang:raise(error, Error, Stacktrace)
@@ -86,13 +83,15 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) ->
Error
end.
-yecc_error_type(function_clause, [{?MODULE,F,[State,_,_,_,Token,_,_]} | _]) ->
+yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs} | _]) ->
case atom_to_list(F) of
- "yeccpars2" ++ _ ->
- {syntax_error, Token};
"yeccgoto_" ++ SymbolL ->
{ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL),
- {missing_in_goto_table, Symbol, State}
+ State = case ArityOrArgs of
+ [S,_,_,_,_,_,_] -> S;
+ _ -> state_is_unknown
+ end,
+ {Symbol, State, missing_in_goto_table}
end.
yeccpars1([Token | Tokens], Tzr, State, States, Vstack) ->
@@ -157,11 +156,13 @@ yecctoken_end_location(Token) ->
yecctoken_location(Token)
end.
+-compile({nowarn_unused_function, yeccerror/1}).
yeccerror(Token) ->
Text = yecctoken_to_string(Token),
Location = yecctoken_location(Token),
{error, {Location, ?MODULE, ["syntax error before: ", Text]}}.
+-compile({nowarn_unused_function, yecctoken_to_string/1}).
yecctoken_to_string(Token) ->
case catch erl_scan:token_info(Token, text) of
{text, Txt} -> Txt;
@@ -174,6 +175,7 @@ yecctoken_location(Token) ->
_ -> element(2, Token)
end.
+-compile({nowarn_unused_function, yecctoken2string/1}).
yecctoken2string({atom, _, A}) -> io_lib:write(A);
yecctoken2string({integer,_,N}) -> io_lib:write(N);
yecctoken2string({float,_,F}) -> io_lib:write(F);
@@ -194,7 +196,7 @@ yecctoken2string(Other) ->
--file("/ldisk/pan/git/otp/bootstrap/lib/compiler/egen/core_parse.erl", 197).
+-file("/ldisk/pan/git/otp/bootstrap/lib/compiler/egen/core_parse.erl", 199).
yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr);
@@ -845,38 +847,54 @@ yeccpars2(321=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(Other, _, _, _, _, _, _) ->
- erlang:error({yecc_bug,"1.3",{missing_state_in_action_table, Other}}).
+ erlang:error({yecc_bug,"1.4",{missing_state_in_action_table, Other}}).
yeccpars2_0(S, '(', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 2, Ss, Stack, T, Ts, Tzr);
yeccpars2_0(S, module, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 3, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 3, Ss, Stack, T, Ts, Tzr);
+yeccpars2_0(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_1(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) ->
- {ok, hd(Stack)}.
+ {ok, hd(Stack)};
+yeccpars2_1(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_2(S, module, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 315, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 315, Ss, Stack, T, Ts, Tzr);
+yeccpars2_2(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_3(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 4, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 4, Ss, Stack, T, Ts, Tzr);
+yeccpars2_3(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_4(S, '[', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 6, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 6, Ss, Stack, T, Ts, Tzr);
+yeccpars2_4(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_5(S, attributes, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 18, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 18, Ss, Stack, T, Ts, Tzr);
+yeccpars2_5(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_6(S, ']', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr);
yeccpars2_6(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
+yeccpars2_6(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_7(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_exported_name(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_8(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr);
+yeccpars2_8(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_9(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr);
@@ -890,10 +908,14 @@ yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_module_export(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_11(S, '/', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
+yeccpars2_11(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_12(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr);
+yeccpars2_12(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -901,7 +923,9 @@ yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_function_name(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_14(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
+yeccpars2_14(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -922,15 +946,21 @@ yeccpars2_17(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_58(_S, Cat, [17 | Ss], NewStack, T, Ts, Tzr).
yeccpars2_18(S, '[', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 19, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 19, Ss, Stack, T, Ts, Tzr);
+yeccpars2_18(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_19(S, ']', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 22, Ss, Stack, T, Ts, Tzr);
yeccpars2_19(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 23, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 23, Ss, Stack, T, Ts, Tzr);
+yeccpars2_19(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_20(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 55, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 55, Ss, Stack, T, Ts, Tzr);
+yeccpars2_20(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_21(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 53, Ss, Stack, T, Ts, Tzr);
@@ -944,7 +974,9 @@ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_module_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_23(S, '=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 24, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 24, Ss, Stack, T, Ts, Tzr);
+yeccpars2_23(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_24(S, '[', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 30, Ss, Stack, T, Ts, Tzr);
@@ -962,7 +994,9 @@ yeccpars2_cont_24(S, float, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_24(S, integer, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_24(S, string, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_24(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_literal(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
@@ -1025,7 +1059,9 @@ yeccpars2_36(S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_24(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_37(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 42, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 42, Ss, Stack, T, Ts, Tzr);
+yeccpars2_37(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_38(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 40, Ss, Stack, T, Ts, Tzr);
@@ -1055,7 +1091,9 @@ yeccpars2_43(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars2_43(S, ']', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
yeccpars2_43(S, '|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_43(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_44(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -1076,7 +1114,9 @@ yeccpars2_47(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_48: see yeccpars2_24
yeccpars2_49(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 50, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 50, Ss, Stack, T, Ts, Tzr);
+yeccpars2_49(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_50(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -1091,7 +1131,9 @@ yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_tail_literal(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_53(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 23, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 23, Ss, Stack, T, Ts, Tzr);
+yeccpars2_53(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -1104,7 +1146,9 @@ yeccpars2_55(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_module_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_56(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 314, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 314, Ss, Stack, T, Ts, Tzr);
+yeccpars2_56(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_57(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_anno_function_name(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
@@ -1121,18 +1165,26 @@ yeccpars2_59(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_313(_S, Cat, [59 | Ss], NewStack, T, Ts, Tzr).
yeccpars2_60(S, '=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 96, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 96, Ss, Stack, T, Ts, Tzr);
+yeccpars2_60(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_61: see yeccpars2_14
yeccpars2_62(S, '-|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr);
+yeccpars2_62(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_63(S, '[', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr);
+yeccpars2_63(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_64(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 95, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 95, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_65(S, ']', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 73, Ss, Stack, T, Ts, Tzr);
@@ -1147,7 +1199,9 @@ yeccpars2_67(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_atomic_constant(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_68(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 94, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 94, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_69(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 92, Ss, Stack, T, Ts, Tzr);
@@ -1197,7 +1251,9 @@ yeccpars2_79(S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_85(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_80(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 82, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 82, Ss, Stack, T, Ts, Tzr);
+yeccpars2_80(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_81(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -1214,7 +1270,9 @@ yeccpars2_83(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars2_83(S, ']', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 86, Ss, Stack, T, Ts, Tzr);
yeccpars2_83(S, '|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 87, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 87, Ss, Stack, T, Ts, Tzr);
+yeccpars2_83(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_84(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -1234,7 +1292,9 @@ yeccpars2_85(S, integer, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_85(S, string, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 78, Ss, Stack, T, Ts, Tzr);
yeccpars2_85(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 79, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 79, Ss, Stack, T, Ts, Tzr);
+yeccpars2_85(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_86(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_86_(Stack),
@@ -1243,7 +1303,9 @@ yeccpars2_86(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_87: see yeccpars2_85
yeccpars2_88(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 89, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 89, Ss, Stack, T, Ts, Tzr);
+yeccpars2_88(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_89(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -1277,7 +1339,9 @@ yeccpars2_95(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_96(S, '(', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 99, Ss, Stack, T, Ts, Tzr);
yeccpars2_96(S, 'fun', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 100, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 100, Ss, Stack, T, Ts, Tzr);
+yeccpars2_96(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_97(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_anno_fun(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
@@ -1288,23 +1352,31 @@ yeccpars2_98(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_function_definition(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_99(S, 'fun', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 100, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 100, Ss, Stack, T, Ts, Tzr);
+yeccpars2_99(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_100(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 101, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 101, Ss, Stack, T, Ts, Tzr);
+yeccpars2_100(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_101(S, '(', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 105, Ss, Stack, T, Ts, Tzr);
yeccpars2_101(S, ')', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 106, Ss, Stack, T, Ts, Tzr);
yeccpars2_101(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr);
+yeccpars2_101(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_102(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_anno_variable(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_103(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 306, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 306, Ss, Stack, T, Ts, Tzr);
+yeccpars2_103(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_104(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 304, Ss, Stack, T, Ts, Tzr);
@@ -1313,10 +1385,14 @@ yeccpars2_104(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_anno_variables(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_105(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr);
+yeccpars2_105(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_106(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 108, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 108, Ss, Stack, T, Ts, Tzr);
+yeccpars2_106(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_107(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_107_(Stack),
@@ -1368,7 +1444,9 @@ yeccpars2_cont_108(S, 'receive', Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_108(S, 'try', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 143, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_108(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 144, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 144, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_108(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_109(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_single_expression(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
@@ -1433,7 +1511,9 @@ yeccpars2_128(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_fun_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_129(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 287, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 287, Ss, Stack, T, Ts, Tzr);
+yeccpars2_129(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_130(S, char, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 32, Ss, Stack, T, Ts, Tzr);
@@ -1509,7 +1589,9 @@ yeccpars2_139(S, '(', Ss, Stack, T, Ts, Tzr) ->
yeccpars2_139(S, '<', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 155, Ss, Stack, T, Ts, Tzr);
yeccpars2_139(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr);
+yeccpars2_139(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_140(S, '(', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 61, Ss, Stack, T, Ts, Tzr);
@@ -1562,7 +1644,9 @@ yeccpars2_144(S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_108(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_145(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 150, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 150, Ss, Stack, T, Ts, Tzr);
+yeccpars2_145(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_146(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 148, Ss, Stack, T, Ts, Tzr);
@@ -1588,12 +1672,16 @@ yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_tuple(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_151(S, 'of', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 152, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 152, Ss, Stack, T, Ts, Tzr);
+yeccpars2_151(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_152: see yeccpars2_139
yeccpars2_153(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 159, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 159, Ss, Stack, T, Ts, Tzr);
+yeccpars2_153(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_154(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_154_(Stack),
@@ -1604,10 +1692,14 @@ yeccpars2_155(S, '(', Ss, Stack, T, Ts, Tzr) ->
yeccpars2_155(S, '>', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 157, Ss, Stack, T, Ts, Tzr);
yeccpars2_155(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr);
+yeccpars2_155(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_156(S, '>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 158, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 158, Ss, Stack, T, Ts, Tzr);
+yeccpars2_156(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -1622,12 +1714,16 @@ yeccpars2_158(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_159: see yeccpars2_108
yeccpars2_160(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 161, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 161, Ss, Stack, T, Ts, Tzr);
+yeccpars2_160(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_161: see yeccpars2_139
yeccpars2_162(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 163, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 163, Ss, Stack, T, Ts, Tzr);
+yeccpars2_162(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_163: see yeccpars2_108
@@ -1651,7 +1747,9 @@ yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_other_pattern(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_169(S, 'when', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 240, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 240, Ss, Stack, T, Ts, Tzr);
+yeccpars2_169(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_anno_clause(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
@@ -1675,7 +1773,9 @@ yeccpars2_175(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_clause_pattern(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_176(S, 'after', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr);
+yeccpars2_176(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_177(S, '#', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr);
@@ -1704,7 +1804,9 @@ yeccpars2_177(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_anno_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_178(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 222, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 222, Ss, Stack, T, Ts, Tzr);
+yeccpars2_178(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_179(S, '#', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr);
@@ -1777,7 +1879,9 @@ yeccpars2_183(S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_24(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_184(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 201, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 201, Ss, Stack, T, Ts, Tzr);
+yeccpars2_184(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_185(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 199, Ss, Stack, T, Ts, Tzr);
@@ -1811,10 +1915,14 @@ yeccpars2_188(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_anno_variable(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_189(S, '-|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
+yeccpars2_189(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_190(S, '=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 191, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 191, Ss, Stack, T, Ts, Tzr);
+yeccpars2_190(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_191(S, '#', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr);
@@ -1839,7 +1947,9 @@ yeccpars2_192(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_193: see yeccpars2_63
yeccpars2_194(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 195, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 195, Ss, Stack, T, Ts, Tzr);
+yeccpars2_194(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_195(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -1849,7 +1959,9 @@ yeccpars2_195(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_196: see yeccpars2_63
yeccpars2_197(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 198, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 198, Ss, Stack, T, Ts, Tzr);
+yeccpars2_197(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_198(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -1869,7 +1981,9 @@ yeccpars2_201(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_tuple_pattern(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_202(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 203, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 203, Ss, Stack, T, Ts, Tzr);
+yeccpars2_202(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_203: see yeccpars2_108
@@ -1883,7 +1997,9 @@ yeccpars2_205(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars2_205(S, ']', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 208, Ss, Stack, T, Ts, Tzr);
yeccpars2_205(S, '|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 209, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 209, Ss, Stack, T, Ts, Tzr);
+yeccpars2_205(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_206(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -1899,7 +2015,9 @@ yeccpars2_208(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_209: see yeccpars2_191
yeccpars2_210(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 211, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 211, Ss, Stack, T, Ts, Tzr);
+yeccpars2_210(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_211(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -1914,7 +2032,9 @@ yeccpars2_213(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_tail_pattern(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_214(S, '>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr);
+yeccpars2_214(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_215(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -1932,12 +2052,16 @@ yeccpars2_217(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_anno_pattern(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_218(S, '-|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 219, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 219, Ss, Stack, T, Ts, Tzr);
+yeccpars2_218(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_219: see yeccpars2_63
yeccpars2_220(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 221, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 221, Ss, Stack, T, Ts, Tzr);
+yeccpars2_220(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_221(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -1947,10 +2071,14 @@ yeccpars2_221(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_222(S, '#', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 225, Ss, Stack, T, Ts, Tzr);
yeccpars2_222(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 226, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 226, Ss, Stack, T, Ts, Tzr);
+yeccpars2_222(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_223(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 236, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 236, Ss, Stack, T, Ts, Tzr);
+yeccpars2_223(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_224(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 234, Ss, Stack, T, Ts, Tzr);
@@ -1959,10 +2087,14 @@ yeccpars2_224(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_segment_patterns(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_225(S, '<', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 228, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 228, Ss, Stack, T, Ts, Tzr);
+yeccpars2_225(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_226(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 227, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 227, Ss, Stack, T, Ts, Tzr);
+yeccpars2_226(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_227(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_|Nss] = Ss,
@@ -1972,15 +2104,21 @@ yeccpars2_227(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_228: see yeccpars2_191
yeccpars2_229(S, '>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 230, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 230, Ss, Stack, T, Ts, Tzr);
+yeccpars2_229(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_230(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 231, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 231, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_231: see yeccpars2_191
yeccpars2_232(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 233, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 233, Ss, Stack, T, Ts, Tzr);
+yeccpars2_232(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_233(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_,_,_|Nss] = Ss,
@@ -1988,7 +2126,9 @@ yeccpars2_233(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_segment_pattern(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_234(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 225, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 225, Ss, Stack, T, Ts, Tzr);
+yeccpars2_234(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_235(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -1996,7 +2136,9 @@ yeccpars2_235(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_segment_patterns(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_236(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 237, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 237, Ss, Stack, T, Ts, Tzr);
+yeccpars2_236(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_237(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -2016,7 +2158,9 @@ yeccpars2_239(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_240: see yeccpars2_108
yeccpars2_241(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 242, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 242, Ss, Stack, T, Ts, Tzr);
+yeccpars2_241(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_242: see yeccpars2_108
@@ -2026,7 +2170,9 @@ yeccpars2_243(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_244(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 246, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 246, Ss, Stack, T, Ts, Tzr);
+yeccpars2_244(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_245(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2053,7 +2199,9 @@ yeccpars2_246(S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_108(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_247(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 249, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 249, Ss, Stack, T, Ts, Tzr);
+yeccpars2_247(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_248(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -2066,7 +2214,9 @@ yeccpars2_249(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_arg_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_250(S, in, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 251, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 251, Ss, Stack, T, Ts, Tzr);
+yeccpars2_250(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_251: see yeccpars2_108
@@ -2076,12 +2226,16 @@ yeccpars2_252(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_letrec_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_253(S, '=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 254, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 254, Ss, Stack, T, Ts, Tzr);
+yeccpars2_253(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_254: see yeccpars2_108
yeccpars2_255(S, in, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 256, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 256, Ss, Stack, T, Ts, Tzr);
+yeccpars2_255(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_256: see yeccpars2_108
@@ -2103,7 +2257,9 @@ yeccpars2_260(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_catch_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_261(S, 'of', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 262, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 262, Ss, Stack, T, Ts, Tzr);
+yeccpars2_261(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_262(S, '#', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr);
@@ -2123,7 +2279,9 @@ yeccpars2_262(S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_24(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_263(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 264, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 264, Ss, Stack, T, Ts, Tzr);
+yeccpars2_263(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_264(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -2131,7 +2289,9 @@ yeccpars2_264(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_case_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_265(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 266, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 266, Ss, Stack, T, Ts, Tzr);
+yeccpars2_265(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_266: see yeccpars2_108
@@ -2154,7 +2314,9 @@ yeccpars2_271(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars2_271(S, ']', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 274, Ss, Stack, T, Ts, Tzr);
yeccpars2_271(S, '|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 275, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 275, Ss, Stack, T, Ts, Tzr);
+yeccpars2_271(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_272(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2170,7 +2332,9 @@ yeccpars2_274(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_275: see yeccpars2_108
yeccpars2_276(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 277, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 277, Ss, Stack, T, Ts, Tzr);
+yeccpars2_276(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_277(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2185,7 +2349,9 @@ yeccpars2_279(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_tail(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_280(S, '>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 282, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 282, Ss, Stack, T, Ts, Tzr);
+yeccpars2_280(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_281(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -2198,12 +2364,16 @@ yeccpars2_282(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_expression(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_283(S, '-|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 284, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 284, Ss, Stack, T, Ts, Tzr);
+yeccpars2_283(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_284: see yeccpars2_63
yeccpars2_285(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 286, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 286, Ss, Stack, T, Ts, Tzr);
+yeccpars2_285(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_286(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -2213,10 +2383,14 @@ yeccpars2_286(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_287(S, '#', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr);
yeccpars2_287(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 291, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 291, Ss, Stack, T, Ts, Tzr);
+yeccpars2_287(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_288(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 301, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 301, Ss, Stack, T, Ts, Tzr);
+yeccpars2_288(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_289(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 299, Ss, Stack, T, Ts, Tzr);
@@ -2225,10 +2399,14 @@ yeccpars2_289(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_segments(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_290(S, '<', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 293, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 293, Ss, Stack, T, Ts, Tzr);
+yeccpars2_290(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_291(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 292, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 292, Ss, Stack, T, Ts, Tzr);
+yeccpars2_291(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_292(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_|Nss] = Ss,
@@ -2238,15 +2416,21 @@ yeccpars2_292(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_293: see yeccpars2_108
yeccpars2_294(S, '>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 295, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 295, Ss, Stack, T, Ts, Tzr);
+yeccpars2_294(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_295(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 296, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 296, Ss, Stack, T, Ts, Tzr);
+yeccpars2_295(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_296: see yeccpars2_108
yeccpars2_297(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 298, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 298, Ss, Stack, T, Ts, Tzr);
+yeccpars2_297(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_298(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_,_,_|Nss] = Ss,
@@ -2254,7 +2438,9 @@ yeccpars2_298(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_segment(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_299(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr);
+yeccpars2_299(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_300(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2262,7 +2448,9 @@ yeccpars2_300(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_segments(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_301(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 302, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 302, Ss, Stack, T, Ts, Tzr);
+yeccpars2_301(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_302(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -2270,12 +2458,16 @@ yeccpars2_302(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_binary(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_303(S, '-|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 196, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 196, Ss, Stack, T, Ts, Tzr);
+yeccpars2_303(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_304(S, '(', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 105, Ss, Stack, T, Ts, Tzr);
yeccpars2_304(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr);
+yeccpars2_304(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_305(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2283,7 +2475,9 @@ yeccpars2_305(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_anno_variables(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_306(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 307, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 307, Ss, Stack, T, Ts, Tzr);
+yeccpars2_306(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_307: see yeccpars2_108
@@ -2293,12 +2487,16 @@ yeccpars2_308(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_fun_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_309(S, '-|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 310, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 310, Ss, Stack, T, Ts, Tzr);
+yeccpars2_309(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_310: see yeccpars2_63
yeccpars2_311(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 312, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 312, Ss, Stack, T, Ts, Tzr);
+yeccpars2_311(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_312(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -2316,7 +2514,9 @@ yeccpars2_314(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_module_definition(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_315(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 316, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 316, Ss, Stack, T, Ts, Tzr);
+yeccpars2_315(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_316: see yeccpars2_4
@@ -2331,15 +2531,21 @@ yeccpars2_318(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_58(_S, Cat, [318 | Ss], NewStack, T, Ts, Tzr).
yeccpars2_319(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 320, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 320, Ss, Stack, T, Ts, Tzr);
+yeccpars2_319(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_320(S, '-|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 321, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 321, Ss, Stack, T, Ts, Tzr);
+yeccpars2_320(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_321: see yeccpars2_63
yeccpars2_322(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 323, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 323, Ss, Stack, T, Ts, Tzr);
+yeccpars2_322(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_323(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_,_,_,_,_,_|Nss] = Ss,
diff --git a/bootstrap/lib/kernel/ebin/code.beam b/bootstrap/lib/kernel/ebin/code.beam
index dc4cf6cf41..18947d98c3 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/dist_util.beam b/bootstrap/lib/kernel/ebin/dist_util.beam
index 167a70e99d..93f0a3754a 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_epmd.beam b/bootstrap/lib/kernel/ebin/erl_epmd.beam
index 68ef714e17..847ed69e23 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/file.beam b/bootstrap/lib/kernel/ebin/file.beam
index 3671dea4f1..343cee3fe7 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 ce14722f4c..f7c170fd28 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/hipe_unified_loader.beam b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
index 70e35c2076..0c39512bb3 100644
--- a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
+++ b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet.beam b/bootstrap/lib/kernel/ebin/inet.beam
index 63088b2e1b..622110bcdb 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/kernel.app b/bootstrap/lib/kernel/ebin/kernel.app
index 2b2c82d89c..5ea0891375 100644
--- a/bootstrap/lib/kernel/ebin/kernel.app
+++ b/bootstrap/lib/kernel/ebin/kernel.app
@@ -21,7 +21,7 @@
{application, kernel,
[
{description, "ERTS CXC 138 10"},
- {vsn, "2.14.1"},
+ {vsn, "2.14.2"},
{modules, [application,
application_controller,
application_master,
diff --git a/bootstrap/lib/kernel/ebin/kernel.appup b/bootstrap/lib/kernel/ebin/kernel.appup
index 013c65b3e2..77f9f42fea 100644
--- a/bootstrap/lib/kernel/ebin/kernel.appup
+++ b/bootstrap/lib/kernel/ebin/kernel.appup
@@ -1 +1 @@
-{"2.14",[],[]}.
+{"2.14.2",[],[]}.
diff --git a/bootstrap/lib/kernel/ebin/kernel.beam b/bootstrap/lib/kernel/ebin/kernel.beam
index 471ab154e8..e1db5986dc 100644
--- a/bootstrap/lib/kernel/ebin/kernel.beam
+++ b/bootstrap/lib/kernel/ebin/kernel.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/c.beam b/bootstrap/lib/stdlib/ebin/c.beam
index 2202b9105d..af54466541 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 3e133f4ff2..4b6e3756e9 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_v8.beam b/bootstrap/lib/stdlib/ebin/dets_v8.beam
index 2ad134d371..968b9bcb28 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 2eabd08ed4..355c5819cf 100644
--- a/bootstrap/lib/stdlib/ebin/dets_v9.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_v9.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/digraph.beam b/bootstrap/lib/stdlib/ebin/digraph.beam
index fa37407d53..c68611ccdc 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/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam
index 8115d9c474..0483b561d4 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_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam
index 5ebd228586..9b54fff03b 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 426bd23e36..4d07a75daf 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/ets.beam b/bootstrap/lib/stdlib/ebin/ets.beam
index 6b25af9b1b..9ade9e2edd 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/filelib.beam b/bootstrap/lib/stdlib/ebin/filelib.beam
index 8a59a62379..7c1ba41e59 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 4cdb6064d2..69af1ef3c2 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/ordsets.beam b/bootstrap/lib/stdlib/ebin/ordsets.beam
index c3f2c3b7b1..48effb764e 100644
--- a/bootstrap/lib/stdlib/ebin/ordsets.beam
+++ b/bootstrap/lib/stdlib/ebin/ordsets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/stdlib.app b/bootstrap/lib/stdlib/ebin/stdlib.app
index 6ab708e43c..6aac1e2f19 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.app
+++ b/bootstrap/lib/stdlib/ebin/stdlib.app
@@ -19,7 +19,7 @@
%%
{application, stdlib,
[{description, "ERTS CXC 138 10"},
- {vsn, "1.17.1"},
+ {vsn, "1.17.2"},
{modules, [array,
base64,
beam_lib,
diff --git a/bootstrap/lib/stdlib/ebin/stdlib.appup b/bootstrap/lib/stdlib/ebin/stdlib.appup
index 097f2b47ed..ca89dcf43a 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.appup
+++ b/bootstrap/lib/stdlib/ebin/stdlib.appup
@@ -1 +1 @@
-{"1.17",[],[]}.
+{"1.17.2",[],[]}.
diff --git a/bootstrap/lib/stdlib/ebin/string.beam b/bootstrap/lib/stdlib/ebin/string.beam
index 3c3eaf6ed2..0de0b44cb8 100644
--- a/bootstrap/lib/stdlib/ebin/string.beam
+++ b/bootstrap/lib/stdlib/ebin/string.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/supervisor.beam b/bootstrap/lib/stdlib/ebin/supervisor.beam
index 54811dad66..13cb6032a9 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/timer.beam b/bootstrap/lib/stdlib/ebin/timer.beam
index 1020f78632..1f84ff37ac 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 4ca769b9a2..cc3a3c1859 100644
--- a/bootstrap/lib/stdlib/ebin/unicode.beam
+++ b/bootstrap/lib/stdlib/ebin/unicode.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/egen/erl_parse.erl b/bootstrap/lib/stdlib/egen/erl_parse.erl
index 75c491aa37..f15deb37f1 100644
--- a/bootstrap/lib/stdlib/egen/erl_parse.erl
+++ b/bootstrap/lib/stdlib/egen/erl_parse.erl
@@ -556,7 +556,7 @@ get_attribute(L, Name) ->
get_attributes(L) ->
erl_scan:attributes_info(L).
--file("/usr/local/otp_product/releases/sles10_64_R14A_patched/lib/parsetools-2.0.3/include/yeccpre.hrl", 0).
+-file("/usr/local/otp/releases/sles10_64_R14B_patched/lib/parsetools-2.0.4/include/yeccpre.hrl", 0).
%%
%% %CopyrightBegin%
%%
@@ -585,8 +585,8 @@ get_attributes(L) ->
parse(Tokens) ->
yeccpars0(Tokens, {no_func, no_line}, 0, [], []).
--spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) ->
- yecc_ret().
+-spec parse_and_scan({function() | {atom(), atom()}, [_]}
+ | {atom(), atom(), [_]}) -> yecc_ret().
parse_and_scan({F, A}) -> % Fun or {M, F}
yeccpars0([], {{F, A}, no_line}, 0, [], []);
parse_and_scan({M, F, A}) ->
@@ -603,7 +603,7 @@ format_error(Message) ->
%% 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}}).
+-compile({nowarn_unused_function, return_error/2}).
-spec return_error(integer(), any()) -> no_return().
return_error(Line, Message) ->
throw({error, {Line, ?MODULE, Message}}).
@@ -616,10 +616,7 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) ->
error: Error ->
Stacktrace = erlang:get_stacktrace(),
try yecc_error_type(Error, Stacktrace) of
- {syntax_error, Token} ->
- yeccerror(Token);
- {missing_in_goto_table=Tag, Symbol, State} ->
- Desc = {Symbol, State, Tag},
+ Desc ->
erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc},
Stacktrace)
catch _:_ -> erlang:raise(error, Error, Stacktrace)
@@ -629,13 +626,15 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) ->
Error
end.
-yecc_error_type(function_clause, [{?MODULE,F,[State,_,_,_,Token,_,_]} | _]) ->
+yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs} | _]) ->
case atom_to_list(F) of
- "yeccpars2" ++ _ ->
- {syntax_error, Token};
"yeccgoto_" ++ SymbolL ->
{ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL),
- {missing_in_goto_table, Symbol, State}
+ State = case ArityOrArgs of
+ [S,_,_,_,_,_,_] -> S;
+ _ -> state_is_unknown
+ end,
+ {Symbol, State, missing_in_goto_table}
end.
yeccpars1([Token | Tokens], Tzr, State, States, Vstack) ->
@@ -700,11 +699,13 @@ yecctoken_end_location(Token) ->
yecctoken_location(Token)
end.
+-compile({nowarn_unused_function, yeccerror/1}).
yeccerror(Token) ->
Text = yecctoken_to_string(Token),
Location = yecctoken_location(Token),
{error, {Location, ?MODULE, ["syntax error before: ", Text]}}.
+-compile({nowarn_unused_function, yecctoken_to_string/1}).
yecctoken_to_string(Token) ->
case catch erl_scan:token_info(Token, text) of
{text, Txt} -> Txt;
@@ -717,6 +718,7 @@ yecctoken_location(Token) ->
_ -> element(2, Token)
end.
+-compile({nowarn_unused_function, yecctoken2string/1}).
yecctoken2string({atom, _, A}) -> io_lib:write(A);
yecctoken2string({integer,_,N}) -> io_lib:write(N);
yecctoken2string({float,_,F}) -> io_lib:write(F);
@@ -737,7 +739,7 @@ yecctoken2string(Other) ->
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 740).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 742).
yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr);
@@ -1670,12 +1672,14 @@ yeccpars2(462=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}}).
+ erlang:error({yecc_bug,"1.4",{missing_state_in_action_table, Other}}).
yeccpars2_0(S, '-', 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).
+ yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr);
+yeccpars2_0(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_1_(Stack),
@@ -1688,7 +1692,9 @@ yeccpars2_2(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_rule_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_3(S, dot, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 459, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 459, Ss, Stack, T, Ts, Tzr);
+yeccpars2_3(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_4(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_4_(Stack),
@@ -1701,21 +1707,31 @@ yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_function_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_6(S, dot, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 453, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 453, Ss, Stack, T, Ts, Tzr);
+yeccpars2_6(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_7(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) ->
- {ok, hd(Stack)}.
+ {ok, hd(Stack)};
+yeccpars2_7(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_8(S, dot, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 452, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 452, Ss, Stack, T, Ts, Tzr);
+yeccpars2_8(_, _, _, _, T, _, _) ->
+ yeccerror(T).
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).
+ yeccpars1(S, 293, Ss, Stack, T, Ts, Tzr);
+yeccpars2_9(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_10(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr);
+yeccpars2_10(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_11(S, 'when', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr);
@@ -1779,7 +1795,9 @@ yeccpars2_cont_13(S, 'receive', Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_13(S, string, 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, 66, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 66, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_13(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
@@ -1832,7 +1850,9 @@ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_26(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 280, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 280, Ss, Stack, T, Ts, Tzr);
+yeccpars2_26(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_27(S, '#', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 275, Ss, Stack, T, Ts, Tzr);
@@ -1953,7 +1973,9 @@ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_44(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 211, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 211, Ss, Stack, T, Ts, Tzr);
+yeccpars2_44(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_45(S, '#', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
@@ -1992,7 +2014,9 @@ yeccpars2_48(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_prefix_op(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).
+ yeccpars1(S, 208, Ss, Stack, T, Ts, Tzr);
+yeccpars2_49(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_50(S, '(', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
@@ -2063,7 +2087,9 @@ yeccpars2_58(_S, Cat, 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).
+ yeccpars1(S, 152, Ss, Stack, T, Ts, Tzr);
+yeccpars2_59(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_60: see yeccpars2_45
@@ -2074,7 +2100,9 @@ yeccpars2_62(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_63(S, '[', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 127, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 127, Ss, Stack, T, Ts, Tzr);
+yeccpars2_63(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_64(S, '#', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
@@ -2141,7 +2169,9 @@ yeccpars2_68(S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_69(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 71, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 71, Ss, Stack, T, Ts, Tzr);
+yeccpars2_69(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_70(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -2201,7 +2231,9 @@ yeccpars2_77(_S, Cat, 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).
+ yeccpars1(S, 75, Ss, Stack, T, Ts, Tzr);
+yeccpars2_78(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_79(S, ';', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 80, Ss, Stack, T, Ts, Tzr);
@@ -2222,7 +2254,9 @@ yeccpars2_82(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_try_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_83(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 90, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 90, Ss, Stack, T, Ts, Tzr);
+yeccpars2_83(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_84: see yeccpars2_45
@@ -2259,7 +2293,9 @@ yeccpars2_91(_S, Cat, 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).
+ yeccpars1(S, 110, Ss, Stack, T, Ts, Tzr);
+yeccpars2_92(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_93(S, ';', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr);
@@ -2335,7 +2371,9 @@ yeccpars2_110(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_try_catch(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).
+ yeccpars1(S, 112, Ss, Stack, T, Ts, Tzr);
+yeccpars2_111(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_112(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -2343,7 +2381,9 @@ yeccpars2_112(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_try_catch(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_113(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 114, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 114, Ss, Stack, T, Ts, Tzr);
+yeccpars2_113(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_114(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2358,14 +2398,18 @@ yeccpars2_115(_S, Cat, Ss, Stack, 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).
+ yeccpars1(S, 122, Ss, Stack, T, Ts, Tzr);
+yeccpars2_116(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_117: see yeccpars2_45
%% yeccpars2_118: see yeccpars2_83
yeccpars2_119(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 120, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 120, Ss, Stack, T, Ts, Tzr);
+yeccpars2_119(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_120(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -2382,7 +2426,9 @@ yeccpars2_122(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_123: see yeccpars2_83
yeccpars2_124(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 125, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 125, Ss, Stack, T, Ts, Tzr);
+yeccpars2_124(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_125(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_,_|Nss] = Ss,
@@ -2390,17 +2436,23 @@ yeccpars2_125(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_receive_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_126(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 141, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 141, Ss, Stack, T, Ts, Tzr);
+yeccpars2_126(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_127: see yeccpars2_45
yeccpars2_128(S, '||', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 129, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 129, Ss, Stack, T, Ts, Tzr);
+yeccpars2_128(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_129: see yeccpars2_45
yeccpars2_130(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 140, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 140, Ss, Stack, T, Ts, Tzr);
+yeccpars2_130(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_131(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 138, Ss, Stack, T, Ts, Tzr);
@@ -2450,7 +2502,9 @@ yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_query_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_142(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 148, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 148, Ss, Stack, T, Ts, Tzr);
+yeccpars2_142(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_143(S, ';', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 146, Ss, Stack, T, Ts, Tzr);
@@ -2478,7 +2532,9 @@ yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_if_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_149(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 163, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 163, Ss, Stack, T, Ts, Tzr);
+yeccpars2_149(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_150(S, ';', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 161, Ss, Stack, T, Ts, Tzr);
@@ -2495,19 +2551,29 @@ yeccpars2_151(_S, 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).
+ yeccpars1(S, 154, Ss, Stack, T, Ts, Tzr);
+yeccpars2_152(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_153(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 158, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 158, Ss, Stack, T, Ts, Tzr);
+yeccpars2_153(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_154(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 155, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 155, Ss, Stack, T, Ts, Tzr);
+yeccpars2_154(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_155(S, '/', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 156, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 156, Ss, Stack, T, Ts, Tzr);
+yeccpars2_155(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_156(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 157, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 157, Ss, Stack, T, Ts, Tzr);
+yeccpars2_156(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_,_|Nss] = Ss,
@@ -2544,12 +2610,16 @@ yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_165(S, 'of', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 166, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 166, Ss, Stack, T, Ts, Tzr);
+yeccpars2_165(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_166: see yeccpars2_45
yeccpars2_167(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 168, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 168, Ss, Stack, T, Ts, Tzr);
+yeccpars2_167(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -2557,7 +2627,9 @@ yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_case_expr(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).
+ yeccpars1(S, 170, Ss, Stack, T, Ts, Tzr);
+yeccpars2_169(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2588,7 +2660,9 @@ yeccpars2_175(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_176: see yeccpars2_45
yeccpars2_177(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr);
+yeccpars2_177(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_178(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2600,7 +2674,9 @@ yeccpars2_179(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars2_179(S, ']', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
yeccpars2_179(S, '|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
+yeccpars2_179(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_180(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2633,7 +2709,9 @@ yeccpars2_184(_S, 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, 190, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 190, Ss, Stack, T, Ts, Tzr);
+yeccpars2_185(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_186(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
@@ -2678,7 +2756,9 @@ yeccpars2_190(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_191: see yeccpars2_45
yeccpars2_192(S, '>>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
+yeccpars2_192(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_193(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -2707,7 +2787,9 @@ yeccpars2_198(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_bin_element(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_199(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 202, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 202, Ss, Stack, T, Ts, Tzr);
+yeccpars2_199(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_200(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -2727,7 +2809,9 @@ yeccpars2_202(_S, Cat, Ss, Stack, 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).
+ yeccpars1(S, 204, Ss, Stack, T, Ts, Tzr);
+yeccpars2_203(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_204(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2752,7 +2836,9 @@ yeccpars2_208(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_expr_900(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_209(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 210, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 210, Ss, Stack, T, Ts, Tzr);
+yeccpars2_209(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_210(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2762,7 +2848,9 @@ yeccpars2_210(_S, Cat, 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).
+ yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr);
+yeccpars2_211(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_212(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -2770,7 +2858,9 @@ yeccpars2_212(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_213(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 227, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 227, Ss, Stack, T, Ts, Tzr);
+yeccpars2_213(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_214(S, '}', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 219, Ss, Stack, T, Ts, Tzr);
@@ -2778,7 +2868,9 @@ yeccpars2_214(S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_224(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_215(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 226, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 226, Ss, Stack, T, Ts, Tzr);
+yeccpars2_215(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_216(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 224, Ss, Stack, T, Ts, Tzr);
@@ -2787,10 +2879,14 @@ yeccpars2_216(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
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).
+ yeccpars1(S, 222, Ss, Stack, T, Ts, Tzr);
+yeccpars2_217(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_218(S, '=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 220, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 220, Ss, Stack, T, Ts, Tzr);
+yeccpars2_218(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_219(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -2814,7 +2910,9 @@ yeccpars2_223(_S, Cat, 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).
+ yeccpars1(S, 218, Ss, Stack, T, Ts, Tzr);
+yeccpars2_224(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_225(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -3005,7 +3103,9 @@ yeccpars2_270(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_function_call(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).
+ yeccpars1(S, 274, Ss, Stack, T, Ts, Tzr);
+yeccpars2_271(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_272: see yeccpars2_181
@@ -3020,12 +3120,16 @@ yeccpars2_274(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_expr_900(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_275(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 276, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 276, Ss, Stack, T, Ts, Tzr);
+yeccpars2_275(_, _, _, _, T, _, _) ->
+ yeccerror(T).
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).
+ yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr);
+yeccpars2_276(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_277(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_|Nss] = Ss,
@@ -3033,7 +3137,9 @@ yeccpars2_277(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_278(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 279, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 279, Ss, Stack, T, Ts, Tzr);
+yeccpars2_278(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_279(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -3051,12 +3157,16 @@ yeccpars2_281(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_expr_600(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_282(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 283, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 283, Ss, Stack, T, Ts, Tzr);
+yeccpars2_282(_, _, _, _, T, _, _) ->
+ yeccerror(T).
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).
+ yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr);
+yeccpars2_283(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_284(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_|Nss] = Ss,
@@ -3064,7 +3174,9 @@ yeccpars2_284(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_285(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 286, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 286, Ss, Stack, T, Ts, Tzr);
+yeccpars2_285(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_286(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -3074,7 +3186,9 @@ yeccpars2_286(_S, Cat, Ss, Stack, 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).
+ yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr);
+yeccpars2_287(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_288(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_|Nss] = Ss,
@@ -3121,7 +3235,9 @@ yeccpars2_292(S, Cat, 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).
+ yeccpars1(S, 297, Ss, Stack, T, Ts, Tzr);
+yeccpars2_293(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_294(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -3129,10 +3245,14 @@ yeccpars2_294(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_295(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 310, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 310, Ss, Stack, T, Ts, Tzr);
+yeccpars2_295(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_296(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 297, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 297, Ss, Stack, T, Ts, Tzr);
+yeccpars2_296(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_297(S, '/', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 298, Ss, Stack, T, Ts, Tzr);
@@ -3142,10 +3262,14 @@ yeccpars2_297(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_spec_fun(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_298(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 304, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 304, Ss, Stack, T, Ts, Tzr);
+yeccpars2_298(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_299(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 300, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 300, Ss, Stack, T, Ts, Tzr);
+yeccpars2_299(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_300(S, '/', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 301, Ss, Stack, T, Ts, Tzr);
@@ -3155,10 +3279,14 @@ yeccpars2_300(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_spec_fun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_301(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 302, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 302, Ss, Stack, T, Ts, Tzr);
+yeccpars2_301(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_302(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 303, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 303, Ss, Stack, T, Ts, Tzr);
+yeccpars2_302(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_303(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_,_|Nss] = Ss,
@@ -3166,7 +3294,9 @@ yeccpars2_303(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_spec_fun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_304(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 305, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 305, Ss, Stack, T, Ts, Tzr);
+yeccpars2_304(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_305(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_|Nss] = Ss,
@@ -3176,7 +3306,9 @@ yeccpars2_305(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_306: see yeccpars2_295
yeccpars2_307(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 423, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 423, Ss, Stack, T, Ts, Tzr);
+yeccpars2_307(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_308(S, ';', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 421, Ss, Stack, T, Ts, Tzr);
@@ -3219,7 +3351,9 @@ yeccpars2_cont_310(S, 'fun', 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).
+ yeccpars1(S, 330, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_310(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_type_400(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
@@ -3269,7 +3403,9 @@ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_type_500(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_316(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 398, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 398, Ss, Stack, T, Ts, Tzr);
+yeccpars2_316(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_top_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
@@ -3289,7 +3425,9 @@ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_321(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 384, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 384, Ss, Stack, T, Ts, Tzr);
+yeccpars2_321(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_322(S, '+', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
@@ -3305,12 +3443,16 @@ 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).
+ yeccpars1(S, 380, Ss, Stack, T, Ts, Tzr);
+yeccpars2_323(_, _, _, _, T, _, _) ->
+ yeccerror(T).
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, 366, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 366, Ss, Stack, T, Ts, Tzr);
+yeccpars2_324(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_325(S, '+', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
@@ -3335,7 +3477,9 @@ yeccpars2_326(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_327(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 337, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 337, Ss, Stack, T, Ts, Tzr);
+yeccpars2_327(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_328(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
@@ -3361,7 +3505,9 @@ 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).
+ yeccpars1(S, 333, Ss, Stack, T, Ts, Tzr);
+yeccpars2_331(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_332(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -3397,10 +3543,14 @@ yeccpars2_336(_S, Cat, Ss, Stack, 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).
+ yeccpars1(S, 341, Ss, Stack, T, Ts, Tzr);
+yeccpars2_337(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_338(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 346, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 346, Ss, Stack, T, Ts, Tzr);
+yeccpars2_338(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_339(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_fun_type_100(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
@@ -3428,10 +3578,14 @@ yeccpars2_341(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_342(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 343, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 343, Ss, Stack, T, Ts, Tzr);
+yeccpars2_342(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_343(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 344, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 344, Ss, Stack, T, Ts, Tzr);
+yeccpars2_343(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_344: see yeccpars2_322
@@ -3461,10 +3615,14 @@ yeccpars2_347(S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_348(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 349, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 349, Ss, Stack, T, Ts, Tzr);
+yeccpars2_348(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_349(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 350, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 350, Ss, Stack, T, Ts, Tzr);
+yeccpars2_349(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_350(S, ')', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 352, Ss, Stack, T, Ts, Tzr);
@@ -3482,7 +3640,9 @@ 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, 353, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 353, Ss, Stack, T, Ts, Tzr);
+yeccpars2_351(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_352(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -3495,7 +3655,9 @@ yeccpars2_353(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_354(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 356, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 356, Ss, Stack, T, Ts, Tzr);
+yeccpars2_354(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_355(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -3510,7 +3672,9 @@ yeccpars2_356(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
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).
+ yeccpars1(S, 360, Ss, Stack, T, Ts, Tzr);
+yeccpars2_357(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_358(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -3518,7 +3682,9 @@ yeccpars2_358(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_359(S, '...', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 361, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 361, Ss, Stack, T, Ts, Tzr);
+yeccpars2_359(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_360(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -3526,7 +3692,9 @@ yeccpars2_360(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
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).
+ yeccpars1(S, 362, Ss, Stack, T, Ts, Tzr);
+yeccpars2_361(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_362(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -3534,12 +3702,16 @@ yeccpars2_362(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_363(S, '>>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 379, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 379, Ss, Stack, T, Ts, Tzr);
+yeccpars2_363(_, _, _, _, T, _, _) ->
+ yeccerror(T).
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).
+ yeccpars1(S, 373, Ss, Stack, T, Ts, Tzr);
+yeccpars2_364(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_365(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
@@ -3547,7 +3719,9 @@ yeccpars2_365(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_366(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 367, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 367, Ss, Stack, T, Ts, Tzr);
+yeccpars2_366(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_367(S, var, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 369, Ss, Stack, T, Ts, Tzr);
@@ -3572,7 +3746,9 @@ yeccpars2_371(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_bin_unit_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_372(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 375, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 375, Ss, Stack, T, Ts, Tzr);
+yeccpars2_372(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_373(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -3580,16 +3756,24 @@ yeccpars2_373(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_374(S, '>>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 378, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 378, Ss, Stack, T, Ts, Tzr);
+yeccpars2_374(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_375(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 376, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 376, Ss, Stack, T, Ts, Tzr);
+yeccpars2_375(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_376(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 377, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 377, Ss, Stack, T, Ts, Tzr);
+yeccpars2_376(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_377(S, '*', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 370, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 370, Ss, Stack, T, Ts, Tzr);
+yeccpars2_377(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_378(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
@@ -3609,7 +3793,9 @@ yeccpars2_381(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_fun_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_382(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 383, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 383, Ss, Stack, T, Ts, Tzr);
+yeccpars2_382(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_383(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -3617,15 +3803,21 @@ yeccpars2_383(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
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).
+ yeccpars1(S, 385, Ss, Stack, T, Ts, Tzr);
+yeccpars2_384(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_385(S, atom, 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).
+ yeccpars1(S, 389, Ss, Stack, T, Ts, Tzr);
+yeccpars2_385(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_386(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 394, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 394, Ss, Stack, T, Ts, Tzr);
+yeccpars2_386(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_387(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 392, Ss, Stack, T, Ts, Tzr);
@@ -3634,7 +3826,9 @@ yeccpars2_387(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_field_types(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_388(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 390, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 390, Ss, Stack, T, Ts, Tzr);
+yeccpars2_388(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_389(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_|Nss] = Ss,
@@ -3649,7 +3843,9 @@ yeccpars2_391(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_field_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_392(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 388, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 388, Ss, Stack, T, Ts, Tzr);
+yeccpars2_392(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_393(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -3674,7 +3870,9 @@ yeccpars2_397(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_top_types(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_398(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 399, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 399, Ss, Stack, T, Ts, Tzr);
+yeccpars2_398(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_399: see yeccpars2_322
@@ -3742,7 +3940,9 @@ yeccpars2_408(_S, 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).
+ yeccpars1(S, 413, Ss, Stack, T, Ts, Tzr);
+yeccpars2_409(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_410(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -3756,10 +3956,14 @@ yeccpars2_411(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_type_guards(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_412(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 416, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 416, Ss, Stack, T, Ts, Tzr);
+yeccpars2_412(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_413(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 414, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 414, Ss, Stack, T, Ts, Tzr);
+yeccpars2_413(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_414: see yeccpars2_322
@@ -3771,7 +3975,9 @@ yeccpars2_415(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_416: see yeccpars2_322
yeccpars2_417(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 418, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 418, Ss, Stack, T, Ts, Tzr);
+yeccpars2_417(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_418(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_|Nss] = Ss,
@@ -3823,14 +4029,18 @@ yeccpars2_427(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_428: see yeccpars2_45
yeccpars2_429(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 449, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 449, Ss, Stack, T, Ts, Tzr);
+yeccpars2_429(_, _, _, _, T, _, _) ->
+ yeccerror(T).
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).
+ yeccpars1(S, 432, Ss, Stack, T, Ts, Tzr);
+yeccpars2_430(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_431(S, '#', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
@@ -3870,12 +4080,16 @@ yeccpars2_434(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_typed_attr_val(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_435(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 448, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 448, Ss, Stack, T, Ts, Tzr);
+yeccpars2_435(_, _, _, _, T, _, _) ->
+ yeccerror(T).
%% yeccpars2_436: see yeccpars2_68
yeccpars2_437(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 447, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 447, Ss, Stack, T, Ts, Tzr);
+yeccpars2_437(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_438(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 444, Ss, Stack, T, Ts, Tzr);
@@ -3950,7 +4164,9 @@ yeccpars2_453(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_form(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_454(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 456, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 456, Ss, Stack, T, Ts, Tzr);
+yeccpars2_454(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_455(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -3973,7 +4189,9 @@ yeccpars2_459(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccgoto_form(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_460(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 462, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 462, Ss, Stack, T, Ts, Tzr);
+yeccpars2_460(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccpars2_461(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
@@ -3989,7 +4207,9 @@ yeccpars2_463(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
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).
+ yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr);
+yeccpars2_464(_, _, _, _, T, _, _) ->
+ yeccerror(T).
yeccgoto_add_op(33, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_230(249, Cat, Ss, Stack, T, Ts, Tzr);
@@ -7975,7 +8195,7 @@ yeccpars2_39_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7978).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8198).
-compile({inline,yeccpars2_46_/1}).
-file("erl_parse.yrl", 434).
yeccpars2_46_(__Stack0) ->
@@ -7984,7 +8204,7 @@ yeccpars2_46_(__Stack0) ->
{ [ ] , ? line ( __1 ) }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7987).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8207).
-compile({inline,yeccpars2_70_/1}).
-file("erl_parse.yrl", 325).
yeccpars2_70_(__Stack0) ->
@@ -7993,7 +8213,7 @@ yeccpars2_70_(__Stack0) ->
{ tuple , ? line ( __1 ) , [ ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7996).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8216).
-compile({inline,yeccpars2_71_/1}).
-file("erl_parse.yrl", 326).
yeccpars2_71_(__Stack0) ->
@@ -8002,7 +8222,7 @@ yeccpars2_71_(__Stack0) ->
{ tuple , ? line ( __1 ) , __2 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8005).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8225).
-compile({inline,yeccpars2_73_/1}).
-file("erl_parse.yrl", 408).
yeccpars2_73_(__Stack0) ->
@@ -8034,7 +8254,7 @@ yeccpars2_81_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8037).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8257).
-compile({inline,yeccpars2_82_/1}).
-file("erl_parse.yrl", 406).
yeccpars2_82_(__Stack0) ->
@@ -8067,7 +8287,7 @@ yeccpars2_88_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8070).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8290).
-compile({inline,yeccpars2_89_/1}).
-file("erl_parse.yrl", 381).
yeccpars2_89_(__Stack0) ->
@@ -8106,7 +8326,7 @@ yeccpars2_98_(__Stack0) ->
[ ]
end | __Stack0].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8109).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8329).
-compile({inline,yeccpars2_100_/1}).
-file("erl_parse.yrl", 427).
yeccpars2_100_(__Stack0) ->
@@ -8123,7 +8343,7 @@ yeccpars2_102_(__Stack0) ->
[ ]
end | __Stack0].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8126).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8346).
-compile({inline,yeccpars2_104_/1}).
-file("erl_parse.yrl", 424).
yeccpars2_104_(__Stack0) ->
@@ -8133,7 +8353,7 @@ yeccpars2_104_(__Stack0) ->
{ clause , L , [ { tuple , L , [ __1 , __3 , { var , L , '_' } ] } ] , __4 , __5 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8136).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8356).
-compile({inline,yeccpars2_106_/1}).
-file("erl_parse.yrl", 421).
yeccpars2_106_(__Stack0) ->
@@ -8175,7 +8395,7 @@ yeccpars2_114_(__Stack0) ->
{ [ ] , __2 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8178).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8398).
-compile({inline,yeccpars2_115_/1}).
-file("erl_parse.yrl", 452).
yeccpars2_115_(__Stack0) ->
@@ -8184,7 +8404,7 @@ yeccpars2_115_(__Stack0) ->
{ string , ? line ( __1 ) , element ( 3 , __1 ) ++ element ( 3 , __2 ) }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8187).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8407).
-compile({inline,yeccpars2_120_/1}).
-file("erl_parse.yrl", 386).
yeccpars2_120_(__Stack0) ->
@@ -8193,7 +8413,7 @@ yeccpars2_120_(__Stack0) ->
{ 'receive' , ? line ( __1 ) , [ ] , __3 , __4 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8196).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8416).
-compile({inline,yeccpars2_122_/1}).
-file("erl_parse.yrl", 384).
yeccpars2_122_(__Stack0) ->
@@ -8202,7 +8422,7 @@ yeccpars2_122_(__Stack0) ->
{ 'receive' , ? line ( __1 ) , __2 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8205).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8425).
-compile({inline,yeccpars2_125_/1}).
-file("erl_parse.yrl", 388).
yeccpars2_125_(__Stack0) ->
@@ -8219,7 +8439,7 @@ yeccpars2_131_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8222).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8442).
-compile({inline,yeccpars2_135_/1}).
-file("erl_parse.yrl", 323).
yeccpars2_135_(__Stack0) ->
@@ -8228,7 +8448,7 @@ yeccpars2_135_(__Stack0) ->
{ b_generate , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8231).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8451).
-compile({inline,yeccpars2_137_/1}).
-file("erl_parse.yrl", 322).
yeccpars2_137_(__Stack0) ->
@@ -8245,7 +8465,7 @@ yeccpars2_139_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8248).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8468).
-compile({inline,yeccpars2_140_/1}).
-file("erl_parse.yrl", 315).
yeccpars2_140_(__Stack0) ->
@@ -8254,7 +8474,7 @@ yeccpars2_140_(__Stack0) ->
{ lc , ? line ( __1 ) , __2 , __4 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8257).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8477).
-compile({inline,yeccpars2_141_/1}).
-file("erl_parse.yrl", 431).
yeccpars2_141_(__Stack0) ->
@@ -8271,7 +8491,7 @@ yeccpars2_143_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8274).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8494).
-compile({inline,yeccpars2_145_/1}).
-file("erl_parse.yrl", 371).
yeccpars2_145_(__Stack0) ->
@@ -8288,7 +8508,7 @@ yeccpars2_147_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8291).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8511).
-compile({inline,yeccpars2_148_/1}).
-file("erl_parse.yrl", 365).
yeccpars2_148_(__Stack0) ->
@@ -8312,7 +8532,7 @@ yeccpars2_151_(__Stack0) ->
[ ]
end | __Stack0].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8315).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8535).
-compile({inline,yeccpars2_157_/1}).
-file("erl_parse.yrl", 394).
yeccpars2_157_(__Stack0) ->
@@ -8321,7 +8541,7 @@ yeccpars2_157_(__Stack0) ->
{ 'fun' , ? line ( __1 ) , { function , element ( 3 , __2 ) , element ( 3 , __4 ) , element ( 3 , __6 ) } }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8324).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8544).
-compile({inline,yeccpars2_158_/1}).
-file("erl_parse.yrl", 392).
yeccpars2_158_(__Stack0) ->
@@ -8347,7 +8567,7 @@ yeccpars2_162_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8350).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8570).
-compile({inline,yeccpars2_163_/1}).
-file("erl_parse.yrl", 396).
yeccpars2_163_(__Stack0) ->
@@ -8356,7 +8576,7 @@ yeccpars2_163_(__Stack0) ->
build_fun ( ? line ( __1 ) , __2 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8359).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8579).
-compile({inline,yeccpars2_164_/1}).
-file("erl_parse.yrl", 214).
yeccpars2_164_(__Stack0) ->
@@ -8365,7 +8585,7 @@ yeccpars2_164_(__Stack0) ->
{ 'catch' , ? line ( __1 ) , __2 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8368).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8588).
-compile({inline,yeccpars2_168_/1}).
-file("erl_parse.yrl", 375).
yeccpars2_168_(__Stack0) ->
@@ -8374,7 +8594,7 @@ yeccpars2_168_(__Stack0) ->
{ 'case' , ? line ( __1 ) , __2 , __4 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8377).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8597).
-compile({inline,yeccpars2_170_/1}).
-file("erl_parse.yrl", 270).
yeccpars2_170_(__Stack0) ->
@@ -8383,7 +8603,7 @@ yeccpars2_170_(__Stack0) ->
{ block , ? line ( __1 ) , __2 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8386).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8606).
-compile({inline,yeccpars2_172_/1}).
-file("erl_parse.yrl", 279).
yeccpars2_172_(__Stack0) ->
@@ -8392,7 +8612,7 @@ yeccpars2_172_(__Stack0) ->
{ nil , ? line ( __1 ) }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8395).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8615).
-compile({inline,yeccpars2_173_/1}).
-file("erl_parse.yrl", 280).
yeccpars2_173_(__Stack0) ->
@@ -8401,7 +8621,7 @@ yeccpars2_173_(__Stack0) ->
{ cons , ? line ( __1 ) , __2 , __3 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8404).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8624).
-compile({inline,yeccpars2_175_/1}).
-file("erl_parse.yrl", 282).
yeccpars2_175_(__Stack0) ->
@@ -8418,7 +8638,7 @@ yeccpars2_178_(__Stack0) ->
__2
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8421).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8641).
-compile({inline,yeccpars2_180_/1}).
-file("erl_parse.yrl", 284).
yeccpars2_180_(__Stack0) ->
@@ -8442,7 +8662,7 @@ yeccpars2_186_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8445).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8665).
-compile({inline,yeccpars2_187_/1}).
-file("erl_parse.yrl", 287).
yeccpars2_187_(__Stack0) ->
@@ -8459,7 +8679,7 @@ yeccpars2_189_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8462).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8682).
-compile({inline,yeccpars2_190_/1}).
-file("erl_parse.yrl", 288).
yeccpars2_190_(__Stack0) ->
@@ -8468,7 +8688,7 @@ yeccpars2_190_(__Stack0) ->
{ bin , ? line ( __1 ) , __2 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8471).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8691).
-compile({inline,yeccpars2_193_/1}).
-file("erl_parse.yrl", 317).
yeccpars2_193_(__Stack0) ->
@@ -8492,7 +8712,7 @@ yeccpars2_197_(__Stack0) ->
__2
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8495).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8715).
-compile({inline,yeccpars2_198_/1}).
-file("erl_parse.yrl", 294).
yeccpars2_198_(__Stack0) ->
@@ -8541,7 +8761,7 @@ yeccpars2_206_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8544).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8764).
-compile({inline,yeccpars2_207_/1}).
-file("erl_parse.yrl", 296).
yeccpars2_207_(__Stack0) ->
@@ -8550,7 +8770,7 @@ yeccpars2_207_(__Stack0) ->
? mkop1 ( __1 , __2 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8553).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8773).
-compile({inline,yeccpars2_208_/1}).
-file("erl_parse.yrl", 256).
yeccpars2_208_(__Stack0) ->
@@ -8567,7 +8787,7 @@ yeccpars2_210_(__Stack0) ->
__2
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8570).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8790).
-compile({inline,yeccpars2_212_/1}).
-file("erl_parse.yrl", 340).
yeccpars2_212_(__Stack0) ->
@@ -8592,7 +8812,7 @@ yeccpars2_219_(__Stack0) ->
[ ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8595).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8815).
-compile({inline,yeccpars2_221_/1}).
-file("erl_parse.yrl", 356).
yeccpars2_221_(__Stack0) ->
@@ -8601,7 +8821,7 @@ yeccpars2_221_(__Stack0) ->
{ record_field , ? line ( __1 ) , __1 , __3 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8604).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8824).
-compile({inline,yeccpars2_223_/1}).
-file("erl_parse.yrl", 357).
yeccpars2_223_(__Stack0) ->
@@ -8626,7 +8846,7 @@ yeccpars2_226_(__Stack0) ->
__2
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8629).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8849).
-compile({inline,yeccpars2_227_/1}).
-file("erl_parse.yrl", 338).
yeccpars2_227_(__Stack0) ->
@@ -8643,7 +8863,7 @@ yeccpars2_229_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8646).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8866).
-compile({inline,yeccpars2_232_/1}).
-file("erl_parse.yrl", 217).
yeccpars2_232_(__Stack0) ->
@@ -8652,7 +8872,7 @@ yeccpars2_232_(__Stack0) ->
{ match , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8655).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8875).
-compile({inline,yeccpars2_233_/1}).
-file("erl_parse.yrl", 218).
yeccpars2_233_(__Stack0) ->
@@ -8661,7 +8881,7 @@ yeccpars2_233_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8664).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8884).
-compile({inline,yeccpars2_235_/1}).
-file("erl_parse.yrl", 221).
yeccpars2_235_(__Stack0) ->
@@ -8670,7 +8890,7 @@ yeccpars2_235_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8673).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8893).
-compile({inline,yeccpars2_237_/1}).
-file("erl_parse.yrl", 224).
yeccpars2_237_(__Stack0) ->
@@ -8679,7 +8899,7 @@ yeccpars2_237_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8682).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8902).
-compile({inline,yeccpars2_247_/1}).
-file("erl_parse.yrl", 228).
yeccpars2_247_(__Stack0) ->
@@ -8688,7 +8908,7 @@ yeccpars2_247_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8691).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8911).
-compile({inline,yeccpars2_260_/1}).
-file("erl_parse.yrl", 236).
yeccpars2_260_(__Stack0) ->
@@ -8697,7 +8917,7 @@ yeccpars2_260_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8700).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8920).
-compile({inline,yeccpars2_268_/1}).
-file("erl_parse.yrl", 240).
yeccpars2_268_(__Stack0) ->
@@ -8706,7 +8926,7 @@ yeccpars2_268_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8709).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8929).
-compile({inline,yeccpars2_269_/1}).
-file("erl_parse.yrl", 232).
yeccpars2_269_(__Stack0) ->
@@ -8715,7 +8935,7 @@ yeccpars2_269_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8718).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8938).
-compile({inline,yeccpars2_270_/1}).
-file("erl_parse.yrl", 362).
yeccpars2_270_(__Stack0) ->
@@ -8724,7 +8944,7 @@ yeccpars2_270_(__Stack0) ->
{ call , ? line ( __1 ) , __1 , element ( 1 , __2 ) }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8727).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8947).
-compile({inline,yeccpars2_273_/1}).
-file("erl_parse.yrl", 252).
yeccpars2_273_(__Stack0) ->
@@ -8733,7 +8953,7 @@ yeccpars2_273_(__Stack0) ->
{ remote , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8736).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8956).
-compile({inline,yeccpars2_274_/1}).
-file("erl_parse.yrl", 258).
yeccpars2_274_(__Stack0) ->
@@ -8742,7 +8962,7 @@ yeccpars2_274_(__Stack0) ->
{ record_field , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8745).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8965).
-compile({inline,yeccpars2_277_/1}).
-file("erl_parse.yrl", 344).
yeccpars2_277_(__Stack0) ->
@@ -8751,7 +8971,7 @@ yeccpars2_277_(__Stack0) ->
{ record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8754).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8974).
-compile({inline,yeccpars2_279_/1}).
-file("erl_parse.yrl", 342).
yeccpars2_279_(__Stack0) ->
@@ -8760,7 +8980,7 @@ yeccpars2_279_(__Stack0) ->
{ record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8763).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8983).
-compile({inline,yeccpars2_280_/1}).
-file("erl_parse.yrl", 435).
yeccpars2_280_(__Stack0) ->
@@ -8769,7 +8989,7 @@ yeccpars2_280_(__Stack0) ->
{ __2 , ? line ( __1 ) }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8772).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8992).
-compile({inline,yeccpars2_281_/1}).
-file("erl_parse.yrl", 244).
yeccpars2_281_(__Stack0) ->
@@ -8778,7 +8998,7 @@ yeccpars2_281_(__Stack0) ->
? mkop1 ( __1 , __2 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8781).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9001).
-compile({inline,yeccpars2_284_/1}).
-file("erl_parse.yrl", 348).
yeccpars2_284_(__Stack0) ->
@@ -8787,7 +9007,7 @@ yeccpars2_284_(__Stack0) ->
{ record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8790).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9010).
-compile({inline,yeccpars2_286_/1}).
-file("erl_parse.yrl", 346).
yeccpars2_286_(__Stack0) ->
@@ -8796,7 +9016,7 @@ yeccpars2_286_(__Stack0) ->
{ record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8799).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9019).
-compile({inline,yeccpars2_288_/1}).
-file("erl_parse.yrl", 493).
yeccpars2_288_(__Stack0) ->
@@ -8805,7 +9025,7 @@ yeccpars2_288_(__Stack0) ->
{ clause , ? line ( __1 ) , element ( 3 , __1 ) , __2 , __3 , __4 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8808).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9028).
-compile({inline,yeccpars2_289_/1}).
-file("erl_parse.yrl", 203).
yeccpars2_289_(__Stack0) ->
@@ -8870,7 +9090,7 @@ yeccpars2_318_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8873).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9093).
-compile({inline,yeccpars2_332_/1}).
-file("erl_parse.yrl", 152).
yeccpars2_332_(__Stack0) ->
@@ -8879,7 +9099,7 @@ yeccpars2_332_(__Stack0) ->
{ type , ? line ( __1 ) , tuple , [ ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8882).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9102).
-compile({inline,yeccpars2_333_/1}).
-file("erl_parse.yrl", 153).
yeccpars2_333_(__Stack0) ->
@@ -8888,7 +9108,7 @@ yeccpars2_333_(__Stack0) ->
{ type , ? line ( __1 ) , tuple , __2 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8891).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9111).
-compile({inline,yeccpars2_335_/1}).
-file("erl_parse.yrl", 116).
yeccpars2_335_(__Stack0) ->
@@ -8897,7 +9117,7 @@ yeccpars2_335_(__Stack0) ->
{ ann_type , ? line ( __1 ) , [ __1 , __3 ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8900).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9120).
-compile({inline,yeccpars2_341_/1}).
-file("erl_parse.yrl", 159).
yeccpars2_341_(__Stack0) ->
@@ -8906,7 +9126,7 @@ yeccpars2_341_(__Stack0) ->
{ type , ? line ( __1 ) , 'fun' , [ ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8909).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9129).
-compile({inline,yeccpars2_345_/1}).
-file("erl_parse.yrl", 163).
yeccpars2_345_(__Stack0) ->
@@ -8924,7 +9144,7 @@ yeccpars2_346_(__Stack0) ->
__3
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8927).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9147).
-compile({inline,yeccpars2_352_/1}).
-file("erl_parse.yrl", 144).
yeccpars2_352_(__Stack0) ->
@@ -8934,7 +9154,7 @@ yeccpars2_352_(__Stack0) ->
[ __1 , __3 , [ ] ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8937).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9157).
-compile({inline,yeccpars2_353_/1}).
-file("erl_parse.yrl", 146).
yeccpars2_353_(__Stack0) ->
@@ -8952,7 +9172,7 @@ yeccpars2_355_(__Stack0) ->
build_gen_type ( __1 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8955).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9175).
-compile({inline,yeccpars2_356_/1}).
-file("erl_parse.yrl", 142).
yeccpars2_356_(__Stack0) ->
@@ -8962,7 +9182,7 @@ yeccpars2_356_(__Stack0) ->
normalise ( __1 ) , __3 }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8965).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9185).
-compile({inline,yeccpars2_358_/1}).
-file("erl_parse.yrl", 148).
yeccpars2_358_(__Stack0) ->
@@ -8971,7 +9191,7 @@ yeccpars2_358_(__Stack0) ->
{ type , ? line ( __1 ) , nil , [ ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8974).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9194).
-compile({inline,yeccpars2_360_/1}).
-file("erl_parse.yrl", 149).
yeccpars2_360_(__Stack0) ->
@@ -8980,7 +9200,7 @@ yeccpars2_360_(__Stack0) ->
{ type , ? line ( __1 ) , list , [ __2 ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8983).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9203).
-compile({inline,yeccpars2_362_/1}).
-file("erl_parse.yrl", 150).
yeccpars2_362_(__Stack0) ->
@@ -8990,7 +9210,7 @@ yeccpars2_362_(__Stack0) ->
nonempty_list , [ __2 ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8993).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9213).
-compile({inline,yeccpars2_365_/1}).
-file("erl_parse.yrl", 179).
yeccpars2_365_(__Stack0) ->
@@ -9017,7 +9237,7 @@ yeccpars2_371_(__Stack0) ->
build_bin_type ( [ __1 , __3 ] , __5 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9020).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9240).
-compile({inline,yeccpars2_373_/1}).
-file("erl_parse.yrl", 182).
yeccpars2_373_(__Stack0) ->
@@ -9027,7 +9247,7 @@ yeccpars2_373_(__Stack0) ->
[ __2 , abstract ( 0 , ? line ( __1 ) ) ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9030).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9250).
-compile({inline,yeccpars2_378_/1}).
-file("erl_parse.yrl", 187).
yeccpars2_378_(__Stack0) ->
@@ -9036,7 +9256,7 @@ yeccpars2_378_(__Stack0) ->
{ type , ? line ( __1 ) , binary , [ __2 , __4 ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9039).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9259).
-compile({inline,yeccpars2_379_/1}).
-file("erl_parse.yrl", 184).
yeccpars2_379_(__Stack0) ->
@@ -9046,7 +9266,7 @@ yeccpars2_379_(__Stack0) ->
[ abstract ( 0 , ? line ( __1 ) ) , __2 ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9049).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9269).
-compile({inline,yeccpars2_381_/1}).
-file("erl_parse.yrl", 167).
yeccpars2_381_(__Stack0) ->
@@ -9056,7 +9276,7 @@ yeccpars2_381_(__Stack0) ->
[ { type , ? line ( __1 ) , product , [ ] } , __4 ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9059).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9279).
-compile({inline,yeccpars2_383_/1}).
-file("erl_parse.yrl", 138).
yeccpars2_383_(__Stack0) ->
@@ -9073,7 +9293,7 @@ yeccpars2_387_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9076).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9296).
-compile({inline,yeccpars2_389_/1}).
-file("erl_parse.yrl", 154).
yeccpars2_389_(__Stack0) ->
@@ -9082,7 +9302,7 @@ yeccpars2_389_(__Stack0) ->
{ type , ? line ( __1 ) , record , [ __2 ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9085).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9305).
-compile({inline,yeccpars2_391_/1}).
-file("erl_parse.yrl", 176).
yeccpars2_391_(__Stack0) ->
@@ -9100,7 +9320,7 @@ yeccpars2_393_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9103).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9323).
-compile({inline,yeccpars2_394_/1}).
-file("erl_parse.yrl", 155).
yeccpars2_394_(__Stack0) ->
@@ -9110,7 +9330,7 @@ yeccpars2_394_(__Stack0) ->
record , [ __2 | __4 ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9113).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9333).
-compile({inline,yeccpars2_395_/1}).
-file("erl_parse.yrl", 135).
yeccpars2_395_(__Stack0) ->
@@ -9127,7 +9347,7 @@ yeccpars2_397_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9130).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9350).
-compile({inline,yeccpars2_400_/1}).
-file("erl_parse.yrl", 170).
yeccpars2_400_(__Stack0) ->
@@ -9145,7 +9365,7 @@ yeccpars2_402_(__Stack0) ->
lift_unions ( __1 , __3 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9148).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9368).
-compile({inline,yeccpars2_405_/1}).
-file("erl_parse.yrl", 122).
yeccpars2_405_(__Stack0) ->
@@ -9156,7 +9376,7 @@ yeccpars2_405_(__Stack0) ->
skip_paren ( __3 ) ] }
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9159).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9379).
-compile({inline,yeccpars2_406_/1}).
-file("erl_parse.yrl", 127).
yeccpars2_406_(__Stack0) ->
@@ -9166,7 +9386,7 @@ yeccpars2_406_(__Stack0) ->
__2 , skip_paren ( __3 ) )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9169).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9389).
-compile({inline,yeccpars2_408_/1}).
-file("erl_parse.yrl", 131).
yeccpars2_408_(__Stack0) ->
@@ -9176,7 +9396,7 @@ yeccpars2_408_(__Stack0) ->
__2 , skip_paren ( __3 ) )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9179).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9399).
-compile({inline,yeccpars2_410_/1}).
-file("erl_parse.yrl", 103).
yeccpars2_410_(__Stack0) ->
@@ -9202,7 +9422,7 @@ yeccpars2_415_(__Stack0) ->
build_def ( __1 , __3 )
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9205).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9425).
-compile({inline,yeccpars2_418_/1}).
-file("erl_parse.yrl", 109).
yeccpars2_418_(__Stack0) ->
@@ -9332,7 +9552,7 @@ yeccpars2_446_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9335).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9555).
-compile({inline,yeccpars2_447_/1}).
-file("erl_parse.yrl", 90).
yeccpars2_447_(__Stack0) ->
diff --git a/configure.in b/configure.in
index d0879c6291..36b33ec399 100644
--- a/configure.in
+++ b/configure.in
@@ -106,7 +106,8 @@ AC_SUBST(CROSS_COMPILING)
AC_ARG_ENABLE(bootstrap-only,
-[ --enable-bootstrap-only enable bootstrap only configuration],
+AS_HELP_STRING([--enable-bootstrap-only],
+ [enable bootstrap only configuration]),
[ if test "X$enableval" = "Xyes"; then
BOOTSTRAP_ONLY=yes
else
@@ -192,53 +193,62 @@ AC_MSG_RESULT([$OTP_REL])
AC_SUBST(OTP_REL)
AC_ARG_ENABLE(threads,
-[ --enable-threads enable async thread support
- --disable-threads disable async thread support])
+AS_HELP_STRING([--enable-threads], [enable async thread support])
+AS_HELP_STRING([--disable-threads], [disable async thread support]))
AC_ARG_ENABLE(halfword-emulator,
-[ --enable-halfword-emulator enable halfword emulator (only for 64bit builds)
- --disable-halfword-emulator disable halfword emulator (only for 64bit builds)])
+AS_HELP_STRING([--enable-halfword-emulator],
+ [enable halfword emulator (only for 64bit builds)]))
AC_ARG_ENABLE(smp-support,
-[ --enable-smp-support enable smp support
- --disable-smp-support disable smp support])
+AS_HELP_STRING([--enable-smp-support], [enable smp support])
+AS_HELP_STRING([--disable-smp-support], [disable smp support]))
AC_ARG_WITH(termcap,
-[ --with-termcap use termcap (default)
- --without-termcap do not use any termcap libraries (ncurses,curses,termcap,termlib)])
+AS_HELP_STRING([--with-termcap], [use termcap (default)])
+AS_HELP_STRING([--without-termcap],
+ [do not use any termcap libraries (ncurses,curses,termcap,termlib)]))
AC_ARG_ENABLE(kernel-poll,
-[ --enable-kernel-poll enable kernel poll support])
+AS_HELP_STRING([--enable-kernel-poll], [enable kernel poll support])
+AS_HELP_STRING([--disable-kernel-poll], [disable kernel poll support]))
+
+AC_ARG_ENABLE(sctp,
+AS_HELP_STRING([--enable-sctp], [enable sctp support])
+AS_HELP_STRING([--disable-sctp], [disable sctp support]))
AC_ARG_ENABLE(hipe,
-[ --enable-hipe enable hipe support
- --disable-hipe disable hipe support])
-
+AS_HELP_STRING([--enable-hipe], [enable hipe support])
+AS_HELP_STRING([--disable-hipe], [disable hipe support]))
+
+AC_ARG_ENABLE(native-libs,
+AS_HELP_STRING([--enable-native-libs],
+ [compile Erlang libraries to native code]))
+
AC_ARG_WITH(javac,
-[ --with-javac=JAVAC specify Java compiler to use
- --with-javac use a Java compiler if found (default)
- --without-javac don't use any Java compiler])
+AS_HELP_STRING([--with-javac=JAVAC], [specify Java compiler to use])
+AS_HELP_STRING([--with-javac], [use a Java compiler if found (default)])
+AS_HELP_STRING([--without-javac], [don't use any Java compiler]))
AC_ARG_ENABLE(megaco_flex_scanner_lineno,
-[ --enable-megaco-flex-scanner-lineno enable megaco flex scanner lineno
- --disable-megaco-flex-scanner-lineno disable megaco flex scanner lineno])
+AS_HELP_STRING([--disable-megaco-flex-scanner-lineno],
+ [disable megaco flex scanner lineno]))
AC_ARG_ENABLE(megaco_reentrant_flex_scanner,
-[ --enable-megaco-reentrant-flex-scanner enable reentrans megaco flex scanner
- --disable-megaco-reentrant-flex-scanner disable reentrans megaco flex scanner])
+AS_HELP_STRING([--disable-megaco-reentrant-flex-scanner],
+ [disable reentrant megaco flex scanner]))
AC_ARG_WITH(ssl,
-[ --with-ssl=PATH specify location of OpenSSL include and lib
- --with-ssl use SSL (default)
- --without-ssl don't use SSL])
+AS_HELP_STRING([--with-ssl=PATH], [specify location of OpenSSL include and lib])
+AS_HELP_STRING([--with-ssl], [use SSL (default)])
+AS_HELP_STRING([--without-ssl], [don't use SSL]))
AC_ARG_ENABLE(dynamic-ssl-lib,
-[ --enable-dynamic-ssl-lib force using dynamic openssl libraries
- --disable-dynamic-ssl-lib disable using dynamic openssl libraries])
+AS_HELP_STRING([--disable-dynamic-ssl-lib],
+ [disable using dynamic openssl libraries]))
AC_ARG_ENABLE(shared-zlib,
-[ --enable-shared-zlib enable using shared zlib library
- --disable-shared-zlib disable shared zlib, compile own zlib source (default)])
+AS_HELP_STRING([--enable-shared-zlib], [enable using shared zlib library]))
dnl This functionality has been lost along the way... :(
dnl It could perhaps be nice to reintroduce some day; therefore,
@@ -256,7 +266,8 @@ dnl esac ], erl_mandir='$(erlang_libdir)/man')
dnl AC_SUBST(erl_mandir)
AC_ARG_ENABLE(darwin-universal,
-[ --enable-darwin-universal build universal binaries on darwin i386],
+AS_HELP_STRING([--enable-darwin-universal],
+ [build universal binaries on darwin i386]),
[ case "$enableval" in
no) enable_darwin_universal=no ;;
*) enable_darwin_univeral=yes ;;
@@ -265,7 +276,7 @@ AC_ARG_ENABLE(darwin-universal,
AC_ARG_ENABLE(darwin-64bit,
-[ --enable-darwin-64bit build 64bit binaries on darwin],
+AS_HELP_STRING([--enable-darwin-64bit], [build 64bit binaries on darwin]),
[ case "$enableval" in
no) enable_darwin_64bit=no ;;
*) enable_darwin_64bit=yes ;;
@@ -273,7 +284,8 @@ AC_ARG_ENABLE(darwin-64bit,
],enable_darwin_64bit=no)
AC_ARG_ENABLE(m64-build,
-[ --enable-m64-build build 64bit binaries using the -m64 flag to (g)cc],
+AS_HELP_STRING([--enable-m64-build],
+ [build 64bit binaries using the -m64 flag to (g)cc]),
[ case "$enableval" in
no) enable_m64_build=no ;;
*) enable_m64_build=yes ;;
@@ -281,7 +293,8 @@ AC_ARG_ENABLE(m64-build,
],enable_m64_build=no)
AC_ARG_ENABLE(m32-build,
-[ --enable-m32-build build 32bit binaries using the -m32 flag to (g)cc],
+AS_HELP_STRING([--enable-m32-build],
+ [build 32bit binaries using the -m32 flag to (g)cc]),
[ case "$enableval" in
no) enable_m32_build=no ;;
*)
@@ -293,6 +306,14 @@ AC_ARG_ENABLE(m32-build,
esac
],enable_m32_build=no)
+AC_ARG_ENABLE(ethread-pre-pentium4-compatibility,
+ AS_HELP_STRING([--enable-ethread-pre-pentium4-compatibility],
+ [enable compatibility with x86 processors before pentium 4 (back to 486) in the ethread library]))
+
+AC_ARG_WITH(libatomic_ops,
+ AS_HELP_STRING([--with-libatomic_ops=PATH],
+ [specify and prefer usage of libatomic_ops in the ethread library]))
+
dnl OK, we might have darwin switches off different kinds, lets
dnl check it all before continuing.
TMPSYS=`uname -s`-`uname -m`
diff --git a/erts/Makefile.in b/erts/Makefile.in
index dc8edcd928..2e63fc469e 100644
--- a/erts/Makefile.in
+++ b/erts/Makefile.in
@@ -87,17 +87,20 @@ endif
# in the same directory...
local_setup:
@cd start_scripts && $(MAKE)
+ @echo `ls $(ERL_TOP)/bin/`
@rm -f $(ERL_TOP)/bin/erl $(ERL_TOP)/bin/erlc $(ERL_TOP)/bin/cerl \
$(ERL_TOP)/bin/erl.exe $(ERL_TOP)/bin/erlc.exe \
$(ERL_TOP)/bin/escript $(ERL_TOP)/bin/escript.exe \
$(ERL_TOP)/bin/dialyzer $(ERL_TOP)/bin/dialyzer.exe \
$(ERL_TOP)/bin/typer $(ERL_TOP)/bin/typer.exe \
$(ERL_TOP)/bin/run_test $(ERL_TOP)/bin/run_test.exe \
+ $(ERL_TOP)/bin/ct_run $(ERL_TOP)/bin/ct_run.exe \
$(ERL_TOP)/bin/start*.boot $(ERL_TOP)/bin/start*.script
@if [ "X$(TARGET)" = "Xwin32" ]; then \
cp $(ERL_TOP)/bin/$(TARGET)/dialyzer.exe $(ERL_TOP)/bin/dialyzer.exe; \
cp $(ERL_TOP)/bin/$(TARGET)/typer.exe $(ERL_TOP)/bin/typer.exe; \
- cp $(ERL_TOP)/bin/$(TARGET)/run_test.exe $(ERL_TOP)/bin/run_test.exe; \
+ cp $(ERL_TOP)/bin/$(TARGET)/ct_run.exe $(ERL_TOP)/bin/ct_run.exe; \
+ cp $(ERL_TOP)/bin/$(TARGET)/ct_run.exe $(ERL_TOP)/bin/run_test.exe; \
cp $(ERL_TOP)/bin/$(TARGET)/erlc.exe $(ERL_TOP)/bin/erlc.exe; \
cp $(ERL_TOP)/bin/$(TARGET)/erl.exe $(ERL_TOP)/bin/erl.exe; \
cp $(ERL_TOP)/bin/$(TARGET)/werl.exe $(ERL_TOP)/bin/werl.exe; \
@@ -117,7 +120,8 @@ local_setup:
$(ERL_TOP)/erts/etc/unix/cerl.src > $(ERL_TOP)/bin/cerl; \
cp $(ERL_TOP)/bin/$(TARGET)/dialyzer $(ERL_TOP)/bin/dialyzer; \
cp $(ERL_TOP)/bin/$(TARGET)/typer $(ERL_TOP)/bin/typer; \
- cp $(ERL_TOP)/bin/$(TARGET)/run_test $(ERL_TOP)/bin/run_test; \
+ cp $(ERL_TOP)/bin/$(TARGET)/ct_run $(ERL_TOP)/bin/ct_run; \
+ ln -s $(ERL_TOP)/bin/ct_run $(ERL_TOP)/bin/run_test; \
cp $(ERL_TOP)/bin/$(TARGET)/erlc $(ERL_TOP)/bin/erlc; \
cp $(ERL_TOP)/bin/$(TARGET)/escript $(ERL_TOP)/bin/escript; \
chmod 755 $(ERL_TOP)/bin/erl $(ERL_TOP)/bin/erlc \
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index 3b1edd7605..a1211bbf0c 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -386,14 +386,24 @@ AC_DEFUN(LM_SYS_IPV6,
AC_CACHE_VAL(ac_cv_sys_ipv6_support,
[ok_so_far=yes
AC_TRY_COMPILE([#include <sys/types.h>
-#include <netinet/in.h>],
+#ifdef __WIN32__
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#include <netinet/in.h>
+#endif],
[struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no)
if test $ok_so_far = yes; then
ac_cv_sys_ipv6_support=yes
else
AC_TRY_COMPILE([#include <sys/types.h>
-#include <netinet/in.h>],
+#ifdef __WIN32__
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#include <netinet/in.h>
+#endif],
[struct in_addr6 a6; struct sockaddr_in6 s6;],
ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no)
fi
@@ -737,9 +747,124 @@ case "$THR_LIB_NAME" in
if test $found_win32_winnt = no; then
AC_MSG_ERROR([-D_WIN32_WINNT missing in CPPFLAGS])
fi
- ethr_have_native_atomics=yes
- ethr_have_native_spinlock=yes
+
AC_DEFINE(ETHR_WIN32_THREADS, 1, [Define if you have win32 threads])
+
+ have_ilckd=no
+ AC_MSG_CHECKING([for _InterlockedCompareExchange64()])
+ AC_TRY_LINK([
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ ],
+ [
+ volatile __int64 *var;
+ _InterlockedCompareExchange64(var, (__int64) 1, (__int64) 0);
+ return 0;
+ ],
+ have_ilckd=yes)
+ AC_MSG_RESULT([$have_ilckd])
+ test $have_ilckd = yes && AC_DEFINE(ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64, 1, [Define if you have _InterlockedCompareExchange64()])
+
+ AC_CHECK_SIZEOF(void *)
+ case "$ac_cv_sizeof_void_p-$have_ilckd" in
+ 8-no)
+ ethr_have_native_atomics=no
+ ethr_have_native_spinlock=no;;
+ *)
+ ethr_have_native_atomics=yes
+ ethr_have_native_spinlock=yes;;
+ esac
+
+ have_ilckd=no
+ AC_MSG_CHECKING([for _InterlockedDecrement64()])
+ AC_TRY_LINK([
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ ],
+ [
+ volatile __int64 *var;
+ _InterlockedDecrement64(var);
+ return 0;
+ ],
+ have_ilckd=yes)
+ AC_MSG_RESULT([$have_ilckd])
+ test $have_ilckd = yes && AC_DEFINE(ETHR_HAVE__INTERLOCKEDDECREMENT64, 1, [Define if you have _InterlockedDecrement64()])
+
+ have_ilckd=no
+ AC_MSG_CHECKING([for _InterlockedIncrement64()])
+ AC_TRY_LINK([
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ ],
+ [
+ volatile __int64 *var;
+ _InterlockedIncrement64(var);
+ return 0;
+ ],
+ have_ilckd=yes)
+ AC_MSG_RESULT([$have_ilckd])
+ test $have_ilckd = yes && AC_DEFINE(ETHR_HAVE__INTERLOCKEDINCREMENT64, 1, [Define if you have _InterlockedIncrement64()])
+
+ have_ilckd=no
+ AC_MSG_CHECKING([for _InterlockedExchangeAdd64()])
+ AC_TRY_LINK([
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ ],
+ [
+ volatile __int64 *var;
+ _InterlockedExchangeAdd64(var, (__int64) 1);
+ return 0;
+ ],
+ have_ilckd=yes)
+ AC_MSG_RESULT([$have_ilckd])
+ test $have_ilckd = yes && AC_DEFINE(ETHR_HAVE__INTERLOCKEDEXCHANGEADD64, 1, [Define if you have _InterlockedExchangeAdd64()])
+
+ have_ilckd=no
+ AC_MSG_CHECKING([for _InterlockedExchange64()])
+ AC_TRY_LINK([
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ ],
+ [
+ volatile __int64 *var;
+ _InterlockedExchange64(var, (__int64) 1);
+ return 0;
+ ],
+ have_ilckd=yes)
+ AC_MSG_RESULT([$have_ilckd])
+ test $have_ilckd = yes && AC_DEFINE(ETHR_HAVE__INTERLOCKEDEXCHANGE64, 1, [Define if you have _InterlockedExchange64()])
+
+ have_ilckd=no
+ AC_MSG_CHECKING([for _InterlockedAnd64()])
+ AC_TRY_LINK([
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ ],
+ [
+ volatile __int64 *var;
+ _InterlockedAnd64(var, (__int64) 1);
+ return 0;
+ ],
+ have_ilckd=yes)
+ AC_MSG_RESULT([$have_ilckd])
+ test $have_ilckd = yes && AC_DEFINE(ETHR_HAVE__INTERLOCKEDAND64, 1, [Define if you have _InterlockedAnd64()])
+
+ have_ilckd=no
+ AC_MSG_CHECKING([for _InterlockedOr64()])
+ AC_TRY_LINK([
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ ],
+ [
+ volatile __int64 *var;
+ _InterlockedOr64(var, (__int64) 1);
+ return 0;
+ ],
+ have_ilckd=yes)
+ AC_MSG_RESULT([$have_ilckd])
+ test $have_ilckd = yes && AC_DEFINE(ETHR_HAVE__INTERLOCKEDOR64, 1, [Define if you have _InterlockedOr64()])
+
;;
pthread)
@@ -994,8 +1119,8 @@ case "$THR_LIB_NAME" in
case "$host_cpu" in
sun4u | sparc64 | sun4v)
- ethr_have_native_atomics=yes;;
- i86pc | i386 | i486 | i586 | i686 | x86_64 | amd64)
+ ethr_have_native_atomics=yes;;
+ i86pc | i*86 | x86_64 | amd64)
ethr_have_native_atomics=yes;;
macppc | ppc | "Power Macintosh")
ethr_have_native_atomics=yes;;
@@ -1077,6 +1202,28 @@ fi
AC_CHECK_SIZEOF(void *)
AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers])
+AC_CHECK_SIZEOF(int)
+AC_DEFINE_UNQUOTED(ETHR_SIZEOF_INT, $ac_cv_sizeof_int, [Define to the size of int])
+AC_CHECK_SIZEOF(long)
+AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG, $ac_cv_sizeof_long, [Define to the size of long])
+AC_CHECK_SIZEOF(long long)
+AC_DEFINE_UNQUOTED(ETHR_SIZEOF_LONG_LONG, $ac_cv_sizeof_long_long, [Define to the size of long long])
+AC_CHECK_SIZEOF(__int64)
+AC_DEFINE_UNQUOTED(ETHR_SIZEOF___INT64, $ac_cv_sizeof___int64, [Define to the size of __int64])
+
+
+case X$erl_xcomp_bigendian in
+ X) ;;
+ Xyes|Xno) ac_cv_c_bigendian=$erl_xcomp_bigendian;;
+ *) AC_MSG_ERROR([Bad erl_xcomp_bigendian value: $erl_xcomp_bigendian]);;
+esac
+
+AC_C_BIGENDIAN
+
+if test "$ac_cv_c_bigendian" = "yes"; then
+ AC_DEFINE(ETHR_BIGENDIAN, 1, [Define if bigendian])
+fi
+
AC_ARG_ENABLE(native-ethr-impls,
AS_HELP_STRING([--disable-native-ethr-impls],
[disable native ethread implementations]),
@@ -1090,7 +1237,7 @@ test "X$disable_native_ethr_impls" = "Xyes" &&
AC_ARG_ENABLE(prefer-gcc-native-ethr-impls,
AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls],
- [enable prefer gcc native ethread implementations]),
+ [prefer gcc native ethread implementations]),
[ case "$enableval" in
yes) enable_prefer_gcc_native_ethr_impls=yes ;;
*) enable_prefer_gcc_native_ethr_impls=no ;;
@@ -1099,21 +1246,60 @@ AC_ARG_ENABLE(prefer-gcc-native-ethr-impls,
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_ARG_WITH(libatomic_ops,
+ AS_HELP_STRING([--with-libatomic_ops=PATH],
+ [specify and prefer usage of libatomic_ops in the ethread library]))
+
AC_ARG_ENABLE(ethread-pre-pentium4-compatibility,
AS_HELP_STRING([--enable-ethread-pre-pentium4-compatibility],
[enable compatibility with x86 processors before pentium 4 (back to 486) in the ethread library]),
-[ case "$enableval" in
- yes) enable_ethread_pre_pentium4_compatibility=yes ;;
- *) enable_ethread_pre_pentium4_compatibilit=no ;;
- esac ], enable_ethread_pre_pentium4_compatibilit=no)
+[
+ case "$enable_ethread_pre_pentium4_compatibility" in
+ yes|no) ;;
+ *) enable_ethread_pre_pentium4_compatibility=check;;
+ esac
+],
+[enable_ethread_pre_pentium4_compatibility=check])
+
+test "$cross_compiling" != "yes" || enable_ethread_pre_pentium4_compatibility=no
+
+case "$enable_ethread_pre_pentium4_compatibility-$host_cpu" in
+ check-i86pc | check-i*86)
+ AC_MSG_CHECKING([whether pre pentium 4 compatibility should forced])
+ AC_RUN_IFELSE([
+#if defined(__GNUC__)
+# if defined(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS)
+# define CHECK_LIBATOMIC_OPS__
+# else
+# define CHECK_GCC_ASM__
+# endif
+#elif defined(ETHR_HAVE_LIBATOMIC_OPS)
+# define CHECK_LIBATOMIC_OPS__
+#endif
+#if defined(CHECK_LIBATOMIC_OPS__)
+#include "atomic_ops.h"
+#endif
+int main(void)
+{
+#if defined(CHECK_GCC_ASM__)
+ __asm__ __volatile__("mfence" : : : "memory");
+#elif defined(CHECK_LIBATOMIC_OPS__)
+ AO_nop_full();
+#endif
+ return 0;
+}
+ ],
+ [enable_ethread_pre_pentium4_compatibility=no],
+ [enable_ethread_pre_pentium4_compatibility=yes],
+ [enable_ethread_pre_pentium4_compatibility=no])
+ AC_MSG_RESULT([$enable_ethread_pre_pentium4_compatibility]);;
+ *)
+ ;;
+esac
-test $enable_ethread_pre_pentium4_compatibilit = yes &&
+test $enable_ethread_pre_pentium4_compatibility = yes &&
AC_DEFINE(ETHR_PRE_PENTIUM4_COMPAT, 1, [Define if you want compatibilty with x86 processors before pentium4.])
-AC_ARG_WITH(libatomic_ops,
- AS_HELP_STRING([--with-libatomic_ops=PATH],
- [use libatomic_ops with the ethread library]))
-
AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \
[Define if you have all ethread defines])
diff --git a/erts/autoconf/win32.config.cache.static b/erts/autoconf/win32.config.cache.static
index 31dfe510cd..d25b1df9d9 100755
--- a/erts/autoconf/win32.config.cache.static
+++ b/erts/autoconf/win32.config.cache.static
@@ -61,7 +61,6 @@ ac_cv_func_fork=${ac_cv_func_fork=no}
ac_cv_func_fork_works=${ac_cv_func_fork_works=no}
ac_cv_func_fpsetmask=${ac_cv_func_fpsetmask=no}
ac_cv_func_fstat=${ac_cv_func_fstat=yes}
-ac_cv_func_getaddrinfo=${ac_cv_func_getaddrinfo=no}
ac_cv_func_gethostbyaddr=${ac_cv_func_gethostbyaddr=no}
ac_cv_func_gethostbyaddr_r=${ac_cv_func_gethostbyaddr_r=no}
ac_cv_func_gethostbyname=${ac_cv_func_gethostbyname=no}
@@ -71,7 +70,6 @@ ac_cv_func_gethostname=${ac_cv_func_gethostname=no}
ac_cv_func_gethrtime=${ac_cv_func_gethrtime=no}
ac_cv_func_getipnodebyaddr=${ac_cv_func_getipnodebyaddr=no}
ac_cv_func_getipnodebyname=${ac_cv_func_getipnodebyname=no}
-ac_cv_func_getnameinfo=${ac_cv_func_getnameinfo=no}
ac_cv_func_getpagesize=${ac_cv_func_getpagesize=no}
ac_cv_func_gettimeofday=${ac_cv_func_gettimeofday=no}
ac_cv_func_gmtime_r=${ac_cv_func_gmtime_r=no}
@@ -212,7 +210,6 @@ ac_cv_sizeof_void_p=${ac_cv_sizeof_void_p=4}
ac_cv_struct_exception=${ac_cv_struct_exception=no}
ac_cv_struct_sockaddr_sa_len=${ac_cv_struct_sockaddr_sa_len=no}
ac_cv_struct_tm=${ac_cv_struct_tm=time.h}
-ac_cv_sys_ipv6_support=${ac_cv_sys_ipv6_support=no}
ac_cv_sys_multicast_support=${ac_cv_sys_multicast_support=no}
ac_cv_type_char=${ac_cv_type_char=yes}
ac_cv_type_int=${ac_cv_type_int=yes}
diff --git a/erts/configure.in b/erts/configure.in
index 8c6f2ac076..627f734409 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -110,7 +110,8 @@ ENABLE_ALLOC_TYPE_VARS=
AC_SUBST(ENABLE_ALLOC_TYPE_VARS)
AC_ARG_ENABLE(bootstrap-only,
-[ --enable-bootstrap-only enable bootstrap only configuration],
+AS_HELP_STRING([--enable-bootstrap-only],
+ [enable bootstrap only configuration]),
[ if test "X$enableval" = "Xyes"; then
# Disable stuff not necessary in a bootstrap only system in order
# to speed up things by reducing the amount of stuff needing to be
@@ -126,46 +127,46 @@ AC_ARG_ENABLE(bootstrap-only,
])
AC_ARG_ENABLE(threads,
-[ --enable-threads enable async thread support
- --disable-threads disable async thread support],
+AS_HELP_STRING([--enable-threads], [enable async thread support])
+AS_HELP_STRING([--disable-threads], [disable async thread support]),
[ case "$enableval" in
no) enable_threads=no ;;
*) enable_threads=yes ;;
esac ], enable_threads=unknown)
AC_ARG_ENABLE(halfword-emulator,
-[ --enable-halfword-emulator enable halfword emulator (only for 64bit builds)
- --disable-halfword-emulator disable halfword emulator (only for 64bit builds)],
+AS_HELP_STRING([--enable-halfword-emulator],
+ [enable halfword emulator (only for 64bit builds)]),
[ case "$enableval" in
no) enable_halfword_emualtor=no ;;
*) enable_halfword_emulator=yes ;;
esac ], enable_halfword_emulator=unknown)
AC_ARG_ENABLE(smp-support,
-[ --enable-smp-support enable smp support
- --disable-smp-support disable smp support],
+AS_HELP_STRING([--enable-smp-support], [enable smp support])
+AS_HELP_STRING([--disable-smp-support], [disable smp support]),
[ case "$enableval" in
no) enable_smp_support=no ;;
*) enable_smp_support=yes ;;
esac ], enable_smp_support=unknown)
AC_ARG_WITH(termcap,
-[ --with-termcap use termcap (default)
- --without-termcap do not use any termcap libraries (ncurses,curses,termcap,termlib)],
+AS_HELP_STRING([--with-termcap], [use termcap (default)])
+AS_HELP_STRING([--without-termcap],
+ [do not use any termcap libraries (ncurses,curses,termcap,termlib)]),
[],
[with_termcap=yes])
AC_ARG_ENABLE(hybrid-heap,
-[ --enable-hybrid-heap enable hybrid heap
- --disable-hybrid-heap disable hybrid heap],
+AS_HELP_STRING([--enable-hybrid-heap], [enable hybrid heap]),
[ case "$enableval" in
no) enable_hybrid_heap=no ;;
*) enable_hybrid_heap=yes ;;
esac ], enable_hybrid_heap=unknown)
AC_ARG_ENABLE(lock-checking,
-[ --enable-lock-checking enable lock checking],
+AS_HELP_STRING([--enable-lock-checking], [enable lock checking]),
[ case "$enableval" in
no) enable_lock_check=no ;;
*) enable_lock_check=yes ;;
@@ -174,16 +175,15 @@ AC_ARG_ENABLE(lock-checking,
enable_lock_check=no)
AC_ARG_ENABLE(lock-counter,
-[ --enable-lock-counter enable lock counters
- --disable-lock-counter disable lock counters],
+AS_HELP_STRING([--enable-lock-counter], [enable lock counters]),
[ case "$enableval" in
no) enable_lock_count=no ;;
*) enable_lock_count=yes ;;
esac ], enable_lock_count=no)
AC_ARG_ENABLE(kernel-poll,
-[ --enable-kernel-poll enable kernel poll support
- --disable-kernel-poll disable kernel poll support],
+AS_HELP_STRING([--enable-kernel-poll], [enable kernel poll support])
+AS_HELP_STRING([--disable-kernel-poll], [disable kernel poll support]),
[ case "$enableval" in
no) enable_kernel_poll=no ;;
*) enable_kernel_poll=yes ;;
@@ -191,25 +191,27 @@ AC_ARG_ENABLE(kernel-poll,
AC_ARG_ENABLE(sctp,
-[ --enable-sctp enable sctp support
- --disable-sctp disable sctp support],
+AS_HELP_STRING([--enable-sctp], [enable sctp support])
+AS_HELP_STRING([--disable-sctp], [disable sctp support]),
[ case "$enableval" in
no) enable_sctp=no ;;
*) enable_sctp=yes ;;
esac ], enable_sctp=unknown)
AC_ARG_ENABLE(hipe,
-[ --enable-hipe enable hipe support
- --disable-hipe disable hipe support])
+AS_HELP_STRING([--enable-hipe], [enable hipe support])
+AS_HELP_STRING([--disable-hipe], [disable hipe support]))
AC_ARG_ENABLE(native-libs,
-[ --enable-native-libs compile Erlang libraries to native code])
+AS_HELP_STRING([--enable-native-libs],
+ [compile Erlang libraries to native code]))
AC_ARG_ENABLE(tsp,
-[ --enable-tsp compile tsp app])
+AS_HELP_STRING([--enable-tsp], [compile tsp app]))
AC_ARG_ENABLE(fp-exceptions,
-[ --enable-fp-exceptions Use hardware floating point exceptions (default if hipe enabled)],
+AS_HELP_STRING([--enable-fp-exceptions],
+ [use hardware floating point exceptions (default if hipe enabled)]),
[ case "$enableval" in
no) enable_fp_exceptions=no ;;
*) enable_fp_exceptions=yes ;;
@@ -217,7 +219,8 @@ AC_ARG_ENABLE(fp-exceptions,
],enable_fp_exceptions=auto)
AC_ARG_ENABLE(darwin-universal,
-[ --enable-darwin-universal build universal binaries on darwin i386],
+AS_HELP_STRING([--enable-darwin-universal],
+ [build universal binaries on darwin i386]),
[ case "$enableval" in
no) enable_darwin_universal=no ;;
*) enable_darwin_univeral=yes ;;
@@ -226,7 +229,7 @@ AC_ARG_ENABLE(darwin-universal,
AC_ARG_ENABLE(darwin-64bit,
-[ --enable-darwin-64bit build 64bit binaries on darwin],
+AS_HELP_STRING([--enable-darwin-64bit], [build 64bit binaries on darwin]),
[ case "$enableval" in
no) enable_darwin_64bit=no ;;
*) enable_darwin_64bit=yes ;;
@@ -234,7 +237,8 @@ AC_ARG_ENABLE(darwin-64bit,
],enable_darwin_64bit=no)
AC_ARG_ENABLE(m64-build,
-[ --enable-m64-build build 64bit binaries using the -m64 flag to (g)cc],
+AS_HELP_STRING([--enable-m64-build],
+ [build 64bit binaries using the -m64 flag to (g)cc]),
[ case "$enableval" in
no) enable_m64_build=no ;;
*) enable_m64_build=yes ;;
@@ -242,7 +246,8 @@ AC_ARG_ENABLE(m64-build,
],enable_m64_build=no)
AC_ARG_ENABLE(m32-build,
-[ --enable-m32-build build 32bit binaries using the -m32 flag to (g)cc],
+AS_HELP_STRING([--enable-m32-build],
+ [build 32bit binaries using the -m32 flag to (g)cc]),
[ case "$enableval" in
no) enable_m32_build=no ;;
*)
@@ -255,7 +260,7 @@ AC_ARG_ENABLE(m32-build,
],enable_m32_build=no)
AC_ARG_ENABLE(fixalloc,
-[ --disable-fixalloc disable the use of fix_alloc])
+AS_HELP_STRING([--disable-fixalloc], [disable the use of fix_alloc]))
if test x${enable_fixalloc} = xno ; then
AC_DEFINE(NO_FIX_ALLOC,[],
[Define if you don't want the fix allocator in Erlang])
@@ -263,8 +268,9 @@ fi
AC_SUBST(PERFCTR_PATH)
AC_ARG_WITH(perfctr,
-[ --with-perfctr=PATH specify location of perfctr include and lib
- --without-perfctr don't use perfctr (default)])
+AS_HELP_STRING([--with-perfctr=PATH],
+ [specify location of perfctr include and lib])
+AS_HELP_STRING([--without-perfctr], [don't use perfctr (default)]))
if test "x$with_perfctr" = "xno" -o "x$with_perfctr" = "x" ; then
PERFCTR_PATH=
@@ -278,7 +284,8 @@ else
fi
AC_ARG_ENABLE(clock-gettime,
-[ --enable-clock-gettime Use clock-gettime for time correction],
+AS_HELP_STRING([--enable-clock-gettime],
+ [use clock-gettime for time correction]),
[ case "$enableval" in
no) clock_gettime_correction=no ;;
*) clock_gettime_correction=yes ;;
@@ -573,6 +580,11 @@ AC_SUBST(WFLAGS)
AC_SUBST(CFLAG_RUNTIME_LIBRARY_PATH)
AC_CHECK_SIZEOF(void *) # Needed for ARCH and smp checks below
+if test "x$ac_cv_sizeof_void_p" = x8; then
+ AC_SUBST(EXTERNAL_WORD_SIZE, 64)
+else
+ AC_SUBST(EXTERNAL_WORD_SIZE, 32)
+fi
dnl
dnl Figure out operating system and cpu architecture
@@ -1293,8 +1305,7 @@ dnl zlib
dnl -------------
AC_ARG_ENABLE(shared-zlib,
-[ --enable-shared-zlib enable using shared zlib library
- --disable-shared-zlib disable shared zlib, compile own zlib source (default)],
+AS_HELP_STRING([--enable-shared-zlib], [enable using shared zlib library]),
[ case "$enableval" in
no) enable_shared_zlib=no ;;
*) enable_shared_zlib=yes ;;
@@ -1473,7 +1484,7 @@ AC_CHECK_HEADERS(fcntl.h limits.h unistd.h syslog.h dlfcn.h ieeefp.h \
sys/ioctl.h sys/time.h sys/uio.h \
sys/socket.h sys/sockio.h sys/socketio.h \
net/errno.h malloc.h mach-o/dyld.h arpa/nameser.h \
- pty.h util.h utmp.h langinfo.h poll.h)
+ pty.h util.h utmp.h langinfo.h poll.h sdkddkver.h)
AC_CHECK_HEADER(sys/resource.h,
[AC_DEFINE(HAVE_SYS_RESOURCE_H, 1,
@@ -1673,18 +1684,62 @@ LIBS="$LIBS $EMU_THR_X_LIBS"
dnl Check if we have these, in which case we'll try to build
dnl inet_gethost with ipv6 support.
-AC_CHECK_FUNC(getaddrinfo, have_getaddrinfo=yes, have_getaddrinfo=no)
+AC_CHECK_HEADERS(windows.h)
+AC_CHECK_HEADERS(winsock2.h)
+AC_CHECK_HEADERS(ws2tcpip.h,[],[],[
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+])
+dnl AC_CHECK_FUNC(getaddrinfo, have_getaddrinfo=yes, have_getaddrinfo=no)
+AC_MSG_CHECKING(for getaddrinfo)
+AC_TRY_LINK([
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#ifndef __WIN32__
+#include <sys/socket.h>
+#include <netdb.h>
+#endif
+],
+[
+getaddrinfo("","",NULL,NULL);
+],have_getaddrinfo=yes, have_getaddrinfo=no)
if test $have_getaddrinfo = yes; then
+ AC_MSG_RESULT([yes])
AC_MSG_CHECKING([whether getaddrinfo accepts enough flags])
- AC_TRY_RUN([
+ AC_TRY_COMPILE([
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#ifndef __WIN32__
#include <sys/socket.h>
#include <netdb.h>
-int main(int argc, char **argv) {
+#endif
+],
+[
struct addrinfo hints, *ai;
memset(&hints, 0, sizeof(hints));
- hints.ai_flags = (AI_CANONNAME|AI_V4MAPPED|AI_ADDRCONFIG);
+ hints.ai_flags = AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_INET6;
if (getaddrinfo("::", NULL, &hints, &ai) == 0) {
@@ -1693,26 +1748,48 @@ int main(int argc, char **argv) {
} else {
exit(1);
}
-}
- ],, have_getaddrinfo=no,
- [
- case X$erl_xcomp_getaddrinfo in
- X) have_getaddrinfo=cross;;
- Xyes|Xno) have_getaddrinfo=$erl_xcomp_getaddrinfo;;
- *) AC_MSG_ERROR([Bad erl_xcomp_getaddrinfo value: $erl_xcomp_getaddrinfo]);;
- esac
- ])
+],, have_getaddrinfo=no)
AC_MSG_RESULT($have_getaddrinfo)
case $have_getaddrinfo in
yes)
AC_DEFINE(HAVE_GETADDRINFO, [1],
[Define to 1 if you have a good `getaddrinfo' function.]);;
- cross)
- AC_MSG_WARN([result no guessed because of cross compilation]);;
*) ;;
esac
+else
+ AC_MSG_RESULT([no])
+fi
+AC_MSG_CHECKING(for getnameinfo)
+AC_TRY_LINK([
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#ifndef __WIN32__
+#include <sys/socket.h>
+#include <netdb.h>
+#endif
+],
+[
+getnameinfo(NULL,0,NULL,0,NULL,0,0);
+],have_getnameinfo=yes, have_getnameinfo=no)
+if test $have_getnameinfo = yes; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_GETNAMEINFO, [1],
+ [Define to 1 if you have a good `getnameinfo' function.])
+else
+ AC_MSG_RESULT([no])
fi
-AC_CHECK_FUNCS([getnameinfo getipnodebyname getipnodebyaddr gethostbyname2])
+
+
+AC_CHECK_FUNCS([getipnodebyname getipnodebyaddr gethostbyname2])
AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlopen \
pread pwrite writev memmove strerror strerror_r strncasecmp \
@@ -1788,7 +1865,7 @@ AC_CHECK_FUNCS([fdatasync])
dnl Find which C libraries are required to use fdatasync
AC_SEARCH_LIBS(fdatasync, [rt])
-AC_CHECK_HEADERS(net/if_dl.h ifaddrs.h)
+AC_CHECK_HEADERS(net/if_dl.h ifaddrs.h netpacket/packet.h)
AC_CHECK_FUNCS([getifaddrs])
dnl ----------------------------------------------------------------------
@@ -1852,6 +1929,27 @@ if test $processor_bind_functionality = yes; then
AC_DEFINE(HAVE_PROCESSOR_BIND, 1, [Define if you have processor_bind functionality])
fi
+AC_MSG_CHECKING([for cpuset_getaffinity/cpuset_setaffinity])
+AC_TRY_COMPILE([
+#include <sys/param.h>
+#include <sys/cpuset.h>
+],
+[
+ int res;
+ cpuset_t cpuset;
+ CPU_ZERO(&cpuset);
+ CPU_SET(1, &cpuset);
+ res = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(cpuset_t), &cpuset);
+ res = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(cpuset_t), &cpuset);
+ res = CPU_ISSET(1, &cpuset);
+ CPU_CLR(1, &cpuset);
+],
+ cpuset_xetaffinity=yes,
+ cpuset_xetaffinity=no)
+AC_MSG_RESULT([$cpuset_xetaffinity])
+if test $cpuset_xetaffinity = yes; then
+ AC_DEFINE(HAVE_CPUSET_xETAFFINITY, 1, [Define if you have cpuset_getaffinity/cpuset_setaffinity])
+fi
AC_CACHE_CHECK([for 'end' symbol],
erts_cv_have_end_symbol,
@@ -3431,9 +3529,12 @@ AC_SUBST(STATIC_ZLIB_LIBS)
std_ssl_locations="/usr/local /usr/sfw /opt/local /usr /usr/pkg /usr/local/openssl /usr/lib/openssl /usr/openssl /usr/local/ssl /usr/lib/ssl /usr/ssl"
AC_ARG_WITH(ssl-zlib,
-[ --with-ssl-zlib=PATH specify location of ZLib to be used by OpenSSL
- --with-ssl-zlib link SSL with Zlib (default if found)
- --without-ssl-zlib don't link SSL with ZLib])
+AS_HELP_STRING([--with-ssl-zlib=PATH],
+ [specify location of ZLib to be used by OpenSSL])
+AS_HELP_STRING([--with-ssl-zlib],
+ [link SSL with Zlib (default if found)])
+AS_HELP_STRING([--without-ssl-zlib],
+ [don't link SSL with ZLib]))
if test "x$with_ssl_zlib" = "xno"; then
@@ -3502,13 +3603,13 @@ fi
AC_ARG_WITH(ssl,
-[ --with-ssl=PATH specify location of OpenSSL include and lib
- --with-ssl use SSL (default)
- --without-ssl don't use SSL])
+AS_HELP_STRING([--with-ssl=PATH], [specify location of OpenSSL include and lib])
+AS_HELP_STRING([--with-ssl], [use SSL (default)])
+AS_HELP_STRING([--without-ssl], [don't use SSL]))
AC_ARG_ENABLE(dynamic-ssl-lib,
-[ --enable-dynamic-ssl-lib enable using dynamic openssl libraries
- --disable-dynamic-ssl-lib disable using dynamic openssl libraries],
+AS_HELP_STRING([--disable-dynamic-ssl-lib],
+ [disable using dynamic openssl libraries]),
[ case "$enableval" in
no) enable_dynamic_ssl=no ;;
*) enable_dynamic_ssl=yes ;;
@@ -3971,9 +4072,9 @@ esac
AC_ARG_WITH(javac,
-[ --with-javac=JAVAC specify Java compiler to use
- --with-javac use a Java compiler if found (default)
- --without-javac don't use any Java compiler])
+AS_HELP_STRING([--with-javac=JAVAC], [specify Java compiler to use])
+AS_HELP_STRING([--with-javac], [use a Java compiler if found (default)])
+AS_HELP_STRING([--without-javac], [don't use any Java compiler]))
dnl
dnl Then there are a number of apps which needs a java compiler...
diff --git a/erts/doc/src/driver.xml b/erts/doc/src/driver.xml
index 006a6160de..db455312ec 100644
--- a/erts/doc/src/driver.xml
+++ b/erts/doc/src/driver.xml
@@ -196,11 +196,14 @@ static ErlDrvData start(ErlDrvPort port, char *command)
<p>We call disconnect to log out from the database.
(This should have been done from Erlang, but just in case.)</p>
<code type="none"><![CDATA[
- static int do_disconnect(our_data_t* data, ei_x_buff* x);
+static int do_disconnect(our_data_t* data, ei_x_buff* x);
static void stop(ErlDrvData drv_data)
{
- do_disconnect((our_data_t*)drv_data, NULL);
+ our_data_t* data = (our_data_t*)drv_data;
+
+ do_disconnect(data, NULL);
+ driver_free(data);
}
]]></code>
<p>We use the binary format only to return data to the emulator;
diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml
index e71b48bd92..dfddbb18ea 100644
--- a/erts/doc/src/driver_entry.xml
+++ b/erts/doc/src/driver_entry.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2010</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -36,7 +36,7 @@
<description>
<p>As of erts version 5.5.3 the driver interface has been extended
(see <seealso marker="driver_entry#extended_marker">extended marker</seealso>).
- The extended interface introduce
+ The extended interface introduces
<seealso marker="erl_driver#version_management">version management</seealso>,
the possibility to pass capability flags
(see <seealso marker="driver_entry#driver_flags">driver flags</seealso>)
@@ -45,21 +45,21 @@
<note>
<p>Old drivers (compiled with an <c>erl_driver.h</c> from an
earlier erts version than 5.5.3) have to be recompiled
- (but does not have to use the extended interface).</p>
+ (but do not have to use the extended interface).</p>
</note>
<p>The <c>driver_entry</c> structure is a C struct that all erlang
- drivers defines. It contains entry points for the erlang driver
+ drivers define. It contains entry points for the erlang driver
that are called by the erlang emulator when erlang code accesses
the driver.</p>
<p>
<marker id="emulator"></marker>
The <seealso marker="driver_entry">erl_driver</seealso> driver
- API functions needs a port handle
+ API functions need a port handle
that identifies the driver instance (and the port in the
emulator). This is only passed to the <c>start</c> function, but
not to the other functions. The <c>start</c> function returns a
driver-defined handle that is passed to the other functions. A
- common practice is to have the <c>start</c> function allocating
+ common practice is to have the <c>start</c> function allocate
some application-defined structure and stash the <c>port</c>
handle in it, to use it later with the driver API functions.</p>
<p>The driver call-back functions are called synchronously from the
@@ -172,7 +172,7 @@ typedef struct erl_drv_entry {
added to the driver list.) The driver should return 0, or if
the driver can't initialize, -1.</p>
</item>
- <tag><marker id="start"/>int (*start)(ErlDrvPort port, char* command)</tag>
+ <tag><marker id="start"/>ErlDrvData (*start)(ErlDrvPort port, char* command)</tag>
<item>
<p>This is called when the driver is instantiated, when
<c>open_port/2</c> is called. The driver should return a
@@ -188,7 +188,9 @@ typedef struct erl_drv_entry {
<p>This is called when the port is closed, with
<c>port_close/1</c> or <c>Port ! {self(), close}</c>. Note
that terminating the port owner process also closes the
- port.</p>
+ port. If <c>drv_data</c> is a pointer to memory allocated in
+ <c>start</c>, then <c>stop</c> is the place to deallocate that
+ memory.</p>
</item>
<tag><marker id="output"/>void (*output)(ErlDrvData drv_data, char *buf, int len)</tag>
<item>
@@ -217,6 +219,10 @@ typedef struct erl_drv_entry {
completes, write to the pipe (use <c>SetEvent</c> on
Windows), this will make the emulator call
<c>ready_input</c> or <c>ready_output</c>.</p>
+ <p>Spurious events may happen. That is, calls to <c>ready_input</c>
+ or <c>ready_output</c> even though no real events are signaled. In
+ reality it should be rare (and OS dependant), but a robust driver
+ must nevertheless be able to handle such cases.</p>
</item>
<tag><marker id="driver_name"/>char *driver_name</tag>
<item>
@@ -233,7 +239,7 @@ typedef struct erl_drv_entry {
</item>
<tag>void *handle</tag>
<item>
- <p>This field is reserved for the emulators internal use. The
+ <p>This field is reserved for the emulator's internal use. The
emulator will modify this field; therefore, it is important
that the <c>driver_entry</c> isn't declared <c>const</c>.</p>
</item>
@@ -397,7 +403,7 @@ typedef struct erl_drv_entry {
<tag>void *handle2</tag>
<item>
<p>
- This field is reserved for the emulators internal use. The
+ This field is reserved for the emulator's internal use. The
emulator will modify this field; therefore, it is important
that the <c>driver_entry</c> isn't declared <c>const</c>.
</p>
diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml
index f01cf90a36..474230cb38 100644
--- a/erts/doc/src/epmd.xml
+++ b/erts/doc/src/epmd.xml
@@ -119,7 +119,7 @@
<tag><c><![CDATA[-port No]]></c></tag>
<item>
<p>Let this instance of epmd listen to another TCP port than
- default 4369. This can be also be set using the
+ default 4369. This can also be set using the
<c><![CDATA[ERL_EPMD_PORT]]></c> environment variable, see the
section <seealso marker="#environment_variables">Environment
variables</seealso> below</p>
@@ -186,7 +186,7 @@
<tag><c><![CDATA[-port No]]></c></tag>
<item>
<p>Contacts the <c>epmd</c> listening on the given TCP port number
- (default 4369). This can be also be set using the
+ (default 4369). This can also be set using the
<c><![CDATA[ERL_EPMD_PORT]]></c> environment variable, see the
section <seealso marker="#environment_variables">Environment
variables</seealso> below</p>
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index e36d0adb0d..1e6e290f6b 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -231,7 +231,8 @@
<tag><c><![CDATA[-detached]]></c></tag>
<item>
<p>Starts the Erlang runtime system detached from the system
- console. Useful for running daemons and backgrounds processes.</p>
+ console. Useful for running daemons and backgrounds processes. Implies
+ <c><![CDATA[-noinput]]></c>.</p>
</item>
<tag><c><![CDATA[-emu_args]]></c></tag>
<item>
@@ -541,6 +542,28 @@
<p>Calling <c>erlang:halt/1</c> with a string argument will still
produce a crash dump.</p>
</item>
+ <tag><c><![CDATA[+e Number]]></c></tag>
+ <item>
+ <p>Set max number of ETS tables.</p>
+ </item>
+ <tag><c><![CDATA[+ec]]></c></tag>
+ <item>
+ <p>Force the <c>compressed</c> option on all ETS tables.
+ Only intended for test and evaluation.</p>
+ </item>
+ <tag><c><![CDATA[+fnl]]></c></tag>
+ <item>
+ <p>The VM works with file names as if they are encoded using the ISO-latin-1 encoding, disallowing Unicode characters with codepoints beyond 255. This is default on operating systems that have transparent file naming, i.e. all Unixes except MacOSX.</p>
+ </item>
+ <tag><c><![CDATA[+fnu]]></c></tag>
+ <item>
+ <p>The VM works with file names as if they are encoded using UTF-8 (or some other system specific Unicode encoding). This is the default on operating systems that enforce Unicode encoding, i.e. Windows and MacOSX.</p>
+ <p>By enabling Unicode file name translation on systems where this is not default, you open up to the possibility that some file names can not be interpreted by the VM and therefore will be returned to the program as raw binaries. The option is therefore considered experimental.</p>
+ </item>
+ <tag><c><![CDATA[+fna]]></c></tag>
+ <item>
+ <p>Selection between <c>+fnl</c> and <c>+fnu</c> is done based on the current locale settings in the OS, meaning that if you have set your terminal for UTF-8 encoding, the filesystem is expected to use the same encoding for filenames (use with care).</p>
+ </item>
<tag><c><![CDATA[+hms Size]]></c></tag>
<item>
<p>Sets the default heap size of processes to the size
@@ -686,7 +709,7 @@
</p></item>
</taglist>
<p>Binding of schedulers is currently only supported on newer
- Linux, Solaris, and Windows systems.</p>
+ Linux, Solaris, FreeBSD, and Windows systems.</p>
<p>If no CPU topology is available when the <c>+sbt</c> flag
is processed and <c>BindType</c> is any other type than
<c>u</c>, the runtime system will fail to start. CPU
@@ -906,6 +929,25 @@
<seealso marker="kernel:error_logger#warning_map/0">error_logger(3)</seealso>
for further information.</p>
</item>
+ <tag><c><![CDATA[+zFlag Value]]></c></tag>
+ <item>
+ <p>Miscellaneous flags.</p>
+ <taglist>
+ <tag><marker id="+zdbbl"><c>+zdbbl size</c></marker></tag>
+ <item>
+ <p>Set the distribution buffer busy limit
+ (<seealso marker="erlang#system_info_dist_buf_busy_limit">dist_buf_busy_limit</seealso>)
+ in kilobytes. Valid range is 1-2097151. Default is 1024.</p>
+ <p>A larger buffer limit will allow processes to buffer
+ more outgoing messages over the distribution. When the
+ buffer limit has been reached, sending processes will be
+ suspended until the buffer size has shrunk. The buffer
+ limit is per distribution channel. A higher limit will
+ give lower latency and higher throughput at the expense
+ of higher memory usage.</p>
+ </item>
+ </taglist>
+ </item>
</taglist>
</section>
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 27887cbdf6..5987ddbd5e 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2010</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -464,7 +464,7 @@ typedef enum {
</section>
<funcs>
- <func><name><ret>void*</ret><nametext>enif_alloc(ErlNifEnv* env, size_t size)</nametext></name>
+ <func><name><ret>void*</ret><nametext>enif_alloc(size_t size)</nametext></name>
<fsummary>Allocate dynamic memory.</fsummary>
<desc><p>Allocate memory of <c>size</c> bytes. Return NULL if allocation failed.</p></desc>
</func>
@@ -539,7 +539,7 @@ typedef enum {
<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>
+ <func><name><ret>void</ret><nametext>enif_free(void* ptr)</nametext></name>
<fsummary>Free dynamic memory</fsummary>
<desc><p>Free memory allocated by <c>enif_alloc</c>.</p></desc>
</func>
@@ -857,11 +857,6 @@ typedef enum {
<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
@@ -980,11 +975,12 @@ 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(ErlNifBinary* bin, size_t size)</nametext></name>
+ <func><name><ret>int</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>
+ a mutable copy is allocated and assigned to <c>*bin</c>. Return true on success,
+ false if memory allocation failed.</p></desc>
</func>
<func><name><ret>void</ret><nametext>enif_release_binary(ErlNifBinary* bin)</nametext></name>
<fsummary>Release a binary.</fsummary>
@@ -1041,7 +1037,12 @@ typedef enum {
<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_send(ErlNifEnv* env, ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg)</nametext></name>
+ <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>int</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>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 59ac3dc66c..78d58a1e56 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -2781,14 +2781,17 @@ os_prompt%</pre>
<name>open_port(PortName, PortSettings) -> port()</name>
<fsummary>Open a port</fsummary>
<type>
- <v>PortName = {spawn, Command} | {spawn_driver, Command} | {spawn_executable, Command} | {fd, In, Out}</v>
+ <v>PortName = {spawn, Command} | {spawn_driver, Command} | {spawn_executable, FileName} | {fd, In, Out}</v>
<v>&nbsp;Command = string()</v>
+ <v>&nbsp;FileName = [ FileNameChar ] | binary()</v>
+ <v>&nbsp;FileNameChar = int() (1..255 or any Unicode codepoint, see description)</v>
<v>&nbsp;In = Out = int()</v>
<v>PortSettings = [Opt]</v>
- <v>&nbsp;Opt = {packet, N} | stream | {line, L} | {cd, Dir} | {env, Env} | {args, [ string() ]} | {arg0, string()} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof</v>
+ <v>&nbsp;Opt = {packet, N} | stream | {line, L} | {cd, Dir} | {env, Env} | {args, [ ArgString ]} | {arg0, ArgString} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof</v>
<v>&nbsp;&nbsp;N = 1 | 2 | 4</v>
<v>&nbsp;&nbsp;L = int()</v>
<v>&nbsp;&nbsp;Dir = string()</v>
+ <v>&nbsp;&nbsp;ArgString = [ FileNameChar ] | binary()</v>
<v>&nbsp;&nbsp;Env = [{Name, Val}]</v>
<v>&nbsp;&nbsp;&nbsp;Name = string()</v>
<v>&nbsp;&nbsp;&nbsp;Val = string() | false</v>
@@ -2851,7 +2854,26 @@ os_prompt%</pre>
executed, the appropriate command interpreter will
implicitly be invoked, but there will still be no
command argument expansion or implicit PATH search.</p>
-
+
+ <p>The name of the executable as well as the arguments
+ given in <c>args</c> and <c>arg0</c> is subject to
+ Unicode file name translation if the system is running
+ in Unicode file name mode. To avoid
+ translation or force i.e. UTF-8, supply the executable
+ and/or arguments as a binary in the correct
+ encoding. See the <seealso
+ marker="kernel:file">file</seealso> module, the
+ <seealso marker="kernel:file#native_name_encoding/0">
+ file:native_name_encoding/0</seealso> function and the
+ <seealso marker="stdlib:unicode_usage">stdlib users guide
+ </seealso> for details.</p>
+
+ <note>The characters in the name (if given as a list)
+ can only be &gt; 255 if the Erlang VM is started in
+ Unicode file name translation mode, otherwise the name
+ of the executable is limited to the ISO-latin-1
+ character set.</note>
+
<p>If the <c>Command</c> cannot be run, an error
exception, with the posix error code as the reason, is
raised. The error reason may differ between operating
@@ -2954,6 +2976,21 @@ os_prompt%</pre>
should not be given in this list. The proper executable name will
automatically be used as argv[0] where applicable.</p>
+ <p>When the Erlang VM is running in Unicode file name
+ mode, the arguments can contain any Unicode characters and
+ will be translated into whatever is appropriate on the
+ underlying OS, which means UTF-8 for all platforms except
+ Windows, which has other (more transparent) ways of
+ dealing with Unicode arguments to programs. To avoid
+ Unicode translation of arguments, they can be supplied as
+ binaries in whatever encoding is deemed appropriate.</p>
+
+ <note>The characters in the arguments (if given as a
+ list of characters) can only be &gt; 255 if the Erlang
+ VM is started in Unicode file name mode,
+ otherwise the arguments are limited to the
+ ISO-latin-1 character set.</note>
+
<p>If one, for any reason, wants to explicitly set the
program name in the argument vector, the <c>arg0</c>
option can be used.</p>
@@ -2969,6 +3006,9 @@ os_prompt%</pre>
responds to this is highly system dependent and no specific
effect is guaranteed.</p>
+ <p>The unicode file name translation rules of the
+ <c>args</c> option apply to this option as well.</p>
+
</item>
<tag><c>exit_status</c></tag>
@@ -5178,7 +5218,7 @@ true</pre>
<seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
</p>
<p>Schedulers can currently only be bound on newer Linux,
- Solaris, and Windows systems, but more systems will be
+ Solaris, FreeBSD, and Windows systems, but more systems will be
supported in the future.
</p>
<p>In order for the runtime system to be able to bind schedulers,
@@ -5559,7 +5599,7 @@ true</pre>
<item>
<p>Returns the automatically detected <c>CpuTopology</c>. The
emulator currently only detects the CPU topology on some newer
- Linux, Solaris, and Windows systems. On Windows system with
+ Linux, Solaris, FreeBSD, and Windows systems. On Windows system with
more than 32 logical processors the CPU topology is not detected.
</p>
<p>For more information see the documentation of the
@@ -5624,6 +5664,13 @@ true</pre>
The return value will always be <c>false</c> since
the elib_malloc allocator has been removed.</p>
</item>
+ <tag><marker id="system_info_dist_buf_busy_limit"><c>dist_buf_busy_limit</c></marker></tag>
+ <item>
+ <p>Returns the value of the distribution buffer busy limit
+ in bytes. This limit can be set on startup by passing the
+ <seealso marker="erl#+zdbbl">+zdbbl</seealso> command line
+ flag to <c>erl</c>.</p>
+ </item>
<tag><c>fullsweep_after</c></tag>
<item>
<p>Returns <c>{fullsweep_after, int()}</c> which is the
diff --git a/erts/doc/src/erlc.xml b/erts/doc/src/erlc.xml
index 1e8960c22c..ebf76a2afe 100644
--- a/erts/doc/src/erlc.xml
+++ b/erts/doc/src/erlc.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1997</year><year>2010</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -141,6 +141,50 @@
for compiling native code, which needs to be compiled with the same
run-time system that it should be run on.</p>
</item>
+ <tag>-M</tag>
+ <item>
+ <p>Produces a Makefile rule to track headers dependencies. The
+ rule is sent to stdout. No object file is produced.
+ </p>
+ </item>
+ <tag>-MF <em>Makefile</em></tag>
+ <item>
+ <p>Like the <c><![CDATA[-M]]></c> option above, except that the
+ Makefile is written to <em>Makefile</em>. No object
+ file is produced.
+ </p>
+ </item>
+ <tag>-MD</tag>
+ <item>
+ <p>Same as <c><![CDATA[-M -MF <File>.Pbeam]]></c>.
+ </p>
+ </item>
+ <tag>-MT <em>Target</em></tag>
+ <item>
+ <p>In conjunction with <c><![CDATA[-M]]></c> or
+ <c><![CDATA[-MF]]></c>, change the name of the rule emitted
+ to <em>Target</em>.
+ </p>
+ </item>
+ <tag>-MQ <em>Target</em></tag>
+ <item>
+ <p>Like the <c><![CDATA[-MT]]></c> option above, except that
+ characters special to make(1) are quoted.
+ </p>
+ </item>
+ <tag>-MP</tag>
+ <item>
+ <p>In conjunction with <c><![CDATA[-M]]></c> or
+ <c><![CDATA[-MF]]></c>, add a phony target for each dependency.
+ </p>
+ </item>
+ <tag>-MG</tag>
+ <item>
+ <p>In conjunction with <c><![CDATA[-M]]></c> or
+ <c><![CDATA[-MF]]></c>, consider missing headers as generated
+ files and add them to the dependencies.
+ </p>
+ </item>
<tag>--</tag>
<item>
<p>Signals that no more options will follow.
diff --git a/erts/doc/src/escript.xml b/erts/doc/src/escript.xml
index 44c9a5ac68..588508aae6 100644
--- a/erts/doc/src/escript.xml
+++ b/erts/doc/src/escript.xml
@@ -153,7 +153,10 @@ halt(1).</pre>
<p>Execution of interpreted code is slower than compiled code.
If much of the execution takes place in interpreted code it
may be worthwhile to compile it, even though the compilation
- itself will take a little while.</p>
+ itself will take a little while. It is also possible to supply
+ <c>native</c> instead of compile, this will compile the script
+ using the native flag, again depending on the characteristics
+ of the escript this could or could not be worth while.</p>
<p>As mentioned earlier, it is possible to have a script which
contains precompiled <c>beam</c> code. In a precompiled
@@ -397,6 +400,9 @@ ok
Warnings and errors (if any) are written to the standard output, but
the script will not be run. The exit status will be 0 if there were
no errors, and 127 otherwise.</item>
+
+ <tag>-n</tag>
+ <item>Compile the escript using the +native flag.</item>
</taglist>
</section>
</comref>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index efe2dada9c..77181d3407 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -30,6 +30,321 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 5.8.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix format_man_pages so it handles all man sections
+ and remove warnings/errors in various man pages. </p>
+ <p>
+ Own Id: OTP-8600</p>
+ </item>
+ <item>
+ <p>
+ The <c>configure</c> command line argument <seealso
+ marker="doc/installation_guide:INSTALL#How-to-Build-and-Install-ErlangOTP_A-Closer-Look-at-the-individual-Steps_Configuring">--enable-ethread-pre-pentium4-compatibility</seealso>
+ had no effect. This option is now also automatically
+ enabled if required on the build machine.</p>
+ <p>
+ Own Id: OTP-8847</p>
+ </item>
+ <item>
+ <p>
+ Windows 2003 and Windows XP pre SP3 would sometimes not
+ start the Erlang R14B VM at all due to a bug in the cpu
+ topology detection. The bug affects Windows only, no
+ other platform is even remotely affected. The bug is now
+ corrected.</p>
+ <p>
+ Own Id: OTP-8876</p>
+ </item>
+ <item>
+ <p>
+ The HiPE run-time in the 64-bit emulator could do a
+ 64-bit write to a 32-bit struct field. It happened to be
+ harmless on Intel/AMD processors. Corrected. (Thanks to
+ Mikael Pettersson.)</p>
+ <p>
+ Own Id: OTP-8877</p>
+ </item>
+ <item>
+ <p>
+ A bug in <seealso
+ marker="erl_driver#erl_drv_tsd_get">erl_drv_tsd_get()</seealso>
+ and <seealso
+ marker="erl_nif#enif_tsd_get">enif_tsd_get()</seealso>
+ could cause an emulator crash. These functions are
+ currently not used in OTP. That is, the crash only occur
+ on systems with user implemented NIF libraries, or
+ drivers that use one of these functions.</p>
+ <p>
+ Own Id: OTP-8889</p>
+ </item>
+ <item>
+ <p>
+ Calling <c>erlang:system_info({cpu_topology,
+ CpuTopologyType})</c> with another <c>CpuTopologyType</c>
+ element than one of the documented atoms <c>defined</c>,
+ <c>detected</c>, or <c>used</c> caused an emulator crash.
+ (Thanks to Paul Guyot)</p>
+ <p>
+ Own Id: OTP-8914</p>
+ </item>
+ <item>
+ <p>
+ The ERTS internal rwlock implementation could get into an
+ inconsistent state. This bug was very seldom triggered,
+ but could be during heavy contention. The bug was
+ introduced in R14B (erts-5.8.1).</p>
+ <p>
+ The bug was most likely to be triggered when using the
+ <c>read_concurrency</c> option on an ETS table that was
+ frequently accessed from multiple processes doing lots of
+ writes and reads. That is, in a situation where you
+ typically don't want to use the <c>read_concurrency</c>
+ option in the first place.</p>
+ <p>
+ Own Id: OTP-8925 Aux Id: OTP-8544 </p>
+ </item>
+ <item>
+ <p>
+ Tracing to port could cause an emulator crash when
+ unloading the trace driver.</p>
+ <p>
+ Own Id: OTP-8932</p>
+ </item>
+ <item>
+ <p>
+ Removed use of CancelIoEx on Windows that had been shown
+ to cause problems with some drivers.</p>
+ <p>
+ Own Id: OTP-8937</p>
+ </item>
+ <item>
+ <p>
+ The fallback implementation used when no native atomic
+ implementation was found did not compile. (Thanks to
+ Patrick Baggett, and Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-8944</p>
+ </item>
+ <item>
+ <p>
+ Some integer values used during load balancing could
+ under rare circumstances wrap causing a load unbalance
+ between schedulers.</p>
+ <p>
+ Own Id: OTP-8950</p>
+ </item>
+ <item>
+ <p>
+ The windows VM now correctly handles appending to large
+ files (> 4GB).</p>
+ <p>
+ Own Id: OTP-8958</p>
+ </item>
+ <item>
+ <p>
+ Name resolving of IPv6 addresses has been implemented for
+ Windows versions that support it. The use of ancient
+ resolver flags (AI_V4MAPPED | AI_ADDRCONFIG) to the
+ getaddrinfo() function has been removed since e.g FreeBSD
+ regard mapped IPv4 addresses to be a security problem and
+ the semantics of the address configured flag is
+ uncertain.</p>
+ <p>
+ Own Id: OTP-8969</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The help texts produced by the <c>configure</c> scripts
+ in the top directory and in the erts directory have been
+ aligned and cleaned up.</p>
+ <p>
+ Own Id: OTP-8859</p>
+ </item>
+ <item>
+ <p>
+ When the runtime system had fewer schedulers than logical
+ processors, the system could get an unnecessarily large
+ amount reader groups.</p>
+ <p>
+ Own Id: OTP-8861</p>
+ </item>
+ <item>
+ <p>
+ <c>run_rel</c> has been updated to support Solaris's
+ /dev/ptmx device and to load the necessary STREAMS
+ modules so that <c>to_erl</c> can provide terminal echo
+ of keyboard input. (Thanks to Ryan Tilder.)</p>
+ <p>
+ Own Id: OTP-8878</p>
+ </item>
+ <item>
+ <p>
+ The Erlang VM now supports Unicode filenames. The feature
+ is turned on by default on systems where Unicode
+ filenames are mandatory (Windows and MacOSX), but can be
+ enabled on other systems with the '+fnu' emulator option.
+ Enabling the Unicode filename feature on systems where it
+ is not default is however considered experimental and not
+ to be used for production. Together with the Unicode file
+ name support, the concept of "raw filenames" is
+ introduced, which means filenames provided without
+ implicit unicode encoding translation. Raw filenames are
+ provided as binaries, not lists. For further information,
+ see stdlib users guide and the chapter about using
+ Unicode in Erlang. Also see the file module manual page.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8887</p>
+ </item>
+ <item>
+ <p>Buffer overflows have been prevented in <c>erlc</c>,
+ <c>dialyzer</c>, <c>typer</c>, <c>run_test</c>,
+ <c>heart</c>, <c>escript</c>, and <c>erlexec</c>.</p>
+ (Thanks to Michael Santos.)
+ <p>
+ Own Id: OTP-8892</p>
+ </item>
+ <item>
+ <p>
+ The runtime system is now less eager to suspend processes
+ sending messages over the distribution. The default value
+ of the distribution buffer busy limit has also been
+ increased from 128 KB to 1 MB. This in order to improve
+ throughput.</p>
+ <p>
+ Own Id: OTP-8901</p>
+ </item>
+ <item>
+ <p>
+ The distribution buffer busy limit can now be configured
+ at system startup. For more information see the
+ documentation of the <c>erl</c> <seealso
+ marker="erl#+zdbbl">+zdbbl</seealso> command line flag.
+ (Thanks to Scott Lystig Fritchie)</p>
+ <p>
+ Own Id: OTP-8912</p>
+ </item>
+ <item>
+ <p>
+ The inet driver internal buffer stack implementation has
+ been rewritten in order to reduce lock contention.</p>
+ <p>
+ Own Id: OTP-8916</p>
+ </item>
+ <item>
+ <p>
+ New ETS option <c>compressed</c>, to enable a more
+ compact storage format at the expence of heavier table
+ operations. For test and evaluation, <c>erl +ec</c> can
+ be used to force compression on all ETS tables.</p>
+ <p>
+ Own Id: OTP-8922 Aux Id: seq11658 </p>
+ </item>
+ <item>
+ <p>
+ There is now a new function inet:getifaddrs/0 modeled
+ after C library function getifaddrs() on BSD and LInux
+ that reports existing interfaces and their addresses on
+ the host. This replaces the undocumented and unsupported
+ inet:getiflist/0 and inet:ifget/2.</p>
+ <p>
+ Own Id: OTP-8926</p>
+ </item>
+ <item>
+ <p>
+ Support for detection of CPU topology and binding of
+ schedulers on FreeBSD 8 have been added. (Thanks to Paul
+ Guyot)</p>
+ <p>
+ Own Id: OTP-8939</p>
+ </item>
+ <item>
+ <p>
+ Several bugs related to hibernate/3 and HiPE have been
+ corrected. (Thanks to Paul Guyot.)</p>
+ <p>
+ Own Id: OTP-8952</p>
+ </item>
+ <item>
+ <p>
+ Support for soft and hard links on Windows versions and
+ filesystems that support them is added.</p>
+ <p>
+ Own Id: OTP-8955</p>
+ </item>
+ <item>
+ <p>
+ The win32 virtual machine is now linked large address
+ aware. his allows the Erlang VM to use up to 3 gigs of
+ address space on Windows instead of the default of 2
+ gigs.</p>
+ <p>
+ Own Id: OTP-8956</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.8.1.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix that the documentation top index generator can
+ handle an Ericsson internal application group. </p>
+ <p>
+ Own Id: OTP-8875</p>
+ </item>
+ <item>
+ <p>In embedded mode, on_load handlers that called
+ <c>code:priv_dir/1</c> or other functions in <c>code</c>
+ would hang the system. Since the <c>crypto</c>
+ application now contains an on_loader handler that calls
+ <c>code:priv_dir/1</c>, including the <c>crypto</c>
+ application in the boot file would prevent the system
+ from starting.</p>
+ <p>Also extended the <c>-init_debug</c> option to print
+ information about on_load handlers being run to
+ facilitate debugging.</p>
+ <p>
+ Own Id: OTP-8902 Aux Id: seq11703 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.8.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Windows 2003 and Windows XP pre SP3 would sometimes not
+ start the Erlang R14B VM at all due to a bug in the cpu
+ topology detection. The bug affects Windows only, no
+ other platform is even remotely affected. The bug is now
+ corrected.</p>
+ <p>
+ Own Id: OTP-8876</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 5.8.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index 903abe6f5c..f04df354a8 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -505,8 +505,10 @@ ifdef HIPE_ENABLED
OPCODE_TABLES += hipe/hipe_ops.tab
endif
-$(TTF_DIR)/beam_opcodes.h $(TTF_DIR)/beam_opcodes.c: $(OPCODE_TABLES)
- LANG=C $(PERL) utils/beam_makeops -outdir $(TTF_DIR) \
+$(TTF_DIR)/beam_opcodes.h $(TTF_DIR)/beam_opcodes.c: $(OPCODE_TABLES) utils/beam_makeops
+ LANG=C $(PERL) utils/beam_makeops \
+ -wordsize @EXTERNAL_WORD_SIZE@ \
+ -outdir $(TTF_DIR) \
-emulator $(OPCODE_TABLES)
# bif and atom table
@@ -531,8 +533,9 @@ TABLES= $(TARGET)/erl_bif_table.c $(TARGET)/erl_bif_table.h \
$(TARGET)/erl_atom_table.c $(TARGET)/erl_atom_table.h \
$(TARGET)/erl_pbifs.c
-$(TABLES): $(ATOMS) $(BIFS)
- LANG=C $(PERL) utils/make_tables -src $(TARGET) -include $(TARGET) $^
+$(TABLES): $(ATOMS) $(BIFS) utils/make_tables
+ LANG=C $(PERL) utils/make_tables -src $(TARGET) -include $(TARGET)\
+ $(ATOMS) $(BIFS)
$(TTF_DIR)/erl_alloc_types.h: beam/erl_alloc.types utils/make_alloc_types
LANG=C $(PERL) utils/make_alloc_types -src $< -dst $@ $(ENABLE_ALLOC_TYPE_VARS)
@@ -733,7 +736,7 @@ RUN_OBJS = \
$(OBJDIR)/erl_fun.o $(OBJDIR)/erl_bif_port.o \
$(OBJDIR)/erl_term.o $(OBJDIR)/erl_node_tables.o \
$(OBJDIR)/erl_monitors.o $(OBJDIR)/erl_process_dump.o \
- $(OBJDIR)/erl_bif_timer.o \
+ $(OBJDIR)/erl_bif_timer.o $(OBJDIR)/erl_cpu_topology.o \
$(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 \
@@ -795,7 +798,8 @@ endif
OS_OBJS += $(OBJDIR)/erl_mseg.o \
$(OBJDIR)/erl_$(ERLANG_OSTYPE)_sys_ddll.o \
- $(OBJDIR)/erl_mtrace_sys_wrap.o
+ $(OBJDIR)/erl_mtrace_sys_wrap.o \
+ $(OBJDIR)/erl_sys_common_misc.o
HIPE_x86_OS_OBJS=$(HIPE_x86_$(OPSYS)_OBJS)
HIPE_x86_OBJS=$(OBJDIR)/hipe_x86.o $(OBJDIR)/hipe_x86_glue.o $(OBJDIR)/hipe_x86_bifs.o $(OBJDIR)/hipe_x86_signal.o $(OBJDIR)/hipe_x86_stack.o $(HIPE_x86_OS_OBJS)
diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c
index 682f31b83f..31910888d1 100644
--- a/erts/emulator/beam/beam_bp.c
+++ b/erts/emulator/beam/beam_bp.c
@@ -950,8 +950,8 @@ static int set_function_break(Module *modp, BeamInstr *pc, int bif,
MatchSetUnref(old_match_spec);
} else {
BpDataCount *bdc = (BpDataCount *) bd;
- long count = 0;
- long res = 0;
+ erts_aint_t count = 0;
+ erts_aint_t res = 0;
ASSERT(! match_spec);
ASSERT(is_nil(tracer_pid));
diff --git a/erts/emulator/beam/beam_bp.h b/erts/emulator/beam/beam_bp.h
index ebc171078d..bd8a7249a7 100644
--- a/erts/emulator/beam/beam_bp.h
+++ b/erts/emulator/beam/beam_bp.h
@@ -157,7 +157,7 @@ do { \
BpData **bds = (BpData **) (pc)[-4]; \
BpDataCount *bdc = NULL; \
Uint ix = bp_sched2ix_proc( (p) ); \
- long count = 0; \
+ erts_aint_t count = 0; \
\
ASSERT((pc)[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); \
ASSERT(bds); \
diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c
index b0bf14b94f..2855241b91 100644
--- a/erts/emulator/beam/beam_debug.c
+++ b/erts/emulator/beam/beam_debug.c
@@ -48,7 +48,6 @@
void dbg_bt(Process* p, Eterm* sp);
void dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg);
-static void print_big(int to, void *to_arg, Eterm* addr);
static int print_op(int to, void *to_arg, int op, int size, BeamInstr* addr);
Eterm
erts_debug_same_2(Process* p, Eterm term1, Eterm term2)
@@ -157,6 +156,25 @@ void debug_dump_code(BeamInstr *I, int num)
}
#endif
+BIF_RETTYPE
+erts_debug_instructions_0(BIF_ALIST_0)
+{
+ int i = 0;
+ Uint needed = num_instructions * 2;
+ Eterm* hp;
+ Eterm res = NIL;
+
+ for (i = 0; i < num_instructions; i++) {
+ needed += 2*strlen(opc[i].name);
+ }
+ hp = HAlloc(BIF_P, needed);
+ for (i = num_instructions-1; i >= 0; i--) {
+ Eterm s = erts_bld_string_n(&hp, 0, opc[i].name, strlen(opc[i].name));
+ res = erts_bld_cons(&hp, 0, s, res);
+ }
+ return res;
+}
+
Eterm
erts_debug_disassemble_1(Process* p, Eterm addr)
{
@@ -312,6 +330,7 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
BeamInstr packed = 0; /* Accumulator for packed operations. */
BeamInstr args[8]; /* Arguments for this instruction. */
BeamInstr* ap; /* Pointer to arguments. */
+ BeamInstr* unpacked; /* Unpacked arguments */
start_prog = opc[op].pack;
@@ -360,6 +379,12 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
*ap++ = packed & BEAM_LOOSE_MASK;
packed >>= BEAM_LOOSE_SHIFT;
break;
+#ifdef ARCH_64
+ case 'w': /* Shift 32 steps */
+ *ap++ = packed & BEAM_WIDE_MASK;
+ packed >>= BEAM_WIDE_SHIFT;
+ break;
+#endif
case 'p':
*sp++ = *--ap;
break;
@@ -386,7 +411,7 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
break;
case 'x': /* x(N) */
if (reg_index(ap[0]) == 0) {
- erts_print(to, to_arg, "X[0]");
+ erts_print(to, to_arg, "x[0]");
} else {
erts_print(to, to_arg, "x(%d)", reg_index(ap[0]));
}
@@ -506,6 +531,7 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
ap++;
break;
case 'P': /* Byte offset into tuple (see beam_load.c) */
+ case 'Q': /* Like 'P', but packable */
erts_print(to, to_arg, "%d", (*ap / sizeof(Eterm)) - 1);
ap++;
break;
@@ -526,9 +552,12 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
* Print more information about certain instructions.
*/
+ unpacked = ap;
ap = addr + size;
switch (op) {
- case op_i_select_val_sfI:
+ case op_i_select_val_rfI:
+ case op_i_select_val_xfI:
+ case op_i_select_val_yfI:
{
int n = ap[-1];
@@ -540,7 +569,24 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
}
}
break;
- case op_i_jump_on_val_sfII:
+ case op_i_select_tuple_arity_rfI:
+ case op_i_select_tuple_arity_xfI:
+ case op_i_select_tuple_arity_yfI:
+ {
+ int n = ap[-1];
+
+ while (n > 0) {
+ Uint arity = arityval(ap[0]);
+ erts_print(to, to_arg, " {%d} f(" HEXF ")", arity, ap[1]);
+ ap += 2;
+ size += 2;
+ n--;
+ }
+ }
+ break;
+ case op_i_jump_on_val_rfII:
+ case op_i_jump_on_val_xfII:
+ case op_i_jump_on_val_yfII:
{
int n;
for (n = ap[-2]; n > 0; n--) {
@@ -550,39 +596,46 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
}
}
break;
- case op_i_select_big_sf:
- while (ap[0]) {
- Eterm *bigp = (Eterm *) ap;
- int arity = thing_arityval(*bigp);
- print_big(to, to_arg, bigp);
- size += TermWords(arity+1);
- ap += TermWords(arity+1);
- erts_print(to, to_arg, " f(" HEXF ") ", ap[0]);
- ap++;
- size++;
+ case op_i_jump_on_val_zero_rfI:
+ case op_i_jump_on_val_zero_xfI:
+ case op_i_jump_on_val_zero_yfI:
+ {
+ int n;
+ for (n = ap[-1]; n > 0; n--) {
+ erts_print(to, to_arg, "f(" HEXF ") ", ap[0]);
+ ap++;
+ size++;
+ }
+ }
+ break;
+ case op_i_put_tuple_rI:
+ case op_i_put_tuple_xI:
+ case op_i_put_tuple_yI:
+ {
+ int n = unpacked[-1];
+
+ while (n > 0) {
+ if (!is_header(ap[0])) {
+ erts_print(to, to_arg, " %T", (Eterm) ap[0]);
+ } else {
+ switch ((ap[0] >> 2) & 0x03) {
+ case R_REG_DEF:
+ erts_print(to, to_arg, " x(0)");
+ break;
+ case X_REG_DEF:
+ erts_print(to, to_arg, " x(%d)", ap[0] >> 4);
+ break;
+ case Y_REG_DEF:
+ erts_print(to, to_arg, " y(%d)", ap[0] >> 4);
+ break;
+ }
+ }
+ ap++, size++, n--;
+ }
}
- ap++;
- size++;
break;
}
erts_print(to, to_arg, "\n");
return size;
}
-
-static void
-print_big(int to, void *to_arg, Eterm* addr)
-{
- int i;
- int k;
-
- i = BIG_SIZE(addr);
- if (BIG_SIGN(addr))
- erts_print(to, to_arg, "-#integer(%d) = {", i);
- else
- erts_print(to, to_arg, "#integer(%d) = {", i);
- erts_print(to, to_arg, "0x%x", BIG_DIGIT(addr, 0));
- for (k = 1; k < i; k++)
- erts_print(to, to_arg, ",0x%x", BIG_DIGIT(addr, k));
- erts_print(to, to_arg, "}");
-}
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 8a0e12dd4f..a4fb454481 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -321,6 +321,7 @@ extern int count_instructions;
# define POST_BIF_GC_SWAPIN_0(_p, _res) \
ERTS_SMP_REQ_PROC_MAIN_LOCK((_p)); \
PROCESS_MAIN_CHK_LOCKS((_p)); \
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC((_p)); \
if (((_p)->mbuf) || (MSO(_p).overhead >= BIN_VHEAP_SZ(_p)) ) { \
_res = erts_gc_after_bif_call((_p), (_res), NULL, 0); \
E = (_p)->stop; \
@@ -328,6 +329,7 @@ extern int count_instructions;
HTOP = HEAP_TOP((_p))
# define POST_BIF_GC_SWAPIN(_p, _res, _regs, _arity) \
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC((_p)); \
ERTS_SMP_REQ_PROC_MAIN_LOCK((_p)); \
PROCESS_MAIN_CHK_LOCKS((_p)); \
if (((_p)->mbuf) || (MSO(_p).overhead >= BIN_VHEAP_SZ(_p)) ) { \
@@ -344,6 +346,8 @@ extern int count_instructions;
#define xb(N) (*(Eterm *) (((unsigned char *)reg) + (N)))
#define yb(N) (*(Eterm *) (((unsigned char *)E) + (N)))
#define fb(N) (*(double *) (((unsigned char *)&(freg[0].fd)) + (N)))
+#define Qb(N) (N)
+#define Ib(N) (N)
#define x(N) reg[N]
#define y(N) E[N]
#define r(N) x##N
@@ -365,6 +369,7 @@ extern int count_instructions;
reg[0] = r(0); \
PROCESS_MAIN_CHK_LOCKS(c_p); \
FCALLS -= erts_garbage_collect(c_p, needed + (HeapNeed), reg, (M)); \
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p); \
PROCESS_MAIN_CHK_LOCKS(c_p); \
r(0) = reg[0]; \
SWAPIN; \
@@ -418,6 +423,7 @@ extern int count_instructions;
reg[0] = r(0); \
PROCESS_MAIN_CHK_LOCKS(c_p); \
FCALLS -= erts_garbage_collect(c_p, need, reg, (Live)); \
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p); \
PROCESS_MAIN_CHK_LOCKS(c_p); \
r(0) = reg[0]; \
SWAPIN; \
@@ -440,6 +446,7 @@ extern int count_instructions;
reg[0] = r(0); \
PROCESS_MAIN_CHK_LOCKS(c_p); \
FCALLS -= erts_garbage_collect(c_p, need, reg, (Live)); \
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p); \
PROCESS_MAIN_CHK_LOCKS(c_p); \
r(0) = reg[0]; \
SWAPIN; \
@@ -462,6 +469,7 @@ extern int count_instructions;
reg[Live] = Extra; \
PROCESS_MAIN_CHK_LOCKS(c_p); \
FCALLS -= erts_garbage_collect(c_p, need, reg, (Live)+1); \
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p); \
PROCESS_MAIN_CHK_LOCKS(c_p); \
if (Live > 0) { \
r(0) = reg[0]; \
@@ -472,6 +480,13 @@ extern int count_instructions;
HEAP_SPACE_VERIFIED(need); \
} while (0)
+#define TestHeapPutList(Need, Reg) \
+ do { \
+ TestHeap((Need), 1); \
+ PutList(Reg, r(0), r(0), StoreSimpleDest); \
+ CHECK_TERM(r(0)); \
+ } while (0)
+
#ifdef HYBRID
#ifdef INCREMENTAL
#define TestGlobalHeap(Nh, Live, hp) \
@@ -516,6 +531,11 @@ extern int count_instructions;
SWAPIN; \
} while (0)
+#define PutTuple(Dst, Arity) \
+ do { \
+ Dst = make_tuple(HTOP); \
+ pt_arity = (Arity); \
+ } while (0)
/*
* Check that we haven't used the reductions and jump to function pointed to by
@@ -674,6 +694,11 @@ extern int count_instructions;
SET_I((BeamInstr *) CallDest); \
Dispatch();
+#define MoveJump(Src) \
+ r(0) = (Src); \
+ SET_I((BeamInstr *) Arg(0)); \
+ Goto(*I);
+
#define GetList(Src, H, T) do { \
Eterm* tmp_ptr = list_val(Src); \
H = CAR(tmp_ptr); \
@@ -723,16 +748,8 @@ extern int count_instructions;
(Dest) = (* (Eterm *) EXPAND_POINTER(tmp_arg1)); \
} while (0)
-#define PutTuple(Arity, Src, Dest) \
- ASSERT(is_arity_value(Arity)); \
- Dest = make_tuple(HTOP); \
- HTOP[0] = (Arity); \
- HTOP[1] = (Src); \
- HTOP += 2
-
-#define Put(Word) *HTOP++ = (Word)
-
#define EqualImmed(X, Y, Action) if (X != Y) { Action; }
+#define NotEqualImmed(X, Y, Action) if (X == Y) { Action; }
#define IsFloat(Src, Fail) if (is_not_float(Src)) { Fail; }
@@ -984,8 +1001,41 @@ extern int count_instructions;
#define IsPid(Src, Fail) if (is_not_pid(Src)) { Fail; }
#define IsRef(Src, Fail) if (is_not_ref(Src)) { Fail; }
-static BifFunction translate_gc_bif(void* gcf);
-static BeamInstr* handle_error(Process* c_p, BeamInstr* pc, Eterm* reg, BifFunction bf);
+/*
+ * process_main() is already huge, so we want to avoid inlining
+ * into it. Especially functions that are seldom used.
+ */
+#ifdef __GNUC__
+# define NOINLINE __attribute__((__noinline__))
+#else
+# define NOINLINE
+#endif
+
+/*
+ * The following functions are called directly by process_main().
+ * Don't inline them.
+ */
+static BifFunction translate_gc_bif(void* gcf) NOINLINE;
+static BeamInstr* handle_error(Process* c_p, BeamInstr* pc,
+ Eterm* reg, BifFunction bf) NOINLINE;
+static BeamInstr* call_error_handler(Process* p, BeamInstr* ip,
+ Eterm* reg, Eterm func) NOINLINE;
+static BeamInstr* fixed_apply(Process* p, Eterm* reg, Uint arity) NOINLINE;
+static BeamInstr* apply(Process* p, Eterm module, Eterm function,
+ Eterm args, Eterm* reg) NOINLINE;
+static int hibernate(Process* c_p, Eterm module, Eterm function,
+ Eterm args, Eterm* reg) NOINLINE;
+static BeamInstr* call_fun(Process* p, int arity,
+ Eterm* reg, Eterm args) NOINLINE;
+static BeamInstr* apply_fun(Process* p, Eterm fun,
+ Eterm args, Eterm* reg) NOINLINE;
+static Eterm new_fun(Process* p, Eterm* reg,
+ ErlFunEntry* fe, int num_free) NOINLINE;
+
+
+/*
+ * Functions not directly called by process_main(). OK to inline.
+ */
static BeamInstr* next_catch(Process* c_p, Eterm *reg);
static void terminate_proc(Process* c_p, Eterm Value);
static Eterm add_stacktrace(Process* c_p, Eterm Value, Eterm exc);
@@ -993,16 +1043,6 @@ static void save_stacktrace(Process* c_p, BeamInstr* pc, Eterm* reg,
BifFunction bf, Eterm args);
static struct StackTrace * get_trace_from_exc(Eterm exc);
static Eterm make_arglist(Process* c_p, Eterm* reg, int a);
-static Eterm call_error_handler(Process* p, BeamInstr* ip, Eterm* reg);
-static Eterm call_breakpoint_handler(Process* p, BeamInstr* fi, Eterm* reg);
-static BeamInstr* fixed_apply(Process* p, Eterm* reg, Uint arity);
-static BeamInstr* apply(Process* p, Eterm module, Eterm function,
- Eterm args, Eterm* reg);
-static int hibernate(Process* c_p, Eterm module, Eterm function,
- Eterm args, Eterm* reg);
-static BeamInstr* call_fun(Process* p, int arity, Eterm* reg, Eterm args);
-static BeamInstr* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg);
-static Eterm new_fun(Process* p, Eterm* reg, ErlFunEntry* fe, int num_free);
#if defined(VXWORKS)
static int init_done;
@@ -1146,6 +1186,8 @@ void process_main(void)
Uint temp_bits; /* Temporary used by BsSkipBits2 & BsGetInteger2 */
+ Eterm pt_arity; /* Used by do_put_tuple */
+
ERL_BITS_DECLARE_STATEP; /* Has to be last declaration */
@@ -1178,7 +1220,12 @@ void process_main(void)
do_schedule1:
PROCESS_MAIN_CHK_LOCKS(c_p);
ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
+#if HALFWORD_HEAP
+ ASSERT(erts_get_scheduler_data()->num_tmp_heap_used == 0);
+#endif
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
c_p = schedule(c_p, reds_used);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
#ifdef DEBUG
pid = c_p->id;
#endif
@@ -1246,6 +1293,52 @@ void process_main(void)
#define STORE_ARITH_RESULT(res) StoreBifResult(2, (res));
#define ARITH_FUNC(name) erts_gc_##name
+ {
+ Eterm increment_reg_val;
+ Eterm increment_val;
+ Uint live;
+ Eterm result;
+
+ OpCase(i_increment_yIId):
+ increment_reg_val = yb(Arg(0));
+ goto do_increment;
+
+ OpCase(i_increment_xIId):
+ increment_reg_val = xb(Arg(0));
+ goto do_increment;
+
+ OpCase(i_increment_rIId):
+ increment_reg_val = r(0);
+ I--;
+
+ do_increment:
+ increment_val = Arg(1);
+ if (is_small(increment_reg_val)) {
+ Sint i = signed_val(increment_reg_val) + increment_val;
+ ASSERT(MY_IS_SSMALL(i) == IS_SSMALL(i));
+ if (MY_IS_SSMALL(i)) {
+ result = make_small(i);
+ store_result:
+ StoreBifResult(3, result);
+ }
+ }
+
+ live = Arg(2);
+ SWAPOUT;
+ reg[0] = r(0);
+ reg[live] = increment_reg_val;
+ reg[live+1] = make_small(increment_val);
+ result = erts_gc_mixed_plus(c_p, reg, live);
+ r(0) = reg[0];
+ SWAPIN;
+ ERTS_HOLE_CHECK(c_p);
+ if (is_value(result)) {
+ goto store_result;
+ }
+ ASSERT(c_p->freason != BADMATCH || is_value(c_p->fvalue));
+ goto find_func_info;
+ }
+
OpCase(i_plus_jId):
{
Eterm result;
@@ -1309,6 +1402,52 @@ void process_main(void)
}
Next(1);
+ {
+ Eterm is_eq_exact_lit_val;
+
+ OpCase(i_is_eq_exact_literal_xfc):
+ is_eq_exact_lit_val = xb(Arg(0));
+ I++;
+ goto do_is_eq_exact_literal;
+
+ OpCase(i_is_eq_exact_literal_yfc):
+ is_eq_exact_lit_val = yb(Arg(0));
+ I++;
+ goto do_is_eq_exact_literal;
+
+ OpCase(i_is_eq_exact_literal_rfc):
+ is_eq_exact_lit_val = r(0);
+
+ do_is_eq_exact_literal:
+ if (!eq(Arg(1), is_eq_exact_lit_val)) {
+ ClauseFail();
+ }
+ Next(2);
+ }
+
+ {
+ Eterm is_ne_exact_lit_val;
+
+ OpCase(i_is_ne_exact_literal_xfc):
+ is_ne_exact_lit_val = xb(Arg(0));
+ I++;
+ goto do_is_ne_exact_literal;
+
+ OpCase(i_is_ne_exact_literal_yfc):
+ is_ne_exact_lit_val = yb(Arg(0));
+ I++;
+ goto do_is_ne_exact_literal;
+
+ OpCase(i_is_ne_exact_literal_rfc):
+ is_ne_exact_lit_val = r(0);
+
+ do_is_ne_exact_literal:
+ if (eq(Arg(1), is_ne_exact_lit_val)) {
+ ClauseFail();
+ }
+ Next(2);
+ }
+
OpCase(i_move_call_only_fcr): {
r(0) = Arg(1);
}
@@ -1392,6 +1531,17 @@ void process_main(void)
NextPF(1, next);
}
+ OpCase(move_x1_c): {
+ x(1) = Arg(0);
+ Next(1);
+ }
+
+ OpCase(move_x2_c): {
+ x(2) = Arg(0);
+ Next(1);
+ }
+
+
OpCase(return): {
SET_I(c_p->cp);
/*
@@ -1405,16 +1555,6 @@ void process_main(void)
Goto(*I);
}
- OpCase(test_heap_1_put_list_Iy): {
- BeamInstr *next;
-
- PreFetch(2, next);
- TestHeap(Arg(0), 1);
- PutList(yb(Arg(1)), r(0), r(0), StoreSimpleDest);
- CHECK_TERM(r(0));
- NextPF(2, next);
- }
-
/*
* Send is almost a standard call-BIF with two arguments, except for:
* 1) It cannot be traced.
@@ -1447,24 +1587,36 @@ void process_main(void)
goto find_func_info;
}
- OpCase(i_element_jssd): {
- Eterm index;
- Eterm tuple;
-
- /*
- * Inlined version of element/2 for speed.
- */
- GetArg2(1, index, tuple);
- if (is_small(index) && is_tuple(tuple)) {
- Eterm* tp = tuple_val(tuple);
-
- if ((signed_val(index) >= 1) &&
- (signed_val(index) <= arityval(*tp))) {
- Eterm result = tp[signed_val(index)];
- StoreBifResult(3, result);
- }
- }
- }
+ {
+ Eterm element_index;
+ Eterm element_tuple;
+
+ OpCase(i_element_xjsd):
+ element_tuple = xb(Arg(0));
+ I++;
+ goto do_element;
+
+ OpCase(i_element_yjsd):
+ element_tuple = yb(Arg(0));
+ I++;
+ goto do_element;
+
+ OpCase(i_element_rjsd):
+ element_tuple = r(0);
+ /* Fall through */
+
+ do_element:
+ GetArg1(1, element_index);
+ if (is_small(element_index) && is_tuple(element_tuple)) {
+ Eterm* tp = tuple_val(element_tuple);
+
+ if ((signed_val(element_index) >= 1) &&
+ (signed_val(element_index) <= arityval(*tp))) {
+ Eterm result = tp[signed_val(element_index)];
+ StoreBifResult(2, result);
+ }
+ }
+ }
/* Fall through */
OpCase(badarg_j):
@@ -1472,24 +1624,32 @@ void process_main(void)
c_p->freason = BADARG;
goto lb_Cl_error;
- OpCase(i_fast_element_jIsd): {
- Eterm tuple;
-
- /*
- * Inlined version of element/2 for even more speed.
- * The first argument is an untagged integer >= 1.
- * The second argument is guaranteed to be a register operand.
- */
- GetArg1(2, tuple);
- if (is_tuple(tuple)) {
- Eterm* tp = tuple_val(tuple);
- tmp_arg2 = Arg(1);
- if (tmp_arg2 <= arityval(*tp)) {
- Eterm result = tp[tmp_arg2];
- StoreBifResult(3, result);
- }
- }
+ {
+ Eterm fast_element_tuple;
+
+ OpCase(i_fast_element_rjId):
+ fast_element_tuple = r(0);
+
+ do_fast_element:
+ if (is_tuple(fast_element_tuple)) {
+ Eterm* tp = tuple_val(fast_element_tuple);
+ Eterm pos = Arg(1); /* Untagged integer >= 1 */
+ if (pos <= arityval(*tp)) {
+ Eterm result = tp[pos];
+ StoreBifResult(2, result);
+ }
+ }
goto badarg;
+
+ OpCase(i_fast_element_xjId):
+ fast_element_tuple = xb(Arg(0));
+ I++;
+ goto do_fast_element;
+
+ OpCase(i_fast_element_yjId):
+ fast_element_tuple = yb(Arg(0));
+ I++;
+ goto do_fast_element;
}
OpCase(catch_yf):
@@ -1515,6 +1675,7 @@ void process_main(void)
SWAPOUT;
PROCESS_MAIN_CHK_LOCKS(c_p);
FCALLS -= erts_garbage_collect(c_p, 3, reg+2, 1);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
SWAPIN;
}
@@ -1633,6 +1794,7 @@ void process_main(void)
PROCESS_MAIN_CHK_LOCKS(c_p);
},
{
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
r(0) = reg[0];
SWAPIN;
@@ -1691,6 +1853,7 @@ void process_main(void)
CANCEL_TIMER(c_p);
free_message(msgp);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
NextPF(0, next);
@@ -1842,8 +2005,87 @@ void process_main(void)
NextPF(0, next);
}
- OpCase(i_select_val_sfI):
- GetArg1(0, tmp_arg1);
+
+ {
+ Eterm select_val2;
+
+ OpCase(i_select_tuple_arity2_yfAfAf):
+ select_val2 = yb(Arg(0));
+ goto do_select_tuple_arity2;
+
+ OpCase(i_select_tuple_arity2_xfAfAf):
+ select_val2 = xb(Arg(0));
+ goto do_select_tuple_arity2;
+
+ OpCase(i_select_tuple_arity2_rfAfAf):
+ select_val2 = r(0);
+ I--;
+
+ do_select_tuple_arity2:
+ if (is_not_tuple(select_val2)) {
+ goto select_val2_fail;
+ }
+ select_val2 = *tuple_val(select_val2);
+ goto do_select_val2;
+
+ OpCase(i_select_val2_yfcfcf):
+ select_val2 = yb(Arg(0));
+ goto do_select_val2;
+
+ OpCase(i_select_val2_xfcfcf):
+ select_val2 = xb(Arg(0));
+ goto do_select_val2;
+
+ OpCase(i_select_val2_rfcfcf):
+ select_val2 = r(0);
+ I--;
+
+ do_select_val2:
+ if (select_val2 == Arg(2)) {
+ I += 2;
+ } else if (select_val2 == Arg(4)) {
+ I += 4;
+ }
+
+ select_val2_fail:
+ SET_I((BeamInstr *) Arg(1));
+ Goto(*I);
+ }
+
+ {
+ Eterm select_val;
+
+ OpCase(i_select_tuple_arity_xfI):
+ select_val = xb(Arg(0));
+ goto do_select_tuple_arity;
+
+ OpCase(i_select_tuple_arity_yfI):
+ select_val = yb(Arg(0));
+ goto do_select_tuple_arity;
+
+ OpCase(i_select_tuple_arity_rfI):
+ select_val = r(0);
+ I--;
+
+ do_select_tuple_arity:
+ if (is_tuple(select_val)) {
+ select_val = *tuple_val(select_val);
+ goto do_binary_search;
+ }
+ SET_I((BeamInstr *) Arg(1));
+ Goto(*I);
+
+ OpCase(i_select_val_xfI):
+ select_val = xb(Arg(0));
+ goto do_binary_search;
+
+ OpCase(i_select_val_yfI):
+ select_val = yb(Arg(0));
+ goto do_binary_search;
+
+ OpCase(i_select_val_rfI):
+ select_val = r(0);
+ I--;
do_binary_search:
{
@@ -1880,9 +2122,9 @@ void process_main(void)
unsigned int boffset = ((unsigned int)bdiff >> 1) & ~(sizeof(struct Pairs)-1);
mid = (struct Pairs*)((char*)low + boffset);
- if (tmp_arg1 < mid->val) {
+ if (select_val < mid->val) {
high = mid;
- } else if (tmp_arg1 > mid->val) {
+ } else if (select_val > mid->val) {
low = mid + 1;
} else {
SET_I(mid->addr);
@@ -1892,16 +2134,28 @@ void process_main(void)
SET_I((BeamInstr *) Arg(1));
Goto(*I);
}
+ }
- OpCase(i_jump_on_val_zero_sfI):
{
- Eterm index;
-
- GetArg1(0, index);
- if (is_small(index)) {
- index = signed_val(index);
- if (index < Arg(2)) {
- SET_I((BeamInstr *) (&Arg(3))[index]);
+ Eterm jump_on_val_zero_index;
+
+ OpCase(i_jump_on_val_zero_yfI):
+ jump_on_val_zero_index = yb(Arg(0));
+ goto do_jump_on_val_zero_index;
+
+ OpCase(i_jump_on_val_zero_xfI):
+ jump_on_val_zero_index = xb(Arg(0));
+ goto do_jump_on_val_zero_index;
+
+ OpCase(i_jump_on_val_zero_rfI):
+ jump_on_val_zero_index = r(0);
+ I--;
+
+ do_jump_on_val_zero_index:
+ if (is_small(jump_on_val_zero_index)) {
+ jump_on_val_zero_index = signed_val(jump_on_val_zero_index);
+ if (jump_on_val_zero_index < Arg(2)) {
+ SET_I((BeamInstr *) (&Arg(3))[jump_on_val_zero_index]);
Goto(*I);
}
}
@@ -1909,15 +2163,27 @@ void process_main(void)
Goto(*I);
}
- OpCase(i_jump_on_val_sfII):
{
- Eterm index;
+ Eterm jump_on_val_index;
- GetArg1(0, index);
- if (is_small(index)) {
- index = (Uint) (signed_val(index) - Arg(3));
- if (index < Arg(2)) {
- SET_I((BeamInstr *) (&Arg(4))[index]);
+
+ OpCase(i_jump_on_val_yfII):
+ jump_on_val_index = yb(Arg(0));
+ goto do_jump_on_val_index;
+
+ OpCase(i_jump_on_val_xfII):
+ jump_on_val_index = xb(Arg(0));
+ goto do_jump_on_val_index;
+
+ OpCase(i_jump_on_val_rfII):
+ jump_on_val_index = r(0);
+ I--;
+
+ do_jump_on_val_index:
+ if (is_small(jump_on_val_index)) {
+ jump_on_val_index = (Uint) (signed_val(jump_on_val_index) - Arg(3));
+ if (jump_on_val_index < Arg(2)) {
+ SET_I((BeamInstr *) (&Arg(4))[jump_on_val_index]);
Goto(*I);
}
}
@@ -1925,6 +2191,32 @@ void process_main(void)
Goto(*I);
}
+ do_put_tuple: {
+ Eterm* hp = HTOP;
+
+ *hp++ = make_arityval(pt_arity);
+
+ do {
+ Eterm term = *I++;
+ switch (term & _TAG_IMMED1_MASK) {
+ case (R_REG_DEF << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER:
+ *hp++ = r(0);
+ break;
+ case (X_REG_DEF << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER:
+ *hp++ = x(term >> _TAG_IMMED1_SIZE);
+ break;
+ case (Y_REG_DEF << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER:
+ *hp++ = y(term >> _TAG_IMMED1_SIZE);
+ break;
+ default:
+ *hp++ = term;
+ break;
+ }
+ } while (--pt_arity != 0);
+ HTOP = hp;
+ Goto(*I);
+ }
+
/*
* All guards with zero arguments have special instructions:
* self/0
@@ -1952,6 +2244,7 @@ void process_main(void)
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
result = (*bf)(c_p, arg);
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(result));
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
ERTS_HOLE_CHECK(c_p);
FCALLS = c_p->fcalls;
@@ -1980,6 +2273,7 @@ void process_main(void)
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
result = (*bf)(c_p, arg);
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(result));
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
ERTS_HOLE_CHECK(c_p);
FCALLS = c_p->fcalls;
@@ -2009,6 +2303,7 @@ void process_main(void)
PROCESS_MAIN_CHK_LOCKS(c_p);
ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
result = (*bf)(c_p, reg, live);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
SWAPIN;
@@ -2044,6 +2339,7 @@ void process_main(void)
PROCESS_MAIN_CHK_LOCKS(c_p);
ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
result = (*bf)(c_p, reg, live);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
SWAPIN;
@@ -2082,6 +2378,7 @@ void process_main(void)
PROCESS_MAIN_CHK_LOCKS(c_p);
ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
result = (*bf)(c_p, reg, live);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
SWAPIN;
@@ -2116,6 +2413,7 @@ void process_main(void)
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
result = (*bf)(c_p, tmp_arg1, tmp_arg2);
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(result));
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
ERTS_HOLE_CHECK(c_p);
FCALLS = c_p->fcalls;
@@ -2139,6 +2437,7 @@ void process_main(void)
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
result = (*bf)(c_p, tmp_arg1, tmp_arg2);
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(result));
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
ERTS_HOLE_CHECK(c_p);
if (is_value(result)) {
@@ -2562,23 +2861,25 @@ void process_main(void)
OpCase(i_int_bnot_jsId):
{
- GetArg1(1, tmp_arg1);
- if (is_small(tmp_arg1)) {
- tmp_arg1 = make_small(~signed_val(tmp_arg1));
+ Eterm bnot_val;
+
+ GetArg1(1, bnot_val);
+ if (is_small(bnot_val)) {
+ bnot_val = make_small(~signed_val(bnot_val));
} else {
Uint live = Arg(2);
SWAPOUT;
reg[0] = r(0);
- reg[live] = tmp_arg1;
- tmp_arg1 = erts_gc_bnot(c_p, reg, live);
+ reg[live] = bnot_val;
+ bnot_val = erts_gc_bnot(c_p, reg, live);
r(0) = reg[0];
SWAPIN;
ERTS_HOLE_CHECK(c_p);
- if (is_nil(tmp_arg1)) {
+ if (is_nil(bnot_val)) {
goto lb_Cl_error;
}
}
- StoreBifResult(3, tmp_arg1);
+ StoreBifResult(3, bnot_val);
}
badarith:
@@ -2833,121 +3134,6 @@ void process_main(void)
goto do_schedule1;
}
- OpCase(i_select_tuple_arity_sfI):
- {
- GetArg1(0, tmp_arg1);
-
- if (is_tuple(tmp_arg1)) {
- tmp_arg1 = *tuple_val(tmp_arg1);
- goto do_binary_search;
- }
- SET_I((BeamInstr *) Arg(1));
- Goto(*I);
- }
-
- OpCase(i_select_big_sf):
- {
- Eterm* bigp;
- Uint arity;
- Eterm* given;
- Uint given_arity;
- Uint given_size;
-
- GetArg1(0, tmp_arg1);
- if (is_big(tmp_arg1)) {
-
- /*
- * The loader has sorted the bignumbers in descending order
- * on the arity word. Therefore, we know that the search
- * has failed as soon as we encounter an arity word less than
- * the arity word of the given number. There is a zero word
- * (less than any valid arity word) stored after the last bignumber.
- */
-
- given = big_val(tmp_arg1);
- given_arity = given[0];
- given_size = thing_arityval(given_arity);
- bigp = (Eterm *) &Arg(2);
- while ((arity = bigp[0]) > given_arity) {
- bigp += (TermWords(thing_arityval(arity) + 1) + 1) * (sizeof(BeamInstr)/sizeof(Eterm));
- }
- while (bigp[0] == given_arity) {
- if (memcmp(bigp+1, given+1, sizeof(Eterm)*given_size) == 0) {
- BeamInstr *tmp =
- ((BeamInstr *) (UWord) bigp) + TermWords(given_size + 1);
- SET_I((BeamInstr *) *tmp);
- Goto(*I);
- }
- bigp += (TermWords(thing_arityval(arity) + 1) + 1) * (sizeof(BeamInstr)/sizeof(Eterm));
- }
- }
-
- /*
- * Failed.
- */
-
- SET_I((BeamInstr *) Arg(1));
- Goto(*I);
- }
-
-#if defined(ARCH_64) && !HALFWORD_HEAP
- OpCase(i_select_float_sfI):
- {
- Uint f;
- int n;
- struct ValLabel {
- Uint f;
- BeamInstr* addr;
- };
- struct ValLabel* ptr;
-
- GetArg1(0, tmp_arg1);
- ASSERT(is_float(tmp_arg1));
- f = float_val(tmp_arg1)[1];
- n = Arg(2);
- ptr = (struct ValLabel *) &Arg(3);
- while (n-- > 0) {
- if (ptr->f == f) {
- SET_I(ptr->addr);
- Goto(*I);
- }
- ptr++;
- }
- SET_I((Eterm *) Arg(1));
- Goto(*I);
- }
-#else
- OpCase(i_select_float_sfI):
- {
- Uint fpart1;
- Uint fpart2;
- int n;
- struct ValLabel {
- Uint fpart1;
- Uint fpart2;
- BeamInstr* addr;
- };
- struct ValLabel* ptr;
-
- GetArg1(0, tmp_arg1);
- ASSERT(is_float(tmp_arg1));
- fpart1 = float_val(tmp_arg1)[1];
- fpart2 = float_val(tmp_arg1)[2];
-
- n = Arg(2);
- ptr = (struct ValLabel *) &Arg(3);
- while (n-- > 0) {
- if (ptr->fpart1 == fpart1 && ptr->fpart2 == fpart2) {
- SET_I(ptr->addr);
- Goto(*I);
- }
- ptr++;
- }
- SET_I((BeamInstr *) Arg(1));
- Goto(*I);
- }
-#endif
-
OpCase(set_tuple_element_sdP): {
Eterm element;
Eterm tuple;
@@ -2993,15 +3179,17 @@ void process_main(void)
the first argument. We also handle atom tags in the first
argument for backwards compatibility.
*/
- GetArg2(0, tmp_arg1, tmp_arg2);
- c_p->fvalue = tmp_arg2;
+ Eterm raise_val1;
+ Eterm raise_val2;
+ GetArg2(0, raise_val1, raise_val2);
+ c_p->fvalue = raise_val2;
if (c_p->freason == EXC_NULL) {
/* a safety check for the R10-0 case; should not happen */
c_p->ftrace = NIL;
c_p->freason = EXC_ERROR;
}
/* for R10-0 code, keep existing c_p->ftrace and hope it's correct */
- switch (tmp_arg1) {
+ switch (raise_val1) {
case am_throw:
c_p->freason = EXC_THROWN & ~EXF_SAVETRACE;
break;
@@ -3017,8 +3205,8 @@ void process_main(void)
passed from a user! Currently only expecting generated calls.
*/
struct StackTrace *s;
- c_p->ftrace = tmp_arg1;
- s = get_trace_from_exc(tmp_arg1);
+ c_p->ftrace = raise_val1;
+ s = get_trace_from_exc(raise_val1);
if (s == NULL) {
c_p->freason = EXC_ERROR;
} else {
@@ -3029,11 +3217,24 @@ void process_main(void)
goto find_func_info;
}
- OpCase(badmatch_s): {
- GetArg1(0, tmp_arg1);
- c_p->fvalue = tmp_arg1;
- c_p->freason = BADMATCH;
- }
+ {
+ Eterm badmatch_val;
+
+ OpCase(badmatch_y):
+ badmatch_val = yb(Arg(0));
+ goto do_badmatch;
+
+ OpCase(badmatch_x):
+ badmatch_val = xb(Arg(0));
+ goto do_badmatch;
+
+ OpCase(badmatch_r):
+ badmatch_val = r(0);
+
+ do_badmatch:
+ c_p->fvalue = badmatch_val;
+ c_p->freason = BADMATCH;
+ }
/* Fall through here */
find_func_info: {
@@ -3056,12 +3257,11 @@ void process_main(void)
*/
SWAPOUT;
reg[0] = r(0);
- tmp_arg1 = call_error_handler(c_p, I-3, reg);
+ I = call_error_handler(c_p, I-3, reg, am_undefined_function);
r(0) = reg[0];
SWAPIN;
- if (tmp_arg1) {
- SET_I(c_p->i);
- Dispatch();
+ if (I) {
+ Goto(*I);
}
/* Fall through */
@@ -3084,128 +3284,149 @@ void process_main(void)
}
}
- OpCase(call_nif):
- {
- /*
- * call_nif is always first instruction in function:
- *
- * I[-3]: Module
- * I[-2]: Function
- * I[-1]: Arity
- * I[0]: &&call_nif
- * I[1]: Function pointer to NIF function
- * I[2]: Pointer to erl_module_nif
- */
- BifFunction vbf;
-
- c_p->current = I-3; /* current and vbf set to please handle_error */
- SWAPOUT;
- c_p->fcalls = FCALLS - 1;
- PROCESS_MAIN_CHK_LOCKS(c_p);
- tmp_arg2 = I[-1];
- ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
+ {
+ Eterm nif_bif_result;
+ Eterm bif_nif_arity;
- ASSERT(!ERTS_PROC_IS_EXITING(c_p));
- {
- typedef Eterm NifF(struct enif_environment_t*, int argc, Eterm argv[]);
- NifF* fp = vbf = (NifF*) I[1];
- struct enif_environment_t env;
- erts_pre_nif(&env, c_p, (struct erl_module_nif*)I[2]);
- reg[0] = r(0);
- tmp_arg1 = (*fp)(&env, tmp_arg2, reg);
- erts_post_nif(&env);
- }
- ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1));
- PROCESS_MAIN_CHK_LOCKS(c_p);
- goto apply_bif_or_nif_epilogue;
-
- OpCase(apply_bif):
- /*
- * At this point, I points to the code[3] in the export entry for
- * the BIF:
- *
- * code[0]: Module
- * code[1]: Function
- * code[2]: Arity
- * code[3]: &&apply_bif
- * code[4]: Function pointer to BIF function
- */
+ OpCase(call_nif):
+ {
+ /*
+ * call_nif is always first instruction in function:
+ *
+ * I[-3]: Module
+ * I[-2]: Function
+ * I[-1]: Arity
+ * I[0]: &&call_nif
+ * I[1]: Function pointer to NIF function
+ * I[2]: Pointer to erl_module_nif
+ */
+ BifFunction vbf;
- c_p->current = I-3; /* In case we apply process_info/1,2 or load_nif/1 */
- c_p->i = I; /* In case we apply check_process_code/2. */
- c_p->arity = 0; /* To allow garbage collection on ourselves
- * (check_process_code/2).
- */
- SWAPOUT;
- c_p->fcalls = FCALLS - 1;
- vbf = (BifFunction) Arg(0);
- PROCESS_MAIN_CHK_LOCKS(c_p);
- tmp_arg2 = I[-1];
- ASSERT(tmp_arg2 <= 3);
- ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
- switch (tmp_arg2) {
- case 3:
+ c_p->current = I-3; /* current and vbf set to please handle_error */
+ SWAPOUT;
+ c_p->fcalls = FCALLS - 1;
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ bif_nif_arity = I[-1];
+ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
+
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p));
{
- Eterm (*bf)(Process*, Eterm, Eterm, Eterm, BeamInstr*) = vbf;
- ASSERT(!ERTS_PROC_IS_EXITING(c_p));
- tmp_arg1 = (*bf)(c_p, r(0), x(1), x(2), I);
- ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1));
- PROCESS_MAIN_CHK_LOCKS(c_p);
+ typedef Eterm NifF(struct enif_environment_t*, int argc, Eterm argv[]);
+ NifF* fp = vbf = (NifF*) I[1];
+ struct enif_environment_t env;
+ erts_pre_nif(&env, c_p, (struct erl_module_nif*)I[2]);
+ reg[0] = r(0);
+ nif_bif_result = (*fp)(&env, bif_nif_arity, reg);
+ erts_post_nif(&env);
}
- break;
- case 2:
- {
- Eterm (*bf)(Process*, Eterm, Eterm, BeamInstr*) = vbf;
- ASSERT(!ERTS_PROC_IS_EXITING(c_p));
- tmp_arg1 = (*bf)(c_p, r(0), x(1), I);
- ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1));
- PROCESS_MAIN_CHK_LOCKS(c_p);
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(nif_bif_result));
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
+ goto apply_bif_or_nif_epilogue;
+
+ OpCase(apply_bif):
+ /*
+ * At this point, I points to the code[3] in the export entry for
+ * the BIF:
+ *
+ * code[0]: Module
+ * code[1]: Function
+ * code[2]: Arity
+ * code[3]: &&apply_bif
+ * code[4]: Function pointer to BIF function
+ */
+
+ c_p->current = I-3; /* In case we apply process_info/1,2 or load_nif/1 */
+ c_p->i = I; /* In case we apply check_process_code/2. */
+ c_p->arity = 0; /* To allow garbage collection on ourselves
+ * (check_process_code/2).
+ */
+ SWAPOUT;
+ c_p->fcalls = FCALLS - 1;
+ vbf = (BifFunction) Arg(0);
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ bif_nif_arity = I[-1];
+ ASSERT(bif_nif_arity <= 3);
+ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
+ switch (bif_nif_arity) {
+ case 3:
+ {
+ Eterm (*bf)(Process*, Eterm, Eterm, Eterm, BeamInstr*) = vbf;
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p));
+ nif_bif_result = (*bf)(c_p, r(0), x(1), x(2), I);
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p) ||
+ is_non_value(nif_bif_result));
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ }
+ break;
+ case 2:
+ {
+ Eterm (*bf)(Process*, Eterm, Eterm, BeamInstr*) = vbf;
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p));
+ nif_bif_result = (*bf)(c_p, r(0), x(1), I);
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p) ||
+ is_non_value(nif_bif_result));
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ }
+ break;
+ case 1:
+ {
+ Eterm (*bf)(Process*, Eterm, BeamInstr*) = vbf;
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p));
+ nif_bif_result = (*bf)(c_p, r(0), I);
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p) ||
+ is_non_value(nif_bif_result));
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ }
+ break;
+ case 0:
+ {
+ Eterm (*bf)(Process*, BeamInstr*) = vbf;
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p));
+ nif_bif_result = (*bf)(c_p, I);
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p) ||
+ is_non_value(nif_bif_result));
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ break;
+ }
+ default:
+ erl_exit(1, "apply_bif: invalid arity: %u\n",
+ bif_nif_arity);
}
- break;
- case 1:
- {
- Eterm (*bf)(Process*, Eterm, BeamInstr*) = vbf;
- ASSERT(!ERTS_PROC_IS_EXITING(c_p));
- tmp_arg1 = (*bf)(c_p, r(0), I);
- ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1));
- PROCESS_MAIN_CHK_LOCKS(c_p);
+
+ apply_bif_or_nif_epilogue:
+ ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
+ ERTS_HOLE_CHECK(c_p);
+ if (c_p->mbuf) {
+ reg[0] = r(0);
+ nif_bif_result = erts_gc_after_bif_call(c_p, nif_bif_result,
+ reg, bif_nif_arity);
+ r(0) = reg[0];
}
- break;
- case 0:
- {
- Eterm (*bf)(Process*, BeamInstr*) = vbf;
- ASSERT(!ERTS_PROC_IS_EXITING(c_p));
- tmp_arg1 = (*bf)(c_p, I);
- ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1));
- PROCESS_MAIN_CHK_LOCKS(c_p);
- break;
+ SWAPIN; /* There might have been a garbage collection. */
+ FCALLS = c_p->fcalls;
+ if (is_value(nif_bif_result)) {
+ r(0) = nif_bif_result;
+ CHECK_TERM(r(0));
+ SET_I(c_p->cp);
+ Goto(*I);
+ } else if (c_p->freason == TRAP) {
+ SET_I(*((BeamInstr **) (UWord) ((c_p)->def_arg_reg + 3)));
+ r(0) = c_p->def_arg_reg[0];
+ x(1) = c_p->def_arg_reg[1];
+ x(2) = c_p->def_arg_reg[2];
+ Dispatch();
}
- }
-apply_bif_or_nif_epilogue:
- ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
- ERTS_HOLE_CHECK(c_p);
- if (c_p->mbuf) {
reg[0] = r(0);
- tmp_arg1 = erts_gc_after_bif_call(c_p, tmp_arg1, reg, tmp_arg2);
- r(0) = reg[0];
+ I = handle_error(c_p, c_p->cp, reg, vbf);
+ goto post_error_handling;
}
- SWAPIN; /* There might have been a garbage collection. */
- FCALLS = c_p->fcalls;
- if (is_value(tmp_arg1)) {
- r(0) = tmp_arg1;
- CHECK_TERM(r(0));
- SET_I(c_p->cp);
- Goto(*I);
- } else if (c_p->freason == TRAP) {
- SET_I(*((BeamInstr **) (UWord) ((c_p)->def_arg_reg + 3)));
- r(0) = c_p->def_arg_reg[0];
- x(1) = c_p->def_arg_reg[1];
- x(2) = c_p->def_arg_reg[2];
- Dispatch();
- }
- reg[0] = r(0);
- I = handle_error(c_p, c_p->cp, reg, vbf);
- goto post_error_handling;
}
OpCase(i_get_sd):
@@ -3218,11 +3439,25 @@ apply_bif_or_nif_epilogue:
StoreBifResult(1, result);
}
- OpCase(case_end_s):
- GetArg1(0, tmp_arg1);
- c_p->fvalue = tmp_arg1;
- c_p->freason = EXC_CASE_CLAUSE;
- goto find_func_info;
+ {
+ Eterm case_end_val;
+
+ OpCase(case_end_x):
+ case_end_val = xb(Arg(0));
+ goto do_case_end;
+
+ OpCase(case_end_y):
+ case_end_val = yb(Arg(0));
+ goto do_case_end;
+
+ OpCase(case_end_r):
+ case_end_val = r(0);
+
+ do_case_end:
+ c_p->fvalue = case_end_val;
+ c_p->freason = EXC_CASE_CLAUSE;
+ goto find_func_info;
+ }
OpCase(if_end):
c_p->freason = EXC_IF_CLAUSE;
@@ -3235,10 +3470,13 @@ apply_bif_or_nif_epilogue:
}
OpCase(try_case_end_s):
- GetArg1(0, tmp_arg1);
- c_p->fvalue = tmp_arg1;
- c_p->freason = EXC_TRY_CLAUSE;
- goto find_func_info;
+ {
+ Eterm try_case_end_val;
+ GetArg1(0, try_case_end_val);
+ c_p->fvalue = try_case_end_val;
+ c_p->freason = EXC_TRY_CLAUSE;
+ goto find_func_info;
+ }
/*
* Construction of binaries using new instructions.
@@ -3786,19 +4024,20 @@ apply_bif_or_nif_epilogue:
Eterm header;
BeamInstr *next;
Uint slots;
+ Eterm context;
OpCase(i_bs_start_match2_rfIId): {
- tmp_arg1 = r(0);
+ context = r(0);
do_start_match:
slots = Arg(2);
- if (!is_boxed(tmp_arg1)) {
+ if (!is_boxed(context)) {
ClauseFail();
}
PreFetch(4, next);
- header = *boxed_val(tmp_arg1);
+ header = *boxed_val(context);
if (header_is_bin_matchstate(header)) {
- ErlBinMatchState* ms = (ErlBinMatchState *) boxed_val(tmp_arg1);
+ ErlBinMatchState* ms = (ErlBinMatchState *) boxed_val(context);
Uint actual_slots = HEADER_NUM_SLOTS(header);
ms->save_offset[0] = ms->mb.offset;
if (actual_slots < slots) {
@@ -3806,8 +4045,8 @@ apply_bif_or_nif_epilogue:
Uint live = Arg(1);
Uint wordsneeded = ERL_BIN_MATCHSTATE_SIZE(slots);
- TestHeapPreserve(wordsneeded, live, tmp_arg1);
- ms = (ErlBinMatchState *) boxed_val(tmp_arg1);
+ TestHeapPreserve(wordsneeded, live, context);
+ ms = (ErlBinMatchState *) boxed_val(context);
dst = (ErlBinMatchState *) HTOP;
*dst = *ms;
*HTOP = HEADER_BIN_MATCHSTATE(slots);
@@ -3819,12 +4058,12 @@ apply_bif_or_nif_epilogue:
Eterm result;
Uint live = Arg(1);
Uint wordsneeded = ERL_BIN_MATCHSTATE_SIZE(slots);
- TestHeapPreserve(wordsneeded, live, tmp_arg1);
+ TestHeapPreserve(wordsneeded, live, context);
HEAP_TOP(c_p) = HTOP;
#ifdef DEBUG
c_p->stop = E; /* Needed for checking in HeapOnlyAlloc(). */
#endif
- result = erts_bs_start_match_2(c_p, tmp_arg1, slots);
+ result = erts_bs_start_match_2(c_p, context, slots);
HTOP = HEAP_TOP(c_p);
HEAP_SPACE_VERIFIED(0);
if (is_non_value(result)) {
@@ -3838,12 +4077,12 @@ apply_bif_or_nif_epilogue:
NextPF(4, next);
}
OpCase(i_bs_start_match2_xfIId): {
- tmp_arg1 = xb(Arg(0));
+ context = xb(Arg(0));
I++;
goto do_start_match;
}
OpCase(i_bs_start_match2_yfIId): {
- tmp_arg1 = yb(Arg(0));
+ context = yb(Arg(0));
I++;
goto do_start_match;
}
@@ -3936,93 +4175,105 @@ apply_bif_or_nif_epilogue:
NextPF(2, next);
}
+ {
+ Eterm bs_get_integer8_context;
+
OpCase(i_bs_get_integer_8_rfd): {
- tmp_arg1 = r(0);
- goto do_bs_get_integer_8;
- }
+ bs_get_integer8_context = r(0);
+ goto do_bs_get_integer_8;
+ }
OpCase(i_bs_get_integer_8_xfd): {
- tmp_arg1 = xb(Arg(0));
- I++;
- }
+ bs_get_integer8_context = xb(Arg(0));
+ I++;
+ }
do_bs_get_integer_8: {
- ErlBinMatchBuffer *_mb;
- Eterm _result;
- _mb = ms_matchbuffer(tmp_arg1);
- if (_mb->size - _mb->offset < 8) {
- ClauseFail();
- }
- if (BIT_OFFSET(_mb->offset) != 0) {
- _result = erts_bs_get_integer_2(c_p, 8, 0, _mb);
- } else {
- _result = make_small(_mb->base[BYTE_OFFSET(_mb->offset)]);
- _mb->offset += 8;
+ ErlBinMatchBuffer *_mb;
+ Eterm _result;
+ _mb = ms_matchbuffer(bs_get_integer8_context);
+ if (_mb->size - _mb->offset < 8) {
+ ClauseFail();
+ }
+ if (BIT_OFFSET(_mb->offset) != 0) {
+ _result = erts_bs_get_integer_2(c_p, 8, 0, _mb);
+ } else {
+ _result = make_small(_mb->base[BYTE_OFFSET(_mb->offset)]);
+ _mb->offset += 8;
+ }
+ StoreBifResult(1, _result);
}
- StoreBifResult(1, _result);
}
- OpCase(i_bs_get_integer_16_rfd): {
- tmp_arg1 = r(0);
+ {
+ Eterm bs_get_integer_16_context;
+
+ OpCase(i_bs_get_integer_16_rfd):
+ bs_get_integer_16_context = r(0);
goto do_bs_get_integer_16;
- }
- OpCase(i_bs_get_integer_16_xfd): {
- tmp_arg1 = xb(Arg(0));
+ OpCase(i_bs_get_integer_16_xfd):
+ bs_get_integer_16_context = xb(Arg(0));
I++;
- }
- do_bs_get_integer_16: {
- ErlBinMatchBuffer *_mb;
- Eterm _result;
- _mb = ms_matchbuffer(tmp_arg1);
- if (_mb->size - _mb->offset < 16) {
- ClauseFail();
- }
- if (BIT_OFFSET(_mb->offset) != 0) {
- _result = erts_bs_get_integer_2(c_p, 16, 0, _mb);
- } else {
- _result = make_small(get_int16(_mb->base+BYTE_OFFSET(_mb->offset)));
- _mb->offset += 16;
+ do_bs_get_integer_16:
+ {
+ ErlBinMatchBuffer *_mb;
+ Eterm _result;
+ _mb = ms_matchbuffer(bs_get_integer_16_context);
+ if (_mb->size - _mb->offset < 16) {
+ ClauseFail();
+ }
+ if (BIT_OFFSET(_mb->offset) != 0) {
+ _result = erts_bs_get_integer_2(c_p, 16, 0, _mb);
+ } else {
+ _result = make_small(get_int16(_mb->base+BYTE_OFFSET(_mb->offset)));
+ _mb->offset += 16;
+ }
+ StoreBifResult(1, _result);
}
- StoreBifResult(1, _result);
}
- OpCase(i_bs_get_integer_32_rfId): {
- tmp_arg1 = r(0);
+ {
+ Eterm bs_get_integer_32_context;
+
+ OpCase(i_bs_get_integer_32_rfId):
+ bs_get_integer_32_context = r(0);
goto do_bs_get_integer_32;
- }
+
- OpCase(i_bs_get_integer_32_xfId): {
- tmp_arg1 = xb(Arg(0));
+ OpCase(i_bs_get_integer_32_xfId):
+ bs_get_integer_32_context = xb(Arg(0));
I++;
- }
- do_bs_get_integer_32: {
- ErlBinMatchBuffer *_mb;
- Uint32 _integer;
- Eterm _result;
- _mb = ms_matchbuffer(tmp_arg1);
- if (_mb->size - _mb->offset < 32) { ClauseFail(); }
- if (BIT_OFFSET(_mb->offset) != 0) {
- _integer = erts_bs_get_unaligned_uint32(_mb);
- } else {
- _integer = get_int32(_mb->base + _mb->offset/8);
- }
- _mb->offset += 32;
+
+ do_bs_get_integer_32:
+ {
+ ErlBinMatchBuffer *_mb;
+ Uint32 _integer;
+ Eterm _result;
+ _mb = ms_matchbuffer(bs_get_integer_32_context);
+ if (_mb->size - _mb->offset < 32) { ClauseFail(); }
+ if (BIT_OFFSET(_mb->offset) != 0) {
+ _integer = erts_bs_get_unaligned_uint32(_mb);
+ } else {
+ _integer = get_int32(_mb->base + _mb->offset/8);
+ }
+ _mb->offset += 32;
#if !defined(ARCH_64) || HALFWORD_HEAP
- if (IS_USMALL(0, _integer)) {
+ if (IS_USMALL(0, _integer)) {
#endif
- _result = make_small(_integer);
+ _result = make_small(_integer);
#if !defined(ARCH_64) || HALFWORD_HEAP
- } else {
- TestHeap(BIG_UINT_HEAP_SIZE, Arg(1));
- _result = uint_to_big((Uint) _integer, HTOP);
- HTOP += BIG_UINT_HEAP_SIZE;
- HEAP_SPACE_VERIFIED(0);
- }
+ } else {
+ TestHeap(BIG_UINT_HEAP_SIZE, Arg(1));
+ _result = uint_to_big((Uint) _integer, HTOP);
+ HTOP += BIG_UINT_HEAP_SIZE;
+ HEAP_SPACE_VERIFIED(0);
+ }
#endif
- StoreBifResult(2, _result);
+ StoreBifResult(2, _result);
+ }
}
/* Operands: Size Live Fail Flags Dst */
@@ -4120,54 +4371,64 @@ apply_bif_or_nif_epilogue:
StoreBifResult(3, result);
}
- /* Operands: MatchContext Fail Dst */
+ {
+ Eterm get_utf8_context;
+
+ /* Operands: MatchContext Fail Dst */
OpCase(i_bs_get_utf8_rfd): {
- tmp_arg1 = r(0);
- goto do_bs_get_utf8;
- }
+ get_utf8_context = r(0);
+ goto do_bs_get_utf8;
+ }
OpCase(i_bs_get_utf8_xfd): {
- tmp_arg1 = xb(Arg(0));
- I++;
- }
+ get_utf8_context = xb(Arg(0));
+ I++;
+ }
- /*
- * tmp_arg1 = match_context
- * Operands: Fail Dst
- */
+ /*
+ * get_utf8_context = match_context
+ * Operands: Fail Dst
+ */
- do_bs_get_utf8: {
- Eterm result = erts_bs_get_utf8(ms_matchbuffer(tmp_arg1));
- if (is_non_value(result)) {
- ClauseFail();
+ do_bs_get_utf8: {
+ Eterm result = erts_bs_get_utf8(ms_matchbuffer(get_utf8_context));
+ if (is_non_value(result)) {
+ ClauseFail();
+ }
+ StoreBifResult(1, result);
}
- StoreBifResult(1, result);
}
- /* Operands: MatchContext Fail Flags Dst */
+ {
+ Eterm get_utf16_context;
+
+ /* Operands: MatchContext Fail Flags Dst */
OpCase(i_bs_get_utf16_rfId): {
- tmp_arg1 = r(0);
- goto do_bs_get_utf16;
- }
+ get_utf16_context = r(0);
+ goto do_bs_get_utf16;
+ }
OpCase(i_bs_get_utf16_xfId): {
- tmp_arg1 = xb(Arg(0));
- I++;
- }
+ get_utf16_context = xb(Arg(0));
+ I++;
+ }
- /*
- * tmp_arg1 = match_context
- * Operands: Fail Flags Dst
- */
- do_bs_get_utf16: {
- Eterm result = erts_bs_get_utf16(ms_matchbuffer(tmp_arg1), Arg(1));
- if (is_non_value(result)) {
- ClauseFail();
+ /*
+ * get_utf16_context = match_context
+ * Operands: Fail Flags Dst
+ */
+ do_bs_get_utf16: {
+ Eterm result = erts_bs_get_utf16(ms_matchbuffer(get_utf16_context),
+ Arg(1));
+ if (is_non_value(result)) {
+ ClauseFail();
+ }
+ StoreBifResult(2, result);
}
- StoreBifResult(2, result);
}
{
+ Eterm context_to_binary_context;
ErlBinMatchBuffer* mb;
ErlSubBin* sb;
Uint size;
@@ -4176,27 +4437,29 @@ apply_bif_or_nif_epilogue:
Uint hole_size;
OpCase(bs_context_to_binary_r): {
- tmp_arg1 = x0;
+ context_to_binary_context = x0;
I -= 2;
goto do_context_to_binary;
}
/* Unfortunately, inlining can generate this instruction. */
OpCase(bs_context_to_binary_y): {
- tmp_arg1 = yb(Arg(0));
+ context_to_binary_context = yb(Arg(0));
goto do_context_to_binary0;
}
OpCase(bs_context_to_binary_x): {
- tmp_arg1 = xb(Arg(0));
+ context_to_binary_context = xb(Arg(0));
do_context_to_binary0:
I--;
}
do_context_to_binary:
- if (is_boxed(tmp_arg1) && header_is_bin_matchstate(*boxed_val(tmp_arg1))) {
- ErlBinMatchState* ms = (ErlBinMatchState *) boxed_val(tmp_arg1);
+ if (is_boxed(context_to_binary_context) &&
+ header_is_bin_matchstate(*boxed_val(context_to_binary_context))) {
+ ErlBinMatchState* ms;
+ ms = (ErlBinMatchState *) boxed_val(context_to_binary_context);
mb = &ms->mb;
offs = ms->save_offset[0];
size = mb->size - offs;
@@ -4205,17 +4468,17 @@ apply_bif_or_nif_epilogue:
Next(2);
OpCase(i_bs_get_binary_all_reuse_rfI): {
- tmp_arg1 = x0;
+ context_to_binary_context = x0;
goto do_bs_get_binary_all_reuse;
}
OpCase(i_bs_get_binary_all_reuse_xfI): {
- tmp_arg1 = xb(Arg(0));
+ context_to_binary_context = xb(Arg(0));
I++;
}
do_bs_get_binary_all_reuse:
- mb = ms_matchbuffer(tmp_arg1);
+ mb = ms_matchbuffer(context_to_binary_context);
size = mb->size - mb->offset;
if (size % Arg(1) != 0) {
ClauseFail();
@@ -4224,7 +4487,7 @@ apply_bif_or_nif_epilogue:
do_bs_get_binary_all_reuse_common:
orig = mb->orig;
- sb = (ErlSubBin *) boxed_val(tmp_arg1);
+ sb = (ErlSubBin *) boxed_val(context_to_binary_context);
hole_size = 1 + header_arity(sb->thing_word) - ERL_SUB_BIN_SIZE;
sb->thing_word = HEADER_SUB_BIN;
sb->size = BYTE_OFFSET(size);
@@ -4240,12 +4503,14 @@ apply_bif_or_nif_epilogue:
}
{
+ Eterm match_string_context;
+
OpCase(i_bs_match_string_rfII): {
- tmp_arg1 = r(0);
+ match_string_context = r(0);
goto do_bs_match_string;
}
OpCase(i_bs_match_string_xfII): {
- tmp_arg1 = xb(Arg(0));
+ match_string_context = xb(Arg(0));
I++;
}
@@ -4260,7 +4525,7 @@ apply_bif_or_nif_epilogue:
PreFetch(3, next);
bits = Arg(1);
bytes = (byte *) Arg(2);
- mb = ms_matchbuffer(tmp_arg1);
+ mb = ms_matchbuffer(match_string_context);
if (mb->size - mb->offset < bits) {
ClauseFail();
}
@@ -4353,6 +4618,7 @@ apply_bif_or_nif_epilogue:
ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
flags = erts_call_trace(c_p, ep->code, ep->match_prog_set, reg,
0, &c_p->tracer_proc);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
@@ -4364,6 +4630,7 @@ apply_bif_or_nif_epilogue:
/* SWAPOUT, SWAPIN was done and r(0) was saved above */
PROCESS_MAIN_CHK_LOCKS(c_p);
FCALLS -= erts_garbage_collect(c_p, 3, reg, ep->code[2]);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
r(0) = reg[0];
SWAPIN;
@@ -4453,6 +4720,7 @@ apply_bif_or_nif_epilogue:
reg[0] = r(0);
PROCESS_MAIN_CHK_LOCKS(c_p);
FCALLS -= erts_garbage_collect(c_p, 2, reg, I[-1]);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
r(0) = reg[0];
}
@@ -4556,6 +4824,7 @@ apply_bif_or_nif_epilogue:
/* SWAPOUT was done and r(0) was saved above */
PROCESS_MAIN_CHK_LOCKS(c_p);
FCALLS -= erts_garbage_collect(c_p, need, reg, I[-1]);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
r(0) = reg[0];
SWAPIN;
@@ -4723,7 +4992,7 @@ apply_bif_or_nif_epilogue:
NextPF(2, next);
}
- OpCase(fmove_new_ld): {
+ OpCase(fmove_ld): {
Eterm fr = Arg(0);
Eterm dest = make_float(HTOP);
@@ -4753,11 +5022,6 @@ apply_bif_or_nif_epilogue:
NextPF(2, next);
}
- /*
- * Old allocating fmove.
- */
-
-
#ifdef NO_FPE_SIGNALS
OpCase(fclearerror):
OpCase(i_fcheckerror):
@@ -4969,12 +5233,11 @@ apply_bif_or_nif_epilogue:
OpCase(i_debug_breakpoint): {
SWAPOUT;
reg[0] = r(0);
- tmp_arg1 = call_breakpoint_handler(c_p, I-3, reg);
+ I = call_error_handler(c_p, I-3, reg, am_breakpoint);
r(0) = reg[0];
SWAPIN;
- if (tmp_arg1) {
- SET_I(c_p->i);
- Dispatch();
+ if (I) {
+ Goto(*I);
}
goto no_error_handler;
}
@@ -5633,9 +5896,6 @@ build_stacktrace(Process* c_p, Eterm exc) {
Eterm args;
int depth;
BeamInstr* current;
-#if HALFWORD_HEAP
- BeamInstr current_buff[3];
-#endif
Eterm Where = NIL;
Eterm *next_p = &Where;
@@ -5665,14 +5925,7 @@ build_stacktrace(Process* c_p, Eterm exc) {
* (e.g. spawn_link(erlang, abs, [1])).
*/
if (current == NULL) {
-#if HALFWORD_HEAP
- current = current_buff;
- current[0] = (BeamInstr) c_p->initial[0];
- current[1] = (BeamInstr) c_p->initial[1];
- current[2] = (BeamInstr) c_p->initial[2];
-#else
current = c_p->initial;
-#endif
args = am_true; /* Just in case */
} else {
args = get_args_from_exc(exc);
@@ -5724,8 +5977,8 @@ build_stacktrace(Process* c_p, Eterm exc) {
}
-static Eterm
-call_error_handler(Process* p, BeamInstr* fi, Eterm* reg)
+static BeamInstr*
+call_error_handler(Process* p, BeamInstr* fi, Eterm* reg, Eterm func)
{
Eterm* hp;
Export* ep;
@@ -5737,62 +5990,12 @@ call_error_handler(Process* p, BeamInstr* fi, Eterm* reg)
/*
* Search for the error_handler module.
*/
- ep = erts_find_function(erts_proc_get_error_handler(p),
- am_undefined_function, 3);
- if (ep == NULL) { /* No error handler */
- p->current = fi;
- p->freason = EXC_UNDEF;
- return 0;
- }
- p->i = ep->address;
-
- /*
- * Create a list with all arguments in the x registers.
- */
-
- arity = fi[2];
- sz = 2 * arity;
- if (HeapWordsLeft(p) < sz) {
- erts_garbage_collect(p, sz, reg, arity);
- }
- hp = HEAP_TOP(p);
- HEAP_TOP(p) += sz;
- args = NIL;
- for (i = arity-1; i >= 0; i--) {
- args = CONS(hp, reg[i], args);
- hp += 2;
- }
-
- /*
- * Set up registers for call to error_handler:undefined_function/3.
- */
- reg[0] = fi[0];
- reg[1] = fi[1];
- reg[2] = args;
- return 1;
-}
-
-static Eterm
-call_breakpoint_handler(Process* p, BeamInstr* fi, Eterm* reg)
-{
- Eterm* hp;
- Export* ep;
- int arity;
- Eterm args;
- Uint sz;
- int i;
-
- /*
- * Search for error handler module.
- */
- ep = erts_find_function(erts_proc_get_error_handler(p),
- am_breakpoint, 3);
+ ep = erts_find_function(erts_proc_get_error_handler(p), func, 3);
if (ep == NULL) { /* No error handler */
p->current = fi;
p->freason = EXC_UNDEF;
return 0;
}
- p->i = ep->address;
/*
* Create a list with all arguments in the x registers.
@@ -5812,15 +6015,14 @@ call_breakpoint_handler(Process* p, BeamInstr* fi, Eterm* reg)
}
/*
- * Set up registers for call to error_handler:breakpoint/3.
+ * Set up registers for call to error_handler:<func>/3.
*/
reg[0] = fi[0];
reg[1] = fi[1];
reg[2] = args;
- return 1;
+ return ep->address;
}
-
static Export*
apply_setup_error_handler(Process* p, Eterm module, Eterm function, Uint arity, Eterm* reg)
@@ -6069,6 +6271,7 @@ hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg)
c_p->fvalue = NIL;
PROCESS_MAIN_CHK_LOCKS(c_p);
erts_garbage_collect_hibernate(c_p);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p);
PROCESS_MAIN_CHK_LOCKS(c_p);
erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MSGQ|ERTS_PROC_LOCK_STATUS);
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
@@ -6314,6 +6517,7 @@ new_fun(Process* p, Eterm* reg, ErlFunEntry* fe, int num_free)
if (HEAP_LIMIT(p) - HEAP_TOP(p) <= needed) {
PROCESS_MAIN_CHK_LOCKS(p);
erts_garbage_collect(p, needed, reg, num_free);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(p);
PROCESS_MAIN_CHK_LOCKS(p);
}
hp = p->htop;
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index df5602b040..788cb4209c 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -89,13 +89,12 @@ typedef struct {
} Label;
/*
- * Type for a operand for a generic instruction.
+ * Type for an operand for a generic instruction.
*/
typedef struct {
unsigned type; /* Type of operand. */
- BeamInstr val; /* Value of operand. */
- Uint bigarity; /* Arity for bignumbers (only). */
+ BeamInstr val; /* Value of operand. */
} GenOpArg;
/*
@@ -326,11 +325,6 @@ typedef struct {
Literal* literals; /* Array of literals. */
LiteralPatch* literal_patches; /* Operands that need to be patched. */
Uint total_literal_size; /* Total heap size for all literals. */
-
- /*
- * Floating point.
- */
- int new_float_instructions; /* New allocation scheme for floating point. */
} LoaderState;
typedef struct {
@@ -476,12 +470,14 @@ static int read_code_header(LoaderState* stp);
static int load_code(LoaderState* stp);
static GenOp* gen_element(LoaderState* stp, GenOpArg Fail, GenOpArg Index,
GenOpArg Tuple, GenOpArg Dst);
-static GenOp* gen_split_values(LoaderState* stp, GenOpArg S, GenOpArg Fail,
+static GenOp* gen_split_values(LoaderState* stp, GenOpArg S,
+ GenOpArg TypeFail, GenOpArg Fail,
GenOpArg Size, GenOpArg* Rest);
static GenOp* gen_select_val(LoaderState* stp, GenOpArg S, GenOpArg Fail,
GenOpArg Size, GenOpArg* Rest);
-static GenOp* gen_select_big(LoaderState* stp, GenOpArg S, GenOpArg Fail,
- GenOpArg Size, GenOpArg* Rest);
+static GenOp* gen_select_literals(LoaderState* stp, GenOpArg S,
+ GenOpArg Fail, GenOpArg Size,
+ GenOpArg* Rest);
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,
@@ -818,7 +814,6 @@ init_state(LoaderState* stp)
stp->total_literal_size = 0;
stp->literal_patches = 0;
stp->string_patches = 0;
- stp->new_float_instructions = 0;
stp->may_load_nif = 0;
stp->on_load = 0;
}
@@ -1618,7 +1613,6 @@ load_code(LoaderState* stp)
BeamInstr val;
BeamInstr words = 0;
- stp->new_float_instructions = 1;
GetTagAndValue(stp, tag, n);
VerifyTag(stp, tag, TAG_u);
while (n-- > 0) {
@@ -1772,7 +1766,7 @@ load_code(LoaderState* stp)
}
stp->specific_op = specific;
- CodeNeed(opc[stp->specific_op].sz+2); /* Extra margin for packing */
+ CodeNeed(opc[stp->specific_op].sz+16); /* Extra margin for packing */
code[ci++] = BeamOpCode(stp->specific_op);
}
@@ -1936,7 +1930,8 @@ load_code(LoaderState* stp)
}
code[ci++] = (BeamInstr) stp->import[i].bf;
break;
- case 'P': /* Byte offset into tuple */
+ case 'P': /* Byte offset into tuple or stack */
+ case 'Q': /* Like 'P', but packable */
VerifyTag(stp, tag, TAG_u);
tmp = tmp_op->a[arg].val;
code[ci++] = (BeamInstr) ((tmp_op->a[arg].val+1) * sizeof(Eterm));
@@ -1957,84 +1952,6 @@ load_code(LoaderState* stp)
}
/*
- * Load any list arguments using the primitive tags.
- */
-
- for ( ; arg < tmp_op->arity; arg++) {
- switch (tmp_op->a[arg].type) {
- case TAG_i:
- CodeNeed(1);
- code[ci++] = make_small(tmp_op->a[arg].val);
- break;
- case TAG_u:
- case TAG_a:
- case TAG_v:
- CodeNeed(1);
- code[ci++] = tmp_op->a[arg].val;
- break;
- case TAG_f:
- CodeNeed(1);
- code[ci] = stp->labels[tmp_op->a[arg].val].patches;
- stp->labels[tmp_op->a[arg].val].patches = ci;
- ci++;
- break;
- case TAG_q:
- {
- Eterm lit;
-
- lit = stp->literals[tmp_op->a[arg].val].term;
- if (is_big(lit)) {
- Eterm* bigp;
- Eterm *tmp;
- Uint size;
- Uint term_size;
-
- bigp = big_val(lit);
- term_size = bignum_header_arity(*bigp);
- size = TermWords(term_size + 1);
- CodeNeed(size);
- tmp = (Eterm *) (code + ci);
- *tmp++ = *bigp++;
- while (term_size-- > 0) {
- *tmp++ = *bigp++;
- }
- ci +=size;
- } else if (is_float(lit)) {
-#if defined(ARCH_64) && !HALFWORD_HEAP
- CodeNeed(1);
- code[ci++] = float_val(stp->literals[tmp_op->a[arg].val].term)[1];
-#elif HALFWORD_HEAP
- Eterm* fptr;
- Uint size;
- Eterm *tmp;
-
- fptr = float_val(stp->literals[tmp_op->a[arg].val].term)+1;
- size = TermWords(2);
- CodeNeed(size);
- tmp = (Eterm *) (code + ci);
- *tmp++ = *fptr++;
- *tmp = *fptr;
- ci += size;
-#else
- Eterm* fptr;
-
- fptr = float_val(stp->literals[tmp_op->a[arg].val].term)+1;
- CodeNeed(2);
- code[ci++] = *fptr++;
- code[ci++] = *fptr;
-#endif
- } else {
- LoadError0(stp, "literal is neither float nor big");
- }
- }
- break;
- default:
- LoadError1(stp, "unsupported primitive type '%c'",
- tag_to_letter[tmp_op->a[arg].type]);
- }
- }
-
- /*
* The packing engine.
*/
if (opc[stp->specific_op].pack[0]) {
@@ -2057,6 +1974,11 @@ load_code(LoaderState* stp)
case '6': /* Shift 16 steps */
packed = (packed << BEAM_LOOSE_SHIFT) | code[--ci];
break;
+#ifdef ARCH_64
+ case 'w': /* Shift 32 steps */
+ packed = (packed << BEAM_WIDE_SHIFT) | code[--ci];
+ break;
+#endif
case 'p': /* Put instruction (from stack). */
code[ci++] = *--sp;
break;
@@ -2072,6 +1994,58 @@ load_code(LoaderState* stp)
}
/*
+ * Load any list arguments using the primitive tags.
+ */
+
+ for ( ; arg < tmp_op->arity; arg++) {
+ switch (tmp_op->a[arg].type) {
+ case TAG_i:
+ CodeNeed(1);
+ code[ci++] = make_small(tmp_op->a[arg].val);
+ break;
+ case TAG_u:
+ case TAG_a:
+ case TAG_v:
+ CodeNeed(1);
+ code[ci++] = tmp_op->a[arg].val;
+ break;
+ case TAG_f:
+ CodeNeed(1);
+ code[ci] = stp->labels[tmp_op->a[arg].val].patches;
+ stp->labels[tmp_op->a[arg].val].patches = ci;
+ ci++;
+ break;
+ case TAG_r:
+ CodeNeed(1);
+ code[ci++] = (R_REG_DEF << _TAG_PRIMARY_SIZE) |
+ TAG_PRIMARY_HEADER;
+ break;
+ case TAG_x:
+ CodeNeed(1);
+ code[ci++] = (tmp_op->a[arg].val << _TAG_IMMED1_SIZE) |
+ (X_REG_DEF << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER;
+ break;
+ case TAG_y:
+ CodeNeed(1);
+ code[ci++] = (tmp_op->a[arg].val << _TAG_IMMED1_SIZE) |
+ (Y_REG_DEF << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER;
+ break;
+ case TAG_n:
+ CodeNeed(1);
+ code[ci++] = NIL;
+ break;
+ case TAG_q:
+ CodeNeed(1);
+ new_literal_patch(stp, ci);
+ code[ci++] = tmp_op->a[arg].val;
+ break;
+ default:
+ LoadError1(stp, "unsupported primitive type '%c'",
+ tag_to_letter[tmp_op->a[arg].type]);
+ }
+ }
+
+ /*
* Handle a few special cases.
*/
switch (stp->specific_op) {
@@ -2239,11 +2213,12 @@ use_jump_tab(LoaderState* stp, GenOpArg Size, GenOpArg* Rest)
}
/*
- * Predicate to test whether all values in a table are big numbers.
+ * Predicate to test whether all values in a table are either
+ * floats or bignums.
*/
static int
-all_values_are_big(LoaderState* stp, GenOpArg Size, GenOpArg* Rest)
+floats_or_bignums(LoaderState* stp, GenOpArg Size, GenOpArg* Rest)
{
int i;
@@ -2255,9 +2230,6 @@ all_values_are_big(LoaderState* stp, GenOpArg Size, GenOpArg* Rest)
if (Rest[i].type != TAG_q) {
return 0;
}
- if (is_not_big(stp->literals[Rest[i].val].term)) {
- return 0;
- }
if (Rest[i+1].type != TAG_f) {
return 0;
}
@@ -2317,6 +2289,14 @@ mixed_types(LoaderState* stp, GenOpArg Size, GenOpArg* Rest)
return 0;
}
+static int
+same_label(LoaderState* stp, GenOpArg Target, GenOpArg Label)
+{
+ return Target.type = TAG_f && Label.type == TAG_u &&
+ Target.val == Label.val;
+}
+
+
/*
* Generate an instruction for element/2.
*/
@@ -2328,23 +2308,23 @@ gen_element(LoaderState* stp, GenOpArg Fail, GenOpArg Index,
GenOp* op;
NEW_GENOP(stp, op);
- op->op = genop_i_element_4;
op->arity = 4;
- op->a[0] = Fail;
- op->a[1] = Index;
- op->a[2] = Tuple;
- op->a[3] = Dst;
op->next = NULL;
- /*
- * If safe, generate a faster instruction.
- */
-
if (Index.type == TAG_i && Index.val > 0 &&
(Tuple.type == TAG_r || Tuple.type == TAG_x || Tuple.type == TAG_y)) {
op->op = genop_i_fast_element_4;
- op->a[1].type = TAG_u;
- op->a[1].val = Index.val;
+ op->a[0] = Tuple;
+ op->a[1] = Fail;
+ op->a[2].type = TAG_u;
+ op->a[2].val = Index.val;
+ op->a[3] = Dst;
+ } else {
+ op->op = genop_i_element_4;
+ op->a[0] = Tuple;
+ op->a[1] = Fail;
+ op->a[2] = Index;
+ op->a[3] = Dst;
}
return op;
@@ -2595,8 +2575,6 @@ binary_too_big_bits(LoaderState* stp, GenOpArg Size)
return Size.type == TAG_u && (((Size.val+7)/8) >> (8*sizeof(Uint)-3) != 0);
}
-#define new_float_allocation(Stp) ((Stp)->new_float_instructions)
-
static GenOp*
gen_put_binary(LoaderState* stp, GenOpArg Fail,GenOpArg Size,
GenOpArg Unit, GenOpArg Flags, GenOpArg Src)
@@ -2809,6 +2787,52 @@ gen_skip_bits2(LoaderState* stp, GenOpArg Fail, GenOpArg Ms,
return op;
}
+static GenOp*
+gen_increment(LoaderState* stp, GenOpArg Reg, GenOpArg Integer,
+ GenOpArg Live, GenOpArg Dst)
+{
+ GenOp* op;
+
+ NEW_GENOP(stp, op);
+ op->op = genop_i_increment_4;
+ op->arity = 4;
+ op->next = NULL;
+ op->a[0] = Reg;
+ op->a[1].type = TAG_u;
+ op->a[1].val = Integer.val;
+ op->a[2] = Live;
+ op->a[3] = Dst;
+ return op;
+}
+
+static GenOp*
+gen_increment_from_minus(LoaderState* stp, GenOpArg Reg, GenOpArg Integer,
+ GenOpArg Live, GenOpArg Dst)
+{
+ GenOp* op;
+
+ NEW_GENOP(stp, op);
+ op->op = genop_i_increment_4;
+ op->arity = 4;
+ op->next = NULL;
+ op->a[0] = Reg;
+ op->a[1].type = TAG_u;
+ op->a[1].val = -Integer.val;
+ op->a[2] = Live;
+ op->a[3] = Dst;
+ return op;
+}
+
+/*
+ * Test whether the negation of the given number is small.
+ */
+static int
+negation_is_small(LoaderState* stp, GenOpArg Int)
+{
+ return Int.type == TAG_i && IS_SSMALL(-Int.val);
+}
+
+
static int
smp(LoaderState* stp)
{
@@ -3000,6 +3024,21 @@ gen_select_tuple_arity(LoaderState* stp, GenOpArg S, GenOpArg Fail,
ASSERT(op->a[i].val < op->a[i+2].val);
}
#endif
+
+ /*
+ * Use a special-cased instruction if there are only two values.
+ */
+ if (size == 2) {
+ op->op = genop_i_select_tuple_arity2_6;
+ op->arity--;
+ op->a[2].type = TAG_u;
+ op->a[2].val = arityval(op->a[3].val);
+ op->a[3] = op->a[4];
+ op->a[4].type = TAG_u;
+ op->a[4].val = arityval(op->a[5].val);
+ op->a[5] = op->a[6];
+ }
+
return op;
}
@@ -3009,18 +3048,24 @@ gen_select_tuple_arity(LoaderState* stp, GenOpArg S, GenOpArg Fail,
*/
static GenOp*
-gen_split_values(LoaderState* stp, GenOpArg S, GenOpArg Fail,
- GenOpArg Size, GenOpArg* Rest)
+gen_split_values(LoaderState* stp, GenOpArg S, GenOpArg TypeFail,
+ GenOpArg Fail, GenOpArg Size, GenOpArg* Rest)
{
GenOp* op1;
GenOp* op2;
GenOp* label;
- Uint type;
+ GenOp* is_integer;
int i;
ASSERT(Size.val >= 2 && Size.val % 2 == 0);
+ NEW_GENOP(stp, is_integer);
+ is_integer->op = genop_is_integer_2;
+ is_integer->arity = 2;
+ is_integer->a[0] = TypeFail;
+ is_integer->a[1] = S;
+
NEW_GENOP(stp, label);
label->op = genop_label_1;
label->arity = 1;
@@ -3046,15 +3091,13 @@ gen_split_values(LoaderState* stp, GenOpArg S, GenOpArg Fail,
op2->a[2].type = TAG_u;
op2->a[2].val = 0;
- op1->next = label;
- label->next = op2;
- op2->next = NULL;
-
- type = Rest[0].type;
+ /*
+ * Split the list.
+ */
ASSERT(Size.type == TAG_u);
for (i = 0; i < Size.val; i += 2) {
- GenOp* op = (Rest[i].type == type) ? op1 : op2;
+ GenOp* op = (Rest[i].type == TAG_q) ? op2 : op1;
int dst = 3 + op->a[2].val;
ASSERT(Rest[i+1].type == TAG_f);
@@ -3063,13 +3106,36 @@ gen_split_values(LoaderState* stp, GenOpArg S, GenOpArg Fail,
op->arity += 2;
op->a[2].val += 2;
}
+ ASSERT(op1->a[2].val > 0);
+ ASSERT(op2->a[2].val > 0);
/*
- * None of the instructions should have zero elements in the list.
+ * Order the instruction sequence appropriately.
*/
- ASSERT(op1->a[2].val > 0);
- ASSERT(op2->a[2].val > 0);
+ if (TypeFail.val == Fail.val) {
+ /*
+ * select_val L1 S ... (small numbers)
+ * label L1
+ * is_integer Fail S
+ * select_val Fail S ... (bignums)
+ */
+ op1->next = label;
+ label->next = is_integer;
+ is_integer->next = op2;
+ } else {
+ /*
+ * is_integer TypeFail S
+ * select_val L1 S ... (small numbers)
+ * label L1
+ * select_val Fail S ... (bignums)
+ */
+ is_integer->next = op1;
+ op1->next = label;
+ label->next = op2;
+ op1 = is_integer;
+ }
+ op2->next = NULL;
return op1;
}
@@ -3091,6 +3157,29 @@ gen_jump_tab(LoaderState* stp, GenOpArg S, GenOpArg Fail, GenOpArg Size, GenOpAr
ASSERT(Size.val >= 2 && Size.val % 2 == 0);
/*
+ * If there is only one choice, don't generate a jump table.
+ */
+ if (Size.val == 2) {
+ GenOp* jump;
+
+ NEW_GENOP(stp, op);
+ op->arity = 3;
+ op->op = genop_is_ne_exact_3;
+ op->a[0] = Rest[1];
+ op->a[1] = S;
+ op->a[2] = Rest[0];
+
+ NEW_GENOP(stp, jump);
+ jump->next = NULL;
+ jump->arity = 1;
+ jump->op = genop_jump_1;
+ jump->a[0] = Fail;
+
+ op->next = jump;
+ return op;
+ }
+
+ /*
* Calculate the minimum and maximum values and size of jump table.
*/
@@ -3162,8 +3251,9 @@ genopargcompare(GenOpArg* a, GenOpArg* b)
}
/*
- * Generate a select_val instruction. We know that a jump table is not suitable,
- * and that all values are of the same type (integer, atoms, floats; never bignums).
+ * Generate a select_val instruction. We know that a jump table
+ * is not suitable, and that all values are of the same type
+ * (integer or atoms).
*/
static GenOp*
@@ -3177,12 +3267,7 @@ gen_select_val(LoaderState* stp, GenOpArg S, GenOpArg Fail,
NEW_GENOP(stp, op);
op->next = NULL;
- if (Rest[0].type != TAG_q) {
- op->op = genop_i_select_val_3;
- } else {
- ASSERT(is_float(stp->literals[Rest[0].val].term));
- op->op = genop_i_select_float_3;
- }
+ op->op = genop_i_select_val_3;
GENOP_ARITY(op, arity);
op->a[0] = S;
op->a[1] = Fail;
@@ -3204,19 +3289,19 @@ gen_select_val(LoaderState* stp, GenOpArg S, GenOpArg Fail,
}
#endif
- return op;
-}
-
-/*
- * Compare function for qsort().
- */
+ /*
+ * Use a special-cased instruction if there are only two values.
+ */
+ if (size == 2) {
+ op->op = genop_i_select_val2_6;
+ op->arity--;
+ op->a[2] = op->a[3];
+ op->a[3] = op->a[4];
+ op->a[4] = op->a[5];
+ op->a[5] = op->a[6];
+ }
-static int
-genbigcompare(GenOpArg* a, GenOpArg* b)
-{
- int val = (int)(b->bigarity - a->bigarity);
-
- return val != 0 ? val : ((int) (a->val - b->val));
+ return op;
}
/*
@@ -3224,37 +3309,35 @@ genbigcompare(GenOpArg* a, GenOpArg* b)
*/
static GenOp*
-gen_select_big(LoaderState* stp, GenOpArg S, GenOpArg Fail,
+gen_select_literals(LoaderState* stp, GenOpArg S, GenOpArg Fail,
GenOpArg Size, GenOpArg* Rest)
{
GenOp* op;
- int arity = Size.val + 2 + 1;
- int size = Size.val / 2;
+ GenOp* jump;
+ GenOp** prev_next = &op;
+
int i;
- NEW_GENOP(stp, op);
- op->next = NULL;
- op->op = genop_i_select_big_2;
- GENOP_ARITY(op, arity);
- op->a[0] = S;
- op->a[1] = Fail;
for (i = 0; i < Size.val; i += 2) {
+ GenOp* op;
ASSERT(Rest[i].type == TAG_q);
- op->a[i+2] = Rest[i];
- op->a[i+2].bigarity = *big_val(stp->literals[op->a[i+2].val].term);
- op->a[i+3] = Rest[i+1];
- }
- ASSERT(i+2 == arity-1);
- op->a[arity-1].type = TAG_u;
- op->a[arity-1].val = 0;
-
- /*
- * Sort the values in descending arity order.
- */
-
- qsort(op->a+2, size, 2*sizeof(GenOpArg),
- (int (*)(const void *, const void *)) genbigcompare);
+ NEW_GENOP(stp, op);
+ op->op = genop_is_ne_exact_3;
+ op->arity = 3;
+ op->a[0] = Rest[i+1];
+ op->a[1] = S;
+ op->a[2] = Rest[i];
+ *prev_next = op;
+ prev_next = &op->next;
+ }
+
+ NEW_GENOP(stp, jump);
+ jump->next = NULL;
+ jump->op = genop_jump_1;
+ jump->arity = 1;
+ jump->a[0] = Fail;
+ *prev_next = jump;
return op;
}
@@ -3272,7 +3355,6 @@ const_select_val(LoaderState* stp, GenOpArg S, GenOpArg Fail,
int i;
ASSERT(Size.type == TAG_u);
- ASSERT(S.type == TAG_q);
NEW_GENOP(stp, op);
op->next = NULL;
@@ -3283,18 +3365,32 @@ const_select_val(LoaderState* stp, GenOpArg S, GenOpArg Fail,
* Search for a literal matching the controlling expression.
*/
- if (S.type == TAG_q) {
- Eterm expr = stp->literals[S.val].term;
- for (i = 0; i < Size.val; i += 2) {
- if (Rest[i].type == TAG_q) {
- Eterm term = stp->literals[Rest[i].val].term;
- if (eq(term, expr)) {
- ASSERT(Rest[i+1].type == TAG_f);
- op->a[0] = Rest[i+1];
- return op;
+ switch (S.type) {
+ case TAG_q:
+ {
+ Eterm expr = stp->literals[S.val].term;
+ for (i = 0; i < Size.val; i += 2) {
+ if (Rest[i].type == TAG_q) {
+ Eterm term = stp->literals[Rest[i].val].term;
+ if (eq(term, expr)) {
+ ASSERT(Rest[i+1].type == TAG_f);
+ op->a[0] = Rest[i+1];
+ return op;
+ }
}
}
}
+ break;
+ case TAG_i:
+ case TAG_a:
+ for (i = 0; i < Size.val; i += 2) {
+ if (Rest[i].val == S.val && Rest[i].type == S.type) {
+ ASSERT(Rest[i+1].type == TAG_f);
+ op->a[0] = Rest[i+1];
+ return op;
+ }
+ }
+ break;
}
/*
@@ -3477,6 +3573,56 @@ gen_guard_bif3(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
return op;
}
+static GenOp*
+tuple_append_put5(LoaderState* stp, GenOpArg Arity, GenOpArg Dst,
+ GenOpArg* Puts, GenOpArg S1, GenOpArg S2, GenOpArg S3,
+ GenOpArg S4, GenOpArg S5)
+{
+ GenOp* op;
+ int arity = Arity.val; /* Arity of tuple, not the instruction */
+ int i;
+
+ NEW_GENOP(stp, op);
+ op->next = NULL;
+ GENOP_ARITY(op, arity+2+5);
+ op->op = genop_i_put_tuple_2;
+ op->a[0] = Dst;
+ op->a[1].type = TAG_u;
+ op->a[1].val = arity + 5;
+ for (i = 0; i < arity; i++) {
+ op->a[i+2] = Puts[i];
+ }
+ op->a[arity+2] = S1;
+ op->a[arity+3] = S2;
+ op->a[arity+4] = S3;
+ op->a[arity+5] = S4;
+ op->a[arity+6] = S5;
+ return op;
+}
+
+static GenOp*
+tuple_append_put(LoaderState* stp, GenOpArg Arity, GenOpArg Dst,
+ GenOpArg* Puts, GenOpArg S)
+{
+ GenOp* op;
+ int arity = Arity.val; /* Arity of tuple, not the instruction */
+ int i;
+
+ NEW_GENOP(stp, op);
+ op->next = NULL;
+ GENOP_ARITY(op, arity+2+1);
+ op->op = genop_i_put_tuple_2;
+ op->a[0] = Dst;
+ op->a[1].type = TAG_u;
+ op->a[1].val = arity + 1;
+ for (i = 0; i < arity; i++) {
+ op->a[i+2] = Puts[i];
+ }
+ op->a[arity+2] = S;
+ return op;
+}
+
+
/*
* Freeze the code in memory, move the string table into place,
@@ -3624,25 +3770,32 @@ freeze_code(LoaderState* stp)
CHKBLK(ERTS_ALC_T_CODE,code);
if (compile_size) {
byte* compile_info = str_table + strtab_size + attr_size;
- CHKBLK(ERTS_ALC_T_CODE,code);
+ CHKBLK(ERTS_ALC_T_CODE,code);
sys_memcpy(compile_info, stp->chunks[COMPILE_CHUNK].start,
stp->chunks[COMPILE_CHUNK].size);
- CHKBLK(ERTS_ALC_T_CODE,code);
+
+ CHKBLK(ERTS_ALC_T_CODE,code);
code[MI_COMPILE_PTR] = (BeamInstr) compile_info;
- CHKBLK(ERTS_ALC_T_CODE,code);
+ CHKBLK(ERTS_ALC_T_CODE,code);
code[MI_COMPILE_SIZE] = (BeamInstr) stp->chunks[COMPILE_CHUNK].size;
- CHKBLK(ERTS_ALC_T_CODE,code);
+ CHKBLK(ERTS_ALC_T_CODE,code);
decoded_size = erts_decode_ext_size(compile_info, compile_size, 0);
- CHKBLK(ERTS_ALC_T_CODE,code);
+ CHKBLK(ERTS_ALC_T_CODE,code);
if (decoded_size < 0) {
LoadError0(stp, "bad external term representation of compilation information");
}
- CHKBLK(ERTS_ALC_T_CODE,code);
+ CHKBLK(ERTS_ALC_T_CODE,code);
code[MI_COMPILE_SIZE_ON_HEAP] = decoded_size;
}
CHKBLK(ERTS_ALC_T_CODE,code);
/*
+ * Make sure that we have not overflowed the allocated code space.
+ */
+ ASSERT(str_table + strtab_size + attr_size + compile_size ==
+ ((byte *) code) + size);
+
+ /*
* Go through all i_new_bs_put_strings instructions, restore the pointer to
* the instruction and convert string offsets to pointers (to the
* FIRST character).
@@ -3876,11 +4029,23 @@ transform_engine(LoaderState* st)
if (i == 0)
goto restart;
break;
+#if defined(TOP_is_eq)
case TOP_is_eq:
ASSERT(ap < instr->arity);
if (*pc++ != instr->a[ap].val)
goto restart;
break;
+#endif
+ case TOP_is_type_eq:
+ mask = *pc++;
+
+ ASSERT(ap < instr->arity);
+ ASSERT(instr->a[ap].type < BEAM_NUM_TAGS);
+ if (((1 << instr->a[ap].type) & mask) == 0)
+ goto restart;
+ if (*pc++ != instr->a[ap].val)
+ goto restart;
+ break;
case TOP_is_same_var:
ASSERT(ap < instr->arity);
i = *pc++;
@@ -4001,14 +4166,17 @@ transform_engine(LoaderState* st)
case TOP_rest_args:
{
int n = *pc++;
+ int formal_arity = gen_opc[instr->op].arity;
+ int num_vars = n + (instr->arity - formal_arity);
+ int j = formal_arity;
+
var = erts_alloc(ERTS_ALC_T_LOADER_TMP,
- instr->arity * sizeof(GenOpArg));
+ num_vars * sizeof(GenOpArg));
for (i = 0; i < n; i++) {
var[i] = def_vars[i];
}
- while (i < instr->arity) {
- var[i] = instr->a[i];
- i++;
+ while (i < num_vars) {
+ var[i++] = instr->a[j++];
}
}
break;
@@ -5315,6 +5483,9 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
if (state.lambdas != state.def_lambdas) {
erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.lambdas);
}
+ erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.labels);
+ erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.atom);
+ erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.export);
if (bin != NULL) {
driver_free_binary(bin);
}
@@ -5326,9 +5497,18 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
if (code != NULL) {
erts_free(ERTS_ALC_T_CODE, code);
}
+ if (state.labels != NULL) {
+ erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.labels);
+ }
if (state.lambdas != state.def_lambdas) {
erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.lambdas);
}
+ if (state.atom != NULL) {
+ erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.atom);
+ }
+ if (state.export != NULL) {
+ erts_free(ERTS_ALC_T_LOADER_TMP, (void *) state.export);
+ }
if (bin != NULL) {
driver_free_binary(bin);
}
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 6e9755ad48..bb237e378a 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -813,7 +813,7 @@ BIF_RETTYPE spawn_opt_1(BIF_ALIST_1)
so.min_heap_size = H_MIN_SIZE;
so.min_vheap_size = BIN_VH_MIN_SIZE;
so.priority = PRIORITY_NORMAL;
- so.max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs);
+ so.max_gen_gcs = (Uint16) erts_smp_atomic32_read(&erts_max_gen_gcs);
so.scheduler = 0;
/*
@@ -1351,9 +1351,10 @@ BIF_RETTYPE exit_2(BIF_ALIST_2)
#ifdef ERTS_SMP
if (rp == BIF_P)
rp_locks &= ~ERTS_PROC_LOCK_MAIN;
- else
+ if (rp_locks)
+ erts_smp_proc_unlock(rp, rp_locks);
+ if (rp != BIF_P)
erts_smp_proc_dec_refc(rp);
- erts_smp_proc_unlock(rp, rp_locks);
#endif
/*
* We may have exited ourselves and may have to take action.
@@ -3269,12 +3270,13 @@ BIF_RETTYPE ports_0(BIF_ALIST_0)
erts_smp_mtx_lock(&ports_snapshot_mtx); /* One snapshot at a time */
- erts_smp_atomic_set(&erts_dead_ports_ptr, (long) (port_buf + erts_max_ports));
+ erts_smp_atomic_set(&erts_dead_ports_ptr,
+ (erts_aint_t) (port_buf + erts_max_ports));
next_ss = erts_smp_atomic_inctest(&erts_ports_snapshot);
if (erts_smp_atomic_read(&erts_ports_alive) > 0) {
- long i;
+ erts_aint_t i;
for (i = erts_max_ports-1; i >= 0; i--) {
Port* prt = &erts_port[i];
erts_smp_port_state_lock(prt);
@@ -3289,7 +3291,7 @@ BIF_RETTYPE ports_0(BIF_ALIST_0)
}
dead_ports = (Eterm*)erts_smp_atomic_xchg(&erts_dead_ports_ptr,
- (long)NULL);
+ (erts_aint_t) NULL);
erts_smp_mtx_unlock(&ports_snapshot_mtx);
ASSERT(pp <= dead_ports);
@@ -3300,7 +3302,7 @@ BIF_RETTYPE ports_0(BIF_ALIST_0)
ASSERT((alive+dead) <= erts_max_ports);
if (alive+dead > 0) {
- long i;
+ erts_aint_t i;
Eterm *hp = HAlloc(BIF_P, (alive+dead)*2);
for (i = 0; i < alive; i++) {
@@ -3796,7 +3798,8 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
goto error;
}
nval = (n > (Sint) ((Uint16) -1)) ? ((Uint16) -1) : ((Uint16) n);
- oval = (Uint) erts_smp_atomic_xchg(&erts_max_gen_gcs, (long) nval);
+ oval = (Uint) erts_smp_atomic32_xchg(&erts_max_gen_gcs,
+ (erts_aint32_t) nval);
BIF_RET(make_small(oval));
} else if (BIF_ARG_1 == am_min_heap_size) {
int oval = H_MIN_SIZE;
@@ -4139,7 +4142,7 @@ void erts_init_bif(void)
erts_smp_spinlock_init(&make_ref_lock, "make_ref");
erts_smp_mtx_init(&ports_snapshot_mtx, "ports_snapshot");
- erts_smp_atomic_init(&erts_dead_ports_ptr, (long)NULL);
+ erts_smp_atomic_init(&erts_dead_ports_ptr, (erts_aint_t) NULL);
/*
* bif_return_trap/1 is a hidden BIF that bifs that need to
diff --git a/erts/emulator/beam/bif.h b/erts/emulator/beam/bif.h
index 50f5f4fbd6..a84ee7bb23 100644
--- a/erts/emulator/beam/bif.h
+++ b/erts/emulator/beam/bif.h
@@ -135,7 +135,6 @@ do { \
(Proc)->arity = 1; \
(Proc)->def_arg_reg[0] = (Eterm) (A0); \
*((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \
- (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \
(Proc)->freason = TRAP; \
(Ret) = THE_NON_VALUE; \
} while (0)
@@ -146,7 +145,6 @@ do { \
(Proc)->def_arg_reg[0] = (Eterm) (A0); \
(Proc)->def_arg_reg[1] = (Eterm) (A1); \
*((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \
- (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \
(Proc)->freason = TRAP; \
(Ret) = THE_NON_VALUE; \
} while (0)
@@ -158,7 +156,6 @@ do { \
(Proc)->def_arg_reg[1] = (Eterm) (A1); \
(Proc)->def_arg_reg[2] = (Eterm) (A2); \
*((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \
- (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \
(Proc)->freason = TRAP; \
(Ret) = THE_NON_VALUE; \
} while (0)
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 0674aae77f..d9dd80fa8b 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -660,6 +660,7 @@ bif erts_debug:display/1
bif 'erl.system.debug':display/1 ebif_erts_debug_display_1
bif erts_debug:dist_ext_to_term/2
bif 'erl.system.debug':dist_ext_to_term/2 ebif_erts_debug_dist_ext_to_term_2
+bif erts_debug:instructions/0
#
# Monitor testing bif's...
@@ -795,6 +796,13 @@ bif erlang:nif_error/1
bif erlang:nif_error/2
#
+# Helpers for unicode filenames
+#
+bif prim_file:internal_name2native/1
+bif prim_file:internal_native2name/1
+bif prim_file:internal_normalize_utf8/1
+bif file:native_name_encoding/0
+#
# Obsolete
#
diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c
index ff15d834ab..f47f5a9c0c 100644
--- a/erts/emulator/beam/big.c
+++ b/erts/emulator/beam/big.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -1558,7 +1558,7 @@ Eterm erts_sint64_to_big(Sint64 x, Eterm **hpp)
** Convert a bignum to a double float
*/
int
-big_to_double(Eterm x, double* resp)
+big_to_double(Wterm x, double* resp)
{
double d = 0.0;
Eterm* xp = big_val(x);
@@ -1725,7 +1725,7 @@ static Eterm big_norm(Eterm *x, dsize_t xl, short sign)
/*
** Compare bignums
*/
-int big_comp(Eterm x, Eterm y)
+int big_comp(Wterm x, Wterm y)
{
Eterm* xp = big_val(x);
Eterm* yp = big_val(y);
@@ -2060,7 +2060,7 @@ static Eterm B_plus_minus(ErtsDigit *x, dsize_t xl, short xsgn,
/*
** Add bignums
*/
-Eterm big_plus(Eterm x, Eterm y, Eterm *r)
+Eterm big_plus(Wterm x, Wterm y, Eterm *r)
{
Eterm* xp = big_val(x);
Eterm* yp = big_val(y);
diff --git a/erts/emulator/beam/big.h b/erts/emulator/beam/big.h
index 25466cd3c2..f28a390aea 100644
--- a/erts/emulator/beam/big.h
+++ b/erts/emulator/beam/big.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -120,7 +120,7 @@ char *erts_big_to_string(Eterm x, char *buf, Uint buf_sz);
Eterm small_times(Sint, Sint, Eterm*);
-Eterm big_plus(Eterm, Eterm, Eterm*);
+Eterm big_plus(Wterm, Wterm, Eterm*);
Eterm big_minus(Eterm, Eterm, Eterm*);
Eterm big_times(Eterm, Eterm, Eterm*);
Eterm big_div(Eterm, Eterm, Eterm*);
@@ -137,9 +137,9 @@ Eterm big_bxor(Eterm, Eterm, Eterm*);
Eterm big_bnot(Eterm, Eterm*);
Eterm big_lshift(Eterm, Sint, Eterm*);
-int big_comp (Eterm, Eterm);
+int big_comp (Wterm, Wterm);
int big_ucomp (Eterm, Eterm);
-int big_to_double(Eterm x, double* resp);
+int big_to_double(Wterm x, double* resp);
Eterm small_to_big(Sint, Eterm*);
Eterm uint_to_big(Uint, Eterm*);
Eterm uword_to_big(UWord, Eterm*);
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index 8ee8fbcb29..4be869f269 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -217,8 +217,8 @@ erts_get_aligned_binary_bytes_extra(Eterm bin, byte** base_ptr, ErtsAlcType_t al
return bytes;
}
-static Eterm
-bin_bytes_to_list(Eterm previous, Eterm* hp, byte* bytes, Uint size, Uint bitoffs)
+Eterm
+erts_bin_bytes_to_list(Eterm previous, Eterm* hp, byte* bytes, Uint size, Uint bitoffs)
{
if (bitoffs == 0) {
while (size) {
@@ -263,7 +263,7 @@ BIF_RETTYPE binary_to_list_1(BIF_ALIST_1)
Eterm* hp = HAlloc(BIF_P, 2 * size);
byte* bytes = binary_bytes(real_bin)+offset;
- BIF_RET(bin_bytes_to_list(NIL, hp, bytes, size, bitoffs));
+ BIF_RET(erts_bin_bytes_to_list(NIL, hp, bytes, size, bitoffs));
}
error:
@@ -295,7 +295,7 @@ BIF_RETTYPE binary_to_list_3(BIF_ALIST_3)
}
i = stop-start+1;
hp = HAlloc(BIF_P, 2*i);
- BIF_RET(bin_bytes_to_list(NIL, hp, bytes+start-1, i, bitoffs));
+ BIF_RET(erts_bin_bytes_to_list(NIL, hp, bytes+start-1, i, bitoffs));
error:
BIF_ERROR(BIF_P, BADARG);
@@ -339,7 +339,7 @@ BIF_RETTYPE bitstring_to_list_1(BIF_ALIST_1)
previous = CONS(hp, make_binary(last), previous);
hp += 2;
}
- BIF_RET(bin_bytes_to_list(previous, hp, bytes, size, bitoffs));
+ BIF_RET(erts_bin_bytes_to_list(previous, hp, bytes, size, bitoffs));
}
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index f339e19761..d255cf3558 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -98,7 +98,7 @@ process_killer(void)
switch(j) {
case 'k':
if (rp->status == P_WAITING) {
- Uint32 rp_locks = ERTS_PROC_LOCKS_XSIG_SEND;
+ ErtsProcLocks rp_locks = ERTS_PROC_LOCKS_XSIG_SEND;
erts_smp_proc_inc_refc(rp);
erts_smp_proc_lock(rp, rp_locks);
(void) erts_send_exit_signal(NULL,
@@ -558,7 +558,7 @@ do_break(void)
#endif
#ifdef DEBUG
case 't':
- p_slpq();
+ erts_p_slpq();
return;
case 'b':
bin_check();
@@ -624,9 +624,9 @@ bin_check(void)
erts_printf("Process %T holding binary data \n", rp->id);
printed = 1;
}
- erts_printf("0x%08lx orig_size: %ld, norefs = %ld\n",
- (unsigned long)bp->val,
- (long)bp->val->orig_size,
+ erts_printf("%p orig_size: %bpd, norefs = %bpd\n",
+ bp->val,
+ bp->val->orig_size,
erts_smp_atomic_read(&bp->val->refc));
}
}
diff --git a/erts/emulator/beam/copy.c b/erts/emulator/beam/copy.c
index 8bee47232e..243e8973cf 100644
--- a/erts/emulator/beam/copy.c
+++ b/erts/emulator/beam/copy.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -72,8 +72,11 @@ copy_object(Eterm obj, Process* to)
* Return the "flat" size of the object.
*/
-Uint
-size_object(Eterm obj)
+#if HALFWORD_HEAP
+Uint size_object_rel(Eterm obj, Eterm* base)
+#else
+Uint size_object(Eterm obj)
+#endif
{
Uint sum = 0;
Eterm* ptr;
@@ -84,7 +87,7 @@ size_object(Eterm obj)
switch (primary_tag(obj)) {
case TAG_PRIMARY_LIST:
sum += 2;
- ptr = list_val(obj);
+ ptr = list_val_rel(obj,base);
obj = *ptr++;
if (!IS_CONST(obj)) {
ESTACK_PUSH(s, obj);
@@ -93,11 +96,11 @@ size_object(Eterm obj)
break;
case TAG_PRIMARY_BOXED:
{
- Eterm hdr = *boxed_val(obj);
+ Eterm hdr = *boxed_val_rel(obj,base);
ASSERT(is_header(hdr));
switch (hdr & _TAG_HEADER_MASK) {
case ARITYVAL_SUBTAG:
- ptr = tuple_val(obj);
+ ptr = tuple_val_rel(obj,base);
arity = header_arity(hdr);
sum += arity + 1;
if (arity == 0) { /* Empty tuple -- unusual. */
@@ -113,7 +116,7 @@ size_object(Eterm obj)
break;
case FUN_SUBTAG:
{
- Eterm* bptr = fun_val(obj);
+ Eterm* bptr = fun_val_rel(obj,base);
ErlFunThing* funp = (ErlFunThing *) bptr;
unsigned eterms = 1 /* creator */ + funp->num_free;
unsigned sz = thing_arityval(hdr);
@@ -136,7 +139,7 @@ size_object(Eterm obj)
Uint bitoffs;
Uint extra_bytes;
Eterm hdr;
- ERTS_GET_REAL_BIN(obj, real_bin, offset, bitoffs, bitsize);
+ ERTS_GET_REAL_BIN_REL(obj, real_bin, offset, bitoffs, bitsize, base);
if ((bitsize + bitoffs) > 8) {
sum += ERL_SUB_BIN_SIZE;
extra_bytes = 2;
@@ -146,11 +149,11 @@ size_object(Eterm obj)
} else {
extra_bytes = 0;
}
- hdr = *binary_val(real_bin);
+ hdr = *binary_val_rel(real_bin,base);
if (thing_subtag(hdr) == REFC_BINARY_SUBTAG) {
sum += PROC_BIN_SIZE;
} else {
- sum += heap_bin_size(binary_size(obj)+extra_bytes);
+ sum += heap_bin_size(binary_size_rel(obj,base)+extra_bytes);
}
goto pop_next;
}
@@ -181,8 +184,12 @@ size_object(Eterm obj)
/*
* Copy a structure to a heap.
*/
-Eterm
-copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
+#if HALFWORD_HEAP
+Eterm copy_struct_rel(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap,
+ Eterm* src_base, Eterm* dst_base)
+#else
+Eterm copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
+#endif
{
char* hstart;
Uint hsize;
@@ -214,7 +221,10 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
/* Copy the object onto the heap */
switch (primary_tag(obj)) {
- case TAG_PRIMARY_LIST: argp = &res; goto L_copy_list;
+ case TAG_PRIMARY_LIST:
+ argp = &res;
+ objp = list_val_rel(obj,src_base);
+ goto L_copy_list;
case TAG_PRIMARY_BOXED: argp = &res; goto L_copy_boxed;
default:
erl_exit(ERTS_ABORT_EXIT,
@@ -231,32 +241,46 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
hp++;
break;
case TAG_PRIMARY_LIST:
- objp = list_val(obj);
+ objp = list_val_rel(obj,src_base);
+ #if !HALFWORD_HEAP || defined(DEBUG)
if (in_area(objp,hstart,hsize)) {
+ ASSERT(!HALFWORD_HEAP);
hp++;
break;
}
+ #endif
argp = hp++;
/* Fall through */
L_copy_list:
tailp = argp;
- while (is_list(obj)) {
- objp = list_val(obj);
+ for (;;) {
tp = tailp;
- elem = *objp;
+ elem = CAR(objp);
if (IS_CONST(elem)) {
- *(hbot-2) = elem;
- tailp = hbot-1;
hbot -= 2;
+ CAR(hbot) = elem;
+ tailp = &CDR(hbot);
}
else {
- *htop = elem;
- tailp = htop+1;
+ CAR(htop) = elem;
+ #if HALFWORD_HEAP
+ CDR(htop) = CDR(objp);
+ *tailp = make_list_rel(htop,dst_base);
+ htop += 2;
+ goto L_copy;
+ #else
+ tailp = &CDR(htop);
htop += 2;
+ #endif
+ }
+ ASSERT(!HALFWORD_HEAP || tp < hp || tp >= hbot);
+ *tp = make_list_rel(tailp - 1, dst_base);
+ obj = CDR(objp);
+ if (!is_list(obj)) {
+ break;
}
- *tp = make_list(tailp - 1);
- obj = *(objp+1);
+ objp = list_val_rel(obj,src_base);
}
switch (primary_tag(obj)) {
case TAG_PRIMARY_IMMED1: *tailp = obj; goto L_copy;
@@ -268,21 +292,24 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
}
case TAG_PRIMARY_BOXED:
- if (in_area(boxed_val(obj),hstart,hsize)) {
+ #if !HALFWORD_HEAP || defined(DEBUG)
+ if (in_area(boxed_val_rel(obj,src_base),hstart,hsize)) {
+ ASSERT(!HALFWORD_HEAP);
hp++;
break;
}
+ #endif
argp = hp++;
L_copy_boxed:
- objp = boxed_val(obj);
+ objp = boxed_val_rel(obj, src_base);
hdr = *objp;
switch (hdr & _TAG_HEADER_MASK) {
case ARITYVAL_SUBTAG:
{
int const_flag = 1; /* assume constant tuple */
i = arityval(hdr);
- *argp = make_tuple(htop);
+ *argp = make_tuple_rel(htop, dst_base);
tp = htop; /* tp is pointer to new arity value */
*htop++ = *objp++; /* copy arity value */
while (i--) {
@@ -311,7 +338,7 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
while (i--) {
*tp++ = *objp++;
}
- *argp = make_binary(hbot);
+ *argp = make_binary_rel(hbot, dst_base);
pb = (ProcBin*) hbot;
erts_refc_inc(&pb->val->refc, 2);
pb->next = off_heap->first;
@@ -338,7 +365,7 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
extra_bytes = 0;
}
real_size = size+extra_bytes;
- objp = binary_val(real_bin);
+ objp = binary_val_rel(real_bin,src_base);
if (thing_subtag(*objp) == HEAP_BINARY_SUBTAG) {
ErlHeapBin* from = (ErlHeapBin *) objp;
ErlHeapBin* to;
@@ -368,7 +395,7 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
off_heap->first = (struct erl_off_heap_header*) to;
OH_OVERHEAD(off_heap, to->size / sizeof(Eterm));
}
- *argp = make_binary(hbot);
+ *argp = make_binary_rel(hbot, dst_base);
if (extra_bytes != 0) {
ErlSubBin* res;
hbot -= ERL_SUB_BIN_SIZE;
@@ -380,7 +407,7 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
res->offs = 0;
res->is_writable = 0;
res->orig = *argp;
- *argp = make_binary(hbot);
+ *argp = make_binary_rel(hbot, dst_base);
}
break;
}
@@ -400,7 +427,7 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
off_heap->first = (struct erl_off_heap_header*) funp;
erts_refc_inc(&funp->fe->refc, 2);
#endif
- *argp = make_fun(tp);
+ *argp = make_fun_rel(tp, dst_base);
}
break;
case EXTERNAL_PID_SUBTAG:
@@ -420,7 +447,7 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
off_heap->first = (struct erl_off_heap_header*)etp;
erts_refc_inc(&etp->node->refc, 2);
- *argp = make_external(tp);
+ *argp = make_external_rel(tp, dst_base);
}
break;
case BIN_MATCHSTATE_SUBTAG:
@@ -430,7 +457,7 @@ copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
i = thing_arityval(hdr)+1;
hbot -= i;
tp = hbot;
- *argp = make_boxed(hbot);
+ *argp = make_boxed_rel(hbot, dst_base);
while (i--) {
*tp++ = *objp++;
}
@@ -885,12 +912,21 @@ Eterm copy_struct_lazy(Process *from, Eterm orig, Uint offs)
*
* NOTE: Assumes that term is a tuple (ptr is an untagged tuple ptr).
*/
-Eterm
-copy_shallow(Eterm* ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
+#if HALFWORD_HEAP
+Eterm copy_shallow_rel(Eterm* ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap,
+ Eterm* src_base)
+#else
+Eterm copy_shallow(Eterm* ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
+#endif
{
Eterm* tp = ptr;
Eterm* hp = *hpp;
- Sint offs = hp - tp;
+ const Eterm res = make_tuple(hp);
+#if HALFWORD_HEAP
+ const Sint offs = COMPRESS_POINTER(hp - (tp - src_base));
+#else
+ const Sint offs = (hp - tp) * sizeof(Eterm);
+#endif
while (sz--) {
Eterm val = *tp++;
@@ -901,7 +937,7 @@ copy_shallow(Eterm* ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
break;
case TAG_PRIMARY_LIST:
case TAG_PRIMARY_BOXED:
- *hp++ = offset_ptr(val, offs);
+ *hp++ = byte_offset_ptr(val, offs);
break;
case TAG_PRIMARY_HEADER:
*hp++ = val;
@@ -958,7 +994,8 @@ copy_shallow(Eterm* ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
}
}
*hpp = hp;
- return make_tuple(ptr + offs);
+
+ return res;
}
/* Move all terms in heap fragments into heap. The terms must be guaranteed to
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 16b6aeac3f..02910fad90 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -97,6 +97,8 @@ dist_msg_dbg(ErtsDistExternal *edep, char *what, byte *buf, int sz)
#define PASS_THROUGH 'p' /* This code should go */
int erts_is_alive; /* System must be blocked on change */
+int erts_dist_buf_busy_limit;
+
/* distribution trap functions */
Export* dsend2_trap = NULL;
@@ -160,7 +162,7 @@ Uint erts_dist_cache_size(void)
static ErtsProcList *
get_suspended_on_de(DistEntry *dep, Uint32 unset_qflgs)
{
- ERTS_SMP_LC_ASSERT(erts_smp_lc_spinlock_is_locked(&dep->qlock));
+ ERTS_SMP_LC_ASSERT(erts_smp_lc_mtx_is_locked(&dep->qlock));
dep->qflgs &= ~unset_qflgs;
if (dep->qflgs & ERTS_DE_QFLG_EXIT) {
/* No resume when exit has been scheduled */
@@ -453,17 +455,17 @@ int erts_do_net_exits(DistEntry *dep, Eterm reason)
if (dep->status & ERTS_DE_SFLG_EXITING) {
#ifdef DEBUG
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
ASSERT(dep->qflgs & ERTS_DE_QFLG_EXIT);
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
#endif
}
else {
dep->status |= ERTS_DE_SFLG_EXITING;
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
ASSERT(!(dep->qflgs & ERTS_DE_QFLG_EXIT));
dep->qflgs |= ERTS_DE_QFLG_EXIT;
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
}
erts_smp_de_links_lock(dep);
@@ -577,7 +579,7 @@ static void clear_dist_entry(DistEntry *dep)
erts_smp_de_links_unlock(dep);
#endif
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
if (!dep->out_queue.last)
obuf = dep->finalized_out_queue.first;
@@ -593,7 +595,7 @@ static void clear_dist_entry(DistEntry *dep)
dep->status = 0;
suspendees = get_suspended_on_de(dep, ERTS_DE_QFLGS_ALL);
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
erts_smp_atomic_set(&dep->dist_cmd_scheduled, 0);
dep->send = NULL;
erts_smp_de_rwunlock(dep);
@@ -611,10 +613,10 @@ static void clear_dist_entry(DistEntry *dep)
}
if (obufsize) {
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
ASSERT(dep->qsize >= obufsize);
dep->qsize -= obufsize;
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
}
}
@@ -915,6 +917,7 @@ int erts_net_message(Port *prt,
Eterm token_size;
ErtsMonitor *mon;
ErtsLink *lnk;
+ Uint tuple_arity;
int res;
#ifdef ERTS_DIST_MSG_DBG
int orig_len = len;
@@ -1001,29 +1004,23 @@ int erts_net_message(Port *prt,
#endif
if (is_not_tuple(arg) ||
- (tuple = tuple_val(arg), arityval(*tuple) < 1) ||
+ (tuple = tuple_val(arg), (tuple_arity = arityval(*tuple)) < 1) ||
is_not_small(tuple[1])) {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- erts_dsprintf(dsbufp, "Invalid distribution message: %.200T", arg);
- erts_send_error_to_logger_nogl(dsbufp);
- goto data_error;
+ goto invalid_message;
}
token_size = 0;
switch (type = unsigned_val(tuple[1])) {
case DOP_LINK:
+ if (tuple_arity != 3) {
+ goto invalid_message;
+ }
from = tuple[2];
to = tuple[3]; /* local proc to link to */
if (is_not_pid(from) || is_not_pid(to)) {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- PURIFY_MSG("data error");
- erts_dsprintf(dsbufp,
- "Invalid DOP_LINK distribution message: %.200T",
- arg);
- erts_send_error_to_logger_nogl(dsbufp);
- goto data_error;
+ goto invalid_message;
}
rp = erts_pid2proc_opt(NULL, 0,
@@ -1062,8 +1059,14 @@ int erts_net_message(Port *prt,
case DOP_UNLINK: {
ErtsDistLinkData dld;
+ if (tuple_arity != 3) {
+ goto invalid_message;
+ }
from = tuple[2];
to = tuple[3];
+ if (is_not_pid(from) || is_not_pid(to)) {
+ goto invalid_message;
+ }
rp = erts_pid2proc_opt(NULL, 0,
to, ERTS_PROC_LOCK_LINK,
@@ -1090,11 +1093,19 @@ int erts_net_message(Port *prt,
/* A remote process wants to monitor us, we get:
{DOP_MONITOR_P, Remote pid, local pid or name, ref} */
Eterm name;
+
+ if (tuple_arity != 4) {
+ goto invalid_message;
+ }
watcher = tuple[2];
watched = tuple[3]; /* local proc to monitor */
ref = tuple[4];
+ if (is_not_ref(ref)) {
+ goto invalid_message;
+ }
+
if (is_atom(watched)) {
name = watched;
rp = erts_whereis_process(NULL, 0,
@@ -1136,10 +1147,17 @@ int erts_net_message(Port *prt,
We get {DOP_DEMONITOR_P, Remote pid, Local pid or name, ref},
We need only the ref of course */
+ if (tuple_arity != 4) {
+ goto invalid_message;
+ }
/* watcher = tuple[2]; */
/* watched = tuple[3]; May be an atom in case of monitor name */
ref = tuple[4];
+ if(is_not_ref(ref)) {
+ goto invalid_message;
+ }
+
erts_smp_de_links_lock(dep);
mon = erts_remove_monitor(&(dep->monitors),ref);
erts_smp_de_links_unlock(dep);
@@ -1164,10 +1182,11 @@ int erts_net_message(Port *prt,
erts_destroy_monitor(mon);
break;
- case DOP_NODE_LINK: /* XXX never sent ?? */
- break;
-
case DOP_REG_SEND_TT:
+ if (tuple_arity != 5) {
+ goto invalid_message;
+ }
+
token_size = size_object(tuple[5]);
/* Fall through ... */
case DOP_REG_SEND:
@@ -1178,12 +1197,19 @@ int erts_net_message(Port *prt,
* There is intentionally no testing of the cookie (it is always '')
* from R9B and onwards.
*/
+ if (type != DOP_REG_SEND_TT && tuple_arity != 4) {
+ goto invalid_message;
+ }
+
#ifdef ERTS_DIST_MSG_DBG
dist_msg_dbg(&ede, "MSG", buf, orig_len);
#endif
from = tuple[2];
to = tuple[4];
+ if (is_not_pid(from) || is_not_atom(to)){
+ goto invalid_message;
+ }
rp = erts_whereis_process(NULL, 0, to, 0, ERTS_P2P_FLG_SMP_INC_REFC);
if (rp) {
Uint xsize = (type == DOP_REG_SEND
@@ -1215,6 +1241,10 @@ int erts_net_message(Port *prt,
break;
case DOP_SEND_TT:
+ if (tuple_arity != 4) {
+ goto invalid_message;
+ }
+
token_size = size_object(tuple[4]);
/* Fall through ... */
case DOP_SEND:
@@ -1225,8 +1255,13 @@ int erts_net_message(Port *prt,
#ifdef ERTS_DIST_MSG_DBG
dist_msg_dbg(&ede, "MSG", buf, orig_len);
#endif
-
+ if (type != DOP_SEND_TT && tuple_arity != 3) {
+ goto invalid_message;
+ }
to = tuple[3];
+ if (is_not_pid(to)) {
+ goto invalid_message;
+ }
rp = erts_pid2proc_opt(NULL, 0, to, 0, ERTS_P2P_FLG_SMP_INC_REFC);
if (rp) {
Uint xsize = type == DOP_SEND ? 0 : ERTS_HEAP_FRAG_SIZE(token_size);
@@ -1264,11 +1299,19 @@ int erts_net_message(Port *prt,
Eterm sysname;
ErtsProcLocks rp_locks = ERTS_PROC_LOCKS_MSG_SEND|ERTS_PROC_LOCK_LINK;
+ if (tuple_arity != 5) {
+ goto invalid_message;
+ }
+
/* watched = tuple[2]; */ /* remote proc which died */
/* watcher = tuple[3]; */
ref = tuple[4];
reason = tuple[5];
+ if(is_not_ref(ref)) {
+ goto invalid_message;
+ }
+
erts_smp_de_links_lock(dep);
sysname = dep->sysname;
mon = erts_remove_monitor(&(dep->monitors), ref);
@@ -1315,24 +1358,25 @@ int erts_net_message(Port *prt,
ErtsProcLocks rp_locks = ERTS_PROC_LOCK_LINK|ERTS_PROC_LOCKS_XSIG_SEND;
/* 'from', which 'to' is linked to, died */
if (type == DOP_EXIT) {
- from = tuple[2];
- to = tuple[3];
- reason = tuple[4];
- token = NIL;
+ if (tuple_arity != 4) {
+ goto invalid_message;
+ }
+
+ from = tuple[2];
+ to = tuple[3];
+ reason = tuple[4];
+ token = NIL;
} else {
- from = tuple[2];
- to = tuple[3];
- token = tuple[4];
- reason = tuple[5];
+ if (tuple_arity != 5) {
+ goto invalid_message;
+ }
+ from = tuple[2];
+ to = tuple[3];
+ token = tuple[4];
+ reason = tuple[5];
}
- if (is_not_internal_pid(to)) {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- PURIFY_MSG("data error");
- erts_dsprintf(dsbufp,
- "Invalid DOP_EXIT distribution message: %.200T",
- arg);
- erts_send_error_to_logger_nogl(dsbufp);
- goto data_error;
+ if (is_not_pid(from) || is_not_internal_pid(to)) {
+ goto invalid_message;
}
rp = erts_pid2proc(NULL, 0, to, rp_locks);
@@ -1379,15 +1423,24 @@ int erts_net_message(Port *prt,
ErtsProcLocks rp_locks = ERTS_PROC_LOCKS_XSIG_SEND;
/* 'from' is send an exit signal to 'to' */
if (type == DOP_EXIT2) {
- from = tuple[2];
- to = tuple[3];
- reason = tuple[4];
- token = NIL;
+ if (tuple_arity != 4) {
+ goto invalid_message;
+ }
+ from = tuple[2];
+ to = tuple[3];
+ reason = tuple[4];
+ token = NIL;
} else {
- from = tuple[2];
- to = tuple[3];
- token = tuple[4];
- reason = tuple[5];
+ if (tuple_arity != 5) {
+ goto invalid_message;
+ }
+ from = tuple[2];
+ to = tuple[3];
+ token = tuple[4];
+ reason = tuple[5];
+ }
+ if (is_not_pid(from) || is_not_internal_pid(to)) {
+ goto invalid_message;
}
rp = erts_pid2proc_opt(NULL, 0, to, rp_locks,
ERTS_P2P_FLG_SMP_INC_REFC);
@@ -1406,10 +1459,14 @@ int erts_net_message(Port *prt,
break;
}
case DOP_GROUP_LEADER:
+ if (tuple_arity != 3) {
+ goto invalid_message;
+ }
from = tuple[2]; /* Group leader */
to = tuple[3]; /* new member */
- if (is_not_pid(from))
- break;
+ if (is_not_pid(from) || is_not_pid(to)) {
+ goto invalid_message;
+ }
rp = erts_pid2proc(NULL, 0, to, ERTS_PROC_LOCK_MAIN);
if (!rp)
@@ -1418,16 +1475,8 @@ int erts_net_message(Port *prt,
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_MAIN);
break;
- default: {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- erts_dsprintf(dsbufp,
- "Illegal value in distribution dispatch switch: "
- "%.200T",
- arg);
- erts_send_error_to_logger_nogl(dsbufp);
- PURIFY_MSG("data error");
- goto data_error;
- }
+ default:
+ goto invalid_message;
}
erts_cleanup_offheap(&off_heap);
@@ -1439,8 +1488,14 @@ int erts_net_message(Port *prt,
UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
ERTS_SMP_CHK_NO_PROC_LOCKS;
return 0;
-
+ invalid_message:
+ {
+ erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
+ erts_dsprintf(dsbufp, "Invalid distribution message: %.200T", arg);
+ erts_send_error_to_logger_nogl(dsbufp);
+ }
data_error:
+ PURIFY_MSG("data error");
erts_cleanup_offheap(&off_heap);
#ifndef HYBRID /* FIND ME! */
if (ctl != ctl_default) {
@@ -1453,8 +1508,6 @@ int erts_net_message(Port *prt,
return -1;
}
-#define ERTS_DE_BUSY_LIMIT (128*1024)
-
static int
dsig_send(ErtsDSigData *dsdp, Eterm ctl, Eterm msg, int force_busy)
{
@@ -1538,18 +1591,18 @@ dsig_send(ErtsDSigData *dsdp, Eterm ctl, Eterm msg, int force_busy)
}
else {
ErtsProcList *plp = NULL;
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
dep->qsize += size_obuf(obuf);
- if (dep->qsize >= ERTS_DE_BUSY_LIMIT)
+ if (dep->qsize >= erts_dist_buf_busy_limit)
dep->qflgs |= ERTS_DE_QFLG_BUSY;
if (!force_busy && (dep->qflgs & ERTS_DE_QFLG_BUSY)) {
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
plp = erts_proclist_create(c_p);
plp->next = NULL;
erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL);
suspended = 1;
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
}
/* Enqueue obuf on dist entry */
@@ -1575,7 +1628,7 @@ dsig_send(ErtsDSigData *dsdp, Eterm ctl, Eterm msg, int force_busy)
}
}
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
erts_schedule_dist_command(NULL, dep);
erts_smp_de_runlock(dep);
@@ -1708,10 +1761,8 @@ erts_dist_command(Port *prt, int reds_limit)
{
Sint reds = ERTS_PORT_REDS_DIST_CMD_START;
int prt_busy;
- int de_busy;
Uint32 status;
Uint32 flags;
- Uint32 qflgs;
Sint obufsize = 0;
ErtsDistOutputQueue oq, foq;
DistEntry *dep = prt->dist_entry;
@@ -1746,13 +1797,12 @@ erts_dist_command(Port *prt, int reds_limit)
* a mess.
*/
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
oq.first = dep->out_queue.first;
oq.last = dep->out_queue.last;
dep->out_queue.first = NULL;
dep->out_queue.last = NULL;
- qflgs = dep->qflgs;
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
foq.first = dep->finalized_out_queue.first;
foq.last = dep->finalized_out_queue.last;
@@ -1763,17 +1813,8 @@ erts_dist_command(Port *prt, int reds_limit)
goto preempted;
prt_busy = (int) (prt->status & ERTS_PORT_SFLG_PORT_BUSY);
- de_busy = (int) (qflgs & ERTS_DE_QFLG_BUSY);
- if (prt_busy) {
- if (!de_busy) {
- erts_smp_spin_lock(&dep->qlock);
- dep->qflgs |= ERTS_DE_QFLG_BUSY;
- erts_smp_spin_unlock(&dep->qlock);
- de_busy = 1;
- }
- }
- else if (foq.first) {
+ if (!prt_busy && foq.first) {
int preempt = 0;
do {
Uint size;
@@ -1791,10 +1832,7 @@ erts_dist_command(Port *prt, int reds_limit)
free_dist_obuf(fob);
preempt = reds > reds_limit || (prt->status & ERTS_PORT_SFLGS_DEAD);
if (prt->status & ERTS_PORT_SFLG_PORT_BUSY) {
- erts_smp_spin_lock(&dep->qlock);
- dep->qflgs |= ERTS_DE_QFLG_BUSY;
- erts_smp_spin_unlock(&dep->qlock);
- de_busy = prt_busy = 1;
+ prt_busy = 1;
break;
}
} while (foq.first && !preempt);
@@ -1877,10 +1915,7 @@ erts_dist_command(Port *prt, int reds_limit)
free_dist_obuf(fob);
preempt = reds > reds_limit || (prt->status & ERTS_PORT_SFLGS_DEAD);
if (prt->status & ERTS_PORT_SFLG_PORT_BUSY) {
- erts_smp_spin_lock(&dep->qlock);
- dep->qflgs |= ERTS_DE_QFLG_BUSY;
- erts_smp_spin_unlock(&dep->qlock);
- de_busy = prt_busy = 1;
+ prt_busy = 1;
if (oq.first && !preempt)
goto finalize_only;
}
@@ -1907,22 +1942,23 @@ erts_dist_command(Port *prt, int reds_limit)
* dist entry in a non-busy state and resume suspended
* processes.
*/
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
ASSERT(dep->qsize >= obufsize);
dep->qsize -= obufsize;
obufsize = 0;
- if (de_busy && !prt_busy && dep->qsize < ERTS_DE_BUSY_LIMIT) {
+ if (!prt_busy
+ && (dep->qflgs & ERTS_DE_QFLG_BUSY)
+ && dep->qsize < erts_dist_buf_busy_limit) {
ErtsProcList *suspendees;
int resumed;
suspendees = get_suspended_on_de(dep, ERTS_DE_QFLG_BUSY);
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
resumed = erts_resume_processes(suspendees);
reds += resumed*ERTS_PORT_REDS_DIST_CMD_RESUMED;
- de_busy = 0;
}
else
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
}
ASSERT(!oq.first && !oq.last);
@@ -1931,10 +1967,10 @@ erts_dist_command(Port *prt, int reds_limit)
if (obufsize != 0) {
ASSERT(obufsize > 0);
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
ASSERT(dep->qsize >= obufsize);
dep->qsize -= obufsize;
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
}
ASSERT(foq.first || !foq.last);
@@ -1984,9 +2020,9 @@ erts_dist_command(Port *prt, int reds_limit)
foq.last = NULL;
#ifdef DEBUG
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
ASSERT(dep->qsize == obufsize);
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
#endif
}
else {
@@ -1995,14 +2031,14 @@ erts_dist_command(Port *prt, int reds_limit)
* Unhandle buffers need to be put back first
* in out_queue.
*/
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
dep->qsize -= obufsize;
obufsize = 0;
oq.last->next = dep->out_queue.first;
dep->out_queue.first = oq.first;
if (!dep->out_queue.last)
dep->out_queue.last = oq.last;
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
}
erts_schedule_dist_command(prt, NULL);
@@ -2026,10 +2062,10 @@ erts_kill_dist_connection(DistEntry *dep, Uint32 connection_id)
dep->status |= ERTS_DE_SFLG_EXITING;
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
ASSERT(!(dep->qflgs & ERTS_DE_QFLG_EXIT));
dep->qflgs |= ERTS_DE_QFLG_EXIT;
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
erts_schedule_dist_command(NULL, dep);
}
@@ -2400,13 +2436,13 @@ BIF_RETTYPE setnode_3(BIF_ALIST_3)
ErtsProcList *plp = erts_proclist_create(BIF_P);
plp->next = NULL;
erts_suspend(BIF_P, ERTS_PROC_LOCK_MAIN, NULL);
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
if (dep->suspended.last)
dep->suspended.last->next = plp;
else
dep->suspended.first = plp;
dep->suspended.last = plp;
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
goto yield;
}
@@ -2434,9 +2470,9 @@ BIF_RETTYPE setnode_3(BIF_ALIST_3)
ASSERT(dep->send);
#ifdef DEBUG
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
ASSERT(dep->qsize == 0);
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
#endif
erts_set_dist_entry_connected(dep, BIF_ARG_2, flags);
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index fa19c7fb45..695a4fc3fe 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -38,6 +38,7 @@
#define DFLAG_UNICODE_IO 0x1000
#define DFLAG_DIST_HDR_ATOM_CACHE 0x2000
#define DFLAG_SMALL_ATOM_TAGS 0x4000
+#define DFLAGS_INTERNAL_TAGS 0x8000
/* All flags that should be enabled when term_to_binary/1 is used. */
#define TERM_TO_BINARY_DFLAGS (DFLAG_EXTENDED_REFERENCES \
@@ -51,7 +52,7 @@
#define DOP_SEND 2
#define DOP_EXIT 3
#define DOP_UNLINK 4
-#define DOP_NODE_LINK 5
+/* Ancient DOP_NODE_LINK (5) was here, can be reused */
#define DOP_REG_SEND 6
#define DOP_GROUP_LEADER 7
#define DOP_EXIT2 8
@@ -68,7 +69,6 @@
/* distribution trap functions */
extern Export* dsend2_trap;
extern Export* dsend3_trap;
-/*extern Export* dsend_nosuspend_trap;*/
extern Export* dlink_trap;
extern Export* dunlink_trap;
extern Export* dmonitor_node_trap;
@@ -99,7 +99,8 @@ typedef struct {
#define ERTS_DE_IS_CONNECTED(DEP) \
(!ERTS_DE_IS_NOT_CONNECTED((DEP)))
-
+#define ERTS_DE_BUSY_LIMIT (1024*1024)
+extern int erts_dist_buf_busy_limit;
extern int erts_is_alive;
/*
@@ -153,10 +154,10 @@ erts_dsig_prepare(ErtsDSigData *dsdp,
}
if (no_suspend) {
failure = ERTS_DSIG_PREP_CONNECTED;
- erts_smp_spin_lock(&dep->qlock);
+ erts_smp_mtx_lock(&dep->qlock);
if (dep->qflgs & ERTS_DE_QFLG_BUSY)
failure = ERTS_DSIG_PREP_WOULD_SUSPEND;
- erts_smp_spin_unlock(&dep->qlock);
+ erts_smp_mtx_unlock(&dep->qlock);
if (failure == ERTS_DSIG_PREP_WOULD_SUSPEND)
goto fail;
}
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index 07b4167b27..775f4435a9 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -1348,6 +1348,13 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
argv[j++] = argv[i];
}
*argc = j;
+#if HALFWORD_HEAP
+ /* If halfword heap, silently ignore any disabling of internal
+ allocators */
+ for (i = 0; i < aui_sz; ++i)
+ aui[i]->enable = 1;
+#endif
+
}
@@ -1404,6 +1411,33 @@ void erts_alloc_reg_scheduler_id(Uint id)
erts_tsd_set(thr_ix_key, (void *)(long) ix);
}
+static void
+no_verify(Allctr_t *allctr)
+{
+
+}
+
+erts_alloc_verify_func_t
+erts_alloc_get_verify_unused_temp_alloc(Allctr_t **allctr)
+{
+ if (erts_allctrs_info[ERTS_ALC_A_TEMPORARY].alloc_util
+ && erts_allctrs_info[ERTS_ALC_A_TEMPORARY].thr_spec) {
+ ErtsAllocatorThrSpec_t *tspec;
+ tspec = &erts_allctr_thr_spec[ERTS_ALC_A_TEMPORARY];
+ if (!tspec->all_thr_safe) {
+ int ix = erts_alc_get_thr_ix();
+
+ if (ix < tspec->size) {
+ *allctr = tspec->allctr[ix];
+ return erts_alcu_verify_unused;
+ }
+ }
+ }
+
+ *allctr = NULL;
+ return no_verify;
+}
+
__decl_noreturn void
erts_alc_fatal_error(int error, int func, ErtsAlcType_t n, ...)
{
@@ -1561,7 +1595,6 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
Eterm atoms[sizeof(size)/sizeof(Uint)];
Uint *uintps[sizeof(size)/sizeof(Uint)];
Eterm euints[sizeof(size)/sizeof(Uint)];
- int need_atom;
int want_tot_or_sys;
int length;
Eterm res = THE_NON_VALUE;
@@ -1749,7 +1782,6 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
/* Calculate values needed... */
want_tot_or_sys = want.total || want.system;
- need_atom = ERTS_MEM_NEED_ALL_ALCU || want.atom;
if (ERTS_MEM_NEED_ALL_ALCU) {
size.total = 0;
diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h
index 3e96c76dbf..17ff9c3b03 100644
--- a/erts/emulator/beam/erl_alloc.h
+++ b/erts/emulator/beam/erl_alloc.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -236,6 +236,11 @@ void *erts_realloc_fnf(ErtsAlcType_t type, void *ptr, Uint size)
#endif /* #if ERTS_ALC_DO_INLINE || defined(ERTS_ALC_INTERNAL__) */
+typedef void (*erts_alloc_verify_func_t)(Allctr_t *);
+
+erts_alloc_verify_func_t
+erts_alloc_get_verify_unused_temp_alloc(Allctr_t **allctr);
+
#ifndef ERTS_CACHE_LINE_SIZE
/* Assume a cache line size of 64 bytes */
# define ERTS_CACHE_LINE_SIZE ((UWord) 64)
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index 7df9f19af0..ca71798917 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2003-2010. All Rights Reserved.
+# Copyright Ericsson AB 2003-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -193,6 +193,7 @@ type DB_FIXATION SHORT_LIVED ETS db_fixation
type DB_FIX_DEL SHORT_LIVED ETS fixed_del
type DB_TABLES LONG_LIVED ETS db_tabs
type DB_NTAB_ENT STANDARD ETS db_named_table_entry
+type DB_HEIR_DATA STANDARD ETS db_heir_data
type DB_TMP TEMPORARY ETS db_tmp
type DB_MC_STK TEMPORARY ETS db_mc_stack
type DB_MS_PSDO_PROC LONG_LIVED ETS db_match_pseudo_proc
@@ -247,7 +248,7 @@ type CPUDATA LONG_LIVED SYSTEM cpu_data
type TMP_CPU_IDS SHORT_LIVED SYSTEM tmp_cpu_ids
type EXT_TERM_DATA SHORT_LIVED PROCESSES external_term_data
type ZLIB STANDARD SYSTEM zlib
-type RDR_GRPS_MAP LONG_LIVED SYSTEM reader_groups_map
+type CPU_GRPS_MAP LONG_LIVED SYSTEM cpu_groups_map
+if smp
type ASYNC SHORT_LIVED SYSTEM async
@@ -263,6 +264,8 @@ type XPORTS_LIST SHORT_LIVED SYSTEM extra_port_list
type PROC_LCK_WTR LONG_LIVED SYSTEM proc_lock_waiter
type PROC_LCK_QS LONG_LIVED SYSTEM proc_lock_queues
type RUNQ_BLNS LONG_LIVED SYSTEM run_queue_balancing
+type MISC_AUX_WORK_Q LONG_LIVED SYSTEM misc_aux_work_q
+type MISC_AUX_WORK SHORT_LIVED SYSTEM misc_aux_work
+endif
#
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 8b184899c9..1394b7e829 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -3368,6 +3368,38 @@ erts_alcu_test(unsigned long op, unsigned long a1, unsigned long a2)
* Debug functions *
\* */
+void
+erts_alcu_verify_unused(Allctr_t *allctr)
+{
+ UWord no;
+
+ no = allctr->sbcs.curr_mseg.no;
+ no += allctr->sbcs.curr_sys_alloc.no;
+ no += allctr->mbcs.blocks.curr.no;
+
+ if (no) {
+ UWord sz = allctr->sbcs.blocks.curr.size;
+ sz += allctr->mbcs.blocks.curr.size;
+ erl_exit(ERTS_ABORT_EXIT,
+ "%salloc() used when expected to be unused!\n"
+ "Total amount of blocks allocated: %bpu\n"
+ "Total amount of bytes allocated: %bpu\n",
+ allctr->name_prefix, no, sz);
+ }
+}
+
+void
+erts_alcu_verify_unused_ts(Allctr_t *allctr)
+{
+#ifdef USE_THREADS
+ erts_mtx_lock(&allctr->mutex);
+#endif
+ erts_alcu_verify_unused(allctr);
+#ifdef USE_THREADS
+ erts_mtx_unlock(&allctr->mutex);
+#endif
+}
+
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
static void
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index f2b951bca6..d296081714 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -333,6 +333,9 @@ struct Allctr_t_ {
int erts_alcu_start(Allctr_t *, AllctrInit_t *);
void erts_alcu_stop(Allctr_t *);
+void erts_alcu_verify_unused(Allctr_t *);
+void erts_alcu_verify_unused_ts(Allctr_t *allctr);
+
unsigned long erts_alcu_test(unsigned long, unsigned long, unsigned long);
diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
index b6a445c55c..684fa5d12f 100644
--- a/erts/emulator/beam/erl_bif_binary.c
+++ b/erts/emulator/beam/erl_bif_binary.c
@@ -1477,7 +1477,7 @@ BIF_RETTYPE binary_matches_3(BIF_ALIST_3)
goto badarg;
}
if (hsend == 0) {
- BIF_RET(am_nomatch);
+ BIF_RET(NIL);
}
if (is_tuple(BIF_ARG_2)) {
tp = tuple_val(BIF_ARG_2);
diff --git a/erts/emulator/beam/erl_bif_ddll.c b/erts/emulator/beam/erl_bif_ddll.c
index 2c2e283f65..c9cdcb87a6 100644
--- a/erts/emulator/beam/erl_bif_ddll.c
+++ b/erts/emulator/beam/erl_bif_ddll.c
@@ -1193,7 +1193,7 @@ int erts_ddll_driver_ok(DE_Handle *dh)
static void ddll_no_more_references(void *vdh)
{
DE_Handle *dh = (DE_Handle *) vdh;
- int x;
+ erts_aint_t x;
lock_drv_list();
@@ -1604,7 +1604,7 @@ static int do_load_driver_entry(DE_Handle *dh, char *path, char *name)
erts_sys_ddll_close(dh->handle);
return ERL_DE_LOAD_ERROR_BAD_NAME;
}
- erts_smp_atomic_init(&(dh->refc), (long) 0);
+ erts_smp_atomic_init(&(dh->refc), (erts_aint_t) 0);
dh->port_count = 0;
dh->full_path = erts_alloc(ERTS_ALC_T_DDLL_HANDLE, sys_strlen(path) + 1);
sys_strcpy(dh->full_path, path);
@@ -1672,7 +1672,7 @@ static int load_driver_entry(DE_Handle **dhp, char *path, char *name)
dh->handle = NULL;
dh->procs = NULL;
dh->port_count = 0;
- erts_refc_init(&(dh->refc), (long) 0);
+ erts_refc_init(&(dh->refc), (erts_aint_t) 0);
dh->status = -1;
dh->reload_full_path = NULL;
dh->reload_driver_name = NULL;
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 40d8dc097c..4a717d7271 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -38,6 +38,7 @@
#include "erl_instrument.h"
#include "dist.h"
#include "erl_gc.h"
+#include "erl_cpu_topology.h"
#ifdef HIPE
#include "hipe_arch.h"
#endif
@@ -1687,6 +1688,8 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */
return erts_get_cpu_topology_term(BIF_P, *tp);
} else if (ERTS_IS_ATOM_STR("cpu_topology", sel) && arity == 2) {
Eterm res = erts_get_cpu_topology_term(BIF_P, *tp);
+ if (res == THE_NON_VALUE)
+ goto badarg;
ERTS_BIF_PREP_TRAP1(ret, erts_format_cpu_topology_trap, BIF_P, res);
return ret;
#if defined(PURIFY) || defined(VALGRIND)
@@ -1999,6 +2002,8 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
BIF_RET(db_get_trace_control_word_0(BIF_P));
} else if (ERTS_IS_ATOM_STR("ets_realloc_moves", BIF_ARG_1)) {
BIF_RET((erts_ets_realloc_always_moves) ? am_true : am_false);
+ } else if (ERTS_IS_ATOM_STR("ets_always_compress", BIF_ARG_1)) {
+ BIF_RET((erts_ets_always_compress) ? am_true : am_false);
} else if (ERTS_IS_ATOM_STR("snifs", BIF_ARG_1)) {
Uint size = 0;
Uint *szp;
@@ -2015,7 +2020,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
res = TUPLE2(hp, am_sequential_tracer, val);
BIF_RET(res);
} else if (BIF_ARG_1 == am_garbage_collection){
- Uint val = (Uint) erts_smp_atomic_read(&erts_max_gen_gcs);
+ Uint val = (Uint) erts_smp_atomic32_read(&erts_max_gen_gcs);
Eterm tup;
hp = HAlloc(BIF_P, 3+2 + 3+2 + 3+2);
@@ -2030,7 +2035,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
BIF_RET(res);
} else if (BIF_ARG_1 == am_fullsweep_after){
- Uint val = (Uint) erts_smp_atomic_read(&erts_max_gen_gcs);
+ Uint val = (Uint) erts_smp_atomic32_read(&erts_max_gen_gcs);
hp = HAlloc(BIF_P, 3);
res = TUPLE2(hp, am_fullsweep_after, make_small(val));
BIF_RET(res);
@@ -2345,9 +2350,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
/* Arguments that are unusual follow ... */
else if (ERTS_IS_ATOM_STR("logical_processors", BIF_ARG_1)) {
int no;
- erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx);
- no = erts_get_cpu_configured(erts_cpuinfo);
- erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx);
+ erts_get_logical_processors(&no, NULL, NULL);
if (no > 0)
BIF_RET(make_small((Uint) no));
else {
@@ -2357,9 +2360,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
}
else if (ERTS_IS_ATOM_STR("logical_processors_online", BIF_ARG_1)) {
int no;
- erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx);
- no = erts_get_cpu_online(erts_cpuinfo);
- erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx);
+ erts_get_logical_processors(NULL, &no, NULL);
if (no > 0)
BIF_RET(make_small((Uint) no));
else {
@@ -2369,9 +2370,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
}
else if (ERTS_IS_ATOM_STR("logical_processors_available", BIF_ARG_1)) {
int no;
- erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx);
- no = erts_get_cpu_available(erts_cpuinfo);
- erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx);
+ erts_get_logical_processors(NULL, NULL, &no);
if (no > 0)
BIF_RET(make_small((Uint) no));
else {
@@ -2533,6 +2532,13 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
BIF_RET(erts_nif_taints(BIF_P));
} else if (ERTS_IS_ATOM_STR("reader_groups_map", BIF_ARG_1)) {
BIF_RET(erts_get_reader_groups_map(BIF_P));
+ } else if (ERTS_IS_ATOM_STR("dist_buf_busy_limit", BIF_ARG_1)) {
+ Uint hsz = 0;
+
+ (void) erts_bld_uint(NULL, &hsz, erts_dist_buf_busy_limit);
+ hp = hsz ? HAlloc(BIF_P, hsz) : NULL;
+ res = erts_bld_uint(&hp, NULL, erts_dist_buf_busy_limit);
+ BIF_RET(res);
}
BIF_ERROR(BIF_P, BADARG);
@@ -3424,8 +3430,8 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
*/
if (ERTS_IS_ATOM_STR("available_internal_state", BIF_ARG_1)
&& (BIF_ARG_2 == am_true || BIF_ARG_2 == am_false)) {
- long on = (long) (BIF_ARG_2 == am_true);
- long prev_on = erts_smp_atomic_xchg(&available_internal_state, on);
+ erts_aint_t on = (erts_aint_t) (BIF_ARG_2 == am_true);
+ erts_aint_t prev_on = erts_smp_atomic_xchg(&available_internal_state, on);
if (on) {
erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
erts_dsprintf(dsbufp, "Process %T ", BIF_P->id);
@@ -3622,7 +3628,7 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
}
else if (ERTS_IS_ATOM_STR("hipe_test_reschedule_suspend", BIF_ARG_1)) {
/* Used by hipe test suites */
- long flag = erts_smp_atomic_read(&hipe_test_reschedule_flag);
+ erts_aint_t flag = erts_smp_atomic_read(&hipe_test_reschedule_flag);
if (!flag && BIF_ARG_2 != am_false) {
erts_smp_atomic_set(&hipe_test_reschedule_flag, 1);
erts_suspend(BIF_P, ERTS_PROC_LOCK_MAIN, NULL);
@@ -3697,7 +3703,7 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
#ifdef ERTS_ENABLE_LOCK_COUNT
static Eterm lcnt_build_lock_stats_term(Eterm **hpp, Uint *szp, erts_lcnt_lock_stats_t *stats, Eterm res) {
- unsigned long tries = 0, colls = 0;
+ Uint tries = 0, colls = 0;
unsigned long timer_s = 0, timer_ns = 0, timer_n = 0;
unsigned int line = 0;
@@ -3710,8 +3716,8 @@ static Eterm lcnt_build_lock_stats_term(Eterm **hpp, Uint *szp, erts_lcnt_lock_s
* [{{file, line}, {tries, colls, {seconds, nanoseconds, n_blocks}}}]
*/
- tries = (unsigned long) ethr_atomic_read(&stats->tries);
- colls = (unsigned long) ethr_atomic_read(&stats->colls);
+ tries = (Uint) ethr_atomic_read(&stats->tries);
+ colls = (Uint) ethr_atomic_read(&stats->colls);
line = stats->line;
timer_s = stats->timer.s;
diff --git a/erts/emulator/beam/erl_bif_lists.c b/erts/emulator/beam/erl_bif_lists.c
index ce13469801..47c48e74d6 100644
--- a/erts/emulator/beam/erl_bif_lists.c
+++ b/erts/emulator/beam/erl_bif_lists.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1999-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -378,7 +378,7 @@ keyfind(int Bif, Process* p, Eterm Key, Eterm Pos, Eterm List)
Eterm *tuple_ptr = tuple_val(term);
if (pos <= arityval(*tuple_ptr)) {
Eterm element = tuple_ptr[pos];
- if (cmp(Key, element) == 0) {
+ if (CMP(Key, element) == 0) {
return term;
}
}
diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c
index 378c5e73fd..fbc92b9730 100644
--- a/erts/emulator/beam/erl_bif_port.c
+++ b/erts/emulator/beam/erl_bif_port.c
@@ -610,6 +610,7 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump)
int binary_io;
int soft_eof;
Sint linebuf;
+ Eterm edir = NIL;
byte dir[MAXPATHLEN];
/* These are the defaults */
@@ -686,19 +687,10 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump)
} else if (option == am_arg0) {
char *a0;
- int n;
- if (is_nil(*tp)) {
- n = 0;
- } else if( (n = is_string(*tp)) == 0) {
+
+ if ((a0 = erts_convert_filename_to_native(*tp, ERTS_ALC_T_TMP, 1)) == NULL) {
goto badarg;
}
- a0 = (char *) erts_alloc(ERTS_ALC_T_TMP,
- (n + 1) * sizeof(byte));
- if (intlist_to_buf(*tp, a0, n) != n) {
- erl_exit(1, "%s:%d: Internal error\n",
- __FILE__, __LINE__);
- }
- a0[n] = '\0';
if (opts.argv == NULL) {
opts.argv = erts_alloc(ERTS_ALC_T_TMP,
2 * sizeof(char **));
@@ -711,22 +703,7 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump)
opts.argv[0] = a0;
}
} else if (option == am_cd) {
- Eterm iolist;
- DeclareTmpHeap(heap,4,p);
- int r;
-
- UseTmpHeap(4,p);
- heap[0] = *tp;
- heap[1] = make_list(heap+2);
- heap[2] = make_small(0);
- heap[3] = NIL;
- iolist = make_list(heap);
- r = io_list_to_buf(iolist, (char*) dir, MAXPATHLEN);
- UnUseTmpHeap(4,p);
- if (r < 0) {
- goto badarg;
- }
- opts.wd = (char *) dir;
+ edir = *tp;
} else {
goto badarg;
}
@@ -838,19 +815,7 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump)
goto badarg;
}
name = tp[1];
- if (is_atom(name)) {
- name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP,
- atom_tab(atom_val(name))->len+1);
- sys_memcpy((void *) name_buf,
- (void *) atom_tab(atom_val(name))->name,
- atom_tab(atom_val(name))->len);
- name_buf[atom_tab(atom_val(name))->len] = '\0';
- } else if ((i = is_string(name))) {
- name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP, i + 1);
- if (intlist_to_buf(name, name_buf, i) != i)
- erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
- name_buf[i] = '\0';
- } else {
+ if ((name_buf = erts_convert_filename_to_native(name,ERTS_ALC_T_TMP,0)) == NULL) {
goto badarg;
}
opts.spawn_type = ERTS_SPAWN_EXECUTABLE;
@@ -892,7 +857,33 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump)
/* Argument vector only if explicit spawn_executable */
goto badarg;
}
-
+
+ if (edir != NIL) {
+ /* A working directory is expressed differently if spawn_executable, i.e. Unicode is handles
+ for spawn_executable... */
+ if (opts.spawn_type != ERTS_SPAWN_EXECUTABLE) {
+ Eterm iolist;
+ DeclareTmpHeap(heap,4,p);
+ int r;
+
+ UseTmpHeap(4,p);
+ heap[0] = edir;
+ heap[1] = make_list(heap+2);
+ heap[2] = make_small(0);
+ heap[3] = NIL;
+ iolist = make_list(heap);
+ r = io_list_to_buf(iolist, (char*) dir, MAXPATHLEN);
+ UnUseTmpHeap(4,p);
+ if (r < 0) {
+ goto badarg;
+ }
+ opts.wd = (char *) dir;
+ } else {
+ if ((opts.wd = erts_convert_filename_to_native(edir,ERTS_ALC_T_TMP,0)) == NULL) {
+ goto badarg;
+ }
+ }
+ }
if (driver != &spawn_driver && opts.exit_status) {
goto badarg;
@@ -941,6 +932,9 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump)
if (opts.argv) {
free_args(opts.argv);
}
+ if (opts.wd && opts.wd != ((char *)dir)) {
+ erts_free(ERTS_ALC_T_TMP, (void *) opts.wd);
+ }
return port_num;
badarg:
@@ -950,6 +944,7 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump)
#undef OPEN_PORT_ERROR
}
+/* Arguments can be given i unicode and as raw binaries, convert filename is used to convert */
static char **convert_args(Eterm l)
{
char **pp;
@@ -966,22 +961,14 @@ static char **convert_args(Eterm l)
pp[i++] = erts_default_arg0;
while (is_list(l)) {
str = CAR(list_val(l));
-
- if (is_nil(str)) {
- n = 0;
- } else if( (n = is_string(str)) == 0) {
- /* Not a string... */
+ if ((b = erts_convert_filename_to_native(str,ERTS_ALC_T_TMP,1)) == NULL) {
int j;
for (j = 1; j < i; ++j)
erts_free(ERTS_ALC_T_TMP, pp[j]);
erts_free(ERTS_ALC_T_TMP, pp);
return NULL;
- }
- b = (char *) erts_alloc(ERTS_ALC_T_TMP, (n + 1) * sizeof(byte));
- pp[i++] = (char *) b;
- if (intlist_to_buf(str, b, n) != n)
- erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
- b[n] = '\0';
+ }
+ pp[i++] = b;
l = CDR(list_val(l));
}
pp[i] = NULL;
diff --git a/erts/emulator/beam/erl_bif_timer.c b/erts/emulator/beam/erl_bif_timer.c
index 4ae2f6ebf4..db771bd216 100644
--- a/erts/emulator/beam/erl_bif_timer.c
+++ b/erts/emulator/beam/erl_bif_timer.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2005-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -478,7 +478,7 @@ setup_bif_timer(Uint32 xflags,
tab_insert(btm);
ASSERT(btm == tab_find(ref));
btm->tm.active = 0; /* MUST be initalized */
- erl_set_timer(&btm->tm,
+ erts_set_timer(&btm->tm,
(ErlTimeoutProc) bif_timer_timeout,
(ErlCancelProc) bif_timer_cleanup,
(void *) btm,
@@ -550,7 +550,7 @@ BIF_RETTYPE cancel_timer_1(BIF_ALIST_1)
res = am_false;
}
else {
- Uint left = time_left(&btm->tm);
+ Uint left = erts_time_left(&btm->tm);
if (!(btm->flags & BTM_FLG_BYNAME)) {
erts_smp_proc_lock(btm->receiver.proc.ess, ERTS_PROC_LOCK_MSGQ);
unlink_proc(btm);
@@ -558,7 +558,7 @@ BIF_RETTYPE cancel_timer_1(BIF_ALIST_1)
}
tab_remove(btm);
ASSERT(!tab_find(BIF_ARG_1));
- erl_cancel_timer(&btm->tm);
+ erts_cancel_timer(&btm->tm);
erts_smp_btm_rwunlock();
res = erts_make_integer(left, BIF_P);
}
@@ -587,7 +587,7 @@ BIF_RETTYPE read_timer_1(BIF_ALIST_1)
res = am_false;
}
else {
- Uint left = time_left(&btm->tm);
+ Uint left = erts_time_left(&btm->tm);
res = erts_make_integer(left, BIF_P);
}
@@ -613,7 +613,8 @@ erts_print_bif_timer_info(int to, void *to_arg)
: btm->receiver.proc.ess->id);
erts_print(to, to_arg, "=timer:%T\n", receiver);
erts_print(to, to_arg, "Message: %T\n", btm->message);
- erts_print(to, to_arg, "Time left: %d ms\n", time_left(&btm->tm));
+ erts_print(to, to_arg, "Time left: %u ms\n",
+ erts_time_left(&btm->tm));
}
}
@@ -640,7 +641,7 @@ erts_cancel_bif_timers(Process *p, ErtsProcLocks plocks)
tab_remove(btm);
tmp_btm = btm;
btm = btm->receiver.proc.next;
- erl_cancel_timer(&tmp_btm->tm);
+ erts_cancel_timer(&tmp_btm->tm);
}
p->bif_timers = NULL;
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index a569fe2e85..506c4813fa 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2000-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -71,6 +71,7 @@ typedef struct erl_heap_bin {
*/
#define binary_size(Bin) (binary_val(Bin)[1])
+#define binary_size_rel(Bin,BasePtr) (binary_val_rel(Bin,BasePtr)[1])
#define binary_bitsize(Bin) \
((*binary_val(Bin) == HEADER_SUB_BIN) ? \
@@ -93,9 +94,12 @@ typedef struct erl_heap_bin {
* Bitsize: output variable (Uint)
*/
-#define ERTS_GET_BINARY_BYTES(Bin,Bytep,Bitoffs,Bitsize) \
+#define ERTS_GET_BINARY_BYTES(Bin,Bytep,Bitoffs,Bitsize) \
+ ERTS_GET_BINARY_BYTES_REL(Bin,Bytep,Bitoffs,Bitsize,NULL)
+
+#define ERTS_GET_BINARY_BYTES_REL(Bin,Bytep,Bitoffs,Bitsize,BasePtr) \
do { \
- Eterm* _real_bin = binary_val(Bin); \
+ Eterm* _real_bin = binary_val_rel(Bin,BasePtr); \
Uint _offs = 0; \
Bitoffs = Bitsize = 0; \
if (*_real_bin == HEADER_SUB_BIN) { \
@@ -103,7 +107,7 @@ do { \
_offs = _sb->offs; \
Bitoffs = _sb->bitoffs; \
Bitsize = _sb->bitsize; \
- _real_bin = binary_val(_sb->orig); \
+ _real_bin = binary_val_rel(_sb->orig,BasePtr); \
} \
if (*_real_bin == HEADER_PROC_BIN) { \
Bytep = ((ProcBin *) _real_bin)->bytes + _offs; \
@@ -125,9 +129,12 @@ do { \
* BitSize: Extra bit size (Uint)
*/
-#define ERTS_GET_REAL_BIN(Bin, RealBin, ByteOffset, BitOffset, BitSize) \
+#define ERTS_GET_REAL_BIN(Bin, RealBin, ByteOffset, BitOffset, BitSize) \
+ ERTS_GET_REAL_BIN_REL(Bin, RealBin, ByteOffset, BitOffset, BitSize, NULL)
+
+#define ERTS_GET_REAL_BIN_REL(Bin, RealBin, ByteOffset, BitOffset, BitSize, BasePtr) \
do { \
- ErlSubBin* _sb = (ErlSubBin *) binary_val(Bin); \
+ ErlSubBin* _sb = (ErlSubBin *) binary_val_rel(Bin,BasePtr); \
if (_sb->thing_word == HEADER_SUB_BIN) { \
RealBin = _sb->orig; \
ByteOffset = _sb->offs; \
@@ -152,6 +159,8 @@ do { \
void erts_init_binary(void);
byte* erts_get_aligned_binary_bytes_extra(Eterm, byte**, ErtsAlcType_t, unsigned extra);
+/* Used by unicode module */
+Eterm erts_bin_bytes_to_list(Eterm previous, Eterm* hp, byte* bytes, Uint size, Uint bitoffs);
/*
* Common implementation for erlang:list_to_binary/1 and binary:list_to_bin/1
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index 88d2c06246..6f8a7436d5 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -555,10 +555,11 @@ fmt_int(byte *buf, Uint sz, Eterm val, Uint size, Uint flags)
{
unsigned long offs;
- ASSERT(size != 0);
offs = BIT_OFFSET(size);
if (is_small(val)) {
Sint v = signed_val(val);
+
+ ASSERT(size != 0); /* Tested by caller */
if (flags & BSF_LITTLE) { /* Little endian */
sz--;
COPY_VAL(buf,1,v,sz);
@@ -578,6 +579,9 @@ fmt_int(byte *buf, Uint sz, Eterm val, Uint size, Uint flags)
ErtsDigit* dp = big_v(val);
int n = MIN(sz,ds);
+ if (size == 0) {
+ return 0;
+ }
if (flags & BSF_LITTLE) {
sz -= n; /* pad with this amount */
if (sign) {
@@ -729,15 +733,13 @@ erts_new_bs_put_integer(ERL_BITS_PROTO_3(Eterm arg, Uint num_bits, unsigned flag
Uint b;
byte *iptr;
- if (num_bits == 0) {
- return 1;
- }
-
bit_offset = BIT_OFFSET(bin_offset);
if (is_small(arg)) {
Uint rbits = 8 - bit_offset;
- if (bit_offset + num_bits <= 8) {
+ if (num_bits == 0) {
+ return 1;
+ } else if (bit_offset + num_bits <= 8) {
/*
* All bits are in the same byte.
*/
diff --git a/erts/emulator/beam/erl_cpu_topology.c b/erts/emulator/beam/erl_cpu_topology.c
new file mode 100644
index 0000000000..bcf8bcf270
--- /dev/null
+++ b/erts/emulator/beam/erl_cpu_topology.c
@@ -0,0 +1,2361 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2010-2011. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Description: CPU topology and related functionality
+ *
+ * Author: Rickard Green
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <ctype.h>
+
+#include "global.h"
+#include "error.h"
+#include "bif.h"
+#include "erl_cpu_topology.h"
+
+#define ERTS_MAX_READER_GROUPS 8
+
+/*
+ * Cpu topology hierarchy.
+ */
+#define ERTS_TOPOLOGY_NODE 0
+#define ERTS_TOPOLOGY_PROCESSOR 1
+#define ERTS_TOPOLOGY_PROCESSOR_NODE 2
+#define ERTS_TOPOLOGY_CORE 3
+#define ERTS_TOPOLOGY_THREAD 4
+#define ERTS_TOPOLOGY_LOGICAL 5
+
+#define ERTS_TOPOLOGY_MAX_DEPTH 6
+
+typedef struct {
+ int bind_id;
+ int bound_id;
+} ErtsCpuBindData;
+
+static erts_cpu_info_t *cpuinfo;
+
+static int max_main_threads;
+static int reader_groups;
+
+static ErtsCpuBindData *scheduler2cpu_map;
+static erts_smp_rwmtx_t cpuinfo_rwmtx;
+
+typedef enum {
+ ERTS_CPU_BIND_UNDEFINED,
+ ERTS_CPU_BIND_SPREAD,
+ ERTS_CPU_BIND_PROCESSOR_SPREAD,
+ ERTS_CPU_BIND_THREAD_SPREAD,
+ ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD,
+ ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD,
+ ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD,
+ ERTS_CPU_BIND_NO_SPREAD,
+ ERTS_CPU_BIND_NONE
+} ErtsCpuBindOrder;
+
+#define ERTS_CPU_BIND_DEFAULT_BIND \
+ ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD
+
+static int no_cpu_groups_callbacks;
+static ErtsCpuBindOrder cpu_bind_order;
+
+static erts_cpu_topology_t *user_cpudata;
+static int user_cpudata_size;
+static erts_cpu_topology_t *system_cpudata;
+static int system_cpudata_size;
+
+typedef struct {
+ int level[ERTS_TOPOLOGY_MAX_DEPTH+1];
+} erts_avail_cput;
+
+typedef struct {
+ int id;
+ int sub_levels;
+ int cpu_groups;
+} erts_cpu_groups_count_t;
+
+typedef struct {
+ int logical;
+ int cpu_group;
+} erts_cpu_groups_map_array_t;
+
+typedef struct erts_cpu_groups_callback_list_t_ erts_cpu_groups_callback_list_t;
+struct erts_cpu_groups_callback_list_t_ {
+ erts_cpu_groups_callback_list_t *next;
+ erts_cpu_groups_callback_t callback;
+ void *arg;
+};
+
+typedef struct erts_cpu_groups_map_t_ erts_cpu_groups_map_t;
+struct erts_cpu_groups_map_t_ {
+ erts_cpu_groups_map_t *next;
+ int groups;
+ erts_cpu_groups_map_array_t *array;
+ int size;
+ int logical_processors;
+ erts_cpu_groups_callback_list_t *callback_list;
+};
+
+typedef struct {
+ erts_cpu_groups_callback_t callback;
+ int ix;
+ void *arg;
+} erts_cpu_groups_callback_call_t;
+
+static erts_cpu_groups_map_t *cpu_groups_maps;
+
+static erts_cpu_groups_map_t *reader_groups_map;
+
+#define ERTS_TOPOLOGY_CG ERTS_TOPOLOGY_MAX_DEPTH
+
+#define ERTS_MAX_CPU_TOPOLOGY_ID ((int) 0xffff)
+
+#ifdef ERTS_SMP
+static void cpu_bind_order_sort(erts_cpu_topology_t *cpudata,
+ int size,
+ ErtsCpuBindOrder bind_order,
+ int mk_seq);
+static void write_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size);
+#endif
+
+static void reader_groups_callback(int, ErtsSchedulerData *, int, void *);
+static erts_cpu_groups_map_t *add_cpu_groups(int groups,
+ erts_cpu_groups_callback_t callback,
+ void *arg);
+static void update_cpu_groups_maps(void);
+static void make_cpu_groups_map(erts_cpu_groups_map_t *map, int test);
+static int cpu_groups_lookup(erts_cpu_groups_map_t *map,
+ ErtsSchedulerData *esdp);
+
+static void create_tmp_cpu_topology_copy(erts_cpu_topology_t **cpudata,
+ int *cpudata_size);
+static void destroy_tmp_cpu_topology_copy(erts_cpu_topology_t *cpudata);
+
+static int
+int_cmp(const void *vx, const void *vy)
+{
+ return *((int *) vx) - *((int *) vy);
+}
+
+static int
+cpu_spread_order_cmp(const void *vx, const void *vy)
+{
+ erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
+ erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
+
+ if (x->thread != y->thread)
+ return x->thread - y->thread;
+ if (x->core != y->core)
+ return x->core - y->core;
+ if (x->processor_node != y->processor_node)
+ return x->processor_node - y->processor_node;
+ if (x->processor != y->processor)
+ return x->processor - y->processor;
+ if (x->node != y->node)
+ return x->node - y->node;
+ return 0;
+}
+
+static int
+cpu_processor_spread_order_cmp(const void *vx, const void *vy)
+{
+ erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
+ erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
+
+ if (x->thread != y->thread)
+ return x->thread - y->thread;
+ if (x->processor_node != y->processor_node)
+ return x->processor_node - y->processor_node;
+ if (x->core != y->core)
+ return x->core - y->core;
+ if (x->node != y->node)
+ return x->node - y->node;
+ if (x->processor != y->processor)
+ return x->processor - y->processor;
+ return 0;
+}
+
+static int
+cpu_thread_spread_order_cmp(const void *vx, const void *vy)
+{
+ erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
+ erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
+
+ if (x->thread != y->thread)
+ return x->thread - y->thread;
+ if (x->node != y->node)
+ return x->node - y->node;
+ if (x->processor != y->processor)
+ return x->processor - y->processor;
+ if (x->processor_node != y->processor_node)
+ return x->processor_node - y->processor_node;
+ if (x->core != y->core)
+ return x->core - y->core;
+ return 0;
+}
+
+static int
+cpu_thread_no_node_processor_spread_order_cmp(const void *vx, const void *vy)
+{
+ erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
+ erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
+
+ if (x->thread != y->thread)
+ return x->thread - y->thread;
+ if (x->node != y->node)
+ return x->node - y->node;
+ if (x->core != y->core)
+ return x->core - y->core;
+ if (x->processor != y->processor)
+ return x->processor - y->processor;
+ return 0;
+}
+
+static int
+cpu_no_node_processor_spread_order_cmp(const void *vx, const void *vy)
+{
+ erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
+ erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
+
+ if (x->node != y->node)
+ return x->node - y->node;
+ if (x->thread != y->thread)
+ return x->thread - y->thread;
+ if (x->core != y->core)
+ return x->core - y->core;
+ if (x->processor != y->processor)
+ return x->processor - y->processor;
+ return 0;
+}
+
+static int
+cpu_no_node_thread_spread_order_cmp(const void *vx, const void *vy)
+{
+ erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
+ erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
+
+ if (x->node != y->node)
+ return x->node - y->node;
+ if (x->thread != y->thread)
+ return x->thread - y->thread;
+ if (x->processor != y->processor)
+ return x->processor - y->processor;
+ if (x->core != y->core)
+ return x->core - y->core;
+ return 0;
+}
+
+static int
+cpu_no_spread_order_cmp(const void *vx, const void *vy)
+{
+ erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
+ erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
+
+ if (x->node != y->node)
+ return x->node - y->node;
+ if (x->processor != y->processor)
+ return x->processor - y->processor;
+ if (x->processor_node != y->processor_node)
+ return x->processor_node - y->processor_node;
+ if (x->core != y->core)
+ return x->core - y->core;
+ if (x->thread != y->thread)
+ return x->thread - y->thread;
+ return 0;
+}
+
+static ERTS_INLINE void
+make_cpudata_id_seq(erts_cpu_topology_t *cpudata, int size, int no_node)
+{
+ int ix;
+ int node = -1;
+ int processor = -1;
+ int processor_node = -1;
+ int processor_node_node = -1;
+ int core = -1;
+ int thread = -1;
+ int old_node = -1;
+ int old_processor = -1;
+ int old_processor_node = -1;
+ int old_core = -1;
+ int old_thread = -1;
+
+ for (ix = 0; ix < size; ix++) {
+ if (!no_node || cpudata[ix].node >= 0) {
+ if (old_node == cpudata[ix].node)
+ cpudata[ix].node = node;
+ else {
+ old_node = cpudata[ix].node;
+ old_processor = processor = -1;
+ if (!no_node)
+ old_processor_node = processor_node = -1;
+ old_core = core = -1;
+ old_thread = thread = -1;
+ if (no_node || cpudata[ix].node >= 0)
+ cpudata[ix].node = ++node;
+ }
+ }
+ if (old_processor == cpudata[ix].processor)
+ cpudata[ix].processor = processor;
+ else {
+ old_processor = cpudata[ix].processor;
+ if (!no_node)
+ processor_node_node = old_processor_node = processor_node = -1;
+ old_core = core = -1;
+ old_thread = thread = -1;
+ cpudata[ix].processor = ++processor;
+ }
+ if (no_node && cpudata[ix].processor_node < 0)
+ old_processor_node = -1;
+ else {
+ if (old_processor_node == cpudata[ix].processor_node) {
+ if (no_node)
+ cpudata[ix].node = cpudata[ix].processor_node = node;
+ else {
+ if (processor_node_node >= 0)
+ cpudata[ix].node = processor_node_node;
+ cpudata[ix].processor_node = processor_node;
+ }
+ }
+ else {
+ old_processor_node = cpudata[ix].processor_node;
+ old_core = core = -1;
+ old_thread = thread = -1;
+ if (no_node)
+ cpudata[ix].node = cpudata[ix].processor_node = ++node;
+ else {
+ cpudata[ix].node = processor_node_node = ++node;
+ cpudata[ix].processor_node = ++processor_node;
+ }
+ }
+ }
+ if (!no_node && cpudata[ix].processor_node < 0)
+ cpudata[ix].processor_node = 0;
+ if (old_core == cpudata[ix].core)
+ cpudata[ix].core = core;
+ else {
+ old_core = cpudata[ix].core;
+ old_thread = thread = -1;
+ cpudata[ix].core = ++core;
+ }
+ if (old_thread == cpudata[ix].thread)
+ cpudata[ix].thread = thread;
+ else
+ old_thread = cpudata[ix].thread = ++thread;
+ }
+}
+
+static void
+cpu_bind_order_sort(erts_cpu_topology_t *cpudata,
+ int size,
+ ErtsCpuBindOrder bind_order,
+ int mk_seq)
+{
+ if (size > 1) {
+ int no_node = 0;
+ int (*cmp_func)(const void *, const void *);
+ switch (bind_order) {
+ case ERTS_CPU_BIND_SPREAD:
+ cmp_func = cpu_spread_order_cmp;
+ break;
+ case ERTS_CPU_BIND_PROCESSOR_SPREAD:
+ cmp_func = cpu_processor_spread_order_cmp;
+ break;
+ case ERTS_CPU_BIND_THREAD_SPREAD:
+ cmp_func = cpu_thread_spread_order_cmp;
+ break;
+ case ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD:
+ no_node = 1;
+ cmp_func = cpu_thread_no_node_processor_spread_order_cmp;
+ break;
+ case ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD:
+ no_node = 1;
+ cmp_func = cpu_no_node_processor_spread_order_cmp;
+ break;
+ case ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD:
+ no_node = 1;
+ cmp_func = cpu_no_node_thread_spread_order_cmp;
+ break;
+ case ERTS_CPU_BIND_NO_SPREAD:
+ cmp_func = cpu_no_spread_order_cmp;
+ break;
+ default:
+ cmp_func = NULL;
+ erl_exit(ERTS_ABORT_EXIT,
+ "Bad cpu bind type: %d\n",
+ (int) cpu_bind_order);
+ break;
+ }
+
+ if (mk_seq)
+ make_cpudata_id_seq(cpudata, size, no_node);
+
+ qsort(cpudata, size, sizeof(erts_cpu_topology_t), cmp_func);
+ }
+}
+
+static int
+processor_order_cmp(const void *vx, const void *vy)
+{
+ erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
+ erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
+
+ if (x->processor != y->processor)
+ return x->processor - y->processor;
+ if (x->node != y->node)
+ return x->node - y->node;
+ if (x->processor_node != y->processor_node)
+ return x->processor_node - y->processor_node;
+ if (x->core != y->core)
+ return x->core - y->core;
+ if (x->thread != y->thread)
+ return x->thread - y->thread;
+ return 0;
+}
+
+#ifdef ERTS_SMP
+void
+erts_sched_check_cpu_bind_prep_suspend(ErtsSchedulerData *esdp)
+{
+ erts_cpu_groups_map_t *cgm;
+ erts_cpu_groups_callback_list_t *cgcl;
+ erts_cpu_groups_callback_call_t *cgcc;
+ int cgcc_ix;
+
+ /* Unbind from cpu */
+ erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
+ if (scheduler2cpu_map[esdp->no].bound_id >= 0
+ && erts_unbind_from_cpu(cpuinfo) == 0) {
+ esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = -1;
+ }
+
+ cgcc = erts_alloc(ERTS_ALC_T_TMP,
+ (no_cpu_groups_callbacks
+ * sizeof(erts_cpu_groups_callback_call_t)));
+ cgcc_ix = 0;
+ for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) {
+ for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) {
+ cgcc[cgcc_ix].callback = cgcl->callback;
+ cgcc[cgcc_ix].ix = cpu_groups_lookup(cgm, esdp);
+ cgcc[cgcc_ix].arg = cgcl->arg;
+ cgcc_ix++;
+ }
+ }
+ ASSERT(no_cpu_groups_callbacks == cgcc_ix);
+ erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
+
+ for (cgcc_ix = 0; cgcc_ix < no_cpu_groups_callbacks; cgcc_ix++)
+ cgcc[cgcc_ix].callback(1,
+ esdp,
+ cgcc[cgcc_ix].ix,
+ cgcc[cgcc_ix].arg);
+
+ erts_free(ERTS_ALC_T_TMP, cgcc);
+
+ if (esdp->no <= max_main_threads)
+ erts_thr_set_main_status(0, 0);
+
+}
+
+void
+erts_sched_check_cpu_bind_post_suspend(ErtsSchedulerData *esdp)
+{
+ ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(esdp->run_queue));
+
+ if (esdp->no <= max_main_threads)
+ erts_thr_set_main_status(1, (int) esdp->no);
+
+ /* Make sure we check if we should bind to a cpu or not... */
+ if (esdp->run_queue->flags & ERTS_RUNQ_FLG_SHARED_RUNQ)
+ erts_smp_atomic32_set(&esdp->chk_cpu_bind, 1);
+ else
+ esdp->run_queue->flags |= ERTS_RUNQ_FLG_CHK_CPU_BIND;
+}
+
+#endif
+
+void
+erts_sched_check_cpu_bind(ErtsSchedulerData *esdp)
+{
+ int res, cpu_id, cgcc_ix;
+ erts_cpu_groups_map_t *cgm;
+ erts_cpu_groups_callback_list_t *cgcl;
+ erts_cpu_groups_callback_call_t *cgcc;
+#ifdef ERTS_SMP
+ if (erts_common_run_queue)
+ erts_smp_atomic32_set(&esdp->chk_cpu_bind, 0);
+ else {
+ esdp->run_queue->flags &= ~ERTS_RUNQ_FLG_CHK_CPU_BIND;
+ }
+#endif
+ erts_smp_runq_unlock(esdp->run_queue);
+ erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
+ cpu_id = scheduler2cpu_map[esdp->no].bind_id;
+ if (cpu_id >= 0 && cpu_id != scheduler2cpu_map[esdp->no].bound_id) {
+ res = erts_bind_to_cpu(cpuinfo, cpu_id);
+ if (res == 0)
+ esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = cpu_id;
+ else {
+ erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
+ erts_dsprintf(dsbufp, "Scheduler %d failed to bind to cpu %d: %s\n",
+ (int) esdp->no, cpu_id, erl_errno_id(-res));
+ erts_send_error_to_logger_nogl(dsbufp);
+ if (scheduler2cpu_map[esdp->no].bound_id >= 0)
+ goto unbind;
+ }
+ }
+ else if (cpu_id < 0) {
+ unbind:
+ /* Get rid of old binding */
+ res = erts_unbind_from_cpu(cpuinfo);
+ if (res == 0)
+ esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = -1;
+ else if (res != -ENOTSUP) {
+ erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
+ erts_dsprintf(dsbufp, "Scheduler %d failed to unbind from cpu %d: %s\n",
+ (int) esdp->no, cpu_id, erl_errno_id(-res));
+ erts_send_error_to_logger_nogl(dsbufp);
+ }
+ }
+
+ cgcc = erts_alloc(ERTS_ALC_T_TMP,
+ (no_cpu_groups_callbacks
+ * sizeof(erts_cpu_groups_callback_call_t)));
+ cgcc_ix = 0;
+ for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) {
+ for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) {
+ cgcc[cgcc_ix].callback = cgcl->callback;
+ cgcc[cgcc_ix].ix = cpu_groups_lookup(cgm, esdp);
+ cgcc[cgcc_ix].arg = cgcl->arg;
+ cgcc_ix++;
+ }
+ }
+
+ ASSERT(no_cpu_groups_callbacks == cgcc_ix);
+ erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
+
+ for (cgcc_ix = 0; cgcc_ix < no_cpu_groups_callbacks; cgcc_ix++)
+ cgcc[cgcc_ix].callback(0,
+ esdp,
+ cgcc[cgcc_ix].ix,
+ cgcc[cgcc_ix].arg);
+
+ erts_free(ERTS_ALC_T_TMP, cgcc);
+
+ erts_smp_runq_lock(esdp->run_queue);
+}
+
+#ifdef ERTS_SMP
+void
+erts_sched_init_check_cpu_bind(ErtsSchedulerData *esdp)
+{
+ int cgcc_ix;
+ erts_cpu_groups_map_t *cgm;
+ erts_cpu_groups_callback_list_t *cgcl;
+ erts_cpu_groups_callback_call_t *cgcc;
+
+ erts_smp_rwmtx_rlock(&cpuinfo_rwmtx);
+
+ cgcc = erts_alloc(ERTS_ALC_T_TMP,
+ (no_cpu_groups_callbacks
+ * sizeof(erts_cpu_groups_callback_call_t)));
+ cgcc_ix = 0;
+ for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) {
+ for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) {
+ cgcc[cgcc_ix].callback = cgcl->callback;
+ cgcc[cgcc_ix].ix = cpu_groups_lookup(cgm, esdp);
+ cgcc[cgcc_ix].arg = cgcl->arg;
+ cgcc_ix++;
+ }
+ }
+
+ ASSERT(no_cpu_groups_callbacks == cgcc_ix);
+ erts_smp_rwmtx_runlock(&cpuinfo_rwmtx);
+
+ for (cgcc_ix = 0; cgcc_ix < no_cpu_groups_callbacks; cgcc_ix++)
+ cgcc[cgcc_ix].callback(0,
+ esdp,
+ cgcc[cgcc_ix].ix,
+ cgcc[cgcc_ix].arg);
+
+ erts_free(ERTS_ALC_T_TMP, cgcc);
+
+ if (esdp->no <= max_main_threads)
+ erts_thr_set_main_status(1, (int) esdp->no);
+}
+#endif
+
+static void
+write_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size)
+{
+ int s_ix = 1;
+ int cpu_ix;
+
+ ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx));
+
+ if (cpu_bind_order != ERTS_CPU_BIND_NONE && size) {
+
+ cpu_bind_order_sort(cpudata, size, cpu_bind_order, 1);
+
+ for (cpu_ix = 0; cpu_ix < size && cpu_ix < erts_no_schedulers; cpu_ix++)
+ if (erts_is_cpu_available(cpuinfo, cpudata[cpu_ix].logical))
+ scheduler2cpu_map[s_ix++].bind_id = cpudata[cpu_ix].logical;
+ }
+
+ if (s_ix <= erts_no_schedulers)
+ for (; s_ix <= erts_no_schedulers; s_ix++)
+ scheduler2cpu_map[s_ix].bind_id = -1;
+}
+
+int
+erts_init_scheduler_bind_type_string(char *how)
+{
+ if (sys_strcmp(how, "u") == 0)
+ cpu_bind_order = ERTS_CPU_BIND_NONE;
+ else if (erts_bind_to_cpu(cpuinfo, -1) == -ENOTSUP)
+ return ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED;
+ else if (!system_cpudata && !user_cpudata)
+ return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY;
+ else 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, "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;
+ else if (sys_strcmp(how, "nnts") == 0)
+ cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD;
+ else if (sys_strcmp(how, "ns") == 0)
+ cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD;
+ else
+ return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE;
+ return ERTS_INIT_SCHED_BIND_TYPE_SUCCESS;
+}
+
+static Eterm
+bound_schedulers_term(ErtsCpuBindOrder order)
+{
+ switch (order) {
+ case ERTS_CPU_BIND_SPREAD: {
+ ERTS_DECL_AM(spread);
+ return AM_spread;
+ }
+ case ERTS_CPU_BIND_PROCESSOR_SPREAD: {
+ ERTS_DECL_AM(processor_spread);
+ return AM_processor_spread;
+ }
+ case ERTS_CPU_BIND_THREAD_SPREAD: {
+ ERTS_DECL_AM(thread_spread);
+ return AM_thread_spread;
+ }
+ case ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD: {
+ ERTS_DECL_AM(thread_no_node_processor_spread);
+ return AM_thread_no_node_processor_spread;
+ }
+ case ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD: {
+ ERTS_DECL_AM(no_node_processor_spread);
+ return AM_no_node_processor_spread;
+ }
+ case ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD: {
+ ERTS_DECL_AM(no_node_thread_spread);
+ return AM_no_node_thread_spread;
+ }
+ case ERTS_CPU_BIND_NO_SPREAD: {
+ ERTS_DECL_AM(no_spread);
+ return AM_no_spread;
+ }
+ case ERTS_CPU_BIND_NONE: {
+ ERTS_DECL_AM(unbound);
+ return AM_unbound;
+ }
+ default:
+ ASSERT(0);
+ return THE_NON_VALUE;
+ }
+}
+
+Eterm
+erts_bound_schedulers_term(Process *c_p)
+{
+ ErtsCpuBindOrder order;
+ erts_smp_rwmtx_rlock(&cpuinfo_rwmtx);
+ order = cpu_bind_order;
+ erts_smp_rwmtx_runlock(&cpuinfo_rwmtx);
+ return bound_schedulers_term(order);
+}
+
+Eterm
+erts_bind_schedulers(Process *c_p, Eterm how)
+{
+ int notify = 0;
+ Eterm res;
+ erts_cpu_topology_t *cpudata;
+ int cpudata_size;
+ ErtsCpuBindOrder old_cpu_bind_order;
+
+ erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
+
+ if (erts_bind_to_cpu(cpuinfo, -1) == -ENOTSUP) {
+ if (cpu_bind_order == ERTS_CPU_BIND_NONE
+ && ERTS_IS_ATOM_STR("unbound", how)) {
+ res = bound_schedulers_term(ERTS_CPU_BIND_NONE);
+ goto done;
+ }
+ ERTS_BIF_PREP_ERROR(res, c_p, EXC_NOTSUP);
+ }
+ else {
+
+ old_cpu_bind_order = cpu_bind_order;
+
+ 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("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;
+ else if (ERTS_IS_ATOM_STR("no_node_thread_spread", how))
+ cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD;
+ else if (ERTS_IS_ATOM_STR("no_spread", how))
+ cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD;
+ else if (ERTS_IS_ATOM_STR("unbound", how))
+ cpu_bind_order = ERTS_CPU_BIND_NONE;
+ else {
+ cpu_bind_order = old_cpu_bind_order;
+ ERTS_BIF_PREP_ERROR(res, c_p, BADARG);
+ goto done;
+ }
+
+ create_tmp_cpu_topology_copy(&cpudata, &cpudata_size);
+
+ if (!cpudata) {
+ cpu_bind_order = old_cpu_bind_order;
+ ERTS_BIF_PREP_ERROR(res, c_p, BADARG);
+ goto done;
+ }
+
+ write_schedulers_bind_change(cpudata, cpudata_size);
+ notify = 1;
+
+ destroy_tmp_cpu_topology_copy(cpudata);
+
+ res = bound_schedulers_term(old_cpu_bind_order);
+ }
+
+ done:
+
+ erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
+
+ if (notify)
+ erts_sched_notify_check_cpu_bind();
+
+ return res;
+}
+
+int
+erts_sched_bind_atthrcreate_prepare(void)
+{
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ return esdp != NULL && erts_is_scheduler_bound(esdp);
+}
+
+int
+erts_sched_bind_atthrcreate_child(int unbind)
+{
+ int res = 0;
+ if (unbind) {
+ erts_smp_rwmtx_rlock(&cpuinfo_rwmtx);
+ res = erts_unbind_from_cpu(cpuinfo);
+ erts_smp_rwmtx_runlock(&cpuinfo_rwmtx);
+ }
+ return res;
+}
+
+void
+erts_sched_bind_atthrcreate_parent(int unbind)
+{
+
+}
+
+int
+erts_sched_bind_atfork_prepare(void)
+{
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ int unbind = esdp != NULL && erts_is_scheduler_bound(esdp);
+ if (unbind)
+ erts_smp_rwmtx_rlock(&cpuinfo_rwmtx);
+ return unbind;
+}
+
+int
+erts_sched_bind_atfork_child(int unbind)
+{
+ if (unbind) {
+ ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rlocked(&cpuinfo_rwmtx)
+ || erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx));
+ return erts_unbind_from_cpu(cpuinfo);
+ }
+ return 0;
+}
+
+char *
+erts_sched_bind_atvfork_child(int unbind)
+{
+ if (unbind) {
+ ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rlocked(&cpuinfo_rwmtx)
+ || erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx));
+ return erts_get_unbind_from_cpu_str(cpuinfo);
+ }
+ return "false";
+}
+
+void
+erts_sched_bind_atfork_parent(int unbind)
+{
+ if (unbind)
+ erts_smp_rwmtx_runlock(&cpuinfo_rwmtx);
+}
+
+Eterm
+erts_fake_scheduler_bindings(Process *p, Eterm how)
+{
+ ErtsCpuBindOrder fake_cpu_bind_order;
+ erts_cpu_topology_t *cpudata;
+ int cpudata_size;
+ Eterm res;
+
+ 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("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;
+ else if (ERTS_IS_ATOM_STR("no_node_thread_spread", how))
+ fake_cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD;
+ else if (ERTS_IS_ATOM_STR("no_spread", how))
+ fake_cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD;
+ else if (ERTS_IS_ATOM_STR("unbound", how))
+ fake_cpu_bind_order = ERTS_CPU_BIND_NONE;
+ else {
+ ERTS_BIF_PREP_ERROR(res, p, BADARG);
+ return res;
+ }
+
+ erts_smp_rwmtx_rlock(&cpuinfo_rwmtx);
+ create_tmp_cpu_topology_copy(&cpudata, &cpudata_size);
+ erts_smp_rwmtx_runlock(&cpuinfo_rwmtx);
+
+ if (!cpudata || fake_cpu_bind_order == ERTS_CPU_BIND_NONE)
+ ERTS_BIF_PREP_RET(res, am_false);
+ else {
+ int i;
+ Eterm *hp;
+
+ cpu_bind_order_sort(cpudata, cpudata_size, fake_cpu_bind_order, 1);
+
+#ifdef ERTS_FAKE_SCHED_BIND_PRINT_SORTED_CPU_DATA
+
+ erts_fprintf(stderr, "node: ");
+ for (i = 0; i < cpudata_size; i++)
+ erts_fprintf(stderr, " %2d", cpudata[i].node);
+ erts_fprintf(stderr, "\n");
+ erts_fprintf(stderr, "processor: ");
+ for (i = 0; i < cpudata_size; i++)
+ erts_fprintf(stderr, " %2d", cpudata[i].processor);
+ erts_fprintf(stderr, "\n");
+ if (fake_cpu_bind_order != ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD
+ && fake_cpu_bind_order != ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD
+ && fake_cpu_bind_order != ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD) {
+ erts_fprintf(stderr, "processor_node:");
+ for (i = 0; i < cpudata_size; i++)
+ erts_fprintf(stderr, " %2d", cpudata[i].processor_node);
+ erts_fprintf(stderr, "\n");
+ }
+ erts_fprintf(stderr, "core: ");
+ for (i = 0; i < cpudata_size; i++)
+ erts_fprintf(stderr, " %2d", cpudata[i].core);
+ erts_fprintf(stderr, "\n");
+ erts_fprintf(stderr, "thread: ");
+ for (i = 0; i < cpudata_size; i++)
+ erts_fprintf(stderr, " %2d", cpudata[i].thread);
+ erts_fprintf(stderr, "\n");
+ erts_fprintf(stderr, "logical: ");
+ for (i = 0; i < cpudata_size; i++)
+ erts_fprintf(stderr, " %2d", cpudata[i].logical);
+ erts_fprintf(stderr, "\n");
+#endif
+
+ hp = HAlloc(p, cpudata_size+1);
+ ERTS_BIF_PREP_RET(res, make_tuple(hp));
+ *hp++ = make_arityval((Uint) cpudata_size);
+ for (i = 0; i < cpudata_size; i++)
+ *hp++ = make_small((Uint) cpudata[i].logical);
+ }
+
+ destroy_tmp_cpu_topology_copy(cpudata);
+
+ return res;
+}
+
+Eterm
+erts_get_schedulers_binds(Process *c_p)
+{
+ int ix;
+ ERTS_DECL_AM(unbound);
+ Eterm *hp = HAlloc(c_p, erts_no_schedulers+1);
+ Eterm res = make_tuple(hp);
+
+ *(hp++) = make_arityval(erts_no_schedulers);
+ erts_smp_rwmtx_rlock(&cpuinfo_rwmtx);
+ for (ix = 1; ix <= erts_no_schedulers; ix++)
+ *(hp++) = (scheduler2cpu_map[ix].bound_id >= 0
+ ? make_small(scheduler2cpu_map[ix].bound_id)
+ : AM_unbound);
+ erts_smp_rwmtx_runlock(&cpuinfo_rwmtx);
+ return res;
+}
+
+/*
+ * CPU topology
+ */
+
+typedef struct {
+ int *id;
+ int used;
+ int size;
+} ErtsCpuTopIdSeq;
+
+typedef struct {
+ ErtsCpuTopIdSeq logical;
+ ErtsCpuTopIdSeq thread;
+ ErtsCpuTopIdSeq core;
+ ErtsCpuTopIdSeq processor_node;
+ ErtsCpuTopIdSeq processor;
+ ErtsCpuTopIdSeq node;
+} ErtsCpuTopEntry;
+
+static void
+init_cpu_top_entry(ErtsCpuTopEntry *cte)
+{
+ int size = 10;
+ cte->logical.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
+ sizeof(int)*size);
+ cte->logical.size = size;
+ cte->thread.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
+ sizeof(int)*size);
+ cte->thread.size = size;
+ cte->core.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
+ sizeof(int)*size);
+ cte->core.size = size;
+ cte->processor_node.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
+ sizeof(int)*size);
+ cte->processor_node.size = size;
+ cte->processor.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
+ sizeof(int)*size);
+ cte->processor.size = size;
+ cte->node.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
+ sizeof(int)*size);
+ cte->node.size = size;
+}
+
+static void
+destroy_cpu_top_entry(ErtsCpuTopEntry *cte)
+{
+ erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->logical.id);
+ erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->thread.id);
+ erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->core.id);
+ erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->processor_node.id);
+ erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->processor.id);
+ erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->node.id);
+}
+
+static int
+get_cput_value_or_range(int *v, int *vr, char **str)
+{
+ long l;
+ char *c = *str;
+ errno = 0;
+ if (!isdigit((unsigned char)*c))
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID;
+ l = strtol(c, &c, 10);
+ if (errno != 0 || l < 0 || ERTS_MAX_CPU_TOPOLOGY_ID < l)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID;
+ *v = (int) l;
+ if (*c == '-') {
+ c++;
+ if (!isdigit((unsigned char)*c))
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
+ l = strtol(c, &c, 10);
+ if (errno != 0 || l < 0 || ERTS_MAX_CPU_TOPOLOGY_ID < l)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
+ *vr = (int) l;
+ }
+ *str = c;
+ return ERTS_INIT_CPU_TOPOLOGY_OK;
+}
+
+static int
+get_cput_id_seq(ErtsCpuTopIdSeq *idseq, char **str)
+{
+ int ix = 0;
+ int need_size = 0;
+ char *c = *str;
+
+ while (1) {
+ int res;
+ int val;
+ int nids;
+ int val_range = -1;
+ res = get_cput_value_or_range(&val, &val_range, &c);
+ if (res != ERTS_INIT_CPU_TOPOLOGY_OK)
+ return res;
+ if (val_range < 0 || val_range == val)
+ nids = 1;
+ else {
+ if (val_range > val)
+ nids = val_range - val + 1;
+ else
+ nids = val - val_range + 1;
+ }
+ need_size += nids;
+ if (need_size > idseq->size) {
+ idseq->size = need_size + 10;
+ idseq->id = erts_realloc(ERTS_ALC_T_TMP_CPU_IDS,
+ idseq->id,
+ sizeof(int)*idseq->size);
+ }
+ if (nids == 1)
+ idseq->id[ix++] = val;
+ else if (val_range > val) {
+ for (; val <= val_range; val++)
+ idseq->id[ix++] = val;
+ }
+ else {
+ for (; val >= val_range; val--)
+ idseq->id[ix++] = val;
+ }
+ if (*c != ',')
+ break;
+ c++;
+ }
+ *str = c;
+ idseq->used = ix;
+ return ERTS_INIT_CPU_TOPOLOGY_OK;
+}
+
+static int
+get_cput_entry(ErtsCpuTopEntry *cput, char **str)
+{
+ int h;
+ char *c = *str;
+
+ cput->logical.used = 0;
+ cput->thread.id[0] = 0;
+ cput->thread.used = 1;
+ cput->core.id[0] = 0;
+ cput->core.used = 1;
+ cput->processor_node.id[0] = -1;
+ cput->processor_node.used = 1;
+ cput->processor.id[0] = 0;
+ cput->processor.used = 1;
+ cput->node.id[0] = -1;
+ cput->node.used = 1;
+
+ h = ERTS_TOPOLOGY_MAX_DEPTH;
+ while (*c != ':' && *c != '\0') {
+ int res;
+ ErtsCpuTopIdSeq *idseqp;
+ switch (*c++) {
+ case 'L':
+ if (h <= ERTS_TOPOLOGY_LOGICAL)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
+ idseqp = &cput->logical;
+ h = ERTS_TOPOLOGY_LOGICAL;
+ break;
+ case 't':
+ case 'T':
+ if (h <= ERTS_TOPOLOGY_THREAD)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
+ idseqp = &cput->thread;
+ h = ERTS_TOPOLOGY_THREAD;
+ break;
+ case 'c':
+ case 'C':
+ if (h <= ERTS_TOPOLOGY_CORE)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
+ idseqp = &cput->core;
+ h = ERTS_TOPOLOGY_CORE;
+ break;
+ case 'p':
+ case 'P':
+ if (h <= ERTS_TOPOLOGY_PROCESSOR)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
+ idseqp = &cput->processor;
+ h = ERTS_TOPOLOGY_PROCESSOR;
+ break;
+ case 'n':
+ case 'N':
+ if (h <= ERTS_TOPOLOGY_PROCESSOR) {
+ do_node:
+ if (h <= ERTS_TOPOLOGY_NODE)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
+ idseqp = &cput->node;
+ h = ERTS_TOPOLOGY_NODE;
+ }
+ else {
+ int p_node = 0;
+ char *p_chk = c;
+ while (*p_chk != '\0' && *p_chk != ':') {
+ if (*p_chk == 'p' || *p_chk == 'P') {
+ p_node = 1;
+ break;
+ }
+ p_chk++;
+ }
+ if (!p_node)
+ goto do_node;
+ if (h <= ERTS_TOPOLOGY_PROCESSOR_NODE)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
+ idseqp = &cput->processor_node;
+ h = ERTS_TOPOLOGY_PROCESSOR_NODE;
+ }
+ break;
+ default:
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_TYPE;
+ }
+ res = get_cput_id_seq(idseqp, &c);
+ if (res != ERTS_INIT_CPU_TOPOLOGY_OK)
+ return res;
+ }
+
+ if (cput->logical.used < 1)
+ return ERTS_INIT_CPU_TOPOLOGY_MISSING_LID;
+
+ if (*c == ':') {
+ c++;
+ }
+
+ if (cput->thread.used != 1
+ && cput->thread.used != cput->logical.used)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
+ if (cput->core.used != 1
+ && cput->core.used != cput->logical.used)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
+ if (cput->processor_node.used != 1
+ && cput->processor_node.used != cput->logical.used)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
+ if (cput->processor.used != 1
+ && cput->processor.used != cput->logical.used)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
+ if (cput->node.used != 1
+ && cput->node.used != cput->logical.used)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
+
+ *str = c;
+ return ERTS_INIT_CPU_TOPOLOGY_OK;
+}
+
+static int
+verify_topology(erts_cpu_topology_t *cpudata, int size)
+{
+ if (size > 0) {
+ int *logical;
+ int node, processor, no_nodes, i;
+
+ /* Verify logical ids */
+ logical = erts_alloc(ERTS_ALC_T_TMP, sizeof(int)*size);
+
+ for (i = 0; i < size; i++)
+ logical[i] = cpudata[i].logical;
+
+ qsort(logical, size, sizeof(int), int_cmp);
+ for (i = 0; i < size-1; i++) {
+ if (logical[i] == logical[i+1]) {
+ erts_free(ERTS_ALC_T_TMP, logical);
+ return ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_LIDS;
+ }
+ }
+
+ erts_free(ERTS_ALC_T_TMP, logical);
+
+ qsort(cpudata, size, sizeof(erts_cpu_topology_t), processor_order_cmp);
+
+ /* Verify unique entities */
+
+ for (i = 1; i < size; i++) {
+ if (cpudata[i-1].processor == cpudata[i].processor
+ && cpudata[i-1].node == cpudata[i].node
+ && (cpudata[i-1].processor_node
+ == cpudata[i].processor_node)
+ && cpudata[i-1].core == cpudata[i].core
+ && cpudata[i-1].thread == cpudata[i].thread) {
+ return ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_ENTITIES;
+ }
+ }
+
+ /* Verify numa nodes */
+ node = cpudata[0].node;
+ processor = cpudata[0].processor;
+ no_nodes = cpudata[0].node < 0 && cpudata[0].processor_node < 0;
+ for (i = 1; i < size; i++) {
+ if (no_nodes) {
+ if (cpudata[i].node >= 0 || cpudata[i].processor_node >= 0)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES;
+ }
+ else {
+ if (cpudata[i].processor == processor && cpudata[i].node != node)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES;
+ node = cpudata[i].node;
+ processor = cpudata[i].processor;
+ if (node >= 0 && cpudata[i].processor_node >= 0)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES;
+ if (node < 0 && cpudata[i].processor_node < 0)
+ return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES;
+ }
+ }
+ }
+
+ return ERTS_INIT_CPU_TOPOLOGY_OK;
+}
+
+int
+erts_init_cpu_topology_string(char *topology_str)
+{
+ ErtsCpuTopEntry cput;
+ int need_size;
+ char *c;
+ int ix;
+ int error = ERTS_INIT_CPU_TOPOLOGY_OK;
+
+ if (user_cpudata)
+ erts_free(ERTS_ALC_T_CPUDATA, user_cpudata);
+ user_cpudata_size = 10;
+
+ user_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA,
+ (sizeof(erts_cpu_topology_t)
+ * user_cpudata_size));
+
+ init_cpu_top_entry(&cput);
+
+ ix = 0;
+ need_size = 0;
+
+ c = topology_str;
+ if (*c == '\0') {
+ error = ERTS_INIT_CPU_TOPOLOGY_MISSING;
+ goto fail;
+ }
+ do {
+ int r;
+ error = get_cput_entry(&cput, &c);
+ if (error != ERTS_INIT_CPU_TOPOLOGY_OK)
+ goto fail;
+ need_size += cput.logical.used;
+ if (user_cpudata_size < need_size) {
+ user_cpudata_size = need_size + 10;
+ user_cpudata = erts_realloc(ERTS_ALC_T_CPUDATA,
+ user_cpudata,
+ (sizeof(erts_cpu_topology_t)
+ * user_cpudata_size));
+ }
+
+ ASSERT(cput.thread.used == 1
+ || cput.thread.used == cput.logical.used);
+ ASSERT(cput.core.used == 1
+ || cput.core.used == cput.logical.used);
+ ASSERT(cput.processor_node.used == 1
+ || cput.processor_node.used == cput.logical.used);
+ ASSERT(cput.processor.used == 1
+ || cput.processor.used == cput.logical.used);
+ ASSERT(cput.node.used == 1
+ || cput.node.used == cput.logical.used);
+
+ for (r = 0; r < cput.logical.used; r++) {
+ user_cpudata[ix].logical = cput.logical.id[r];
+ user_cpudata[ix].thread =
+ cput.thread.id[cput.thread.used == 1 ? 0 : r];
+ user_cpudata[ix].core =
+ cput.core.id[cput.core.used == 1 ? 0 : r];
+ user_cpudata[ix].processor_node =
+ cput.processor_node.id[cput.processor_node.used == 1 ? 0 : r];
+ user_cpudata[ix].processor =
+ cput.processor.id[cput.processor.used == 1 ? 0 : r];
+ user_cpudata[ix].node =
+ cput.node.id[cput.node.used == 1 ? 0 : r];
+ ix++;
+ }
+ } while (*c != '\0');
+
+ if (user_cpudata_size != ix) {
+ user_cpudata_size = ix;
+ user_cpudata = erts_realloc(ERTS_ALC_T_CPUDATA,
+ user_cpudata,
+ (sizeof(erts_cpu_topology_t)
+ * user_cpudata_size));
+ }
+
+ error = verify_topology(user_cpudata, user_cpudata_size);
+ if (error == ERTS_INIT_CPU_TOPOLOGY_OK) {
+ destroy_cpu_top_entry(&cput);
+ return ERTS_INIT_CPU_TOPOLOGY_OK;
+ }
+
+ fail:
+ if (user_cpudata)
+ erts_free(ERTS_ALC_T_CPUDATA, user_cpudata);
+ user_cpudata_size = 0;
+ destroy_cpu_top_entry(&cput);
+ return error;
+}
+
+#define ERTS_GET_CPU_TOPOLOGY_ERROR -1
+#define ERTS_GET_USED_CPU_TOPOLOGY 0
+#define ERTS_GET_DETECTED_CPU_TOPOLOGY 1
+#define ERTS_GET_DEFINED_CPU_TOPOLOGY 2
+
+static Eterm get_cpu_topology_term(Process *c_p, int type);
+
+Eterm
+erts_set_cpu_topology(Process *c_p, Eterm term)
+{
+ erts_cpu_topology_t *cpudata = NULL;
+ int cpudata_size = 0;
+ Eterm res;
+
+ erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
+ res = get_cpu_topology_term(c_p, ERTS_GET_USED_CPU_TOPOLOGY);
+ if (term == am_undefined) {
+ if (user_cpudata)
+ erts_free(ERTS_ALC_T_CPUDATA, user_cpudata);
+ user_cpudata = NULL;
+ user_cpudata_size = 0;
+
+ if (cpu_bind_order != ERTS_CPU_BIND_NONE && system_cpudata) {
+ cpudata_size = system_cpudata_size;
+ cpudata = erts_alloc(ERTS_ALC_T_TMP,
+ (sizeof(erts_cpu_topology_t)
+ * cpudata_size));
+
+ sys_memcpy((void *) cpudata,
+ (void *) system_cpudata,
+ sizeof(erts_cpu_topology_t)*cpudata_size);
+ }
+ }
+ else if (is_not_list(term)) {
+ error:
+ erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
+ res = THE_NON_VALUE;
+ goto done;
+ }
+ else {
+ Eterm list = term;
+ int ix = 0;
+
+ cpudata_size = 100;
+ cpudata = erts_alloc(ERTS_ALC_T_TMP,
+ (sizeof(erts_cpu_topology_t)
+ * cpudata_size));
+
+ while (is_list(list)) {
+ Eterm *lp = list_val(list);
+ Eterm cpu = CAR(lp);
+ Eterm* tp;
+ Sint id;
+
+ if (is_not_tuple(cpu))
+ goto error;
+
+ tp = tuple_val(cpu);
+
+ if (arityval(tp[0]) != 7 || tp[1] != am_cpu)
+ goto error;
+
+ if (ix >= cpudata_size) {
+ cpudata_size += 100;
+ cpudata = erts_realloc(ERTS_ALC_T_TMP,
+ cpudata,
+ (sizeof(erts_cpu_topology_t)
+ * cpudata_size));
+ }
+
+ id = signed_val(tp[2]);
+ if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
+ goto error;
+ cpudata[ix].node = (int) id;
+
+ id = signed_val(tp[3]);
+ if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
+ goto error;
+ cpudata[ix].processor = (int) id;
+
+ id = signed_val(tp[4]);
+ if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
+ goto error;
+ cpudata[ix].processor_node = (int) id;
+
+ id = signed_val(tp[5]);
+ if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
+ goto error;
+ cpudata[ix].core = (int) id;
+
+ id = signed_val(tp[6]);
+ if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
+ goto error;
+ cpudata[ix].thread = (int) id;
+
+ id = signed_val(tp[7]);
+ if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
+ goto error;
+ cpudata[ix].logical = (int) id;
+
+ list = CDR(lp);
+ ix++;
+ }
+
+ if (is_not_nil(list))
+ goto error;
+
+ cpudata_size = ix;
+
+ if (ERTS_INIT_CPU_TOPOLOGY_OK != verify_topology(cpudata, cpudata_size))
+ goto error;
+
+ if (user_cpudata_size != cpudata_size) {
+ if (user_cpudata)
+ erts_free(ERTS_ALC_T_CPUDATA, user_cpudata);
+ user_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA,
+ sizeof(erts_cpu_topology_t)*cpudata_size);
+ user_cpudata_size = cpudata_size;
+ }
+
+ sys_memcpy((void *) user_cpudata,
+ (void *) cpudata,
+ sizeof(erts_cpu_topology_t)*cpudata_size);
+ }
+
+ update_cpu_groups_maps();
+
+ write_schedulers_bind_change(cpudata, cpudata_size);
+
+ erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
+ erts_sched_notify_check_cpu_bind();
+
+ done:
+
+ if (cpudata)
+ erts_free(ERTS_ALC_T_TMP, cpudata);
+
+ return res;
+}
+
+static void
+create_tmp_cpu_topology_copy(erts_cpu_topology_t **cpudata, int *cpudata_size)
+{
+ if (user_cpudata) {
+ *cpudata_size = user_cpudata_size;
+ *cpudata = erts_alloc(ERTS_ALC_T_TMP,
+ (sizeof(erts_cpu_topology_t)
+ * (*cpudata_size)));
+ sys_memcpy((void *) *cpudata,
+ (void *) user_cpudata,
+ sizeof(erts_cpu_topology_t)*(*cpudata_size));
+ }
+ else if (system_cpudata) {
+ *cpudata_size = system_cpudata_size;
+ *cpudata = erts_alloc(ERTS_ALC_T_TMP,
+ (sizeof(erts_cpu_topology_t)
+ * (*cpudata_size)));
+ sys_memcpy((void *) *cpudata,
+ (void *) system_cpudata,
+ sizeof(erts_cpu_topology_t)*(*cpudata_size));
+ }
+ else {
+ *cpudata = NULL;
+ *cpudata_size = 0;
+ }
+}
+
+static void
+destroy_tmp_cpu_topology_copy(erts_cpu_topology_t *cpudata)
+{
+ if (cpudata)
+ erts_free(ERTS_ALC_T_TMP, cpudata);
+}
+
+
+static Eterm
+bld_topology_term(Eterm **hpp,
+ Uint *hszp,
+ erts_cpu_topology_t *cpudata,
+ int size)
+{
+ Eterm res = NIL;
+ int i;
+
+ if (size == 0)
+ return am_undefined;
+
+ for (i = size-1; i >= 0; i--) {
+ res = erts_bld_cons(hpp,
+ hszp,
+ erts_bld_tuple(hpp,
+ hszp,
+ 7,
+ am_cpu,
+ make_small(cpudata[i].node),
+ make_small(cpudata[i].processor),
+ make_small(cpudata[i].processor_node),
+ make_small(cpudata[i].core),
+ make_small(cpudata[i].thread),
+ make_small(cpudata[i].logical)),
+ res);
+ }
+ return res;
+}
+
+static Eterm
+get_cpu_topology_term(Process *c_p, int type)
+{
+#ifdef DEBUG
+ Eterm *hp_end;
+#endif
+ Eterm *hp;
+ Uint hsz;
+ Eterm res = THE_NON_VALUE;
+ erts_cpu_topology_t *cpudata = NULL;
+ int size = 0;
+
+ switch (type) {
+ case ERTS_GET_USED_CPU_TOPOLOGY:
+ if (user_cpudata)
+ goto defined;
+ else
+ goto detected;
+ case ERTS_GET_DETECTED_CPU_TOPOLOGY:
+ detected:
+ if (!system_cpudata)
+ res = am_undefined;
+ else {
+ size = system_cpudata_size;
+ cpudata = erts_alloc(ERTS_ALC_T_TMP,
+ (sizeof(erts_cpu_topology_t)
+ * size));
+ sys_memcpy((void *) cpudata,
+ (void *) system_cpudata,
+ sizeof(erts_cpu_topology_t)*size);
+ }
+ break;
+ case ERTS_GET_DEFINED_CPU_TOPOLOGY:
+ defined:
+ if (!user_cpudata)
+ res = am_undefined;
+ else {
+ size = user_cpudata_size;
+ cpudata = user_cpudata;
+ }
+ break;
+ default:
+ erl_exit(ERTS_ABORT_EXIT, "Bad cpu topology type: %d\n", type);
+ break;
+ }
+
+ if (res == am_undefined) {
+ ASSERT(!cpudata);
+ return res;
+ }
+
+ hsz = 0;
+
+ bld_topology_term(NULL, &hsz,
+ cpudata, size);
+
+ hp = HAlloc(c_p, hsz);
+
+#ifdef DEBUG
+ hp_end = hp + hsz;
+#endif
+
+ res = bld_topology_term(&hp, NULL,
+ cpudata, size);
+
+ ASSERT(hp_end == hp);
+
+ if (cpudata && cpudata != system_cpudata && cpudata != user_cpudata)
+ erts_free(ERTS_ALC_T_TMP, cpudata);
+
+ return res;
+}
+
+Eterm
+erts_get_cpu_topology_term(Process *c_p, Eterm which)
+{
+ Eterm res;
+ int type;
+ erts_smp_rwmtx_rlock(&cpuinfo_rwmtx);
+ if (ERTS_IS_ATOM_STR("used", which))
+ type = ERTS_GET_USED_CPU_TOPOLOGY;
+ else if (ERTS_IS_ATOM_STR("detected", which))
+ type = ERTS_GET_DETECTED_CPU_TOPOLOGY;
+ else if (ERTS_IS_ATOM_STR("defined", which))
+ type = ERTS_GET_DEFINED_CPU_TOPOLOGY;
+ else
+ type = ERTS_GET_CPU_TOPOLOGY_ERROR;
+ if (type == ERTS_GET_CPU_TOPOLOGY_ERROR)
+ res = THE_NON_VALUE;
+ else
+ res = get_cpu_topology_term(c_p, type);
+ erts_smp_rwmtx_runlock(&cpuinfo_rwmtx);
+ return res;
+}
+
+static void
+get_logical_processors(int *conf, int *onln, int *avail)
+{
+ if (conf)
+ *conf = erts_get_cpu_configured(cpuinfo);
+ if (onln)
+ *onln = erts_get_cpu_online(cpuinfo);
+ if (avail)
+ *avail = erts_get_cpu_available(cpuinfo);
+}
+
+void
+erts_get_logical_processors(int *conf, int *onln, int *avail)
+{
+ erts_smp_rwmtx_rlock(&cpuinfo_rwmtx);
+ get_logical_processors(conf, onln, avail);
+ erts_smp_rwmtx_runlock(&cpuinfo_rwmtx);
+}
+
+void
+erts_pre_early_init_cpu_topology(int *max_rg_p,
+ int *conf_p,
+ int *onln_p,
+ int *avail_p)
+{
+ cpu_groups_maps = NULL;
+ no_cpu_groups_callbacks = 0;
+ *max_rg_p = ERTS_MAX_READER_GROUPS;
+ cpuinfo = erts_cpu_info_create();
+ get_logical_processors(conf_p, onln_p, avail_p);
+}
+
+void
+erts_early_init_cpu_topology(int no_schedulers,
+ int *max_main_threads_p,
+ int max_reader_groups,
+ int *reader_groups_p)
+{
+ user_cpudata = NULL;
+ user_cpudata_size = 0;
+
+ system_cpudata_size = erts_get_cpu_topology_size(cpuinfo);
+ system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA,
+ (sizeof(erts_cpu_topology_t)
+ * system_cpudata_size));
+
+ cpu_bind_order = ERTS_CPU_BIND_UNDEFINED;
+
+ if (!erts_get_cpu_topology(cpuinfo, system_cpudata)
+ || ERTS_INIT_CPU_TOPOLOGY_OK != verify_topology(system_cpudata,
+ system_cpudata_size)) {
+ erts_free(ERTS_ALC_T_CPUDATA, system_cpudata);
+ system_cpudata = NULL;
+ system_cpudata_size = 0;
+ }
+
+ max_main_threads = erts_get_cpu_configured(cpuinfo);
+ if (max_main_threads > no_schedulers)
+ max_main_threads = no_schedulers;
+ *max_main_threads_p = max_main_threads;
+
+ reader_groups = max_main_threads;
+ if (reader_groups <= 1 || max_reader_groups <= 1)
+ reader_groups = 0;
+ if (reader_groups > max_reader_groups)
+ reader_groups = max_reader_groups;
+ *reader_groups_p = reader_groups;
+}
+
+void
+erts_init_cpu_topology(void)
+{
+ int ix;
+
+ erts_smp_rwmtx_init(&cpuinfo_rwmtx, "cpu_info");
+ erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
+
+ scheduler2cpu_map = erts_alloc(ERTS_ALC_T_CPUDATA,
+ (sizeof(ErtsCpuBindData)
+ * (erts_no_schedulers+1)));
+ for (ix = 1; ix <= erts_no_schedulers; ix++) {
+ scheduler2cpu_map[ix].bind_id = -1;
+ scheduler2cpu_map[ix].bound_id = -1;
+ }
+
+ if (cpu_bind_order == ERTS_CPU_BIND_UNDEFINED) {
+ int ncpus = erts_get_cpu_configured(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(cpuinfo, -1) != -ENOTSUP)
+ ? ERTS_CPU_BIND_DEFAULT_BIND
+ : ERTS_CPU_BIND_NONE);
+ }
+
+ reader_groups_map = add_cpu_groups(reader_groups,
+ reader_groups_callback,
+ NULL);
+
+ if (cpu_bind_order == ERTS_CPU_BIND_NONE)
+ erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
+ else {
+ erts_cpu_topology_t *cpudata;
+ int cpudata_size;
+ create_tmp_cpu_topology_copy(&cpudata, &cpudata_size);
+ write_schedulers_bind_change(cpudata, cpudata_size);
+ erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
+ erts_sched_notify_check_cpu_bind();
+ destroy_tmp_cpu_topology_copy(cpudata);
+ }
+}
+
+int
+erts_update_cpu_info(void)
+{
+ int changed;
+ erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
+ changed = erts_cpu_info_update(cpuinfo);
+ if (changed) {
+ erts_cpu_topology_t *cpudata;
+ int cpudata_size;
+
+ if (system_cpudata)
+ erts_free(ERTS_ALC_T_CPUDATA, system_cpudata);
+
+ system_cpudata_size = erts_get_cpu_topology_size(cpuinfo);
+ if (!system_cpudata_size)
+ system_cpudata = NULL;
+ else {
+ system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA,
+ (sizeof(erts_cpu_topology_t)
+ * system_cpudata_size));
+
+ if (!erts_get_cpu_topology(cpuinfo, system_cpudata)
+ || (ERTS_INIT_CPU_TOPOLOGY_OK
+ != verify_topology(system_cpudata,
+ system_cpudata_size))) {
+ erts_free(ERTS_ALC_T_CPUDATA, system_cpudata);
+ system_cpudata = NULL;
+ system_cpudata_size = 0;
+ }
+ }
+
+ update_cpu_groups_maps();
+
+ create_tmp_cpu_topology_copy(&cpudata, &cpudata_size);
+ write_schedulers_bind_change(cpudata, cpudata_size);
+ destroy_tmp_cpu_topology_copy(cpudata);
+ }
+ erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
+ if (changed)
+ erts_sched_notify_check_cpu_bind();
+ return changed;
+}
+
+/*
+ * reader groups map
+ */
+
+void
+reader_groups_callback(int suspending,
+ ErtsSchedulerData *esdp,
+ int group,
+ void *unused)
+{
+ if (reader_groups && esdp->no <= max_main_threads)
+ erts_smp_rwmtx_set_reader_group(suspending ? 0 : group+1);
+}
+
+static Eterm get_cpu_groups_map(Process *c_p,
+ erts_cpu_groups_map_t *map,
+ int offset);
+Eterm
+erts_debug_reader_groups_map(Process *c_p, int groups)
+{
+ Eterm res;
+ erts_cpu_groups_map_t test;
+
+ test.array = NULL;
+ test.groups = groups;
+ make_cpu_groups_map(&test, 1);
+ if (!test.array)
+ res = NIL;
+ else {
+ res = get_cpu_groups_map(c_p, &test, 1);
+ erts_free(ERTS_ALC_T_TMP, test.array);
+ }
+ return res;
+}
+
+
+Eterm
+erts_get_reader_groups_map(Process *c_p)
+{
+ Eterm res;
+ erts_smp_rwmtx_rlock(&cpuinfo_rwmtx);
+ res = get_cpu_groups_map(c_p, reader_groups_map, 1);
+ erts_smp_rwmtx_runlock(&cpuinfo_rwmtx);
+ return res;
+}
+
+/*
+ * CPU groups
+ */
+
+static Eterm
+get_cpu_groups_map(Process *c_p,
+ erts_cpu_groups_map_t *map,
+ int offset)
+{
+#ifdef DEBUG
+ Eterm *endp;
+#endif
+ Eterm res = NIL, tuple;
+ Eterm *hp;
+ int i;
+
+ hp = HAlloc(c_p, map->logical_processors*(2+3));
+#ifdef DEBUG
+ endp = hp + map->logical_processors*(2+3);
+#endif
+ for (i = map->size - 1; i >= 0; i--) {
+ if (map->array[i].logical >= 0) {
+ tuple = TUPLE2(hp,
+ make_small(map->array[i].logical),
+ make_small(map->array[i].cpu_group + offset));
+ hp += 3;
+ res = CONS(hp, tuple, res);
+ hp += 2;
+ }
+ }
+ ASSERT(hp == endp);
+ return res;
+}
+
+static void
+make_available_cpu_topology(erts_avail_cput *no,
+ erts_avail_cput *avail,
+ erts_cpu_topology_t *cpudata,
+ int *size,
+ int test)
+{
+ int len = *size;
+ erts_cpu_topology_t last;
+ int a, i, j;
+
+ no->level[ERTS_TOPOLOGY_NODE] = -1;
+ no->level[ERTS_TOPOLOGY_PROCESSOR] = -1;
+ no->level[ERTS_TOPOLOGY_PROCESSOR_NODE] = -1;
+ no->level[ERTS_TOPOLOGY_CORE] = -1;
+ no->level[ERTS_TOPOLOGY_THREAD] = -1;
+ no->level[ERTS_TOPOLOGY_LOGICAL] = -1;
+
+ last.node = INT_MIN;
+ last.processor = INT_MIN;
+ last.processor_node = INT_MIN;
+ last.core = INT_MIN;
+ last.thread = INT_MIN;
+ last.logical = INT_MIN;
+
+ a = 0;
+
+ for (i = 0; i < len; i++) {
+
+ if (!test && !erts_is_cpu_available(cpuinfo, cpudata[i].logical))
+ continue;
+
+ if (last.node != cpudata[i].node)
+ goto node;
+ if (last.processor != cpudata[i].processor)
+ goto processor;
+ if (last.processor_node != cpudata[i].processor_node)
+ goto processor_node;
+ if (last.core != cpudata[i].core)
+ goto core;
+ ASSERT(last.thread != cpudata[i].thread);
+ goto thread;
+
+ node:
+ no->level[ERTS_TOPOLOGY_NODE]++;
+ processor:
+ no->level[ERTS_TOPOLOGY_PROCESSOR]++;
+ processor_node:
+ no->level[ERTS_TOPOLOGY_PROCESSOR_NODE]++;
+ core:
+ no->level[ERTS_TOPOLOGY_CORE]++;
+ thread:
+ no->level[ERTS_TOPOLOGY_THREAD]++;
+
+ no->level[ERTS_TOPOLOGY_LOGICAL]++;
+
+ for (j = 0; j < ERTS_TOPOLOGY_LOGICAL; j++)
+ avail[a].level[j] = no->level[j];
+
+ avail[a].level[ERTS_TOPOLOGY_LOGICAL] = cpudata[i].logical;
+ avail[a].level[ERTS_TOPOLOGY_CG] = 0;
+
+ ASSERT(last.logical != cpudata[i].logical);
+
+ last = cpudata[i];
+ a++;
+ }
+
+ no->level[ERTS_TOPOLOGY_NODE]++;
+ no->level[ERTS_TOPOLOGY_PROCESSOR]++;
+ no->level[ERTS_TOPOLOGY_PROCESSOR_NODE]++;
+ no->level[ERTS_TOPOLOGY_CORE]++;
+ no->level[ERTS_TOPOLOGY_THREAD]++;
+ no->level[ERTS_TOPOLOGY_LOGICAL]++;
+
+ *size = a;
+}
+
+static void
+cpu_group_insert(erts_cpu_groups_map_t *map,
+ int logical, int cpu_group)
+{
+ int start = logical % map->size;
+ int ix = start;
+
+ do {
+ if (map->array[ix].logical < 0) {
+ map->array[ix].logical = logical;
+ map->array[ix].cpu_group = cpu_group;
+ return;
+ }
+ ix++;
+ if (ix == map->size)
+ ix = 0;
+ } while (ix != start);
+
+ erl_exit(ERTS_ABORT_EXIT, "Reader groups map full\n");
+}
+
+
+static int
+sub_levels(erts_cpu_groups_count_t *cgc, int level, int aix,
+ int avail_sz, erts_avail_cput *avail)
+{
+ int sub_level = level+1;
+ int last = -1;
+ cgc->sub_levels = 0;
+
+ do {
+ if (last != avail[aix].level[sub_level]) {
+ cgc->sub_levels++;
+ last = avail[aix].level[sub_level];
+ }
+ aix++;
+ }
+ while (aix < avail_sz && cgc->id == avail[aix].level[level]);
+ cgc->cpu_groups = 0;
+ return aix;
+}
+
+static int
+write_cpu_groups(int *cgp, erts_cpu_groups_count_t *cgcp,
+ int level, int a,
+ int avail_sz, erts_avail_cput *avail)
+{
+ int cg = *cgp;
+ int sub_level = level+1;
+ int sl_per_gr = cgcp->sub_levels / cgcp->cpu_groups;
+ int xsl = cgcp->sub_levels % cgcp->cpu_groups;
+ int sls = 0;
+ int last = -1;
+ int xsl_cg_lim = (cgcp->cpu_groups - xsl) + cg + 1;
+
+ ASSERT(level < 0 || avail[a].level[level] == cgcp->id);
+
+ do {
+ if (last != avail[a].level[sub_level]) {
+ if (!sls) {
+ sls = sl_per_gr;
+ cg++;
+ if (cg >= xsl_cg_lim)
+ sls++;
+ }
+ last = avail[a].level[sub_level];
+ sls--;
+ }
+ avail[a].level[ERTS_TOPOLOGY_CG] = cg;
+ a++;
+ } while (a < avail_sz && (level < 0
+ || avail[a].level[level] == cgcp->id));
+
+ ASSERT(cgcp->cpu_groups == cg - *cgp);
+
+ *cgp = cg;
+
+ return a;
+}
+
+static int
+cg_count_sub_levels_compare(const void *vx, const void *vy)
+{
+ erts_cpu_groups_count_t *x = (erts_cpu_groups_count_t *) vx;
+ erts_cpu_groups_count_t *y = (erts_cpu_groups_count_t *) vy;
+ if (x->sub_levels != y->sub_levels)
+ return y->sub_levels - x->sub_levels;
+ return x->id - y->id;
+}
+
+static int
+cg_count_id_compare(const void *vx, const void *vy)
+{
+ erts_cpu_groups_count_t *x = (erts_cpu_groups_count_t *) vx;
+ erts_cpu_groups_count_t *y = (erts_cpu_groups_count_t *) vy;
+ return x->id - y->id;
+}
+
+static void
+make_cpu_groups_map(erts_cpu_groups_map_t *map, int test)
+{
+ int i, spread_level, avail_sz;
+ erts_avail_cput no, *avail;
+ erts_cpu_topology_t *cpudata;
+ ErtsAlcType_t alc_type = (test
+ ? ERTS_ALC_T_TMP
+ : ERTS_ALC_T_CPU_GRPS_MAP);
+
+ if (map->array)
+ erts_free(alc_type, map->array);
+
+ map->array = NULL;
+ map->logical_processors = 0;
+ map->size = 0;
+
+ if (!map->groups)
+ return;
+
+ create_tmp_cpu_topology_copy(&cpudata, &avail_sz);
+
+ if (!cpudata)
+ return;
+
+ cpu_bind_order_sort(cpudata,
+ avail_sz,
+ ERTS_CPU_BIND_NO_SPREAD,
+ 1);
+
+ avail = erts_alloc(ERTS_ALC_T_TMP,
+ sizeof(erts_avail_cput)*avail_sz);
+
+ make_available_cpu_topology(&no, avail, cpudata,
+ &avail_sz, test);
+
+ destroy_tmp_cpu_topology_copy(cpudata);
+
+ map->size = avail_sz*2+1;
+
+ map->array = erts_alloc(alc_type,
+ (sizeof(erts_cpu_groups_map_array_t)
+ * map->size));;
+ map->logical_processors = avail_sz;
+
+ for (i = 0; i < map->size; i++) {
+ map->array[i].logical = -1;
+ map->array[i].cpu_group = -1;
+ }
+
+ spread_level = ERTS_TOPOLOGY_CORE;
+ for (i = ERTS_TOPOLOGY_NODE; i < ERTS_TOPOLOGY_THREAD; i++) {
+ if (no.level[i] > map->groups) {
+ spread_level = i;
+ break;
+ }
+ }
+
+ if (no.level[spread_level] <= map->groups) {
+ int a, cg, last = -1;
+ cg = -1;
+ ASSERT(spread_level == ERTS_TOPOLOGY_CORE);
+ for (a = 0; a < avail_sz; a++) {
+ if (last != avail[a].level[spread_level]) {
+ cg++;
+ last = avail[a].level[spread_level];
+ }
+ cpu_group_insert(map,
+ avail[a].level[ERTS_TOPOLOGY_LOGICAL],
+ cg);
+ }
+ }
+ else { /* map->groups < no.level[spread_level] */
+ erts_cpu_groups_count_t *cg_count;
+ int a, cg, tl, toplevels;
+
+ tl = spread_level-1;
+
+ if (spread_level == ERTS_TOPOLOGY_NODE)
+ toplevels = 1;
+ else
+ toplevels = no.level[tl];
+
+ cg_count = erts_alloc(ERTS_ALC_T_TMP,
+ toplevels*sizeof(erts_cpu_groups_count_t));
+
+ if (toplevels == 1) {
+ cg_count[0].id = 0;
+ cg_count[0].sub_levels = no.level[spread_level];
+ cg_count[0].cpu_groups = map->groups;
+ }
+ else {
+ int cgs_per_tl, cgs;
+ cgs = map->groups;
+ cgs_per_tl = cgs / toplevels;
+
+ a = 0;
+ for (i = 0; i < toplevels; i++) {
+ cg_count[i].id = avail[a].level[tl];
+ a = sub_levels(&cg_count[i], tl, a, avail_sz, avail);
+ }
+
+ qsort(cg_count,
+ toplevels,
+ sizeof(erts_cpu_groups_count_t),
+ cg_count_sub_levels_compare);
+
+ for (i = 0; i < toplevels; i++) {
+ if (cg_count[i].sub_levels < cgs_per_tl) {
+ cg_count[i].cpu_groups = cg_count[i].sub_levels;
+ cgs -= cg_count[i].sub_levels;
+ }
+ else {
+ cg_count[i].cpu_groups = cgs_per_tl;
+ cgs -= cgs_per_tl;
+ }
+ }
+
+ while (cgs > 0) {
+ for (i = 0; i < toplevels; i++) {
+ if (cg_count[i].sub_levels == cg_count[i].cpu_groups)
+ break;
+ else {
+ cg_count[i].cpu_groups++;
+ if (--cgs == 0)
+ break;
+ }
+ }
+ }
+
+ qsort(cg_count,
+ toplevels,
+ sizeof(erts_cpu_groups_count_t),
+ cg_count_id_compare);
+ }
+
+ a = i = 0;
+ cg = -1;
+ while (a < avail_sz) {
+ a = write_cpu_groups(&cg, &cg_count[i], tl,
+ a, avail_sz, avail);
+ i++;
+ }
+
+ ASSERT(map->groups == cg + 1);
+
+ for (a = 0; a < avail_sz; a++)
+ cpu_group_insert(map,
+ avail[a].level[ERTS_TOPOLOGY_LOGICAL],
+ avail[a].level[ERTS_TOPOLOGY_CG]);
+
+ erts_free(ERTS_ALC_T_TMP, cg_count);
+ }
+
+ erts_free(ERTS_ALC_T_TMP, avail);
+}
+
+static erts_cpu_groups_map_t *
+add_cpu_groups(int groups,
+ erts_cpu_groups_callback_t callback,
+ void *arg)
+{
+ int use_groups = groups;
+ erts_cpu_groups_callback_list_t *cgcl;
+ erts_cpu_groups_map_t *cgm;
+
+ ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx));
+
+ if (use_groups > max_main_threads)
+ use_groups = max_main_threads;
+
+ if (!use_groups)
+ return NULL;
+
+ no_cpu_groups_callbacks++;
+ cgcl = erts_alloc(ERTS_ALC_T_CPU_GRPS_MAP,
+ sizeof(erts_cpu_groups_callback_list_t));
+ cgcl->callback = callback;
+ cgcl->arg = arg;
+
+ for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) {
+ if (cgm->groups == use_groups) {
+ cgcl->next = cgm->callback_list;
+ cgm->callback_list = cgcl;
+ return cgm;
+ }
+ }
+
+
+ cgm = erts_alloc(ERTS_ALC_T_CPU_GRPS_MAP,
+ sizeof(erts_cpu_groups_map_t));
+ cgm->next = cpu_groups_maps;
+ cgm->groups = use_groups;
+ cgm->array = NULL;
+ cgm->size = 0;
+ cgm->logical_processors = 0;
+ cgm->callback_list = cgcl;
+
+ cgcl->next = NULL;
+
+ make_cpu_groups_map(cgm, 0);
+
+ cpu_groups_maps = cgm;
+
+ return cgm;
+}
+
+static void
+remove_cpu_groups(erts_cpu_groups_callback_t callback, void *arg)
+{
+ erts_cpu_groups_map_t *prev_cgm, *cgm;
+ erts_cpu_groups_callback_list_t *prev_cgcl, *cgcl;
+
+ ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx));
+
+ no_cpu_groups_callbacks--;
+
+ prev_cgm = NULL;
+ for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) {
+ prev_cgcl = NULL;
+ for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) {
+ if (cgcl->callback == callback && cgcl->arg == arg) {
+ if (prev_cgcl)
+ prev_cgcl->next = cgcl->next;
+ else
+ cgm->callback_list = cgcl->next;
+ erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgcl);
+ if (!cgm->callback_list) {
+ if (prev_cgm)
+ prev_cgm->next = cgm->next;
+ else
+ cpu_groups_maps = cgm->next;
+ if (cgm->array)
+ erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm->array);
+ erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm);
+ }
+ return;
+ }
+ prev_cgcl = cgcl;
+ }
+ prev_cgm = cgm;
+ }
+
+ erl_exit(ERTS_ABORT_EXIT, "Cpu groups not found\n");
+}
+
+static int
+cpu_groups_lookup(erts_cpu_groups_map_t *map,
+ ErtsSchedulerData *esdp)
+{
+ int start, logical, ix;
+
+ ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rlocked(&cpuinfo_rwmtx)
+ || erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx));
+
+ if (esdp->cpu_id < 0)
+ return (((int) esdp->no) - 1) % map->groups;
+
+ logical = esdp->cpu_id;
+ start = logical % map->size;
+ ix = start;
+
+ do {
+ if (map->array[ix].logical == logical) {
+ int group = map->array[ix].cpu_group;
+ ASSERT(0 <= group && group < map->groups);
+ return group;
+ }
+ ix++;
+ if (ix == map->size)
+ ix = 0;
+ } while (ix != start);
+
+ erl_exit(ERTS_ABORT_EXIT, "Logical cpu id %d not found\n", logical);
+}
+
+static void
+update_cpu_groups_maps(void)
+{
+ erts_cpu_groups_map_t *cgm;
+ ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx));
+
+ for (cgm = cpu_groups_maps; cgm; cgm = cgm->next)
+ make_cpu_groups_map(cgm, 0);
+}
+
+void
+erts_add_cpu_groups(int groups,
+ erts_cpu_groups_callback_t callback,
+ void *arg)
+{
+ erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
+ add_cpu_groups(groups, callback, arg);
+ erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
+}
+
+void erts_remove_cpu_groups(erts_cpu_groups_callback_t callback,
+ void *arg)
+{
+ erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
+ remove_cpu_groups(callback, arg);
+ erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
+}
diff --git a/erts/emulator/beam/erl_cpu_topology.h b/erts/emulator/beam/erl_cpu_topology.h
new file mode 100644
index 0000000000..c5a9520b61
--- /dev/null
+++ b/erts/emulator/beam/erl_cpu_topology.h
@@ -0,0 +1,105 @@
+/*
+ * %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: CPU topology and related functionality
+ *
+ * Author: Rickard Green
+ */
+
+#ifndef ERL_CPU_TOPOLOGY_H__
+#define ERL_CPU_TOPOLOGY_H__
+
+void erts_pre_early_init_cpu_topology(int *max_rg_p,
+ int *conf_p,
+ int *onln_p,
+ int *avail_p);
+void erts_early_init_cpu_topology(int no_schedulers,
+ int *max_main_threads_p,
+ int max_reader_groups,
+ int *reader_groups_p);
+void erts_init_cpu_topology(void);
+
+
+#define ERTS_INIT_SCHED_BIND_TYPE_SUCCESS 0
+#define ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED 1
+#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY 2
+#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE 3
+
+int erts_init_scheduler_bind_type_string(char *how);
+
+
+#define ERTS_INIT_CPU_TOPOLOGY_OK 0
+#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID 1
+#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE 2
+#define ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY 3
+#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_TYPE 4
+#define ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES 5
+#define ERTS_INIT_CPU_TOPOLOGY_MISSING_LID 6
+#define ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_LIDS 7
+#define ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_ENTITIES 8
+#define ERTS_INIT_CPU_TOPOLOGY_MISSING 9
+
+int erts_init_cpu_topology_string(char *topology_str);
+
+void erts_sched_check_cpu_bind(ErtsSchedulerData *esdp);
+#ifdef ERTS_SMP
+void erts_sched_init_check_cpu_bind(ErtsSchedulerData *esdp);
+void erts_sched_check_cpu_bind_prep_suspend(ErtsSchedulerData *esdp);
+void erts_sched_check_cpu_bind_post_suspend(ErtsSchedulerData *esdp);
+#endif
+
+int erts_update_cpu_info(void);
+
+Eterm erts_bind_schedulers(Process *c_p, Eterm how);
+Eterm erts_get_schedulers_binds(Process *c_p);
+
+Eterm erts_get_reader_groups_map(Process *c_p);
+
+Eterm erts_set_cpu_topology(Process *c_p, Eterm term);
+Eterm erts_get_cpu_topology_term(Process *c_p, Eterm which);
+
+int erts_update_cpu_info(void);
+void erts_get_logical_processors(int *conf, int *onln, int *avail);
+
+int erts_sched_bind_atthrcreate_prepare(void);
+int erts_sched_bind_atthrcreate_child(int unbind);
+void erts_sched_bind_atthrcreate_parent(int unbind);
+
+int erts_sched_bind_atfork_prepare(void);
+int erts_sched_bind_atfork_child(int unbind);
+char *erts_sched_bind_atvfork_child(int unbind);
+void erts_sched_bind_atfork_parent(int unbind);
+
+Eterm erts_fake_scheduler_bindings(Process *p, Eterm how);
+Eterm erts_debug_cpu_groups_map(Process *c_p, int groups);
+
+
+typedef void (*erts_cpu_groups_callback_t)(int,
+ ErtsSchedulerData *,
+ int,
+ void *);
+
+void erts_add_cpu_groups(int groups,
+ erts_cpu_groups_callback_t callback,
+ void *arg);
+void erts_remove_cpu_groups(erts_cpu_groups_callback_t callback,
+ void *arg);
+
+#endif
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index 52d5f86ee0..5b74240cc3 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -179,6 +179,7 @@ extern DbTableMethod db_tree;
int user_requested_db_max_tabs;
int erts_ets_realloc_always_moves;
+int erts_ets_always_compress;
static int db_max_tabs;
static DbTable *meta_pid_to_tab; /* Pid mapped to owned tables */
static DbTable *meta_pid_to_fixed_tab; /* Pid mapped to fixed tables */
@@ -218,47 +219,68 @@ Export ets_select_continue_exp;
* Static traps
*/
static Export ets_delete_continue_exp;
-
-static ERTS_INLINE DbTable* db_ref(DbTable* tb, db_lock_kind_t kind)
-{
- if (tb != NULL && kind != LCK_READ) {
- erts_refc_inc(&tb->common.ref, 2);
- }
- return tb;
-}
-
-static ERTS_INLINE DbTable* db_unref(DbTable* tb, db_lock_kind_t kind)
+
+static void
+free_dbtable(DbTable* tb)
{
- if (kind != LCK_READ && !erts_refc_dectest(&tb->common.ref, 0)) {
#ifdef HARDDEBUG
if (erts_smp_atomic_read(&tb->common.memory_size) != sizeof(DbTable)) {
- erts_fprintf(stderr, "ets: db_unref memory remain=%ld fix=%x\n",
- erts_smp_atomic_read(&tb->common.memory_size)-sizeof(DbTable),
+ erts_fprintf(stderr, "ets: free_dbtable memory remain=%ld fix=%x\n",
+ erts_smp_atomic_read(&tb->common.memory_size)-sizeof(DbTable),
tb->common.fixations);
}
- erts_fprintf(stderr, "ets: db_unref(%T) deleted!!!\r\n",
+ erts_fprintf(stderr, "ets: free_dbtable(%T) deleted!!!\r\n",
tb->common.id);
- erts_fprintf(stderr, "ets: db_unref: meta_pid_to_tab common.memory_size = %ld\n",
+ erts_fprintf(stderr, "ets: free_dbtable: meta_pid_to_tab common.memory_size = %ld\n",
erts_smp_atomic_read(&meta_pid_to_tab->common.memory_size));
print_table(ERTS_PRINT_STDOUT, NULL, 1, meta_pid_to_tab);
- erts_fprintf(stderr, "ets: db_unref: meta_pid_to_fixed_tab common.memory_size = %ld\n",
+ erts_fprintf(stderr, "ets: free_dbtable: meta_pid_to_fixed_tab common.memory_size = %ld\n",
erts_smp_atomic_read(&meta_pid_to_fixed_tab->common.memory_size));
print_table(ERTS_PRINT_STDOUT, NULL, 1, meta_pid_to_fixed_tab);
-
#endif
#ifdef ERTS_SMP
erts_smp_rwmtx_destroy(&tb->common.rwlock);
erts_smp_mtx_destroy(&tb->common.fixlock);
#endif
ASSERT(is_immed(tb->common.heir_data));
- erts_db_free(ERTS_ALC_T_DB_TABLE, tb, (void *) tb, sizeof(DbTable));
+ erts_db_free(ERTS_ALC_T_DB_TABLE, tb, (void *) tb, sizeof(DbTable));
ERTS_ETS_MISC_MEM_ADD(-sizeof(DbTable));
- return NULL;
- }
- return tb;
+}
+
+#ifdef ERTS_SMP
+static void
+chk_free_dbtable(void *vtb)
+{
+ DbTable * tb = (DbTable *) vtb;
+ ERTS_THR_MEMORY_BARRIER;
+ if (erts_refc_dectest(&tb->common.ref, 0) == 0)
+ free_dbtable(tb);
+}
+#endif
+
+static void schedule_free_dbtable(DbTable* tb)
+{
+ /*
+ * NON-SMP case: Caller is *not* allowed to access the *tb
+ * structure after this function has returned!
+ * SMP case: Caller is allowed to access the *tb structure
+ * until the bif has returned (we typically
+ * need to unlock the table lock after this
+ * function has returned).
+ */
+#ifdef ERTS_SMP
+ int scheds = erts_get_max_no_executing_schedulers();
+ ASSERT(scheds >= 1);
+ ASSERT(erts_refc_read(&tb->common.ref, 0) == 0);
+ erts_refc_init(&tb->common.ref, scheds);
+ ERTS_THR_MEMORY_BARRIER;
+ erts_smp_schedule_misc_aux_work(0, scheds, chk_free_dbtable, tb);
+#else
+ free_dbtable(tb);
+#endif
}
static ERTS_INLINE void db_init_lock(DbTable* tb, int use_frequent_read_lock,
@@ -269,8 +291,6 @@ static ERTS_INLINE void db_init_lock(DbTable* tb, int use_frequent_read_lock,
if (use_frequent_read_lock)
rwmtx_opt.type = ERTS_SMP_RWMTX_TYPE_FREQUENT_READ;
#endif
- erts_refc_init(&tb->common.ref, 1);
- erts_refc_init(&tb->common.fixref, 0);
#ifdef ERTS_SMP
erts_smp_rwmtx_init_opt_x(&tb->common.rwlock, &rwmtx_opt,
rwname, tb->common.the_name);
@@ -279,7 +299,7 @@ static ERTS_INLINE void db_init_lock(DbTable* tb, int use_frequent_read_lock,
#endif
}
-static ERTS_INLINE void db_lock_take_over_ref(DbTable* tb, db_lock_kind_t kind)
+static ERTS_INLINE void db_lock(DbTable* tb, db_lock_kind_t kind)
{
#ifdef ERTS_SMP
ASSERT(tb != meta_pid_to_tab && tb != meta_pid_to_fixed_tab);
@@ -307,16 +327,13 @@ static ERTS_INLINE void db_lock_take_over_ref(DbTable* tb, db_lock_kind_t kind)
#endif
}
-static ERTS_INLINE void db_lock(DbTable* tb, db_lock_kind_t kind)
-{
- (void) db_ref(tb, kind);
-#ifdef ERTS_SMP
- db_lock_take_over_ref(tb, kind);
-#endif
-}
-
static ERTS_INLINE void db_unlock(DbTable* tb, db_lock_kind_t kind)
{
+ /*
+ * In NON-SMP case tb may refer to an already deallocated
+ * DbTable structure. That is, ONLY the SMP case is allowed
+ * to follow the tb pointer!
+ */
#ifdef ERTS_SMP
ASSERT(tb != meta_pid_to_tab && tb != meta_pid_to_fixed_tab);
@@ -343,7 +360,6 @@ static ERTS_INLINE void db_unlock(DbTable* tb, db_lock_kind_t kind)
}
}
#endif
- (void) db_unref(tb, kind); /* May delete table... */
}
@@ -370,6 +386,13 @@ DbTable* db_get_table_aux(Process *p,
DbTable *tb = NULL;
erts_smp_rwmtx_t *mtl = NULL;
+ /*
+ * IMPORTANT: Only scheduler threads are allowed
+ * to access tables. Memory management
+ * depend on it.
+ */
+ ASSERT(erts_get_scheduler_data());
+
if (is_small(id)) {
Uint slot = unsigned_val(id) & meta_main_tab_slot_mask;
if (!meta_already_locked) {
@@ -383,12 +406,8 @@ DbTable* db_get_table_aux(Process *p,
|| erts_lc_rwmtx_is_rwlocked(test_mtl));
}
#endif
- if (slot < db_max_tabs && IS_SLOT_ALIVE(slot)) {
- /* SMP: inc to prevent race, between unlock of meta_main_tab_lock
- * and the table locking outside the meta_main_tab_lock
- */
- tb = db_ref(meta_main_tab[slot].u.tb, kind);
- }
+ if (slot < db_max_tabs && IS_SLOT_ALIVE(slot))
+ tb = meta_main_tab[slot].u.tb;
}
else if (is_atom(id)) {
struct meta_name_tab_entry* bucket = meta_name_tab_bucket(id,&mtl);
@@ -402,16 +421,15 @@ DbTable* db_get_table_aux(Process *p,
if (bucket->pu.tb != NULL) {
if (is_atom(bucket->u.name_atom)) { /* single */
- if (bucket->u.name_atom == id) {
- tb = db_ref(bucket->pu.tb, kind);
- }
+ if (bucket->u.name_atom == id)
+ tb = bucket->pu.tb;
}
else { /* multi */
Uint cnt = unsigned_val(bucket->u.mcnt);
Uint i;
for (i=0; i<cnt; i++) {
if (bucket->pu.mvec[i].u.name_atom == id) {
- tb = db_ref(bucket->pu.mvec[i].pu.tb, kind);
+ tb = bucket->pu.mvec[i].pu.tb;
break;
}
}
@@ -419,7 +437,7 @@ DbTable* db_get_table_aux(Process *p,
}
}
if (tb) {
- db_lock_take_over_ref(tb, kind);
+ db_lock(tb, kind);
if (tb->common.id != id
|| ((tb->common.status & what) == 0 && p->id != tb->common.owner)) {
db_unlock(tb, kind);
@@ -593,11 +611,11 @@ done:
*/
static ERTS_INLINE void local_fix_table(DbTable* tb)
{
- erts_refc_inc(&tb->common.fixref, 1);
+ erts_refc_inc(&tb->common.ref, 1);
}
static ERTS_INLINE void local_unfix_table(DbTable* tb)
{
- if (erts_refc_dectest(&tb->common.fixref, 0) == 0) {
+ if (erts_refc_dectest(&tb->common.ref, 0) == 0) {
ASSERT(IS_HASH_TABLE(tb->common.status));
db_unfix_table_hash(&(tb->hash));
}
@@ -892,7 +910,8 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
Eterm upop;
Eterm* tpl;
Sint position;
- Eterm incr, warp, oldcnt;
+ Eterm incr, warp;
+ Wterm oldcnt;
if (is_not_list(iter)) {
goto finalize;
@@ -931,7 +950,7 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
position > arityval(handle.dbterm->tpl[0])) {
goto finalize;
}
- oldcnt = handle.dbterm->tpl[position];
+ oldcnt = db_do_read_element(&handle, position);
if (is_big(oldcnt)) {
halloc_size += BIG_NEED_SIZE(big_arity(oldcnt));
}
@@ -967,7 +986,7 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
Eterm* tpl = tuple_val(CAR(list_val(iter)));
Sint position = signed_val(tpl[1]);
Eterm incr = tpl[2];
- Eterm oldcnt = handle.dbterm->tpl[position];
+ Wterm oldcnt = db_do_read_element(&handle,position);
Eterm newcnt = db_add_counter(&htop, oldcnt, incr);
if (newcnt == NIL) {
@@ -980,9 +999,9 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
if (arityval(*tpl) == 4) { /* Maybe warp it */
Eterm threshold = tpl[3];
- if ((cmp(incr,make_small(0)) < 0) ? /* negative increment? */
- (cmp(newcnt,threshold) < 0) : /* if negative, check if below */
- (cmp(newcnt,threshold) > 0)) { /* else check if above threshold */
+ if ((CMP(incr,make_small(0)) < 0) ? /* negative increment? */
+ (CMP(newcnt,threshold) < 0) : /* if negative, check if below */
+ (CMP(newcnt,threshold) > 0)) { /* else check if above threshold */
newcnt = tpl[4];
}
@@ -1276,7 +1295,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
UWord heir_data;
Uint32 status;
Sint keypos;
- int is_named, is_fine_locked, frequent_read;
+ int is_named, is_fine_locked, frequent_read, is_compressed;
int cret;
DeclareTmpHeap(meta_tuple,3,BIF_P);
DbTableMethod* meth;
@@ -1296,6 +1315,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
frequent_read = 0;
heir = am_none;
heir_data = (UWord) am_undefined;
+ is_compressed = erts_ets_always_compress;
list = BIF_ARG_2;
while(is_list(list)) {
@@ -1358,6 +1378,9 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
else if (val == am_named_table) {
is_named = 1;
}
+ else if (val == am_compressed) {
+ is_compressed = 1;
+ }
else if (val == am_set || val == am_protected)
;
else break;
@@ -1409,6 +1432,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
tb->common.type = status & ERTS_ETS_TABLE_TYPES;
/* Note, 'type' is *read only* from now on... */
#endif
+ erts_refc_init(&tb->common.ref, 0);
db_init_lock(tb, status & (DB_FINE_LOCKED|DB_FREQ_READ),
"db_tab", "db_tab_fix");
tb->common.keypos = keypos;
@@ -1418,6 +1442,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
erts_smp_atomic_init(&tb->common.nitems, 0);
tb->common.fixations = NULL;
+ tb->common.compress = is_compressed;
cret = meth->db_create(BIF_P, tb);
ASSERT(cret == DB_ERROR_NONE);
@@ -1430,8 +1455,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
"** Too many db tables **\n");
free_heir_data(tb);
tb->common.meth->db_free_table(tb);
- erts_db_free(ERTS_ALC_T_DB_TABLE, tb, (void *) tb, sizeof(DbTable));
- ERTS_ETS_MISC_MEM_ADD(-sizeof(DbTable));
+ free_dbtable(tb);
BIF_ERROR(BIF_P, SYSTEM_LIMIT);
}
@@ -1465,9 +1489,10 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
free_slot(slot);
erts_smp_rwmtx_rwunlock(mmtl);
- db_lock_take_over_ref(tb,LCK_WRITE);
+ db_lock(tb,LCK_WRITE);
free_heir_data(tb);
tb->common.meth->db_free_table(tb);
+ schedule_free_dbtable(tb);
db_unlock(tb,LCK_WRITE);
BIF_ERROR(BIF_P, BADARG);
}
@@ -2572,7 +2597,7 @@ BIF_RETTYPE ets_match_object_3(BIF_ALIST_3)
BIF_RETTYPE ets_info_1(BIF_ALIST_1)
{
static Eterm fields[] = {am_protection, am_keypos, am_type, am_named_table,
- am_node, am_size, am_name, am_heir, am_owner, am_memory};
+ am_node, am_size, am_name, am_heir, am_owner, am_memory, am_compressed};
Eterm results[sizeof(fields)/sizeof(Eterm)];
DbTable* tb;
Eterm res;
@@ -2688,7 +2713,6 @@ BIF_RETTYPE ets_match_spec_run_r_3(BIF_ALIST_3)
Binary *mp;
Eterm res;
Uint32 dummy;
- Uint sz;
if (!(is_list(BIF_ARG_1) || BIF_ARG_1 == NIL) || !is_binary(BIF_ARG_2)) {
error:
@@ -2713,11 +2737,10 @@ BIF_RETTYPE ets_match_spec_run_r_3(BIF_ALIST_3)
BIF_TRAP3(bif_export[BIF_ets_match_spec_run_r_3],
BIF_P,lst,BIF_ARG_2,ret);
}
- res = db_prog_match(BIF_P, mp, CAR(list_val(lst)), NULL, 0, &dummy);
+ res = db_prog_match(BIF_P, mp, CAR(list_val(lst)), NULL, NULL, 0,
+ ERTS_PAM_COPY_RESULT, &dummy);
if (is_value(res)) {
- sz = size_object(res);
- hp = HAlloc(BIF_P, sz + 2);
- res = copy_struct(res, sz, &hp, &MSO(BIF_P));
+ hp = HAlloc(BIF_P, 2);
ret = CONS(hp,res,ret);
/*hp += 2;*/
}
@@ -2754,13 +2777,13 @@ void init_db(void)
(sizeof(erts_meta_main_tab_lock_t)
* (ERTS_META_MAIN_TAB_LOCK_TAB_SIZE+1)));
- if ((((Uint) meta_main_tab_locks) & ERTS_CACHE_LINE_MASK) != 0)
+ if ((((UWord) meta_main_tab_locks) & ERTS_CACHE_LINE_MASK) != 0)
meta_main_tab_locks = ((erts_meta_main_tab_lock_t *)
- ((((Uint) meta_main_tab_locks)
+ ((((UWord) meta_main_tab_locks)
& ~ERTS_CACHE_LINE_MASK)
+ ERTS_CACHE_LINE_SIZE));
- ASSERT((((Uint) meta_main_tab_locks) & ERTS_CACHE_LINE_MASK) == 0);
+ ASSERT((((UWord) meta_main_tab_locks) & ERTS_CACHE_LINE_MASK) == 0);
for (i = 0; i < ERTS_META_MAIN_TAB_LOCK_TAB_SIZE; i++) {
erts_smp_rwmtx_init_opt_x(&meta_main_tab_locks[i].rwmtx, &rwmtx_opt,
@@ -2837,9 +2860,9 @@ void init_db(void)
erts_smp_atomic_init(&meta_pid_to_tab->common.nitems, 0);
meta_pid_to_tab->common.slot = -1;
meta_pid_to_tab->common.meth = &db_hash;
+ meta_pid_to_tab->common.compress = 0;
- erts_refc_init(&meta_pid_to_tab->common.ref, 1);
- erts_refc_init(&meta_pid_to_tab->common.fixref, 0);
+ erts_refc_init(&meta_pid_to_tab->common.ref, 0);
/* Neither rwlock or fixlock used
db_init_lock(meta_pid_to_tab, "meta_pid_to_tab", "meta_pid_to_tab_FIX");*/
@@ -2869,9 +2892,9 @@ void init_db(void)
erts_smp_atomic_init(&meta_pid_to_fixed_tab->common.nitems, 0);
meta_pid_to_fixed_tab->common.slot = -1;
meta_pid_to_fixed_tab->common.meth = &db_hash;
+ meta_pid_to_fixed_tab->common.compress = 0;
- erts_refc_init(&meta_pid_to_fixed_tab->common.ref, 1);
- erts_refc_init(&meta_pid_to_fixed_tab->common.fixref, 0);
+ erts_refc_init(&meta_pid_to_fixed_tab->common.ref, 0);
/* Neither rwlock or fixlock used
db_init_lock(meta_pid_to_fixed_tab, "meta_pid_to_fixed_tab", "meta_pid_to_fixed_tab_FIX");*/
@@ -3029,12 +3052,10 @@ retry:
to_pid, to_locks,
ERTS_P2P_FLG_TRY_LOCK);
if (to_proc == ERTS_PROC_LOCK_BUSY) {
- db_ref(tb, LCK_NONE); /* while unlocked */
db_unlock(tb,LCK_WRITE);
to_proc = erts_pid2proc(p, ERTS_PROC_LOCK_MAIN,
to_pid, to_locks);
db_lock(tb,LCK_WRITE);
- tb = db_unref(tb, LCK_NONE);
ASSERT(tb != NULL);
if (tb->common.owner != p->id) {
@@ -3077,7 +3098,7 @@ retry:
db_unlock(tb,LCK_WRITE);
heir_data = tb->common.heir_data;
if (!is_immed(heir_data)) {
- Eterm* tpv = DBTERM_BUF((DbTerm*)heir_data); /* tuple_val */
+ Eterm* tpv = ((DbTerm*)heir_data)->tpl; /* tuple_val */
ASSERT(arityval(*tpv) == 1);
heir_data = tpv[1];
}
@@ -3145,13 +3166,13 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks)
erts_smp_rwmtx_t *mmtl = get_meta_main_tab_lock(ix);
erts_smp_rwmtx_rlock(mmtl);
if (!IS_SLOT_FREE(ix)) {
- tb = db_ref(GET_ANY_SLOT_TAB(ix), LCK_WRITE);
+ tb = GET_ANY_SLOT_TAB(ix);
ASSERT(tb);
}
erts_smp_rwmtx_runlock(mmtl);
if (tb) {
int do_yield;
- db_lock_take_over_ref(tb, LCK_WRITE);
+ db_lock(tb, LCK_WRITE);
/* Ownership may have changed since
we looked up the table. */
if (tb->common.owner != pid) {
@@ -3233,7 +3254,7 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks)
erts_smp_rwmtx_t *mmtl = get_meta_main_tab_lock(ix);
erts_smp_rwmtx_rlock(mmtl);
if (IS_SLOT_ALIVE(ix)) {
- tb = db_ref(meta_main_tab[ix].u.tb, LCK_WRITE_REC);
+ tb = meta_main_tab[ix].u.tb;
ASSERT(tb);
}
erts_smp_rwmtx_runlock(mmtl);
@@ -3241,7 +3262,7 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks)
int reds;
DbFixation** pp;
- db_lock_take_over_ref(tb, LCK_WRITE_REC);
+ db_lock(tb, LCK_WRITE_REC);
#ifdef ERTS_SMP
erts_smp_mtx_lock(&tb->common.fixlock);
#endif
@@ -3251,7 +3272,8 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks)
pp = &(*pp)->next) {
if ((*pp)->pid == pid) {
DbFixation* fix = *pp;
- erts_refc_add(&tb->common.fixref,-fix->counter,0);
+ erts_aint_t diff = -((erts_aint_t) fix->counter);
+ erts_refc_add(&tb->common.ref,diff,0);
*pp = fix->next;
erts_db_free(ERTS_ALC_T_DB_FIXATION,
tb, fix, sizeof(DbFixation));
@@ -3326,7 +3348,7 @@ static void fix_table_locked(Process* p, DbTable* tb)
#ifdef ERTS_SMP
erts_smp_mtx_lock(&tb->common.fixlock);
#endif
- erts_refc_inc(&tb->common.fixref,1);
+ erts_refc_inc(&tb->common.ref,1);
fix = tb->common.fixations;
if (fix == NULL) {
get_now(&(tb->common.megasec),
@@ -3380,7 +3402,7 @@ static void unfix_table_locked(Process* p, DbTable* tb,
for (pp = &tb->common.fixations; *pp != NULL; pp = &(*pp)->next) {
if ((*pp)->pid == p->id) {
DbFixation* fix = *pp;
- erts_refc_dec(&tb->common.fixref,0);
+ erts_refc_dec(&tb->common.ref,0);
--(fix->counter);
ASSERT(fix->counter >= 0);
if (fix->counter > 0) {
@@ -3406,11 +3428,10 @@ static void unfix_table_locked(Process* p, DbTable* tb,
unlocked:
if (!IS_FIXED(tb) && IS_HASH_TABLE(tb->common.status)
- && erts_smp_atomic_read(&tb->hash.fixdel) != (long)NULL) {
+ && erts_smp_atomic_read(&tb->hash.fixdel) != (erts_aint_t)NULL) {
#ifdef ERTS_SMP
if (*kind_p == LCK_READ && tb->common.is_thread_safe) {
/* Must have write lock while purging pseudo-deleted (OTP-8166) */
- db_ref(tb, LCK_WRITE); /* LCK_WRITE need it, but not LCK_READ */
erts_smp_rwmtx_runlock(&tb->common.rwlock);
erts_smp_rwmtx_rwlock(&tb->common.rwlock);
*kind_p = LCK_WRITE;
@@ -3429,6 +3450,8 @@ static void free_fixations_locked(DbTable *tb)
fix = tb->common.fixations;
while (fix != NULL) {
+ erts_aint_t diff = -((erts_aint_t) fix->counter);
+ erts_refc_add(&tb->common.ref,diff,0);
next_fix = fix->next;
db_meta_lock(meta_pid_to_fixed_tab, LCK_WRITE_REC);
db_erase_bag_exact2(meta_pid_to_fixed_tab,
@@ -3466,11 +3489,24 @@ static void set_heir(Process* me, DbTable* tb, Eterm heir, UWord heir_data)
if (!is_immed(heir_data)) {
DeclareTmpHeap(tmp,2,me);
+ Eterm wrap_tpl;
+ int size;
+ DbTerm* dbterm;
+ Eterm* top;
+ ErlOffHeap tmp_offheap;
UseTmpHeap(2,me);
- /* Make a dummy 1-tuple around data to use db_get_term() */
- heir_data = (UWord) db_get_term(&tb->common, NULL, 0,
- TUPLE1(tmp,heir_data));
+ /* Make a dummy 1-tuple around data to use DbTerm */
+ wrap_tpl = TUPLE1(tmp,heir_data);
+ size = size_object(wrap_tpl);
+ dbterm = erts_db_alloc(ERTS_ALC_T_DB_HEIR_DATA, (DbTable *)tb,
+ (sizeof(DbTerm) + sizeof(Eterm)*(size-1)));
+ dbterm->size = size;
+ top = dbterm->tpl;
+ tmp_offheap.first = NULL;
+ copy_struct(wrap_tpl, size, &top, &tmp_offheap);
+ dbterm->first_oh = tmp_offheap.first;
+ heir_data = (UWord)dbterm;
UnUseTmpHeap(2,me);
ASSERT(!is_immed(heir_data));
}
@@ -3481,8 +3517,8 @@ static void free_heir_data(DbTable* tb)
{
if (tb->common.heir != am_none && !is_immed(tb->common.heir_data)) {
DbTerm* p = (DbTerm*) tb->common.heir_data;
- db_free_term_data(p);
- erts_db_free(ERTS_ALC_T_DB_TERM, tb, (void *)p,
+ db_cleanup_offheap_comp(p);
+ erts_db_free(ERTS_ALC_T_DB_HEIR_DATA, tb, (void *)p,
sizeof(DbTerm) + (p->size-1)*sizeof(Eterm));
}
#ifdef DEBUG
@@ -3552,10 +3588,6 @@ static int free_table_cont(Process *p,
mmtl = get_meta_main_tab_lock(tb->common.slot);
#ifdef ERTS_SMP
if (erts_smp_rwmtx_tryrwlock(mmtl) == EBUSY) {
- /*
- * We keep our increased refc over this op in order to
- * prevent the table from disapearing.
- */
erts_smp_rwmtx_rwunlock(&tb->common.rwlock);
erts_smp_rwmtx_rwlock(mmtl);
erts_smp_rwmtx_rwlock(&tb->common.rwlock);
@@ -3570,7 +3602,7 @@ static int free_table_cont(Process *p,
make_small(tb->common.slot));
db_meta_unlock(meta_pid_to_tab, LCK_WRITE_REC);
}
- db_unref(tb, LCK_NONE);
+ schedule_free_dbtable(tb);
BUMP_REDS(p, 100);
return 0;
}
@@ -3618,10 +3650,13 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What)
ret = erts_this_dist_entry->sysname;
} else if (What == am_named_table) {
ret = is_atom(tb->common.id) ? am_true : am_false;
+ } else if (What == am_compressed) {
+ ret = tb->common.compress ? am_true : am_false;
+ }
/*
* For debugging purposes
*/
- } else if (What == am_data) {
+ else if (What == am_data) {
print_table(ERTS_PRINT_STDOUT, NULL, 1, tb);
ret = am_true;
} else if (What == am_atom_put("fixed",5)) {
diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h
index 7da28fad29..e0bdebcb01 100644
--- a/erts/emulator/beam/erl_db.h
+++ b/erts/emulator/beam/erl_db.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -61,6 +61,7 @@ void erts_db_foreach_offheap(DbTable *,
extern int user_requested_db_max_tabs; /* set in erl_init */
extern int erts_ets_realloc_always_moves; /* set in erl_init */
+extern int erts_ets_always_compress; /* set in erl_init */
extern Export ets_select_delete_continue_exp;
extern Export ets_select_count_continue_exp;
extern Export ets_select_continue_exp;
@@ -82,7 +83,8 @@ Eterm erts_ets_colliding_names(Process*, Eterm name, Uint cnt);
#define ERTS_DB_ALC_MEM_UPDATE_(TAB, FREE_SZ, ALLOC_SZ) \
do { \
- long sz__ = ((long) (ALLOC_SZ)) - ((long) (FREE_SZ)); \
+ erts_aint_t sz__ = (((erts_aint_t) (ALLOC_SZ)) \
+ - ((erts_aint_t) (FREE_SZ))); \
ASSERT((TAB)); \
erts_smp_atomic_add(&(TAB)->common.memory_size, sz__); \
} while (0)
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index fa707f4eed..9ef990cc4f 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -135,8 +135,8 @@ static ERTS_INLINE Uint hash_to_ix(DbTableHash* tb, HashValue hval)
*/
static ERTS_INLINE void add_fixed_deletion(DbTableHash* tb, int ix)
{
- long was_next;
- long exp_next;
+ erts_aint_t was_next;
+ erts_aint_t exp_next;
FixedDeletion* fixd = (FixedDeletion*) erts_db_alloc(ERTS_ALC_T_DB_FIX_DEL,
(DbTable *) tb,
sizeof(FixedDeletion));
@@ -146,7 +146,9 @@ static ERTS_INLINE void add_fixed_deletion(DbTableHash* tb, int ix)
do { /* Lockless atomic insertion in linked list: */
exp_next = was_next;
fixd->next = (FixedDeletion*) exp_next;
- was_next = erts_smp_atomic_cmpxchg(&tb->fixdel, (long)fixd, exp_next);
+ was_next = erts_smp_atomic_cmpxchg(&tb->fixdel,
+ (erts_aint_t) fixd,
+ exp_next);
}while (was_next != exp_next);
}
@@ -256,22 +258,16 @@ static ERTS_INLINE Sint next_slot_w(DbTableHash* tb, Uint ix,
}
-/*
- * tplp is an untagged pointer to a tuple we know is large enough
- * and dth is a pointer to a DbTableHash.
- */
-#define GETKEY(dth, tplp) (*((tplp) + (dth)->common.keypos))
-
/*
* Some special binary flags
*/
#define BIN_FLAG_ALL_OBJECTS BIN_FLAG_USR1
-/*
- * Size calculations
- */
-#define SIZ_OVERHEAD ((sizeof(HashDbTerm)/sizeof(Eterm)) - 1)
-#define SIZ_DBTERM(HDT) (SIZ_OVERHEAD + (HDT)->dbterm.size)
+
+static ERTS_INLINE void free_term(DbTableHash *tb, HashDbTerm* p)
+{
+ db_free_term((DbTable*)tb, p, offsetof(HashDbTerm, dbterm));
+}
/*
* Local types
@@ -358,10 +354,8 @@ static HashDbTerm* search_list(DbTableHash* tb, Eterm key,
HashValue hval, HashDbTerm *list);
static void shrink(DbTableHash* tb, int nactive);
static void grow(DbTableHash* tb, int nactive);
-static void free_term(DbTableHash *tb, HashDbTerm* p);
-static Eterm put_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2);
-static HashDbTerm* get_term(DbTableHash* tb, HashDbTerm* old,
- Eterm obj, HashValue hval);
+static Eterm build_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2,
+ DbTableHash*);
static int analyze_pattern(DbTableHash *tb, Eterm pattern,
struct mp_info *mpi);
@@ -434,6 +428,9 @@ static ERTS_INLINE void try_shrink(DbTableHash* tb)
}
}
+#define EQ_REL(x,y,y_base) \
+ (is_same(x,NULL,y,y_base) || (is_not_both_immed((x),(y)) && eq_rel((x),NULL,(y),y_base)))
+
/* Is this a live object (not pseodo-deleted) with the specified key?
*/
static ERTS_INLINE int has_live_key(DbTableHash* tb, HashDbTerm* b,
@@ -442,7 +439,8 @@ static ERTS_INLINE int has_live_key(DbTableHash* tb, HashDbTerm* b,
if (b->hvalue != hval) return 0;
else {
Eterm itemKey = GETKEY(tb, b->dbterm.tpl);
- return EQ(key,itemKey);
+ ASSERT(!is_header(itemKey));
+ return EQ_REL(key, itemKey, b->dbterm.tpl);
}
}
@@ -454,10 +452,38 @@ static ERTS_INLINE int has_key(DbTableHash* tb, HashDbTerm* b,
if (b->hvalue != hval && b->hvalue != INVALID_HASH) return 0;
else {
Eterm itemKey = GETKEY(tb, b->dbterm.tpl);
- return EQ(key,itemKey);
+ ASSERT(!is_header(itemKey));
+ return EQ_REL(key, itemKey, b->dbterm.tpl);
}
}
+static ERTS_INLINE HashDbTerm* new_dbterm(DbTableHash* tb, Eterm obj)
+{
+ HashDbTerm* p;
+ if (tb->common.compress) {
+ p = db_store_term_comp(&tb->common, NULL, offsetof(HashDbTerm,dbterm), obj);
+ }
+ else {
+ p = db_store_term(&tb->common, NULL, offsetof(HashDbTerm,dbterm), obj);
+ }
+ return p;
+}
+
+static ERTS_INLINE HashDbTerm* replace_dbterm(DbTableHash* tb, HashDbTerm* old,
+ Eterm obj)
+{
+ HashDbTerm* ret;
+ ASSERT(old != NULL);
+ if (tb->common.compress) {
+ ret = db_store_term_comp(&tb->common, &(old->dbterm), offsetof(HashDbTerm,dbterm), obj);
+ }
+ else {
+ ret = db_store_term(&tb->common, &(old->dbterm), offsetof(HashDbTerm,dbterm), obj);
+ }
+ return ret;
+}
+
+
/*
** External interface
@@ -514,12 +540,12 @@ static void restore_fixdel(DbTableHash* tb, FixedDeletion* fixdel)
{
/*int tries = 0;*/
DEBUG_WAIT();
- if (erts_smp_atomic_cmpxchg(&tb->fixdel, (long)fixdel,
- (long)NULL) != (long)NULL) {
+ if (erts_smp_atomic_cmpxchg(&tb->fixdel, (erts_aint_t)fixdel,
+ (erts_aint_t)NULL) != (erts_aint_t)NULL) {
/* Oboy, must join lists */
FixedDeletion* last = fixdel;
- long was_tail;
- long exp_tail;
+ erts_aint_t was_tail;
+ erts_aint_t exp_tail;
while (last->next != NULL) last = last->next;
was_tail = erts_smp_atomic_read(&tb->fixdel);
@@ -528,7 +554,7 @@ static void restore_fixdel(DbTableHash* tb, FixedDeletion* fixdel)
last->next = (FixedDeletion*) exp_tail;
/*++tries;*/
DEBUG_WAIT();
- was_tail = erts_smp_atomic_cmpxchg(&tb->fixdel, (long)fixdel,
+ was_tail = erts_smp_atomic_cmpxchg(&tb->fixdel, (erts_aint_t)fixdel,
exp_tail);
}while (was_tail != exp_tail);
}
@@ -546,7 +572,7 @@ void db_unfix_table_hash(DbTableHash *tb)
|| (erts_smp_lc_rwmtx_is_rlocked(&tb->common.rwlock)
&& !tb->common.is_thread_safe));
restart:
- fixdel = (FixedDeletion*) erts_smp_atomic_xchg(&tb->fixdel, (long)NULL);
+ fixdel = (FixedDeletion*) erts_smp_atomic_xchg(&tb->fixdel, (erts_aint_t)NULL);
while (fixdel != NULL) {
FixedDeletion *fx = fixdel;
int ix = fx->slot;
@@ -615,8 +641,8 @@ int db_create_hash(Process *p, DbTable *tbl)
erts_smp_atomic_init(&tb->szm, SEGSZ_MASK);
erts_smp_atomic_init(&tb->nactive, SEGSZ);
- erts_smp_atomic_init(&tb->fixdel, (long)NULL);
- erts_smp_atomic_init(&tb->segtab, (long) alloc_ext_seg(tb,0,NULL)->segtab);
+ erts_smp_atomic_init(&tb->fixdel, (erts_aint_t)NULL);
+ erts_smp_atomic_init(&tb->segtab, (erts_aint_t) alloc_ext_seg(tb,0,NULL)->segtab);
tb->nsegs = NSEG_1;
tb->nslots = SEGSZ;
@@ -667,9 +693,7 @@ static int db_first_hash(Process *p, DbTable *tbl, Eterm *ret)
}
}
if (list != NULL) {
- Eterm key = GETKEY(tb, list->dbterm.tpl);
-
- COPY_OBJECT(key, p, ret);
+ *ret = db_copy_key(p, tbl, &list->dbterm);
RUNLOCK_HASH(lck);
}
else {
@@ -717,7 +741,7 @@ static int db_next_hash(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
*ret = am_EOT;
}
else {
- COPY_OBJECT(GETKEY(tb, b->dbterm.tpl), p, ret);
+ *ret = db_copy_key(p, tbl, &b->dbterm);
RUNLOCK_HASH(lck);
}
return DB_ERROR_NONE;
@@ -764,7 +788,7 @@ int db_put_hash(DbTable *tbl, Eterm obj, int key_clash_fail)
ret = DB_ERROR_BADKEY;
goto Ldone;
}
- q = get_term(tb, b, obj, hval);
+ q = replace_dbterm(tb, b, obj);
q->next = bnext;
q->hvalue = hval; /* In case of INVALID_HASH */
*bp = q;
@@ -784,7 +808,7 @@ int db_put_hash(DbTable *tbl, Eterm obj, int key_clash_fail)
HashDbTerm** qp = bp;
q = b;
do {
- if (eq(make_tuple(q->dbterm.tpl), obj)) {
+ if (db_eq(&tb->common,obj,&q->dbterm)) {
if (q->hvalue == INVALID_HASH) {
erts_smp_atomic_inc(&tb->common.nitems);
q->hvalue = hval;
@@ -803,7 +827,8 @@ int db_put_hash(DbTable *tbl, Eterm obj, int key_clash_fail)
/*else DB_DUPLICATE_BAG */
Lnew:
- q = get_term(tb, NULL, obj, hval);
+ q = new_dbterm(tb, obj);
+ q->hvalue = hval;
q->next = b;
*bp = q;
nitems = erts_smp_atomic_inctest(&tb->common.nitems);
@@ -844,7 +869,7 @@ int db_get_hash(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
while(b2 != NULL && has_key(tb,b2,key,hval))
b2 = b2->next;
}
- copy = put_term_list(p, b1, b2);
+ copy = build_term_list(p, b1, b2, tb);
CHECK_TABLES();
*ret = copy;
goto done;
@@ -967,13 +992,10 @@ static int db_get_element_hash(Process *p, DbTable *tbl,
while(b1 != 0) {
if (has_live_key(tb,b1,key,hval)) {
- Eterm copy;
-
if (ndex > arityval(b1->dbterm.tpl[0])) {
retval = DB_ERROR_BADITEM;
goto done;
}
-
if (tb->common.status & (DB_BAG | DB_DUPLICATE_BAG)) {
HashDbTerm* b;
HashDbTerm* b2 = b1->next;
@@ -987,15 +1009,12 @@ static int db_get_element_hash(Process *p, DbTable *tbl,
}
b2 = b2->next;
}
-
b = b1;
while(b != b2) {
if (b->hvalue != INVALID_HASH) {
Eterm *hp;
- Uint sz = size_object(b->dbterm.tpl[ndex])+2;
-
- hp = HAlloc(p, sz);
- copy = copy_struct(b->dbterm.tpl[ndex], sz-2, &hp, &MSO(p));
+ Eterm copy = db_copy_element_from_ets(&tb->common, p,
+ &b->dbterm, ndex, &hp, 2);
elem_list = CONS(hp, copy, elem_list);
hp += 2;
}
@@ -1004,8 +1023,8 @@ static int db_get_element_hash(Process *p, DbTable *tbl,
*ret = elem_list;
}
else {
- COPY_OBJECT(b1->dbterm.tpl[ndex], p, &copy);
- *ret = copy;
+ Eterm* hp;
+ *ret = db_copy_element_from_ets(&tb->common, p, &b1->dbterm, ndex, &hp, 0);
}
retval = DB_ERROR_NONE;
goto done;
@@ -1040,6 +1059,7 @@ int db_erase_bag_exact2(DbTable *tbl, Eterm key, Eterm value)
ASSERT(!IS_FIXED(tb));
ASSERT((tb->common.status & DB_BAG));
+ ASSERT(!tb->common.compress);
while(b != 0) {
if (has_live_key(tb,b,key,hval)) {
@@ -1139,7 +1159,7 @@ static int db_erase_object_hash(DbTable *tbl, Eterm object, Eterm *ret)
while(b != 0) {
if (has_live_key(tb,b,key,hval)) {
++nkeys;
- if (eq(object, make_tuple(b->dbterm.tpl))) {
+ if (db_eq(&tb->common,object, &b->dbterm)) {
--nitems_diff;
if (nkeys==1 && IS_FIXED(tb)) { /* Pseudo remove */
add_fixed_deletion(tb,ix);
@@ -1188,7 +1208,7 @@ static int db_slot_hash(Process *p, DbTable *tbl, Eterm slot_term, Eterm *ret)
lck = RLOCK_HASH(tb, slot);
nactive = NACTIVE(tb);
if (slot < nactive) {
- *ret = put_term_list(p, BUCKET(tb, slot), 0);
+ *ret = build_term_list(p, BUCKET(tb, slot), 0, tb);
retval = DB_ERROR_NONE;
}
else if (slot == nactive) {
@@ -1232,8 +1252,6 @@ static int db_select_continue_hash(Process *p,
int num_left = 1000;
HashDbTerm *current = 0;
Eterm match_list;
- Uint32 dummy;
- unsigned sz;
Eterm *hp;
Eterm match_res;
Sint got;
@@ -1285,26 +1303,14 @@ static int db_select_continue_hash(Process *p,
}
for(;;) {
if (current->hvalue != INVALID_HASH &&
- (match_res =
- db_prog_match(p,mp,
- make_tuple(current->dbterm.tpl),
- NULL,0,&dummy),
+ (match_res = db_match_dbterm(&tb->common, p, mp, all_objects,
+ &current->dbterm, &hp, 2),
is_value(match_res))) {
- if (all_objects) {
- hp = HAlloc(p, current->dbterm.size + 2);
- match_res = copy_shallow(DBTERM_BUF(&current->dbterm),
- current->dbterm.size,
- &hp,
- &MSO(p));
- } else {
- sz = size_object(match_res);
-
- hp = HAlloc(p, sz + 2);
- match_res = copy_struct(match_res, sz, &hp, &MSO(p));
- }
- match_list = CONS(hp, match_res, match_list);
+
+ match_list = CONS(hp, match_res, match_list);
++got;
}
+
--num_left;
save_slot_ix = slot_ix;
if ((current = next(tb, (Uint*)&slot_ix, &lck, current)) == NULL) {
@@ -1395,9 +1401,7 @@ static int db_select_chunk_hash(Process *p, DbTable *tbl,
HashDbTerm *current = 0;
unsigned current_list_pos = 0;
Eterm match_list;
- Uint32 dummy;
Eterm match_res;
- unsigned sz;
Eterm *hp;
int num_left = 1000;
Uint got = 0;
@@ -1464,22 +1468,9 @@ static int db_select_chunk_hash(Process *p, DbTable *tbl,
for(;;) {
if (current != NULL) {
if (current->hvalue != INVALID_HASH) {
- match_res = db_prog_match(p,mpi.mp,
- make_tuple(current->dbterm.tpl),
- NULL,0,&dummy);
+ match_res = db_match_dbterm(&tb->common, p, mpi.mp, 0,
+ &current->dbterm, &hp, 2);
if (is_value(match_res)) {
- if (mpi.all_objects) {
- hp = HAlloc(p, current->dbterm.size + 2);
- match_res = copy_shallow(DBTERM_BUF(&current->dbterm),
- current->dbterm.size,
- &hp,
- &MSO(p));
- } else {
- sz = size_object(match_res);
-
- hp = HAlloc(p, sz + 2);
- match_res = copy_struct(match_res, sz, &hp, &MSO(p));
- }
match_list = CONS(hp, match_res, match_list);
++got;
}
@@ -1594,7 +1585,6 @@ static int db_select_count_hash(Process *p,
Uint slot_ix = 0;
HashDbTerm* current = NULL;
unsigned current_list_pos = 0;
- Uint32 dummy;
Eterm *hp;
int num_left = 1000;
Uint got = 0;
@@ -1644,8 +1634,8 @@ static int db_select_count_hash(Process *p,
for(;;) {
if (current != NULL) {
if (current->hvalue != INVALID_HASH) {
- if (db_prog_match(p, mpi.mp, make_tuple(current->dbterm.tpl),
- NULL,0, &dummy) == am_true) {
+ if (db_match_dbterm(&tb->common, p, mpi.mp, 0,
+ &current->dbterm, NULL,0) == am_true) {
++got;
}
--num_left;
@@ -1713,7 +1703,6 @@ static int db_select_delete_hash(Process *p,
Uint slot_ix = 0;
HashDbTerm **current = NULL;
unsigned current_list_pos = 0;
- Uint32 dummy;
Eterm *hp;
int num_left = 1000;
Uint got = 0;
@@ -1723,9 +1712,9 @@ static int db_select_delete_hash(Process *p,
Eterm mpb;
Eterm egot;
#ifdef ERTS_SMP
- int fixated_by_me = tb->common.is_thread_safe ? 0 : 1; /* ToDo: something nicer */
+ erts_aint_t fixated_by_me = tb->common.is_thread_safe ? 0 : 1; /* ToDo: something nicer */
#else
- int fixated_by_me = 0;
+ erts_aint_t fixated_by_me = 0;
#endif
erts_smp_rwmtx_t* lck;
@@ -1794,9 +1783,8 @@ static int db_select_delete_hash(Process *p,
}
else {
int did_erase = 0;
- if ((db_prog_match(p,mpi.mp,
- make_tuple((*current)->dbterm.tpl),
- NULL,0,&dummy)) == am_true) {
+ if (db_match_dbterm(&tb->common, p, mpi.mp, 0,
+ &(*current)->dbterm, NULL, 0) == am_true) {
if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */
if (slot_ix != last_pseudo_delete) {
add_fixed_deletion(tb, slot_ix);
@@ -1859,7 +1847,6 @@ static int db_select_delete_continue_hash(Process *p,
Uint slot_ix;
Uint last_pseudo_delete = (Uint)-1;
HashDbTerm **current = NULL;
- Uint32 dummy;
Eterm *hp;
int num_left = 1000;
Uint got;
@@ -1907,8 +1894,8 @@ static int db_select_delete_continue_hash(Process *p,
}
else {
int did_erase = 0;
- if ((db_prog_match(p,mp,make_tuple((*current)->dbterm.tpl),
- NULL,0,&dummy)) == am_true) {
+ if (db_match_dbterm(&tb->common, p, mp, 0,
+ &(*current)->dbterm, NULL, 0) == am_true) {
if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */
if (slot_ix != last_pseudo_delete) {
add_fixed_deletion(tb, slot_ix);
@@ -1970,7 +1957,6 @@ static int db_select_count_continue_hash(Process *p,
DbTableHash *tb = &tbl->hash;
Uint slot_ix;
HashDbTerm* current;
- Uint32 dummy;
Eterm *hp;
int num_left = 1000;
Uint got;
@@ -2008,8 +1994,8 @@ static int db_select_count_continue_hash(Process *p,
current = current->next;
continue;
}
- if (db_prog_match(p, mp, make_tuple(current->dbterm.tpl),
- NULL,0,&dummy) == am_true) {
+ if (db_match_dbterm(&tb->common, p, mp, 0, &current->dbterm,
+ NULL, 0) == am_true) {
++got;
}
--num_left;
@@ -2135,11 +2121,11 @@ static int db_free_table_continue_hash(DbTable *tbl)
sizeof(FixedDeletion));
ERTS_ETS_MISC_MEM_ADD(-sizeof(FixedDeletion));
if (++done >= 2*DELETE_RECORD_LIMIT) {
- erts_smp_atomic_set(&tb->fixdel, (long)fixdel);
+ erts_smp_atomic_set(&tb->fixdel, (erts_aint_t)fixdel);
return 0; /* Not done */
}
}
- erts_smp_atomic_set(&tb->fixdel, (long)NULL);
+ erts_smp_atomic_set(&tb->fixdel, (erts_aint_t)NULL);
done /= 2;
while(tb->nslots != 0) {
@@ -2188,7 +2174,7 @@ static int analyze_pattern(DbTableHash *tb, Eterm pattern,
HashValue hval = NIL;
int num_heads = 0;
int i;
-
+
mpi->lists = mpi->dlists;
mpi->num_lists = 0;
mpi->key_given = 1;
@@ -2356,7 +2342,7 @@ static int alloc_seg(DbTableHash *tb)
struct ext_segment* eseg;
eseg = (struct ext_segment*) SEGTAB(tb)[seg_ix-1];
MY_ASSERT(eseg!=NULL && eseg->s.is_ext_segment);
- erts_smp_atomic_set(&tb->segtab, (long) eseg->segtab);
+ erts_smp_atomic_set(&tb->segtab, (erts_aint_t) eseg->segtab);
tb->nsegs = eseg->nsegs;
}
ASSERT(seg_ix < tb->nsegs);
@@ -2428,7 +2414,7 @@ static int free_seg(DbTableHash *tb, int free_records)
MY_ASSERT(newtop->s.is_ext_segment);
if (newtop->prev_segtab != NULL) {
/* Time to use a smaller segtab */
- erts_smp_atomic_set(&tb->segtab, (long)newtop->prev_segtab);
+ erts_smp_atomic_set(&tb->segtab, (erts_aint_t)newtop->prev_segtab);
tb->nsegs = seg_ix;
ASSERT(tb->nsegs == EXTSEG(SEGTAB(tb))->nsegs);
}
@@ -2445,7 +2431,7 @@ static int free_seg(DbTableHash *tb, int free_records)
if (seg_ix > 0) {
if (seg_ix < tb->nsegs) SEGTAB(tb)[seg_ix] = NULL;
} else {
- erts_smp_atomic_set(&tb->segtab, (long)NULL);
+ erts_smp_atomic_set(&tb->segtab, (erts_aint_t)NULL);
}
#endif
tb->nslots -= SEGSZ;
@@ -2454,31 +2440,19 @@ static int free_seg(DbTableHash *tb, int free_records)
}
-static HashDbTerm* get_term(DbTableHash* tb, HashDbTerm* old,
- Eterm obj, HashValue hval)
-{
- HashDbTerm* p = db_get_term((DbTableCommon *) tb,
- (old != NULL) ? &(old->dbterm) : NULL,
- ((char *) &(old->dbterm)) - ((char *) old),
- obj);
- p->hvalue = hval;
- /*p->next = NULL;*/ /*No Need */
- return p;
-}
-
-
/*
** Copy terms from ptr1 until ptr2
** works for ptr1 == ptr2 == 0 => []
** or ptr2 == 0
*/
-static Eterm put_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2)
+static Eterm build_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2,
+ DbTableHash* tb)
{
int sz = 0;
HashDbTerm* ptr;
Eterm list = NIL;
Eterm copy;
- Eterm *hp;
+ Eterm *hp, *hend;
ptr = ptr1;
while(ptr != ptr2) {
@@ -2490,26 +2464,20 @@ static Eterm put_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2)
}
hp = HAlloc(p, sz);
+ hend = hp + sz;
ptr = ptr1;
while(ptr != ptr2) {
if (ptr->hvalue != INVALID_HASH) {
- copy = copy_shallow(DBTERM_BUF(&ptr->dbterm), ptr->dbterm.size, &hp, &MSO(p));
+ copy = db_copy_object_from_ets(&tb->common, &ptr->dbterm, &hp, &MSO(p));
list = CONS(hp, copy, list);
hp += 2;
}
ptr = ptr->next;
}
- return list;
-}
+ HRelease(p,hend,hp);
-static void free_term(DbTableHash *tb, HashDbTerm* p)
-{
- db_free_term_data(&(p->dbterm));
- erts_db_free(ERTS_ALC_T_DB_TERM,
- (DbTable *) tb,
- (void *) p,
- SIZ_DBTERM(p)*sizeof(Eterm));
+ return list;
}
/* Grow table with one new bucket.
@@ -2720,8 +2688,11 @@ static int db_lookup_dbterm_hash(DbTable *tbl, Eterm key, DbUpdateHandle* handle
handle->tb = tbl;
handle->bp = (void**) prevp;
handle->dbterm = &b->dbterm;
- handle->new_size = b->dbterm.size;
handle->mustResize = 0;
+ handle->new_size = b->dbterm.size;
+ #if HALFWORD_HEAP
+ handle->abs_vec = NULL;
+ #endif
handle->lck = lck;
/* KEEP hval WLOCKED, db_finalize_dbterm_hash will WUNLOCK */
return 1;
@@ -2742,37 +2713,14 @@ static void db_finalize_dbterm_hash(DbUpdateHandle* handle)
erts_smp_rwmtx_t* lck = (erts_smp_rwmtx_t*) handle->lck;
ERTS_SMP_LC_ASSERT(IS_HASH_WLOCKED(&tbl->hash,lck)); /* locked by db_lookup_dbterm_hash */
- ASSERT(&oldp->dbterm == handle->dbterm);
- if (handle->mustResize) {
- ErlOffHeap tmp_offheap;
- Eterm* top;
- Eterm copy;
- DbTerm* newDbTerm;
- HashDbTerm* newp = erts_db_alloc(ERTS_ALC_T_DB_TERM, tbl,
- sizeof(HashDbTerm)+sizeof(Eterm)*(handle->new_size-1));
- sys_memcpy(newp, oldp, sizeof(HashDbTerm)-sizeof(DbTerm)); /* copy only hashtab header */
- *(handle->bp) = newp;
- newDbTerm = &newp->dbterm;
-
- newDbTerm->size = handle->new_size;
- tmp_offheap.first = NULL;
- tmp_offheap.overhead = 0;
-
- /* make a flat copy */
- top = DBTERM_BUF(newDbTerm);
- copy = copy_struct(make_tuple(handle->dbterm->tpl),
- handle->new_size,
- &top, &tmp_offheap);
- newDbTerm->first_oh = tmp_offheap.first;
- DBTERM_SET_TPL(newDbTerm,tuple_val(copy));
+ ASSERT((&oldp->dbterm == handle->dbterm) == !(tbl->common.compress && handle->mustResize));
+ if (handle->mustResize) {
+ db_finalize_resize(handle, offsetof(HashDbTerm,dbterm));
WUNLOCK_HASH(lck);
-
- db_free_term_data(handle->dbterm);
- erts_db_free(ERTS_ALC_T_DB_TERM, tbl,
- (void *) (((char *) handle->dbterm) - (sizeof(HashDbTerm) - sizeof(DbTerm))),
- sizeof(HashDbTerm) + sizeof(Eterm)*(handle->dbterm->size-1));
+
+ free_term(&tbl->hash, oldp);
}
else {
WUNLOCK_HASH(lck);
@@ -2781,7 +2729,7 @@ static void db_finalize_dbterm_hash(DbUpdateHandle* handle)
handle->dbterm = 0;
#endif
return;
-}
+}
static int db_delete_all_objects_hash(Process* p, DbTable* tbl)
{
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index 5644e85f97..6cdbec3213 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -48,9 +48,6 @@
#include "erl_db_tree.h"
-
-
-#define GETKEY(dtt, tplp) (*((tplp) + (dtt)->common.keypos))
#define GETKEY_WITH_POS(Keypos, Tplp) (*((Tplp) + Keypos))
#define NITEMS(tb) ((int)erts_smp_atomic_read(&(tb)->common.nitems))
@@ -122,12 +119,41 @@ static void release_stack(DbTableTree* tb, DbTreeStack* stack)
}
}
-static void reset_static_stack(DbTableTree* tb)
+static ERTS_INLINE void reset_static_stack(DbTableTree* tb)
{
tb->static_stack.pos = 0;
tb->static_stack.slot = 0;
}
+static ERTS_INLINE void free_term(DbTableTree *tb, TreeDbTerm* p)
+{
+ db_free_term((DbTable*)tb, p, offsetof(TreeDbTerm, dbterm));
+}
+
+static ERTS_INLINE TreeDbTerm* new_dbterm(DbTableTree *tb, Eterm obj)
+{
+ TreeDbTerm* p;
+ if (tb->common.compress) {
+ p = db_store_term_comp(&tb->common, NULL, offsetof(TreeDbTerm,dbterm), obj);
+ }
+ else {
+ p = db_store_term(&tb->common, NULL, offsetof(TreeDbTerm,dbterm), obj);
+ }
+ return p;
+}
+static ERTS_INLINE TreeDbTerm* replace_dbterm(DbTableTree *tb, TreeDbTerm* old,
+ Eterm obj)
+{
+ TreeDbTerm* p;
+ ASSERT(old != NULL);
+ if (tb->common.compress) {
+ p = db_store_term_comp(&tb->common, &(old->dbterm), offsetof(TreeDbTerm,dbterm), obj);
+ }
+ else {
+ p = db_store_term(&tb->common, &(old->dbterm), offsetof(TreeDbTerm,dbterm), obj);
+ }
+ return p;
+}
/*
** Some macros for "direction stacks"
@@ -178,12 +204,6 @@ static void do_dump_tree2(int to, void *to_arg, int show, TreeDbTerm *t,
#endif
/*
- * Size calculations
- */
-#define SIZ_OVERHEAD ((sizeof(TreeDbTerm)/sizeof(Eterm)) - 1)
-#define SIZ_DBTERM(TDT) (SIZ_OVERHEAD + (TDT)->dbterm.size)
-
-/*
** Datatypes
*/
@@ -259,13 +279,10 @@ struct select_delete_context {
/*
** Forward declarations
*/
-static TreeDbTerm *linkout_tree(DbTableTree *tb, Eterm key);
+static TreeDbTerm *linkout_tree(DbTableTree *tb, Eterm key, Eterm* key_base);
static TreeDbTerm *linkout_object_tree(DbTableTree *tb,
Eterm object);
static int do_free_tree_cont(DbTableTree *tb, int num_left);
-static TreeDbTerm* get_term(DbTableTree *tb,
- TreeDbTerm* old,
- Eterm obj);
static void free_term(DbTableTree *tb, TreeDbTerm* p);
static int balance_left(TreeDbTerm **this);
static int balance_right(TreeDbTerm **this);
@@ -273,15 +290,15 @@ static int delsub(TreeDbTerm **this);
static TreeDbTerm *slot_search(Process *p, DbTableTree *tb, Sint slot);
static TreeDbTerm *find_node(DbTableTree *tb, Eterm key);
static TreeDbTerm **find_node2(DbTableTree *tb, Eterm key);
-static TreeDbTerm *find_next(DbTableTree *tb, DbTreeStack*, Eterm key);
-static TreeDbTerm *find_prev(DbTableTree *tb, DbTreeStack*, Eterm key);
+static TreeDbTerm *find_next(DbTableTree *tb, DbTreeStack*, Eterm key, Eterm* kbase);
+static TreeDbTerm *find_prev(DbTableTree *tb, DbTreeStack*, Eterm key, Eterm* kbase);
static TreeDbTerm *find_next_from_pb_key(DbTableTree *tb, DbTreeStack*,
Eterm key);
static TreeDbTerm *find_prev_from_pb_key(DbTableTree *tb, DbTreeStack*,
Eterm key);
static void traverse_backwards(DbTableTree *tb,
DbTreeStack*,
- Eterm lastkey,
+ Eterm lastkey, Eterm* lk_base,
int (*doit)(DbTableTree *tb,
TreeDbTerm *,
void *,
@@ -289,7 +306,7 @@ static void traverse_backwards(DbTableTree *tb,
void *context);
static void traverse_forward(DbTableTree *tb,
DbTreeStack*,
- Eterm lastkey,
+ Eterm lastkey, Eterm* lk_base,
int (*doit)(DbTableTree *tb,
TreeDbTerm *,
void *,
@@ -297,8 +314,8 @@ static void traverse_forward(DbTableTree *tb,
void *context);
static int key_given(DbTableTree *tb, Eterm pattern, TreeDbTerm **ret,
Eterm *partly_bound_key);
-static Sint cmp_partly_bound(Eterm partly_bound_key, Eterm bound_key);
-static Sint do_cmp_partly_bound(Eterm a, Eterm b, int *done);
+static Sint cmp_partly_bound(Eterm partly_bound_key, Eterm bound_key, Eterm* bk_base);
+static Sint do_cmp_partly_bound(Eterm a, Eterm b, Eterm* b_base, int *done);
static int analyze_pattern(DbTableTree *tb, Eterm pattern,
struct mp_info *mpi);
@@ -318,7 +335,6 @@ static int doit_select_delete(DbTableTree *tb,
TreeDbTerm *this,
void *ptr,
int forward);
-static void do_dump_tree(int to, void *to_arg, TreeDbTerm *t);
static int partly_bound_can_match_lesser(Eterm partly_bound_1,
Eterm partly_bound_2);
@@ -472,9 +488,6 @@ static int db_first_tree(Process *p, DbTable *tbl, Eterm *ret)
DbTableTree *tb = &tbl->tree;
DbTreeStack* stack;
TreeDbTerm *this;
- Eterm e;
- Eterm *hp;
- Uint sz;
if (( this = tb->root ) == NULL) {
*ret = am_EOT;
@@ -493,13 +506,7 @@ static int db_first_tree(Process *p, DbTable *tbl, Eterm *ret)
stack->slot = 1;
release_stack(tb,stack);
}
- e = GETKEY(tb, this->dbterm.tpl);
- sz = size_object(e);
-
- hp = HAlloc(p, sz);
-
- *ret = copy_struct(e,sz,&hp,&MSO(p));
-
+ *ret = db_copy_key(p, tbl, &this->dbterm);
return DB_ERROR_NONE;
}
@@ -508,26 +515,17 @@ static int db_next_tree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
DbTableTree *tb = &tbl->tree;
DbTreeStack* stack;
TreeDbTerm *this;
- Eterm e;
- Eterm *hp;
- Uint sz;
if (is_atom(key) && key == am_EOT)
return DB_ERROR_BADKEY;
stack = get_any_stack(tb);
- this = find_next(tb, stack, key);
+ this = find_next(tb, stack, key, NULL);
release_stack(tb,stack);
if (this == NULL) {
*ret = am_EOT;
return DB_ERROR_NONE;
}
- e = GETKEY(tb, this->dbterm.tpl);
- sz = size_object(e);
-
- hp = HAlloc(p, sz);
-
- *ret = copy_struct(e,sz,&hp,&MSO(p));
-
+ *ret = db_copy_key(p, tbl, &this->dbterm);
return DB_ERROR_NONE;
}
@@ -536,9 +534,6 @@ static int db_last_tree(Process *p, DbTable *tbl, Eterm *ret)
DbTableTree *tb = &tbl->tree;
TreeDbTerm *this;
DbTreeStack* stack;
- Eterm e;
- Eterm *hp;
- Uint sz;
if (( this = tb->root ) == NULL) {
*ret = am_EOT;
@@ -557,13 +552,7 @@ static int db_last_tree(Process *p, DbTable *tbl, Eterm *ret)
stack->slot = NITEMS(tb);
release_stack(tb,stack);
}
- e = GETKEY(tb, this->dbterm.tpl);
- sz = size_object(e);
-
- hp = HAlloc(p, sz);
-
- *ret = copy_struct(e,sz,&hp,&MSO(p));
-
+ *ret = db_copy_key(p, tbl, &this->dbterm);
return DB_ERROR_NONE;
}
@@ -572,27 +561,33 @@ static int db_prev_tree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
DbTableTree *tb = &tbl->tree;
TreeDbTerm *this;
DbTreeStack* stack;
- Eterm e;
- Eterm *hp;
- Uint sz;
if (is_atom(key) && key == am_EOT)
return DB_ERROR_BADKEY;
stack = get_any_stack(tb);
- this = find_prev(tb, stack, key);
+ this = find_prev(tb, stack, key, NULL);
release_stack(tb,stack);
if (this == NULL) {
*ret = am_EOT;
return DB_ERROR_NONE;
}
- e = GETKEY(tb, this->dbterm.tpl);
- sz = size_object(e);
+ *ret = db_copy_key(p, tbl, &this->dbterm);
+ return DB_ERROR_NONE;
+}
- hp = HAlloc(p, sz);
+static ERTS_INLINE int cmp_key(DbTableTree* tb, Eterm key, Eterm* key_base,
+ TreeDbTerm* obj)
+{
+ return cmp_rel(key, key_base,
+ GETKEY(tb,obj->dbterm.tpl), obj->dbterm.tpl);
+}
- *ret = copy_struct(e,sz,&hp,&MSO(p));
-
- return DB_ERROR_NONE;
+static ERTS_INLINE int cmp_key_eq(DbTableTree* tb, Eterm key, Eterm* key_base,
+ TreeDbTerm* obj)
+{
+ Eterm obj_key = GETKEY(tb,obj->dbterm.tpl);
+ return is_same(key, key_base, obj_key, obj->dbterm.tpl)
+ || cmp_rel(key, key_base, obj_key, obj->dbterm.tpl) == 0;
}
static int db_put_tree(DbTable *tbl, Eterm obj, int key_clash_fail)
@@ -622,12 +617,12 @@ static int db_put_tree(DbTable *tbl, Eterm obj, int key_clash_fail)
erts_smp_atomic_dec(&tb->common.nitems);
return DB_ERROR_SYSRES;
}
- *this = get_term(tb, NULL, obj);
+ *this = new_dbterm(tb, obj);
(*this)->balance = 0;
(*this)->left = (*this)->right = NULL;
break;
- } else if ((c = cmp(key,GETKEY(tb,(*this)->dbterm.tpl))) < 0) {
- /* go left */
+ } else if ((c = cmp_key(tb, key, NULL, *this)) < 0) {
+ /* go lefts */
dstack[dpos++] = DIR_LEFT;
tstack[tpos++] = this;
this = &((*this)->left);
@@ -636,7 +631,7 @@ static int db_put_tree(DbTable *tbl, Eterm obj, int key_clash_fail)
tstack[tpos++] = this;
this = &((*this)->right);
} else if (!key_clash_fail) { /* Equal key and this is a set, replace. */
- *this = get_term(tb, *this, obj);
+ *this = replace_dbterm(tb, *this, obj);
break;
} else {
return DB_ERROR_BADKEY; /* key already exists */
@@ -714,7 +709,7 @@ static int db_get_tree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
{
DbTableTree *tb = &tbl->tree;
Eterm copy;
- Eterm *hp;
+ Eterm *hp, *hend;
TreeDbTerm *this;
/*
@@ -728,11 +723,11 @@ static int db_get_tree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
*ret = NIL;
} else {
hp = HAlloc(p, this->dbterm.size + 2);
- copy = copy_shallow(DBTERM_BUF(&this->dbterm),
- this->dbterm.size,
- &hp,
- &MSO(p));
+ hend = hp + this->dbterm.size + 2;
+ copy = db_copy_object_from_ets(&tb->common, &this->dbterm, &hp, &MSO(p));
*ret = CONS(hp, copy, NIL);
+ hp += 2;
+ HRelease(p,hend,hp);
}
return DB_ERROR_NONE;
}
@@ -766,18 +761,10 @@ static int db_get_element_tree(Process *p, DbTable *tbl,
if (this == NULL) {
return DB_ERROR_BADKEY;
} else {
- Eterm element;
- Uint sz;
if (ndex > arityval(this->dbterm.tpl[0])) {
return DB_ERROR_BADPARAM;
}
- element = this->dbterm.tpl[ndex];
- sz = size_object(element);
- hp = HAlloc(p, sz);
- *ret = copy_struct(element,
- sz,
- &hp,
- &MSO(p));
+ *ret = db_copy_element_from_ets(&tb->common, p, &this->dbterm, ndex, &hp, 0);
}
return DB_ERROR_NONE;
}
@@ -789,7 +776,7 @@ static int db_erase_tree(DbTable *tbl, Eterm key, Eterm *ret)
*ret = am_true;
- if ((res = linkout_tree(tb, key)) != NULL) {
+ if ((res = linkout_tree(tb, key, NULL)) != NULL) {
free_term(tb, res);
}
return DB_ERROR_NONE;
@@ -815,7 +802,7 @@ static int db_slot_tree(Process *p, DbTable *tbl,
DbTableTree *tb = &tbl->tree;
Sint slot;
TreeDbTerm *st;
- Eterm *hp;
+ Eterm *hp, *hend;
Eterm copy;
/*
@@ -847,11 +834,11 @@ static int db_slot_tree(Process *p, DbTable *tbl,
return DB_ERROR_UNSPEC;
}
hp = HAlloc(p, st->dbterm.size + 2);
- copy = copy_shallow(DBTERM_BUF(&st->dbterm),
- st->dbterm.size,
- &hp,
- &MSO(p));
+ hend = hp + st->dbterm.size + 2;
+ copy = db_copy_object_from_ets(&tb->common, &st->dbterm, &hp, &MSO(p));
*ret = CONS(hp, copy, NIL);
+ hp += 2;
+ HRelease(p,hend,hp);
return DB_ERROR_NONE;
}
@@ -981,15 +968,15 @@ static int db_select_continue_tree(Process *p,
stack = get_any_stack(tb);
if (chunk_size) {
if (reverse) {
- traverse_backwards(tb, stack, lastkey, &doit_select_chunk, &sc);
+ traverse_backwards(tb, stack, lastkey, NULL, &doit_select_chunk, &sc);
} else {
- traverse_forward(tb, stack, lastkey, &doit_select_chunk, &sc);
+ traverse_forward(tb, stack, lastkey, NULL, &doit_select_chunk, &sc);
}
} else {
if (reverse) {
- traverse_forward(tb, stack, lastkey, &doit_select, &sc);
+ traverse_forward(tb, stack, lastkey, NULL, &doit_select, &sc);
} else {
- traverse_backwards(tb, stack, lastkey, &doit_select, &sc);
+ traverse_backwards(tb, stack, lastkey, NULL, &doit_select, &sc);
}
}
release_stack(tb,stack);
@@ -1014,10 +1001,9 @@ static int db_select_continue_tree(Process *p,
}
key = GETKEY(tb, sc.lastobj);
-
- sz = size_object(key);
+ sz = size_object_rel(key,sc.lastobj);
hp = HAlloc(p, 9 + sz);
- key = copy_struct(key, sz, &hp, &MSO(p));
+ key = copy_struct_rel(key, sz, &hp, &MSO(p), sc.lastobj, NULL);
continuation = TUPLE8
(hp,
tptr[1],
@@ -1038,8 +1024,8 @@ static int db_select_continue_tree(Process *p,
key = GETKEY(tb, sc.lastobj);
if (chunk_size) {
if (end_condition != NIL &&
- ((!reverse && cmp_partly_bound(end_condition,key) < 0) ||
- (reverse && cmp_partly_bound(end_condition,key) > 0))) {
+ ((!reverse && cmp_partly_bound(end_condition,key,sc.lastobj) < 0) ||
+ (reverse && cmp_partly_bound(end_condition,key,sc.lastobj) > 0))) {
/* done anyway */
if (!sc.got) {
RET_TO_BIF(am_EOT, DB_ERROR_NONE);
@@ -1051,16 +1037,16 @@ static int db_select_continue_tree(Process *p,
}
} else {
if (end_condition != NIL &&
- ((!reverse && cmp_partly_bound(end_condition,key) > 0) ||
- (reverse && cmp_partly_bound(end_condition,key) < 0))) {
+ ((!reverse && cmp_partly_bound(end_condition,key,sc.lastobj) > 0) ||
+ (reverse && cmp_partly_bound(end_condition,key,sc.lastobj) < 0))) {
/* done anyway */
RET_TO_BIF(sc.accum,DB_ERROR_NONE);
}
}
/* Not done yet, let's trap. */
- sz = size_object(key);
+ sz = size_object_rel(key,sc.lastobj);
hp = HAlloc(p, 9 + sz);
- key = copy_struct(key, sz, &hp, &MSO(p));
+ key = copy_struct_rel(key, sz, &hp, &MSO(p), sc.lastobj, NULL);
continuation = TUPLE8
(hp,
tptr[1],
@@ -1087,6 +1073,7 @@ static int db_select_tree(Process *p, DbTable *tbl,
struct select_context sc;
struct mp_info mpi;
Eterm lastkey = THE_NON_VALUE;
+ Eterm* lk_base = NULL;
Eterm key;
Eterm continuation;
unsigned sz;
@@ -1128,7 +1115,7 @@ static int db_select_tree(Process *p, DbTable *tbl,
sc.all_objects = mpi.all_objects;
if (!mpi.got_partial && mpi.some_limitation &&
- cmp(mpi.least,mpi.most) == 0) {
+ CMP(mpi.least,mpi.most) == 0) {
doit_select(tb,mpi.save_term,&sc,0 /* direction doesn't matter */);
RET_TO_BIF(sc.accum,DB_ERROR_NONE);
}
@@ -1138,20 +1125,20 @@ static int db_select_tree(Process *p, DbTable *tbl,
if (mpi.some_limitation) {
if ((this = find_prev_from_pb_key(tb, stack, mpi.least)) != NULL) {
lastkey = GETKEY(tb, this->dbterm.tpl);
+ lk_base = this->dbterm.tpl;
}
sc.end_condition = mpi.most;
}
-
- traverse_forward(tb, stack, lastkey, &doit_select, &sc);
+ traverse_forward(tb, stack, lastkey, lk_base, &doit_select, &sc);
} else {
if (mpi.some_limitation) {
if ((this = find_next_from_pb_key(tb, stack, mpi.most)) != NULL) {
lastkey = GETKEY(tb, this->dbterm.tpl);
+ lk_base = this->dbterm.tpl;
}
sc.end_condition = mpi.least;
}
-
- traverse_backwards(tb, stack, lastkey, &doit_select, &sc);
+ traverse_backwards(tb, stack, lastkey, lk_base, &doit_select, &sc);
}
release_stack(tb,stack);
#ifdef HARDDEBUG
@@ -1164,9 +1151,9 @@ static int db_select_tree(Process *p, DbTable *tbl,
}
key = GETKEY(tb, sc.lastobj);
- sz = size_object(key);
+ sz = size_object_rel(key, sc.lastobj);
hp = HAlloc(p, 9 + sz + PROC_BIN_SIZE);
- key = copy_struct(key, sz, &hp, &MSO(p));
+ key = copy_struct_rel(key, sz, &hp, &MSO(p), sc.lastobj, NULL);
if (mpi.all_objects)
(mpi.mp)->flags |= BIN_FLAG_ALL_OBJECTS;
mpb=db_make_mp_binary(p,mpi.mp,&hp);
@@ -1247,7 +1234,7 @@ static int db_select_count_continue_tree(Process *p,
}
stack = get_any_stack(tb);
- traverse_backwards(tb, stack, lastkey, &doit_select_count, &sc);
+ traverse_backwards(tb, stack, lastkey, NULL, &doit_select_count, &sc);
release_stack(tb,stack);
BUMP_REDS(p, 1000 - sc.max);
@@ -1257,12 +1244,12 @@ static int db_select_count_continue_tree(Process *p,
}
key = GETKEY(tb, sc.lastobj);
if (end_condition != NIL &&
- (cmp_partly_bound(end_condition,key) > 0)) {
+ (cmp_partly_bound(end_condition,key,sc.lastobj) > 0)) {
/* done anyway */
RET_TO_BIF(make_small(sc.got),DB_ERROR_NONE);
}
/* Not done yet, let's trap. */
- sz = size_object(key);
+ sz = size_object_rel(key, sc.lastobj);
if (IS_USMALL(0, sc.got)) {
hp = HAlloc(p, sz + 6);
egot = make_small(sc.got);
@@ -1272,7 +1259,7 @@ static int db_select_count_continue_tree(Process *p,
egot = uint_to_big(sc.got, hp);
hp += BIG_UINT_HEAP_SIZE;
}
- key = copy_struct(key, sz, &hp, &MSO(p));
+ key = copy_struct_rel(key, sz, &hp, &MSO(p), sc.lastobj, NULL);
continuation = TUPLE5
(hp,
tptr[1],
@@ -1295,6 +1282,7 @@ static int db_select_count_tree(Process *p, DbTable *tbl,
struct select_count_context sc;
struct mp_info mpi;
Eterm lastkey = THE_NON_VALUE;
+ Eterm* lk_base = NULL;
Eterm key;
Eterm continuation;
unsigned sz;
@@ -1335,7 +1323,7 @@ static int db_select_count_tree(Process *p, DbTable *tbl,
sc.all_objects = mpi.all_objects;
if (!mpi.got_partial && mpi.some_limitation &&
- cmp(mpi.least,mpi.most) == 0) {
+ CMP(mpi.least,mpi.most) == 0) {
doit_select_count(tb,mpi.save_term,&sc,0 /* dummy */);
RET_TO_BIF(erts_make_integer(sc.got,p),DB_ERROR_NONE);
}
@@ -1344,11 +1332,12 @@ static int db_select_count_tree(Process *p, DbTable *tbl,
if (mpi.some_limitation) {
if ((this = find_next_from_pb_key(tb, stack, mpi.most)) != NULL) {
lastkey = GETKEY(tb, this->dbterm.tpl);
+ lk_base = this->dbterm.tpl;
}
sc.end_condition = mpi.least;
}
- traverse_backwards(tb, stack, lastkey, &doit_select_count, &sc);
+ traverse_backwards(tb, stack, lastkey, lk_base, &doit_select_count, &sc);
release_stack(tb,stack);
BUMP_REDS(p, 1000 - sc.max);
if (sc.max > 0) {
@@ -1356,7 +1345,7 @@ static int db_select_count_tree(Process *p, DbTable *tbl,
}
key = GETKEY(tb, sc.lastobj);
- sz = size_object(key);
+ sz = size_object_rel(key, sc.lastobj);
if (IS_USMALL(0, sc.got)) {
hp = HAlloc(p, sz + PROC_BIN_SIZE + 6);
egot = make_small(sc.got);
@@ -1366,7 +1355,7 @@ static int db_select_count_tree(Process *p, DbTable *tbl,
egot = uint_to_big(sc.got, hp);
hp += BIG_UINT_HEAP_SIZE;
}
- key = copy_struct(key, sz, &hp, &MSO(p));
+ key = copy_struct_rel(key, sz, &hp, &MSO(p), sc.lastobj, NULL);
if (mpi.all_objects)
(mpi.mp)->flags |= BIN_FLAG_ALL_OBJECTS;
mpb = db_make_mp_binary(p,mpi.mp,&hp);
@@ -1397,6 +1386,7 @@ static int db_select_chunk_tree(Process *p, DbTable *tbl,
struct select_context sc;
struct mp_info mpi;
Eterm lastkey = THE_NON_VALUE;
+ Eterm* lk_base = NULL;
Eterm key;
Eterm continuation;
unsigned sz;
@@ -1438,7 +1428,7 @@ static int db_select_chunk_tree(Process *p, DbTable *tbl,
sc.all_objects = mpi.all_objects;
if (!mpi.got_partial && mpi.some_limitation &&
- cmp(mpi.least,mpi.most) == 0) {
+ CMP(mpi.least,mpi.most) == 0) {
doit_select(tb,mpi.save_term,&sc, 0 /* direction doesn't matter */);
if (sc.accum != NIL) {
hp=HAlloc(p, 3);
@@ -1453,20 +1443,20 @@ static int db_select_chunk_tree(Process *p, DbTable *tbl,
if (mpi.some_limitation) {
if ((this = find_next_from_pb_key(tb, stack, mpi.most)) != NULL) {
lastkey = GETKEY(tb, this->dbterm.tpl);
+ lk_base = this->dbterm.tpl;
}
sc.end_condition = mpi.least;
}
-
- traverse_backwards(tb, stack, lastkey, &doit_select_chunk, &sc);
+ traverse_backwards(tb, stack, lastkey, lk_base, &doit_select_chunk, &sc);
} else {
if (mpi.some_limitation) {
if ((this = find_prev_from_pb_key(tb, stack, mpi.least)) != NULL) {
lastkey = GETKEY(tb, this->dbterm.tpl);
+ lk_base = this->dbterm.tpl;
}
sc.end_condition = mpi.most;
}
-
- traverse_forward(tb, stack, lastkey, &doit_select_chunk, &sc);
+ traverse_forward(tb, stack, lastkey, lk_base, &doit_select_chunk, &sc);
}
release_stack(tb,stack);
@@ -1491,9 +1481,9 @@ static int db_select_chunk_tree(Process *p, DbTable *tbl,
}
key = GETKEY(tb, sc.lastobj);
- sz = size_object(key);
+ sz = size_object_rel(key, sc.lastobj);
hp = HAlloc(p, 9 + sz + PROC_BIN_SIZE);
- key = copy_struct(key, sz, &hp, &MSO(p));
+ key = copy_struct_rel(key, sz, &hp, &MSO(p), sc.lastobj, NULL);
if (mpi.all_objects)
(mpi.mp)->flags |= BIN_FLAG_ALL_OBJECTS;
mpb = db_make_mp_binary(p,mpi.mp,&hp);
@@ -1516,9 +1506,9 @@ static int db_select_chunk_tree(Process *p, DbTable *tbl,
}
key = GETKEY(tb, sc.lastobj);
- sz = size_object(key);
+ sz = size_object_rel(key, sc.lastobj);
hp = HAlloc(p, 9 + sz + PROC_BIN_SIZE);
- key = copy_struct(key, sz, &hp, &MSO(p));
+ key = copy_struct_rel(key, sz, &hp, &MSO(p), sc.lastobj, NULL);
if (mpi.all_objects)
(mpi.mp)->flags |= BIN_FLAG_ALL_OBJECTS;
@@ -1594,7 +1584,7 @@ static int db_select_delete_continue_tree(Process *p,
sc.keypos = tb->common.keypos;
ASSERT(!erts_smp_atomic_read(&tb->is_stack_busy));
- traverse_backwards(tb, &tb->static_stack, lastkey, &doit_select_delete, &sc);
+ traverse_backwards(tb, &tb->static_stack, lastkey, NULL, &doit_select_delete, &sc);
BUMP_REDS(p, 1000 - sc.max);
@@ -1603,11 +1593,11 @@ static int db_select_delete_continue_tree(Process *p,
}
key = GETKEY(tb, (sc.lastterm)->dbterm.tpl);
if (end_condition != NIL &&
- cmp_partly_bound(end_condition,key) > 0) { /* done anyway */
+ cmp_partly_bound(end_condition,key,sc.lastterm->dbterm.tpl) > 0) { /* done anyway */
RET_TO_BIF(erts_make_integer(sc.accum,p),DB_ERROR_NONE);
}
/* Not done yet, let's trap. */
- sz = size_object(key);
+ sz = size_object_rel(key, sc.lastterm->dbterm.tpl);
if (IS_USMALL(0, sc.accum)) {
hp = HAlloc(p, sz + 6);
eaccsum = make_small(sc.accum);
@@ -1617,7 +1607,7 @@ static int db_select_delete_continue_tree(Process *p,
eaccsum = uint_to_big(sc.accum, hp);
hp += BIG_UINT_HEAP_SIZE;
}
- key = copy_struct(key, sz, &hp, &MSO(p));
+ key = copy_struct_rel(key, sz, &hp, &MSO(p), sc.lastterm->dbterm.tpl, NULL);
continuation = TUPLE5
(hp,
tptr[1],
@@ -1638,6 +1628,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
struct select_delete_context sc;
struct mp_info mpi;
Eterm lastkey = THE_NON_VALUE;
+ Eterm* lk_base = NULL;
Eterm key;
Eterm continuation;
unsigned sz;
@@ -1681,7 +1672,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
sc.mp = mpi.mp;
if (!mpi.got_partial && mpi.some_limitation &&
- cmp(mpi.least,mpi.most) == 0) {
+ CMP(mpi.least,mpi.most) == 0) {
doit_select_delete(tb,mpi.save_term,&sc, 0 /* direction doesn't
matter */);
RET_TO_BIF(erts_make_integer(sc.accum,p),DB_ERROR_NONE);
@@ -1690,11 +1681,12 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
if (mpi.some_limitation) {
if ((this = find_next_from_pb_key(tb, &tb->static_stack, mpi.most)) != NULL) {
lastkey = GETKEY(tb, this->dbterm.tpl);
+ lk_base = this->dbterm.tpl;
}
sc.end_condition = mpi.least;
}
- traverse_backwards(tb, &tb->static_stack, lastkey, &doit_select_delete, &sc);
+ traverse_backwards(tb, &tb->static_stack, lastkey, lk_base, &doit_select_delete, &sc);
BUMP_REDS(p, 1000 - sc.max);
if (sc.max > 0) {
@@ -1702,7 +1694,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
}
key = GETKEY(tb, (sc.lastterm)->dbterm.tpl);
- sz = size_object(key);
+ sz = size_object_rel(key, sc.lastterm->dbterm.tpl);
if (IS_USMALL(0, sc.accum)) {
hp = HAlloc(p, sz + PROC_BIN_SIZE + 6);
eaccsum = make_small(sc.accum);
@@ -1712,7 +1704,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
eaccsum = uint_to_big(sc.accum, hp);
hp += BIG_UINT_HEAP_SIZE;
}
- key = copy_struct(key, sz, &hp, &MSO(p));
+ key = copy_struct_rel(key, sz, &hp, &MSO(p), sc.lastterm->dbterm.tpl, NULL);
mpb = db_make_mp_binary(p,mpi.mp,&hp);
continuation = TUPLE5
@@ -1738,7 +1730,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
** Other interface routines (not directly coupled to one bif)
*/
-/* Display hash table contents (for dump) */
+/* Display tree contents (for dump) */
static void db_print_tree(int to, void *to_arg,
int show,
DbTable *tbl)
@@ -1754,7 +1746,6 @@ static void db_print_tree(int to, void *to_arg,
"------------------------------------------------\n");
#else
erts_print(to, to_arg, "Ordered set (AVL tree), Elements: %d\n", NITEMS(tb));
- do_dump_tree(to, to_arg, tb->root);
#endif
}
@@ -1830,7 +1821,7 @@ do_db_tree_foreach_offheap(TreeDbTerm *tdbt,
}
static TreeDbTerm *linkout_tree(DbTableTree *tb,
- Eterm key)
+ Eterm key, Eterm* key_base)
{
TreeDbTerm **tstack[STACK_NEED];
int tpos = 0;
@@ -1853,7 +1844,7 @@ static TreeDbTerm *linkout_tree(DbTableTree *tb,
for (;;) {
if (!*this) { /* Failure */
return NULL;
- } else if ((c = cmp(key,GETKEY(tb,(*this)->dbterm.tpl))) < 0) {
+ } else if ((c = cmp_key(tb, key, key_base, *this)) < 0) {
dstack[dpos++] = DIR_LEFT;
tstack[tpos++] = this;
this = &((*this)->left);
@@ -1917,7 +1908,7 @@ static TreeDbTerm *linkout_object_tree(DbTableTree *tb,
for (;;) {
if (!*this) { /* Failure */
return NULL;
- } else if ((c = cmp(key,GETKEY(tb,(*this)->dbterm.tpl))) < 0) {
+ } else if ((c = cmp_key(tb,key,NULL,*this)) < 0) {
dstack[dpos++] = DIR_LEFT;
tstack[tpos++] = this;
this = &((*this)->left);
@@ -1926,7 +1917,7 @@ static TreeDbTerm *linkout_object_tree(DbTableTree *tb,
tstack[tpos++] = this;
this = &((*this)->right);
} else { /* Equal key, found the only possible matching object*/
- if (!eq(object,make_tuple((*this)->dbterm.tpl))) {
+ if (!db_eq(&tb->common,object,&(*this)->dbterm)) {
return NULL;
}
q = (*this);
@@ -2070,24 +2061,6 @@ static int analyze_pattern(DbTableTree *tb, Eterm pattern,
return DB_ERROR_NONE;
}
-static void do_dump_tree(int to, void *to_arg, TreeDbTerm *t)
-{
- if (t != NULL) {
- do_dump_tree(to, to_arg, t->left);
- erts_print(to, to_arg, "%T\n", make_tuple(t->dbterm.tpl));
- do_dump_tree(to, to_arg, t->right);
- }
-}
-
-static void free_term(DbTableTree *tb, TreeDbTerm* p)
-{
- db_free_term_data(&(p->dbterm));
- erts_db_free(ERTS_ALC_T_DB_TERM,
- (DbTable *) tb,
- (void *) p,
- SIZ_DBTERM(p)*sizeof(Uint));
-}
-
static int do_free_tree_cont(DbTableTree *tb, int num_left)
{
TreeDbTerm *root;
@@ -2118,17 +2091,6 @@ static int do_free_tree_cont(DbTableTree *tb, int num_left)
return 1;
}
-static TreeDbTerm* get_term(DbTableTree *tb,
- TreeDbTerm* old,
- Eterm obj)
-{
- TreeDbTerm* p = db_get_term((DbTableCommon *) tb,
- (old != NULL) ? &(old->dbterm) : NULL,
- ((char *) &(old->dbterm)) - ((char *) old),
- obj);
- return p;
-}
-
/*
* Deletion helpers
*/
@@ -2332,14 +2294,15 @@ done:
* Find next and previous in sort order
*/
-static TreeDbTerm *find_next(DbTableTree *tb, DbTreeStack* stack, Eterm key)
+static TreeDbTerm *find_next(DbTableTree *tb, DbTreeStack* stack,
+ Eterm key, Eterm* key_base)
{
TreeDbTerm *this;
TreeDbTerm *tmp;
Sint c;
if(( this = TOP_NODE(stack)) != NULL) {
- if (!CMP_EQ(GETKEY(tb, this->dbterm.tpl),key)) {
+ if (!cmp_key_eq(tb,key,key_base,this)) {
/* Start from the beginning */
stack->pos = stack->slot = 0;
}
@@ -2349,14 +2312,14 @@ static TreeDbTerm *find_next(DbTableTree *tb, DbTreeStack* stack, Eterm key)
return NULL;
for (;;) {
PUSH_NODE(stack, this);
- if (( c = cmp(GETKEY(tb, this->dbterm.tpl),key) ) < 0) {
+ if (( c = cmp_key(tb,key,key_base,this) ) > 0) {
if (this->right == NULL) /* We are at the previos
and the element does
not exist */
break;
else
this = this->right;
- } else if (c > 0) {
+ } else if (c < 0) {
if (this->left == NULL) /* Done */
return this;
else
@@ -2389,14 +2352,15 @@ static TreeDbTerm *find_next(DbTableTree *tb, DbTreeStack* stack, Eterm key)
return this;
}
-static TreeDbTerm *find_prev(DbTableTree *tb, DbTreeStack* stack, Eterm key)
+static TreeDbTerm *find_prev(DbTableTree *tb, DbTreeStack* stack,
+ Eterm key, Eterm* key_base)
{
TreeDbTerm *this;
TreeDbTerm *tmp;
Sint c;
if(( this = TOP_NODE(stack)) != NULL) {
- if (!CMP_EQ(GETKEY(tb, this->dbterm.tpl),key)) {
+ if (!cmp_key_eq(tb,key,key_base,this)) {
/* Start from the beginning */
stack->pos = stack->slot = 0;
}
@@ -2406,14 +2370,14 @@ static TreeDbTerm *find_prev(DbTableTree *tb, DbTreeStack* stack, Eterm key)
return NULL;
for (;;) {
PUSH_NODE(stack, this);
- if (( c = cmp(GETKEY(tb, this->dbterm.tpl),key) ) > 0) {
+ if (( c = cmp_key(tb,key,key_base,this) ) < 0) {
if (this->left == NULL) /* We are at the next
and the element does
not exist */
break;
else
this = this->left;
- } else if (c < 0) {
+ } else if (c > 0) {
if (this->right == NULL) /* Done */
return this;
else
@@ -2459,7 +2423,8 @@ static TreeDbTerm *find_next_from_pb_key(DbTableTree *tb, DbTreeStack* stack,
return NULL;
for (;;) {
PUSH_NODE(stack, this);
- if (( c = cmp_partly_bound(key,GETKEY(tb, this->dbterm.tpl)) ) >= 0) {
+ if (( c = cmp_partly_bound(key,GETKEY(tb, this->dbterm.tpl),
+ this->dbterm.tpl) ) >= 0) {
if (this->right == NULL) {
do {
tmp = POP_NODE(stack);
@@ -2492,7 +2457,8 @@ static TreeDbTerm *find_prev_from_pb_key(DbTableTree *tb, DbTreeStack* stack,
return NULL;
for (;;) {
PUSH_NODE(stack, this);
- if (( c = cmp_partly_bound(key,GETKEY(tb, this->dbterm.tpl)) ) <= 0) {
+ if (( c = cmp_partly_bound(key,GETKEY(tb, this->dbterm.tpl),
+ this->dbterm.tpl) ) <= 0) {
if (this->left == NULL) {
do {
tmp = POP_NODE(stack);
@@ -2522,12 +2488,11 @@ static TreeDbTerm *find_node(DbTableTree *tb, Eterm key)
Sint res;
DbTreeStack* stack = get_static_stack(tb);
- if(!stack || EMPTY_NODE(stack)
- || !CMP_EQ(GETKEY(tb, ( this = TOP_NODE(stack) )->dbterm.tpl), key)) {
+ if(!stack || EMPTY_NODE(stack)
+ || !cmp_key_eq(tb, key, NULL, (this=TOP_NODE(stack)))) {
this = tb->root;
- while (this != NULL &&
- ( res = cmp(key, GETKEY(tb, this->dbterm.tpl)) ) != 0) {
+ while (this != NULL && (res = cmp_key(tb,key,NULL,this)) != 0) {
if (res < 0)
this = this->left;
else
@@ -2549,8 +2514,7 @@ static TreeDbTerm **find_node2(DbTableTree *tb, Eterm key)
Sint res;
this = &tb->root;
- while ((*this) != NULL &&
- ( res = cmp(key, GETKEY(tb, (*this)->dbterm.tpl)) ) != 0) {
+ while ((*this) != NULL && (res = cmp_key(tb, key, NULL, *this)) != 0) {
if (res < 0)
this = &((*this)->left);
else
@@ -2570,46 +2534,24 @@ static int db_lookup_dbterm_tree(DbTable *tbl, Eterm key, DbUpdateHandle* handle
handle->tb = tbl;
handle->dbterm = &(*pp)->dbterm;
+ handle->mustResize = 0;
handle->bp = (void**) pp;
handle->new_size = (*pp)->dbterm.size;
- handle->mustResize = 0;
+#if HALFWORD_HEAP
+ handle->abs_vec = NULL;
+#endif
return 1;
}
static void db_finalize_dbterm_tree(DbUpdateHandle* handle)
{
if (handle->mustResize) {
- ErlOffHeap tmp_offheap;
- Eterm* top;
- Eterm copy;
- DbTerm* newDbTerm;
- DbTableTree *tb = &handle->tb->tree;
TreeDbTerm* oldp = (TreeDbTerm*) *handle->bp;
- TreeDbTerm* newp = erts_db_alloc(ERTS_ALC_T_DB_TERM,
- handle->tb,
- sizeof(TreeDbTerm)+sizeof(Eterm)*(handle->new_size-1));
- memcpy(newp, oldp, sizeof(TreeDbTerm)-sizeof(DbTerm)); /* copy only tree header */
- *(handle->bp) = newp;
- reset_static_stack(tb);
- newDbTerm = &newp->dbterm;
-
- newDbTerm->size = handle->new_size;
- tmp_offheap.first = NULL;
- tmp_offheap.overhead = 0;
-
- /* make a flat copy */
- top = DBTERM_BUF(newDbTerm);
- copy = copy_struct(make_tuple(handle->dbterm->tpl),
- handle->new_size,
- &top, &tmp_offheap);
- newDbTerm->first_oh = tmp_offheap.first;
- DBTERM_SET_TPL(newDbTerm,tuple_val(copy));
-
- db_free_term_data(handle->dbterm);
- erts_db_free(ERTS_ALC_T_DB_TERM,
- handle->tb,
- (void *) (((char *) handle->dbterm) - (sizeof(TreeDbTerm) - sizeof(DbTerm))),
- sizeof(TreeDbTerm) + sizeof(Eterm)*(handle->dbterm->size-1));
+
+ db_finalize_resize(handle, offsetof(TreeDbTerm,dbterm));
+ reset_static_stack(&handle->tb->tree);
+
+ free_term(&handle->tb->tree, oldp);
}
#ifdef DEBUG
handle->dbterm = 0;
@@ -2622,7 +2564,7 @@ static void db_finalize_dbterm_tree(DbUpdateHandle* handle)
*/
static void traverse_backwards(DbTableTree *tb,
DbTreeStack* stack,
- Eterm lastkey,
+ Eterm lastkey, Eterm* lk_base,
int (*doit)(DbTableTree *,
TreeDbTerm *,
void *,
@@ -2641,15 +2583,16 @@ static void traverse_backwards(DbTableTree *tb,
this = this->right;
}
this = TOP_NODE(stack);
- next = find_prev(tb, stack, GETKEY(tb, this->dbterm.tpl));
+ next = find_prev(tb, stack, GETKEY(tb, this->dbterm.tpl),
+ this->dbterm.tpl);
if (!((*doit)(tb, this, context, 0)))
return;
} else {
- next = find_prev(tb, stack, lastkey);
+ next = find_prev(tb, stack, lastkey, lk_base);
}
while ((this = next) != NULL) {
- next = find_prev(tb, stack, GETKEY(tb, this->dbterm.tpl));
+ next = find_prev(tb, stack, GETKEY(tb, this->dbterm.tpl), this->dbterm.tpl);
if (!((*doit)(tb, this, context, 0)))
return;
}
@@ -2660,7 +2603,7 @@ static void traverse_backwards(DbTableTree *tb,
*/
static void traverse_forward(DbTableTree *tb,
DbTreeStack* stack,
- Eterm lastkey,
+ Eterm lastkey, Eterm* lk_base,
int (*doit)(DbTableTree *,
TreeDbTerm *,
void *,
@@ -2679,15 +2622,15 @@ static void traverse_forward(DbTableTree *tb,
this = this->left;
}
this = TOP_NODE(stack);
- next = find_next(tb, stack, GETKEY(tb, this->dbterm.tpl));
+ next = find_next(tb, stack, GETKEY(tb, this->dbterm.tpl), this->dbterm.tpl);
if (!((*doit)(tb, this, context, 1)))
return;
} else {
- next = find_next(tb, stack, lastkey);
+ next = find_next(tb, stack, lastkey, lk_base);
}
while ((this = next) != NULL) {
- next = find_next(tb, stack, GETKEY(tb, this->dbterm.tpl));
+ next = find_next(tb, stack, GETKEY(tb, this->dbterm.tpl), this->dbterm.tpl);
if (!((*doit)(tb, this, context, 1)))
return;
}
@@ -2713,7 +2656,7 @@ static int key_given(DbTableTree *tb, Eterm pattern, TreeDbTerm **ret,
if (( this = find_node(tb, key) ) == NULL) {
return -1;
}
- *ret = this;
+ *ret = this;
return 1;
} else if (partly_bound != NULL && key != am_Underscore &&
db_is_variable(key) < 0)
@@ -2724,7 +2667,7 @@ static int key_given(DbTableTree *tb, Eterm pattern, TreeDbTerm **ret,
-static Sint do_cmp_partly_bound(Eterm a, Eterm b, int *done)
+static Sint do_cmp_partly_bound(Eterm a, Eterm b, Eterm* b_base, int *done)
{
Eterm* aa;
Eterm* bb;
@@ -2738,44 +2681,44 @@ static Sint do_cmp_partly_bound(Eterm a, Eterm b, int *done)
*done = 1;
return 0;
}
- if (a == b)
+ if (is_same(a,NULL,b,b_base))
return 0;
switch (a & _TAG_PRIMARY_MASK) {
case TAG_PRIMARY_LIST:
if (!is_list(b)) {
- return cmp(a,b);
+ return cmp_rel(a,NULL,b,b_base);
}
aa = list_val(a);
- bb = list_val(b);
+ bb = list_val_rel(b,b_base);
while (1) {
- if ((j = do_cmp_partly_bound(*aa++, *bb++, done)) != 0 || *done)
+ if ((j = do_cmp_partly_bound(*aa++, *bb++, b_base, done)) != 0 || *done)
return j;
if (*aa==*bb)
return 0;
if (is_not_list(*aa) || is_not_list(*bb))
- return do_cmp_partly_bound(*aa, *bb, done);
+ return do_cmp_partly_bound(*aa, *bb, b_base, done);
aa = list_val(*aa);
- bb = list_val(*bb);
+ bb = list_val_rel(*bb,b_base);
}
case TAG_PRIMARY_BOXED:
if ((b & _TAG_PRIMARY_MASK) != TAG_PRIMARY_BOXED) {
- return cmp(a,b);
+ return cmp_rel(a,NULL,b,b_base);
}
a_hdr = ((*boxed_val(a)) & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE;
- b_hdr = ((*boxed_val(b)) & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE;
+ b_hdr = ((*boxed_val_rel(b,b_base)) & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE;
if (a_hdr != b_hdr) {
- return cmp(a, b);
+ return cmp_rel(a, NULL, b, b_base);
}
if (a_hdr == (_TAG_HEADER_ARITYVAL >> _TAG_PRIMARY_SIZE)) {
aa = tuple_val(a);
- bb = tuple_val(b);
+ bb = tuple_val_rel(b, b_base);
/* compare the arities */
i = arityval(*aa); /* get the arity*/
if (i < arityval(*bb)) return(-1);
if (i > arityval(*bb)) return(1);
while (i--) {
- if ((j = do_cmp_partly_bound(*++aa, *++bb, done)) != 0
+ if ((j = do_cmp_partly_bound(*++aa, *++bb, b_base, done)) != 0
|| *done)
return j;
}
@@ -2783,14 +2726,14 @@ static Sint do_cmp_partly_bound(Eterm a, Eterm b, int *done)
}
/* Drop through */
default:
- return cmp(a, b);
+ return cmp_rel(a, NULL, b, b_base);
}
}
-static Sint cmp_partly_bound(Eterm partly_bound_key, Eterm bound_key)
+static Sint cmp_partly_bound(Eterm partly_bound_key, Eterm bound_key, Eterm* bk_base)
{
int done = 0;
- Sint ret = do_cmp_partly_bound(partly_bound_key, bound_key, &done);
+ Sint ret = do_cmp_partly_bound(partly_bound_key, bound_key, bk_base, &done);
#ifdef HARDDEBUG
erts_fprintf(stderr,"\ncmp_partly_bound: %T", partly_bound_key);
if (ret < 0)
@@ -2799,7 +2742,7 @@ static Sint cmp_partly_bound(Eterm partly_bound_key, Eterm bound_key)
erts_fprintf(stderr," > ");
else
erts_fprintf(stderr," == ");
- erts_fprintf(stderr,"%T\n",bound_key);
+ erts_fprintf(stderr,"%T\n",bound_key); // HALFWORD BUG: printing rterm
#endif
return ret;
}
@@ -2886,7 +2829,7 @@ static int do_partly_bound_can_match_lesser(Eterm a, Eterm b,
if (not_eq_tags(a,b)) {
*done = 1;
- return (cmp(a, b) < 0) ? 1 : 0;
+ return (CMP(a, b) < 0) ? 1 : 0;
}
/* we now know that tags are the same */
@@ -2922,7 +2865,7 @@ static int do_partly_bound_can_match_lesser(Eterm a, Eterm b,
bb = list_val(*bb);
}
default:
- if((i = cmp(a, b)) != 0) {
+ if((i = CMP(a, b)) != 0) {
*done = 1;
}
return (i < 0) ? 1 : 0;
@@ -2957,7 +2900,7 @@ static int do_partly_bound_can_match_greater(Eterm a, Eterm b,
if (not_eq_tags(a,b)) {
*done = 1;
- return (cmp(a, b) > 0) ? 1 : 0;
+ return (CMP(a, b) > 0) ? 1 : 0;
}
/* we now know that tags are the same */
@@ -2993,7 +2936,7 @@ static int do_partly_bound_can_match_greater(Eterm a, Eterm b,
bb = list_val(*bb);
}
default:
- if((i = cmp(a, b)) != 0) {
+ if((i = CMP(a, b)) != 0) {
*done = 1;
}
return (i > 0) ? 1 : 0;
@@ -3009,39 +2952,24 @@ static int doit_select(DbTableTree *tb, TreeDbTerm *this, void *ptr,
{
struct select_context *sc = (struct select_context *) ptr;
Eterm ret;
- Uint32 dummy;
+ Eterm* hp;
sc->lastobj = this->dbterm.tpl;
if (sc->end_condition != NIL &&
((forward &&
cmp_partly_bound(sc->end_condition,
- GETKEY_WITH_POS(sc->keypos,
- this->dbterm.tpl)) < 0) ||
+ GETKEY_WITH_POS(sc->keypos, this->dbterm.tpl),
+ this->dbterm.tpl) < 0) ||
(!forward &&
cmp_partly_bound(sc->end_condition,
- GETKEY_WITH_POS(sc->keypos,
- this->dbterm.tpl)) > 0))) {
+ GETKEY_WITH_POS(sc->keypos, this->dbterm.tpl),
+ this->dbterm.tpl) > 0))) {
return 0;
}
- ret = db_prog_match(sc->p, sc->mp,
- make_tuple(this->dbterm.tpl),
- NULL,0, &dummy);
+ ret = db_match_dbterm(&tb->common,sc->p,sc->mp,sc->all_objects,
+ &this->dbterm, &hp, 2);
if (is_value(ret)) {
- Uint sz;
- Eterm *hp;
- if (sc->all_objects) {
- hp = HAlloc(sc->p, this->dbterm.size + 2);
- ret = copy_shallow(DBTERM_BUF(&this->dbterm),
- this->dbterm.size,
- &hp,
- &MSO(sc->p));
- } else {
- sz = size_object(ret);
- hp = HAlloc(sc->p, sz + 2);
- ret = copy_struct(ret, sz,
- &hp, &MSO(sc->p));
- }
sc->accum = CONS(hp, ret, sc->accum);
}
if (MBUF(sc->p)) {
@@ -3062,20 +2990,18 @@ static int doit_select_count(DbTableTree *tb, TreeDbTerm *this, void *ptr,
{
struct select_count_context *sc = (struct select_count_context *) ptr;
Eterm ret;
- Uint32 dummy;
sc->lastobj = this->dbterm.tpl;
/* Always backwards traversing */
if (sc->end_condition != NIL &&
(cmp_partly_bound(sc->end_condition,
- GETKEY_WITH_POS(sc->keypos,
- this->dbterm.tpl)) > 0)) {
+ GETKEY_WITH_POS(sc->keypos, this->dbterm.tpl),
+ this->dbterm.tpl) > 0)) {
return 0;
}
- ret = db_prog_match(sc->p, sc->mp,
- make_tuple(this->dbterm.tpl),
- NULL,0, &dummy);
+ ret = db_match_dbterm(&tb->common, sc->p, sc->mp, 0,
+ &this->dbterm, NULL, 0);
if (ret == am_true) {
++(sc->got);
}
@@ -3090,41 +3016,26 @@ static int doit_select_chunk(DbTableTree *tb, TreeDbTerm *this, void *ptr,
{
struct select_context *sc = (struct select_context *) ptr;
Eterm ret;
- Uint32 dummy;
+ Eterm* hp;
sc->lastobj = this->dbterm.tpl;
if (sc->end_condition != NIL &&
((forward &&
cmp_partly_bound(sc->end_condition,
- GETKEY_WITH_POS(sc->keypos,
- this->dbterm.tpl)) < 0) ||
+ GETKEY_WITH_POS(sc->keypos, this->dbterm.tpl),
+ this->dbterm.tpl) < 0) ||
(!forward &&
cmp_partly_bound(sc->end_condition,
- GETKEY_WITH_POS(sc->keypos,
- this->dbterm.tpl)) > 0))) {
+ GETKEY_WITH_POS(sc->keypos, this->dbterm.tpl),
+ this->dbterm.tpl) > 0))) {
return 0;
}
- ret = db_prog_match(sc->p, sc->mp,
- make_tuple(this->dbterm.tpl),
- NULL,0, &dummy);
+ ret = db_match_dbterm(&tb->common, sc->p, sc->mp, sc->all_objects,
+ &this->dbterm, &hp, 2);
if (is_value(ret)) {
- Uint sz;
- Eterm *hp;
-
++(sc->got);
- if (sc->all_objects) {
- hp = HAlloc(sc->p, this->dbterm.size + 2);
- ret = copy_shallow(DBTERM_BUF(&this->dbterm),
- this->dbterm.size,
- &hp,
- &MSO(sc->p));
- } else {
- sz = size_object(ret);
- hp = HAlloc(sc->p, sz + 2);
- ret = copy_struct(ret, sz, &hp, &MSO(sc->p));
- }
sc->accum = CONS(hp, ret, sc->accum);
}
if (MBUF(sc->p)) {
@@ -3146,7 +3057,6 @@ static int doit_select_delete(DbTableTree *tb, TreeDbTerm *this, void *ptr,
{
struct select_delete_context *sc = (struct select_delete_context *) ptr;
Eterm ret;
- Uint32 dummy;
Eterm key;
if (sc->erase_lastterm)
@@ -3156,15 +3066,14 @@ static int doit_select_delete(DbTableTree *tb, TreeDbTerm *this, void *ptr,
if (sc->end_condition != NIL &&
cmp_partly_bound(sc->end_condition,
- GETKEY_WITH_POS(sc->keypos,
- this->dbterm.tpl)) > 0)
+ GETKEY_WITH_POS(sc->keypos, this->dbterm.tpl),
+ this->dbterm.tpl) > 0)
return 0;
- ret = db_prog_match(sc->p, sc->mp,
- make_tuple(this->dbterm.tpl),
- NULL,0, &dummy);
+ ret = db_match_dbterm(&tb->common, sc->p, sc->mp, 0,
+ &this->dbterm, NULL, 0);
if (ret == am_true) {
key = GETKEY(sc->tb, this->dbterm.tpl);
- linkout_tree(sc->tb, key);
+ linkout_tree(sc->tb, key, this->dbterm.tpl);
sc->erase_lastterm = 1;
++sc->accum;
}
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index 2f34561234..d3e31da413 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,6 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-
#include "sys.h"
#include "erl_vm.h"
#include "global.h"
@@ -58,6 +57,7 @@
DBIF_TABLE_GUARD | DBIF_TABLE_BODY | DBIF_TRACE_GUARD | DBIF_TRACE_BODY
+#define HEAP_XTRA 100
/*
** Some convenience macros for stacks (DMC == db_match_compile)
@@ -230,6 +230,11 @@ typedef enum {
matchCall2,
matchCall3,
matchPushV,
+#if HALFWORD_HEAP
+ matchPushVGuard, /* First guard-only variable reference */
+#endif
+ matchPushVResult, /* First variable reference in result, or (if HALFWORD)
+ in guard if also referenced in result */
matchPushExpr, /* Push the whole expression we're matching ('$_') */
matchPushArrayAsList, /* Only when parameter is an Array and
not an erlang term (DCOMP_TRACE) */
@@ -293,11 +298,19 @@ DMC_DECLARE_STACK_TYPE(unsigned);
** Data about the heap during compilation
*/
+typedef struct DMCVariable {
+ int is_bound;
+ int is_in_body;
+#if HALFWORD_HEAP
+ int first_guard_label; /* to maybe change from PushVGuard to PushVResult */
+#endif
+} DMCVariable;
+
typedef struct DMCHeap {
int size;
- unsigned def[DMC_DEFAULT_SIZE];
- unsigned *data;
- int used;
+ DMCVariable vars_def[DMC_DEFAULT_SIZE];
+ DMCVariable* vars;
+ int vars_used;
} DMCHeap;
/*
@@ -324,7 +337,6 @@ typedef struct dmc_context {
Eterm *bodyexpr;
int num_match;
int current_match;
- int eheap_need;
Uint cflags;
int is_guard; /* 1 if in guard, 0 if in body */
int special; /* 1 if the head in the match was a single expression */
@@ -347,9 +359,22 @@ typedef struct dmc_context {
#define ERTS_DEFAULT_MS_HEAP_SIZE 128
+/* Runtime info about a $-variable
+*/
+typedef struct MatchVariable {
+ Eterm term;
+#ifdef DEBUG
+ Process* proc;
+ Eterm* base;
+#endif
+} MatchVariable;
+
typedef struct {
Process process;
- Eterm *heap;
+ union {
+ Eterm* heap;
+ MatchVariable* variables; /* first on "heap" */
+ }u;
Eterm default_heap[ERTS_DEFAULT_MS_HEAP_SIZE];
} ErtsMatchPseudoProcess;
@@ -372,10 +397,10 @@ cleanup_match_pseudo_process(ErtsMatchPseudoProcess *mpsp, int keep_heap)
}
#endif
if (!keep_heap) {
- if (mpsp->heap != &mpsp->default_heap[0]) {
+ if (mpsp->u.heap != mpsp->default_heap) {
/* Have to be done *after* call to erts_cleanup_empty_process() */
- erts_free(ERTS_ALC_T_DB_MS_RUN_HEAP, (void *) mpsp->heap);
- mpsp->heap = &mpsp->default_heap[0];
+ erts_free(ERTS_ALC_T_DB_MS_RUN_HEAP, (void *) mpsp->u.heap);
+ mpsp->u.heap = mpsp->default_heap;
}
#ifdef DEBUG
else {
@@ -399,7 +424,7 @@ create_match_pseudo_process(void)
mpsp = (ErtsMatchPseudoProcess *)erts_alloc(ERTS_ALC_T_DB_MS_PSDO_PROC,
sizeof(ErtsMatchPseudoProcess));
erts_init_empty_process(&mpsp->process);
- mpsp->heap = &mpsp->default_heap[0];
+ mpsp->u.heap = mpsp->default_heap;
return mpsp;
}
@@ -423,11 +448,11 @@ get_match_pseudo_process(Process *c_p, Uint heap_size)
mpsp = match_pseudo_process;
cleanup_match_pseudo_process(mpsp, 0);
#endif
- if (heap_size > ERTS_DEFAULT_MS_HEAP_SIZE)
- mpsp->heap = (Eterm *) erts_alloc(ERTS_ALC_T_DB_MS_RUN_HEAP,
- heap_size*sizeof(Uint));
+ if (heap_size > ERTS_DEFAULT_MS_HEAP_SIZE*sizeof(Eterm)) {
+ mpsp->u.heap = (Eterm*) erts_alloc(ERTS_ALC_T_DB_MS_RUN_HEAP, heap_size);
+ }
else {
- ASSERT(mpsp->heap == &mpsp->default_heap[0]);
+ ASSERT(mpsp->u.heap == mpsp->default_heap);
}
return mpsp;
}
@@ -468,23 +493,6 @@ erts_match_set_release_result(Process* c_p)
static erts_smp_atomic_t trace_control_word;
-
-Eterm
-erts_ets_copy_object(Eterm obj, Process* to)
-{
- Uint size = size_object(obj);
- Eterm* hp = HAlloc(to, size);
- Eterm res;
-
- res = copy_struct(obj, size, &hp, &MSO(to));
-#ifdef DEBUG
- if (eq(obj, res) == 0) {
- erl_exit(1, "copy not equal to source\n");
- }
-#endif
- return res;
-}
-
/* This needs to be here, before the bif table... */
static Eterm db_set_trace_control_word_fake_1(Process *p, Eterm val);
@@ -870,9 +878,9 @@ static DMCRet dmc_one_term(DMCContext *context,
#ifdef DMC_DEBUG
static int test_disassemble_next = 0;
-static void db_match_dis(Binary *prog);
+void db_match_dis(Binary *prog);
#define TRACE erts_fprintf(stderr,"Trace: %s:%d\n",__FILE__,__LINE__)
-#define FENCE_PATTERN_SIZE 1
+#define FENCE_PATTERN_SIZE (1*sizeof(Uint))
#define FENCE_PATTERN 0xDEADBEEFUL
#else
#define TRACE /* Nothing */
@@ -890,6 +898,8 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace);
static Eterm seq_trace_fake(Process *p, Eterm arg1);
+static void db_free_tmp_uncompressed(DbTerm* obj);
+
/*
** Interface routines.
@@ -914,7 +924,7 @@ BIF_RETTYPE db_set_trace_control_word_1(Process *p, Eterm new)
if (val != ((Uint32)val))
BIF_ERROR(p, BADARG);
- old_tcw = (Uint32) erts_smp_atomic_xchg(&trace_control_word, (long) val);
+ old_tcw = (Uint32) erts_smp_atomic_xchg(&trace_control_word, (erts_aint_t) val);
BIF_RET(erts_make_integer((Uint) old_tcw, p));
}
@@ -1178,14 +1188,14 @@ done:
}
Eterm erts_match_set_run(Process *p, Binary *mpsp,
- Eterm *args, int num_args,
+ Eterm *args, int num_args,
+ enum erts_pam_run_flags in_flags,
Uint32 *return_flags)
{
Eterm ret;
- ret = db_prog_match(p, mpsp,
- NIL, args,
- num_args, return_flags);
+ ret = db_prog_match(p, mpsp, NIL, NULL, args, num_args,
+ in_flags, return_flags);
#if defined(HARDDEBUG)
if (is_non_value(ret)) {
erts_fprintf(stderr, "Failed\n");
@@ -1209,9 +1219,9 @@ static Eterm erts_match_set_run_ets(Process *p, Binary *mpsp,
{
Eterm ret;
- ret = db_prog_match(p, mpsp,
- args, NULL,
- num_args, return_flags);
+ ret = db_prog_match(p, mpsp, args, NULL, NULL, num_args,
+ ERTS_PAM_CONTIGUOUS_TUPLE | ERTS_PAM_COPY_RESULT,
+ return_flags);
#if defined(HARDDEBUG)
if (is_non_value(ret)) {
erts_fprintf(stderr, "Failed\n");
@@ -1279,7 +1289,6 @@ Binary *db_match_compile(Eterm *matchexpr,
int structure_checked;
DMCRet res;
int current_try_label;
- Uint max_eheap_need;
Binary *bp = NULL;
unsigned clause_start;
@@ -1292,27 +1301,24 @@ Binary *db_match_compile(Eterm *matchexpr,
context.matchexpr = matchexpr;
context.guardexpr = guards;
context.bodyexpr = body;
- context.eheap_need = 0;
context.err_info = err_info;
context.cflags = flags;
heap.size = DMC_DEFAULT_SIZE;
- heap.data = heap.def;
+ heap.vars = heap.vars_def;
/*
** Compile the match expression
*/
restart:
- heap.used = 0;
- max_eheap_need = 0;
+ heap.vars_used = 0;
for (context.current_match = 0;
context.current_match < num_progs;
++context.current_match) { /* This loop is long,
too long */
- memset(heap.data, 0, heap.size * sizeof(*heap.data));
+ memset(heap.vars, 0, heap.size * sizeof(*heap.vars));
t = context.matchexpr[context.current_match];
context.stack_used = 0;
- context.eheap_need = 0;
structure_checked = 0;
if (context.current_match < num_progs - 1) {
DMC_PUSH(text,matchTryMeElse);
@@ -1484,10 +1490,6 @@ restart:
if (current_try_label >= 0) {
DMC_POKE(text, current_try_label, DMC_STACK_NUM(text));
}
- /* So, how much eheap did this part of the match program need? */
- if (context.eheap_need > max_eheap_need) {
- max_eheap_need = context.eheap_need;
- }
} /* for (context.current_match = 0 ...) */
@@ -1523,16 +1525,13 @@ restart:
ret->saved_program_buf = NULL;
ret->saved_program = NIL;
ret->term_save = context.save;
- ret->num_bindings = heap.used;
+ ret->num_bindings = heap.vars_used;
ret->single_variable = context.special;
sys_memcpy(ret->text, DMC_STACK_DATA(text),
DMC_STACK_NUM(text) * sizeof(UWord));
- ret->heap_size = ((heap.used * sizeof(Eterm)) +
- (max_eheap_need * sizeof(Eterm)) +
- (context.stack_need * sizeof(Eterm *)) +
- (3 * (FENCE_PATTERN_SIZE * sizeof(Eterm *))));
- ret->eheap_offset = heap.used + FENCE_PATTERN_SIZE;
- ret->stack_offset = ret->eheap_offset + max_eheap_need + FENCE_PATTERN_SIZE;
+ ret->stack_offset = heap.vars_used*sizeof(MatchVariable) + FENCE_PATTERN_SIZE;
+ ret->heap_size = ret->stack_offset + context.stack_need * sizeof(Eterm*) + FENCE_PATTERN_SIZE;
+
#ifdef DMC_DEBUG
ret->prog_end = ret->text + DMC_STACK_NUM(text);
#endif
@@ -1550,8 +1549,8 @@ error: /* Here is were we land when compilation failed. */
DMC_FREE(text);
if (context.copy != NULL)
free_message_buffer(context.copy);
- if (heap.data != heap.def)
- erts_free(ERTS_ALC_T_DB_MS_CMPL_HEAP, (void *) heap.data);
+ if (heap.vars != heap.vars_def)
+ erts_free(ERTS_ALC_T_DB_MS_CMPL_HEAP, (void *) heap.vars);
return bp;
}
@@ -1596,7 +1595,7 @@ erts_match_prog_foreach_offheap(Binary *bprog,
*/
static Eterm dpm_array_to_list(Process *psp, Eterm *arr, int arity)
{
- Eterm *hp = HAlloc(psp, arity * 2);
+ Eterm *hp = HAllocX(psp, arity * 2, HEAP_XTRA);
Eterm ret = NIL;
while (--arity >= 0) {
ret = CONS(hp, arr[arity], ret);
@@ -1604,15 +1603,83 @@ static Eterm dpm_array_to_list(Process *psp, Eterm *arr, int arity)
}
return ret;
}
+
+
+#if HALFWORD_HEAP
+struct heap_checkpoint_t
+{
+ Process *p;
+ Eterm* htop;
+ ErlHeapFragment* mbuf;
+ unsigned used_size;
+ ErlOffHeap off_heap;
+};
+
+static void heap_checkpoint_init(Process* p, struct heap_checkpoint_t* hcp)
+{
+ hcp->p = p;
+ hcp->htop = HEAP_TOP(p);
+ hcp->mbuf = MBUF(p);
+ hcp->used_size = hcp->mbuf ? hcp->mbuf->used_size : 0;
+ hcp->off_heap = MSO(p);
+}
+
+static void heap_checkpoint_revert(struct heap_checkpoint_t* hcp)
+{
+ struct erl_off_heap_header* oh = MSO(hcp->p).first;
+
+ if (oh != hcp->off_heap.first) {
+ ASSERT(oh != NULL);
+ if (hcp->off_heap.first) {
+ while (oh->next != hcp->off_heap.first) {
+ oh = oh->next;
+ }
+ oh->next = NULL;
+ }
+ erts_cleanup_offheap(&MSO(hcp->p));
+ MSO(hcp->p) = hcp->off_heap;
+ }
+ if (MBUF(hcp->p) != hcp->mbuf) {
+ ErlHeapFragment* hf = MBUF(hcp->p);
+ ASSERT(hf != NULL);
+ if (hcp->mbuf) {
+ while (hf->next != hcp->mbuf) {
+ hf = hf->next;
+ }
+ hf->next = NULL;
+ }
+ free_message_buffer(MBUF(hcp->p));
+ MBUF(hcp->p) = hcp->mbuf;
+ }
+ if (hcp->mbuf != NULL && hcp->mbuf->used_size != hcp->used_size) {
+ hcp->mbuf->used_size = hcp->used_size;
+ }
+ HEAP_TOP(hcp->p) = hcp->htop;
+}
+#endif /* HALFWORD_HEAP */
+
+static ERTS_INLINE Eterm copy_object_rel(Process* p, Eterm term, Eterm* base)
+{
+ if (!is_immed(term)) {
+ Uint sz = size_object_rel(term, base);
+ Eterm* top = HAllocX(p, sz, HEAP_XTRA);
+ return copy_struct_rel(term, sz, &top, &MSO(p), base, NULL);
+ }
+ return term;
+}
+
+
/*
** Execution of the match program, this is Pam.
** May return THE_NON_VALUE, which is a bailout.
-** the para meter 'arity' is only used if 'term' is actually an array,
+** the parameter 'arity' is only used if 'term' is actually an array,
** i.e. 'DCOMP_TRACE' was specified
*/
-Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term,
+Eterm db_prog_match(Process *c_p, Binary *bprog,
+ Eterm term, Eterm* base,
Eterm *termp,
int arity,
+ enum erts_pam_run_flags in_flags,
Uint32 *return_flags)
{
MatchProg *prog = Binary2MatchProg(bprog);
@@ -1621,7 +1688,7 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term,
Eterm t;
Eterm **sp;
Eterm *esp;
- Eterm *hp;
+ MatchVariable* variables;
BeamInstr *cp;
UWord *pc = prog->text;
Eterm *ehp;
@@ -1631,19 +1698,24 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term,
unsigned do_catch;
ErtsMatchPseudoProcess *mpsp;
Process *psp;
+ Process* build_proc;
Process *tmpp;
Process *current_scheduled;
ErtsSchedulerData *esdp;
Eterm (*bif)(Process*, ...);
int fail_label;
int atomic_trace;
+#if HALFWORD_HEAP
+ struct heap_checkpoint_t c_p_checkpoint = {};
+#endif
#ifdef DMC_DEBUG
Uint *heap_fence;
- Uint *eheap_fence;
Uint *stack_fence;
Uint save_op;
#endif /* DMC_DEBUG */
+ ASSERT(base==NULL || HALFWORD_HEAP);
+
mpsp = get_match_pseudo_process(c_p, prog->heap_size);
psp = &mpsp->process;
@@ -1653,7 +1725,6 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term,
esdp = ERTS_GET_SCHEDULER_DATA_FROM_PROC(c_p);
ASSERT(esdp != NULL);
current_scheduled = esdp->current_process;
- esdp->current_process = psp;
/* SMP: psp->scheduler_data is set by get_match_pseudo_process */
atomic_trace = 0;
@@ -1676,11 +1747,9 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term,
#ifdef DMC_DEBUG
save_op = 0;
- heap_fence = (Uint *) mpsp->heap + prog->eheap_offset - 1;
- eheap_fence = (Uint *) mpsp->heap + prog->stack_offset - 1;
- stack_fence = (Uint *) mpsp->heap + prog->heap_size - 1;
+ heap_fence = (Eterm*)((char*) mpsp->u.heap + prog->stack_offset) - 1;
+ stack_fence = (Eterm*)((char*) mpsp->u.heap + prog->heap_size) - 1;
*heap_fence = FENCE_PATTERN;
- *eheap_fence = FENCE_PATTERN;
*stack_fence = FENCE_PATTERN;
#endif /* DMC_DEBUG */
@@ -1694,36 +1763,48 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term,
*return_flags = 0U;
+ variables = mpsp->u.variables;
+#if HALFWORD_HEAP
+ c_p_checkpoint.p = NULL;
+#endif
+
restart:
ep = &term;
- esp = mpsp->heap + prog->stack_offset;
+ esp = (Eterm*)((char*)mpsp->u.heap + prog->stack_offset);
sp = (Eterm **) esp;
- hp = mpsp->heap;
- ehp = mpsp->heap + prog->eheap_offset;
ret = am_true;
do_catch = 0;
fail_label = -1;
+ build_proc = psp;
+ esdp->current_process = psp;
+ ASSERT_HALFWORD(!c_p_checkpoint.p);
+
+#ifdef DEBUG
+ ASSERT(variables == mpsp->u.variables);
+ for (i=0; i<prog->num_bindings; i++) {
+ variables[i].term = THE_NON_VALUE;
+ variables[i].proc = NULL;
+ variables[i].base = base;
+ }
+#endif
for (;;) {
-#ifdef DMC_DEBUG
+
+ #ifdef DMC_DEBUG
if (*heap_fence != FENCE_PATTERN) {
erl_exit(1, "Heap fence overwritten in db_prog_match after op "
"0x%08x, overwritten with 0x%08x.", save_op, *heap_fence);
}
- if (*eheap_fence != FENCE_PATTERN) {
- erl_exit(1, "Eheap fence overwritten in db_prog_match after op "
- "0x%08x, overwritten with 0x%08x.", save_op,
- *eheap_fence);
- }
if (*stack_fence != FENCE_PATTERN) {
erl_exit(1, "Stack fence overwritten in db_prog_match after op "
"0x%08x, overwritten with 0x%08x.", save_op,
*stack_fence);
}
save_op = *pc;
-#endif
+ #endif
switch (*pc++) {
case matchTryMeElse:
+ ASSERT(fail_label == -1);
fail_label = *pc++;
break;
case matchArray: /* only when DCOMP_TRACE, is always first
@@ -1734,13 +1815,14 @@ restart:
ep = termp;
break;
case matchArrayBind: /* When the array size is unknown. */
+ ASSERT(termp);
n = *pc++;
- hp[n] = dpm_array_to_list(psp, termp, arity);
+ variables[n].term = dpm_array_to_list(psp, termp, arity);
break;
case matchTuple: /* *ep is a tuple of arity n */
- if (!is_tuple(*ep))
+ if (!is_tuple_rel(*ep,base))
FAIL();
- ep = tuple_val(*ep);
+ ep = tuple_val_rel(*ep,base);
n = *pc++;
if (arityval(*ep) != n)
FAIL();
@@ -1748,9 +1830,9 @@ restart:
break;
case matchPushT: /* *ep is a tuple of arity n,
push ptr to first element */
- if (!is_tuple(*ep))
+ if (!is_tuple_rel(*ep,base))
FAIL();
- tp = tuple_val(*ep);
+ tp = tuple_val_rel(*ep,base);
n = *pc++;
if (arityval(*tp) != n)
FAIL();
@@ -1760,12 +1842,12 @@ restart:
case matchList:
if (!is_list(*ep))
FAIL();
- ep = list_val(*ep);
+ ep = list_val_rel(*ep,base);
break;
case matchPushL:
if (!is_list(*ep))
FAIL();
- *sp++ = list_val(*ep);
+ *sp++ = list_val_rel(*ep,base);
++ep;
break;
case matchPop:
@@ -1773,41 +1855,44 @@ restart:
break;
case matchBind:
n = *pc++;
- hp[n] = *ep++;
+ variables[n].term = *ep++;
break;
case matchCmp:
n = *pc++;
- if (!eq(hp[n],*ep))
+ if (!eq_rel(variables[n].term, base, *ep, base))
FAIL();
++ep;
break;
case matchEqBin:
t = (Eterm) *pc++;
- if (!eq(*ep,t))
+ if (!eq_rel(t,NULL,*ep,base))
FAIL();
++ep;
break;
case matchEqFloat:
- if (!is_float(*ep))
+ if (!is_float_rel(*ep,base))
FAIL();
- if (memcmp(float_val(*ep) + 1, pc, sizeof(double)))
+ if (memcmp(float_val_rel(*ep,base) + 1, pc, sizeof(double)))
FAIL();
pc += TermWords(2);
++ep;
break;
- case matchEqRef:
- if (!is_ref(*ep))
+ case matchEqRef: {
+ Eterm* epc = (Eterm*)pc;
+ if (!is_ref_rel(*ep,base))
FAIL();
- if (!eq(*ep, make_internal_ref((Uint *) pc)))
+ if (!eq_rel(make_internal_ref_rel(epc, epc), epc, *ep, base)) {
FAIL();
- i = thing_arityval(*((Uint *) pc));
+ }
+ i = thing_arityval(*epc);
pc += TermWords(i+1);
++ep;
break;
+ }
case matchEqBig:
- if (!is_big(*ep))
+ if (!is_big_rel(*ep,base))
FAIL();
- tp = big_val(*ep);
+ tp = big_val_rel(*ep,base);
{
Eterm *epc = (Eterm *) pc;
if (*tp != *epc)
@@ -1823,7 +1908,8 @@ restart:
++ep;
break;
case matchEq:
- t = (Eterm) *pc++;
+ t = (Eterm) *pc++;
+ ASSERT(is_immed(t));
if (t != *ep++)
FAIL();
break;
@@ -1831,25 +1917,32 @@ restart:
++ep;
break;
/*
- * Here comes guard instructions
+ * Here comes guard & body instructions
*/
case matchPushC: /* Push constant */
- *esp++ = *pc++;
+ if ((in_flags & ERTS_PAM_COPY_RESULT)
+ && do_catch && !is_immed(*pc)) {
+ *esp++ = copy_object(*pc++, c_p);
+ }
+ else {
+ *esp++ = *pc++;
+ }
break;
case matchConsA:
- ehp[1] = *--esp;
- ehp[0] = esp[-1];
+ ehp = HAllocX(build_proc, 2, HEAP_XTRA);
+ CDR(ehp) = *--esp;
+ CAR(ehp) = esp[-1];
esp[-1] = make_list(ehp);
- ehp += 2;
break;
case matchConsB:
- ehp[0] = *--esp;
- ehp[1] = esp[-1];
+ ehp = HAllocX(build_proc, 2, HEAP_XTRA);
+ CAR(ehp) = *--esp;
+ CDR(ehp) = esp[-1];
esp[-1] = make_list(ehp);
- ehp += 2;
break;
case matchMkTuple:
n = *pc++;
+ ehp = HAllocX(build_proc, n+1, HEAP_XTRA);
t = make_tuple(ehp);
*ehp++ = make_arityval(n);
while (n--) {
@@ -1859,7 +1952,7 @@ restart:
break;
case matchCall0:
bif = (Eterm (*)(Process*, ...)) *pc++;
- t = (*bif)(psp);
+ t = (*bif)(build_proc);
if (is_non_value(t)) {
if (do_catch)
t = FAIL_TERM;
@@ -1870,7 +1963,7 @@ restart:
break;
case matchCall1:
bif = (Eterm (*)(Process*, ...)) *pc++;
- t = (*bif)(psp, esp[-1]);
+ t = (*bif)(build_proc, esp[-1]);
if (is_non_value(t)) {
if (do_catch)
t = FAIL_TERM;
@@ -1881,7 +1974,7 @@ restart:
break;
case matchCall2:
bif = (Eterm (*)(Process*, ...)) *pc++;
- t = (*bif)(psp, esp[-1], esp[-2]);
+ t = (*bif)(build_proc, esp[-1], esp[-2]);
if (is_non_value(t)) {
if (do_catch)
t = FAIL_TERM;
@@ -1893,7 +1986,7 @@ restart:
break;
case matchCall3:
bif = (Eterm (*)(Process*, ...)) *pc++;
- t = (*bif)(psp, esp[-1], esp[-2], esp[-3]);
+ t = (*bif)(build_proc, esp[-1], esp[-2], esp[-3]);
if (is_non_value(t)) {
if (do_catch)
t = FAIL_TERM;
@@ -1903,15 +1996,73 @@ restart:
esp -= 2;
esp[-1] = t;
break;
+
+ #if HALFWORD_HEAP
+ case matchPushVGuard:
+ if (!base) goto case_matchPushV;
+ /* Build NULL-based copy on pseudo heap for easy disposal */
+ n = *pc++;
+ ASSERT(is_value(variables[n].term));
+ ASSERT(!variables[n].proc);
+ variables[n].term = copy_object_rel(psp, variables[n].term, base);
+ *esp++ = variables[n].term;
+ #ifdef DEBUG
+ variables[n].proc = psp;
+ variables[n].base = NULL;
+ #endif
+ break;
+ #endif
+ case matchPushVResult:
+ if (!(in_flags & ERTS_PAM_COPY_RESULT)) goto case_matchPushV;
+
+ /* Build (NULL-based) copy on callers heap */
+ #if HALFWORD_HEAP
+ if (!do_catch && !c_p_checkpoint.p) {
+ heap_checkpoint_init(c_p, &c_p_checkpoint);
+ }
+ #endif
+ n = *pc++;
+ ASSERT(is_value(variables[n].term));
+ ASSERT(!variables[n].proc);
+ variables[n].term = copy_object_rel(c_p, variables[n].term, base);
+ *esp++ = variables[n].term;
+ #ifdef DEBUG
+ variables[n].proc = c_p;
+ variables[n].base = NULL;
+ #endif
+ break;
case matchPushV:
- *esp++ = hp[*pc++];
+ case_matchPushV:
+ n = *pc++;
+ ASSERT(is_value(variables[n].term));
+ ASSERT(!variables[n].base);
+ *esp++ = variables[n].term;
break;
case matchPushExpr:
- *esp++ = term;
+ if (in_flags & ERTS_PAM_COPY_RESULT) {
+ Uint sz;
+ Eterm* top;
+ sz = size_object_rel(term, base);
+ top = HAllocX(build_proc, sz, HEAP_XTRA);
+ if (in_flags & ERTS_PAM_CONTIGUOUS_TUPLE) {
+ ASSERT(is_tuple_rel(term,base));
+ *esp++ = copy_shallow_rel(tuple_val_rel(term,base), sz,
+ &top, &MSO(build_proc), base);
+ }
+ else {
+ *esp++ = copy_struct_rel(term, sz, &top, &MSO(build_proc),
+ base, NULL);
+ }
+ }
+ else {
+ *esp = term;
+ }
break;
case matchPushArrayAsList:
+ ASSERT_HALFWORD(base == NULL);
n = arity; /* Only happens when 'term' is an array */
tp = termp;
+ ehp = HAllocX(build_proc, n*2, HEAP_XTRA);
*esp++ = make_list(ehp);
while (n--) {
*ehp++ = *tp++;
@@ -1924,7 +2075,8 @@ restart:
break;
case matchPushArrayAsListU:
/* This instruction is NOT efficient. */
- *esp++ = dpm_array_to_list(psp, termp, arity);
+ ASSERT_HALFWORD(base == NULL);
+ *esp++ = dpm_array_to_list(build_proc, termp, arity);
break;
case matchTrue:
if (*--esp != am_true)
@@ -2010,7 +2162,7 @@ restart:
case matchProcessDump: {
erts_dsprintf_buf_t *dsbufp = erts_create_tmp_dsbuf(0);
print_process_info(ERTS_PRINT_DSBUF, (void *) dsbufp, c_p);
- *esp++ = new_binary(psp, (byte *)dsbufp->str, (int)dsbufp->str_len);
+ *esp++ = new_binary(build_proc, (byte *)dsbufp->str, (int)dsbufp->str_len);
erts_destroy_tmp_dsbuf(dsbufp);
break;
}
@@ -2054,29 +2206,24 @@ restart:
if (SEQ_TRACE_TOKEN(c_p) == NIL)
*esp++ = NIL;
else {
+ Eterm sender = SEQ_TRACE_TOKEN_SENDER(c_p);
+ Uint sender_sz = is_immed(sender) ? 0 : size_object(sender);
+ ehp = HAllocX(build_proc, 6 + sender_sz, HEAP_XTRA);
+ if (sender_sz) {
+ sender = copy_struct(sender, sender_sz, &ehp, &MSO(build_proc));
+ }
*esp++ = make_tuple(ehp);
ehp[0] = make_arityval(5);
ehp[1] = SEQ_TRACE_TOKEN_FLAGS(c_p);
ehp[2] = SEQ_TRACE_TOKEN_LABEL(c_p);
ehp[3] = SEQ_TRACE_TOKEN_SERIAL(c_p);
- ehp[4] = SEQ_TRACE_TOKEN_SENDER(c_p);
+ ehp[4] = sender;
ehp[5] = SEQ_TRACE_TOKEN_LASTCNT(c_p);
ASSERT(SEQ_TRACE_TOKEN_ARITY(c_p) == 5);
ASSERT(is_immed(ehp[1]));
ASSERT(is_immed(ehp[2]));
ASSERT(is_immed(ehp[3]));
ASSERT(is_immed(ehp[5]));
- if(!is_immed(ehp[4])) {
- Eterm *sender = &ehp[4];
- ehp += 6;
- *sender = copy_struct(*sender,
- size_object(*sender),
- &ehp,
- &MSO(psp));
- }
- else
- ehp += 6;
-
}
break;
case matchEnableTrace:
@@ -2125,12 +2272,12 @@ restart:
if (!(c_p->cp) || !(cp = find_function_from_pc(c_p->cp))) {
*esp++ = am_undefined;
} else {
+ ehp = HAllocX(build_proc, 4, HEAP_XTRA);
*esp++ = make_tuple(ehp);
ehp[0] = make_arityval(3);
ehp[1] = cp[0];
ehp[2] = cp[1];
ehp[3] = make_small((Uint) cp[2]);
- ehp += 4;
}
break;
case matchSilent:
@@ -2207,8 +2354,12 @@ restart:
}
}
break;
- case matchCatch:
+ case matchCatch: /* Match success, now build result */
do_catch = 1;
+ if (in_flags & ERTS_PAM_COPY_RESULT) {
+ build_proc = c_p;
+ esdp->current_process = c_p;
+ }
break;
case matchHalt:
goto success;
@@ -2217,9 +2368,16 @@ restart:
}
}
fail:
+#if HALFWORD_HEAP
+ if (c_p_checkpoint.p) {
+ /* Dispose garbage built by guards on caller heap */
+ heap_checkpoint_revert(&c_p_checkpoint);
+ c_p_checkpoint.p = NULL;
+ }
+#endif
*return_flags = 0U;
- if (fail_label >= 0) { /* We failed during a "TryMeElse",
- lets restart, with the next match
+ if (fail_label >= 0) { /* We failed during a "TryMeElse",
+ lets restart, with the next match
program */
pc = (prog->text) + fail_label;
cleanup_match_pseudo_process(mpsp, 1);
@@ -2233,11 +2391,6 @@ success:
erl_exit(1, "Heap fence overwritten in db_prog_match after op "
"0x%08x, overwritten with 0x%08x.", save_op, *heap_fence);
}
- if (*eheap_fence != FENCE_PATTERN) {
- erl_exit(1, "Eheap fence overwritten in db_prog_match after op "
- "0x%08x, overwritten with 0x%08x.", save_op,
- *eheap_fence);
- }
if (*stack_fence != FENCE_PATTERN) {
erl_exit(1, "Stack fence overwritten in db_prog_match after op "
"0x%08x, overwritten with 0x%08x.", save_op,
@@ -2248,6 +2401,7 @@ success:
esdp->current_process = current_scheduled;
END_ATOMIC_TRACE(c_p);
+
return ret;
#undef FAIL
#undef FAIL_TERM
@@ -2259,7 +2413,8 @@ success:
/*
* Convert a match program to a "magic" binary to return up to erlang
*/
-Eterm db_make_mp_binary(Process *p, Binary *mp, Eterm **hpp) {
+Eterm db_make_mp_binary(Process *p, Binary *mp, Eterm **hpp)
+{
return erts_mk_magic_binary_term(hpp, &MSO(p), mp);
}
@@ -2325,13 +2480,13 @@ void db_free_dmc_err_info(DMCErrInfo *ei){
** Store bignum in *hpp and increase *hpp accordingly.
** *hpp is assumed to be large enough to hold the result.
*/
-Eterm db_add_counter(Eterm** hpp, Eterm counter, Eterm incr)
+Eterm db_add_counter(Eterm** hpp, Wterm counter, Eterm incr)
{
DeclareTmpHeapNoproc(big_tmp,2);
Eterm res;
Sint ires;
- Eterm arg1;
- Eterm arg2;
+ Wterm arg1;
+ Wterm arg2;
if (is_both_small(counter,incr)) {
ires = signed_val(counter) + signed_val(incr);
@@ -2372,6 +2527,34 @@ Eterm db_add_counter(Eterm** hpp, Eterm counter, Eterm incr)
}
}
+/* Must be called to read elements after db_lookup_dbterm.
+** Will decompress if needed.
+** HEALFWORD_HEAP:
+** Will convert from relative to Wterm format if needed.
+** (but only on top level, tuples and lists will still contain rterms)
+*/
+Wterm db_do_read_element(DbUpdateHandle* handle, Sint position)
+{
+ Eterm elem = handle->dbterm->tpl[position];
+ if (!is_header(elem)) {
+#if HALFWORD_HEAP
+ if (!is_immed(elem)
+ && !handle->tb->common.compress
+ && !(handle->abs_vec && handle->abs_vec[position])) {
+ return rterm2wterm(elem, handle->dbterm->tpl);
+ }
+#endif
+ return elem;
+ }
+
+ ASSERT(((DbTableCommon*)handle->tb)->compress);
+ ASSERT(!handle->mustResize);
+ handle->dbterm = db_alloc_tmp_uncompressed(&handle->tb->common,
+ handle->dbterm);
+ handle->mustResize = 1;
+ return handle->dbterm->tpl[position];
+}
+
/*
** Update one element:
** handle: Initialized by db_lookup_dbterm()
@@ -2388,132 +2571,489 @@ void db_do_update_element(DbUpdateHandle* handle,
Eterm* oldp;
Uint newval_sz;
Uint oldval_sz;
+#if HALFWORD_HEAP
+ Eterm* old_base;
+#endif
if (is_both_immed(newval,oldval)) {
handle->dbterm->tpl[position] = newval;
+ #ifdef DEBUG_CLONE
+ if (handle->dbterm->debug_clone) {
+ handle->dbterm->debug_clone[position] = newval;
+ }
+ #endif
return;
}
- else if (!handle->mustResize && is_boxed(newval)) {
- newp = boxed_val(newval);
- switch (*newp & _TAG_HEADER_MASK) {
- case _TAG_HEADER_POS_BIG:
- case _TAG_HEADER_NEG_BIG:
- case _TAG_HEADER_FLOAT:
- case _TAG_HEADER_HEAP_BIN:
- newval_sz = header_arity(*newp) + 1;
- if (is_boxed(oldval)) {
- oldp = boxed_val(oldval);
- switch (*oldp & _TAG_HEADER_MASK) {
+ if (!handle->mustResize) {
+ if (handle->tb->common.compress) {
+ handle->dbterm = db_alloc_tmp_uncompressed(&handle->tb->common,
+ handle->dbterm);
+ handle->mustResize = 1;
+ oldval = handle->dbterm->tpl[position];
+ #if HALFWORD_HEAP
+ old_base = NULL;
+ #endif
+ }
+ else {
+ #if HALFWORD_HEAP
+ ASSERT(!handle->abs_vec);
+ old_base = handle->dbterm->tpl;
+ #endif
+ if (is_boxed(newval)) {
+ newp = boxed_val(newval);
+ switch (*newp & _TAG_HEADER_MASK) {
case _TAG_HEADER_POS_BIG:
case _TAG_HEADER_NEG_BIG:
case _TAG_HEADER_FLOAT:
case _TAG_HEADER_HEAP_BIN:
- oldval_sz = header_arity(*oldp) + 1;
- if (oldval_sz == newval_sz) {
- /* "self contained" terms of same size, do memcpy */
- sys_memcpy(oldp, newp, newval_sz*sizeof(Eterm));
- return;
+ newval_sz = header_arity(*newp) + 1;
+ if (is_boxed(oldval)) {
+ oldp = boxed_val_rel(oldval,old_base);
+ switch (*oldp & _TAG_HEADER_MASK) {
+ case _TAG_HEADER_POS_BIG:
+ case _TAG_HEADER_NEG_BIG:
+ case _TAG_HEADER_FLOAT:
+ case _TAG_HEADER_HEAP_BIN:
+ oldval_sz = header_arity(*oldp) + 1;
+ if (oldval_sz == newval_sz) {
+ /* "self contained" terms of same size, do memcpy */
+ sys_memcpy(oldp, newp, newval_sz*sizeof(Eterm));
+ return;
+ }
+ goto both_size_set;
+ }
}
- goto both_size_set;
+ goto new_size_set;
}
}
- goto new_size_set;
}
}
+#if HALFWORD_HEAP
+ else {
+ old_base = (handle->tb->common.compress
+ || (handle->abs_vec && handle->abs_vec[position])) ?
+ NULL : handle->dbterm->tpl;
+ }
+#endif
/* Not possible for simple memcpy or dbterm is already non-contiguous, */
/* need to realloc... */
newval_sz = is_immed(newval) ? 0 : size_object(newval);
new_size_set:
-
- oldval_sz = is_immed(oldval) ? 0 : size_object(oldval);
+
+ oldval_sz = is_immed(oldval) ? 0 : size_object_rel(oldval,old_base);
both_size_set:
handle->new_size = handle->new_size - oldval_sz + newval_sz;
- /* write new value in old dbterm, finalize will make a flat copy */
+ /* write new value in old dbterm, finalize will make a flat copy */
handle->dbterm->tpl[position] = newval;
handle->mustResize = 1;
+
+#if HALFWORD_HEAP
+ if (old_base && newval_sz > 0) {
+ ASSERT(!handle->tb->common.compress);
+ if (!handle->abs_vec) {
+ int i = header_arity(handle->dbterm->tpl[0]);
+ handle->abs_vec = erts_alloc(ERTS_ALC_T_TMP, (i+1)*sizeof(char));
+ sys_memset(handle->abs_vec, 0, i+1);
+ /* abs_vec[0] not used */
+ }
+ handle->abs_vec[position] = 1;
+ }
+#endif
+}
+
+static ERTS_INLINE byte* db_realloc_term(DbTableCommon* tb, void* old,
+ Uint old_sz, Uint new_sz, Uint offset)
+{
+ byte* ret;
+ if (erts_ets_realloc_always_moves) {
+ ret = erts_db_alloc(ERTS_ALC_T_DB_TERM, (DbTable*)tb, new_sz);
+ sys_memcpy(ret, old, offset);
+ erts_db_free(ERTS_ALC_T_DB_TERM, (DbTable*)tb, old, old_sz);
+ } else {
+ ret = erts_db_realloc(ERTS_ALC_T_DB_TERM, (DbTable*)tb,
+ old, old_sz, new_sz);
+ }
+ return ret;
+}
+
+/* Allocated size of a compressed dbterm
+*/
+static ERTS_INLINE Uint db_alloced_size_comp(DbTerm* obj)
+{
+ return obj->tpl[arityval(*obj->tpl) + 1];
+}
+
+void db_free_term(DbTable *tb, void* basep, Uint offset)
+{
+ DbTerm* db = (DbTerm*) ((byte*)basep + offset);
+ Uint size;
+ if (tb->common.compress) {
+ db_cleanup_offheap_comp(db);
+ size = db_alloced_size_comp(db);
+ }
+ else {
+ ErlOffHeap tmp_oh;
+ tmp_oh.first = db->first_oh;
+ erts_cleanup_offheap(&tmp_oh);
+ size = offset + offsetof(DbTerm,tpl) + db->size*sizeof(Eterm);
+ }
+ erts_db_free(ERTS_ALC_T_DB_TERM, tb, basep, size);
}
+static ERTS_INLINE Uint align_up(Uint value, Uint pow2)
+{
+ ASSERT((pow2 & (pow2-1)) == 0);
+ return (value + (pow2-1)) & ~(pow2-1);
+}
+
+/* Compressed size of an uncompressed term
+*/
+static Uint db_size_dbterm_comp(DbTableCommon* tb, Eterm obj)
+{
+ Eterm* tpl = tuple_val(obj);
+ int i;
+ Uint size = sizeof(DbTerm)
+ + arityval(*tpl) * sizeof(Eterm)
+ + sizeof(Uint); /* "alloc_size" */
+
+ for (i = arityval(*tpl); i>0; i--) {
+ if (i != tb->keypos && is_not_immed(tpl[i])) {
+ size += erts_encode_ext_size_ets(tpl[i]);
+ }
+ }
+ size += size_object(tpl[tb->keypos]) * sizeof(Eterm);
+ return align_up(size, sizeof(Uint));
+}
+
+/* Conversion between top tuple element and pointer to compressed data
+*/
+static ERTS_INLINE Eterm ext2elem(Eterm* tpl, byte* ext)
+{
+ return (((Uint)(ext - (byte*)tpl)) << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER;
+}
+static ERTS_INLINE byte* elem2ext(Eterm* tpl, Uint ix)
+{
+ ASSERT(is_header(tpl[ix]));
+ return (byte*)tpl + (tpl[ix] >> _TAG_PRIMARY_SIZE);
+}
+
+static void* copy_to_comp(DbTableCommon* tb, Eterm obj, DbTerm* dest,
+ Uint alloc_size)
+{
+ ErlOffHeap tmp_offheap;
+ Eterm* src = tuple_val(obj);
+ Eterm* tpl = dest->tpl;
+ Eterm key = src[tb->keypos];
+ int arity = arityval(src[0]);
+ union {
+ Eterm* ep;
+ byte* cp;
+ UWord ui;
+ }top;
+ int i;
+
+ top.ep = tpl+ 1 + arity + 1;
+ tpl[0] = src[0];
+ tpl[arity + 1] = alloc_size;
+
+ tmp_offheap.first = NULL;
+ tpl[tb->keypos] = copy_struct_rel(key, size_object(key), &top.ep, &tmp_offheap, NULL, tpl);
+ dest->first_oh = tmp_offheap.first;
+ for (i=1; i<=arity; i++) {
+ if (i != tb->keypos) {
+ if (is_immed(src[i])) {
+ tpl[i] = src[i];
+ }
+ else {
+ tpl[i] = ext2elem(tpl, top.cp);
+ top.cp = erts_encode_ext_ets(src[i], top.cp, &dest->first_oh);
+ }
+ }
+ }
+
+#ifdef DEBUG_CLONE
+ {
+ Eterm* dbg_top = erts_alloc(ERTS_ALC_T_DB_TERM, dest->size * sizeof(Eterm));
+ dest->debug_clone = dbg_top;
+ tmp_offheap.first = dest->first_oh;
+ copy_struct_rel(obj, dest->size, &dbg_top, &tmp_offheap, NULL, dbg_top);
+ dest->first_oh = tmp_offheap.first;
+ ASSERT(dbg_top == dest->debug_clone + dest->size);
+ }
+#endif
+ return top.cp;
+}
/*
** Copy the object into a possibly new DbTerm,
** offset is the offset of the DbTerm from the start
-** of the sysAllocaed structure, The possibly realloced and copied
+** of the allocated structure, The possibly realloced and copied
** structure is returned. Make sure (((char *) old) - offset) is a
** pointer to a ERTS_ALC_T_DB_TERM allocated data area.
*/
-void* db_get_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj)
+void* db_store_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj)
{
+ byte* basep;
+ DbTerm* newp;
+ Eterm* top;
int size = size_object(obj);
- void *structp = ((char*) old) - offset;
- DbTerm* p;
- Eterm copy;
- Eterm *top;
ErlOffHeap tmp_offheap;
if (old != 0) {
+ basep = ((byte*) old) - offset;
tmp_offheap.first = old->first_oh;
- tmp_offheap.overhead = 0;
erts_cleanup_offheap(&tmp_offheap);
old->first_oh = tmp_offheap.first;
if (size == old->size) {
- p = old;
- } else {
+ newp = old;
+ }
+ else {
Uint new_sz = offset + sizeof(DbTerm) + sizeof(Eterm)*(size-1);
Uint old_sz = offset + sizeof(DbTerm) + sizeof(Eterm)*(old->size-1);
- if (erts_ets_realloc_always_moves) {
- void *nstructp = erts_db_alloc(ERTS_ALC_T_DB_TERM,
- (DbTable *) tb,
- new_sz);
- memcpy(nstructp,structp,offset);
- erts_db_free(ERTS_ALC_T_DB_TERM,
- (DbTable *) tb,
- structp,
- old_sz);
- structp = nstructp;
- } else {
- structp = erts_db_realloc(ERTS_ALC_T_DB_TERM,
- (DbTable *) tb,
- structp,
- old_sz,
- new_sz);
- }
- p = (DbTerm*) ((void *)(((char *) structp) + offset));
+ basep = db_realloc_term(tb, basep, old_sz, new_sz, offset);
+ newp = (DbTerm*) (basep + offset);
}
}
else {
- structp = erts_db_alloc(ERTS_ALC_T_DB_TERM,
- (DbTable *) tb,
- (offset
- + sizeof(DbTerm)
- + sizeof(Eterm)*(size-1)));
- p = (DbTerm*) ((void *)(((char *) structp) + offset));
- }
- p->size = size;
+ basep = erts_db_alloc(ERTS_ALC_T_DB_TERM, (DbTable *)tb,
+ (offset + sizeof(DbTerm) + sizeof(Eterm)*(size-1)));
+ newp = (DbTerm*) (basep + offset);
+ }
+ newp->size = size;
+ top = newp->tpl;
tmp_offheap.first = NULL;
- tmp_offheap.overhead = 0;
+ copy_struct_rel(obj, size, &top, &tmp_offheap, NULL, top);
+ newp->first_oh = tmp_offheap.first;
+#ifdef DEBUG_CLONE
+ newp->debug_clone = NULL;
+#endif
+ return basep;
+}
- top = DBTERM_BUF(p);
- copy = copy_struct(obj, size, &top, &tmp_offheap);
- p->first_oh = tmp_offheap.first;
- DBTERM_SET_TPL(p,tuple_val(copy));
- return structp;
+void* db_store_term_comp(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj)
+{
+ Uint new_sz = offset + db_size_dbterm_comp(tb, obj);
+ byte* basep;
+ DbTerm* newp;
+ byte* top;
+
+ ASSERT(tb->compress);
+ if (old != 0) {
+ Uint old_sz = db_alloced_size_comp(old);
+ db_cleanup_offheap_comp(old);
+
+ basep = ((byte*) old) - offset;
+ if (new_sz == old_sz) {
+ newp = old;
+ }
+ else {
+ basep = db_realloc_term(tb, basep, old_sz, new_sz, offset);
+ newp = (DbTerm*) (basep + offset);
+ }
+ }
+ else {
+ basep = erts_db_alloc(ERTS_ALC_T_DB_TERM, (DbTable*)tb, new_sz);
+ newp = (DbTerm*) (basep + offset);
+ }
+
+ newp->size = size_object(obj);
+ top = copy_to_comp(tb, obj, newp, new_sz);
+ ASSERT(top <= basep + new_sz);
+
+ /* ToDo: Maybe realloc if ((basep+new_sz) - top) > WASTED_SPACE_LIMIT */
+
+ return basep;
+}
+
+
+void db_finalize_resize(DbUpdateHandle* handle, Uint offset)
+{
+ DbTable* tbl = handle->tb;
+ DbTerm* newDbTerm;
+ Uint alloc_sz = offset +
+ (tbl->common.compress ?
+ db_size_dbterm_comp(&tbl->common, make_tuple(handle->dbterm->tpl)) :
+ sizeof(DbTerm)+sizeof(Eterm)*(handle->new_size-1));
+ byte* newp = erts_db_alloc(ERTS_ALC_T_DB_TERM, tbl, alloc_sz);
+ byte* oldp = *(handle->bp);
+
+ sys_memcpy(newp, oldp, offset); /* copy only hash/tree header */
+ *(handle->bp) = newp;
+ newDbTerm = (DbTerm*) (newp + offset);
+ newDbTerm->size = handle->new_size;
+#ifdef DEBUG_CLONE
+ newDbTerm->debug_clone = NULL;
+#endif
+
+ /* make a flat copy */
+
+ if (tbl->common.compress) {
+ copy_to_comp(&tbl->common, make_tuple(handle->dbterm->tpl),
+ newDbTerm, alloc_sz);
+ db_free_tmp_uncompressed(handle->dbterm);
+ }
+ else {
+ ErlOffHeap tmp_offheap;
+ Eterm* tpl = handle->dbterm->tpl;
+ Eterm* top = newDbTerm->tpl;
+
+ tmp_offheap.first = NULL;
+
+ #if HALFWORD_HEAP
+ if (handle->abs_vec) {
+ int i, arity = header_arity(handle->dbterm->tpl[0]);
+
+ top[0] = tpl[0];
+ top += arity + 1;
+ for (i=1; i<=arity; i++) {
+ Eterm* src_base = handle->abs_vec[i] ? NULL : tpl;
+
+ newDbTerm->tpl[i] = copy_struct_rel(tpl[i],
+ size_object_rel(tpl[i],src_base),
+ &top, &tmp_offheap, src_base,
+ newDbTerm->tpl);
+ }
+ newDbTerm->first_oh = tmp_offheap.first;
+ ASSERT((byte*)top <= (newp + alloc_sz));
+ erts_free(ERTS_ALC_T_TMP, handle->abs_vec);
+ }
+ else
+ #endif /* HALFWORD_HEAP */
+ {
+ copy_struct_rel(make_tuple_rel(tpl,tpl), handle->new_size, &top,
+ &tmp_offheap, tpl, top);
+ newDbTerm->first_oh = tmp_offheap.first;
+ ASSERT((byte*)top == (newp + alloc_sz));
+ }
+ }
}
+Eterm db_copy_from_comp(DbTableCommon* tb, DbTerm* bp, Eterm** hpp,
+ ErlOffHeap* off_heap)
+{
+ Eterm* hp = *hpp;
+ int i, arity = arityval(bp->tpl[0]);
+
+ hp[0] = bp->tpl[0];
+ *hpp += arity + 1;
+
+ hp[tb->keypos] = copy_struct_rel(bp->tpl[tb->keypos],
+ size_object_rel(bp->tpl[tb->keypos], bp->tpl),
+ hpp, off_heap, bp->tpl, NULL);
+ for (i=arity; i>0; i--) {
+ if (i != tb->keypos) {
+ if (is_immed(bp->tpl[i])) {
+ hp[i] = bp->tpl[i];
+ }
+ else {
+ hp[i] = erts_decode_ext_ets(hpp, off_heap,
+ elem2ext(bp->tpl, i));
+ }
+ }
+ }
+ ASSERT((*hpp - hp) <= bp->size);
+#ifdef DEBUG_CLONE
+ ASSERT(eq_rel(make_tuple(hp),make_tuple(bp->debug_clone),bp->debug_clone));
+#endif
+ return make_tuple(hp);
+}
-void db_free_term_data(DbTerm* p)
+Eterm db_copy_element_from_ets(DbTableCommon* tb, Process* p,
+ DbTerm* obj, Uint pos,
+ Eterm** hpp, Uint extra)
+{
+ if (is_immed(obj->tpl[pos])) {
+ *hpp = HAlloc(p, extra);
+ return obj->tpl[pos];
+ }
+ if (tb->compress && pos != tb->keypos) {
+ byte* ext = elem2ext(obj->tpl, pos);
+ Sint sz = erts_decode_ext_size_ets(ext, db_alloced_size_comp(obj)) + extra;
+ Eterm* hp = HAlloc(p, sz);
+ Eterm* endp = hp + sz;
+ Eterm copy = erts_decode_ext_ets(&hp, &MSO(p), ext);
+ *hpp = hp;
+ hp += extra;
+ HRelease(p, endp, hp);
+#ifdef DEBUG_CLONE
+ ASSERT(eq_rel(copy, obj->debug_clone[pos], obj->debug_clone));
+#endif
+ return copy;
+ }
+ else {
+ Uint sz = size_object_rel(obj->tpl[pos], obj->tpl);
+ *hpp = HAlloc(p, sz + extra);
+ return copy_struct_rel(obj->tpl[pos], sz, hpp, &MSO(p), obj->tpl, NULL);
+ }
+}
+
+
+/* Our own "cleanup_offheap"
+ * as refc-binaries may be unaligned in compressed terms
+*/
+void db_cleanup_offheap_comp(DbTerm* obj)
+{
+ union erl_off_heap_ptr u;
+ ProcBin tmp;
+
+ for (u.hdr = obj->first_oh; u.hdr; u.hdr = u.hdr->next) {
+ if ((UWord)u.voidp % sizeof(Uint) != 0) { /* unaligned ptr */
+ sys_memcpy(&tmp, u.voidp, sizeof(tmp));
+ /* Warning, must pass (void*)-variable to memcpy. Otherwise it will
+ cause Bus error on Sparc due to false compile time assumptions
+ about word aligned memory (type cast is not enough) */
+ u.pb = &tmp;
+ }
+ switch (thing_subtag(u.hdr->thing_word)) {
+ case REFC_BINARY_SUBTAG:
+ if (erts_refc_dectest(&u.pb->val->refc, 0) == 0) {
+ erts_bin_free(u.pb->val);
+ }
+ break;
+ case FUN_SUBTAG:
+ ASSERT(u.pb != &tmp);
+ if (erts_refc_dectest(&u.fun->fe->refc, 0) == 0) {
+ erts_erase_fun_entry(u.fun->fe);
+ }
+ break;
+ default:
+ ASSERT(is_external_header(u.hdr->thing_word));
+ ASSERT(u.pb != &tmp);
+ erts_deref_node_entry(u.ext->node);
+ break;
+ }
+ }
+#ifdef DEBUG_CLONE
+ if (obj->debug_clone != NULL) {
+ erts_free(ERTS_ALC_T_DB_TERM, obj->debug_clone);
+ obj->debug_clone = NULL;
+ }
+#endif
+}
+
+int db_eq_comp(DbTableCommon* tb, Eterm a, DbTerm* b)
{
ErlOffHeap tmp_offheap;
- tmp_offheap.first = p->first_oh;
- tmp_offheap.overhead = 0;
+ Eterm* allocp;
+ Eterm* hp;
+ Eterm tmp_b;
+ int is_eq;
+
+ ASSERT(tb->compress);
+ hp = allocp = erts_alloc(ERTS_ALC_T_TMP, b->size*sizeof(Eterm));
+ tmp_offheap.first = NULL;
+ tmp_b = db_copy_from_comp(tb, b, &hp, &tmp_offheap);
+ is_eq = eq(a,tmp_b);
erts_cleanup_offheap(&tmp_offheap);
+ erts_free(ERTS_ALC_T_TMP, allocp);
+ return is_eq;
}
-
/*
** Check if object represents a "match" variable
** i.e and atom $N where N is an integer
@@ -2658,7 +3198,7 @@ static DMCRet dmc_one_term(DMCContext *context,
** Ouch, big integer in match variable.
*/
Eterm *save_hp;
- ASSERT(heap->data == heap->def);
+ ASSERT(heap->vars == heap->vars_def);
sz = sz2 = sz3 = 0;
for (j = 0; j < context->num_match; ++j) {
sz += size_object(context->matchexpr[j]);
@@ -2696,24 +3236,23 @@ static DMCRet dmc_one_term(DMCContext *context,
may be atoms that changed */
context->matchexpr[j] = context->copy->mem[j];
}
- heap->data = erts_alloc(ERTS_ALC_T_DB_MS_CMPL_HEAP,
- heap->size*sizeof(unsigned));
- sys_memset(heap->data, 0,
- heap->size * sizeof(unsigned));
+ heap->vars = erts_alloc(ERTS_ALC_T_DB_MS_CMPL_HEAP,
+ heap->size*sizeof(DMCVariable));
+ sys_memset(heap->vars, 0, heap->size * sizeof(DMCVariable));
DMC_CLEAR(*stack);
/*DMC_PUSH(*stack,NIL);*/
DMC_CLEAR(*text);
return retRestart;
}
- if (heap->data[n]) { /* already bound ? */
+ if (heap->vars[n].is_bound) {
DMC_PUSH(*text,matchCmp);
DMC_PUSH(*text,n);
} else { /* Not bound, bind! */
- if (n >= heap->used)
- heap->used = n + 1;
+ if (n >= heap->vars_used)
+ heap->vars_used = n + 1;
DMC_PUSH(*text,matchBind);
DMC_PUSH(*text,n);
- heap->data[n] = 1;
+ heap->vars[n].is_bound = 1;
}
} else if (c == am_Underscore) {
DMC_PUSH(*text, matchSkip);
@@ -2738,6 +3277,8 @@ static DMCRet dmc_one_term(DMCContext *context,
DMC_PUSH(*stack, c);
break;
case (_TAG_HEADER_REF >> _TAG_PRIMARY_SIZE):
+ {
+ Eterm* ref_val = internal_ref_val(c);
DMC_PUSH(*text, matchEqRef);
#if HALFWORD_HEAP
{
@@ -2745,25 +3286,27 @@ static DMCRet dmc_one_term(DMCContext *context,
UWord u;
Uint t[2];
} fiddle;
- ASSERT(thing_arityval(*internal_ref_val(c)) == 3);
- fiddle.t[0] = *internal_ref_val(c);
- fiddle.t[1] = (Uint) internal_ref_val(c)[1];
+ ASSERT(thing_arityval(ref_val[0]) == 3);
+ fiddle.t[0] = ref_val[0];
+ fiddle.t[1] = ref_val[1];
DMC_PUSH(*text, fiddle.u);
- fiddle.t[0] = (Uint) internal_ref_val(c)[2];
- fiddle.t[1] = (Uint) internal_ref_val(c)[3];
+ fiddle.t[0] = ref_val[2];
+ fiddle.t[1] = ref_val[3];
DMC_PUSH(*text, fiddle.u);
}
#else
- n = thing_arityval(*internal_ref_val(c));
- DMC_PUSH(*text, *internal_ref_val(c));
- for (i = 1; i <= n; ++i) {
- DMC_PUSH(*text, (Uint) internal_ref_val(c)[i]);
+ n = thing_arityval(ref_val[0]);
+ for (i = 0; i <= n; ++i) {
+ DMC_PUSH(*text, ref_val[i]);
}
#endif
break;
+ }
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
- n = thing_arityval(*big_val(c));
+ {
+ Eterm* bval = big_val(c);
+ n = thing_arityval(bval[0]);
DMC_PUSH(*text, matchEqBig);
#if HALFWORD_HEAP
{
@@ -2772,13 +3315,13 @@ static DMCRet dmc_one_term(DMCContext *context,
Uint t[2];
} fiddle;
ASSERT(n >= 1);
- fiddle.t[0] = *big_val(c);
- fiddle.t[1] = big_val(c)[1];
+ fiddle.t[0] = bval[0];
+ fiddle.t[1] = bval[1];
DMC_PUSH(*text, fiddle.u);
for (i = 2; i <= n; ++i) {
- fiddle.t[0] = big_val(c)[i];
+ fiddle.t[0] = bval[i];
if (++i <= n) {
- fiddle.t[1] = big_val(c)[i];
+ fiddle.t[1] = bval[i];
} else {
fiddle.t[1] = (Uint) 0;
}
@@ -2786,12 +3329,12 @@ static DMCRet dmc_one_term(DMCContext *context,
}
}
#else
- DMC_PUSH(*text, *big_val(c));
- for (i = 1; i <= n; ++i) {
- DMC_PUSH(*text, (Uint) big_val(c)[i]);
+ for (i = 0; i <= n; ++i) {
+ DMC_PUSH(*text, (Uint) bval[i]);
}
#endif
break;
+ }
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
DMC_PUSH(*text,matchEqFloat);
#if HALFWORD_HEAP
@@ -2924,7 +3467,6 @@ static DMCRet dmc_list(DMCContext *context,
DMC_PUSH(*text, matchConsB);
}
--context->stack_used; /* Two objects on stack becomes one */
- context->eheap_need += 2;
return retOk;
}
@@ -2983,7 +3525,6 @@ static DMCRet dmc_tuple(DMCContext *context,
DMC_PUSH(*text, matchMkTuple);
DMC_PUSH(*text, nelems);
context->stack_used -= (nelems - 1);
- context->eheap_need += (nelems + 1);
*constant = 0;
return retOk;
}
@@ -3001,9 +3542,6 @@ static DMCRet dmc_whole_expression(DMCContext *context,
} else {
ASSERT(is_tuple(context->matchexpr
[context->current_match]));
- context->eheap_need +=
- arityval(*(tuple_val(context->matchexpr
- [context->current_match]))) * 2;
DMC_PUSH(*text, matchPushArrayAsList);
}
} else {
@@ -3016,6 +3554,41 @@ static DMCRet dmc_whole_expression(DMCContext *context,
return retOk;
}
+/* Figure out which PushV instruction to use.
+*/
+static void dmc_add_pushv_variant(DMCContext *context, DMCHeap *heap,
+ DMC_STACK_TYPE(UWord) *text, Uint n)
+{
+ DMCVariable* v = &heap->vars[n];
+ MatchOps instr = matchPushV;
+
+ ASSERT(n < heap->vars_used && v->is_bound);
+ if (context->is_guard) {
+ #if HALFWORD_HEAP
+ if (!v->first_guard_label) {
+ v->first_guard_label = DMC_STACK_NUM(*text);
+ ASSERT(v->first_guard_label);
+ instr = matchPushVGuard; /* may be changed to PushVResult below */
+ }
+ #endif
+ }
+ else { /* body */
+ #if HALFWORD_HEAP
+ if (v->first_guard_label) {
+ /* Avoid double-copy, copy to result heap at first encounter in guard */
+ DMC_POKE(*text, v->first_guard_label, matchPushVResult);
+ v->is_in_body = 1;
+ }
+ #endif
+ if (!v->is_in_body) {
+ instr = matchPushVResult;
+ v->is_in_body = 1;
+ }
+ }
+ DMC_PUSH(*text, instr);
+ DMC_PUSH(*text, n);
+}
+
static DMCRet dmc_variable(DMCContext *context,
DMCHeap *heap,
DMC_STACK_TYPE(UWord) *text,
@@ -3023,13 +3596,13 @@ static DMCRet dmc_variable(DMCContext *context,
int *constant)
{
Uint n = db_is_variable(t);
- ASSERT(n >= 0);
- if (n >= heap->used)
- RETURN_VAR_ERROR("Variable $%d is unbound.", n, context, *constant);
- if (heap->data[n] == 0U)
+
+ if (n >= heap->vars_used || !heap->vars[n].is_bound) {
RETURN_VAR_ERROR("Variable $%d is unbound.", n, context, *constant);
- DMC_PUSH(*text, matchPushV);
- DMC_PUSH(*text, n);
+ }
+
+ dmc_add_pushv_variant(context, heap, text, n);
+
++context->stack_used;
if (context->stack_used > context->stack_need)
context->stack_need = context->stack_used;
@@ -3048,10 +3621,9 @@ static DMCRet dmc_all_bindings(DMCContext *context,
DMC_PUSH(*text, matchPushC);
DMC_PUSH(*text, NIL);
- for (i = heap->used - 1; i >= 0; --i) {
- if (heap->data[i]) {
- DMC_PUSH(*text, matchPushV);
- DMC_PUSH(*text, i);
+ for (i = heap->vars_used - 1; i >= 0; --i) {
+ if (heap->vars[i].is_bound) {
+ dmc_add_pushv_variant(context, heap, text, i);
DMC_PUSH(*text, matchConsB);
heap_used += 2;
}
@@ -3059,7 +3631,6 @@ static DMCRet dmc_all_bindings(DMCContext *context,
++context->stack_used;
if ((context->stack_used + 1) > context->stack_need)
context->stack_need = (context->stack_used + 1);
- context->eheap_need += heap_used;
*constant = 0;
return retOk;
}
@@ -3462,10 +4033,6 @@ static DMCRet dmc_get_seq_token(DMCContext *context,
*constant = 0;
DMC_PUSH(*text, matchGetSeqToken);
- context->eheap_need += (6 /* A 5-tuple is built */
- + EXTERNAL_THING_HEAD_SIZE + 2 /* Sender can
- be an external
- pid */);
if (++context->stack_used > context->stack_need)
context->stack_need = context->stack_used;
return retOk;
@@ -3762,7 +4329,6 @@ static DMCRet dmc_caller(DMCContext *context,
}
*constant = 0;
DMC_PUSH(*text, matchCaller); /* Creates binary */
- context->eheap_need += 4; /* A 3-tuple is built */
if (++context->stack_used > context->stack_need)
context->stack_need = context->stack_used;
return retOk;
@@ -4360,7 +4926,8 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace)
}
save_cp = p->cp;
p->cp = NULL;
- res = erts_match_set_run(p, mps, arr, n, &ret_flags);
+ res = erts_match_set_run(p, mps, arr, n,
+ ERTS_PAM_COPY_RESULT, &ret_flags);
p->cp = save_cp;
} else {
n = 0;
@@ -4373,11 +4940,10 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace)
if (is_non_value(res)) {
res = am_false;
}
- sz = size_object(res);
+ sz = 0;
if (ret_flags & MATCH_SET_EXCEPTION_TRACE) sz += 2;
if (ret_flags & MATCH_SET_RETURN_TRACE) sz += 2;
hp = HAlloc(p, 5 + sz);
- res = copy_struct(res, sz, &hp, &MSO(p));
flg = NIL;
if (ret_flags & MATCH_SET_EXCEPTION_TRACE) {
flg = CONS(hp, am_exception_trace, flg);
@@ -4404,12 +4970,67 @@ static Eterm seq_trace_fake(Process *p, Eterm arg1)
}
return result;
}
-
+
+DbTerm* db_alloc_tmp_uncompressed(DbTableCommon* tb, DbTerm* org)
+{
+ ErlOffHeap tmp_offheap;
+ DbTerm* res = erts_alloc(ERTS_ALC_T_TMP,
+ sizeof(DbTerm) + org->size*sizeof(Eterm));
+ Eterm* hp = res->tpl;
+ tmp_offheap.first = NULL;
+ db_copy_from_comp(tb, org, &hp, &tmp_offheap);
+ res->first_oh = tmp_offheap.first;
+ res->size = org->size;
+#ifdef DEBUG_CLONE
+ res->debug_clone = NULL;
+#endif
+ return res;
+}
+
+void db_free_tmp_uncompressed(DbTerm* obj)
+{
+ ErlOffHeap off_heap;
+ off_heap.first = obj->first_oh;
+ erts_cleanup_offheap(&off_heap);
+#ifdef DEBUG_CLONE
+ ASSERT(obj->debug_clone == NULL);
+#endif
+ erts_free(ERTS_ALC_T_TMP, obj);
+}
+
+Eterm db_match_dbterm(DbTableCommon* tb, Process* c_p, Binary* bprog,
+ int all, DbTerm* obj, Eterm** hpp, Uint extra)
+{
+ Uint32 dummy;
+ Eterm* base;
+ Eterm res;
+
+ if (tb->compress) {
+ obj = db_alloc_tmp_uncompressed(tb, obj);
+ base = NULL;
+ }
+ else base = HALFWORD_HEAP ? obj->tpl : NULL;
+
+ res = db_prog_match(c_p, bprog, make_tuple_rel(obj->tpl,base), base, NULL, 0,
+ ERTS_PAM_COPY_RESULT|ERTS_PAM_CONTIGUOUS_TUPLE, &dummy);
+
+ if (is_value(res) && hpp!=NULL) {
+ *hpp = HAlloc(c_p, extra);
+ }
+
+ if (tb->compress) {
+ db_free_tmp_uncompressed(obj);
+ }
+ return res;
+}
+
+
#ifdef DMC_DEBUG
+
/*
** Disassemble match program
*/
-static void db_match_dis(Binary *bp)
+void db_match_dis(Binary *bp)
{
MatchProg *prog = Binary2MatchProg(bp);
UWord *t = prog->text;
@@ -4624,6 +5245,18 @@ static void db_match_dis(Binary *bp)
++t;
erts_printf("PushV\t%bpu\n", n);
break;
+ #if HALFWORD_HEAP
+ case matchPushVGuard:
+ n = (Uint) *++t;
+ ++t;
+ erts_printf("PushVGuard\t%bpu\n", n);
+ break;
+ #endif
+ case matchPushVResult:
+ n = (Uint) *++t;
+ ++t;
+ erts_printf("PushVResult\t%bpu\n", n);
+ break;
case matchTrue:
++t;
erts_printf("True\n");
@@ -4734,7 +5367,6 @@ static void db_match_dis(Binary *bp)
erts_printf("}\n");
erts_printf("num_bindings: %d\n", prog->num_bindings);
erts_printf("heap_size: %bpu\n", prog->heap_size);
- erts_printf("eheap_offset: %bpu\n", prog->eheap_offset);
erts_printf("stack_offset: %bpu\n", prog->stack_offset);
erts_printf("text: 0x%08x\n", (unsigned long) prog->text);
erts_printf("stack_size: %d (words)\n", prog->heap_size-prog->stack_offset);
diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h
index 0f333e8b34..bb1751d309 100644
--- a/erts/emulator/beam/erl_db_util.h
+++ b/erts/emulator/beam/erl_db_util.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -52,22 +52,27 @@
is broken.*/
#define DB_ERROR_UNSPEC -10 /* Unspecified error */
+/*#define DEBUG_CLONE*/
/*
* A datatype for a database entry stored out of a process heap
*/
typedef struct db_term {
struct erl_off_heap_header* first_oh; /* Off heap data for term. */
- Uint size; /* Size of term in "words" */
- Eterm tpl[1]; /* Untagged "constant pointer" to top tuple */
- /* (assumed to be first in buffer) */
+ Uint size; /* Heap size of term in "words" */
+#ifdef DEBUG_CLONE
+ Eterm* debug_clone; /* An uncompressed copy */
+#endif
+ Eterm tpl[1]; /* Term data. Top tuple always first */
+
+ /* Compression: is_immed and key element are uncompressed.
+ Compressed elements are stored in external format after each other
+ last in dbterm. The top tuple elements contains byte offsets, to
+ the start of the data, tagged as headers.
+ The allocated size of the dbterm in bytes is stored at tpl[arity+1].
+ */
} DbTerm;
-/* "Assign" a value to DbTerm.tpl */
-#define DBTERM_SET_TPL(dbtermPtr,tplPtr) ASSERT((tplPtr)==(dbtermPtr->tpl))
-/* Get start of term buffer */
-#define DBTERM_BUF(dbtermPtr) ((dbtermPtr)->tpl)
-
union db_table;
typedef union db_table DbTable;
@@ -81,6 +86,9 @@ typedef struct {
Uint new_size;
int mustResize;
void* lck;
+#if HALFWORD_HEAP
+ unsigned char* abs_vec; /* [i] true if dbterm->tpl[i] is absolute Eterm */
+#endif
} DbUpdateHandle;
@@ -186,6 +194,12 @@ typedef struct db_table_method
} DbTableMethod;
+typedef struct db_fixation {
+ Eterm pid;
+ Uint counter;
+ struct db_fixation *next;
+} DbFixation;
+
/*
* This structure contains data for all different types of database
* tables. Note that these fields must match the same fields
@@ -194,16 +208,8 @@ typedef struct db_table_method
* operations may be the same on different types of tables.
*/
-typedef struct db_fixation {
- Eterm pid;
- Uint counter;
- struct db_fixation *next;
-} DbFixation;
-
-
typedef struct db_table_common {
- erts_refc_t ref;
- erts_refc_t fixref; /* fixation counter */
+ erts_refc_t ref; /* fixation counter and delete counter */
#ifdef ERTS_SMP
erts_smp_rwmtx_t rwlock; /* rw lock on table */
erts_smp_mtx_t fixlock; /* Protects fixations,megasec,sec,microsec */
@@ -226,6 +232,7 @@ typedef struct db_table_common {
Uint32 status; /* bit masks defined below */
int slot; /* slot index in meta_main_tab */
int keypos; /* defaults to 1 */
+ int compress;
} DbTableCommon;
/* These are status bit patterns */
@@ -248,23 +255,70 @@ typedef struct db_table_common {
(DB_BAG | DB_SET | DB_DUPLICATE_BAG)))
#define IS_TREE_TABLE(Status) (!!((Status) & \
DB_ORDERED_SET))
-#define NFIXED(T) (erts_refc_read(&(T)->common.fixref,0))
+#define NFIXED(T) (erts_refc_read(&(T)->common.ref,0))
#define IS_FIXED(T) (NFIXED(T) != 0)
-Eterm erts_ets_copy_object(Eterm, Process*);
+/*
+ * tplp is an untagged pointer to a tuple we know is large enough
+ * and dth is a pointer to a DbTableHash.
+ */
+#define GETKEY(dth, tplp) (*((tplp) + ((DbTableCommon*)(dth))->keypos))
+
+
+ERTS_GLB_INLINE Eterm db_copy_key(Process* p, DbTable* tb, DbTerm* obj);
+Eterm db_copy_from_comp(DbTableCommon* tb, DbTerm* bp, Eterm** hpp,
+ ErlOffHeap* off_heap);
+int db_eq_comp(DbTableCommon* tb, Eterm a, DbTerm* b);
+DbTerm* db_alloc_tmp_uncompressed(DbTableCommon* tb, DbTerm* org);
+
+ERTS_GLB_INLINE Eterm db_copy_object_from_ets(DbTableCommon* tb, DbTerm* bp,
+ Eterm** hpp, ErlOffHeap* off_heap);
+ERTS_GLB_INLINE int db_eq(DbTableCommon* tb, Eterm a, DbTerm* b);
+Wterm db_do_read_element(DbUpdateHandle* handle, Sint position);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+
+ERTS_GLB_INLINE Eterm db_copy_key(Process* p, DbTable* tb, DbTerm* obj)
+{
+ Eterm key = GETKEY(tb, obj->tpl);
+ if IS_CONST(key) return key;
+ else {
+ Uint size = size_object_rel(key, obj->tpl);
+ Eterm* hp = HAlloc(p, size);
+ Eterm res = copy_struct_rel(key, size, &hp, &MSO(p), obj->tpl, NULL);
+ ASSERT(eq_rel(res,NULL,key,obj->tpl));
+ return res;
+ }
+}
+
+ERTS_GLB_INLINE Eterm db_copy_object_from_ets(DbTableCommon* tb, DbTerm* bp,
+ Eterm** hpp, ErlOffHeap* off_heap)
+{
+ if (tb->compress) {
+ return db_copy_from_comp(tb, bp, hpp, off_heap);
+ }
+ else {
+ return copy_shallow_rel(bp->tpl, bp->size, hpp, off_heap, bp->tpl);
+ }
+}
+
+ERTS_GLB_INLINE int db_eq(DbTableCommon* tb, Eterm a, DbTerm* b)
+{
+ if (!tb->compress) {
+ return eq_rel(a, NULL, make_tuple_rel(b->tpl,b->tpl), b->tpl);
+ }
+ else {
+ return db_eq_comp(tb, a, b);
+ }
+}
+
+#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
-/* optimised version of copy_object (normal case? atomic object) */
-#define COPY_OBJECT(obj, p, objp) \
- if (IS_CONST(obj)) { *(objp) = (obj); } \
- else { *objp = erts_ets_copy_object(obj, p); }
#define DB_READ (DB_PROTECTED|DB_PUBLIC)
#define DB_WRITE DB_PUBLIC
#define DB_INFO (DB_PROTECTED|DB_PUBLIC|DB_PRIVATE)
-/* tb is an DbTableCommon and obj is an Eterm (tagged) */
-#define TERM_GETKEY(tb, obj) db_getkey((tb)->common.keypos, (obj))
-
#define ONLY_WRITER(P,T) (((T)->common.status & (DB_PRIVATE|DB_PROTECTED)) \
&& (T)->common.owner == (P)->id)
@@ -277,15 +331,19 @@ Eterm db_set_trace_control_word_1(Process *p, Eterm val);
void db_initialize_util(void);
Eterm db_getkey(int keypos, Eterm obj);
-void db_free_term_data(DbTerm* p);
-void* db_get_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj);
+void db_cleanup_offheap_comp(DbTerm* p);
+void db_free_term(DbTable *tb, void* basep, Uint offset);
+void* db_store_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj);
+void* db_store_term_comp(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj);
+Eterm db_copy_element_from_ets(DbTableCommon* tb, Process* p, DbTerm* obj,
+ Uint pos, Eterm** hpp, Uint extra);
int db_has_variable(Eterm obj);
int db_is_variable(Eterm obj);
void db_do_update_element(DbUpdateHandle* handle,
Sint position,
Eterm newval);
-void db_finalize_update_element(DbUpdateHandle* handle);
-Eterm db_add_counter(Eterm** hpp, Eterm counter, Eterm incr);
+void db_finalize_resize(DbUpdateHandle* handle, Uint offset);
+Eterm db_add_counter(Eterm** hpp, Wterm counter, Eterm incr);
Eterm db_match_set_lint(Process *p, Eterm matchexpr, Uint flags);
Binary *db_match_set_compile(Process *p, Eterm matchexpr,
Uint flags);
@@ -302,7 +360,6 @@ typedef struct match_prog {
struct erl_heap_fragment *saved_program_buf;
Eterm saved_program;
Uint heap_size; /* size of: heap + eheap + stack */
- Uint eheap_offset;
Uint stack_offset;
#ifdef DMC_DEBUG
UWord* prog_end; /* End of program */
@@ -367,8 +424,15 @@ Binary *db_match_compile(Eterm *matchexpr, Eterm *guards,
Uint flags,
DMCErrInfo *err_info);
/* Returns newly allocated MatchProg binary with refc == 0*/
-Eterm db_prog_match(Process *p, Binary *prog, Eterm term, Eterm *termp, int arity,
+
+Eterm db_match_dbterm(DbTableCommon* tb, Process* c_p, Binary* bprog,
+ int all, DbTerm* obj, Eterm** hpp, Uint extra);
+
+Eterm db_prog_match(Process *p, Binary *prog, Eterm term, Eterm* base,
+ Eterm *termp, int arity,
+ enum erts_pam_run_flags in_flags,
Uint32 *return_flags /* Zeroed on enter */);
+
/* returns DB_ERROR_NONE if matches, 1 if not matches and some db error on
error. */
DMCErrInfo *db_new_dmc_err_info(void);
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index 9733c0e5b5..13a73e01bb 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -150,6 +150,27 @@ typedef struct {
#define ERL_DRV_FLAG_SOFT_BUSY (1 << 1)
/*
+ * Integer types
+ */
+
+typedef unsigned long ErlDrvTermData;
+typedef unsigned long ErlDrvUInt;
+typedef signed long ErlDrvSInt;
+
+#if defined(__WIN32__)
+typedef unsigned __int64 ErlDrvUInt64;
+typedef __int64 ErlDrvSInt64;
+#elif SIZEOF_LONG == 8
+typedef unsigned long ErlDrvUInt64;
+typedef long ErlDrvSInt64;
+#elif SIZEOF_LONG_LONG == 8
+typedef unsigned long long ErlDrvUInt64;
+typedef long long ErlDrvSInt64;
+#else
+#error No 64-bit integer type
+#endif
+
+/*
* A binary as seen in a driver. Note that a binary should never be
* altered by the driver when it has been sent to Erlang.
*/
@@ -179,26 +200,6 @@ struct erl_drv_event_data {
#endif
typedef struct erl_drv_event_data *ErlDrvEventData; /* Event data */
-/*
- * Used in monitors...
- */
-typedef unsigned long ErlDrvTermData;
-typedef unsigned long ErlDrvUInt;
-typedef signed long ErlDrvSInt;
-
-#if defined(__WIN32__)
-typedef unsigned __int64 ErlDrvUInt64;
-typedef __int64 ErlDrvSInt64;
-#elif SIZEOF_LONG == 8
-typedef unsigned long ErlDrvUInt64;
-typedef long ErlDrvSInt64;
-#elif SIZEOF_LONG_LONG == 8
-typedef unsigned long long ErlDrvUInt64;
-typedef long long ErlDrvSInt64;
-#else
-#error No 64-bit integer type
-#endif
-
/*
* A driver monitor
*/
@@ -394,9 +395,9 @@ EXTERN int driver_exit (ErlDrvPort port, int err);
EXTERN ErlDrvPDL driver_pdl_create(ErlDrvPort);
EXTERN void driver_pdl_lock(ErlDrvPDL);
EXTERN void driver_pdl_unlock(ErlDrvPDL);
-EXTERN long driver_pdl_get_refc(ErlDrvPDL);
-EXTERN long driver_pdl_inc_refc(ErlDrvPDL);
-EXTERN long driver_pdl_dec_refc(ErlDrvPDL);
+EXTERN ErlDrvSInt driver_pdl_get_refc(ErlDrvPDL);
+EXTERN ErlDrvSInt driver_pdl_inc_refc(ErlDrvPDL);
+EXTERN ErlDrvSInt driver_pdl_dec_refc(ErlDrvPDL);
/*
* Process monitors
@@ -432,9 +433,9 @@ EXTERN ErlDrvBinary* driver_realloc_binary(ErlDrvBinary *bin, int size);
EXTERN void driver_free_binary(ErlDrvBinary *bin);
/* Referenc count on driver binaries */
-EXTERN long driver_binary_get_refc(ErlDrvBinary *dbp);
-EXTERN long driver_binary_inc_refc(ErlDrvBinary *dbp);
-EXTERN long driver_binary_dec_refc(ErlDrvBinary *dbp);
+EXTERN ErlDrvSInt driver_binary_get_refc(ErlDrvBinary *dbp);
+EXTERN ErlDrvSInt driver_binary_inc_refc(ErlDrvBinary *dbp);
+EXTERN ErlDrvSInt driver_binary_dec_refc(ErlDrvBinary *dbp);
/* Allocation interface */
EXTERN void *driver_alloc(size_t size);
diff --git a/erts/emulator/beam/erl_drv_thread.c b/erts/emulator/beam/erl_drv_thread.c
index d42820ddf3..39bbe9633b 100644
--- a/erts/emulator/beam/erl_drv_thread.c
+++ b/erts/emulator/beam/erl_drv_thread.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2007-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2007-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -24,6 +24,10 @@
#include "global.h"
#include <string.h>
+#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
+#define __DARWIN__ 1
+#endif
+
#define ERL_DRV_THR_OPTS_SIZE(LAST_FIELD) \
(((size_t) &((ErlDrvThreadOpts *) 0)->LAST_FIELD) \
+ sizeof(((ErlDrvThreadOpts *) 0)->LAST_FIELD))
@@ -528,7 +532,7 @@ erl_drv_tsd_get(ErlDrvTSDKey key)
if (!dtid)
return NULL;
#endif
- if (ERL_DRV_TSD_LEN__ < key)
+ if (ERL_DRV_TSD_LEN__ <= key)
return NULL;
return ERL_DRV_TSD__[key];
}
@@ -692,3 +696,57 @@ erl_drv_thread_join(ErlDrvTid tid, void **respp)
#endif
}
+#if defined(__DARWIN__) && defined(USE_THREADS) && defined(ERTS_SMP)
+extern int erts_darwin_main_thread_pipe[2];
+extern int erts_darwin_main_thread_result_pipe[2];
+
+
+int
+erl_drv_stolen_main_thread_join(ErlDrvTid tid, void **respp)
+{
+ void *dummy;
+ void **x;
+ if (respp == NULL)
+ x = &dummy;
+ else
+ x = respp;
+ read(erts_darwin_main_thread_result_pipe[0],x,sizeof(void *));
+ return 0;
+}
+
+int
+erl_drv_steal_main_thread(char *name,
+ ErlDrvTid *tid,
+ void* (*func)(void*),
+ void* arg,
+ ErlDrvThreadOpts *opts)
+{
+ char buff[sizeof(void* (*)(void*)) + sizeof(void *)];
+ int buff_sz = sizeof(void* (*)(void*)) + sizeof(void *);
+ /*struct ErlDrvTid_ *dtid;
+
+ dtid = erts_alloc_fnf(ERTS_ALC_T_DRV_TID,
+ (sizeof(struct ErlDrvTid_)
+ + (name ? sys_strlen(name) + 1 : 0)));
+ if (!dtid)
+ return ENOMEM;
+ memset(dtid,0,sizeof(ErlDrvTid_));
+ dtid->tid = (void * ) -1;
+ dtid->drv_thr = 1;
+ dtid->func = func;
+ dtid->arg = arg;
+ dtid->tsd = NULL;
+ dtid->tsd_len = 0;
+ dtid->name = no_name;
+ *tid = (ErlDrvTid) dtid;
+ */
+ *tid = NULL;
+ /* Ignore options and name... */
+
+ memcpy(buff,&func,sizeof(void* (*)(void*)));
+ memcpy(buff + sizeof(void* (*)(void*)),&arg,sizeof(void *));
+ write(erts_darwin_main_thread_pipe[1],buff,buff_sz);
+ return 0;
+}
+
+#endif
diff --git a/erts/emulator/beam/erl_fun.c b/erts/emulator/beam/erl_fun.c
index 84869f12d6..88947b5536 100644
--- a/erts/emulator/beam/erl_fun.c
+++ b/erts/emulator/beam/erl_fun.c
@@ -97,7 +97,7 @@ erts_put_fun_entry(Eterm mod, int uniq, int index)
{
ErlFunEntry template;
ErlFunEntry* fe;
- long refc;
+ erts_aint_t refc;
ASSERT(is_atom(mod));
template.old_uniq = uniq;
template.old_index = index;
@@ -119,7 +119,7 @@ erts_put_fun_entry2(Eterm mod, int old_uniq, int old_index,
{
ErlFunEntry template;
ErlFunEntry* fe;
- long refc;
+ erts_aint_t refc;
ASSERT(is_atom(mod));
template.old_uniq = old_uniq;
@@ -157,7 +157,7 @@ erts_get_fun_entry(Eterm mod, int uniq, int index)
erts_fun_read_lock();
ret = (ErlFunEntry *) hash_get(&erts_fun_table, (void*) &template);
if (ret) {
- long refc = erts_refc_inctest(&ret->refc, 1);
+ erts_aint_t refc = erts_refc_inctest(&ret->refc, 1);
if (refc < 2) /* Pending delete */
erts_refc_inc(&ret->refc, 1);
}
@@ -257,7 +257,7 @@ erts_dump_fun_entries(int to, void *to_arg)
#ifdef HIPE
erts_print(to, to_arg, "Native_address: %p\n", fe->native_address);
#endif
- erts_print(to, to_arg, "Refc: %d\n", erts_refc_read(&fe->refc, 1));
+ erts_print(to, to_arg, "Refc: %ld\n", erts_refc_read(&fe->refc, 1));
b = b->next;
}
}
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 0f4d2a2ef9..2aa932e7d1 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -2471,7 +2471,7 @@ erts_check_off_heap2(Process *p, Eterm *htop)
old = 0;
for (u.hdr = MSO(p).first; u.hdr; u.hdr = u.hdr->next) {
- long refc;
+ erts_aint_t refc;
switch (thing_subtag(u.hdr->thing_word)) {
case REFC_BINARY_SUBTAG:
refc = erts_refc_read(&u.pb->val->refc, 1);
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 4ae656a3ad..0a57eb6d88 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -41,6 +41,7 @@
#include "erl_printf_term.h"
#include "erl_misc_utils.h"
#include "packet_parser.h"
+#include "erl_cpu_topology.h"
#ifdef HIPE
#include "hipe_mode_switch.h" /* for hipe_mode_switch_init() */
@@ -63,6 +64,8 @@ extern void ConNormalExit(void);
extern void ConWaitForExit(void);
#endif
+static void erl_init(int ncpu);
+
#define ERTS_MIN_COMPAT_REL 7
#ifdef ERTS_SMP
@@ -76,9 +79,6 @@ int erts_initialized = 0;
static erts_tid_t main_thread;
#endif
-erts_cpu_info_t *erts_cpuinfo;
-
-int erts_reader_groups;
int erts_use_sender_punish;
/*
@@ -100,7 +100,7 @@ int erts_backtrace_depth; /* How many functions to show in a backtrace
int erts_async_max_threads; /* number of threads for async support */
int erts_async_thread_suggested_stack_size;
-erts_smp_atomic_t erts_max_gen_gcs;
+erts_smp_atomic32_t erts_max_gen_gcs;
Eterm erts_error_logger_warnings; /* What to map warning logs to, am_error,
am_info or am_warning, am_error is
@@ -111,7 +111,6 @@ int erts_compat_rel;
static int use_multi_run_queue;
static int no_schedulers;
static int no_schedulers_online;
-static int max_reader_groups;
#ifdef DEBUG
Uint32 verbose; /* See erl_debug.h for information about verbose */
@@ -230,18 +229,18 @@ void erl_error(char *fmt, va_list args)
erts_vfprintf(stderr, fmt, args);
}
-static void early_init(int *argc, char **argv);
+static int early_init(int *argc, char **argv);
void
erts_short_init(void)
{
- early_init(NULL, NULL);
- erl_init();
+ int ncpu = early_init(NULL, NULL);
+ erl_init(ncpu);
erts_initialized = 1;
}
-void
-erl_init(void)
+static void
+erl_init(int ncpu)
{
init_benchmarking();
@@ -251,12 +250,13 @@ erl_init(void)
erts_init_monitors();
erts_init_gc();
- init_time();
- erts_init_process();
+ erts_init_time();
+ erts_init_sys_common_misc();
+ erts_init_process(ncpu);
erts_init_scheduling(use_multi_run_queue,
no_schedulers,
no_schedulers_online);
-
+ erts_init_cpu_topology(); /* Must be after init_scheduling */
H_MIN_SIZE = erts_next_heap_size(H_MIN_SIZE, 0);
BIN_VH_MIN_SIZE = erts_next_heap_size(BIN_VH_MIN_SIZE, 0);
@@ -289,7 +289,7 @@ erl_init(void)
erts_delay_trap = erts_export_put(am_erlang, am_delay_trap, 2);
erts_late_init_process();
#if HAVE_ERTS_MSEG
- erts_mseg_late_init(); /* Must be after timer (init_time()) and thread
+ erts_mseg_late_init(); /* Must be after timer (erts_init_time()) and thread
initializations */
#endif
#ifdef HIPE
@@ -323,7 +323,7 @@ init_shared_memory(int argc, char **argv)
#endif
global_gen_gcs = 0;
- global_max_gen_gcs = erts_smp_atomic_read(&erts_max_gen_gcs);
+ global_max_gen_gcs = (Uint16) erts_smp_atomic32_read(&erts_max_gen_gcs);
global_gc_flags = erts_default_process_flags;
erts_global_offheap.mso = NULL;
@@ -535,7 +535,8 @@ void erts_usage(void)
erts_fprintf(stderr, "-W<i|w> set error logger warnings mapping,\n");
erts_fprintf(stderr, " see error_logger documentation for details\n");
-
+ erts_fprintf(stderr, "-zdbbl size set the distribution buffer busy limit in kilobytes\n");
+ erts_fprintf(stderr, " valid range is [1-%d]\n", INT_MAX/1024);
erts_fprintf(stderr, "\n");
erts_fprintf(stderr, "Note that if the emulator is started with erlexec (typically\n");
erts_fprintf(stderr, "from the erl script), these flags should be specified with +.\n");
@@ -587,7 +588,7 @@ static void ethr_ll_free(void *ptr)
#endif
-static void
+static int
early_init(int *argc, char **argv) /*
* Only put things here which are
* really important initialize
@@ -600,6 +601,10 @@ early_init(int *argc, char **argv) /*
int ncpuavail;
int schdlrs;
int schdlrs_onln;
+ int max_main_threads;
+ int max_reader_groups;
+ int reader_groups;
+
use_multi_run_queue = 1;
erts_printf_eterm_func = erts_printf_term;
erts_disable_tolerant_timeofday = 0;
@@ -615,13 +620,11 @@ early_init(int *argc, char **argv) /*
erts_use_sender_punish = 1;
- erts_cpuinfo = erts_cpu_info_create();
-
-#ifdef ERTS_SMP
- ncpu = erts_get_cpu_configured(erts_cpuinfo);
- ncpuonln = erts_get_cpu_online(erts_cpuinfo);
- ncpuavail = erts_get_cpu_available(erts_cpuinfo);
-#else
+ erts_pre_early_init_cpu_topology(&max_reader_groups,
+ &ncpu,
+ &ncpuonln,
+ &ncpuavail);
+#ifndef ERTS_SMP
ncpu = 1;
ncpuonln = 1;
ncpuavail = 1;
@@ -648,7 +651,7 @@ early_init(int *argc, char **argv) /*
erts_writing_erl_crash_dump = 0;
#endif
- erts_smp_atomic_init(&erts_max_gen_gcs, (long)((Uint16) -1));
+ erts_smp_atomic32_init(&erts_max_gen_gcs, (erts_aint32_t) ((Uint16) -1));
erts_pre_init_process();
#if defined(USE_THREADS) && !defined(ERTS_SMP)
@@ -664,15 +667,9 @@ early_init(int *argc, char **argv) /*
? ncpuavail
: (ncpuonln > 0 ? ncpuonln : no_schedulers));
-#ifdef ERTS_SMP
- erts_max_main_threads = no_schedulers_online;
-#endif
-
schdlrs = no_schedulers;
schdlrs_onln = no_schedulers_online;
- max_reader_groups = ERTS_MAX_READER_GROUPS;
-
if (argc && argv) {
int i = 1;
while (i < *argc) {
@@ -768,9 +765,13 @@ early_init(int *argc, char **argv) /*
erts_alloc_init(argc, argv, &alloc_opts); /* Handles (and removes)
-M flags. */
-
- erts_early_init_scheduling(); /* Require allocators */
- erts_init_utils(); /* Require allocators */
+ /* Require allocators */
+ erts_early_init_scheduling();
+ erts_init_utils();
+ erts_early_init_cpu_topology(no_schedulers,
+ &max_main_threads,
+ max_reader_groups,
+ &reader_groups);
#ifdef USE_THREADS
{
@@ -784,24 +785,13 @@ early_init(int *argc, char **argv) /*
elid.mem.ll.alloc = ethr_ll_alloc;
elid.mem.ll.realloc = ethr_ll_realloc;
elid.mem.ll.free = ethr_ll_free;
-
-#ifdef ERTS_SMP
- elid.main_threads = erts_max_main_threads;
-#else
- elid.main_threads = 1;
-#endif
- elid.reader_groups = (elid.main_threads > 1
- ? elid.main_threads
- : 0);
- if (max_reader_groups <= 1)
- elid.reader_groups = 0;
- if (elid.reader_groups > max_reader_groups)
- elid.reader_groups = max_reader_groups;
- erts_reader_groups = elid.reader_groups;
+ elid.main_threads = max_main_threads;
+ elid.reader_groups = reader_groups;
erts_thr_late_init(&elid);
}
#endif
+
#ifdef ERTS_ENABLE_LOCK_CHECK
erts_lc_late_init();
#endif
@@ -818,7 +808,10 @@ early_init(int *argc, char **argv) /*
erl_sys_args(argc, argv);
erts_ets_realloc_always_moves = 0;
+ erts_ets_always_compress = 0;
+ erts_dist_buf_busy_limit = ERTS_DE_BUSY_LIMIT;
+ return ncpu;
}
#ifndef ERTS_SMP
@@ -852,8 +845,7 @@ erl_start(int argc, char **argv)
char envbuf[21]; /* enough for any 64-bit integer */
size_t envbufsz;
int async_max_threads = erts_async_max_threads;
-
- early_init(&argc, argv);
+ int ncpu = early_init(&argc, argv);
envbufsz = sizeof(envbuf);
if (erts_sys_getenv(ERL_MAX_ETS_TABLES_ENV, envbuf, &envbufsz) == 0)
@@ -864,7 +856,7 @@ erl_start(int argc, char **argv)
envbufsz = sizeof(envbuf);
if (erts_sys_getenv("ERL_FULLSWEEP_AFTER", envbuf, &envbufsz) == 0) {
Uint16 max_gen_gcs = atoi(envbuf);
- erts_smp_atomic_set(&erts_max_gen_gcs, (long) max_gen_gcs);
+ erts_smp_atomic32_set(&erts_max_gen_gcs, (erts_aint32_t) max_gen_gcs);
}
envbufsz = sizeof(envbuf);
@@ -916,7 +908,27 @@ erl_start(int argc, char **argv)
VERBOSE(DEBUG_SYSTEM,
("using display items %d\n",display_items));
break;
-
+ case 'f':
+ if (!strncmp(argv[i],"-fn",3)) {
+ arg = get_arg(argv[i]+3, argv[i+1], &i);
+ switch (*arg) {
+ case 'u':
+ erts_set_user_requested_filename_encoding(ERL_FILENAME_UTF8);
+ break;
+ case 'l':
+ erts_set_user_requested_filename_encoding(ERL_FILENAME_LATIN1);
+ break;
+ case 'a':
+ erts_set_user_requested_filename_encoding(ERL_FILENAME_UNKNOWN);
+ default:
+ erts_fprintf(stderr, "bad filename encoding %s, can be (l,u or a)\n", arg);
+ erts_usage();
+ }
+ break;
+ } else {
+ erts_fprintf(stderr, "%s unknown flag %s\n", argv[0], argv[i]);
+ erts_usage();
+ }
case 'l':
display_loads++;
break;
@@ -1038,15 +1050,20 @@ erl_start(int argc, char **argv)
break;
case 'e':
- /* set maximum number of ets tables */
- arg = get_arg(argv[i]+2, argv[i+1], &i);
- if (( user_requested_db_max_tabs = atoi(arg) ) < 0) {
- erts_fprintf(stderr, "bad maximum number of ets tables %s\n", arg);
- erts_usage();
+ if (sys_strcmp("c", argv[i]+2) == 0) {
+ erts_ets_always_compress = 1;
+ }
+ else {
+ /* set maximum number of ets tables */
+ arg = get_arg(argv[i]+2, argv[i+1], &i);
+ if (( user_requested_db_max_tabs = atoi(arg) ) < 0) {
+ erts_fprintf(stderr, "bad maximum number of ets tables %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM,
+ ("using maximum number of ets tables %d\n",
+ user_requested_db_max_tabs));
}
- VERBOSE(DEBUG_SYSTEM,
- ("using maximum number of ets tables %d\n",
- user_requested_db_max_tabs));
break;
case 'i':
@@ -1110,7 +1127,7 @@ erl_start(int argc, char **argv)
char *sub_param = argv[i]+2;
if (has_prefix("bt", sub_param)) {
arg = get_arg(sub_param+2, argv[i+1], &i);
- res = erts_init_scheduler_bind_type(arg);
+ res = erts_init_scheduler_bind_type_string(arg);
if (res != ERTS_INIT_SCHED_BIND_TYPE_SUCCESS) {
switch (res) {
case ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED:
@@ -1135,7 +1152,7 @@ erl_start(int argc, char **argv)
}
else if (has_prefix("ct", sub_param)) {
arg = get_arg(sub_param+2, argv[i+1], &i);
- res = erts_init_cpu_topology(arg);
+ res = erts_init_cpu_topology_string(arg);
if (res != ERTS_INIT_CPU_TOPOLOGY_OK) {
switch (res) {
case ERTS_INIT_CPU_TOPOLOGY_INVALID_ID:
@@ -1346,6 +1363,26 @@ erl_start(int argc, char **argv)
}
break;
+ case 'z': {
+ char *sub_param = argv[i]+2;
+ int new_limit;
+
+ if (has_prefix("dbbl", sub_param)) {
+ arg = get_arg(sub_param+4, argv[i+1], &i);
+ new_limit = atoi(arg);
+ if (new_limit < 1 || INT_MAX/1024 < new_limit) {
+ erts_fprintf(stderr, "Invalid dbbl limit: %d\n", new_limit);
+ erts_usage();
+ } else {
+ erts_dist_buf_busy_limit = new_limit*1024;
+ }
+ } else {
+ erts_fprintf(stderr, "bad -z option %s\n", argv[i]);
+ erts_usage();
+ }
+ break;
+ }
+
default:
erts_fprintf(stderr, "%s unknown flag %s\n", argv[0], argv[i]);
erts_usage();
@@ -1386,7 +1423,7 @@ erl_start(int argc, char **argv)
boot_argc = argc - i; /* Number of arguments to init */
boot_argv = &argv[i];
- erl_init();
+ erl_init(ncpu);
init_shared_memory(boot_argc, boot_argv);
load_preloaded();
diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c
index d6138fa4e4..9e18997890 100644
--- a/erts/emulator/beam/erl_lock_check.c
+++ b/erts/emulator/beam/erl_lock_check.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2005-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -128,8 +128,8 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "removed_fd_pre_alloc_lock", NULL },
{ "state_prealloc", NULL },
{ "schdlr_sspnd", NULL },
- { "cpu_bind", NULL },
{ "run_queue", "address" },
+ { "cpu_info", NULL },
{ "pollset", "address" },
#ifdef __WIN32__
{ "pollwaiter", "address" },
@@ -155,7 +155,7 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "alcu_allocator", "index" },
{ "alcu_delayed_free", "index" },
{ "mseg", NULL },
-#ifdef HALFWORD_HEAP
+#if HALFWORD_HEAP
{ "pmmap", NULL },
#endif
#ifdef ERTS_SMP
@@ -177,6 +177,8 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "async_id", NULL },
{ "pix_lock", "address" },
{ "run_queues_lists", NULL },
+ { "misc_aux_work_queue", "index" },
+ { "misc_aux_work_pre_alloc_lock", "address" },
{ "sched_stat", NULL },
{ "run_queue_sleep_list", "address" },
#endif
@@ -978,10 +980,10 @@ erts_lc_trylock_force_busy_flg(erts_lc_lock_t *lck, Uint16 op_flags)
/* We only force busy if a lock order violation would occur
and when on an even millisecond. */
{
- erts_thr_timeval_t time;
- erts_thr_time_now(&time);
+ SysTimeval tv;
+ sys_gettimeofday(&tv);
- if ((time.tv_nsec / 1000000) & 1)
+ if ((tv.tv_usec / 1000) & 1)
return 0;
}
#endif
diff --git a/erts/emulator/beam/erl_lock_count.c b/erts/emulator/beam/erl_lock_count.c
index 239773f366..a36c53560e 100644
--- a/erts/emulator/beam/erl_lock_count.c
+++ b/erts/emulator/beam/erl_lock_count.c
@@ -159,7 +159,7 @@ static char* lock_opt(Uint16 flag) {
}
static void print_lock_x(erts_lcnt_lock_t *lock, Uint16 flag, char *action, char *extra) {
- long int colls, tries, w_state, r_state;
+ erts_aint_t colls, tries, w_state, r_state;
erts_lcnt_lock_stats_t *stats = NULL;
char *type;
@@ -385,7 +385,7 @@ void erts_lcnt_destroy_lock(erts_lcnt_lock_t *lock) {
/* lock */
void erts_lcnt_lock_opt(erts_lcnt_lock_t *lock, Uint16 option) {
- long r_state = 0, w_state = 0;
+ erts_aint_t r_state = 0, w_state = 0;
erts_lcnt_thread_data_t *eltd;
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
@@ -418,7 +418,7 @@ void erts_lcnt_lock_opt(erts_lcnt_lock_t *lock, Uint16 option) {
}
void erts_lcnt_lock(erts_lcnt_lock_t *lock) {
- long w_state;
+ erts_aint_t w_state;
erts_lcnt_thread_data_t *eltd;
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
@@ -471,7 +471,7 @@ void erts_lcnt_lock_post_x(erts_lcnt_lock_t *lock, char *file, unsigned int line
erts_lcnt_time_t time_wait;
erts_lcnt_lock_stats_t *stats;
#ifdef DEBUG
- long flowstate;
+ erts_aint_t flowstate;
#endif
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
@@ -516,8 +516,8 @@ void erts_lcnt_unlock_opt(erts_lcnt_lock_t *lock, Uint16 option) {
void erts_lcnt_unlock(erts_lcnt_lock_t *lock) {
#ifdef DEBUG
- long w_state;
- long flowstate;
+ erts_aint_t w_state;
+ erts_aint_t flowstate;
#endif
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
#ifdef DEBUG
@@ -552,7 +552,7 @@ void erts_lcnt_trylock_opt(erts_lcnt_lock_t *lock, int res, Uint16 option) {
void erts_lcnt_trylock(erts_lcnt_lock_t *lock, int res) {
/* Determine lock_state via res instead of state */
#ifdef DEBUG
- long flowstate;
+ erts_aint_t flowstate;
#endif
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_SUSPEND) return;
if (res != EBUSY) {
diff --git a/erts/emulator/beam/erl_monitors.c b/erts/emulator/beam/erl_monitors.c
index d873c7a701..9751b5d77c 100644
--- a/erts/emulator/beam/erl_monitors.c
+++ b/erts/emulator/beam/erl_monitors.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2004-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2004-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -85,7 +85,7 @@ static ERTS_INLINE int cmp_mon_ref(Eterm ref1, Eterm ref2)
if (is_ref_thing_header(*b2)) {
return 1;
}
- return cmp(ref1,ref2);
+ return CMP(ref1,ref2);
}
#define CP_LINK_VAL(To, Hp, From) \
@@ -380,7 +380,7 @@ int erts_add_link(ErtsLink **root, Uint type, Eterm pid)
state = 1;
*this = create_link(type,pid);
break;
- } else if ((c = cmp(pid,(*this)->pid)) < 0) {
+ } else if ((c = CMP(pid,(*this)->pid)) < 0) {
/* go left */
dstack[dpos++] = DIR_LEFT;
tstack[tpos++] = this;
@@ -415,7 +415,7 @@ erts_add_or_lookup_suspend_monitor(ErtsSuspendMonitor **root, Eterm pid)
state = 1;
res = *this = create_suspend_monitor(pid);
break;
- } else if ((c = cmp(pid,(*this)->pid)) < 0) {
+ } else if ((c = CMP(pid,(*this)->pid)) < 0) {
/* go left */
dstack[dpos++] = DIR_LEFT;
tstack[tpos++] = this;
@@ -453,7 +453,7 @@ ErtsLink *erts_add_or_lookup_link(ErtsLink **root, Uint type, Eterm pid)
*this = create_link(type,pid);
ret = *this;
break;
- } else if ((c = cmp(pid,(*this)->pid)) < 0) {
+ } else if ((c = CMP(pid,(*this)->pid)) < 0) {
/* go left */
dstack[dpos++] = DIR_LEFT;
tstack[tpos++] = this;
@@ -663,7 +663,7 @@ ErtsLink *erts_remove_link(ErtsLink **root, Eterm pid)
for (;;) {
if (!*this) { /* Failure */
return NULL;
- } else if ((c = cmp(pid,(*this)->pid)) < 0) {
+ } else if ((c = CMP(pid,(*this)->pid)) < 0) {
dstack[dpos++] = DIR_LEFT;
tstack[tpos++] = this;
this = &((*this)->left);
@@ -715,7 +715,7 @@ erts_delete_suspend_monitor(ErtsSuspendMonitor **root, Eterm pid)
for (;;) {
if (!*this) { /* Nothing found */
return;
- } else if ((c = cmp(pid,(*this)->pid)) < 0) {
+ } else if ((c = CMP(pid,(*this)->pid)) < 0) {
dstack[dpos++] = DIR_LEFT;
tstack[tpos++] = this;
this = &((*this)->left);
@@ -771,7 +771,7 @@ ErtsLink *erts_lookup_link(ErtsLink *root, Eterm pid)
Sint c;
for (;;) {
- if (root == NULL || (c = cmp(pid,root->pid)) == 0) {
+ if (root == NULL || (c = CMP(pid,root->pid)) == 0) {
return root;
} else if (c < 0) {
root = root->left;
@@ -787,7 +787,7 @@ erts_lookup_suspend_monitor(ErtsSuspendMonitor *root, Eterm pid)
Sint c;
for (;;) {
- if (root == NULL || (c = cmp(pid,root->pid)) == 0) {
+ if (root == NULL || (c = CMP(pid,root->pid)) == 0) {
return root;
} else if (c < 0) {
root = root->left;
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 1dd9c8bd4a..135c6b0ccc 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2009-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2009-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -81,7 +81,6 @@ static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, unsigned need)
static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp)
{
- unsigned frag_sz;
env->hp = hp;
if (env->heap_frag == NULL) {
ASSERT(HEAP_LIMIT(env->proc) == env->hp_end);
@@ -91,14 +90,24 @@ static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* 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);
- env->hp = hp + need;
- env->hp_end = hp + frag_sz;
+ hp = erts_heap_alloc(env->proc, need, MIN_HEAP_FRAG_SZ);
env->heap_frag = MBUF(env->proc);
+ env->hp = hp + need;
+ env->hp_end = env->heap_frag->mem + env->heap_frag->alloc_size;
+
return hp;
}
+#if SIZEOF_LONG != ERTS_SIZEOF_ETERM
+static ERTS_INLINE void ensure_heap(ErlNifEnv* env, unsigned may_need)
+{
+ if (env->hp + may_need > env->hp_end) {
+ alloc_heap_heavy(env, may_need, env->hp);
+ env->hp -= may_need;
+ }
+}
+#endif
+
void erts_pre_nif(ErlNifEnv* env, Process* p, struct erl_module_nif* mod_nif)
{
env->mod_nif = mod_nif;
@@ -564,7 +573,7 @@ int enif_is_identical(Eterm lhs, Eterm rhs)
int enif_compare(Eterm lhs, Eterm rhs)
{
- return cmp(lhs,rhs);
+ return CMP(lhs,rhs);
}
int enif_get_tuple(ErlNifEnv* env, Eterm tpl, int* arity, const Eterm** array)
@@ -730,9 +739,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
- Sint i;
- return term_to_Sint(term, &i) ? (*ip = (long) i, 1) : 0;
+#elif SIZEOF_LONG == 8
+ return term_to_Sint64(term, ip);
#else
# error Unknown long word size
#endif
@@ -742,9 +750,8 @@ int enif_get_ulong(ErlNifEnv* env, Eterm term, unsigned long* ip)
{
#if SIZEOF_LONG == ERTS_SIZEOF_ETERM
return term_to_Uint(term, ip);
-#elif SIZEOF_INT == ERTS_SIZEOF_ETERM
- Uint u;
- return term_to_Uint(term, &u) ? (*ip = (unsigned long) u, 1) : 0;
+#elif SIZEOF_LONG == 8
+ return term_to_Uint64(term, ip);
#else
# error Unknown long word size
#endif
@@ -821,12 +828,22 @@ ERL_NIF_TERM enif_make_uint(ErlNifEnv* env, unsigned i)
ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long i)
{
+#if SIZEOF_LONG == ERTS_SIZEOF_ETERM
return IS_SSMALL(i) ? make_small(i) : small_to_big(i, alloc_heap(env,2));
+#elif SIZEOF_LONG == 8
+ ensure_heap(env,3);
+ return erts_sint64_to_big(i, &env->hp);
+#endif
}
ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i)
{
+#if SIZEOF_LONG == ERTS_SIZEOF_ETERM
return IS_USMALL(0,i) ? make_small(i) : uint_to_big(i,alloc_heap(env,2));
+#elif SIZEOF_LONG == 8
+ ensure_heap(env,3);
+ return erts_uint64_to_big(i, &env->hp);
+#endif
}
#if HAVE_INT64 && SIZEOF_LONG != 8
@@ -921,21 +938,26 @@ ERL_NIF_TERM enif_make_list_cell(ErlNifEnv* env, Eterm car, Eterm cdr)
ERL_NIF_TERM enif_make_list(ErlNifEnv* env, unsigned cnt, ...)
{
- Eterm* hp = alloc_heap(env,cnt*2);
- Eterm ret = make_list(hp);
- Eterm* last = &ret;
- va_list ap;
-
- va_start(ap,cnt);
- while (cnt--) {
- *last = make_list(hp);
- *hp = va_arg(ap,Eterm);
- last = ++hp;
- ++hp;
+ if (cnt == 0) {
+ return NIL;
+ }
+ else {
+ Eterm* hp = alloc_heap(env,cnt*2);
+ Eterm ret = make_list(hp);
+ Eterm* last = &ret;
+ va_list ap;
+
+ va_start(ap,cnt);
+ while (cnt--) {
+ *last = make_list(hp);
+ *hp = va_arg(ap,Eterm);
+ last = ++hp;
+ ++hp;
+ }
+ va_end(ap);
+ *last = NIL;
+ return ret;
}
- va_end(ap);
- *last = NIL;
- return ret;
}
ERL_NIF_TERM enif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)
@@ -1456,7 +1478,13 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
ret = load_nif_error(BIF_P, bad_lib, "Library version (%d.%d) not compatible (with %d.%d).",
entry->major, entry->minor, ERL_NIF_MAJOR_VERSION, ERL_NIF_MINOR_VERSION);
- }
+ }
+ else if (entry->minor >= 1
+ && sys_strcmp(entry->vm_variant, ERL_NIF_VM_VARIANT) != 0) {
+ ret = load_nif_error(BIF_P, bad_lib, "Library (%s) not compiled for "
+ "this vm variant (%s).",
+ entry->vm_variant, ERL_NIF_VM_VARIANT);
+ }
else if (!erts_is_atom_str((char*)entry->name, mod_atom)) {
ret = load_nif_error(BIF_P, bad_lib, "Library module name '%s' does not"
" match calling module '%T'", entry->name, mod_atom);
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index ee3a7cd5f4..8050b3640a 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2009-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2009-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -30,9 +30,10 @@
** 0.1: R13B03
** 1.0: R13B04
** 2.0: R14A
+** 2.1: R14B02 "vm_variant"
*/
#define ERL_NIF_MAJOR_VERSION 2
-#define ERL_NIF_MINOR_VERSION 0
+#define ERL_NIF_MINOR_VERSION 1
#include <stdlib.h>
@@ -80,8 +81,10 @@ typedef long long ErlNifSInt64;
#endif
#ifdef HALFWORD_HEAP_EMULATOR
+# define ERL_NIF_VM_VARIANT "beam.halfword"
typedef unsigned int ERL_NIF_TERM;
#else
+# define ERL_NIF_VM_VARIANT "beam.vanilla"
typedef unsigned long ERL_NIF_TERM;
#endif
@@ -105,7 +108,8 @@ typedef struct enif_entry_t
int (*load) (ErlNifEnv*, void** priv_data, ERL_NIF_TERM load_info);
int (*reload) (ErlNifEnv*, void** priv_data, ERL_NIF_TERM load_info);
int (*upgrade)(ErlNifEnv*, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info);
- void (*unload) (ErlNifEnv*, void* priv_data);
+ void (*unload) (ErlNifEnv*, void* priv_data);
+ const char* vm_variant;
}ErlNifEntry;
@@ -198,6 +202,7 @@ extern TWinDynNifCallbacks WinDynNifCallbacks;
#define ERL_NIF_INIT(NAME, FUNCS, LOAD, RELOAD, UPGRADE, UNLOAD) \
ERL_NIF_INIT_PROLOGUE \
ERL_NIF_INIT_GLOB \
+ERL_NIF_INIT_DECL(NAME); \
ERL_NIF_INIT_DECL(NAME) \
{ \
static ErlNifEntry entry = \
@@ -207,7 +212,8 @@ ERL_NIF_INIT_DECL(NAME) \
#NAME, \
sizeof(FUNCS) / sizeof(*FUNCS), \
FUNCS, \
- LOAD, RELOAD, UPGRADE, UNLOAD \
+ LOAD, RELOAD, UPGRADE, UNLOAD, \
+ ERL_NIF_VM_VARIANT \
}; \
ERL_NIF_INIT_BODY; \
return &entry; \
diff --git a/erts/emulator/beam/erl_node_container_utils.h b/erts/emulator/beam/erl_node_container_utils.h
index ae1316eba2..2c67e781e0 100644
--- a/erts/emulator/beam/erl_node_container_utils.h
+++ b/erts/emulator/beam/erl_node_container_utils.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -255,19 +255,32 @@ extern int erts_use_r9_pids_ports;
#define internal_ref_no_of_numbers(x) \
(internal_ref_data((x))[0])
+#define internal_thing_ref_no_of_numbers(thing) \
+ (internal_thing_ref_data(thing)[0])
#define internal_ref_numbers(x) \
(&internal_ref_data((x))[1])
+#define internal_thing_ref_numbers(thing) \
+ (&internal_thing_ref_data(thing)[1])
#define external_ref_no_of_numbers(x) \
(external_ref_data((x))[0])
+#define external_thing_ref_no_of_numbers(thing) \
+ (external_thing_ref_data(thing)[0])
#define external_ref_numbers(x) \
(&external_ref_data((x))[1])
+#define external_thing_ref_numbers(thing) \
+ (&external_thing_ref_data(thing)[1])
+
#else
#define internal_ref_no_of_numbers(x) (internal_ref_data_words((x)))
+#define internal_thing_ref_no_of_numbers(t) (internal_thing_ref_data_words(t))
#define internal_ref_numbers(x) (internal_ref_data((x)))
+#define internal_thing_ref_numbers(t) (internal_thing_ref_data(t))
#define external_ref_no_of_numbers(x) (external_ref_data_words((x)))
+#define external_thing_ref_no_of_numbers(t) (external_thing_ref_data_words((t)))
#define external_ref_numbers(x) (external_ref_data((x)))
+#define external_thing_ref_numbers(t) (external_thing_ref_data((t)))
#endif
@@ -311,6 +324,8 @@ extern int erts_use_r9_pids_ports;
: external_ref_channel_no((x)))
#define is_ref(x) (is_internal_ref((x)) \
|| is_external_ref((x)))
+#define is_ref_rel(x,Base) (is_internal_ref_rel((x),Base) \
+ || is_external_ref_rel((x),Base))
#define is_not_ref(x) (!is_ref(x))
#endif
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index d0b08bf72e..6daa127d23 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -107,7 +107,7 @@ dist_table_alloc(void *dep_tmpl)
dep->nlinks = NULL;
dep->monitors = NULL;
- erts_smp_spinlock_init_x(&dep->qlock, "dist_entry_out_queue", chnl_nr);
+ erts_smp_mtx_init_x(&dep->qlock, "dist_entry_out_queue", chnl_nr);
dep->qflgs = 0;
dep->qsize = 0;
dep->out_queue.first = NULL;
@@ -172,7 +172,7 @@ dist_table_free(void *vdep)
ASSERT(!dep->cache);
erts_smp_rwmtx_destroy(&dep->rwmtx);
erts_smp_mtx_destroy(&dep->lnk_mtx);
- erts_smp_spinlock_destroy(&dep->qlock);
+ erts_smp_mtx_destroy(&dep->qlock);
#ifdef DEBUG
sys_memset(vdep, 0x77, sizeof(DistEntry));
@@ -235,7 +235,7 @@ erts_sysname_to_connected_dist_entry(Eterm sysname)
erts_smp_rwmtx_rlock(&erts_dist_table_rwmtx);
res_dep = (DistEntry *) hash_get(&erts_dist_table, (void *) &de);
if (res_dep) {
- long refc = erts_refc_inctest(&res_dep->refc, 1);
+ erts_aint_t refc = erts_refc_inctest(&res_dep->refc, 1);
if (refc < 2) /* Pending delete */
erts_refc_inc(&res_dep->refc, 1);
}
@@ -257,7 +257,7 @@ DistEntry *erts_find_or_insert_dist_entry(Eterm sysname)
{
DistEntry *res;
DistEntry de;
- long refc;
+ erts_aint_t refc;
res = erts_find_dist_entry(sysname);
if (res)
return res;
@@ -279,7 +279,7 @@ DistEntry *erts_find_dist_entry(Eterm sysname)
erts_smp_rwmtx_rlock(&erts_dist_table_rwmtx);
res = hash_get(&erts_dist_table, (void *) &de);
if (res) {
- long refc = erts_refc_inctest(&res->refc, 1);
+ erts_aint_t refc = erts_refc_inctest(&res->refc, 1);
if (refc < 2) /* Pending delete */
erts_refc_inc(&res->refc, 1);
}
@@ -586,7 +586,7 @@ ErlNode *erts_find_or_insert_node(Eterm sysname, Uint creation)
erts_smp_rwmtx_rlock(&erts_node_table_rwmtx);
res = hash_get(&erts_node_table, (void *) &ne);
if (res && res != erts_this_node) {
- long refc = erts_refc_inctest(&res->refc, 0);
+ erts_aint_t refc = erts_refc_inctest(&res->refc, 0);
if (refc < 2) /* New or pending delete */
erts_refc_inc(&res->refc, 1);
}
@@ -598,7 +598,7 @@ ErlNode *erts_find_or_insert_node(Eterm sysname, Uint creation)
res = hash_put(&erts_node_table, (void *) &ne);
ASSERT(res);
if (res != erts_this_node) {
- long refc = erts_refc_inctest(&res->refc, 0);
+ erts_aint_t refc = erts_refc_inctest(&res->refc, 0);
if (refc < 2) /* New or pending delete */
erts_refc_inc(&res->refc, 1);
}
@@ -755,9 +755,9 @@ void erts_init_node_tables(void)
erts_this_dist_entry->nlinks = NULL;
erts_this_dist_entry->monitors = NULL;
- erts_smp_spinlock_init_x(&erts_this_dist_entry->qlock,
- "dist_entry_out_queue",
- make_small(ERST_INTERNAL_CHANNEL_NO));
+ erts_smp_mtx_init_x(&erts_this_dist_entry->qlock,
+ "dist_entry_out_queue",
+ make_small(ERST_INTERNAL_CHANNEL_NO));
erts_this_dist_entry->qflgs = 0;
erts_this_dist_entry->qsize = 0;
erts_this_dist_entry->out_queue.first = NULL;
diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h
index eb759b87e9..b0a63ae035 100644
--- a/erts/emulator/beam/erl_node_tables.h
+++ b/erts/emulator/beam/erl_node_tables.h
@@ -131,7 +131,7 @@ typedef struct dist_entry_ {
ErtsLink *nlinks; /* Link tree with subtrees */
ErtsMonitor *monitors; /* Monitor tree */
- erts_smp_spinlock_t qlock; /* Protects qflgs and out_queue */
+ erts_smp_mtx_t qlock; /* Protects qflgs and out_queue */
Uint32 qflgs;
Sint qsize;
ErtsDistOutputQueue out_queue;
diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c
index c10724b951..1b07024ca1 100644
--- a/erts/emulator/beam/erl_port_task.c
+++ b/erts/emulator/beam/erl_port_task.c
@@ -129,7 +129,7 @@ reset_handle(ErtsPortTask *ptp)
{
if (ptp->handle) {
ASSERT(ptp == handle2task(ptp->handle));
- erts_smp_atomic_set(ptp->handle, (long) NULL);
+ erts_smp_atomic_set(ptp->handle, (erts_aint_t) NULL);
}
}
@@ -138,7 +138,7 @@ set_handle(ErtsPortTask *ptp, ErtsPortTaskHandle *pthp)
{
ptp->handle = pthp;
if (pthp) {
- erts_smp_atomic_set(pthp, (long) ptp);
+ erts_smp_atomic_set(pthp, (erts_aint_t) ptp);
ASSERT(ptp == handle2task(ptp->handle));
}
}
@@ -568,7 +568,7 @@ erts_port_task_schedule(Eterm id,
ErtsRunQueue *xrunq = erts_check_emigration_need(runq, ERTS_PORT_PRIO_LEVEL);
if (xrunq) {
/* Port emigrated ... */
- erts_smp_atomic_set(&pp->run_queue, (long) xrunq);
+ erts_smp_atomic_set(&pp->run_queue, (erts_aint_t) xrunq);
erts_smp_runq_unlock(runq);
runq = xrunq;
}
@@ -727,7 +727,8 @@ resume_after_block(void *vd)
ErtsPortTaskExeBlockData *d = (ErtsPortTaskExeBlockData *) vd;
erts_smp_runq_lock(d->runq);
if (d->resp)
- *d->resp = erts_smp_atomic_read(&erts_port_task_outstanding_io_tasks) != (long) 0;
+ *d->resp = (erts_smp_atomic_read(&erts_port_task_outstanding_io_tasks)
+ != (erts_aint_t) 0);
}
/*
@@ -748,7 +749,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
ErtsPortTask *ptp;
int res = 0;
int reds = ERTS_PORT_REDS_EXECUTE;
- long io_tasks_executed = 0;
+ erts_aint_t io_tasks_executed = 0;
int fpe_was_unmasked;
ErtsPortTaskExeBlockData blk_data = {runq, NULL};
@@ -942,7 +943,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
}
else {
/* Port emigrated ... */
- erts_smp_atomic_set(&pp->run_queue, (long) xrunq);
+ erts_smp_atomic_set(&pp->run_queue, (erts_aint_t) xrunq);
enqueue_port(xrunq, pp);
ASSERT(pp->sched.exe_taskq);
pp->sched.exe_taskq = NULL;
@@ -953,7 +954,8 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
port_was_enqueued = 1;
}
- res = erts_smp_atomic_read(&erts_port_task_outstanding_io_tasks) != (long) 0;
+ res = (erts_smp_atomic_read(&erts_port_task_outstanding_io_tasks)
+ != (erts_aint_t) 0);
ERTS_PT_CHK_PRES_PORTQ(runq, pp);
@@ -971,7 +973,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
erts_port_release(pp);
#else
{
- long refc;
+ erts_aint_t refc;
erts_smp_mtx_unlock(pp->lock);
refc = erts_smp_atomic_dectest(&pp->refc);
ASSERT(refc >= 0);
@@ -979,7 +981,8 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
erts_smp_runq_unlock(runq);
erts_port_cleanup(pp); /* Might aquire runq lock */
erts_smp_runq_lock(runq);
- res = erts_smp_atomic_read(&erts_port_task_outstanding_io_tasks) != (long) 0;
+ res = (erts_smp_atomic_read(&erts_port_task_outstanding_io_tasks)
+ != (erts_aint_t) 0);
}
}
#endif
@@ -1112,7 +1115,7 @@ erts_port_migrate(Port *prt, int *prt_locked,
if (!ERTS_PORT_IS_IN_RUNQ(from_rq, prt))
return ERTS_MIGRATE_FAILED_NOT_IN_RUNQ;
dequeue_port(from_rq, prt);
- erts_smp_atomic_set(&prt->run_queue, (long) to_rq);
+ erts_smp_atomic_set(&prt->run_queue, (erts_aint_t) to_rq);
enqueue_port(to_rq, prt);
return ERTS_MIGRATE_SUCCESS;
}
@@ -1125,7 +1128,7 @@ erts_port_migrate(Port *prt, int *prt_locked,
void
erts_port_task_init(void)
{
- erts_smp_atomic_init(&erts_port_task_outstanding_io_tasks, (long) 0);
+ erts_smp_atomic_init(&erts_port_task_outstanding_io_tasks, (erts_aint_t) 0);
init_port_task_alloc();
init_port_taskq_alloc();
}
diff --git a/erts/emulator/beam/erl_port_task.h b/erts/emulator/beam/erl_port_task.h
index f12d02da0c..714b4ea7dd 100644
--- a/erts/emulator/beam/erl_port_task.h
+++ b/erts/emulator/beam/erl_port_task.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2006-2010. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -79,7 +79,7 @@ ERTS_GLB_INLINE int erts_port_task_have_outstanding_io_tasks(void);
ERTS_GLB_INLINE void
erts_port_task_handle_init(ErtsPortTaskHandle *pthp)
{
- erts_smp_atomic_init(pthp, (long) NULL);
+ erts_smp_atomic_init(pthp, (erts_aint_t) NULL);
}
ERTS_GLB_INLINE int
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 901167a315..4d6e982325 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -24,7 +24,6 @@
#endif
#include <stddef.h> /* offsetof() */
-#include <ctype.h>
#include "sys.h"
#include "erl_vm.h"
#include "global.h"
@@ -39,6 +38,7 @@
#include "erl_threads.h"
#include "erl_binary.h"
#include "beam_bp.h"
+#include "erl_cpu_topology.h"
#define ERTS_RUNQ_CHECK_BALANCE_REDS_PER_SCHED (2000*CONTEXT_REDS)
#define ERTS_RUNQ_CALL_CHECK_BALANCE_REDS \
@@ -63,8 +63,6 @@
#define ERTS_WAKEUP_OTHER_DEC 10
#define ERTS_WAKEUP_OTHER_FIXED_INC (CONTEXT_REDS/10)
-#define ERTS_MAX_CPU_TOPOLOGY_ID ((int) 0xffff)
-
#if 0 || defined(DEBUG)
#define ERTS_FAKE_SCHED_BIND_PRINT_SORTED_CPU_DATA
#endif
@@ -119,10 +117,6 @@ Uint erts_process_tab_index_mask;
static int wakeup_other_limit;
-#ifdef ERTS_SMP
-Uint erts_max_main_threads;
-#endif
-
int erts_sched_thread_suggested_stack_size = -1;
#ifdef ERTS_ENABLE_LOCK_CHECK
@@ -133,21 +127,22 @@ ErtsLcPSDLocks erts_psd_required_locks[ERTS_PSD_SIZE];
int erts_disable_proc_not_running_opt;
-#define ERTS_SCHDLR_SSPND_CHNG_WAITER (((long) 1) << 0)
-#define ERTS_SCHDLR_SSPND_CHNG_MSB (((long) 1) << 1)
-#define ERTS_SCHDLR_SSPND_CHNG_ONLN (((long) 1) << 2)
+#define ERTS_SCHDLR_SSPND_CHNG_WAITER (((erts_aint32_t) 1) << 0)
+#define ERTS_SCHDLR_SSPND_CHNG_MSB (((erts_aint32_t) 1) << 1)
+#define ERTS_SCHDLR_SSPND_CHNG_ONLN (((erts_aint32_t) 1) << 2)
#ifndef DEBUG
#define ERTS_SCHDLR_SSPND_CHNG_SET(VAL, OLD_VAL) \
- erts_smp_atomic_set(&schdlr_sspnd.changing, (VAL))
+ erts_smp_atomic32_set(&schdlr_sspnd.changing, (VAL))
#else
#define ERTS_SCHDLR_SSPND_CHNG_SET(VAL, OLD_VAL) \
do { \
- long old_val__ = erts_smp_atomic_xchg(&schdlr_sspnd.changing, \
- (VAL)); \
+ erts_aint32_t old_val__; \
+ old_val__ = erts_smp_atomic32_xchg(&schdlr_sspnd.changing, \
+ (VAL)); \
ASSERT(old_val__ == (OLD_VAL)); \
} while (0)
@@ -160,10 +155,10 @@ static struct {
int online;
int curr_online;
int wait_curr_online;
- erts_smp_atomic_t changing;
- erts_smp_atomic_t active;
+ erts_smp_atomic32_t changing;
+ erts_smp_atomic32_t active;
struct {
- erts_smp_atomic_t ongoing;
+ erts_smp_atomic32_t ongoing;
long wait_active;
ErtsProcList *procs;
} msb; /* Multi Scheduling Block */
@@ -171,11 +166,11 @@ static struct {
static struct {
erts_smp_mtx_t update_mtx;
- erts_smp_atomic_t active_runqs;
+ erts_smp_atomic32_t active_runqs;
int last_active_runqs;
- erts_smp_atomic_t used_runqs;
+ erts_smp_atomic32_t used_runqs;
int forced_check_balance;
- erts_smp_atomic_t checking_balance;
+ erts_smp_atomic32_t checking_balance;
int halftime;
int full_reds_history_index;
struct {
@@ -195,48 +190,6 @@ do { \
#endif
-/*
- * Cpu topology hierarchy.
- */
-#define ERTS_TOPOLOGY_NODE 0
-#define ERTS_TOPOLOGY_PROCESSOR 1
-#define ERTS_TOPOLOGY_PROCESSOR_NODE 2
-#define ERTS_TOPOLOGY_CORE 3
-#define ERTS_TOPOLOGY_THREAD 4
-#define ERTS_TOPOLOGY_LOGICAL 5
-
-#define ERTS_TOPOLOGY_MAX_DEPTH 6
-
-typedef struct {
- int bind_id;
- int bound_id;
-} ErtsCpuBindData;
-
-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,
- ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD,
- ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD,
- ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD,
- ERTS_CPU_BIND_NO_SPREAD,
- 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;
-static int user_cpudata_size;
-static erts_cpu_topology_t *system_cpudata;
-static int system_cpudata_size;
-
erts_sched_stat_t erts_sched_stat;
ErtsRunQueue *erts_common_run_queue;
@@ -247,11 +200,11 @@ static erts_tsd_key_t sched_data_key;
static erts_smp_mtx_t proc_tab_mtx;
-static erts_smp_atomic_t function_calls;
+static erts_smp_atomic32_t function_calls;
#ifdef ERTS_SMP
-static erts_smp_atomic_t doing_sys_schedule;
-static erts_smp_atomic_t no_empty_run_queues;
+static erts_smp_atomic32_t doing_sys_schedule;
+static erts_smp_atomic32_t no_empty_run_queues;
#else /* !ERTS_SMP */
ErtsSchedulerData *erts_scheduler_data;
#endif
@@ -259,11 +212,6 @@ ErtsSchedulerData *erts_scheduler_data;
ErtsAlignedRunQueue *erts_aligned_run_queues;
Uint erts_no_run_queues;
-typedef union {
- ErtsSchedulerData esd;
- char align[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(ErtsSchedulerData))];
-} ErtsAlignedSchedulerData;
-
ErtsAlignedSchedulerData *erts_aligned_scheduler_data;
#ifdef ERTS_SMP
@@ -300,7 +248,10 @@ Uint erts_num_active_procs;
Process** erts_active_procs;
#endif
-static erts_smp_atomic_t process_count;
+#if ERTS_MAX_PROCESSES > 0x7fffffff
+#error "Need to store process_count in another type"
+#endif
+static erts_smp_atomic32_t process_count;
typedef struct ErtsTermProcElement_ ErtsTermProcElement;
struct ErtsTermProcElement_ {
@@ -334,12 +285,6 @@ ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(proclist,
200,
ERTS_ALC_T_PROC_LIST)
-#define ERTS_RUNQ_IX(IX) \
- (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_run_queues), \
- &erts_aligned_run_queues[(IX)].runq)
-#define ERTS_SCHEDULER_IX(IX) \
- (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_schedulers), \
- &erts_aligned_scheduler_data[(IX)].esd)
#define ERTS_SCHED_SLEEP_INFO_IX(IX) \
(ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_schedulers), \
&aligned_sched_sleep_info[(IX)].ssi)
@@ -398,22 +343,8 @@ static int stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp,
#ifdef ERTS_SMP
static void handle_pending_exiters(ErtsProcList *);
-static void cpu_bind_order_sort(erts_cpu_topology_t *cpudata,
- int size,
- ErtsCpuBindOrder bind_order,
- int mk_seq);
-static void signal_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size);
-
#endif
-static int reader_group_lookup(int logical);
-static void create_tmp_cpu_topology_copy(erts_cpu_topology_t **cpudata,
- int *cpudata_size);
-static void destroy_tmp_cpu_topology_copy(erts_cpu_topology_t *cpudata);
-
-static void early_cpu_bind_init(void);
-static void late_cpu_bind_init(void);
-
#if defined(ERTS_SMP) && defined(ERTS_ENABLE_LOCK_CHECK)
int
erts_smp_lc_runq_is_locked(ErtsRunQueue *runq)
@@ -469,18 +400,18 @@ erts_pre_init_process(void)
/* initialize the scheduler */
void
-erts_init_process(void)
+erts_init_process(int ncpu)
{
Uint proc_bits = ERTS_PROC_BITS;
#ifdef ERTS_SMP
erts_disable_proc_not_running_opt = 0;
- erts_init_proc_lock();
+ erts_init_proc_lock(ncpu);
#endif
init_proclist_alloc();
- erts_smp_atomic_init(&process_count, 0);
+ erts_smp_atomic32_init(&process_count, 0);
if (erts_use_r9_pids_ports) {
proc_bits = ERTS_R9_PROC_BITS;
@@ -641,7 +572,7 @@ erts_psd_set_init(Process *p, ErtsProcLocks plocks, int ix, void *data)
#ifdef ERTS_SMP
void
-erts_sched_finish_poke(ErtsSchedulerSleepInfo *ssi, long flags)
+erts_sched_finish_poke(ErtsSchedulerSleepInfo *ssi, erts_aint32_t flags)
{
switch (flags & ERTS_SSI_FLGS_SLEEP_TYPE) {
case ERTS_SSI_FLG_POLL_SLEEPING:
@@ -659,6 +590,122 @@ erts_sched_finish_poke(ErtsSchedulerSleepInfo *ssi, long flags)
}
}
+typedef struct erts_misc_aux_work_t_ erts_misc_aux_work_t;
+struct erts_misc_aux_work_t_ {
+ erts_misc_aux_work_t *next;
+ void (*func)(void *);
+ void *arg;
+};
+
+typedef struct {
+ erts_smp_mtx_t mtx;
+ erts_misc_aux_work_t *first;
+ erts_misc_aux_work_t *last;
+} erts_misc_aux_work_q_t;
+
+typedef union {
+ erts_misc_aux_work_q_t data;
+ char align[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(erts_misc_aux_work_q_t))];
+} erts_algnd_misc_aux_work_q_t;
+
+static erts_algnd_misc_aux_work_q_t *misc_aux_work_queues;
+
+ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(misc_aux_work,
+ erts_misc_aux_work_t,
+ 200,
+ ERTS_ALC_T_MISC_AUX_WORK)
+
+static void
+init_misc_aux_work(void)
+{
+ int ix;
+
+ init_misc_aux_work_alloc();
+
+ misc_aux_work_queues = erts_alloc(ERTS_ALC_T_MISC_AUX_WORK_Q,
+ (sizeof(erts_algnd_misc_aux_work_q_t)
+ *(erts_no_schedulers+1)));
+ if ((((UWord) misc_aux_work_queues) & ERTS_CACHE_LINE_MASK) != 0)
+ misc_aux_work_queues = ((erts_algnd_misc_aux_work_q_t *)
+ ((((UWord) misc_aux_work_queues)
+ & ~ERTS_CACHE_LINE_MASK)
+ + ERTS_CACHE_LINE_SIZE));
+
+ for (ix = 0; ix < erts_no_schedulers; ix++) {
+ erts_smp_mtx_init_x(&misc_aux_work_queues[ix].data.mtx,
+ "misc_aux_work_queue",
+ make_small(ix + 1));
+ misc_aux_work_queues[ix].data.first = NULL;
+ misc_aux_work_queues[ix].data.last = NULL;
+ }
+}
+
+static void
+handle_misc_aux_work(ErtsSchedulerData *esdp)
+{
+ int ix = (int) esdp->no - 1;
+ erts_misc_aux_work_t *mawp;
+
+ erts_smp_mtx_lock(&misc_aux_work_queues[ix].data.mtx);
+ mawp = misc_aux_work_queues[ix].data.first;
+ misc_aux_work_queues[ix].data.first = NULL;
+ misc_aux_work_queues[ix].data.last = NULL;
+ erts_smp_mtx_unlock(&misc_aux_work_queues[ix].data.mtx);
+
+ while (mawp) {
+ erts_misc_aux_work_t *free_mawp;
+ mawp->func(mawp->arg);
+ free_mawp = mawp;
+ mawp = mawp->next;
+ misc_aux_work_free(free_mawp);
+ }
+}
+
+void
+erts_smp_schedule_misc_aux_work(int ignore_self,
+ int max_sched,
+ void (*func)(void *),
+ void *arg)
+{
+ int ix, ignore_ix = -1;
+
+ if (ignore_self) {
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ if (esdp)
+ ignore_ix = (int) esdp->no - 1;
+ }
+
+ ASSERT(0 <= max_sched && max_sched <= erts_no_schedulers);
+
+ for (ix = 0; ix < max_sched; ix++) {
+ erts_aint32_t aux_work;
+ erts_misc_aux_work_t *mawp;
+ ErtsSchedulerSleepInfo *ssi;
+ if (ix == ignore_ix)
+ continue;
+
+ mawp = misc_aux_work_alloc();
+
+ mawp->func = func;
+ mawp->arg = arg;
+ mawp->next = NULL;
+
+ erts_smp_mtx_lock(&misc_aux_work_queues[ix].data.mtx);
+ if (!misc_aux_work_queues[ix].data.last)
+ misc_aux_work_queues[ix].data.first = mawp;
+ else
+ misc_aux_work_queues[ix].data.last->next = mawp;
+ misc_aux_work_queues[ix].data.last = mawp;
+ erts_smp_mtx_unlock(&misc_aux_work_queues[ix].data.mtx);
+
+ ssi = ERTS_SCHED_SLEEP_INFO_IX(ix);
+ aux_work = erts_smp_atomic32_bor(&ssi->aux_work,
+ ERTS_SSI_AUX_WORK_MISC);
+ if ((aux_work & ERTS_SSI_AUX_WORK_MISC) == 0)
+ erts_sched_poke(ssi);
+ }
+}
+
#ifdef ERTS_SMP_SCHEDULERS_NEED_TO_CHECK_CHILDREN
void
erts_smp_notify_check_children_needed(void)
@@ -666,11 +713,11 @@ erts_smp_notify_check_children_needed(void)
int i;
for (i = 0; i < erts_no_schedulers; i++) {
- long aux_work;
+ erts_aint32_t aux_work;
ErtsSchedulerSleepInfo *ssi;
ssi = ERTS_SCHED_SLEEP_INFO_IX(i);
- aux_work = erts_smp_atomic_bor(&ssi->aux_work,
- ERTS_SSI_AUX_WORK_CHECK_CHILDREN);
+ aux_work = erts_smp_atomic32_bor(&ssi->aux_work,
+ ERTS_SSI_AUX_WORK_CHECK_CHILDREN);
if (!(aux_work & ERTS_SSI_AUX_WORK_CHECK_CHILDREN))
erts_sched_poke(ssi);
}
@@ -678,16 +725,22 @@ erts_smp_notify_check_children_needed(void)
#endif
#ifdef ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
-static ERTS_INLINE long
+static ERTS_INLINE erts_aint32_t
blockable_aux_work(ErtsSchedulerData *esdp,
ErtsSchedulerSleepInfo *ssi,
- long aux_work)
+ erts_aint32_t aux_work)
{
if (aux_work & ERTS_SSI_BLOCKABLE_AUX_WORK_MASK) {
+ if (aux_work & ERTS_SSI_AUX_WORK_MISC) {
+ aux_work = erts_smp_atomic32_band(&ssi->aux_work,
+ ~ERTS_SSI_AUX_WORK_MISC);
+ aux_work &= ~ERTS_SSI_AUX_WORK_MISC;
+ handle_misc_aux_work(esdp);
+ }
#ifdef ERTS_SMP_SCHEDULERS_NEED_TO_CHECK_CHILDREN
if (aux_work & ERTS_SSI_AUX_WORK_CHECK_CHILDREN) {
- aux_work = erts_smp_atomic_band(&ssi->aux_work,
- ~ERTS_SSI_AUX_WORK_CHECK_CHILDREN);
+ aux_work = erts_smp_atomic32_band(&ssi->aux_work,
+ ~ERTS_SSI_AUX_WORK_CHECK_CHILDREN);
aux_work &= ~ERTS_SSI_AUX_WORK_CHECK_CHILDREN;
erts_check_children();
}
@@ -699,10 +752,10 @@ blockable_aux_work(ErtsSchedulerData *esdp,
#endif
#ifdef ERTS_SCHED_NEED_NONBLOCKABLE_AUX_WORK
-static ERTS_INLINE long
+static ERTS_INLINE erts_aint32_t
nonblockable_aux_work(ErtsSchedulerData *esdp,
ErtsSchedulerSleepInfo *ssi,
- long aux_work)
+ erts_aint32_t aux_work)
{
if (aux_work & ERTS_SSI_NONBLOCKABLE_AUX_WORK_MASK) {
@@ -767,10 +820,10 @@ prepare_for_sys_schedule(void)
{
#ifdef ERTS_SMP
while (!erts_port_task_have_outstanding_io_tasks()
- && !erts_smp_atomic_xchg(&doing_sys_schedule, 1)) {
+ && !erts_smp_atomic32_xchg(&doing_sys_schedule, 1)) {
if (!erts_port_task_have_outstanding_io_tasks())
return 1;
- erts_smp_atomic_set(&doing_sys_schedule, 0);
+ erts_smp_atomic32_set(&doing_sys_schedule, 0);
}
return 0;
#else
@@ -818,53 +871,55 @@ sched_active(Uint no, ErtsRunQueue *rq)
static int ERTS_INLINE
ongoing_multi_scheduling_block(void)
{
- return erts_smp_atomic_read(&schdlr_sspnd.msb.ongoing) != 0;
+ return erts_smp_atomic32_read(&schdlr_sspnd.msb.ongoing) != 0;
}
static ERTS_INLINE void
empty_runq(ErtsRunQueue *rq)
{
- long oifls = erts_smp_atomic_band(&rq->info_flags, ~ERTS_RUNQ_IFLG_NONEMPTY);
+ erts_aint32_t oifls = erts_smp_atomic32_band(&rq->info_flags,
+ ~ERTS_RUNQ_IFLG_NONEMPTY);
if (oifls & ERTS_RUNQ_IFLG_NONEMPTY) {
#ifdef DEBUG
- long empty = erts_smp_atomic_read(&no_empty_run_queues);
+ erts_aint32_t empty = erts_smp_atomic32_read(&no_empty_run_queues);
/*
* For a short period of time no_empty_run_queues may have
* been increased twice for a specific run queue.
*/
ASSERT(0 <= empty && empty < 2*erts_no_run_queues);
#endif
- erts_smp_atomic_inc(&no_empty_run_queues);
+ erts_smp_atomic32_inc(&no_empty_run_queues);
}
}
static ERTS_INLINE void
non_empty_runq(ErtsRunQueue *rq)
{
- long oifls = erts_smp_atomic_bor(&rq->info_flags, ERTS_RUNQ_IFLG_NONEMPTY);
+ erts_aint32_t oifls = erts_smp_atomic32_bor(&rq->info_flags,
+ ERTS_RUNQ_IFLG_NONEMPTY);
if (!(oifls & ERTS_RUNQ_IFLG_NONEMPTY)) {
#ifdef DEBUG
- long empty = erts_smp_atomic_read(&no_empty_run_queues);
+ erts_aint32_t empty = erts_smp_atomic32_read(&no_empty_run_queues);
/*
* For a short period of time no_empty_run_queues may have
* been increased twice for a specific run queue.
*/
ASSERT(0 < empty && empty <= 2*erts_no_run_queues);
#endif
- erts_smp_atomic_dec(&no_empty_run_queues);
+ erts_smp_atomic32_dec(&no_empty_run_queues);
}
}
-static long
+static erts_aint32_t
sched_prep_spin_wait(ErtsSchedulerSleepInfo *ssi)
{
- long oflgs;
- long nflgs = (ERTS_SSI_FLG_SLEEPING
- | ERTS_SSI_FLG_WAITING);
- long xflgs = 0;
+ erts_aint32_t oflgs;
+ erts_aint32_t nflgs = (ERTS_SSI_FLG_SLEEPING
+ | ERTS_SSI_FLG_WAITING);
+ erts_aint32_t xflgs = 0;
do {
- oflgs = erts_smp_atomic_cmpxchg(&ssi->flags, nflgs, xflgs);
+ oflgs = erts_smp_atomic32_cmpxchg(&ssi->flags, nflgs, xflgs);
if (oflgs == xflgs)
return nflgs;
xflgs = oflgs;
@@ -872,16 +927,16 @@ sched_prep_spin_wait(ErtsSchedulerSleepInfo *ssi)
return oflgs;
}
-static long
+static erts_aint32_t
sched_prep_cont_spin_wait(ErtsSchedulerSleepInfo *ssi)
{
- long oflgs;
- long nflgs = (ERTS_SSI_FLG_SLEEPING
- | ERTS_SSI_FLG_WAITING);
- long xflgs = ERTS_SSI_FLG_WAITING;
+ erts_aint32_t oflgs;
+ erts_aint32_t nflgs = (ERTS_SSI_FLG_SLEEPING
+ | ERTS_SSI_FLG_WAITING);
+ erts_aint32_t xflgs = ERTS_SSI_FLG_WAITING;
do {
- oflgs = erts_smp_atomic_cmpxchg(&ssi->flags, nflgs, xflgs);
+ oflgs = erts_smp_atomic32_cmpxchg(&ssi->flags, nflgs, xflgs);
if (oflgs == xflgs)
return nflgs;
xflgs = oflgs;
@@ -890,15 +945,15 @@ sched_prep_cont_spin_wait(ErtsSchedulerSleepInfo *ssi)
return oflgs;
}
-static long
+static erts_aint32_t
sched_spin_wait(ErtsSchedulerSleepInfo *ssi, int spincount)
{
- long until_yield = ERTS_SCHED_SPIN_UNTIL_YIELD;
+ int until_yield = ERTS_SCHED_SPIN_UNTIL_YIELD;
int sc = spincount;
- long flgs;
+ erts_aint32_t flgs;
do {
- flgs = erts_smp_atomic_read(&ssi->flags);
+ flgs = erts_smp_atomic32_read(&ssi->flags);
if ((flgs & (ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING))
!= (ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING)) {
break;
@@ -912,18 +967,18 @@ sched_spin_wait(ErtsSchedulerSleepInfo *ssi, int spincount)
return flgs;
}
-static long
-sched_set_sleeptype(ErtsSchedulerSleepInfo *ssi, long sleep_type)
+static erts_aint32_t
+sched_set_sleeptype(ErtsSchedulerSleepInfo *ssi, erts_aint32_t sleep_type)
{
- long oflgs;
- long nflgs = ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING|sleep_type;
- long xflgs = ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING;
+ erts_aint32_t oflgs;
+ erts_aint32_t nflgs = ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING|sleep_type;
+ erts_aint32_t xflgs = ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING;
if (sleep_type == ERTS_SSI_FLG_TSE_SLEEPING)
erts_tse_reset(ssi->event);
while (1) {
- oflgs = erts_smp_atomic_cmpxchg(&ssi->flags, nflgs, xflgs);
+ oflgs = erts_smp_atomic32_cmpxchg(&ssi->flags, nflgs, xflgs);
if (oflgs == xflgs)
return nflgs;
if ((oflgs & (ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING))
@@ -940,14 +995,14 @@ sched_set_sleeptype(ErtsSchedulerSleepInfo *ssi, long sleep_type)
!= ERTS_SSI_FLG_WAITING)
static void
-scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
+scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
{
ErtsSchedulerSleepInfo *ssi = esdp->ssi;
int spincount;
- long flgs;
+ erts_aint32_t flgs;
#if defined(ERTS_SCHED_NEED_NONBLOCKABLE_AUX_WORK) \
|| defined(ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK)
- long aux_work;
+ erts_aint32_t aux_work;
#endif
ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(rq));
@@ -983,7 +1038,7 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
tse_wait:
#ifdef ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
- aux_work = erts_smp_atomic_read(&ssi->aux_work);
+ aux_work = erts_smp_atomic32_read(&ssi->aux_work);
tse_blockable_aux_work:
aux_work = blockable_aux_work(esdp, ssi, aux_work);
#endif
@@ -993,7 +1048,7 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
#ifdef ERTS_SCHED_NEED_NONBLOCKABLE_AUX_WORK
#ifndef ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
- aux_work = erts_smp_atomic_read(&ssi->aux_work);
+ aux_work = erts_smp_atomic32_read(&ssi->aux_work);
#endif
nonblockable_aux_work(esdp, ssi, aux_work);
#endif
@@ -1026,7 +1081,7 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
}
#ifdef ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
- aux_work = erts_smp_atomic_read(&ssi->aux_work);
+ aux_work = erts_smp_atomic32_read(&ssi->aux_work);
if (aux_work & ERTS_SSI_BLOCKABLE_AUX_WORK_MASK) {
erts_smp_activity_end(ERTS_ACTIVITY_WAIT, NULL, NULL, NULL);
goto tse_blockable_aux_work;
@@ -1038,16 +1093,16 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
erts_smp_activity_end(ERTS_ACTIVITY_WAIT, NULL, NULL, NULL);
if (flgs & ~ERTS_SSI_FLG_SUSPENDED)
- erts_smp_atomic_band(&ssi->flags, ERTS_SSI_FLG_SUSPENDED);
+ erts_smp_atomic32_band(&ssi->flags, ERTS_SSI_FLG_SUSPENDED);
erts_smp_runq_lock(rq);
sched_active(esdp->no, rq);
}
else {
- long dt;
+ erts_aint_t dt;
- erts_smp_atomic_set(&function_calls, 0);
+ erts_smp_atomic32_set(&function_calls, 0);
*fcalls = 0;
sched_waiting_sys(esdp->no, rq);
@@ -1060,25 +1115,27 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
sys_poll_aux_work:
+ ASSERT(!erts_port_task_have_outstanding_io_tasks());
+
erl_sys_schedule(1); /* Might give us something to do */
- dt = do_time_read_and_reset();
- if (dt) bump_timer(dt);
+ dt = erts_do_time_read_and_reset();
+ if (dt) erts_bump_timer(dt);
sys_aux_work:
#ifdef ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
- aux_work = erts_smp_atomic_read(&ssi->aux_work);
+ aux_work = erts_smp_atomic32_read(&ssi->aux_work);
aux_work = blockable_aux_work(esdp, ssi, aux_work);
#endif
#ifdef ERTS_SCHED_NEED_NONBLOCKABLE_AUX_WORK
#ifndef ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
- aux_work = erts_smp_atomic_read(&ssi->aux_work);
+ aux_work = erts_smp_atomic32_read(&ssi->aux_work);
#endif
nonblockable_aux_work(esdp, ssi, aux_work);
#endif
- flgs = erts_smp_atomic_read(&ssi->flags);
+ flgs = erts_smp_atomic32_read(&ssi->flags);
if (!(flgs & ERTS_SSI_FLG_WAITING)) {
ASSERT(!(flgs & ERTS_SSI_FLG_SLEEPING));
goto sys_woken;
@@ -1096,7 +1153,7 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
* call erl_sys_schedule() until it is handled.
*/
if (erts_port_task_have_outstanding_io_tasks()) {
- erts_smp_atomic_set(&doing_sys_schedule, 0);
+ erts_smp_atomic32_set(&doing_sys_schedule, 0);
/*
* Got to check that we still got I/O tasks; otherwise
* we have to continue checking for I/O...
@@ -1115,7 +1172,7 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
* sleep in erl_sys_schedule().
*/
if (erts_port_task_have_outstanding_io_tasks()) {
- erts_smp_atomic_set(&doing_sys_schedule, 0);
+ erts_smp_atomic32_set(&doing_sys_schedule, 0);
/*
* Got to check that we still got I/O tasks; otherwise
@@ -1155,10 +1212,12 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
erts_smp_runq_unlock(rq);
+ ASSERT(!erts_port_task_have_outstanding_io_tasks());
+
erl_sys_schedule(0);
- dt = do_time_read_and_reset();
- if (dt) bump_timer(dt);
+ dt = erts_do_time_read_and_reset();
+ if (dt) erts_bump_timer(dt);
flgs = sched_prep_cont_spin_wait(ssi);
if (flgs & ERTS_SSI_FLG_WAITING)
@@ -1167,9 +1226,9 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
sys_woken:
erts_smp_runq_lock(rq);
sys_locked_woken:
- erts_smp_atomic_set(&doing_sys_schedule, 0);
+ erts_smp_atomic32_set(&doing_sys_schedule, 0);
if (flgs & ~ERTS_SSI_FLG_SUSPENDED)
- erts_smp_atomic_band(&ssi->flags, ERTS_SSI_FLG_SUSPENDED);
+ erts_smp_atomic32_band(&ssi->flags, ERTS_SSI_FLG_SUSPENDED);
sched_active_sys(esdp->no, rq);
}
}
@@ -1177,15 +1236,15 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(rq));
}
-static ERTS_INLINE long
+static ERTS_INLINE erts_aint32_t
ssi_flags_set_wake(ErtsSchedulerSleepInfo *ssi)
{
/* reset all flags but suspended */
- long oflgs;
- long nflgs = 0;
- long xflgs = ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING;
+ erts_aint32_t oflgs;
+ erts_aint32_t nflgs = 0;
+ erts_aint32_t xflgs = ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLG_WAITING;
while (1) {
- oflgs = erts_smp_atomic_cmpxchg(&ssi->flags, nflgs, xflgs);
+ oflgs = erts_smp_atomic32_cmpxchg(&ssi->flags, nflgs, xflgs);
if (oflgs == xflgs)
return oflgs;
nflgs = oflgs & ERTS_SSI_FLG_SUSPENDED;
@@ -1217,7 +1276,7 @@ wake_scheduler(ErtsRunQueue *rq, int incq, int one)
if (!ssi)
erts_smp_spin_unlock(&sl->lock);
else if (one) {
- long flgs;
+ erts_aint32_t flgs;
if (ssi->prev)
ssi->prev->next = ssi->next;
else {
@@ -1242,7 +1301,7 @@ wake_scheduler(ErtsRunQueue *rq, int incq, int one)
do {
ErtsSchedulerSleepInfo *wake_ssi = ssi;
ssi = ssi->next;
- erts_sched_finish_poke(ssi, ssi_flags_set_wake(wake_ssi));
+ erts_sched_finish_poke(wake_ssi, ssi_flags_set_wake(wake_ssi));
} while (ssi);
}
}
@@ -1264,15 +1323,17 @@ wake_all_schedulers(void)
static ERTS_INLINE int
chk_wake_sched(ErtsRunQueue *crq, int ix, int activate)
{
- long iflgs;
+ erts_aint32_t iflgs;
ErtsRunQueue *wrq;
if (crq->ix == ix)
return 0;
wrq = ERTS_RUNQ_IX(ix);
- iflgs = erts_smp_atomic_read(&wrq->info_flags);
+ iflgs = erts_smp_atomic32_read(&wrq->info_flags);
if (!(iflgs & (ERTS_RUNQ_IFLG_SUSPENDED|ERTS_RUNQ_IFLG_NONEMPTY))) {
if (activate) {
- if (ix == erts_smp_atomic_cmpxchg(&balance_info.active_runqs, ix+1, ix)) {
+ if (ix == erts_smp_atomic32_cmpxchg(&balance_info.active_runqs,
+ ix+1,
+ ix)) {
erts_smp_xrunq_lock(crq, wrq);
wrq->flags &= ~ERTS_RUNQ_FLG_INACTIVE;
erts_smp_xrunq_unlock(crq, wrq);
@@ -1289,8 +1350,8 @@ wake_scheduler_on_empty_runq(ErtsRunQueue *crq)
{
int ix = crq->ix;
int stop_ix = ix;
- int active_ix = erts_smp_atomic_read(&balance_info.active_runqs);
- int balance_ix = erts_smp_atomic_read(&balance_info.used_runqs);
+ int active_ix = erts_smp_atomic32_read(&balance_info.active_runqs);
+ int balance_ix = erts_smp_atomic32_read(&balance_info.used_runqs);
if (active_ix > balance_ix)
active_ix = balance_ix;
@@ -1335,6 +1396,31 @@ erts_smp_notify_inc_runq(ErtsRunQueue *runq)
smp_notify_inc_runq(runq);
}
+void
+erts_sched_notify_check_cpu_bind(void)
+{
+#ifdef ERTS_SMP
+ int ix;
+ if (erts_common_run_queue) {
+ for (ix = 0; ix < erts_no_schedulers; ix++)
+ erts_smp_atomic32_set(&ERTS_SCHEDULER_IX(ix)->chk_cpu_bind, 1);
+ wake_all_schedulers();
+ }
+ else {
+ for (ix = 0; ix < erts_no_run_queues; ix++) {
+ ErtsRunQueue *rq = ERTS_RUNQ_IX(ix);
+ erts_smp_runq_lock(rq);
+ rq->flags |= ERTS_RUNQ_FLG_CHK_CPU_BIND;
+ erts_smp_runq_unlock(rq);
+ wake_scheduler(rq, 0, 1);
+ };
+ }
+#else
+ erts_sched_check_cpu_bind(erts_get_scheduler_data());
+#endif
+}
+
+
#ifdef ERTS_SMP
ErtsRunQueue *
@@ -1485,14 +1571,15 @@ evacuate_run_queue(ErtsRunQueue *evac_rq, ErtsRunQueue *rq)
erts_smp_runq_lock(evac_rq);
- erts_smp_atomic_bor(&evac_rq->scheduler->ssi->flags, ERTS_SSI_FLG_SUSPENDED);
+ erts_smp_atomic32_bor(&evac_rq->scheduler->ssi->flags,
+ ERTS_SSI_FLG_SUSPENDED);
evac_rq->flags &= ~ERTS_RUNQ_FLGS_IMMIGRATE_QMASK;
evac_rq->flags |= (ERTS_RUNQ_FLGS_EMIGRATE_QMASK
| ERTS_RUNQ_FLGS_EVACUATE_QMASK
| ERTS_RUNQ_FLG_SUSPENDED);
- erts_smp_atomic_bor(&evac_rq->info_flags, ERTS_RUNQ_IFLG_SUSPENDED);
+ erts_smp_atomic32_bor(&evac_rq->info_flags, ERTS_RUNQ_IFLG_SUSPENDED);
/*
* Need to set up evacuation paths first since we
* may release the run queue lock on evac_rq
@@ -1741,7 +1828,7 @@ static ERTS_INLINE int
check_possible_steal_victim(ErtsRunQueue *rq, int *rq_lockedp, int vix)
{
ErtsRunQueue *vrq = ERTS_RUNQ_IX(vix);
- long iflgs = erts_smp_atomic_read(&vrq->info_flags);
+ erts_aint32_t iflgs = erts_smp_atomic32_read(&vrq->info_flags);
if (iflgs & ERTS_RUNQ_IFLG_NONEMPTY)
return try_steal_task_from_victim(rq, rq_lockedp, vrq);
else
@@ -1771,8 +1858,8 @@ try_steal_task(ErtsRunQueue *rq)
ERTS_SMP_LC_CHK_RUNQ_LOCK(rq, rq_locked);
- active_rqs = erts_smp_atomic_read(&balance_info.active_runqs);
- blnc_rqs = erts_smp_atomic_read(&balance_info.used_runqs);
+ active_rqs = erts_smp_atomic32_read(&balance_info.active_runqs);
+ blnc_rqs = erts_smp_atomic32_read(&balance_info.used_runqs);
if (active_rqs > blnc_rqs)
active_rqs = blnc_rqs;
@@ -1783,7 +1870,7 @@ try_steal_task(ErtsRunQueue *rq)
if (active_rqs < blnc_rqs) {
int no = blnc_rqs - active_rqs;
int stop_ix = vix = active_rqs + rq->ix % no;
- while (erts_smp_atomic_read(&no_empty_run_queues) < blnc_rqs) {
+ while (erts_smp_atomic32_read(&no_empty_run_queues) < blnc_rqs) {
res = check_possible_steal_victim(rq, &rq_locked, vix);
if (res)
goto done;
@@ -1798,7 +1885,7 @@ try_steal_task(ErtsRunQueue *rq)
vix = rq->ix;
/* ... then try to steal a job from another active queue... */
- while (erts_smp_atomic_read(&no_empty_run_queues) < blnc_rqs) {
+ while (erts_smp_atomic32_read(&no_empty_run_queues) < blnc_rqs) {
vix++;
if (vix >= active_rqs)
vix = 0;
@@ -1886,20 +1973,23 @@ do { \
static void
check_balance(ErtsRunQueue *c_rq)
{
+#if ERTS_MAX_PROCESSES >= (1 << 27)
+# error check_balance() assumes ERTS_MAX_PROCESS < (1 << 27)
+#endif
ErtsRunQueueBalance avg = {0};
Sint64 scheds_reds, full_scheds_reds;
int forced, active, current_active, oowc, half_full_scheds, full_scheds,
mmax_len, blnc_no_rqs, qix, pix, freds_hist_ix;
- if (erts_smp_atomic_xchg(&balance_info.checking_balance, 1)) {
+ if (erts_smp_atomic32_xchg(&balance_info.checking_balance, 1)) {
c_rq->check_balance_reds = INT_MAX;
return;
}
- blnc_no_rqs = (int) erts_smp_atomic_read(&balance_info.used_runqs);
+ blnc_no_rqs = (int) erts_smp_atomic32_read(&balance_info.used_runqs);
if (blnc_no_rqs == 1) {
c_rq->check_balance_reds = INT_MAX;
- erts_smp_atomic_set(&balance_info.checking_balance, 0);
+ erts_smp_atomic32_set(&balance_info.checking_balance, 0);
return;
}
@@ -1907,7 +1997,7 @@ check_balance(ErtsRunQueue *c_rq)
if (balance_info.halftime) {
balance_info.halftime = 0;
- erts_smp_atomic_set(&balance_info.checking_balance, 0);
+ erts_smp_atomic32_set(&balance_info.checking_balance, 0);
ERTS_FOREACH_RUNQ(rq,
{
if (rq->waiting)
@@ -1935,12 +2025,12 @@ check_balance(ErtsRunQueue *c_rq)
forced = balance_info.forced_check_balance;
balance_info.forced_check_balance = 0;
- blnc_no_rqs = (int) erts_smp_atomic_read(&balance_info.used_runqs);
+ blnc_no_rqs = (int) erts_smp_atomic32_read(&balance_info.used_runqs);
if (blnc_no_rqs == 1) {
erts_smp_mtx_unlock(&balance_info.update_mtx);
erts_smp_runq_lock(c_rq);
c_rq->check_balance_reds = INT_MAX;
- erts_smp_atomic_set(&balance_info.checking_balance, 0);
+ erts_smp_atomic32_set(&balance_info.checking_balance, 0);
return;
}
@@ -1949,7 +2039,7 @@ check_balance(ErtsRunQueue *c_rq)
if (balance_info.full_reds_history_index >= ERTS_FULL_REDS_HISTORY_SIZE)
balance_info.full_reds_history_index = 0;
- current_active = erts_smp_atomic_read(&balance_info.active_runqs);
+ current_active = erts_smp_atomic32_read(&balance_info.active_runqs);
/* Read balance information for all run queues */
for (qix = 0; qix < blnc_no_rqs; qix++) {
@@ -2009,12 +2099,14 @@ check_balance(ErtsRunQueue *c_rq)
run_queue_info[qix].prio[pix].avail = 0;
}
else {
- int xreds = 0;
- int procreds = treds;
- procreds -= run_queue_info[qix].prio[ERTS_PORT_PRIO_LEVEL].reds;
+ Sint64 xreds = 0;
+ Sint64 procreds = treds;
+ procreds -=
+ ((Sint64)
+ run_queue_info[qix].prio[ERTS_PORT_PRIO_LEVEL].reds);
for (pix = 0; pix < ERTS_NO_PROC_PRIO_LEVELS; pix++) {
- int av;
+ Sint64 av;
if (xreds == 0)
av = 100;
@@ -2025,9 +2117,10 @@ check_balance(ErtsRunQueue *c_rq)
if (av == 0)
av = 1;
}
- run_queue_info[qix].prio[pix].avail = av;
+ run_queue_info[qix].prio[pix].avail = (int) av;
+ ASSERT(run_queue_info[qix].prio[pix].avail >= 0);
if (pix < PRIORITY_NORMAL) /* ie., max or high */
- xreds += run_queue_info[qix].prio[pix].reds;
+ xreds += (Sint64) run_queue_info[qix].prio[pix].reds;
}
run_queue_info[qix].prio[ERTS_PORT_PRIO_LEVEL].avail = 100;
}
@@ -2132,7 +2225,8 @@ check_balance(ErtsRunQueue *c_rq)
if (max_len != 0) {
int avail = avg.prio[pix].avail;
if (avail != 0) {
- max_len = ((100*max_len - 1) / avail) + 1;
+ max_len = (int) ((100*((Sint64) max_len) - 1)
+ / ((Sint64) avail)) + 1;
avg.prio[pix].max_len = max_len;
ASSERT(max_len >= 0);
}
@@ -2149,9 +2243,10 @@ check_balance(ErtsRunQueue *c_rq)
|| run_queue_info[qix].prio[pix].avail == 0)
limit = 0;
else
- limit = (((avg.prio[pix].max_len
- * run_queue_info[qix].prio[pix].avail) - 1)
- / 100 + 1);
+ limit = (int) (((((Sint64) avg.prio[pix].max_len)
+ * ((Sint64) run_queue_info[qix].prio[pix].avail))
+ - 1)
+ / 100 + 1);
run_queue_info[qix].prio[pix].migration_limit = limit;
}
}
@@ -2279,10 +2374,10 @@ erts_fprintf(stderr, "--------------------------------\n");
}
balance_info.last_active_runqs = active;
- erts_smp_atomic_set(&balance_info.active_runqs, active);
+ erts_smp_atomic32_set(&balance_info.active_runqs, active);
balance_info.halftime = 1;
- erts_smp_atomic_set(&balance_info.checking_balance, 0);
+ erts_smp_atomic32_set(&balance_info.checking_balance, 0);
/* Write migration paths and reset balance statistics in all queues */
for (qix = 0; qix < blnc_no_rqs; qix++) {
@@ -2379,7 +2474,6 @@ erts_debug_nbalance(void)
void
erts_early_init_scheduling(void)
{
- early_cpu_bind_init();
wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_MEDIUM;
}
@@ -2432,7 +2526,7 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
ASSERT((((UWord) erts_aligned_run_queues) & ERTS_CACHE_LINE_MASK) == 0);
#ifdef ERTS_SMP
- erts_smp_atomic_init(&no_empty_run_queues, 0);
+ erts_smp_atomic32_init(&no_empty_run_queues, 0);
#endif
erts_no_run_queues = n;
@@ -2442,7 +2536,7 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
ErtsRunQueue *rq = ERTS_RUNQ_IX(ix);
rq->ix = ix;
- erts_smp_atomic_init(&rq->info_flags, ERTS_RUNQ_IFLG_NONEMPTY);
+ erts_smp_atomic32_init(&rq->info_flags, ERTS_RUNQ_IFLG_NONEMPTY);
/* make sure that the "extra" id correponds to the schedulers
* id if the esdp->no <-> ix+1 mapping change.
@@ -2528,9 +2622,9 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
aligned_sched_sleep_info = erts_alloc(ERTS_ALC_T_SCHDLR_SLP_INFO,
(sizeof(ErtsAlignedSchedulerSleepInfo)
*(n+1)));
- if ((((Uint) aligned_sched_sleep_info) & ERTS_CACHE_LINE_MASK) == 0)
+ if ((((UWord) aligned_sched_sleep_info) & ERTS_CACHE_LINE_MASK) == 0)
aligned_sched_sleep_info = ((ErtsAlignedSchedulerSleepInfo *)
- ((((Uint) aligned_sched_sleep_info)
+ ((((UWord) aligned_sched_sleep_info)
& ~ERTS_CACHE_LINE_MASK)
+ ERTS_CACHE_LINE_SIZE));
for (ix = 0; ix < n; ix++) {
@@ -2539,9 +2633,9 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
ssi->next = NULL;
ssi->prev = NULL;
#endif
- erts_smp_atomic_init(&ssi->flags, 0);
+ erts_smp_atomic32_init(&ssi->flags, 0);
ssi->event = NULL; /* initialized in sched_thread_func */
- erts_smp_atomic_init(&ssi->aux_work, 0);
+ erts_smp_atomic32_init(&ssi->aux_work, 0);
}
#endif
@@ -2592,7 +2686,7 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
}
#ifdef ERTS_SMP
- erts_smp_atomic_init(&esdp->chk_cpu_bind, 0);
+ erts_smp_atomic32_init(&esdp->chk_cpu_bind, 0);
#endif
}
@@ -2600,21 +2694,21 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
erts_smp_mtx_init(&schdlr_sspnd.mtx, "schdlr_sspnd");
erts_smp_cnd_init(&schdlr_sspnd.cnd);
- erts_smp_atomic_init(&schdlr_sspnd.changing, 0);
+ erts_smp_atomic32_init(&schdlr_sspnd.changing, 0);
schdlr_sspnd.online = no_schedulers_online;
schdlr_sspnd.curr_online = no_schedulers;
- erts_smp_atomic_init(&schdlr_sspnd.msb.ongoing, 0);
- erts_smp_atomic_init(&schdlr_sspnd.active, no_schedulers);
+ erts_smp_atomic32_init(&schdlr_sspnd.msb.ongoing, 0);
+ erts_smp_atomic32_init(&schdlr_sspnd.active, no_schedulers);
schdlr_sspnd.msb.procs = NULL;
- erts_smp_atomic_set(&balance_info.used_runqs,
- erts_common_run_queue ? 1 : no_schedulers_online);
- erts_smp_atomic_init(&balance_info.active_runqs, no_schedulers);
+ erts_smp_atomic32_set(&balance_info.used_runqs,
+ erts_common_run_queue ? 1 : no_schedulers_online);
+ erts_smp_atomic32_init(&balance_info.active_runqs, no_schedulers);
balance_info.last_active_runqs = no_schedulers;
erts_smp_mtx_init(&balance_info.update_mtx, "migration_info_update");
balance_info.forced_check_balance = 0;
balance_info.halftime = 1;
balance_info.full_reds_history_index = 0;
- erts_smp_atomic_init(&balance_info.checking_balance, 0);
+ erts_smp_atomic32_init(&balance_info.checking_balance, 0);
balance_info.prev_rise.active_runqs = 0;
balance_info.prev_rise.max_len = 0;
balance_info.prev_rise.reds = 0;
@@ -2623,8 +2717,8 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
if (no_schedulers_online < no_schedulers) {
if (erts_common_run_queue) {
for (ix = no_schedulers_online; ix < no_schedulers; ix++)
- erts_smp_atomic_bor(&ERTS_SCHED_SLEEP_INFO_IX(ix)->flags,
- ERTS_SSI_FLG_SUSPENDED);
+ erts_smp_atomic32_bor(&ERTS_SCHED_SLEEP_INFO_IX(ix)->flags,
+ ERTS_SSI_FLG_SUSPENDED);
}
else {
for (ix = no_schedulers_online; ix < erts_no_run_queues; ix++)
@@ -2638,7 +2732,9 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
ERTS_SCHDLR_SSPND_CHNG_SET((ERTS_SCHDLR_SSPND_CHNG_ONLN
| ERTS_SCHDLR_SSPND_CHNG_WAITER), 0);
- erts_smp_atomic_init(&doing_sys_schedule, 0);
+ erts_smp_atomic32_init(&doing_sys_schedule, 0);
+
+ init_misc_aux_work();
#else /* !ERTS_SMP */
{
@@ -2652,12 +2748,19 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
erts_no_schedulers = 1;
#endif
- erts_smp_atomic_init(&function_calls, 0);
+ erts_smp_atomic32_init(&function_calls, 0);
/* init port tasks */
erts_port_task_init();
- late_cpu_bind_init();
+#ifndef ERTS_SMP
+#ifdef ERTS_DO_VERIFY_UNUSED_TEMP_ALLOC
+ erts_scheduler_data->verify_unused_temp_alloc
+ = erts_alloc_get_verify_unused_temp_alloc(
+ &erts_scheduler_data->verify_unused_temp_alloc_data);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(NULL);
+#endif
+#endif
}
ErtsRunQueue *
@@ -2769,6 +2872,19 @@ resume_process(Process *p)
p->rstatus = P_FREE;
}
+int
+erts_get_max_no_executing_schedulers(void)
+{
+#ifdef ERTS_SMP
+ if (erts_smp_atomic32_read(&schdlr_sspnd.changing))
+ return (int) erts_no_schedulers;
+ ERTS_THR_MEMORY_BARRIER;
+ return (int) erts_smp_atomic32_read(&schdlr_sspnd.active);
+#else
+ return 1;
+#endif
+}
+
#ifdef ERTS_SMP
static void
@@ -2787,13 +2903,13 @@ static void
scheduler_ix_resume_wake(Uint ix)
{
ErtsSchedulerSleepInfo *ssi = ERTS_SCHED_SLEEP_INFO_IX(ix);
- long xflgs = (ERTS_SSI_FLG_SLEEPING
- | ERTS_SSI_FLG_TSE_SLEEPING
- | ERTS_SSI_FLG_WAITING
- | ERTS_SSI_FLG_SUSPENDED);
- long oflgs;
+ erts_aint32_t xflgs = (ERTS_SSI_FLG_SLEEPING
+ | ERTS_SSI_FLG_TSE_SLEEPING
+ | ERTS_SSI_FLG_WAITING
+ | ERTS_SSI_FLG_SUSPENDED);
+ erts_aint32_t oflgs;
do {
- oflgs = erts_smp_atomic_cmpxchg(&ssi->flags, 0, xflgs);
+ oflgs = erts_smp_atomic32_cmpxchg(&ssi->flags, 0, xflgs);
if (oflgs == xflgs) {
erts_sched_finish_poke(ssi, oflgs);
break;
@@ -2802,17 +2918,17 @@ scheduler_ix_resume_wake(Uint ix)
} while (oflgs & ERTS_SSI_FLG_SUSPENDED);
}
-static long
-sched_prep_spin_suspended(ErtsSchedulerSleepInfo *ssi, long xpct)
+static erts_aint32_t
+sched_prep_spin_suspended(ErtsSchedulerSleepInfo *ssi, erts_aint32_t xpct)
{
- long oflgs;
- long nflgs = (ERTS_SSI_FLG_SLEEPING
- | ERTS_SSI_FLG_WAITING
- | ERTS_SSI_FLG_SUSPENDED);
- long xflgs = xpct;
+ erts_aint32_t oflgs;
+ erts_aint32_t nflgs = (ERTS_SSI_FLG_SLEEPING
+ | ERTS_SSI_FLG_WAITING
+ | ERTS_SSI_FLG_SUSPENDED);
+ erts_aint32_t xflgs = xpct;
do {
- oflgs = erts_smp_atomic_cmpxchg(&ssi->flags, nflgs, xflgs);
+ oflgs = erts_smp_atomic32_cmpxchg(&ssi->flags, nflgs, xflgs);
if (oflgs == xflgs)
return nflgs;
xflgs = oflgs;
@@ -2821,15 +2937,15 @@ sched_prep_spin_suspended(ErtsSchedulerSleepInfo *ssi, long xpct)
return oflgs;
}
-static long
+static erts_aint32_t
sched_spin_suspended(ErtsSchedulerSleepInfo *ssi, int spincount)
{
int until_yield = ERTS_SCHED_SPIN_UNTIL_YIELD;
int sc = spincount;
- long flgs;
+ erts_aint32_t flgs;
do {
- flgs = erts_smp_atomic_read(&ssi->flags);
+ flgs = erts_smp_atomic32_read(&ssi->flags);
if ((flgs & (ERTS_SSI_FLG_SLEEPING
| ERTS_SSI_FLG_WAITING
| ERTS_SSI_FLG_SUSPENDED))
@@ -2847,22 +2963,22 @@ sched_spin_suspended(ErtsSchedulerSleepInfo *ssi, int spincount)
return flgs;
}
-static long
+static erts_aint32_t
sched_set_suspended_sleeptype(ErtsSchedulerSleepInfo *ssi)
{
- long oflgs;
- long nflgs = (ERTS_SSI_FLG_SLEEPING
- | ERTS_SSI_FLG_TSE_SLEEPING
- | ERTS_SSI_FLG_WAITING
- | ERTS_SSI_FLG_SUSPENDED);
- long xflgs = (ERTS_SSI_FLG_SLEEPING
- | ERTS_SSI_FLG_WAITING
- | ERTS_SSI_FLG_SUSPENDED);
+ erts_aint32_t oflgs;
+ erts_aint32_t nflgs = (ERTS_SSI_FLG_SLEEPING
+ | ERTS_SSI_FLG_TSE_SLEEPING
+ | ERTS_SSI_FLG_WAITING
+ | ERTS_SSI_FLG_SUSPENDED);
+ erts_aint32_t xflgs = (ERTS_SSI_FLG_SLEEPING
+ | ERTS_SSI_FLG_WAITING
+ | ERTS_SSI_FLG_SUSPENDED);
erts_tse_reset(ssi->event);
while (1) {
- oflgs = erts_smp_atomic_cmpxchg(&ssi->flags, nflgs, xflgs);
+ oflgs = erts_smp_atomic32_cmpxchg(&ssi->flags, nflgs, xflgs);
if (oflgs == xflgs)
return nflgs;
if ((oflgs & (ERTS_SSI_FLG_SLEEPING
@@ -2880,18 +2996,16 @@ sched_set_suspended_sleeptype(ErtsSchedulerSleepInfo *ssi)
static void
suspend_scheduler(ErtsSchedulerData *esdp)
{
- long flgs;
- int changing;
+ erts_aint32_t flgs;
+ erts_aint32_t changing;
long no = (long) esdp->no;
- ErtsRunQueue *rq = esdp->run_queue;
ErtsSchedulerSleepInfo *ssi = esdp->ssi;
long active_schedulers;
int curr_online = 1;
int wake = 0;
- int reset_read_group = 0;
#if defined(ERTS_SCHED_NEED_NONBLOCKABLE_AUX_WORK) \
|| defined(ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK)
- long aux_work;
+ erts_aint32_t aux_work;
#endif
/*
@@ -2909,20 +3023,7 @@ suspend_scheduler(ErtsSchedulerData *esdp)
erts_smp_runq_unlock(esdp->run_queue);
- /* Unbind from cpu */
- erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx);
- if (scheduler2cpu_map[esdp->no].bound_id >= 0
- && erts_unbind_from_cpu(erts_cpuinfo) == 0) {
- esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = -1;
- reset_read_group = 1;
- }
- erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx);
-
- if (reset_read_group)
- erts_smp_rwmtx_set_reader_group(0);
-
- if (esdp->no <= erts_max_main_threads)
- erts_thr_set_main_status(0, 0);
+ erts_sched_check_cpu_bind_prep_suspend(esdp);
if (erts_system_profile_flags.scheduler)
profile_scheduler(make_small(esdp->no), am_inactive);
@@ -2932,15 +3033,15 @@ suspend_scheduler(ErtsSchedulerData *esdp)
flgs = sched_prep_spin_suspended(ssi, ERTS_SSI_FLG_SUSPENDED);
if (flgs & ERTS_SSI_FLG_SUSPENDED) {
- active_schedulers = erts_smp_atomic_dectest(&schdlr_sspnd.active);
+ active_schedulers = erts_smp_atomic32_dectest(&schdlr_sspnd.active);
ASSERT(active_schedulers >= 1);
- changing = erts_smp_atomic_read(&schdlr_sspnd.changing);
+ changing = erts_smp_atomic32_read(&schdlr_sspnd.changing);
if (changing & ERTS_SCHDLR_SSPND_CHNG_MSB) {
if (active_schedulers == schdlr_sspnd.msb.wait_active)
wake = 1;
if (active_schedulers == 1) {
- changing = erts_smp_atomic_band(&schdlr_sspnd.changing,
- ~ERTS_SCHDLR_SSPND_CHNG_MSB);
+ changing = erts_smp_atomic32_band(&schdlr_sspnd.changing,
+ ~ERTS_SCHDLR_SSPND_CHNG_MSB);
changing &= ~ERTS_SCHDLR_SSPND_CHNG_MSB;
}
}
@@ -2962,8 +3063,8 @@ suspend_scheduler(ErtsSchedulerData *esdp)
&& schdlr_sspnd.curr_online == schdlr_sspnd.wait_curr_online)
wake = 1;
if (schdlr_sspnd.online == schdlr_sspnd.curr_online) {
- changing = erts_smp_atomic_band(&schdlr_sspnd.changing,
- ~ERTS_SCHDLR_SSPND_CHNG_ONLN);
+ changing = erts_smp_atomic32_band(&schdlr_sspnd.changing,
+ ~ERTS_SCHDLR_SSPND_CHNG_ONLN);
changing &= ~ERTS_SCHDLR_SSPND_CHNG_ONLN;
}
}
@@ -2973,29 +3074,30 @@ suspend_scheduler(ErtsSchedulerData *esdp)
wake = 0;
}
- flgs = erts_smp_atomic_read(&ssi->flags);
+ flgs = erts_smp_atomic32_read(&ssi->flags);
if (!(flgs & ERTS_SSI_FLG_SUSPENDED))
break;
erts_smp_mtx_unlock(&schdlr_sspnd.mtx);
#ifdef ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
- aux_work = erts_smp_atomic_read(&ssi->aux_work);
+ aux_work = erts_smp_atomic32_read(&ssi->aux_work);
blockable_aux_work:
blockable_aux_work(esdp, ssi, aux_work);
#endif
erts_smp_activity_begin(ERTS_ACTIVITY_WAIT, NULL, NULL, NULL);
while (1) {
- long flgs;
+ erts_aint32_t flgs;
#ifdef ERTS_SCHED_NEED_NONBLOCKABLE_AUX_WORK
#ifndef ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
- aux_work = erts_smp_atomic_read(&ssi->aux_work);
+ aux_work = erts_smp_atomic32_read(&ssi->aux_work);
#endif
nonblockable_aux_work(esdp, ssi, aux_work);
#endif
- flgs = sched_spin_suspended(ssi, ERTS_SCHED_SUSPEND_SLEEP_SPINCOUNT);
+ flgs = sched_spin_suspended(ssi,
+ ERTS_SCHED_SUSPEND_SLEEP_SPINCOUNT);
if (flgs == (ERTS_SSI_FLG_SLEEPING
| ERTS_SSI_FLG_WAITING
| ERTS_SSI_FLG_SUSPENDED)) {
@@ -3015,13 +3117,13 @@ suspend_scheduler(ErtsSchedulerData *esdp)
| ERTS_SSI_FLG_SUSPENDED));
if (!(flgs & ERTS_SSI_FLG_SUSPENDED))
break;
- changing = erts_smp_atomic_read(&schdlr_sspnd.changing);
+ changing = erts_smp_atomic32_read(&schdlr_sspnd.changing);
if (changing & ~ERTS_SCHDLR_SSPND_CHNG_WAITER)
break;
#ifdef ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
- aux_work = erts_smp_atomic_read(&ssi->aux_work);
+ aux_work = erts_smp_atomic32_read(&ssi->aux_work);
if (aux_work & ERTS_SSI_BLOCKABLE_AUX_WORK_MASK) {
erts_smp_activity_end(ERTS_ACTIVITY_WAIT, NULL, NULL, NULL);
goto blockable_aux_work;
@@ -3033,19 +3135,19 @@ suspend_scheduler(ErtsSchedulerData *esdp)
erts_smp_activity_end(ERTS_ACTIVITY_WAIT, NULL, NULL, NULL);
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
- changing = erts_smp_atomic_read(&schdlr_sspnd.changing);
+ changing = erts_smp_atomic32_read(&schdlr_sspnd.changing);
}
- active_schedulers = erts_smp_atomic_inctest(&schdlr_sspnd.active);
- changing = erts_smp_atomic_read(&schdlr_sspnd.changing);
+ active_schedulers = erts_smp_atomic32_inctest(&schdlr_sspnd.active);
+ changing = erts_smp_atomic32_read(&schdlr_sspnd.changing);
if ((changing & ERTS_SCHDLR_SSPND_CHNG_MSB)
&& schdlr_sspnd.online == active_schedulers) {
- erts_smp_atomic_band(&schdlr_sspnd.changing,
- ~ERTS_SCHDLR_SSPND_CHNG_MSB);
+ erts_smp_atomic32_band(&schdlr_sspnd.changing,
+ ~ERTS_SCHDLR_SSPND_CHNG_MSB);
}
ASSERT(no <= schdlr_sspnd.online);
- ASSERT(!erts_smp_atomic_read(&schdlr_sspnd.msb.ongoing));
+ ASSERT(!erts_smp_atomic32_read(&schdlr_sspnd.msb.ongoing));
}
@@ -3056,17 +3158,10 @@ suspend_scheduler(ErtsSchedulerData *esdp)
if (erts_system_profile_flags.scheduler)
profile_scheduler(make_small(esdp->no), am_active);
- if (esdp->no <= erts_max_main_threads)
- erts_thr_set_main_status(1, (int) esdp->no);
-
erts_smp_runq_lock(esdp->run_queue);
non_empty_runq(esdp->run_queue);
- /* Make sure we check if we should bind to a cpu or not... */
- if (rq->flags & ERTS_RUNQ_FLG_SHARED_RUNQ)
- erts_smp_atomic_set(&esdp->chk_cpu_bind, 1);
- else
- rq->flags |= ERTS_RUNQ_FLG_CHK_CPU_BIND;
+ erts_sched_check_cpu_bind_post_suspend(esdp);
}
#define ERTS_RUNQ_RESET_SUSPEND_INFO(RQ, DBG_ID) \
@@ -3081,7 +3176,7 @@ do { \
(RQ)->flags |= (ERTS_RUNQ_FLG_OUT_OF_WORK \
| ERTS_RUNQ_FLG_HALFTIME_OUT_OF_WORK); \
(RQ)->check_balance_reds = ERTS_RUNQ_CALL_CHECK_BALANCE_REDS; \
- erts_smp_atomic_band(&(RQ)->info_flags, ~ERTS_RUNQ_IFLG_SUSPENDED); \
+ erts_smp_atomic32_band(&(RQ)->info_flags, ~ERTS_RUNQ_IFLG_SUSPENDED);\
for (pix__ = 0; pix__ < ERTS_NO_PROC_PRIO_LEVELS; pix__++) { \
(RQ)->procs.prio_info[pix__].max_len = 0; \
(RQ)->procs.prio_info[pix__].reds = 0; \
@@ -3123,9 +3218,9 @@ erts_schedulers_state(Uint *total,
int yield_allowed)
{
int res;
- long changing;
+ erts_aint32_t changing;
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
- changing = erts_smp_atomic_read(&schdlr_sspnd.changing);
+ changing = erts_smp_atomic32_read(&schdlr_sspnd.changing);
if (yield_allowed && (changing & ~ERTS_SCHDLR_SSPND_CHNG_WAITER))
res = ERTS_SCHDLR_SSPND_YIELD_RESTART;
else {
@@ -3146,7 +3241,7 @@ erts_set_schedulers_online(Process *p,
Sint *old_no)
{
int ix, res, no, have_unlocked_plocks;
- long changing;
+ erts_aint32_t changing;
if (new_no < 1 || erts_no_schedulers < new_no)
return ERTS_SCHDLR_SSPND_EINVAL;
@@ -3156,7 +3251,7 @@ erts_set_schedulers_online(Process *p,
have_unlocked_plocks = 0;
no = (int) new_no;
- changing = erts_smp_atomic_read(&schdlr_sspnd.changing);
+ changing = erts_smp_atomic32_read(&schdlr_sspnd.changing);
if (changing) {
res = ERTS_SCHDLR_SSPND_YIELD_RESTART;
}
@@ -3203,7 +3298,7 @@ erts_set_schedulers_online(Process *p,
ErtsRunQueue *to_rq = ERTS_RUNQ_IX(ix % no);
evacuate_run_queue(from_rq, to_rq);
}
- erts_smp_atomic_set(&balance_info.used_runqs, no);
+ erts_smp_atomic32_set(&balance_info.used_runqs, no);
erts_smp_mtx_unlock(&balance_info.update_mtx);
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
}
@@ -3231,8 +3326,8 @@ erts_set_schedulers_online(Process *p,
for (ix = no; ix < online; ix++) {
ErtsSchedulerSleepInfo *ssi;
ssi = ERTS_SCHED_SLEEP_INFO_IX(ix);
- erts_smp_atomic_bor(&ssi->flags,
- ERTS_SSI_FLG_SUSPENDED);
+ erts_smp_atomic32_bor(&ssi->flags,
+ ERTS_SSI_FLG_SUSPENDED);
}
wake_all_schedulers();
}
@@ -3257,7 +3352,7 @@ erts_set_schedulers_online(Process *p,
for (ix = erts_no_run_queues-1; ix >= no; ix--)
evacuate_run_queue(ERTS_RUNQ_IX(ix),
ERTS_RUNQ_IX(ix % no));
- erts_smp_atomic_set(&balance_info.used_runqs, no);
+ erts_smp_atomic32_set(&balance_info.used_runqs, no);
erts_smp_mtx_unlock(&balance_info.update_mtx);
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
for (ix = no; ix < online; ix++) {
@@ -3279,10 +3374,11 @@ erts_set_schedulers_online(Process *p,
NULL);
ASSERT(res != ERTS_SCHDLR_SSPND_DONE
? (ERTS_SCHDLR_SSPND_CHNG_WAITER
- & erts_smp_atomic_read(&schdlr_sspnd.changing))
+ & erts_smp_atomic32_read(&schdlr_sspnd.changing))
: (ERTS_SCHDLR_SSPND_CHNG_WAITER
- == erts_smp_atomic_read(&schdlr_sspnd.changing)));
- erts_smp_atomic_band(&schdlr_sspnd.changing, ~ERTS_SCHDLR_SSPND_CHNG_WAITER);
+ == erts_smp_atomic32_read(&schdlr_sspnd.changing)));
+ erts_smp_atomic32_band(&schdlr_sspnd.changing,
+ ~ERTS_SCHDLR_SSPND_CHNG_WAITER);
}
}
@@ -3297,11 +3393,11 @@ ErtsSchedSuspendResult
erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
{
int ix, res, have_unlocked_plocks = 0;
- long changing;
+ erts_aint32_t changing;
ErtsProcList *plp;
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
- changing = erts_smp_atomic_read(&schdlr_sspnd.changing);
+ changing = erts_smp_atomic32_read(&schdlr_sspnd.changing);
if (changing) {
res = ERTS_SCHDLR_SSPND_YIELD_RESTART; /* Yield */
}
@@ -3311,7 +3407,7 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
plp->next = schdlr_sspnd.msb.procs;
schdlr_sspnd.msb.procs = plp;
p->flags |= F_HAVE_BLCKD_MSCHED;
- ASSERT(erts_smp_atomic_read(&schdlr_sspnd.active) == 1);
+ ASSERT(erts_smp_atomic32_read(&schdlr_sspnd.active) == 1);
ASSERT(p->scheduler_data->no == 1);
res = ERTS_SCHDLR_SSPND_DONE_MSCHED_BLOCKED;
}
@@ -3322,11 +3418,11 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
have_unlocked_plocks = 1;
erts_smp_proc_unlock(p, plocks);
}
- ASSERT(0 == erts_smp_atomic_read(&schdlr_sspnd.msb.ongoing));
- erts_smp_atomic_set(&schdlr_sspnd.msb.ongoing, 1);
+ ASSERT(0 == erts_smp_atomic32_read(&schdlr_sspnd.msb.ongoing));
+ erts_smp_atomic32_set(&schdlr_sspnd.msb.ongoing, 1);
if (online == 1) {
res = ERTS_SCHDLR_SSPND_DONE_MSCHED_BLOCKED;
- ASSERT(erts_smp_atomic_read(&schdlr_sspnd.active) == 1);
+ ASSERT(erts_smp_atomic32_read(&schdlr_sspnd.active) == 1);
ASSERT(p->scheduler_data->no == 1);
}
else {
@@ -3346,14 +3442,14 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
}
if (erts_common_run_queue) {
for (ix = 1; ix < online; ix++)
- erts_smp_atomic_bor(&ERTS_SCHED_SLEEP_INFO_IX(ix)->flags,
- ERTS_SSI_FLG_SUSPENDED);
+ erts_smp_atomic32_bor(&ERTS_SCHED_SLEEP_INFO_IX(ix)->flags,
+ ERTS_SSI_FLG_SUSPENDED);
wake_all_schedulers();
}
else {
erts_smp_mtx_unlock(&schdlr_sspnd.mtx);
erts_smp_mtx_lock(&balance_info.update_mtx);
- erts_smp_atomic_set(&balance_info.used_runqs, 1);
+ erts_smp_atomic32_set(&balance_info.used_runqs, 1);
for (ix = 0; ix < online; ix++) {
ErtsRunQueue *rq = ERTS_RUNQ_IX(ix);
erts_smp_runq_lock(rq);
@@ -3375,7 +3471,7 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
susp_sched_prep_block,
susp_sched_resume_block,
NULL);
- while (erts_smp_atomic_read(&schdlr_sspnd.active)
+ while (erts_smp_atomic32_read(&schdlr_sspnd.active)
!= schdlr_sspnd.msb.wait_active)
erts_smp_cnd_wait(&schdlr_sspnd.cnd, &schdlr_sspnd.mtx);
erts_smp_activity_end(ERTS_ACTIVITY_WAIT,
@@ -3384,11 +3480,11 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
NULL);
ASSERT(res != ERTS_SCHDLR_SSPND_DONE_MSCHED_BLOCKED
? (ERTS_SCHDLR_SSPND_CHNG_WAITER
- & erts_smp_atomic_read(&schdlr_sspnd.changing))
+ & erts_smp_atomic32_read(&schdlr_sspnd.changing))
: (ERTS_SCHDLR_SSPND_CHNG_WAITER
- == erts_smp_atomic_read(&schdlr_sspnd.changing)));
- erts_smp_atomic_band(&schdlr_sspnd.changing,
- ~ERTS_SCHDLR_SSPND_CHNG_WAITER);
+ == erts_smp_atomic32_read(&schdlr_sspnd.changing)));
+ erts_smp_atomic32_band(&schdlr_sspnd.changing,
+ ~ERTS_SCHDLR_SSPND_CHNG_WAITER);
}
plp = proclist_create(p);
plp->next = schdlr_sspnd.msb.procs;
@@ -3455,16 +3551,16 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
});
#endif
p->flags &= ~F_HAVE_BLCKD_MSCHED;
- erts_smp_atomic_set(&schdlr_sspnd.msb.ongoing, 0);
+ erts_smp_atomic32_set(&schdlr_sspnd.msb.ongoing, 0);
if (schdlr_sspnd.online == 1) {
/* No schedulers to resume */
- ASSERT(erts_smp_atomic_read(&schdlr_sspnd.active) == 1);
+ ASSERT(erts_smp_atomic32_read(&schdlr_sspnd.active) == 1);
ERTS_SCHDLR_SSPND_CHNG_SET(0, ERTS_SCHDLR_SSPND_CHNG_MSB);
}
else if (erts_common_run_queue) {
for (ix = 1; ix < schdlr_sspnd.online; ix++)
- erts_smp_atomic_band(&ERTS_SCHED_SLEEP_INFO_IX(ix)->flags,
- ~ERTS_SSI_FLG_SUSPENDED);
+ erts_smp_atomic32_band(&ERTS_SCHED_SLEEP_INFO_IX(ix)->flags,
+ ~ERTS_SSI_FLG_SUSPENDED);
wake_all_schedulers();
}
else {
@@ -3490,7 +3586,7 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
evacuate_run_queue(ERTS_RUNQ_IX(ix),
ERTS_RUNQ_IX(ix % online));
- erts_smp_atomic_set(&balance_info.used_runqs, online);
+ erts_smp_atomic32_set(&balance_info.used_runqs, online);
/* Make sure that we balance soon... */
balance_info.forced_check_balance = 1;
erts_smp_runq_lock(ERTS_RUNQ_IX(0));
@@ -3514,7 +3610,7 @@ void
erts_dbg_multi_scheduling_return_trap(Process *p, Eterm return_value)
{
if (return_value == am_blocked) {
- long active = erts_smp_atomic_read(&schdlr_sspnd.active);
+ erts_aint32_t active = erts_smp_atomic32_read(&schdlr_sspnd.active);
ASSERT(1 <= active && active <= 2);
ASSERT(ERTS_PROC_GET_SCHDATA(p)->no == 1);
}
@@ -3583,15 +3679,7 @@ sched_thread_func(void *vesdp)
erts_tsd_set(sched_data_key, vesdp);
#ifdef ERTS_SMP
- if (no <= erts_max_main_threads) {
- erts_thr_set_main_status(1, (int) no);
- if (erts_reader_groups) {
- int rg = (int) no;
- if (rg > erts_reader_groups)
- rg = (((int) no) - 1) % erts_reader_groups + 1;
- erts_smp_rwmtx_set_reader_group(rg);
- }
- }
+ erts_sched_init_check_cpu_bind((ErtsSchedulerData *) vesdp);
erts_proc_lock_prepare_proc_lock_waiter();
ERTS_SCHED_SLEEP_INFO_IX(no - 1)->event = erts_tse_fetch();
@@ -3605,12 +3693,12 @@ sched_thread_func(void *vesdp)
erts_thread_init_float();
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
- ASSERT(erts_smp_atomic_read(&schdlr_sspnd.changing)
+ ASSERT(erts_smp_atomic32_read(&schdlr_sspnd.changing)
& ERTS_SCHDLR_SSPND_CHNG_ONLN);
if (--schdlr_sspnd.curr_online == schdlr_sspnd.wait_curr_online) {
- erts_smp_atomic_band(&schdlr_sspnd.changing,
- ~ERTS_SCHDLR_SSPND_CHNG_ONLN);
+ erts_smp_atomic32_band(&schdlr_sspnd.changing,
+ ~ERTS_SCHDLR_SSPND_CHNG_ONLN);
if (((ErtsSchedulerData *) vesdp)->no != 1)
erts_smp_cnd_signal(&schdlr_sspnd.cnd);
}
@@ -3632,6 +3720,13 @@ sched_thread_func(void *vesdp)
}
erts_smp_mtx_unlock(&schdlr_sspnd.mtx);
+#ifdef ERTS_DO_VERIFY_UNUSED_TEMP_ALLOC
+ ((ErtsSchedulerData *) vesdp)->verify_unused_temp_alloc
+ = erts_alloc_get_verify_unused_temp_alloc(
+ &((ErtsSchedulerData *) vesdp)->verify_unused_temp_alloc_data);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(NULL);
+#endif
+
process_main();
/* No schedulers should *ever* terminate */
erl_exit(ERTS_ABORT_EXIT, "Scheduler thread number %bpu terminated\n",
@@ -3693,1907 +3788,6 @@ erts_start_schedulers(void)
#endif /* ERTS_SMP */
-static int
-int_cmp(const void *vx, const void *vy)
-{
- return *((int *) vx) - *((int *) vy);
-}
-
-static int
-cpu_spread_order_cmp(const void *vx, const void *vy)
-{
- erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
- erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
-
- if (x->thread != y->thread)
- return x->thread - y->thread;
- if (x->core != y->core)
- return x->core - y->core;
- if (x->processor_node != y->processor_node)
- return x->processor_node - y->processor_node;
- if (x->processor != y->processor)
- return x->processor - y->processor;
- if (x->node != y->node)
- return x->node - y->node;
- return 0;
-}
-
-static int
-cpu_processor_spread_order_cmp(const void *vx, const void *vy)
-{
- erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
- erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
-
- if (x->thread != y->thread)
- return x->thread - y->thread;
- if (x->processor_node != y->processor_node)
- return x->processor_node - y->processor_node;
- if (x->core != y->core)
- return x->core - y->core;
- if (x->node != y->node)
- return x->node - y->node;
- if (x->processor != y->processor)
- return x->processor - y->processor;
- return 0;
-}
-
-static int
-cpu_thread_spread_order_cmp(const void *vx, const void *vy)
-{
- erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
- erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
-
- if (x->thread != y->thread)
- return x->thread - y->thread;
- if (x->node != y->node)
- return x->node - y->node;
- if (x->processor != y->processor)
- return x->processor - y->processor;
- if (x->processor_node != y->processor_node)
- return x->processor_node - y->processor_node;
- if (x->core != y->core)
- return x->core - y->core;
- return 0;
-}
-
-static int
-cpu_thread_no_node_processor_spread_order_cmp(const void *vx, const void *vy)
-{
- erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
- erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
-
- if (x->thread != y->thread)
- return x->thread - y->thread;
- if (x->node != y->node)
- return x->node - y->node;
- if (x->core != y->core)
- return x->core - y->core;
- if (x->processor != y->processor)
- return x->processor - y->processor;
- return 0;
-}
-
-static int
-cpu_no_node_processor_spread_order_cmp(const void *vx, const void *vy)
-{
- erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
- erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
-
- if (x->node != y->node)
- return x->node - y->node;
- if (x->thread != y->thread)
- return x->thread - y->thread;
- if (x->core != y->core)
- return x->core - y->core;
- if (x->processor != y->processor)
- return x->processor - y->processor;
- return 0;
-}
-
-static int
-cpu_no_node_thread_spread_order_cmp(const void *vx, const void *vy)
-{
- erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
- erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
-
- if (x->node != y->node)
- return x->node - y->node;
- if (x->thread != y->thread)
- return x->thread - y->thread;
- if (x->processor != y->processor)
- return x->processor - y->processor;
- if (x->core != y->core)
- return x->core - y->core;
- return 0;
-}
-
-static int
-cpu_no_spread_order_cmp(const void *vx, const void *vy)
-{
- erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
- erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
-
- if (x->node != y->node)
- return x->node - y->node;
- if (x->processor != y->processor)
- return x->processor - y->processor;
- if (x->processor_node != y->processor_node)
- return x->processor_node - y->processor_node;
- if (x->core != y->core)
- return x->core - y->core;
- if (x->thread != y->thread)
- return x->thread - y->thread;
- return 0;
-}
-
-static ERTS_INLINE void
-make_cpudata_id_seq(erts_cpu_topology_t *cpudata, int size, int no_node)
-{
- int ix;
- int node = -1;
- int processor = -1;
- int processor_node = -1;
- int processor_node_node = -1;
- int core = -1;
- int thread = -1;
- int old_node = -1;
- int old_processor = -1;
- int old_processor_node = -1;
- int old_core = -1;
- int old_thread = -1;
-
- for (ix = 0; ix < size; ix++) {
- if (!no_node || cpudata[ix].node >= 0) {
- if (old_node == cpudata[ix].node)
- cpudata[ix].node = node;
- else {
- old_node = cpudata[ix].node;
- old_processor = processor = -1;
- if (!no_node)
- old_processor_node = processor_node = -1;
- old_core = core = -1;
- old_thread = thread = -1;
- if (no_node || cpudata[ix].node >= 0)
- cpudata[ix].node = ++node;
- }
- }
- if (old_processor == cpudata[ix].processor)
- cpudata[ix].processor = processor;
- else {
- old_processor = cpudata[ix].processor;
- if (!no_node)
- processor_node_node = old_processor_node = processor_node = -1;
- old_core = core = -1;
- old_thread = thread = -1;
- cpudata[ix].processor = ++processor;
- }
- if (no_node && cpudata[ix].processor_node < 0)
- old_processor_node = -1;
- else {
- if (old_processor_node == cpudata[ix].processor_node) {
- if (no_node)
- cpudata[ix].node = cpudata[ix].processor_node = node;
- else {
- if (processor_node_node >= 0)
- cpudata[ix].node = processor_node_node;
- cpudata[ix].processor_node = processor_node;
- }
- }
- else {
- old_processor_node = cpudata[ix].processor_node;
- old_core = core = -1;
- old_thread = thread = -1;
- if (no_node)
- cpudata[ix].node = cpudata[ix].processor_node = ++node;
- else {
- cpudata[ix].node = processor_node_node = ++node;
- cpudata[ix].processor_node = ++processor_node;
- }
- }
- }
- if (!no_node && cpudata[ix].processor_node < 0)
- cpudata[ix].processor_node = 0;
- if (old_core == cpudata[ix].core)
- cpudata[ix].core = core;
- else {
- old_core = cpudata[ix].core;
- old_thread = thread = -1;
- cpudata[ix].core = ++core;
- }
- if (old_thread == cpudata[ix].thread)
- cpudata[ix].thread = thread;
- else
- old_thread = cpudata[ix].thread = ++thread;
- }
-}
-
-static void
-cpu_bind_order_sort(erts_cpu_topology_t *cpudata,
- int size,
- ErtsCpuBindOrder bind_order,
- int mk_seq)
-{
- if (size > 1) {
- int no_node = 0;
- int (*cmp_func)(const void *, const void *);
- switch (bind_order) {
- case ERTS_CPU_BIND_SPREAD:
- cmp_func = cpu_spread_order_cmp;
- break;
- case ERTS_CPU_BIND_PROCESSOR_SPREAD:
- cmp_func = cpu_processor_spread_order_cmp;
- break;
- case ERTS_CPU_BIND_THREAD_SPREAD:
- cmp_func = cpu_thread_spread_order_cmp;
- break;
- case ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD:
- no_node = 1;
- cmp_func = cpu_thread_no_node_processor_spread_order_cmp;
- break;
- case ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD:
- no_node = 1;
- cmp_func = cpu_no_node_processor_spread_order_cmp;
- break;
- case ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD:
- no_node = 1;
- cmp_func = cpu_no_node_thread_spread_order_cmp;
- break;
- case ERTS_CPU_BIND_NO_SPREAD:
- cmp_func = cpu_no_spread_order_cmp;
- break;
- default:
- cmp_func = NULL;
- erl_exit(ERTS_ABORT_EXIT,
- "Bad cpu bind type: %d\n",
- (int) cpu_bind_order);
- break;
- }
-
- if (mk_seq)
- make_cpudata_id_seq(cpudata, size, no_node);
-
- qsort(cpudata, size, sizeof(erts_cpu_topology_t), cmp_func);
- }
-}
-
-static int
-processor_order_cmp(const void *vx, const void *vy)
-{
- erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx;
- erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy;
-
- if (x->processor != y->processor)
- return x->processor - y->processor;
- if (x->node != y->node)
- return x->node - y->node;
- if (x->processor_node != y->processor_node)
- return x->processor_node - y->processor_node;
- if (x->core != y->core)
- return x->core - y->core;
- if (x->thread != y->thread)
- return x->thread - y->thread;
- return 0;
-}
-
-static void
-check_cpu_bind(ErtsSchedulerData *esdp)
-{
- int rg = 0;
- int res;
- int cpu_id;
- erts_smp_runq_unlock(esdp->run_queue);
- erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx);
- cpu_id = scheduler2cpu_map[esdp->no].bind_id;
- if (cpu_id >= 0 && cpu_id != scheduler2cpu_map[esdp->no].bound_id) {
- res = erts_bind_to_cpu(erts_cpuinfo, cpu_id);
- if (res == 0)
- esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = cpu_id;
- else {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- erts_dsprintf(dsbufp, "Scheduler %d failed to bind to cpu %d: %s\n",
- (int) esdp->no, cpu_id, erl_errno_id(-res));
- erts_send_error_to_logger_nogl(dsbufp);
- if (scheduler2cpu_map[esdp->no].bound_id >= 0)
- goto unbind;
- }
- }
- else if (cpu_id < 0) {
- unbind:
- /* Get rid of old binding */
- res = erts_unbind_from_cpu(erts_cpuinfo);
- if (res == 0)
- esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = -1;
- else if (res != -ENOTSUP) {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- erts_dsprintf(dsbufp, "Scheduler %d failed to unbind from cpu %d: %s\n",
- (int) esdp->no, cpu_id, erl_errno_id(-res));
- erts_send_error_to_logger_nogl(dsbufp);
- }
- }
- if (erts_reader_groups) {
- if (esdp->cpu_id >= 0)
- rg = reader_group_lookup(esdp->cpu_id);
- else
- rg = (((int) esdp->no) - 1) % erts_reader_groups + 1;
- }
- erts_smp_runq_lock(esdp->run_queue);
-#ifdef ERTS_SMP
- if (erts_common_run_queue)
- erts_smp_atomic_set(&esdp->chk_cpu_bind, 0);
- else {
- esdp->run_queue->flags &= ~ERTS_RUNQ_FLG_CHK_CPU_BIND;
- }
-#endif
- erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx);
-
- if (erts_reader_groups)
- erts_smp_rwmtx_set_reader_group(rg);
-}
-
-static void
-signal_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size)
-{
- int s_ix = 1;
- int cpu_ix;
-
- if (cpu_bind_order != ERTS_CPU_BIND_NONE && size) {
-
- cpu_bind_order_sort(cpudata, size, cpu_bind_order, 1);
-
- for (cpu_ix = 0; cpu_ix < size && cpu_ix < erts_no_schedulers; cpu_ix++)
- if (erts_is_cpu_available(erts_cpuinfo, cpudata[cpu_ix].logical))
- scheduler2cpu_map[s_ix++].bind_id = cpudata[cpu_ix].logical;
- }
-
- if (s_ix <= erts_no_schedulers)
- for (; s_ix <= erts_no_schedulers; s_ix++)
- scheduler2cpu_map[s_ix].bind_id = -1;
-
-#ifdef ERTS_SMP
- if (erts_common_run_queue) {
- for (s_ix = 0; s_ix < erts_no_schedulers; s_ix++)
- erts_smp_atomic_set(&ERTS_SCHEDULER_IX(s_ix)->chk_cpu_bind, 1);
- wake_all_schedulers();
- }
- else {
- for (s_ix = 0; s_ix < erts_no_run_queues; s_ix++) {
- ErtsRunQueue *rq = ERTS_RUNQ_IX(s_ix);
- erts_smp_runq_lock(rq);
- rq->flags |= ERTS_RUNQ_FLG_CHK_CPU_BIND;
- erts_smp_runq_unlock(rq);
- wake_scheduler(rq, 0, 1);
- };
- }
-#else
- check_cpu_bind(erts_get_scheduler_data());
-#endif
-}
-
-int
-erts_init_scheduler_bind_type(char *how)
-{
- if (erts_bind_to_cpu(erts_cpuinfo, -1) == -ENOTSUP)
- return ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED;
-
- if (!system_cpudata && !user_cpudata)
- return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY;
-
- 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, "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;
- else if (sys_strcmp(how, "nnts") == 0)
- cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD;
- else if (sys_strcmp(how, "ns") == 0)
- cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD;
- else if (sys_strcmp(how, "u") == 0)
- cpu_bind_order = ERTS_CPU_BIND_NONE;
- else
- return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE;
-
- return ERTS_INIT_SCHED_BIND_TYPE_SUCCESS;
-}
-
-/*
- * reader groups map
- */
-
-typedef struct {
- int level[ERTS_TOPOLOGY_MAX_DEPTH+1];
-} erts_avail_cput;
-
-typedef struct {
- int *map;
- int size;
- int groups;
-} erts_reader_groups_map_test;
-
-typedef struct {
- int id;
- int sub_levels;
- int reader_groups;
-} erts_rg_count_t;
-
-typedef struct {
- int logical;
- int reader_group;
-} erts_reader_groups_map_t;
-
-typedef struct {
- erts_reader_groups_map_t *map;
- int map_size;
- int logical_processors;
- int groups;
-} erts_make_reader_groups_map_test;
-
-static int reader_groups_available_cpu_check;
-static int reader_groups_logical_processors;
-static int reader_groups_map_size;
-static erts_reader_groups_map_t *reader_groups_map;
-
-#define ERTS_TOPOLOGY_RG ERTS_TOPOLOGY_MAX_DEPTH
-
-static void
-make_reader_groups_map(erts_make_reader_groups_map_test *test);
-
-static Eterm
-get_reader_groups_map(Process *c_p,
- erts_reader_groups_map_t *map,
- int map_size,
- int logical_processors)
-{
-#ifdef DEBUG
- Eterm *endp;
-#endif
- Eterm res = NIL, tuple;
- Eterm *hp;
- int i;
-
- hp = HAlloc(c_p, logical_processors*(2+3));
-#ifdef DEBUG
- endp = hp + logical_processors*(2+3);
-#endif
- for (i = map_size - 1; i >= 0; i--) {
- if (map[i].logical >= 0) {
- tuple = TUPLE2(hp,
- make_small(map[i].logical),
- make_small(map[i].reader_group));
- hp += 3;
- res = CONS(hp, tuple, res);
- hp += 2;
- }
- }
- ASSERT(hp == endp);
- return res;
-}
-
-Eterm
-erts_debug_reader_groups_map(Process *c_p, int groups)
-{
- Eterm res;
- erts_make_reader_groups_map_test test;
-
- test.groups = groups;
- make_reader_groups_map(&test);
- if (!test.map)
- res = NIL;
- else {
- res = get_reader_groups_map(c_p,
- test.map,
- test.map_size,
- test.logical_processors);
- erts_free(ERTS_ALC_T_TMP, test.map);
- }
- return res;
-}
-
-
-Eterm
-erts_get_reader_groups_map(Process *c_p)
-{
- Eterm res;
- erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx);
- res = get_reader_groups_map(c_p,
- reader_groups_map,
- reader_groups_map_size,
- reader_groups_logical_processors);
- erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx);
- return res;
-}
-
-static void
-make_available_cpu_topology(erts_avail_cput *no,
- erts_avail_cput *avail,
- erts_cpu_topology_t *cpudata,
- int *size,
- int test)
-{
- int len = *size;
- erts_cpu_topology_t last;
- int a, i, j;
-
- no->level[ERTS_TOPOLOGY_NODE] = -1;
- no->level[ERTS_TOPOLOGY_PROCESSOR] = -1;
- no->level[ERTS_TOPOLOGY_PROCESSOR_NODE] = -1;
- no->level[ERTS_TOPOLOGY_CORE] = -1;
- no->level[ERTS_TOPOLOGY_THREAD] = -1;
- no->level[ERTS_TOPOLOGY_LOGICAL] = -1;
-
- last.node = INT_MIN;
- last.processor = INT_MIN;
- last.processor_node = INT_MIN;
- last.core = INT_MIN;
- last.thread = INT_MIN;
- last.logical = INT_MIN;
-
- a = 0;
-
- for (i = 0; i < len; i++) {
-
- if (!test && !erts_is_cpu_available(erts_cpuinfo, cpudata[i].logical))
- continue;
-
- if (last.node != cpudata[i].node)
- goto node;
- if (last.processor != cpudata[i].processor)
- goto processor;
- if (last.processor_node != cpudata[i].processor_node)
- goto processor_node;
- if (last.core != cpudata[i].core)
- goto core;
- ASSERT(last.thread != cpudata[i].thread);
- goto thread;
-
- node:
- no->level[ERTS_TOPOLOGY_NODE]++;
- processor:
- no->level[ERTS_TOPOLOGY_PROCESSOR]++;
- processor_node:
- no->level[ERTS_TOPOLOGY_PROCESSOR_NODE]++;
- core:
- no->level[ERTS_TOPOLOGY_CORE]++;
- thread:
- no->level[ERTS_TOPOLOGY_THREAD]++;
-
- no->level[ERTS_TOPOLOGY_LOGICAL]++;
-
- for (j = 0; j < ERTS_TOPOLOGY_LOGICAL; j++)
- avail[a].level[j] = no->level[j];
-
- avail[a].level[ERTS_TOPOLOGY_LOGICAL] = cpudata[i].logical;
- avail[a].level[ERTS_TOPOLOGY_RG] = 0;
-
- ASSERT(last.logical != cpudata[a].logical);
-
- last = cpudata[i];
- a++;
- }
-
- no->level[ERTS_TOPOLOGY_NODE]++;
- no->level[ERTS_TOPOLOGY_PROCESSOR]++;
- no->level[ERTS_TOPOLOGY_PROCESSOR_NODE]++;
- no->level[ERTS_TOPOLOGY_CORE]++;
- no->level[ERTS_TOPOLOGY_THREAD]++;
- no->level[ERTS_TOPOLOGY_LOGICAL]++;
-
- *size = a;
-}
-
-static int
-reader_group_lookup(int logical)
-{
- int start = logical % reader_groups_map_size;
- int ix = start;
-
- do {
- if (reader_groups_map[ix].logical == logical) {
- ASSERT(reader_groups_map[ix].reader_group > 0);
- return reader_groups_map[ix].reader_group;
- }
- ix++;
- if (ix == reader_groups_map_size)
- ix = 0;
- } while (ix != start);
-
- erl_exit(ERTS_ABORT_EXIT, "Logical cpu id %d not found\n", logical);
-}
-
-static void
-reader_group_insert(erts_reader_groups_map_t *map, int map_size,
- int logical, int reader_group)
-{
- int start = logical % map_size;
- int ix = start;
-
- do {
- if (map[ix].logical < 0) {
- map[ix].logical = logical;
- map[ix].reader_group = reader_group;
- return;
- }
- ix++;
- if (ix == map_size)
- ix = 0;
- } while (ix != start);
-
- erl_exit(ERTS_ABORT_EXIT, "Reader groups map full\n");
-}
-
-
-static int
-sub_levels(erts_rg_count_t *rgc, int level, int aix, int avail_sz, erts_avail_cput *avail)
-{
- int sub_level = level+1;
- int last = -1;
- rgc->sub_levels = 0;
-
- do {
- if (last != avail[aix].level[sub_level]) {
- rgc->sub_levels++;
- last = avail[aix].level[sub_level];
- }
- aix++;
- }
- while (aix < avail_sz && rgc->id == avail[aix].level[level]);
- rgc->reader_groups = 0;
- return aix;
-}
-
-static int
-write_reader_groups(int *rgp, erts_rg_count_t *rgcp,
- int level, int a,
- int avail_sz, erts_avail_cput *avail)
-{
- int rg = *rgp;
- int sub_level = level+1;
- int sl_per_gr = rgcp->sub_levels / rgcp->reader_groups;
- int xsl = rgcp->sub_levels % rgcp->reader_groups;
- int sls = 0;
- int last = -1;
- int xsl_rg_lim = (rgcp->reader_groups - xsl) + rg + 1;
-
- ASSERT(level < 0 || avail[a].level[level] == rgcp->id)
-
- do {
- if (last != avail[a].level[sub_level]) {
- if (!sls) {
- sls = sl_per_gr;
- rg++;
- if (rg >= xsl_rg_lim)
- sls++;
- }
- last = avail[a].level[sub_level];
- sls--;
- }
- avail[a].level[ERTS_TOPOLOGY_RG] = rg;
- a++;
- } while (a < avail_sz && (level < 0
- || avail[a].level[level] == rgcp->id));
-
- ASSERT(rgcp->reader_groups == rg - *rgp);
-
- *rgp = rg;
-
- return a;
-}
-
-static int
-rg_count_sub_levels_compare(const void *vx, const void *vy)
-{
- erts_rg_count_t *x = (erts_rg_count_t *) vx;
- erts_rg_count_t *y = (erts_rg_count_t *) vy;
- if (x->sub_levels != y->sub_levels)
- return y->sub_levels - x->sub_levels;
- return x->id - y->id;
-}
-
-static int
-rg_count_id_compare(const void *vx, const void *vy)
-{
- erts_rg_count_t *x = (erts_rg_count_t *) vx;
- erts_rg_count_t *y = (erts_rg_count_t *) vy;
- return x->id - y->id;
-}
-
-static void
-make_reader_groups_map(erts_make_reader_groups_map_test *test)
-{
- int i, spread_level, avail_sz;
- erts_avail_cput no, *avail;
- erts_cpu_topology_t *cpudata;
- erts_reader_groups_map_t *map;
- int map_sz;
- int groups = erts_reader_groups;
-
- if (test) {
- test->map = NULL;
- test->map_size = 0;
- groups = test->groups;
- }
-
- if (!groups)
- return;
-
- if (!test) {
- if (reader_groups_map)
- erts_free(ERTS_ALC_T_RDR_GRPS_MAP, reader_groups_map);
-
- reader_groups_logical_processors = 0;
- reader_groups_map_size = 0;
- reader_groups_map = NULL;
- }
-
- create_tmp_cpu_topology_copy(&cpudata, &avail_sz);
-
- if (!cpudata)
- return;
-
- cpu_bind_order_sort(cpudata,
- avail_sz,
- ERTS_CPU_BIND_NO_SPREAD,
- 1);
-
- avail = erts_alloc(ERTS_ALC_T_TMP,
- sizeof(erts_avail_cput)*avail_sz);
-
- make_available_cpu_topology(&no, avail, cpudata,
- &avail_sz, test != NULL);
-
- destroy_tmp_cpu_topology_copy(cpudata);
-
- map_sz = avail_sz*2+1;
-
- if (test) {
- map = erts_alloc(ERTS_ALC_T_TMP,
- (sizeof(erts_reader_groups_map_t)
- * map_sz));
- test->map = map;
- test->map_size = map_sz;
- test->logical_processors = avail_sz;
- }
- else {
- map = erts_alloc(ERTS_ALC_T_RDR_GRPS_MAP,
- (sizeof(erts_reader_groups_map_t)
- * map_sz));
- reader_groups_map = map;
- reader_groups_logical_processors = avail_sz;
- reader_groups_map_size = map_sz;
-
- }
-
- for (i = 0; i < map_sz; i++) {
- map[i].logical = -1;
- map[i].reader_group = 0;
- }
-
- spread_level = ERTS_TOPOLOGY_CORE;
- for (i = ERTS_TOPOLOGY_NODE; i < ERTS_TOPOLOGY_THREAD; i++) {
- if (no.level[i] > groups) {
- spread_level = i;
- break;
- }
- }
-
- if (no.level[spread_level] <= groups) {
- int a, rg, last = -1;
- rg = 0;
- ASSERT(spread_level == ERTS_TOPOLOGY_CORE);
- for (a = 0; a < avail_sz; a++) {
- if (last != avail[a].level[spread_level]) {
- rg++;
- last = avail[a].level[spread_level];
- }
- reader_group_insert(map,
- map_sz,
- avail[a].level[ERTS_TOPOLOGY_LOGICAL],
- rg);
- }
- }
- else { /* groups < no.level[spread_level] */
- erts_rg_count_t *rg_count;
- int a, rg, tl, toplevels;
-
- tl = spread_level-1;
-
- if (spread_level == ERTS_TOPOLOGY_NODE)
- toplevels = 1;
- else
- toplevels = no.level[tl];
-
- rg_count = erts_alloc(ERTS_ALC_T_TMP,
- toplevels*sizeof(erts_rg_count_t));
-
- if (toplevels == 1) {
- rg_count[0].id = 0;
- rg_count[0].sub_levels = no.level[spread_level];
- rg_count[0].reader_groups = groups;
- }
- else {
- int rgs_per_tl, rgs;
- rgs = groups;
- rgs_per_tl = rgs / toplevels;
-
- a = 0;
- for (i = 0; i < toplevels; i++) {
- rg_count[i].id = avail[a].level[tl];
- a = sub_levels(&rg_count[i], tl, a, avail_sz, avail);
- }
-
- qsort(rg_count,
- toplevels,
- sizeof(erts_rg_count_t),
- rg_count_sub_levels_compare);
-
- for (i = 0; i < toplevels; i++) {
- if (rg_count[i].sub_levels < rgs_per_tl) {
- rg_count[i].reader_groups = rg_count[i].sub_levels;
- rgs -= rg_count[i].sub_levels;
- }
- else {
- rg_count[i].reader_groups = rgs_per_tl;
- rgs -= rgs_per_tl;
- }
- }
-
- while (rgs > 0) {
- for (i = 0; i < toplevels; i++) {
- if (rg_count[i].sub_levels == rg_count[i].reader_groups)
- break;
- else {
- rg_count[i].reader_groups++;
- if (--rgs == 0)
- break;
- }
- }
- }
-
- qsort(rg_count,
- toplevels,
- sizeof(erts_rg_count_t),
- rg_count_id_compare);
- }
-
- a = i = rg = 0;
- while (a < avail_sz) {
- a = write_reader_groups(&rg, &rg_count[i], tl,
- a, avail_sz, avail);
- i++;
- }
-
- ASSERT(groups == rg);
-
- for (a = 0; a < avail_sz; a++)
- reader_group_insert(map,
- map_sz,
- avail[a].level[ERTS_TOPOLOGY_LOGICAL],
- avail[a].level[ERTS_TOPOLOGY_RG]);
-
- erts_free(ERTS_ALC_T_TMP, rg_count);
- }
-
- erts_free(ERTS_ALC_T_TMP, avail);
-}
-
-/*
- * CPU topology
- */
-
-typedef struct {
- int *id;
- int used;
- int size;
-} ErtsCpuTopIdSeq;
-
-typedef struct {
- ErtsCpuTopIdSeq logical;
- ErtsCpuTopIdSeq thread;
- ErtsCpuTopIdSeq core;
- ErtsCpuTopIdSeq processor_node;
- ErtsCpuTopIdSeq processor;
- ErtsCpuTopIdSeq node;
-} ErtsCpuTopEntry;
-
-static void
-init_cpu_top_entry(ErtsCpuTopEntry *cte)
-{
- int size = 10;
- cte->logical.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
- sizeof(int)*size);
- cte->logical.size = size;
- cte->thread.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
- sizeof(int)*size);
- cte->thread.size = size;
- cte->core.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
- sizeof(int)*size);
- cte->core.size = size;
- cte->processor_node.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
- sizeof(int)*size);
- cte->processor_node.size = size;
- cte->processor.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
- sizeof(int)*size);
- cte->processor.size = size;
- cte->node.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS,
- sizeof(int)*size);
- cte->node.size = size;
-}
-
-static void
-destroy_cpu_top_entry(ErtsCpuTopEntry *cte)
-{
- erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->logical.id);
- erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->thread.id);
- erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->core.id);
- erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->processor_node.id);
- erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->processor.id);
- erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->node.id);
-}
-
-static int
-get_cput_value_or_range(int *v, int *vr, char **str)
-{
- long l;
- char *c = *str;
- errno = 0;
- if (!isdigit((unsigned char)*c))
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID;
- l = strtol(c, &c, 10);
- if (errno != 0 || l < 0 || ERTS_MAX_CPU_TOPOLOGY_ID < l)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID;
- *v = (int) l;
- if (*c == '-') {
- c++;
- if (!isdigit((unsigned char)*c))
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
- l = strtol(c, &c, 10);
- if (errno != 0 || l < 0 || ERTS_MAX_CPU_TOPOLOGY_ID < l)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
- *vr = (int) l;
- }
- *str = c;
- return ERTS_INIT_CPU_TOPOLOGY_OK;
-}
-
-static int
-get_cput_id_seq(ErtsCpuTopIdSeq *idseq, char **str)
-{
- int ix = 0;
- int need_size = 0;
- char *c = *str;
-
- while (1) {
- int res;
- int val;
- int nids;
- int val_range = -1;
- res = get_cput_value_or_range(&val, &val_range, &c);
- if (res != ERTS_INIT_CPU_TOPOLOGY_OK)
- return res;
- if (val_range < 0 || val_range == val)
- nids = 1;
- else {
- if (val_range > val)
- nids = val_range - val + 1;
- else
- nids = val - val_range + 1;
- }
- need_size += nids;
- if (need_size > idseq->size) {
- idseq->size = need_size + 10;
- idseq->id = erts_realloc(ERTS_ALC_T_TMP_CPU_IDS,
- idseq->id,
- sizeof(int)*idseq->size);
- }
- if (nids == 1)
- idseq->id[ix++] = val;
- else if (val_range > val) {
- for (; val <= val_range; val++)
- idseq->id[ix++] = val;
- }
- else {
- for (; val >= val_range; val--)
- idseq->id[ix++] = val;
- }
- if (*c != ',')
- break;
- c++;
- }
- *str = c;
- idseq->used = ix;
- return ERTS_INIT_CPU_TOPOLOGY_OK;
-}
-
-static int
-get_cput_entry(ErtsCpuTopEntry *cput, char **str)
-{
- int h;
- char *c = *str;
-
- cput->logical.used = 0;
- cput->thread.id[0] = 0;
- cput->thread.used = 1;
- cput->core.id[0] = 0;
- cput->core.used = 1;
- cput->processor_node.id[0] = -1;
- cput->processor_node.used = 1;
- cput->processor.id[0] = 0;
- cput->processor.used = 1;
- cput->node.id[0] = -1;
- cput->node.used = 1;
-
- h = ERTS_TOPOLOGY_MAX_DEPTH;
- while (*c != ':' && *c != '\0') {
- int res;
- ErtsCpuTopIdSeq *idseqp;
- switch (*c++) {
- case 'L':
- if (h <= ERTS_TOPOLOGY_LOGICAL)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
- idseqp = &cput->logical;
- h = ERTS_TOPOLOGY_LOGICAL;
- break;
- case 't':
- case 'T':
- if (h <= ERTS_TOPOLOGY_THREAD)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
- idseqp = &cput->thread;
- h = ERTS_TOPOLOGY_THREAD;
- break;
- case 'c':
- case 'C':
- if (h <= ERTS_TOPOLOGY_CORE)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
- idseqp = &cput->core;
- h = ERTS_TOPOLOGY_CORE;
- break;
- case 'p':
- case 'P':
- if (h <= ERTS_TOPOLOGY_PROCESSOR)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
- idseqp = &cput->processor;
- h = ERTS_TOPOLOGY_PROCESSOR;
- break;
- case 'n':
- case 'N':
- if (h <= ERTS_TOPOLOGY_PROCESSOR) {
- do_node:
- if (h <= ERTS_TOPOLOGY_NODE)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
- idseqp = &cput->node;
- h = ERTS_TOPOLOGY_NODE;
- }
- else {
- int p_node = 0;
- char *p_chk = c;
- while (*p_chk != '\0' && *p_chk != ':') {
- if (*p_chk == 'p' || *p_chk == 'P') {
- p_node = 1;
- break;
- }
- p_chk++;
- }
- if (!p_node)
- goto do_node;
- if (h <= ERTS_TOPOLOGY_PROCESSOR_NODE)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY;
- idseqp = &cput->processor_node;
- h = ERTS_TOPOLOGY_PROCESSOR_NODE;
- }
- break;
- default:
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_TYPE;
- }
- res = get_cput_id_seq(idseqp, &c);
- if (res != ERTS_INIT_CPU_TOPOLOGY_OK)
- return res;
- }
-
- if (cput->logical.used < 1)
- return ERTS_INIT_CPU_TOPOLOGY_MISSING_LID;
-
- if (*c == ':') {
- c++;
- }
-
- if (cput->thread.used != 1
- && cput->thread.used != cput->logical.used)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
- if (cput->core.used != 1
- && cput->core.used != cput->logical.used)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
- if (cput->processor_node.used != 1
- && cput->processor_node.used != cput->logical.used)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
- if (cput->processor.used != 1
- && cput->processor.used != cput->logical.used)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
- if (cput->node.used != 1
- && cput->node.used != cput->logical.used)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE;
-
- *str = c;
- return ERTS_INIT_CPU_TOPOLOGY_OK;
-}
-
-static int
-verify_topology(erts_cpu_topology_t *cpudata, int size)
-{
- if (size > 0) {
- int *logical;
- int node, processor, no_nodes, i;
-
- /* Verify logical ids */
- logical = erts_alloc(ERTS_ALC_T_TMP, sizeof(int)*size);
-
- for (i = 0; i < size; i++)
- logical[i] = cpudata[i].logical;
-
- qsort(logical, size, sizeof(int), int_cmp);
- for (i = 0; i < size-1; i++) {
- if (logical[i] == logical[i+1]) {
- erts_free(ERTS_ALC_T_TMP, logical);
- return ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_LIDS;
- }
- }
-
- erts_free(ERTS_ALC_T_TMP, logical);
-
- qsort(cpudata, size, sizeof(erts_cpu_topology_t), processor_order_cmp);
-
- /* Verify unique entities */
-
- for (i = 1; i < size; i++) {
- if (cpudata[i-1].processor == cpudata[i].processor
- && cpudata[i-1].node == cpudata[i].node
- && (cpudata[i-1].processor_node
- == cpudata[i].processor_node)
- && cpudata[i-1].core == cpudata[i].core
- && cpudata[i-1].thread == cpudata[i].thread) {
- return ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_ENTITIES;
- }
- }
-
- /* Verify numa nodes */
- node = cpudata[0].node;
- processor = cpudata[0].processor;
- no_nodes = cpudata[0].node < 0 && cpudata[0].processor_node < 0;
- for (i = 1; i < size; i++) {
- if (no_nodes) {
- if (cpudata[i].node >= 0 || cpudata[i].processor_node >= 0)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES;
- }
- else {
- if (cpudata[i].processor == processor && cpudata[i].node != node)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES;
- node = cpudata[i].node;
- processor = cpudata[i].processor;
- if (node >= 0 && cpudata[i].processor_node >= 0)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES;
- if (node < 0 && cpudata[i].processor_node < 0)
- return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES;
- }
- }
- }
-
- return ERTS_INIT_CPU_TOPOLOGY_OK;
-}
-
-int
-erts_init_cpu_topology(char *topology_str)
-{
- ErtsCpuTopEntry cput;
- int need_size;
- char *c;
- int ix;
- int error = ERTS_INIT_CPU_TOPOLOGY_OK;
-
- if (user_cpudata)
- erts_free(ERTS_ALC_T_CPUDATA, user_cpudata);
- user_cpudata_size = 10;
-
- user_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA,
- (sizeof(erts_cpu_topology_t)
- * user_cpudata_size));
-
- init_cpu_top_entry(&cput);
-
- ix = 0;
- need_size = 0;
-
- c = topology_str;
- if (*c == '\0') {
- error = ERTS_INIT_CPU_TOPOLOGY_MISSING;
- goto fail;
- }
- do {
- int r;
- error = get_cput_entry(&cput, &c);
- if (error != ERTS_INIT_CPU_TOPOLOGY_OK)
- goto fail;
- need_size += cput.logical.used;
- if (user_cpudata_size < need_size) {
- user_cpudata_size = need_size + 10;
- user_cpudata = erts_realloc(ERTS_ALC_T_CPUDATA,
- user_cpudata,
- (sizeof(erts_cpu_topology_t)
- * user_cpudata_size));
- }
-
- ASSERT(cput.thread.used == 1
- || cput.thread.used == cput.logical.used);
- ASSERT(cput.core.used == 1
- || cput.core.used == cput.logical.used);
- ASSERT(cput.processor_node.used == 1
- || cput.processor_node.used == cput.logical.used);
- ASSERT(cput.processor.used == 1
- || cput.processor.used == cput.logical.used);
- ASSERT(cput.node.used == 1
- || cput.node.used == cput.logical.used);
-
- for (r = 0; r < cput.logical.used; r++) {
- user_cpudata[ix].logical = cput.logical.id[r];
- user_cpudata[ix].thread =
- cput.thread.id[cput.thread.used == 1 ? 0 : r];
- user_cpudata[ix].core =
- cput.core.id[cput.core.used == 1 ? 0 : r];
- user_cpudata[ix].processor_node =
- cput.processor_node.id[cput.processor_node.used == 1 ? 0 : r];
- user_cpudata[ix].processor =
- cput.processor.id[cput.processor.used == 1 ? 0 : r];
- user_cpudata[ix].node =
- cput.node.id[cput.node.used == 1 ? 0 : r];
- ix++;
- }
- } while (*c != '\0');
-
- if (user_cpudata_size != ix) {
- user_cpudata_size = ix;
- user_cpudata = erts_realloc(ERTS_ALC_T_CPUDATA,
- user_cpudata,
- (sizeof(erts_cpu_topology_t)
- * user_cpudata_size));
- }
-
- error = verify_topology(user_cpudata, user_cpudata_size);
- if (error == ERTS_INIT_CPU_TOPOLOGY_OK) {
- destroy_cpu_top_entry(&cput);
- return ERTS_INIT_CPU_TOPOLOGY_OK;
- }
-
- fail:
- if (user_cpudata)
- erts_free(ERTS_ALC_T_CPUDATA, user_cpudata);
- user_cpudata_size = 0;
- destroy_cpu_top_entry(&cput);
- return error;
-}
-
-#define ERTS_GET_CPU_TOPOLOGY_ERROR -1
-#define ERTS_GET_USED_CPU_TOPOLOGY 0
-#define ERTS_GET_DETECTED_CPU_TOPOLOGY 1
-#define ERTS_GET_DEFINED_CPU_TOPOLOGY 2
-
-static Eterm get_cpu_topology_term(Process *c_p, int type);
-
-Eterm
-erts_set_cpu_topology(Process *c_p, Eterm term)
-{
- erts_cpu_topology_t *cpudata = NULL;
- int cpudata_size = 0;
- Eterm res;
-
- erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx);
- res = get_cpu_topology_term(c_p, ERTS_GET_USED_CPU_TOPOLOGY);
- if (term == am_undefined) {
- if (user_cpudata)
- erts_free(ERTS_ALC_T_CPUDATA, user_cpudata);
- user_cpudata = NULL;
- user_cpudata_size = 0;
-
- if (cpu_bind_order != ERTS_CPU_BIND_NONE && system_cpudata) {
- cpudata_size = system_cpudata_size;
- cpudata = erts_alloc(ERTS_ALC_T_TMP,
- (sizeof(erts_cpu_topology_t)
- * cpudata_size));
-
- sys_memcpy((void *) cpudata,
- (void *) system_cpudata,
- sizeof(erts_cpu_topology_t)*cpudata_size);
- }
- }
- else if (is_not_list(term)) {
- error:
- res = THE_NON_VALUE;
- goto done;
- }
- else {
- Eterm list = term;
- int ix = 0;
-
- cpudata_size = 100;
- cpudata = erts_alloc(ERTS_ALC_T_TMP,
- (sizeof(erts_cpu_topology_t)
- * cpudata_size));
-
- while (is_list(list)) {
- Eterm *lp = list_val(list);
- Eterm cpu = CAR(lp);
- Eterm* tp;
- Sint id;
-
- if (is_not_tuple(cpu))
- goto error;
-
- tp = tuple_val(cpu);
-
- if (arityval(tp[0]) != 7 || tp[1] != am_cpu)
- goto error;
-
- if (ix >= cpudata_size) {
- cpudata_size += 100;
- cpudata = erts_realloc(ERTS_ALC_T_TMP,
- cpudata,
- (sizeof(erts_cpu_topology_t)
- * cpudata_size));
- }
-
- id = signed_val(tp[2]);
- if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
- goto error;
- cpudata[ix].node = (int) id;
-
- id = signed_val(tp[3]);
- if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
- goto error;
- cpudata[ix].processor = (int) id;
-
- id = signed_val(tp[4]);
- if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
- goto error;
- cpudata[ix].processor_node = (int) id;
-
- id = signed_val(tp[5]);
- if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
- goto error;
- cpudata[ix].core = (int) id;
-
- id = signed_val(tp[6]);
- if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
- goto error;
- cpudata[ix].thread = (int) id;
-
- id = signed_val(tp[7]);
- if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id)
- goto error;
- cpudata[ix].logical = (int) id;
-
- list = CDR(lp);
- ix++;
- }
-
- if (is_not_nil(list))
- goto error;
-
- cpudata_size = ix;
-
- if (ERTS_INIT_CPU_TOPOLOGY_OK != verify_topology(cpudata, cpudata_size))
- goto error;
-
- if (user_cpudata_size != cpudata_size) {
- if (user_cpudata)
- erts_free(ERTS_ALC_T_CPUDATA, user_cpudata);
- user_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA,
- sizeof(erts_cpu_topology_t)*cpudata_size);
- user_cpudata_size = cpudata_size;
- }
-
- sys_memcpy((void *) user_cpudata,
- (void *) cpudata,
- sizeof(erts_cpu_topology_t)*cpudata_size);
- }
-
- make_reader_groups_map(NULL);
-
- signal_schedulers_bind_change(cpudata, cpudata_size);
-
- done:
- erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx);
-
- if (cpudata)
- erts_free(ERTS_ALC_T_TMP, cpudata);
-
- return res;
-}
-
-static Eterm
-bound_schedulers_term(ErtsCpuBindOrder order)
-{
- switch (order) {
- case ERTS_CPU_BIND_SPREAD: {
- ERTS_DECL_AM(spread);
- return AM_spread;
- }
- case ERTS_CPU_BIND_PROCESSOR_SPREAD: {
- ERTS_DECL_AM(processor_spread);
- return AM_processor_spread;
- }
- case ERTS_CPU_BIND_THREAD_SPREAD: {
- ERTS_DECL_AM(thread_spread);
- return AM_thread_spread;
- }
- case ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD: {
- ERTS_DECL_AM(thread_no_node_processor_spread);
- return AM_thread_no_node_processor_spread;
- }
- case ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD: {
- ERTS_DECL_AM(no_node_processor_spread);
- return AM_no_node_processor_spread;
- }
- case ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD: {
- ERTS_DECL_AM(no_node_thread_spread);
- return AM_no_node_thread_spread;
- }
- case ERTS_CPU_BIND_NO_SPREAD: {
- ERTS_DECL_AM(no_spread);
- return AM_no_spread;
- }
- case ERTS_CPU_BIND_NONE: {
- ERTS_DECL_AM(unbound);
- return AM_unbound;
- }
- default:
- ASSERT(0);
- return THE_NON_VALUE;
- }
-}
-
-Eterm
-erts_bound_schedulers_term(Process *c_p)
-{
- ErtsCpuBindOrder order;
- erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx);
- order = cpu_bind_order;
- erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx);
- return bound_schedulers_term(order);
-}
-
-static void
-create_tmp_cpu_topology_copy(erts_cpu_topology_t **cpudata, int *cpudata_size)
-{
- if (user_cpudata) {
- *cpudata_size = user_cpudata_size;
- *cpudata = erts_alloc(ERTS_ALC_T_TMP,
- (sizeof(erts_cpu_topology_t)
- * (*cpudata_size)));
- sys_memcpy((void *) *cpudata,
- (void *) user_cpudata,
- sizeof(erts_cpu_topology_t)*(*cpudata_size));
- }
- else if (system_cpudata) {
- *cpudata_size = system_cpudata_size;
- *cpudata = erts_alloc(ERTS_ALC_T_TMP,
- (sizeof(erts_cpu_topology_t)
- * (*cpudata_size)));
- sys_memcpy((void *) *cpudata,
- (void *) system_cpudata,
- sizeof(erts_cpu_topology_t)*(*cpudata_size));
- }
- else {
- *cpudata = NULL;
- *cpudata_size = 0;
- }
-}
-
-static void
-destroy_tmp_cpu_topology_copy(erts_cpu_topology_t *cpudata)
-{
- if (cpudata)
- erts_free(ERTS_ALC_T_TMP, cpudata);
-}
-
-Eterm
-erts_bind_schedulers(Process *c_p, Eterm how)
-{
- Eterm res;
- erts_cpu_topology_t *cpudata;
- int cpudata_size;
- ErtsCpuBindOrder old_cpu_bind_order;
-
- erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx);
-
- if (erts_bind_to_cpu(erts_cpuinfo, -1) == -ENOTSUP) {
- ERTS_BIF_PREP_ERROR(res, c_p, EXC_NOTSUP);
- }
- else {
-
- old_cpu_bind_order = cpu_bind_order;
-
- 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("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;
- else if (ERTS_IS_ATOM_STR("no_node_thread_spread", how))
- cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD;
- else if (ERTS_IS_ATOM_STR("no_spread", how))
- cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD;
- else if (ERTS_IS_ATOM_STR("unbound", how))
- cpu_bind_order = ERTS_CPU_BIND_NONE;
- else {
- cpu_bind_order = old_cpu_bind_order;
- ERTS_BIF_PREP_ERROR(res, c_p, BADARG);
- goto done;
- }
-
- create_tmp_cpu_topology_copy(&cpudata, &cpudata_size);
-
- if (!cpudata) {
- cpu_bind_order = old_cpu_bind_order;
- ERTS_BIF_PREP_ERROR(res, c_p, BADARG);
- goto done;
- }
-
- signal_schedulers_bind_change(cpudata, cpudata_size);
-
- destroy_tmp_cpu_topology_copy(cpudata);
-
- res = bound_schedulers_term(old_cpu_bind_order);
- }
-
- done:
-
- erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx);
-
- return res;
-}
-
-Eterm
-erts_fake_scheduler_bindings(Process *p, Eterm how)
-{
- ErtsCpuBindOrder fake_cpu_bind_order;
- erts_cpu_topology_t *cpudata;
- int cpudata_size;
- Eterm res;
-
- 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("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;
- else if (ERTS_IS_ATOM_STR("no_node_thread_spread", how))
- fake_cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD;
- else if (ERTS_IS_ATOM_STR("no_spread", how))
- fake_cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD;
- else if (ERTS_IS_ATOM_STR("unbound", how))
- fake_cpu_bind_order = ERTS_CPU_BIND_NONE;
- else {
- ERTS_BIF_PREP_ERROR(res, p, BADARG);
- return res;
- }
-
- erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx);
- create_tmp_cpu_topology_copy(&cpudata, &cpudata_size);
- erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx);
-
- if (!cpudata || fake_cpu_bind_order == ERTS_CPU_BIND_NONE)
- ERTS_BIF_PREP_RET(res, am_false);
- else {
- int i;
- Eterm *hp;
-
- cpu_bind_order_sort(cpudata, cpudata_size, fake_cpu_bind_order, 1);
-
-#ifdef ERTS_FAKE_SCHED_BIND_PRINT_SORTED_CPU_DATA
-
- erts_fprintf(stderr, "node: ");
- for (i = 0; i < cpudata_size; i++)
- erts_fprintf(stderr, " %2d", cpudata[i].node);
- erts_fprintf(stderr, "\n");
- erts_fprintf(stderr, "processor: ");
- for (i = 0; i < cpudata_size; i++)
- erts_fprintf(stderr, " %2d", cpudata[i].processor);
- erts_fprintf(stderr, "\n");
- if (fake_cpu_bind_order != ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD
- && fake_cpu_bind_order != ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD
- && fake_cpu_bind_order != ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD) {
- erts_fprintf(stderr, "processor_node:");
- for (i = 0; i < cpudata_size; i++)
- erts_fprintf(stderr, " %2d", cpudata[i].processor_node);
- erts_fprintf(stderr, "\n");
- }
- erts_fprintf(stderr, "core: ");
- for (i = 0; i < cpudata_size; i++)
- erts_fprintf(stderr, " %2d", cpudata[i].core);
- erts_fprintf(stderr, "\n");
- erts_fprintf(stderr, "thread: ");
- for (i = 0; i < cpudata_size; i++)
- erts_fprintf(stderr, " %2d", cpudata[i].thread);
- erts_fprintf(stderr, "\n");
- erts_fprintf(stderr, "logical: ");
- for (i = 0; i < cpudata_size; i++)
- erts_fprintf(stderr, " %2d", cpudata[i].logical);
- erts_fprintf(stderr, "\n");
-#endif
-
- hp = HAlloc(p, cpudata_size+1);
- ERTS_BIF_PREP_RET(res, make_tuple(hp));
- *hp++ = make_arityval((Uint) cpudata_size);
- for (i = 0; i < cpudata_size; i++)
- *hp++ = make_small((Uint) cpudata[i].logical);
- }
-
- destroy_tmp_cpu_topology_copy(cpudata);
-
- return res;
-}
-
-Eterm
-erts_get_schedulers_binds(Process *c_p)
-{
- int ix;
- ERTS_DECL_AM(unbound);
- Eterm *hp = HAlloc(c_p, erts_no_schedulers+1);
- Eterm res = make_tuple(hp);
-
- *(hp++) = make_arityval(erts_no_schedulers);
- erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx);
- for (ix = 1; ix <= erts_no_schedulers; ix++)
- *(hp++) = (scheduler2cpu_map[ix].bound_id >= 0
- ? make_small(scheduler2cpu_map[ix].bound_id)
- : AM_unbound);
- erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx);
- return res;
-}
-
-static Eterm
-bld_topology_term(Eterm **hpp,
- Uint *hszp,
- erts_cpu_topology_t *cpudata,
- int size)
-{
- Eterm res = NIL;
- int i;
-
- if (size == 0)
- return am_undefined;
-
- for (i = size-1; i >= 0; i--) {
- res = erts_bld_cons(hpp,
- hszp,
- erts_bld_tuple(hpp,
- hszp,
- 7,
- am_cpu,
- make_small(cpudata[i].node),
- make_small(cpudata[i].processor),
- make_small(cpudata[i].processor_node),
- make_small(cpudata[i].core),
- make_small(cpudata[i].thread),
- make_small(cpudata[i].logical)),
- res);
- }
- return res;
-}
-
-static Eterm
-get_cpu_topology_term(Process *c_p, int type)
-{
-#ifdef DEBUG
- Eterm *hp_end;
-#endif
- Eterm *hp;
- Uint hsz;
- Eterm res = THE_NON_VALUE;
- erts_cpu_topology_t *cpudata = NULL;
- int size = 0;
-
- switch (type) {
- case ERTS_GET_USED_CPU_TOPOLOGY:
- if (user_cpudata)
- goto defined;
- else
- goto detected;
- case ERTS_GET_DETECTED_CPU_TOPOLOGY:
- detected:
- if (!system_cpudata)
- res = am_undefined;
- else {
- size = system_cpudata_size;
- cpudata = erts_alloc(ERTS_ALC_T_TMP,
- (sizeof(erts_cpu_topology_t)
- * size));
- sys_memcpy((void *) cpudata,
- (void *) system_cpudata,
- sizeof(erts_cpu_topology_t)*size);
- }
- break;
- case ERTS_GET_DEFINED_CPU_TOPOLOGY:
- defined:
- if (!user_cpudata)
- res = am_undefined;
- else {
- size = user_cpudata_size;
- cpudata = user_cpudata;
- }
- break;
- default:
- erl_exit(ERTS_ABORT_EXIT, "Bad cpu topology type: %d\n", type);
- break;
- }
-
- if (res == am_undefined) {
- ASSERT(!cpudata);
- return res;
- }
-
- hsz = 0;
-
- bld_topology_term(NULL, &hsz,
- cpudata, size);
-
- hp = HAlloc(c_p, hsz);
-
-#ifdef DEBUG
- hp_end = hp + hsz;
-#endif
-
- res = bld_topology_term(&hp, NULL,
- cpudata, size);
-
- ASSERT(hp_end == hp);
-
- if (cpudata && cpudata != system_cpudata && cpudata != user_cpudata)
- erts_free(ERTS_ALC_T_TMP, cpudata);
-
- return res;
-}
-
-Eterm
-erts_get_cpu_topology_term(Process *c_p, Eterm which)
-{
- Eterm res;
- int type;
- erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx);
- if (ERTS_IS_ATOM_STR("used", which))
- type = ERTS_GET_USED_CPU_TOPOLOGY;
- else if (ERTS_IS_ATOM_STR("detected", which))
- type = ERTS_GET_DETECTED_CPU_TOPOLOGY;
- else if (ERTS_IS_ATOM_STR("defined", which))
- type = ERTS_GET_DEFINED_CPU_TOPOLOGY;
- else
- type = ERTS_GET_CPU_TOPOLOGY_ERROR;
- if (type == ERTS_GET_CPU_TOPOLOGY_ERROR)
- res = THE_NON_VALUE;
- else
- res = get_cpu_topology_term(c_p, type);
- erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx);
- return res;
-}
-
-static void
-early_cpu_bind_init(void)
-{
- user_cpudata = NULL;
- user_cpudata_size = 0;
-
- system_cpudata_size = erts_get_cpu_topology_size(erts_cpuinfo);
- system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA,
- (sizeof(erts_cpu_topology_t)
- * system_cpudata_size));
-
- cpu_bind_order = ERTS_CPU_BIND_UNDEFINED;
-
- reader_groups_available_cpu_check = 1;
- reader_groups_logical_processors = 0;
- reader_groups_map_size = 0;
- reader_groups_map = NULL;
-
- if (!erts_get_cpu_topology(erts_cpuinfo, system_cpudata)
- || ERTS_INIT_CPU_TOPOLOGY_OK != verify_topology(system_cpudata,
- system_cpudata_size)) {
- erts_free(ERTS_ALC_T_CPUDATA, system_cpudata);
- system_cpudata = NULL;
- system_cpudata_size = 0;
- }
-}
-
-static void
-late_cpu_bind_init(void)
-{
- int ix;
-
- erts_smp_rwmtx_init(&erts_cpu_bind_rwmtx, "cpu_bind");
-
- scheduler2cpu_map = erts_alloc(ERTS_ALC_T_CPUDATA,
- (sizeof(ErtsCpuBindData)
- * (erts_no_schedulers+1)));
- for (ix = 1; ix <= erts_no_schedulers; ix++) {
- scheduler2cpu_map[ix].bind_id = -1;
- 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);
- }
-
- make_reader_groups_map(NULL);
-
- if (cpu_bind_order != ERTS_CPU_BIND_NONE) {
- erts_cpu_topology_t *cpudata;
- int cpudata_size;
- create_tmp_cpu_topology_copy(&cpudata, &cpudata_size);
- signal_schedulers_bind_change(cpudata, cpudata_size);
- destroy_tmp_cpu_topology_copy(cpudata);
- }
-}
-
-int
-erts_update_cpu_info(void)
-{
- int changed;
- erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx);
- changed = erts_cpu_info_update(erts_cpuinfo);
- if (changed) {
- erts_cpu_topology_t *cpudata;
- int cpudata_size;
-
- if (system_cpudata)
- erts_free(ERTS_ALC_T_CPUDATA, system_cpudata);
-
- system_cpudata_size = erts_get_cpu_topology_size(erts_cpuinfo);
- if (!system_cpudata_size)
- system_cpudata = NULL;
- else {
- system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA,
- (sizeof(erts_cpu_topology_t)
- * system_cpudata_size));
-
- if (!erts_get_cpu_topology(erts_cpuinfo, system_cpudata)
- || (ERTS_INIT_CPU_TOPOLOGY_OK
- != verify_topology(system_cpudata,
- system_cpudata_size))) {
- erts_free(ERTS_ALC_T_CPUDATA, system_cpudata);
- system_cpudata = NULL;
- system_cpudata_size = 0;
- }
- }
-
- create_tmp_cpu_topology_copy(&cpudata, &cpudata_size);
- signal_schedulers_bind_change(cpudata, cpudata_size);
- destroy_tmp_cpu_topology_copy(cpudata);
- }
- erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx);
- return changed;
-}
-
#ifdef ERTS_SMP
static void
@@ -6884,10 +5078,10 @@ Process *schedule(Process *p, int calls)
{
ErtsRunQueue *rq;
ErtsRunPrioQueue *rpq;
- long dt;
+ erts_aint_t dt;
ErtsSchedulerData *esdp;
int context_reds;
- long fcalls;
+ int fcalls;
int input_reductions;
int actual_reds;
int reds;
@@ -6910,7 +5104,7 @@ Process *schedule(Process *p, int calls)
esdp = erts_get_scheduler_data();
rq = erts_get_runq_current(esdp);
ASSERT(esdp);
- fcalls = erts_smp_atomic_read(&function_calls);
+ fcalls = (int) erts_smp_atomic32_read(&function_calls);
actual_reds = reds = 0;
erts_smp_runq_lock(rq);
} else {
@@ -6928,7 +5122,7 @@ Process *schedule(Process *p, int calls)
reds = ERTS_PROC_MIN_CONTEXT_SWITCH_REDS_COST;
esdp->virtual_reds = 0;
- fcalls = erts_smp_atomic_addtest(&function_calls, reds);
+ fcalls = (int) erts_smp_atomic32_addtest(&function_calls, reds);
ASSERT(esdp && esdp == erts_get_scheduler_data());
rq = erts_get_runq_current(esdp);
@@ -7029,10 +5223,10 @@ Process *schedule(Process *p, int calls)
ERTS_SMP_CHK_NO_PROC_LOCKS;
- dt = do_time_read_and_reset();
+ dt = erts_do_time_read_and_reset();
if (dt) {
erts_smp_runq_unlock(rq);
- bump_timer(dt);
+ erts_bump_timer(dt);
erts_smp_runq_lock(rq);
}
BM_STOP_TIMER(system);
@@ -7061,15 +5255,15 @@ Process *schedule(Process *p, int calls)
| ERTS_RUNQ_FLG_CHK_CPU_BIND
| ERTS_RUNQ_FLG_SUSPENDED)) {
if ((rq->flags & ERTS_RUNQ_FLG_SUSPENDED)
- || (erts_smp_atomic_read(&esdp->ssi->flags)
+ || (erts_smp_atomic32_read(&esdp->ssi->flags)
& ERTS_SSI_FLG_SUSPENDED)) {
- ASSERT(erts_smp_atomic_read(&esdp->ssi->flags)
+ ASSERT(erts_smp_atomic32_read(&esdp->ssi->flags)
& ERTS_SSI_FLG_SUSPENDED);
suspend_scheduler(esdp);
}
if ((rq->flags & ERTS_RUNQ_FLG_CHK_CPU_BIND)
- || erts_smp_atomic_read(&esdp->chk_cpu_bind)) {
- check_cpu_bind(esdp);
+ || erts_smp_atomic32_read(&esdp->chk_cpu_bind)) {
+ erts_sched_check_cpu_bind(esdp);
}
}
@@ -7077,7 +5271,7 @@ Process *schedule(Process *p, int calls)
|| defined(ERTS_SCHED_NEED_NONBLOCKABLE_AUX_WORK)
{
ErtsSchedulerSleepInfo *ssi = esdp->ssi;
- long aux_work = erts_smp_atomic_read(&ssi->aux_work);
+ erts_aint32_t aux_work = erts_smp_atomic32_read(&ssi->aux_work);
if (aux_work) {
erts_smp_runq_unlock(rq);
#ifdef ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
@@ -7119,9 +5313,9 @@ Process *schedule(Process *p, int calls)
if (rq->flags & (ERTS_RUNQ_FLG_SHARED_RUNQ
| ERTS_RUNQ_FLG_SUSPENDED)) {
if ((rq->flags & ERTS_RUNQ_FLG_SUSPENDED)
- || (erts_smp_atomic_read(&esdp->ssi->flags)
+ || (erts_smp_atomic32_read(&esdp->ssi->flags)
& ERTS_SSI_FLG_SUSPENDED)) {
- ASSERT(erts_smp_atomic_read(&esdp->ssi->flags)
+ ASSERT(erts_smp_atomic32_read(&esdp->ssi->flags)
& ERTS_SSI_FLG_SUSPENDED);
non_empty_runq(rq);
goto continue_check_activities_to_run;
@@ -7163,19 +5357,21 @@ Process *schedule(Process *p, int calls)
* Schedule system-level activities.
*/
- erts_smp_atomic_set(&function_calls, 0);
+ erts_smp_atomic32_set(&function_calls, 0);
fcalls = 0;
+
ASSERT(!erts_port_task_have_outstanding_io_tasks());
+
#ifdef ERTS_SMP
/* erts_sys_schedule_interrupt(0); */
#endif
erts_smp_runq_unlock(rq);
erl_sys_schedule(runnable);
- dt = do_time_read_and_reset();
- if (dt) bump_timer(dt);
+ dt = erts_do_time_read_and_reset();
+ if (dt) erts_bump_timer(dt);
#ifdef ERTS_SMP
erts_smp_runq_lock(rq);
- erts_smp_atomic_set(&doing_sys_schedule, 0);
+ erts_smp_atomic32_set(&doing_sys_schedule, 0);
goto continue_check_activities_to_run;
#else
if (!runnable)
@@ -7203,7 +5399,7 @@ Process *schedule(Process *p, int calls)
if (erts_common_run_queue->waiting)
wake_scheduler(erts_common_run_queue, 0, 1);
}
- else if (erts_smp_atomic_read(&no_empty_run_queues) != 0) {
+ else if (erts_smp_atomic32_read(&no_empty_run_queues) != 0) {
wake_scheduler_on_empty_runq(rq);
rq->wakeup_other = 0;
}
@@ -7497,6 +5693,15 @@ erts_schedule_misc_op(void (*func)(void *), void *arg)
ErtsRunQueue *rq = erts_get_runq_current(NULL);
ErtsMiscOpList *molp = misc_op_list_alloc();
+ if (!rq) {
+ /*
+ * This can only happen when the sys msg dispatcher
+ * thread schedules misc ops (this happens *very*
+ * seldom; only when trace drivers are unloaded).
+ */
+ rq = ERTS_RUNQ_IX(0);
+ }
+
erts_smp_runq_lock(rq);
while (rq->misc.evac_runq) {
@@ -7651,7 +5856,7 @@ erts_test_next_pid(int set, Uint next)
Uint erts_process_count(void)
{
- long res = erts_smp_atomic_read(&process_count);
+ erts_aint32_t res = erts_smp_atomic32_read(&process_count);
ASSERT(res >= 0);
return (Uint) res;
}
@@ -7700,7 +5905,7 @@ alloc_process(void)
ASSERT(!process_tab[p_next]);
process_tab[p_next] = p;
- erts_smp_atomic_inc(&process_count);
+ erts_smp_atomic32_inc(&process_count);
p->id = make_internal_pid(p_serial << p_serial_shift | p_next);
if (p->id == ERTS_INVALID_PID) {
/* Do not use the invalid pid; change serial */
@@ -7826,7 +6031,7 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->min_heap_size = H_MIN_SIZE;
p->min_vheap_size = BIN_VH_MIN_SIZE;
p->prio = PRIORITY_NORMAL;
- p->max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs);
+ p->max_gen_gcs = (Uint16) erts_smp_atomic32_read(&erts_max_gen_gcs);
}
p->skipped = 0;
ASSERT(p->min_heap_size == erts_next_heap_size(p->min_heap_size, 0));
@@ -8879,11 +7084,11 @@ static void doit_exit_monitor(ErtsMonitor *mon, void *vpcontext)
DeclareTmpHeapNoproc(lhp,3);
ErtsProcLocks rp_locks = (ERTS_PROC_LOCK_LINK
| ERTS_PROC_LOCKS_MSG_SEND);
- UseTmpHeapNoproc(3);
rp = erts_pid2proc(NULL, 0, mon->pid, rp_locks);
if (rp == NULL) {
goto done;
}
+ UseTmpHeapNoproc(3);
rmon = erts_remove_monitor(&(rp->monitors),mon->ref);
if (rmon) {
erts_destroy_monitor(rmon);
@@ -9283,8 +7488,8 @@ continue_exit_process(Process *p
p->status_flags = 0;
#endif
process_tab[pix] = NULL; /* Time of death! */
- ASSERT(erts_smp_atomic_read(&process_count) > 0);
- erts_smp_atomic_dec(&process_count);
+ ASSERT(erts_smp_atomic32_read(&process_count) > 0);
+ erts_smp_atomic32_dec(&process_count);
#ifdef ERTS_SMP
erts_pix_unlock(pix_lock);
@@ -9424,7 +7629,7 @@ cancel_timer(Process* p)
#ifdef ERTS_SMP
erts_cancel_smp_ptimer(p->u.ptimer);
#else
- erl_cancel_timer(&p->u.tm);
+ erts_cancel_timer(&p->u.tm);
#endif
}
@@ -9450,7 +7655,7 @@ set_timer(Process* p, Uint timeout)
(ErlTimeoutProc) timeout_proc,
timeout);
#else
- erl_set_timer(&p->u.tm,
+ erts_set_timer(&p->u.tm,
(ErlTimeoutProc) timeout_proc,
NULL,
(void*) p,
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 4365e409e5..e871a9834a 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -28,6 +28,12 @@
#define ERTS_INCLUDE_SCHEDULER_INTERNALS
#endif
+/* #define ERTS_DO_VERIFY_UNUSED_TEMP_ALLOC */
+
+#if !defined(ERTS_DO_VERIFY_UNUSED_TEMP_ALLOC) && defined(DEBUG)
+# define ERTS_DO_VERIFY_UNUSED_TEMP_ALLOC
+#endif
+
typedef struct process Process;
#include "sys.h"
@@ -89,7 +95,6 @@ extern int erts_sched_thread_suggested_stack_size;
#define ERTS_SCHED_THREAD_MAX_STACK_SIZE 8192 /* Kilo words */
#ifdef ERTS_SMP
-extern Uint erts_max_main_threads;
#include "erl_bits.h"
#endif
@@ -175,8 +180,8 @@ extern Uint erts_max_main_threads;
#define ERTS_UNSET_RUNQ_FLG_EVACUATE(FLGS, PRIO) \
((FLGS) &= ~ERTS_RUNQ_FLG_EVACUATE((PRIO)))
-#define ERTS_RUNQ_IFLG_SUSPENDED (((long) 1) << 0)
-#define ERTS_RUNQ_IFLG_NONEMPTY (((long) 1) << 1)
+#define ERTS_RUNQ_IFLG_SUSPENDED (((erts_aint32_t) 1) << 0)
+#define ERTS_RUNQ_IFLG_NONEMPTY (((erts_aint32_t) 1) << 1)
#ifdef DEBUG
@@ -220,11 +225,11 @@ typedef enum {
ERTS_MIGRATE_FAILED_RUNQ_SUSPENDED
} ErtsMigrateResult;
-#define ERTS_SSI_FLG_SLEEPING (((long) 1) << 0)
-#define ERTS_SSI_FLG_POLL_SLEEPING (((long) 1) << 1)
-#define ERTS_SSI_FLG_TSE_SLEEPING (((long) 1) << 2)
-#define ERTS_SSI_FLG_WAITING (((long) 1) << 3)
-#define ERTS_SSI_FLG_SUSPENDED (((long) 1) << 4)
+#define ERTS_SSI_FLG_SLEEPING (((erts_aint32_t) 1) << 0)
+#define ERTS_SSI_FLG_POLL_SLEEPING (((erts_aint32_t) 1) << 1)
+#define ERTS_SSI_FLG_TSE_SLEEPING (((erts_aint32_t) 1) << 2)
+#define ERTS_SSI_FLG_WAITING (((erts_aint32_t) 1) << 3)
+#define ERTS_SSI_FLG_SUSPENDED (((erts_aint32_t) 1) << 4)
#define ERTS_SSI_FLGS_SLEEP_TYPE \
(ERTS_SSI_FLG_TSE_SLEEPING|ERTS_SSI_FLG_POLL_SLEEPING)
@@ -237,16 +242,14 @@ typedef enum {
| ERTS_SSI_FLG_WAITING \
| ERTS_SSI_FLG_SUSPENDED)
-
-#if !defined(ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK) \
- && defined(ERTS_SMP_SCHEDULERS_NEED_TO_CHECK_CHILDREN)
#define ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK
-#endif
-#define ERTS_SSI_AUX_WORK_CHECK_CHILDREN (((long) 1) << 0)
+#define ERTS_SSI_AUX_WORK_CHECK_CHILDREN (((erts_aint32_t) 1) << 0)
+#define ERTS_SSI_AUX_WORK_MISC (((erts_aint32_t) 1) << 1)
#define ERTS_SSI_BLOCKABLE_AUX_WORK_MASK \
- (ERTS_SSI_AUX_WORK_CHECK_CHILDREN)
+ (ERTS_SSI_AUX_WORK_CHECK_CHILDREN \
+ | ERTS_SSI_AUX_WORK_MISC)
#define ERTS_SSI_NONBLOCKABLE_AUX_WORK_MASK \
(0)
@@ -260,9 +263,9 @@ typedef struct {
struct ErtsSchedulerSleepInfo_ {
ErtsSchedulerSleepInfo *next;
ErtsSchedulerSleepInfo *prev;
- erts_smp_atomic_t flags;
+ erts_smp_atomic32_t flags;
erts_tse_t *event;
- erts_smp_atomic_t aux_work;
+ erts_smp_atomic32_t aux_work;
};
/* times to reschedule low prio process before running */
@@ -312,7 +315,7 @@ typedef struct {
struct ErtsRunQueue_ {
int ix;
- erts_smp_atomic_t info_flags;
+ erts_smp_atomic32_t info_flags;
erts_smp_mtx_t mtx;
erts_smp_cnd_t cnd;
@@ -422,10 +425,22 @@ struct ErtsSchedulerData_ {
#ifdef ERTS_SMP
/* NOTE: These fields are modified under held mutexes by other threads */
- erts_smp_atomic_t chk_cpu_bind; /* Only used when common run queue */
+ erts_smp_atomic32_t chk_cpu_bind; /* Only used when common run queue */
+#endif
+
+#ifdef ERTS_DO_VERIFY_UNUSED_TEMP_ALLOC
+ erts_alloc_verify_func_t verify_unused_temp_alloc;
+ Allctr_t *verify_unused_temp_alloc_data;
#endif
};
+typedef union {
+ ErtsSchedulerData esd;
+ char align[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(ErtsSchedulerData))];
+} ErtsAlignedSchedulerData;
+
+extern ErtsAlignedSchedulerData *erts_aligned_scheduler_data;
+
#ifndef ERTS_SMP
extern ErtsSchedulerData *erts_scheduler_data;
#endif
@@ -820,7 +835,7 @@ ERTS_GLB_INLINE void erts_heap_frag_shrink(Process* p, Eterm* hp)
}
#endif /* inline */
-Eterm* erts_heap_alloc(Process* p, Uint need);
+Eterm* erts_heap_alloc(Process* p, Uint need, Uint xtra);
#ifdef CHECK_FOR_HOLES
Eterm* erts_set_hole_marker(Eterm* ptr, Uint sz);
#endif
@@ -1007,27 +1022,12 @@ extern struct erts_system_profile_flags_t erts_system_profile_flags;
(p)->flags &= ~F_TIMO; \
} while (0)
-
-#define ERTS_INIT_SCHED_BIND_TYPE_SUCCESS 0
-#define ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED 1
-#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY 2
-#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE 3
-
-int erts_init_scheduler_bind_type(char *how);
-
-#define ERTS_INIT_CPU_TOPOLOGY_OK 0
-#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID 1
-#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE 2
-#define ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY 3
-#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_TYPE 4
-#define ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES 5
-#define ERTS_INIT_CPU_TOPOLOGY_MISSING_LID 6
-#define ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_LIDS 7
-#define ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_ENTITIES 8
-#define ERTS_INIT_CPU_TOPOLOGY_MISSING 9
-
-int erts_init_cpu_topology(char *topology_str);
-int erts_update_cpu_info(void);
+#define ERTS_RUNQ_IX(IX) \
+ (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_run_queues), \
+ &erts_aligned_run_queues[(IX)].runq)
+#define ERTS_SCHEDULER_IX(IX) \
+ (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_schedulers), \
+ &erts_aligned_scheduler_data[(IX)].esd)
void erts_pre_init_process(void);
void erts_late_init_process(void);
@@ -1043,6 +1043,7 @@ int erts_sched_set_wakeup_limit(char *str);
#ifdef DEBUG
void erts_dbg_multi_scheduling_return_trap(Process *, Eterm);
#endif
+int erts_get_max_no_executing_schedulers(void);
#ifdef ERTS_SMP
ErtsSchedSuspendResult
erts_schedulers_state(Uint *, Uint *, Uint *, int);
@@ -1057,9 +1058,15 @@ int erts_is_multi_scheduling_blocked(void);
Eterm erts_multi_scheduling_blockers(Process *);
void erts_start_schedulers(void);
void erts_smp_notify_check_children_needed(void);
+void
+erts_smp_schedule_misc_aux_work(int ignore_self,
+ int max_sched,
+ void (*func)(void *),
+ void *arg);
#endif
+void erts_sched_notify_check_cpu_bind(void);
Uint erts_active_schedulers(void);
-void erts_init_process(void);
+void erts_init_process(int);
Eterm erts_process_status(Process *, ErtsProcLocks, Process *, Eterm);
Uint erts_run_queues_len(Uint *);
void erts_add_to_runq(Process *);
@@ -1149,6 +1156,20 @@ Uint erts_debug_nbalance(void);
# define ERTS_PROC_GET_SCHDATA(PROC) (erts_scheduler_data)
#endif
+#ifdef ERTS_DO_VERIFY_UNUSED_TEMP_ALLOC
+# define ERTS_VERIFY_UNUSED_TEMP_ALLOC(P) \
+do { \
+ ErtsSchedulerData *esdp__ = ((P) \
+ ? ERTS_PROC_GET_SCHDATA((Process *) (P)) \
+ : erts_get_scheduler_data()); \
+ if (esdp__) \
+ esdp__->verify_unused_temp_alloc( \
+ esdp__->verify_unused_temp_alloc_data); \
+} while (0)
+#else
+# define ERTS_VERIFY_UNUSED_TEMP_ALLOC(ESDP)
+#endif
+
#if defined(ERTS_SMP) || defined(USE_THREADS)
ErtsSchedulerData *erts_get_scheduler_data(void);
#else
@@ -1563,7 +1584,7 @@ extern int erts_disable_proc_not_running_opt;
void erts_smp_notify_inc_runq(ErtsRunQueue *runq);
#ifdef ERTS_SMP
-void erts_sched_finish_poke(ErtsSchedulerSleepInfo *, long);
+void erts_sched_finish_poke(ErtsSchedulerSleepInfo *, erts_aint32_t);
ERTS_GLB_INLINE void erts_sched_poke(ErtsSchedulerSleepInfo *ssi);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
@@ -1571,11 +1592,11 @@ ERTS_GLB_INLINE void erts_sched_poke(ErtsSchedulerSleepInfo *ssi);
ERTS_GLB_INLINE void
erts_sched_poke(ErtsSchedulerSleepInfo *ssi)
{
- long flags = erts_smp_atomic_read(&ssi->flags);
+ erts_aint32_t flags = erts_smp_atomic32_read(&ssi->flags);
ASSERT(!(flags & ERTS_SSI_FLG_SLEEPING)
|| (flags & ERTS_SSI_FLG_WAITING));
if (flags & ERTS_SSI_FLG_SLEEPING) {
- flags = erts_smp_atomic_band(&ssi->flags, ~ERTS_SSI_FLGS_SLEEP);
+ flags = erts_smp_atomic32_band(&ssi->flags, ~ERTS_SSI_FLGS_SLEEP);
erts_sched_finish_poke(ssi, flags);
}
}
diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c
index 7a7042abe4..68fda01597 100644
--- a/erts/emulator/beam/erl_process_dump.c
+++ b/erts/emulator/beam/erl_process_dump.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2003-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -261,139 +261,139 @@ print_function_from_pc(int to, void *to_arg, BeamInstr* x)
static void
heap_dump(int to, void *to_arg, Eterm x)
{
+ DeclareTmpHeapNoproc(last,1);
+ Eterm* next = last;
Eterm* ptr;
- Eterm last = OUR_NIL;
- Eterm* next = &last;
if (is_immed(x) || is_CP(x)) {
return;
}
-
- again:
- if (x == OUR_NIL) { /* We are done. */
- return;
- } if (is_CP(x)) {
- next = (Eterm *) EXPAND_POINTER(x);
- } else if (is_list(x)) {
- ptr = list_val(x);
- if (ptr[0] != OUR_NIL) {
- erts_print(to, to_arg, ADDR_FMT ":l", ptr);
- dump_element(to, to_arg, ptr[0]);
- erts_putc(to, to_arg, '|');
- dump_element(to, to_arg, ptr[1]);
- erts_putc(to, to_arg, '\n');
- if (is_immed(ptr[1])) {
- ptr[1] = make_small(0);
- }
- x = ptr[0];
- ptr[0] = (Eterm) COMPRESS_POINTER(next);
- next = ptr + 1;
- goto again;
- }
- } else if (is_boxed(x)) {
- Eterm hdr;
-
- ptr = boxed_val(x);
- hdr = *ptr;
- if (hdr != OUR_NIL) { /* If not visited */
- erts_print(to, to_arg, ADDR_FMT ":", ptr);
- if (is_arity_value(hdr)) {
- Uint i;
- Uint arity = arityval(hdr);
-
- erts_print(to, to_arg, "t" WORD_FMT ":", arity);
- for (i = 1; i <= arity; i++) {
- dump_element(to, to_arg, ptr[i]);
- if (is_immed(ptr[i])) {
- ptr[i] = make_small(0);
- }
- if (i < arity) {
- erts_putc(to, to_arg, ',');
- }
- }
+ UseTmpHeapNoproc(1);
+ *last = OUR_NIL;
+
+ while (x != OUR_NIL) {
+ if (is_CP(x)) {
+ next = (Eterm *) EXPAND_POINTER(x);
+ } else if (is_list(x)) {
+ ptr = list_val(x);
+ if (ptr[0] != OUR_NIL) {
+ erts_print(to, to_arg, ADDR_FMT ":l", ptr);
+ dump_element(to, to_arg, ptr[0]);
+ erts_putc(to, to_arg, '|');
+ dump_element(to, to_arg, ptr[1]);
erts_putc(to, to_arg, '\n');
- if (arity == 0) {
- ptr[0] = OUR_NIL;
- } else {
- x = ptr[arity];
- ptr[0] = (Eterm) COMPRESS_POINTER(next);
- next = ptr + arity - 1;
- goto again;
+ if (is_immed(ptr[1])) {
+ ptr[1] = make_small(0);
}
- } else if (hdr == HEADER_FLONUM) {
- FloatDef f;
- char sbuf[31];
- int i;
-
- GET_DOUBLE_DATA((ptr+1), f);
- i = sys_double_to_chars(f.fd, (char*) sbuf);
- sys_memset(sbuf+i, 0, 31-i);
- erts_print(to, to_arg, "F%X:%s\n", i, sbuf);
- *ptr = OUR_NIL;
- } else if (_is_bignum_header(hdr)) {
- erts_print(to, to_arg, "B%T\n", x);
- *ptr = OUR_NIL;
- } else if (is_binary_header(hdr)) {
- Uint tag = thing_subtag(hdr);
- Uint size = binary_size(x);
- Uint i;
-
- if (tag == HEAP_BINARY_SUBTAG) {
- byte* p;
-
- erts_print(to, to_arg, "Yh%X:", size);
- p = binary_bytes(x);
- for (i = 0; i < size; i++) {
- erts_print(to, to_arg, "%02X", p[i]);
+ x = ptr[0];
+ ptr[0] = (Eterm) COMPRESS_POINTER(next);
+ next = ptr + 1;
+ continue;
+ }
+ } else if (is_boxed(x)) {
+ Eterm hdr;
+
+ ptr = boxed_val(x);
+ hdr = *ptr;
+ if (hdr != OUR_NIL) { /* If not visited */
+ erts_print(to, to_arg, ADDR_FMT ":", ptr);
+ if (is_arity_value(hdr)) {
+ Uint i;
+ Uint arity = arityval(hdr);
+
+ erts_print(to, to_arg, "t" WORD_FMT ":", arity);
+ for (i = 1; i <= arity; i++) {
+ dump_element(to, to_arg, ptr[i]);
+ if (is_immed(ptr[i])) {
+ ptr[i] = make_small(0);
+ }
+ if (i < arity) {
+ erts_putc(to, to_arg, ',');
+ }
}
- } else if (tag == REFC_BINARY_SUBTAG) {
- ProcBin* pb = (ProcBin *) binary_val(x);
- Binary* val = pb->val;
-
- if (erts_smp_atomic_xchg(&val->refc, 0) != 0) {
- val->flags = (UWord) all_binaries;
- all_binaries = val;
+ erts_putc(to, to_arg, '\n');
+ if (arity == 0) {
+ ptr[0] = OUR_NIL;
+ } else {
+ x = ptr[arity];
+ ptr[0] = (Eterm) COMPRESS_POINTER(next);
+ next = ptr + arity - 1;
+ continue;
}
- erts_print(to, to_arg, "Yc%X:%X:%X", val,
- pb->bytes - (byte *)val->orig_bytes,
- size);
- } else if (tag == SUB_BINARY_SUBTAG) {
- ErlSubBin* Sb = (ErlSubBin *) binary_val(x);
- Eterm* real_bin = binary_val(Sb->orig);
- void* val;
-
- if (thing_subtag(*real_bin) == REFC_BINARY_SUBTAG) {
- ProcBin* pb = (ProcBin *) real_bin;
- val = pb->val;
- } else { /* Heap binary */
- val = real_bin;
+ } else if (hdr == HEADER_FLONUM) {
+ FloatDef f;
+ char sbuf[31];
+ int i;
+
+ GET_DOUBLE_DATA((ptr+1), f);
+ i = sys_double_to_chars(f.fd, (char*) sbuf);
+ sys_memset(sbuf+i, 0, 31-i);
+ erts_print(to, to_arg, "F%X:%s\n", i, sbuf);
+ *ptr = OUR_NIL;
+ } else if (_is_bignum_header(hdr)) {
+ erts_print(to, to_arg, "B%T\n", x);
+ *ptr = OUR_NIL;
+ } else if (is_binary_header(hdr)) {
+ Uint tag = thing_subtag(hdr);
+ Uint size = binary_size(x);
+ Uint i;
+
+ if (tag == HEAP_BINARY_SUBTAG) {
+ byte* p;
+
+ erts_print(to, to_arg, "Yh%X:", size);
+ p = binary_bytes(x);
+ for (i = 0; i < size; i++) {
+ erts_print(to, to_arg, "%02X", p[i]);
+ }
+ } else if (tag == REFC_BINARY_SUBTAG) {
+ ProcBin* pb = (ProcBin *) binary_val(x);
+ Binary* val = pb->val;
+
+ if (erts_smp_atomic_xchg(&val->refc, 0) != 0) {
+ val->flags = (UWord) all_binaries;
+ all_binaries = val;
+ }
+ erts_print(to, to_arg, "Yc%X:%X:%X", val,
+ pb->bytes - (byte *)val->orig_bytes,
+ size);
+ } else if (tag == SUB_BINARY_SUBTAG) {
+ ErlSubBin* Sb = (ErlSubBin *) binary_val(x);
+ Eterm* real_bin = binary_val(Sb->orig);
+ void* val;
+
+ if (thing_subtag(*real_bin) == REFC_BINARY_SUBTAG) {
+ ProcBin* pb = (ProcBin *) real_bin;
+ val = pb->val;
+ } else { /* Heap binary */
+ val = real_bin;
+ }
+ erts_print(to, to_arg, "Ys%X:%X:%X", val, Sb->offs, size);
}
- erts_print(to, to_arg, "Ys%X:%X:%X", val, Sb->offs, size);
+ erts_putc(to, to_arg, '\n');
+ *ptr = OUR_NIL;
+ } else if (is_external_pid_header(hdr)) {
+ erts_print(to, to_arg, "P%T\n", x);
+ *ptr = OUR_NIL;
+ } else if (is_external_port_header(hdr)) {
+ erts_print(to, to_arg, "p<%bpu.%bpu>\n",
+ port_channel_no(x), port_number(x));
+ *ptr = OUR_NIL;
+ } else {
+ /*
+ * All other we dump in the external term format.
+ */
+ dump_externally(to, to_arg, x);
+ erts_putc(to, to_arg, '\n');
+ *ptr = OUR_NIL;
}
- erts_putc(to, to_arg, '\n');
- *ptr = OUR_NIL;
- } else if (is_external_pid_header(hdr)) {
- erts_print(to, to_arg, "P%T\n", x);
- *ptr = OUR_NIL;
- } else if (is_external_port_header(hdr)) {
- erts_print(to, to_arg, "p<%bpu.%bpu>\n",
- port_channel_no(x), port_number(x));
- *ptr = OUR_NIL;
- } else {
- /*
- * All other we dump in the external term format.
- */
- dump_externally(to, to_arg, x);
- erts_putc(to, to_arg, '\n');
- *ptr = OUR_NIL;
}
}
+ x = *next;
+ *next = OUR_NIL;
+ next--;
}
-
- x = *next;
- *next = OUR_NIL;
- next--;
- goto again;
+ UnUseTmpHeapNoproc(1);
}
static void
diff --git a/erts/emulator/beam/erl_process_lock.c b/erts/emulator/beam/erl_process_lock.c
index a4d12139e9..72560aa124 100644
--- a/erts/emulator/beam/erl_process_lock.c
+++ b/erts/emulator/beam/erl_process_lock.c
@@ -117,15 +117,14 @@ static int aux_thr_proc_lock_spin_count;
static void cleanup_tse(void);
void
-erts_init_proc_lock(void)
+erts_init_proc_lock(int cpus)
{
int i;
- int cpus;
erts_smp_spinlock_init(&qs_lock, "proc_lck_qs_alloc");
for (i = 0; i < ERTS_NO_OF_PIX_LOCKS; i++) {
#ifdef ERTS_ENABLE_LOCK_COUNT
erts_smp_spinlock_init_x(&erts_pix_locks[i].u.spnlck,
- "pix_lock", make_small(i));
+ "pix_lock", make_small(i));
#else
erts_smp_spinlock_init(&erts_pix_locks[i].u.spnlck, "pix_lock");
#endif
@@ -138,7 +137,6 @@ erts_init_proc_lock(void)
lc_id.proc_lock_msgq = erts_lc_get_lock_order_id("proc_msgq");
lc_id.proc_lock_status = erts_lc_get_lock_order_id("proc_status");
#endif
- cpus = erts_get_cpu_configured(erts_cpuinfo);
if (cpus > 1) {
proc_lock_spin_count = ERTS_PROC_LOCK_SPIN_COUNT_BASE;
proc_lock_spin_count += (ERTS_PROC_LOCK_SPIN_COUNT_SCHED_INC
@@ -415,7 +413,7 @@ transfer_locks(Process *p,
do {
erts_tse_t *tmp = wake;
wake = wake->next;
- erts_atomic_set(&tmp->uaflgs, 0);
+ erts_atomic32_set(&tmp->uaflgs, 0);
erts_tse_set(tmp);
} while (wake);
@@ -511,14 +509,14 @@ wait_for_locks(Process *p,
ASSERT((wtr->uflgs & ~ERTS_PROC_LOCKS_ALL) == 0);
- erts_atomic_set(&wtr->uaflgs, 1);
+ erts_atomic32_set(&wtr->uaflgs, 1);
erts_pix_unlock(pix_lock);
while (1) {
int res;
erts_tse_reset(wtr);
- if (erts_atomic_read(&wtr->uaflgs) == 0)
+ if (erts_atomic32_read(&wtr->uaflgs) == 0)
break;
/*
@@ -957,7 +955,7 @@ erts_proc_lock_init(Process *p)
{
/* We always start with all locks locked */
#if ERTS_PROC_LOCK_ATOMIC_IMPL
- erts_smp_atomic_init(&p->lock.flags, (long) ERTS_PROC_LOCKS_ALL);
+ erts_smp_atomic32_init(&p->lock.flags, (erts_aint32_t) ERTS_PROC_LOCKS_ALL);
#else
p->lock.flags = ERTS_PROC_LOCKS_ALL;
#endif
@@ -976,7 +974,7 @@ erts_proc_lock_init(Process *p)
{
int i;
for (i = 0; i <= ERTS_PROC_LOCK_MAX_BIT; i++)
- erts_smp_atomic_init(&p->lock.locked[i], (long) 1);
+ erts_smp_atomic32_init(&p->lock.locked[i], (erts_aint32_t) 1);
}
#endif
}
diff --git a/erts/emulator/beam/erl_process_lock.h b/erts/emulator/beam/erl_process_lock.h
index 7cfc9893fa..355179f084 100644
--- a/erts/emulator/beam/erl_process_lock.h
+++ b/erts/emulator/beam/erl_process_lock.h
@@ -1,7 +1,7 @@
/*
* %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
@@ -54,20 +54,20 @@
#define ERTS_PROC_LOCK_MAX_BIT 3
-typedef Uint32 ErtsProcLocks;
+typedef erts_aint32_t ErtsProcLocks;
typedef struct erts_proc_lock_queues_t_ erts_proc_lock_queues_t;
typedef struct erts_proc_lock_t_ {
#if ERTS_PROC_LOCK_ATOMIC_IMPL
- erts_smp_atomic_t flags;
+ erts_smp_atomic32_t flags;
#else
ErtsProcLocks flags;
#endif
erts_proc_lock_queues_t *queues;
- long refc;
+ Sint32 refc;
#ifdef ERTS_PROC_LOCK_DEBUG
- erts_smp_atomic_t locked[ERTS_PROC_LOCK_MAX_BIT+1];
+ erts_smp_atomic32_t locked[ERTS_PROC_LOCK_MAX_BIT+1];
#endif
#ifdef ERTS_ENABLE_LOCK_COUNT
erts_lcnt_lock_t lcnt_main;
@@ -270,17 +270,19 @@ typedef struct {
#if ERTS_PROC_LOCK_ATOMIC_IMPL
#define ERTS_PROC_LOCK_FLGS_BAND_(L, MSK) \
- ((ErtsProcLocks) erts_smp_atomic_band(&(L)->flags, (long) (MSK)))
+ ((ErtsProcLocks) erts_smp_atomic32_band(&(L)->flags, (erts_aint32_t) (MSK)))
#define ERTS_PROC_LOCK_FLGS_BOR_(L, MSK) \
- ((ErtsProcLocks) erts_smp_atomic_bor(&(L)->flags, (long) (MSK)))
+ ((ErtsProcLocks) erts_smp_atomic32_bor(&(L)->flags, (erts_aint32_t) (MSK)))
#define ERTS_PROC_LOCK_FLGS_CMPXCHG_ACQB_(L, NEW, EXPECTED) \
- ((ErtsProcLocks) erts_smp_atomic_cmpxchg_acqb(&(L)->flags, \
- (long) (NEW), (long) (EXPECTED)))
+ ((ErtsProcLocks) erts_smp_atomic32_cmpxchg_acqb(&(L)->flags, \
+ (erts_aint32_t) (NEW), \
+ (erts_aint32_t) (EXPECTED)))
#define ERTS_PROC_LOCK_FLGS_CMPXCHG_RELB_(L, NEW, EXPECTED) \
- ((ErtsProcLocks) erts_smp_atomic_cmpxchg_relb(&(L)->flags, \
- (long) (NEW), (long) (EXPECTED)))
+ ((ErtsProcLocks) erts_smp_atomic32_cmpxchg_relb(&(L)->flags, \
+ (erts_aint32_t) (NEW), \
+ (erts_aint32_t) (EXPECTED)))
#define ERTS_PROC_LOCK_FLGS_READ_(L) \
- ((ErtsProcLocks) erts_smp_atomic_read(&(L)->flags))
+ ((ErtsProcLocks) erts_smp_atomic32_read(&(L)->flags))
#else /* no opt atomic ops */
@@ -334,7 +336,7 @@ erts_proc_lock_flags_cmpxchg(erts_proc_lock_t *lck, ErtsProcLocks new,
extern erts_pix_lock_t erts_pix_locks[ERTS_NO_OF_PIX_LOCKS];
-void erts_init_proc_lock(void);
+void erts_init_proc_lock(int cpus);
void erts_proc_lock_prepare_proc_lock_waiter(void);
void erts_proc_lock_failed(Process *,
erts_pix_lock_t *,
@@ -619,13 +621,13 @@ erts_proc_lock_op_debug(Process *p, ErtsProcLocks locks, int locked)
for (i = 0; i <= ERTS_PROC_LOCK_MAX_BIT; i++) {
ErtsProcLocks lock = ((ErtsProcLocks) 1) << i;
if (locks & lock) {
- long lock_count;
+ erts_aint32_t lock_count;
if (locked) {
- lock_count = erts_smp_atomic_inctest(&p->lock.locked[i]);
+ lock_count = erts_smp_atomic32_inctest(&p->lock.locked[i]);
ERTS_LC_ASSERT(lock_count == 1);
}
else {
- lock_count = erts_smp_atomic_dectest(&p->lock.locked[i]);
+ lock_count = erts_smp_atomic32_dectest(&p->lock.locked[i]);
ERTS_LC_ASSERT(lock_count == 0);
}
}
diff --git a/erts/emulator/beam/erl_smp.h b/erts/emulator/beam/erl_smp.h
index b41fa70476..287327bfe1 100644
--- a/erts/emulator/beam/erl_smp.h
+++ b/erts/emulator/beam/erl_smp.h
@@ -54,10 +54,10 @@ typedef erts_cnd_t erts_smp_cnd_t;
typedef erts_rwmtx_opt_t erts_smp_rwmtx_opt_t;
typedef erts_rwmtx_t erts_smp_rwmtx_t;
typedef erts_tsd_key_t erts_smp_tsd_key_t;
-typedef ethr_atomic_t erts_smp_atomic_t;
+typedef erts_atomic_t erts_smp_atomic_t;
+typedef erts_atomic32_t erts_smp_atomic32_t;
typedef erts_spinlock_t erts_smp_spinlock_t;
typedef erts_rwlock_t erts_smp_rwlock_t;
-typedef erts_thr_timeval_t erts_smp_thr_timeval_t;
void erts_thr_fatal_error(int, char *); /* implemented in erl_init.c */
#else /* #ifdef ERTS_SMP */
@@ -83,7 +83,8 @@ typedef struct {
} erts_smp_rwmtx_opt_t;
typedef int erts_smp_rwmtx_t;
typedef int erts_smp_tsd_key_t;
-typedef long erts_smp_atomic_t;
+typedef SWord erts_smp_atomic_t;
+typedef Uint32 erts_smp_atomic32_t;
#if __GNUC__ > 2
typedef struct { } erts_smp_spinlock_t;
typedef struct { } erts_smp_rwlock_t;
@@ -92,11 +93,6 @@ typedef struct { int gcc_is_buggy; } erts_smp_spinlock_t;
typedef struct { int gcc_is_buggy; } erts_smp_rwlock_t;
#endif
-typedef struct {
- long tv_sec;
- long tv_nsec;
-} erts_smp_thr_timeval_t;
-
#endif /* #ifdef ERTS_SMP */
ERTS_GLB_INLINE void erts_smp_thr_init(erts_smp_thr_init_data_t *id);
@@ -164,33 +160,82 @@ ERTS_GLB_INLINE int erts_smp_rwmtx_tryrwlock(erts_smp_rwmtx_t *rwmtx);
ERTS_GLB_INLINE void erts_smp_rwmtx_rwunlock(erts_smp_rwmtx_t *rwmtx);
ERTS_GLB_INLINE int erts_smp_lc_rwmtx_is_rlocked(erts_smp_rwmtx_t *mtx);
ERTS_GLB_INLINE int erts_smp_lc_rwmtx_is_rwlocked(erts_smp_rwmtx_t *mtx);
-ERTS_GLB_INLINE void erts_smp_atomic_init(erts_smp_atomic_t *var, long i);
-ERTS_GLB_INLINE void erts_smp_atomic_set(erts_smp_atomic_t *var, long i);
-ERTS_GLB_INLINE long erts_smp_atomic_read(erts_smp_atomic_t *var);
-ERTS_GLB_INLINE long erts_smp_atomic_inctest(erts_smp_atomic_t *incp);
-ERTS_GLB_INLINE long erts_smp_atomic_dectest(erts_smp_atomic_t *decp);
+ERTS_GLB_INLINE void erts_smp_atomic_init(erts_smp_atomic_t *var,
+ erts_aint_t i);
+ERTS_GLB_INLINE void erts_smp_atomic_set(erts_smp_atomic_t *var, erts_aint_t i);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_read(erts_smp_atomic_t *var);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_inctest(erts_smp_atomic_t *incp);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_dectest(erts_smp_atomic_t *decp);
ERTS_GLB_INLINE void erts_smp_atomic_inc(erts_smp_atomic_t *incp);
ERTS_GLB_INLINE void erts_smp_atomic_dec(erts_smp_atomic_t *decp);
-ERTS_GLB_INLINE long erts_smp_atomic_addtest(erts_smp_atomic_t *addp,
- long i);
-ERTS_GLB_INLINE void erts_smp_atomic_add(erts_smp_atomic_t *addp, long i);
-ERTS_GLB_INLINE long erts_smp_atomic_xchg(erts_smp_atomic_t *xchgp,
- long new);
-ERTS_GLB_INLINE long erts_smp_atomic_cmpxchg(erts_smp_atomic_t *xchgp,
- long new,
- long expected);
-ERTS_GLB_INLINE long erts_smp_atomic_bor(erts_smp_atomic_t *var, long mask);
-ERTS_GLB_INLINE long erts_smp_atomic_band(erts_smp_atomic_t *var, long mask);
-ERTS_GLB_INLINE long erts_smp_atomic_read_acqb(erts_smp_atomic_t *var);
-ERTS_GLB_INLINE void erts_smp_atomic_set_relb(erts_smp_atomic_t *var, long i);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_addtest(erts_smp_atomic_t *addp,
+ erts_aint_t i);
+ERTS_GLB_INLINE void erts_smp_atomic_add(erts_smp_atomic_t *addp,
+ erts_aint_t i);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_xchg(erts_smp_atomic_t *xchgp,
+ erts_aint_t new);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_cmpxchg(erts_smp_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t expected);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_bor(erts_smp_atomic_t *var,
+ erts_aint_t mask);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_band(erts_smp_atomic_t *var,
+ erts_aint_t mask);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_read_acqb(erts_smp_atomic_t *var);
+ERTS_GLB_INLINE void erts_smp_atomic_set_relb(erts_smp_atomic_t *var,
+ erts_aint_t i);
ERTS_GLB_INLINE void erts_smp_atomic_dec_relb(erts_smp_atomic_t *decp);
-ERTS_GLB_INLINE long erts_smp_atomic_dectest_relb(erts_smp_atomic_t *decp);
-ERTS_GLB_INLINE long erts_smp_atomic_cmpxchg_acqb(erts_smp_atomic_t *xchgp,
- long new,
- long exp);
-ERTS_GLB_INLINE long erts_smp_atomic_cmpxchg_relb(erts_smp_atomic_t *xchgp,
- long new,
- long exp);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_dectest_relb(erts_smp_atomic_t *decp);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_cmpxchg_acqb(erts_smp_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t exp);
+ERTS_GLB_INLINE erts_aint_t erts_smp_atomic_cmpxchg_relb(erts_smp_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t exp);
+ERTS_GLB_INLINE void
+erts_smp_atomic32_init(erts_smp_atomic32_t *var, erts_aint32_t i);
+ERTS_GLB_INLINE void
+erts_smp_atomic32_set(erts_smp_atomic32_t *var, erts_aint32_t i);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_read(erts_smp_atomic32_t *var);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_inctest(erts_smp_atomic32_t *incp);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_dectest(erts_smp_atomic32_t *decp);
+ERTS_GLB_INLINE void
+erts_smp_atomic32_inc(erts_smp_atomic32_t *incp);
+ERTS_GLB_INLINE void
+erts_smp_atomic32_dec(erts_smp_atomic32_t *decp);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_addtest(erts_smp_atomic32_t *addp, erts_aint32_t i);
+ERTS_GLB_INLINE void
+erts_smp_atomic32_add(erts_smp_atomic32_t *addp, erts_aint32_t i);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_xchg(erts_smp_atomic32_t *xchgp, erts_aint32_t new);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_cmpxchg(erts_smp_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t expected);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_bor(erts_smp_atomic32_t *var, erts_aint32_t mask);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_band(erts_smp_atomic32_t *var, erts_aint32_t mask);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_read_acqb(erts_smp_atomic32_t *var);
+ERTS_GLB_INLINE void
+erts_smp_atomic32_set_relb(erts_smp_atomic32_t *var, erts_aint32_t i);
+ERTS_GLB_INLINE void
+erts_smp_atomic32_dec_relb(erts_smp_atomic32_t *decp);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_dectest_relb(erts_smp_atomic32_t *decp);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_cmpxchg_acqb(erts_smp_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t exp);
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_cmpxchg_relb(erts_smp_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t exp);
ERTS_GLB_INLINE void erts_smp_spinlock_init_x(erts_smp_spinlock_t *lock,
char *name,
Eterm extra);
@@ -221,7 +266,6 @@ ERTS_GLB_INLINE void erts_smp_write_lock(erts_smp_rwlock_t *lock);
ERTS_GLB_INLINE void erts_smp_write_unlock(erts_smp_rwlock_t *lock);
ERTS_GLB_INLINE int erts_smp_lc_rwlock_is_rlocked(erts_smp_rwlock_t *lock);
ERTS_GLB_INLINE int erts_smp_lc_rwlock_is_rwlocked(erts_smp_rwlock_t *lock);
-ERTS_GLB_INLINE void erts_smp_thr_time_now(erts_smp_thr_timeval_t *time);
ERTS_GLB_INLINE void erts_smp_tsd_key_create(erts_smp_tsd_key_t *keyp);
ERTS_GLB_INLINE void erts_smp_tsd_key_delete(erts_smp_tsd_key_t key);
ERTS_GLB_INLINE void erts_smp_tsd_set(erts_smp_tsd_key_t key, void *value);
@@ -611,7 +655,7 @@ erts_smp_lc_rwmtx_is_rwlocked(erts_smp_rwmtx_t *mtx)
}
ERTS_GLB_INLINE void
-erts_smp_atomic_init(erts_smp_atomic_t *var, long i)
+erts_smp_atomic_init(erts_smp_atomic_t *var, erts_aint_t i)
{
#ifdef ERTS_SMP
erts_atomic_init(var, i);
@@ -621,7 +665,7 @@ erts_smp_atomic_init(erts_smp_atomic_t *var, long i)
}
ERTS_GLB_INLINE void
-erts_smp_atomic_set(erts_smp_atomic_t *var, long i)
+erts_smp_atomic_set(erts_smp_atomic_t *var, erts_aint_t i)
{
#ifdef ERTS_SMP
erts_atomic_set(var, i);
@@ -630,7 +674,7 @@ erts_smp_atomic_set(erts_smp_atomic_t *var, long i)
#endif
}
-ERTS_GLB_INLINE long
+ERTS_GLB_INLINE erts_aint_t
erts_smp_atomic_read(erts_smp_atomic_t *var)
{
#ifdef ERTS_SMP
@@ -640,7 +684,7 @@ erts_smp_atomic_read(erts_smp_atomic_t *var)
#endif
}
-ERTS_GLB_INLINE long
+ERTS_GLB_INLINE erts_aint_t
erts_smp_atomic_inctest(erts_smp_atomic_t *incp)
{
#ifdef ERTS_SMP
@@ -650,7 +694,7 @@ erts_smp_atomic_inctest(erts_smp_atomic_t *incp)
#endif
}
-ERTS_GLB_INLINE long
+ERTS_GLB_INLINE erts_aint_t
erts_smp_atomic_dectest(erts_smp_atomic_t *decp)
{
#ifdef ERTS_SMP
@@ -680,8 +724,8 @@ erts_smp_atomic_dec(erts_smp_atomic_t *decp)
#endif
}
-ERTS_GLB_INLINE long
-erts_smp_atomic_addtest(erts_smp_atomic_t *addp, long i)
+ERTS_GLB_INLINE erts_aint_t
+erts_smp_atomic_addtest(erts_smp_atomic_t *addp, erts_aint_t i)
{
#ifdef ERTS_SMP
return erts_atomic_addtest(addp, i);
@@ -691,7 +735,7 @@ erts_smp_atomic_addtest(erts_smp_atomic_t *addp, long i)
}
ERTS_GLB_INLINE void
-erts_smp_atomic_add(erts_smp_atomic_t *addp, long i)
+erts_smp_atomic_add(erts_smp_atomic_t *addp, erts_aint_t i)
{
#ifdef ERTS_SMP
erts_atomic_add(addp, i);
@@ -700,59 +744,61 @@ erts_smp_atomic_add(erts_smp_atomic_t *addp, long i)
#endif
}
-ERTS_GLB_INLINE long
-erts_smp_atomic_xchg(erts_smp_atomic_t *xchgp, long new)
+ERTS_GLB_INLINE erts_aint_t
+erts_smp_atomic_xchg(erts_smp_atomic_t *xchgp, erts_aint_t new)
{
#ifdef ERTS_SMP
return erts_atomic_xchg(xchgp, new);
#else
- long old;
+ erts_aint_t old;
old = *xchgp;
*xchgp = new;
return old;
#endif
}
-ERTS_GLB_INLINE long
-erts_smp_atomic_cmpxchg(erts_smp_atomic_t *xchgp, long new, long expected)
+ERTS_GLB_INLINE erts_aint_t
+erts_smp_atomic_cmpxchg(erts_smp_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t expected)
{
#ifdef ERTS_SMP
return erts_atomic_cmpxchg(xchgp, new, expected);
#else
- long old = *xchgp;
+ erts_aint_t old = *xchgp;
if (old == expected)
*xchgp = new;
return old;
#endif
}
-ERTS_GLB_INLINE long
-erts_smp_atomic_bor(erts_smp_atomic_t *var, long mask)
+ERTS_GLB_INLINE erts_aint_t
+erts_smp_atomic_bor(erts_smp_atomic_t *var, erts_aint_t mask)
{
#ifdef ERTS_SMP
return erts_atomic_bor(var, mask);
#else
- long old;
+ erts_aint_t old;
old = *var;
*var |= mask;
return old;
#endif
}
-ERTS_GLB_INLINE long
-erts_smp_atomic_band(erts_smp_atomic_t *var, long mask)
+ERTS_GLB_INLINE erts_aint_t
+erts_smp_atomic_band(erts_smp_atomic_t *var, erts_aint_t mask)
{
#ifdef ERTS_SMP
return erts_atomic_band(var, mask);
#else
- long old;
+ erts_aint_t old;
old = *var;
*var &= mask;
return old;
#endif
}
-ERTS_GLB_INLINE long
+ERTS_GLB_INLINE erts_aint_t
erts_smp_atomic_read_acqb(erts_smp_atomic_t *var)
{
#ifdef ERTS_SMP
@@ -763,7 +809,7 @@ erts_smp_atomic_read_acqb(erts_smp_atomic_t *var)
}
ERTS_GLB_INLINE void
-erts_smp_atomic_set_relb(erts_smp_atomic_t *var, long i)
+erts_smp_atomic_set_relb(erts_smp_atomic_t *var, erts_aint_t i)
{
#ifdef ERTS_SMP
erts_atomic_set_relb(var, i);
@@ -772,7 +818,8 @@ erts_smp_atomic_set_relb(erts_smp_atomic_t *var, long i)
#endif
}
-ERTS_GLB_INLINE void erts_smp_atomic_dec_relb(erts_smp_atomic_t *decp)
+ERTS_GLB_INLINE void
+erts_smp_atomic_dec_relb(erts_smp_atomic_t *decp)
{
#ifdef ERTS_SMP
erts_atomic_dec_relb(decp);
@@ -781,7 +828,7 @@ ERTS_GLB_INLINE void erts_smp_atomic_dec_relb(erts_smp_atomic_t *decp)
#endif
}
-ERTS_GLB_INLINE long
+ERTS_GLB_INLINE erts_aint_t
erts_smp_atomic_dectest_relb(erts_smp_atomic_t *decp)
{
#ifdef ERTS_SMP
@@ -791,28 +838,244 @@ erts_smp_atomic_dectest_relb(erts_smp_atomic_t *decp)
#endif
}
-ERTS_GLB_INLINE long erts_smp_atomic_cmpxchg_acqb(erts_smp_atomic_t *xchgp,
- long new,
- long exp)
+ERTS_GLB_INLINE erts_aint_t
+erts_smp_atomic_cmpxchg_acqb(erts_smp_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t exp)
{
#ifdef ERTS_SMP
return erts_atomic_cmpxchg_acqb(xchgp, new, exp);
#else
- long old = *xchgp;
+ erts_aint_t old = *xchgp;
if (old == exp)
*xchgp = new;
return old;
#endif
}
-ERTS_GLB_INLINE long erts_smp_atomic_cmpxchg_relb(erts_smp_atomic_t *xchgp,
- long new,
- long exp)
+ERTS_GLB_INLINE erts_aint_t
+erts_smp_atomic_cmpxchg_relb(erts_smp_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t exp)
{
#ifdef ERTS_SMP
return erts_atomic_cmpxchg_relb(xchgp, new, exp);
#else
- long old = *xchgp;
+ erts_aint_t old = *xchgp;
+ if (old == exp)
+ *xchgp = new;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_smp_atomic32_init(erts_smp_atomic32_t *var, erts_aint32_t i)
+{
+#ifdef ERTS_SMP
+ erts_atomic32_init(var, i);
+#else
+ *var = i;
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_smp_atomic32_set(erts_smp_atomic32_t *var, erts_aint32_t i)
+{
+#ifdef ERTS_SMP
+ erts_atomic32_set(var, i);
+#else
+ *var = i;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_read(erts_smp_atomic32_t *var)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_read(var);
+#else
+ return *var;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_inctest(erts_smp_atomic32_t *incp)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_inctest(incp);
+#else
+ return ++(*incp);
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_dectest(erts_smp_atomic32_t *decp)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_dectest(decp);
+#else
+ return --(*decp);
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_smp_atomic32_inc(erts_smp_atomic32_t *incp)
+{
+#ifdef ERTS_SMP
+ erts_atomic32_inc(incp);
+#else
+ ++(*incp);
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_smp_atomic32_dec(erts_smp_atomic32_t *decp)
+{
+#ifdef ERTS_SMP
+ erts_atomic32_dec(decp);
+#else
+ --(*decp);
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_addtest(erts_smp_atomic32_t *addp, erts_aint32_t i)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_addtest(addp, i);
+#else
+ return *addp += i;
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_smp_atomic32_add(erts_smp_atomic32_t *addp, erts_aint32_t i)
+{
+#ifdef ERTS_SMP
+ erts_atomic32_add(addp, i);
+#else
+ *addp += i;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_xchg(erts_smp_atomic32_t *xchgp, erts_aint32_t new)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_xchg(xchgp, new);
+#else
+ erts_aint32_t old;
+ old = *xchgp;
+ *xchgp = new;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_cmpxchg(erts_smp_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t expected)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_cmpxchg(xchgp, new, expected);
+#else
+ erts_aint32_t old = *xchgp;
+ if (old == expected)
+ *xchgp = new;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_bor(erts_smp_atomic32_t *var, erts_aint32_t mask)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_bor(var, mask);
+#else
+ erts_aint32_t old;
+ old = *var;
+ *var |= mask;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_band(erts_smp_atomic32_t *var, erts_aint32_t mask)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_band(var, mask);
+#else
+ erts_aint32_t old;
+ old = *var;
+ *var &= mask;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_read_acqb(erts_smp_atomic32_t *var)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_read_acqb(var);
+#else
+ return *var;
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_smp_atomic32_set_relb(erts_smp_atomic32_t *var, erts_aint32_t i)
+{
+#ifdef ERTS_SMP
+ erts_atomic32_set_relb(var, i);
+#else
+ *var = i;
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_smp_atomic32_dec_relb(erts_smp_atomic32_t *decp)
+{
+#ifdef ERTS_SMP
+ erts_atomic32_dec_relb(decp);
+#else
+ --(*decp);
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_dectest_relb(erts_smp_atomic32_t *decp)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_dectest_relb(decp);
+#else
+ return --(*decp);
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_cmpxchg_acqb(erts_smp_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t exp)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_cmpxchg_acqb(xchgp, new, exp);
+#else
+ erts_aint32_t old = *xchgp;
+ if (old == exp)
+ *xchgp = new;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_smp_atomic32_cmpxchg_relb(erts_smp_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t exp)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_cmpxchg_relb(xchgp, new, exp);
+#else
+ erts_aint32_t old = *xchgp;
if (old == exp)
*xchgp = new;
return old;
@@ -988,14 +1251,6 @@ erts_smp_lc_rwlock_is_rwlocked(erts_smp_rwlock_t *lock)
}
ERTS_GLB_INLINE void
-erts_smp_thr_time_now(erts_smp_thr_timeval_t *time)
-{
-#ifdef ERTS_SMP
- erts_thr_time_now(time);
-#endif
-}
-
-ERTS_GLB_INLINE void
erts_smp_tsd_key_create(erts_smp_tsd_key_t *keyp)
{
#ifdef ERTS_SMP
diff --git a/erts/emulator/beam/erl_term.c b/erts/emulator/beam/erl_term.c
index c6458a0e45..f77e8b798f 100644
--- a/erts/emulator/beam/erl_term.c
+++ b/erts/emulator/beam/erl_term.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2000-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -58,9 +58,9 @@ do { \
#endif
#if ET_DEBUG
-unsigned tag_val_def_debug(Eterm x, const char *file, unsigned line)
+unsigned tag_val_def_debug(Wterm x, const char *file, unsigned line)
#else
-unsigned tag_val_def(Eterm x)
+unsigned tag_val_def(Wterm x)
#define file __FILE__
#define line __LINE__
#endif
@@ -125,10 +125,10 @@ FUNTY checked_##FUN(ARGTY x, const char *file, unsigned line) \
ET_DEFINE_CHECKED(Eterm,make_boxed,Eterm*,_is_taggable_pointer);
ET_DEFINE_CHECKED(int,is_boxed,Eterm,!is_header);
-ET_DEFINE_CHECKED(Eterm*,boxed_val,Eterm,_boxed_precond);
+ET_DEFINE_CHECKED(Eterm*,boxed_val,Wterm,_boxed_precond);
ET_DEFINE_CHECKED(Eterm,make_list,Eterm*,_is_taggable_pointer);
ET_DEFINE_CHECKED(int,is_not_list,Eterm,!is_header);
-ET_DEFINE_CHECKED(Eterm*,list_val,Eterm,_list_precond);
+ET_DEFINE_CHECKED(Eterm*,list_val,Wterm,_list_precond);
ET_DEFINE_CHECKED(Uint,unsigned_val,Eterm,is_small);
ET_DEFINE_CHECKED(Sint,signed_val,Eterm,is_small);
ET_DEFINE_CHECKED(Uint,atom_val,Eterm,is_atom);
@@ -136,34 +136,35 @@ ET_DEFINE_CHECKED(Uint,header_arity,Eterm,is_header);
ET_DEFINE_CHECKED(Uint,arityval,Eterm,is_arity_value);
ET_DEFINE_CHECKED(Uint,thing_arityval,Eterm,is_thing);
ET_DEFINE_CHECKED(Uint,thing_subtag,Eterm,is_thing);
-ET_DEFINE_CHECKED(Eterm*,binary_val,Eterm,is_binary);
-ET_DEFINE_CHECKED(Eterm*,fun_val,Eterm,is_fun);
+ET_DEFINE_CHECKED(Eterm*,binary_val,Wterm,is_binary);
+ET_DEFINE_CHECKED(Eterm*,fun_val,Wterm,is_fun);
ET_DEFINE_CHECKED(int,bignum_header_is_neg,Eterm,_is_bignum_header);
ET_DEFINE_CHECKED(Eterm,bignum_header_neg,Eterm,_is_bignum_header);
ET_DEFINE_CHECKED(Uint,bignum_header_arity,Eterm,_is_bignum_header);
-ET_DEFINE_CHECKED(Eterm*,big_val,Eterm,is_big);
-ET_DEFINE_CHECKED(Eterm*,float_val,Eterm,is_float);
-ET_DEFINE_CHECKED(Eterm*,tuple_val,Eterm,is_tuple);
+ET_DEFINE_CHECKED(Eterm*,big_val,Wterm,is_big);
+ET_DEFINE_CHECKED(Eterm*,float_val,Wterm,is_float);
+ET_DEFINE_CHECKED(Eterm*,tuple_val,Wterm,is_tuple);
ET_DEFINE_CHECKED(Uint,internal_pid_data,Eterm,is_internal_pid);
ET_DEFINE_CHECKED(struct erl_node_*,internal_pid_node,Eterm,is_internal_pid);
ET_DEFINE_CHECKED(Uint,internal_port_data,Eterm,is_internal_port);
ET_DEFINE_CHECKED(struct erl_node_*,internal_port_node,Eterm,is_internal_port);
-ET_DEFINE_CHECKED(Eterm*,internal_ref_val,Eterm,is_internal_ref);
-ET_DEFINE_CHECKED(Uint,internal_ref_data_words,Eterm,is_internal_ref);
-ET_DEFINE_CHECKED(Uint32*,internal_ref_data,Eterm,is_internal_ref);
+ET_DEFINE_CHECKED(Eterm*,internal_ref_val,Wterm,is_internal_ref);
+ET_DEFINE_CHECKED(Uint,internal_ref_data_words,Wterm,is_internal_ref);
+ET_DEFINE_CHECKED(Uint32*,internal_ref_data,Wterm,is_internal_ref);
ET_DEFINE_CHECKED(struct erl_node_*,internal_ref_node,Eterm,is_internal_ref);
-ET_DEFINE_CHECKED(Eterm*,external_val,Eterm,is_external);
-ET_DEFINE_CHECKED(Uint,external_data_words,Eterm,is_external);
-ET_DEFINE_CHECKED(Uint,external_pid_data_words,Eterm,is_external_pid);
-ET_DEFINE_CHECKED(Uint,external_pid_data,Eterm,is_external_pid);
-ET_DEFINE_CHECKED(struct erl_node_*,external_pid_node,Eterm,is_external_pid);
-ET_DEFINE_CHECKED(Uint,external_port_data_words,Eterm,is_external_port);
-ET_DEFINE_CHECKED(Uint,external_port_data,Eterm,is_external_port);
-ET_DEFINE_CHECKED(struct erl_node_*,external_port_node,Eterm,is_external_port);
-ET_DEFINE_CHECKED(Uint,external_ref_data_words,Eterm,is_external_ref);
-ET_DEFINE_CHECKED(Uint32*,external_ref_data,Eterm,is_external_ref);
+ET_DEFINE_CHECKED(Eterm*,external_val,Wterm,is_external);
+ET_DEFINE_CHECKED(Uint,external_data_words,Wterm,is_external);
+ET_DEFINE_CHECKED(Uint,external_pid_data_words,Wterm,is_external_pid);
+ET_DEFINE_CHECKED(Uint,external_pid_data,Wterm,is_external_pid);
+ET_DEFINE_CHECKED(struct erl_node_*,external_pid_node,Wterm,is_external_pid);
+ET_DEFINE_CHECKED(Uint,external_port_data_words,Wterm,is_external_port);
+ET_DEFINE_CHECKED(Uint,external_port_data,Wterm,is_external_port);
+ET_DEFINE_CHECKED(struct erl_node_*,external_port_node,Wterm,is_external_port);
+ET_DEFINE_CHECKED(Uint,external_ref_data_words,Wterm,is_external_ref);
+ET_DEFINE_CHECKED(Uint32*,external_ref_data,Wterm,is_external_ref);
ET_DEFINE_CHECKED(struct erl_node_*,external_ref_node,Eterm,is_external_ref);
-ET_DEFINE_CHECKED(Eterm*,export_val,Eterm,is_export);
+ET_DEFINE_CHECKED(Eterm*,export_val,Wterm,is_export);
+ET_DEFINE_CHECKED(Uint,external_thing_data_words,ExternalThing*,is_thing_ptr);
ET_DEFINE_CHECKED(Eterm,make_cp,UWord *,_is_taggable_pointer);
ET_DEFINE_CHECKED(UWord *,cp_val,Eterm,is_CP);
diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h
index b8e4473141..1d75fa313c 100644
--- a/erts/emulator/beam/erl_term.h
+++ b/erts/emulator/beam/erl_term.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2000-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -22,6 +22,8 @@
#include "sys.h" /* defines HALFWORD_HEAP */
+typedef UWord Wterm; /* Full word terms */
+
#if HALFWORD_HEAP
# define HEAP_ON_C_STACK 0
# if HALFWORD_ASSERT
@@ -193,7 +195,7 @@ struct erl_node_; /* Declared in erl_node_tables.h */
#endif
#define _is_aligned(x) (((Uint)(x) & 0x3) == 0)
#define _unchecked_make_boxed(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_BOXED)
-_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*);
+_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*)
#define make_boxed(x) _ET_APPLY(make_boxed,(x))
#if 1
#define _is_not_boxed(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_BOXED))
@@ -204,12 +206,12 @@ _ET_DECLARE_CHECKED(int,is_boxed,Eterm)
#define is_boxed(x) (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_BOXED)
#endif
#define _unchecked_boxed_val(x) ((Eterm*) EXPAND_POINTER(((x) - TAG_PRIMARY_BOXED)))
-_ET_DECLARE_CHECKED(Eterm*,boxed_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,boxed_val,Wterm)
#define boxed_val(x) _ET_APPLY(boxed_val,(x))
/* cons cell ("list") access methods */
#define _unchecked_make_list(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_LIST)
-_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*);
+_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*)
#define make_list(x) _ET_APPLY(make_list,(x))
#if 1
#define _unchecked_is_not_list(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_LIST))
@@ -226,7 +228,7 @@ _ET_DECLARE_CHECKED(int,is_not_list,Eterm)
#define _list_precond(x) (is_list(x))
#endif
#define _unchecked_list_val(x) ((Eterm*) EXPAND_POINTER((x) - TAG_PRIMARY_LIST))
-_ET_DECLARE_CHECKED(Eterm*,list_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,list_val,Wterm)
#define list_val(x) _ET_APPLY(list_val,(x))
#define CONS(hp, car, cdr) \
@@ -240,6 +242,8 @@ _ET_DECLARE_CHECKED(Eterm*,list_val,Eterm);
#define ptr_val(x) _unchecked_ptr_val((x)) /*XXX*/
#define _unchecked_offset_ptr(x,offs) ((x)+((offs)*sizeof(Eterm)))
#define offset_ptr(x,offs) _unchecked_offset_ptr(x,offs) /*XXX*/
+#define _unchecked_byte_offset_ptr(x,byte_offs) ((x)+(offs))
+#define byte_offset_ptr(x,offs) _unchecked_byte_offset_ptr(x,offs) /*XXX*/
/* fixnum ("small") access methods */
#if defined(ARCH_64) && !HALFWORD_HEAP
@@ -305,6 +309,7 @@ _ET_DECLARE_CHECKED(Uint,arityval,Eterm)
/* thing access methods */
#define is_thing(x) (is_header((x)) && header_is_thing((x)))
+#define is_thing_ptr(t) (is_thing((t)->header))
#define _unchecked_thing_arityval(x) _unchecked_header_arity((x))
_ET_DECLARE_CHECKED(Uint,thing_arityval,Eterm)
#define thing_arityval(x) _ET_APPLY(thing_arityval,(x))
@@ -339,7 +344,7 @@ _ET_DECLARE_CHECKED(Uint,thing_subtag,Eterm)
#define is_binary(x) (is_boxed((x)) && is_binary_header(*boxed_val((x))))
#define is_not_binary(x) (!is_binary((x)))
#define _unchecked_binary_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,binary_val,Eterm)
+_ET_DECLARE_CHECKED(Eterm*,binary_val,Wterm)
#define binary_val(x) _ET_APPLY(binary_val,(x))
/* process binaries stuff (special case of binaries) */
@@ -356,7 +361,7 @@ _ET_DECLARE_CHECKED(Eterm*,binary_val,Eterm)
#define is_fun(x) (is_boxed((x)) && is_fun_header(*boxed_val((x))))
#define is_not_fun(x) (!is_fun((x)))
#define _unchecked_fun_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm)
+_ET_DECLARE_CHECKED(Eterm*,fun_val,Wterm)
#define fun_val(x) _ET_APPLY(fun_val,(x))
/* export access methods */
@@ -364,7 +369,7 @@ _ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm)
#define is_export(x) (is_boxed((x)) && is_export_header(*boxed_val((x))))
#define is_not_export(x) (!is_export((x)))
#define _unchecked_export_val(x) _unchecked_boxed_val(x)
-_ET_DECLARE_CHECKED(Eterm*,export_val,Eterm)
+_ET_DECLARE_CHECKED(Eterm*,export_val,Wterm)
#define export_val(x) _ET_APPLY(export_val,(x))
#define is_export_header(x) ((x) == HEADER_EXPORT)
#if HALFWORD_HEAP
@@ -391,7 +396,7 @@ _ET_DECLARE_CHECKED(Uint,bignum_header_arity,Eterm)
#define is_big(x) (is_boxed((x)) && _is_bignum_header(*boxed_val((x))))
#define is_not_big(x) (!is_big((x)))
#define _unchecked_big_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,big_val,Eterm)
+_ET_DECLARE_CHECKED(Eterm*,big_val,Wterm)
#define big_val(x) _ET_APPLY(big_val,(x))
/* flonum ("float") access methods */
@@ -404,7 +409,7 @@ _ET_DECLARE_CHECKED(Eterm*,big_val,Eterm)
#define is_float(x) (is_boxed((x)) && *boxed_val((x)) == HEADER_FLONUM)
#define is_not_float(x) (!is_float(x))
#define _unchecked_float_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,float_val,Eterm)
+_ET_DECLARE_CHECKED(Eterm*,float_val,Wterm)
#define float_val(x) _ET_APPLY(float_val,(x))
/* Float definition for byte and word access */
@@ -422,15 +427,16 @@ typedef union float_def
} FloatDef;
#if defined(ARCH_64) && !HALFWORD_HEAP
-#define GET_DOUBLE(x, f) (f).fdw = *(float_val(x)+1)
+
+#define FLOAT_VAL_GET_DOUBLE(fval, f) (f).fdw = *((fval)+1)
#define PUT_DOUBLE(f, x) *(x) = HEADER_FLONUM, \
*((x)+1) = (f).fdw
#define GET_DOUBLE_DATA(p, f) (f).fdw = *((Uint *) (p))
#define PUT_DOUBLE_DATA(f,p) *((Uint *) (p)) = (f).fdw
#else
-#define GET_DOUBLE(x, f) (f).fw[0] = *(float_val(x)+1), \
- (f).fw[1] = *(float_val(x)+2)
+#define FLOAT_VAL_GET_DOUBLE(fval, f) (f).fw[0] = *((fval)+1), \
+ (f).fw[1] = *((fval)+2)
#define PUT_DOUBLE(f, x) *(x) = HEADER_FLONUM, \
*((x)+1) = (f).fw[0], \
@@ -440,6 +446,9 @@ typedef union float_def
#define PUT_DOUBLE_DATA(f,p) *((Uint *) (p)) = (f).fw[0],\
*(((Uint *) (p))+1) = (f).fw[1]
#endif
+
+#define GET_DOUBLE(x, f) FLOAT_VAL_GET_DOUBLE(float_val(x), f)
+
#define DOUBLE_DATA_WORDS (sizeof(ieee754_8)/sizeof(Eterm))
#define FLOAT_SIZE_OBJECT (DOUBLE_DATA_WORDS+1)
@@ -451,7 +460,7 @@ typedef union float_def
(is_boxed((x)) && *boxed_val((x)) == make_arityval((a)))
#define is_not_tuple_arity(x, a) (!is_tuple_arity((x),(a)))
#define _unchecked_tuple_val(x) _unchecked_boxed_val(x)
-_ET_DECLARE_CHECKED(Eterm*,tuple_val,Eterm)
+_ET_DECLARE_CHECKED(Eterm*,tuple_val,Wterm)
#define tuple_val(x) _ET_APPLY(tuple_val,(x))
#define TUPLE0(t) \
@@ -790,21 +799,24 @@ do { \
((RefThing*) internal_ref_val(x))
#define is_internal_ref(x) \
- (_unchecked_is_boxed((x)) && is_ref_thing_header(*boxed_val((x))))
+ (_unchecked_is_boxed((x)) && is_ref_thing_header(*boxed_val((x))))
+
#define is_not_internal_ref(x) \
(!is_internal_ref((x)))
#define _unchecked_internal_ref_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,internal_ref_val,Eterm)
+_ET_DECLARE_CHECKED(Eterm*,internal_ref_val,Wterm)
#define internal_ref_val(x) _ET_APPLY(internal_ref_val,(x))
+#define internal_thing_ref_data_words(t) (thing_arityval(*(Eterm*)(t)))
#define _unchecked_internal_ref_data_words(x) \
(_unchecked_thing_arityval(*_unchecked_internal_ref_val(x)))
-_ET_DECLARE_CHECKED(Uint,internal_ref_data_words,Eterm)
+_ET_DECLARE_CHECKED(Uint,internal_ref_data_words,Wterm)
#define internal_ref_data_words(x) _ET_APPLY(internal_ref_data_words,(x))
-#define _unchecked_internal_ref_data(x) (_unchecked_ref_thing_ptr(x)->data.ui32)
-_ET_DECLARE_CHECKED(Uint32*,internal_ref_data,Eterm)
+#define internal_thing_ref_data(thing) ((thing)->data.ui32)
+#define _unchecked_internal_ref_data(x) (internal_thing_ref_data(_unchecked_ref_thing_ptr(x)))
+_ET_DECLARE_CHECKED(Uint32*,internal_ref_data,Wterm)
#define internal_ref_data(x) _ET_APPLY(internal_ref_data,(x))
#define _unchecked_internal_ref_node(x) erts_this_node
@@ -889,14 +901,14 @@ typedef struct external_thing_ {
#define is_external_header(x) \
(((x) & (_TAG_HEADER_MASK-_BINARY_XXX_MASK)) == _TAG_HEADER_EXTERNAL_PID)
-#define is_external(x) \
- (is_boxed((x)) && is_external_header(*boxed_val((x))))
+#define is_external(x) (is_boxed((x)) && is_external_header(*boxed_val((x))))
+
#define is_external_pid(x) \
(is_boxed((x)) && is_external_pid_header(*boxed_val((x))))
#define is_external_port(x) \
- (is_boxed((x)) && is_external_port_header(*boxed_val((x))))
-#define is_external_ref(x) \
- (_unchecked_is_boxed((x)) && is_external_ref_header(*boxed_val((x))))
+ (is_boxed((x)) && is_external_port_header(*boxed_val((x))))
+
+#define is_external_ref(x) (_unchecked_is_boxed((x)) && is_external_ref_header(*boxed_val((x))))
#define _unchecked_is_external(x) \
(_unchecked_is_boxed((x)) && is_external_header(*_unchecked_boxed_val((x))))
@@ -914,17 +926,21 @@ typedef struct external_thing_ {
#define make_external_ref make_external
#define _unchecked_external_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,external_val,Eterm)
+_ET_DECLARE_CHECKED(Eterm*,external_val,Wterm)
#define external_val(x) _ET_APPLY(external_val,(x))
#define external_thing_ptr(x) ((ExternalThing *) external_val((x)))
#define _unchecked_external_thing_ptr(x) \
((ExternalThing *) _unchecked_external_val((x)))
+#define _unchecked_external_thing_data_words(thing) \
+ (_unchecked_thing_arityval((thing)->header) + (1 - EXTERNAL_THING_HEAD_SIZE))
+_ET_DECLARE_CHECKED(Uint,external_thing_data_words,ExternalThing*)
+#define external_thing_data_words(thing) _ET_APPLY(external_thing_data_words,(thing))
+
#define _unchecked_external_data_words(x) \
- (_unchecked_thing_arityval(_unchecked_external_thing_ptr((x))->header) \
- + (1 - EXTERNAL_THING_HEAD_SIZE))
-_ET_DECLARE_CHECKED(Uint,external_data_words,Eterm)
+ _unchecked_external_thing_data_words(_unchecked_external_thing_ptr((x)))
+_ET_DECLARE_CHECKED(Uint,external_data_words,Wterm)
#define external_data_words(x) _ET_APPLY(external_data_words,(x))
#define _unchecked_external_data(x) (_unchecked_external_thing_ptr((x))->data.ui)
@@ -935,15 +951,15 @@ _ET_DECLARE_CHECKED(Uint,external_data_words,Eterm)
#define _unchecked_external_pid_data_words(x) \
_unchecked_external_data_words((x))
-_ET_DECLARE_CHECKED(Uint,external_pid_data_words,Eterm)
+_ET_DECLARE_CHECKED(Uint,external_pid_data_words,Wterm)
#define external_pid_data_words(x) _ET_APPLY(external_pid_data_words,(x))
#define _unchecked_external_pid_data(x) _unchecked_external_data((x))[0]
-_ET_DECLARE_CHECKED(Uint,external_pid_data,Eterm)
+_ET_DECLARE_CHECKED(Uint,external_pid_data,Wterm)
#define external_pid_data(x) _ET_APPLY(external_pid_data,(x))
#define _unchecked_external_pid_node(x) _unchecked_external_node((x))
-_ET_DECLARE_CHECKED(struct erl_node_*,external_pid_node,Eterm)
+_ET_DECLARE_CHECKED(struct erl_node_*,external_pid_node,Wterm)
#define external_pid_node(x) _ET_APPLY(external_pid_node,(x))
#define external_pid_number(x) _GET_PID_NUM(external_pid_data((x)))
@@ -951,27 +967,29 @@ _ET_DECLARE_CHECKED(struct erl_node_*,external_pid_node,Eterm)
#define _unchecked_external_port_data_words(x) \
_unchecked_external_data_words((x))
-_ET_DECLARE_CHECKED(Uint,external_port_data_words,Eterm)
+_ET_DECLARE_CHECKED(Uint,external_port_data_words,Wterm)
#define external_port_data_words(x) _ET_APPLY(external_port_data_words,(x))
#define _unchecked_external_port_data(x) _unchecked_external_data((x))[0]
-_ET_DECLARE_CHECKED(Uint,external_port_data,Eterm)
+_ET_DECLARE_CHECKED(Uint,external_port_data,Wterm)
#define external_port_data(x) _ET_APPLY(external_port_data,(x))
#define _unchecked_external_port_node(x) _unchecked_external_node((x))
-_ET_DECLARE_CHECKED(struct erl_node_*,external_port_node,Eterm)
+_ET_DECLARE_CHECKED(struct erl_node_*,external_port_node,Wterm)
#define external_port_node(x) _ET_APPLY(external_port_node,(x))
#define external_port_number(x) _GET_PORT_NUM(external_port_data((x)))
#define _unchecked_external_ref_data_words(x) \
_unchecked_external_data_words((x))
-_ET_DECLARE_CHECKED(Uint,external_ref_data_words,Eterm)
+_ET_DECLARE_CHECKED(Uint,external_ref_data_words,Wterm)
#define external_ref_data_words(x) _ET_APPLY(external_ref_data_words,(x))
+#define external_thing_ref_data_words(thing) external_thing_data_words(thing)
#define _unchecked_external_ref_data(x) (_unchecked_external_thing_ptr((x))->data.ui32)
-_ET_DECLARE_CHECKED(Uint32*,external_ref_data,Eterm)
+_ET_DECLARE_CHECKED(Uint32*,external_ref_data,Wterm)
#define external_ref_data(x) _ET_APPLY(external_ref_data,(x))
+#define external_thing_ref_data(thing) ((thing)->data.ui32)
#define _unchecked_external_ref_node(x) _unchecked_external_node((x))
_ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm)
@@ -995,14 +1013,14 @@ _ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm)
#endif
#define _unchecked_make_cp(x) ((Eterm) COMPRESS_POINTER(x))
-_ET_DECLARE_CHECKED(Eterm,make_cp,BeamInstr*);
+_ET_DECLARE_CHECKED(Eterm,make_cp,BeamInstr*)
#define make_cp(x) _ET_APPLY(make_cp,(x))
#define is_not_CP(x) ((x) & _CPMASK)
#define is_CP(x) (!is_not_CP(x))
#define _unchecked_cp_val(x) ((BeamInstr*) EXPAND_POINTER(x))
-_ET_DECLARE_CHECKED(BeamInstr*,cp_val,Eterm);
+_ET_DECLARE_CHECKED(BeamInstr*,cp_val,Eterm)
#define cp_val(x) _ET_APPLY(cp_val,(x))
#define make_catch(x) (((x) << _TAG_IMMED2_SIZE) | _TAG_IMMED2_CATCH)
@@ -1083,10 +1101,10 @@ _ET_DECLARE_CHECKED(Uint,y_reg_index,Uint)
#define SMALL_DEF 0xf
#if ET_DEBUG
-extern unsigned tag_val_def_debug(Eterm, const char*, unsigned);
+extern unsigned tag_val_def_debug(Wterm, const char*, unsigned);
#define tag_val_def(x) tag_val_def_debug((x),__FILE__,__LINE__)
#else
-extern unsigned tag_val_def(Eterm);
+extern unsigned tag_val_def(Wterm);
#endif
#define not_eq_tags(X,Y) (tag_val_def((X)) ^ tag_val_def((Y)))
@@ -1102,5 +1120,81 @@ extern unsigned tag_val_def(Eterm);
#define FLOAT_BIG _NUMBER_CODE(FLOAT_DEF,BIG_DEF)
#define FLOAT_FLOAT _NUMBER_CODE(FLOAT_DEF,FLOAT_DEF)
+#if HALFWORD_HEAP
+#define ptr2rel(PTR,BASE) ((Eterm*)((char*)(PTR) - (char*)(BASE)))
+#define rterm2wterm(REL,BASE) ((Wterm)(REL) + (Wterm)(BASE))
+
+#else /* HALFWORD_HEAP */
+
+#define ptr2rel(PTR,BASE) (PTR)
+#define rterm2wterm(REL,BASE) (REL)
+
+#endif /* !HALFWORD_HEAP */
+
+#define make_list_rel(PTR, BASE) make_list(ptr2rel(PTR,BASE))
+#define make_boxed_rel(PTR, BASE) make_boxed(ptr2rel(PTR,BASE))
+#define make_fun_rel make_boxed_rel
+#define make_binary_rel make_boxed_rel
+#define make_tuple_rel make_boxed_rel
+#define make_external_rel make_boxed_rel
+#define make_internal_ref_rel make_boxed_rel
+
+#define binary_val_rel(RTERM, BASE) binary_val(rterm2wterm(RTERM, BASE))
+#define list_val_rel(RTERM, BASE) list_val(rterm2wterm(RTERM, BASE))
+#define boxed_val_rel(RTERM, BASE) boxed_val(rterm2wterm(RTERM, BASE))
+#define tuple_val_rel(RTERM, BASE) tuple_val(rterm2wterm(RTERM, BASE))
+#define export_val_rel(RTERM, BASE) export_val(rterm2wterm(RTERM, BASE))
+#define fun_val_rel(RTERM, BASE) fun_val(rterm2wterm(RTERM, BASE))
+#define big_val_rel(RTERM,BASE) big_val(rterm2wterm(RTERM,BASE))
+#define float_val_rel(RTERM,BASE) float_val(rterm2wterm(RTERM,BASE))
+#define internal_ref_val_rel(RTERM,BASE) internal_ref_val(rterm2wterm(RTERM,BASE))
+
+#define external_thing_ptr_rel(RTERM, BASE) external_thing_ptr(rterm2wterm(RTERM, BASE))
+#define external_data_words_rel(RTERM,BASE) external_data_words(rterm2wterm(RTERM,BASE))
+
+#define external_port_node_rel(RTERM,BASE) external_port_node(rterm2wterm(RTERM,BASE))
+#define external_port_data_rel(RTERM,BASE) external_port_data(rterm2wterm(RTERM,BASE))
+
+#define is_external_pid_rel(RTERM,BASE) is_external_pid(rterm2wterm(RTERM,BASE))
+#define external_pid_node_rel(RTERM,BASE) external_pid_node(rterm2wterm(RTERM,BASE))
+#define external_pid_data_rel(RTERM,BASE) external_pid_data(rterm2wterm(RTERM,BASE))
+
+#define is_binary_rel(RTERM,BASE) is_binary(rterm2wterm(RTERM,BASE))
+#define is_float_rel(RTERM,BASE) is_float(rterm2wterm(RTERM,BASE))
+#define is_fun_rel(RTERM,BASE) is_fun(rterm2wterm(RTERM,BASE))
+#define is_big_rel(RTERM,BASE) is_big(rterm2wterm(RTERM,BASE))
+#define is_export_rel(RTERM,BASE) is_export(rterm2wterm(RTERM,BASE))
+#define is_tuple_rel(RTERM,BASE) is_tuple(rterm2wterm(RTERM,BASE))
+
+#define GET_DOUBLE_REL(RTERM, f, BASE) GET_DOUBLE(rterm2wterm(RTERM,BASE), f)
+
+#define ref_thing_ptr_rel(RTERM,BASE) ref_thing_ptr(rterm2wterm(RTERM,BASE))
+#define is_internal_ref_rel(RTERM,BASE) is_internal_ref(rterm2wterm(RTERM,BASE))
+#define is_external_rel(RTERM,BASE) is_external(rterm2wterm(RTERM,BASE))
+#define is_external_port_rel(RTERM,BASE) is_external_port(rterm2wterm(RTERM,BASE))
+#define is_external_ref_rel(RTERM,BASE) is_external_ref(rterm2wterm(RTERM,BASE))
+
+#define external_node_rel(RTERM,BASE) external_node(rterm2wterm(RTERM,BASE))
+
+
+#if HALFWORD_HEAP
+ERTS_GLB_INLINE int is_same(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+ERTS_GLB_INLINE int is_same(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base)
+{
+ /* If bases differ, assume a and b are on different "heaps",
+ ie can only be same if immed */
+ ASSERT(a_base == b_base || is_immed(a) || is_immed(b)
+ || rterm2wterm(a,a_base) != rterm2wterm(b,b_base));
+
+ return a == b && (a_base == b_base || is_immed(a));
+}
+#endif
+
+#else /* !HALFWORD_HEAP */
+#define is_same(A,A_BASE,B,B_BASE) ((A)==(B))
+#endif
+
#endif /* __ERL_TERM_H */
diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h
index 0b7269262e..8c9cace0c5 100644
--- a/erts/emulator/beam/erl_threads.h
+++ b/erts/emulator/beam/erl_threads.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -27,9 +27,6 @@
#define ERTS_SPIN_BODY ETHR_SPIN_BODY
-#define ERTS_MAX_READER_GROUPS 8
-extern int erts_reader_groups;
-
#include "sys.h"
#ifdef USE_THREADS
@@ -39,6 +36,16 @@ extern int erts_reader_groups;
#include "erl_lock_count.h"
#include "erl_term.h"
+#if defined(__GLIBC__) && (__GLIBC__ << 16) + __GLIBC_MINOR__ < (2 << 16) + 4
+/*
+ * pthread_mutex_destroy() may return EBUSY when it shouldn't :( We have
+ * only seen this bug in glibc versions before 2.4. Note that condition
+ * variables, rwmutexes, spinlocks, and rwspinlocks also may be effected by
+ * this bug since these implementations may use mutexes internally.
+ */
+# define ERTS_THR_HAVE_BUSY_DESTROY_BUG
+#endif
+
#define ERTS_THR_MEMORY_BARRIER ETHR_MEMORY_BARRIER
#ifdef ERTS_ENABLE_LOCK_COUNT
@@ -92,7 +99,10 @@ typedef ethr_rwmutex_opt erts_rwmtx_opt_t;
typedef ethr_tsd_key erts_tsd_key_t;
typedef ethr_ts_event erts_tse_t;
+typedef ethr_sint_t erts_aint_t;
typedef ethr_atomic_t erts_atomic_t;
+typedef ethr_sint32_t erts_aint32_t;
+typedef ethr_atomic32_t erts_atomic32_t;
/* spinlock */
typedef struct {
@@ -116,7 +126,6 @@ typedef struct {
#endif
} erts_rwlock_t;
-typedef ethr_timeval erts_thr_timeval_t;
__decl_noreturn void __noreturn erts_thr_fatal_error(int, char *);
/* implemented in erl_init.c */
@@ -155,7 +164,10 @@ typedef struct {
typedef int erts_rwmtx_t;
typedef int erts_tsd_key_t;
typedef int erts_tse_t;
-typedef long erts_atomic_t;
+typedef SWord erts_aint_t;
+typedef SWord erts_atomic_t;
+typedef SWord erts_aint32_t;
+typedef SWord erts_atomic32_t;
#if __GNUC__ > 2
typedef struct { } erts_spinlock_t;
typedef struct { } erts_rwlock_t;
@@ -163,10 +175,6 @@ typedef struct { } erts_rwlock_t;
typedef struct { int gcc_is_buggy; } erts_spinlock_t;
typedef struct { int gcc_is_buggy; } erts_rwlock_t;
#endif
-typedef struct {
- long tv_sec;
- long tv_nsec;
-} erts_thr_timeval_t;
#define ERTS_MTX_INITER 0
#define ERTS_CND_INITER 0
@@ -176,6 +184,11 @@ typedef struct {
#endif /* #ifdef USE_THREADS */
+#define ERTS_AINT_T_MAX (~(((erts_aint_t) 1) << (sizeof(erts_aint_t)*8-1)))
+#define ERTS_AINT_T_MIN ((((erts_aint_t) 1) << (sizeof(erts_aint_t)*8-1)))
+#define ERTS_AINT32_T_MAX (~(((erts_aint32_t) 1) << (sizeof(erts_aint32_t)*8-1)))
+#define ERTS_AINT32_T_MIN ((((erts_aint32_t) 1) << (sizeof(erts_aint32_t)*8-1)))
+
ERTS_GLB_INLINE void erts_thr_init(erts_thr_init_data_t *id);
ERTS_GLB_INLINE void erts_thr_late_init(erts_thr_late_init_data_t *id);
ERTS_GLB_INLINE void erts_thr_create(erts_tid_t *tid, void * (*func)(void *),
@@ -234,33 +247,65 @@ ERTS_GLB_INLINE int erts_rwmtx_tryrwlock(erts_rwmtx_t *rwmtx);
ERTS_GLB_INLINE void erts_rwmtx_rwunlock(erts_rwmtx_t *rwmtx);
ERTS_GLB_INLINE int erts_lc_rwmtx_is_rlocked(erts_rwmtx_t *mtx);
ERTS_GLB_INLINE int erts_lc_rwmtx_is_rwlocked(erts_rwmtx_t *mtx);
-ERTS_GLB_INLINE void erts_atomic_init(erts_atomic_t *var, long i);
-ERTS_GLB_INLINE void erts_atomic_set(erts_atomic_t *var, long i);
-ERTS_GLB_INLINE long erts_atomic_read(erts_atomic_t *var);
-ERTS_GLB_INLINE long erts_atomic_inctest(erts_atomic_t *incp);
-ERTS_GLB_INLINE long erts_atomic_dectest(erts_atomic_t *decp);
+ERTS_GLB_INLINE void erts_atomic_init(erts_atomic_t *var, erts_aint_t i);
+ERTS_GLB_INLINE void erts_atomic_set(erts_atomic_t *var, erts_aint_t i);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_read(erts_atomic_t *var);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_inctest(erts_atomic_t *incp);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_dectest(erts_atomic_t *decp);
ERTS_GLB_INLINE void erts_atomic_inc(erts_atomic_t *incp);
ERTS_GLB_INLINE void erts_atomic_dec(erts_atomic_t *decp);
-ERTS_GLB_INLINE long erts_atomic_addtest(erts_atomic_t *addp,
- long i);
-ERTS_GLB_INLINE void erts_atomic_add(erts_atomic_t *addp, long i);
-ERTS_GLB_INLINE long erts_atomic_xchg(erts_atomic_t *xchgp,
- long new);
-ERTS_GLB_INLINE long erts_atomic_cmpxchg(erts_atomic_t *xchgp,
- long new,
- long expected);
-ERTS_GLB_INLINE long erts_atomic_bor(erts_atomic_t *var, long mask);
-ERTS_GLB_INLINE long erts_atomic_band(erts_atomic_t *var, long mask);
-ERTS_GLB_INLINE long erts_atomic_read_acqb(erts_atomic_t *var);
-ERTS_GLB_INLINE void erts_atomic_set_relb(erts_atomic_t *var, long i);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_addtest(erts_atomic_t *addp,
+ erts_aint_t i);
+ERTS_GLB_INLINE void erts_atomic_add(erts_atomic_t *addp, erts_aint_t i);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_xchg(erts_atomic_t *xchgp,
+ erts_aint_t new);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_cmpxchg(erts_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t expected);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_bor(erts_atomic_t *var,
+ erts_aint_t mask);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_band(erts_atomic_t *var,
+ erts_aint_t mask);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_read_acqb(erts_atomic_t *var);
+ERTS_GLB_INLINE void erts_atomic_set_relb(erts_atomic_t *var, erts_aint_t i);
ERTS_GLB_INLINE void erts_atomic_dec_relb(erts_atomic_t *decp);
-ERTS_GLB_INLINE long erts_atomic_dectest_relb(erts_atomic_t *decp);
-ERTS_GLB_INLINE long erts_atomic_cmpxchg_acqb(erts_atomic_t *xchgp,
- long new,
- long exp);
-ERTS_GLB_INLINE long erts_atomic_cmpxchg_relb(erts_atomic_t *xchgp,
- long new,
- long exp);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_dectest_relb(erts_atomic_t *decp);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_cmpxchg_acqb(erts_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t exp);
+ERTS_GLB_INLINE erts_aint_t erts_atomic_cmpxchg_relb(erts_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t exp);
+ERTS_GLB_INLINE void erts_atomic32_init(erts_atomic32_t *var, erts_aint32_t i);
+ERTS_GLB_INLINE void erts_atomic32_set(erts_atomic32_t *var, erts_aint32_t i);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_read(erts_atomic32_t *var);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_inctest(erts_atomic32_t *incp);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_dectest(erts_atomic32_t *decp);
+ERTS_GLB_INLINE void erts_atomic32_inc(erts_atomic32_t *incp);
+ERTS_GLB_INLINE void erts_atomic32_dec(erts_atomic32_t *decp);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_addtest(erts_atomic32_t *addp,
+ erts_aint32_t i);
+ERTS_GLB_INLINE void erts_atomic32_add(erts_atomic32_t *addp, erts_aint32_t i);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_xchg(erts_atomic32_t *xchgp,
+ erts_aint32_t new);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_cmpxchg(erts_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t expected);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_bor(erts_atomic32_t *var,
+ erts_aint32_t mask);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_band(erts_atomic32_t *var,
+ erts_aint32_t mask);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_read_acqb(erts_atomic32_t *var);
+ERTS_GLB_INLINE void erts_atomic32_set_relb(erts_atomic32_t *var,
+ erts_aint32_t i);
+ERTS_GLB_INLINE void erts_atomic32_dec_relb(erts_atomic32_t *decp);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_dectest_relb(erts_atomic32_t *decp);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_cmpxchg_acqb(erts_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t exp);
+ERTS_GLB_INLINE erts_aint32_t erts_atomic32_cmpxchg_relb(erts_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t exp);
ERTS_GLB_INLINE void erts_spinlock_init_x_opt(erts_spinlock_t *lock,
char *name,
Eterm extra,
@@ -295,7 +340,6 @@ ERTS_GLB_INLINE void erts_write_lock(erts_rwlock_t *lock);
ERTS_GLB_INLINE void erts_write_unlock(erts_rwlock_t *lock);
ERTS_GLB_INLINE int erts_lc_rwlock_is_rlocked(erts_rwlock_t *lock);
ERTS_GLB_INLINE int erts_lc_rwlock_is_rwlocked(erts_rwlock_t *lock);
-ERTS_GLB_INLINE void erts_thr_time_now(erts_thr_timeval_t *time);
ERTS_GLB_INLINE void erts_tsd_key_create(erts_tsd_key_t *keyp);
ERTS_GLB_INLINE void erts_tsd_key_delete(erts_tsd_key_t key);
ERTS_GLB_INLINE void erts_tsd_set(erts_tsd_key_t key, void *value);
@@ -520,8 +564,16 @@ erts_mtx_destroy(erts_mtx_t *mtx)
erts_lcnt_destroy_lock(&mtx->lcnt);
#endif
res = ethr_mutex_destroy(&mtx->mtx);
- if (res)
+ if (res != 0) {
+#ifdef ERTS_THR_HAVE_BUSY_DESTROY_BUG
+ if (res == EBUSY) {
+ char *warn = "Ignoring busy mutex destroy. "
+ "Most likely a bug in pthread implementation.";
+ erts_send_warning_to_logger_str_nogl(warn);
+ }
+#endif
erts_thr_fatal_error(res, "destroy mutex");
+ }
#endif
}
@@ -616,8 +668,16 @@ erts_cnd_destroy(erts_cnd_t *cnd)
{
#ifdef USE_THREADS
int res = ethr_cond_destroy(cnd);
- if (res)
+ if (res != 0) {
+#ifdef ERTS_THR_HAVE_BUSY_DESTROY_BUG
+ if (res == EBUSY) {
+ char *warn = "Ignoring busy cond destroy. "
+ "Most likely a bug in pthread implementation.";
+ erts_send_warning_to_logger_str_nogl(warn);
+ }
+#endif
erts_thr_fatal_error(res, "destroy condition variable");
+ }
#endif
}
@@ -743,8 +803,16 @@ erts_rwmtx_destroy(erts_rwmtx_t *rwmtx)
erts_lcnt_destroy_lock(&rwmtx->lcnt);
#endif
res = ethr_rwmutex_destroy(&rwmtx->rwmtx);
- if (res != 0)
+ if (res != 0) {
+#ifdef ERTS_THR_HAVE_BUSY_DESTROY_BUG
+ if (res == EBUSY) {
+ char *warn = "Ignoring busy rwmutex destroy. "
+ "Most likely a bug in pthread implementation.";
+ erts_send_warning_to_logger_str_nogl(warn);
+ }
+#endif
erts_thr_fatal_error(res, "destroy rwmutex");
+ }
#endif
}
@@ -928,7 +996,7 @@ erts_lc_rwmtx_is_rwlocked(erts_rwmtx_t *mtx)
}
ERTS_GLB_INLINE void
-erts_atomic_init(erts_atomic_t *var, long i)
+erts_atomic_init(erts_atomic_t *var, erts_aint_t i)
{
#ifdef USE_THREADS
ethr_atomic_init(var, i);
@@ -938,7 +1006,7 @@ erts_atomic_init(erts_atomic_t *var, long i)
}
ERTS_GLB_INLINE void
-erts_atomic_set(erts_atomic_t *var, long i)
+erts_atomic_set(erts_atomic_t *var, erts_aint_t i)
{
#ifdef USE_THREADS
ethr_atomic_set(var, i);
@@ -947,7 +1015,7 @@ erts_atomic_set(erts_atomic_t *var, long i)
#endif
}
-ERTS_GLB_INLINE long
+ERTS_GLB_INLINE erts_aint_t
erts_atomic_read(erts_atomic_t *var)
{
#ifdef USE_THREADS
@@ -957,7 +1025,7 @@ erts_atomic_read(erts_atomic_t *var)
#endif
}
-ERTS_GLB_INLINE long
+ERTS_GLB_INLINE erts_aint_t
erts_atomic_inctest(erts_atomic_t *incp)
{
#ifdef USE_THREADS
@@ -967,7 +1035,7 @@ erts_atomic_inctest(erts_atomic_t *incp)
#endif
}
-ERTS_GLB_INLINE long
+ERTS_GLB_INLINE erts_aint_t
erts_atomic_dectest(erts_atomic_t *decp)
{
#ifdef USE_THREADS
@@ -997,8 +1065,8 @@ erts_atomic_dec(erts_atomic_t *decp)
#endif
}
-ERTS_GLB_INLINE long
-erts_atomic_addtest(erts_atomic_t *addp, long i)
+ERTS_GLB_INLINE erts_aint_t
+erts_atomic_addtest(erts_atomic_t *addp, erts_aint_t i)
{
#ifdef USE_THREADS
return ethr_atomic_add_read(addp, i);
@@ -1008,7 +1076,7 @@ erts_atomic_addtest(erts_atomic_t *addp, long i)
}
ERTS_GLB_INLINE void
-erts_atomic_add(erts_atomic_t *addp, long i)
+erts_atomic_add(erts_atomic_t *addp, erts_aint_t i)
{
#ifdef USE_THREADS
ethr_atomic_add(addp, i);
@@ -1017,59 +1085,58 @@ erts_atomic_add(erts_atomic_t *addp, long i)
#endif
}
-ERTS_GLB_INLINE long
-erts_atomic_xchg(erts_atomic_t *xchgp, long new)
+ERTS_GLB_INLINE erts_aint_t
+erts_atomic_xchg(erts_atomic_t *xchgp, erts_aint_t new)
{
- long old;
#ifdef USE_THREADS
return ethr_atomic_xchg(xchgp, new);
#else
- old = *xchgp;
+ erts_aint_t old = *xchgp;
*xchgp = new;
-#endif
return old;
+#endif
}
-ERTS_GLB_INLINE long
-erts_atomic_cmpxchg(erts_atomic_t *xchgp, long new, long expected)
+ERTS_GLB_INLINE erts_aint_t
+erts_atomic_cmpxchg(erts_atomic_t *xchgp, erts_aint_t new, erts_aint_t expected)
{
#ifdef USE_THREADS
return ethr_atomic_cmpxchg(xchgp, new, expected);
#else
- long old = *xchgp;
+ erts_aint_t old = *xchgp;
if (old == expected)
*xchgp = new;
return old;
#endif
}
-ERTS_GLB_INLINE long
-erts_atomic_bor(erts_atomic_t *var, long mask)
+ERTS_GLB_INLINE erts_aint_t
+erts_atomic_bor(erts_atomic_t *var, erts_aint_t mask)
{
#ifdef USE_THREADS
return ethr_atomic_read_bor(var, mask);
#else
- long old;
+ erts_aint_t old;
old = *var;
*var |= mask;
return old;
#endif
}
-ERTS_GLB_INLINE long
-erts_atomic_band(erts_atomic_t *var, long mask)
+ERTS_GLB_INLINE erts_aint_t
+erts_atomic_band(erts_atomic_t *var, erts_aint_t mask)
{
#ifdef USE_THREADS
return ethr_atomic_read_band(var, mask);
#else
- long old;
+ erts_aint_t old;
old = *var;
*var &= mask;
return old;
#endif
}
-ERTS_GLB_INLINE long
+ERTS_GLB_INLINE erts_aint_t
erts_atomic_read_acqb(erts_atomic_t *var)
{
#ifdef USE_THREADS
@@ -1080,7 +1147,7 @@ erts_atomic_read_acqb(erts_atomic_t *var)
}
ERTS_GLB_INLINE void
-erts_atomic_set_relb(erts_atomic_t *var, long i)
+erts_atomic_set_relb(erts_atomic_t *var, erts_aint_t i)
{
#ifdef USE_THREADS
ethr_atomic_set_relb(var, i);
@@ -1099,7 +1166,7 @@ erts_atomic_dec_relb(erts_atomic_t *decp)
#endif
}
-ERTS_GLB_INLINE long
+ERTS_GLB_INLINE erts_aint_t
erts_atomic_dectest_relb(erts_atomic_t *decp)
{
#ifdef USE_THREADS
@@ -1109,28 +1176,243 @@ erts_atomic_dectest_relb(erts_atomic_t *decp)
#endif
}
-ERTS_GLB_INLINE long erts_atomic_cmpxchg_acqb(erts_atomic_t *xchgp,
- long new,
- long exp)
+ERTS_GLB_INLINE erts_aint_t erts_atomic_cmpxchg_acqb(erts_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t exp)
{
#ifdef USE_THREADS
return ethr_atomic_cmpxchg_acqb(xchgp, new, exp);
#else
- long old = *xchgp;
+ erts_aint_t old = *xchgp;
if (old == exp)
*xchgp = new;
return old;
#endif
}
-ERTS_GLB_INLINE long erts_atomic_cmpxchg_relb(erts_atomic_t *xchgp,
- long new,
- long exp)
+ERTS_GLB_INLINE erts_aint_t erts_atomic_cmpxchg_relb(erts_atomic_t *xchgp,
+ erts_aint_t new,
+ erts_aint_t exp)
{
#ifdef USE_THREADS
return ethr_atomic_cmpxchg_relb(xchgp, new, exp);
#else
- long old = *xchgp;
+ erts_aint_t old = *xchgp;
+ if (old == exp)
+ *xchgp = new;
+ return old;
+#endif
+}
+
+/* atomic32 */
+
+ERTS_GLB_INLINE void
+erts_atomic32_init(erts_atomic32_t *var, erts_aint32_t i)
+{
+#ifdef USE_THREADS
+ ethr_atomic32_init(var, i);
+#else
+ *var = i;
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_atomic32_set(erts_atomic32_t *var, erts_aint32_t i)
+{
+#ifdef USE_THREADS
+ ethr_atomic32_set(var, i);
+#else
+ *var = i;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_read(erts_atomic32_t *var)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_read(var);
+#else
+ return *var;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_inctest(erts_atomic32_t *incp)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_inc_read(incp);
+#else
+ return ++(*incp);
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_dectest(erts_atomic32_t *decp)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_dec_read(decp);
+#else
+ return --(*decp);
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_atomic32_inc(erts_atomic32_t *incp)
+{
+#ifdef USE_THREADS
+ ethr_atomic32_inc(incp);
+#else
+ ++(*incp);
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_atomic32_dec(erts_atomic32_t *decp)
+{
+#ifdef USE_THREADS
+ ethr_atomic32_dec(decp);
+#else
+ --(*decp);
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_addtest(erts_atomic32_t *addp, erts_aint32_t i)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_add_read(addp, i);
+#else
+ return *addp += i;
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_atomic32_add(erts_atomic32_t *addp, erts_aint32_t i)
+{
+#ifdef USE_THREADS
+ ethr_atomic32_add(addp, i);
+#else
+ *addp += i;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_xchg(erts_atomic32_t *xchgp, erts_aint32_t new)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_xchg(xchgp, new);
+#else
+ erts_aint32_t old = *xchgp;
+ *xchgp = new;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_cmpxchg(erts_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t expected)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_cmpxchg(xchgp, new, expected);
+#else
+ erts_aint32_t old = *xchgp;
+ if (old == expected)
+ *xchgp = new;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_bor(erts_atomic32_t *var, erts_aint32_t mask)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_read_bor(var, mask);
+#else
+ erts_aint32_t old;
+ old = *var;
+ *var |= mask;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_band(erts_atomic32_t *var, erts_aint32_t mask)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_read_band(var, mask);
+#else
+ erts_aint32_t old;
+ old = *var;
+ *var &= mask;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_read_acqb(erts_atomic32_t *var)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_read_acqb(var);
+#else
+ return *var;
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_atomic32_set_relb(erts_atomic32_t *var, erts_aint32_t i)
+{
+#ifdef USE_THREADS
+ ethr_atomic32_set_relb(var, i);
+#else
+ *var = i;
+#endif
+}
+
+ERTS_GLB_INLINE void
+erts_atomic32_dec_relb(erts_atomic32_t *decp)
+{
+#ifdef USE_THREADS
+ ethr_atomic32_dec_relb(decp);
+#else
+ --(*decp);
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_dectest_relb(erts_atomic32_t *decp)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_dec_read_relb(decp);
+#else
+ return --(*decp);
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_cmpxchg_acqb(erts_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t exp)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_cmpxchg_acqb(xchgp, new, exp);
+#else
+ erts_aint32_t old = *xchgp;
+ if (old == exp)
+ *xchgp = new;
+ return old;
+#endif
+}
+
+ERTS_GLB_INLINE erts_aint32_t
+erts_atomic32_cmpxchg_relb(erts_atomic32_t *xchgp,
+ erts_aint32_t new,
+ erts_aint32_t exp)
+{
+#ifdef USE_THREADS
+ return ethr_atomic32_cmpxchg_relb(xchgp, new, exp);
+#else
+ erts_aint32_t old = *xchgp;
if (old == exp)
*xchgp = new;
return old;
@@ -1207,8 +1489,16 @@ erts_spinlock_destroy(erts_spinlock_t *lock)
erts_lcnt_destroy_lock(&lock->lcnt);
#endif
res = ethr_spinlock_destroy(&lock->slck);
- if (res)
- erts_thr_fatal_error(res, "destroy spinlock");
+ if (res != 0) {
+#ifdef ERTS_THR_HAVE_BUSY_DESTROY_BUG
+ if (res == EBUSY) {
+ char *warn = "Ignoring busy spinlock destroy. "
+ "Most likely a bug in pthread implementation.";
+ erts_send_warning_to_logger_str_nogl(warn);
+ }
+#endif
+ erts_thr_fatal_error(res, "destroy rwlock");
+ }
#else
(void)lock;
#endif
@@ -1317,8 +1607,16 @@ erts_rwlock_destroy(erts_rwlock_t *lock)
erts_lcnt_destroy_lock(&lock->lcnt);
#endif
res = ethr_rwlock_destroy(&lock->rwlck);
- if (res)
+ if (res != 0) {
+#ifdef ERTS_THR_HAVE_BUSY_DESTROY_BUG
+ if (res == EBUSY) {
+ char *warn = "Ignoring busy rwlock destroy. "
+ "Most likely a bug in pthread implementation.";
+ erts_send_warning_to_logger_str_nogl(warn);
+ }
+#endif
erts_thr_fatal_error(res, "destroy rwlock");
+ }
#else
(void)lock;
#endif
@@ -1431,16 +1729,6 @@ erts_lc_rwlock_is_rwlocked(erts_rwlock_t *lock)
}
ERTS_GLB_INLINE void
-erts_thr_time_now(erts_thr_timeval_t *time)
-{
-#ifdef USE_THREADS
- int res = ethr_time_now(time);
- if (res)
- erts_thr_fatal_error(res, "get current time");
-#endif
-}
-
-ERTS_GLB_INLINE void
erts_tsd_key_create(erts_tsd_key_t *keyp)
{
#ifdef USE_THREADS
diff --git a/erts/emulator/beam/erl_time.h b/erts/emulator/beam/erl_time.h
index 6f6b971d34..93d8ea4cb4 100644
--- a/erts/emulator/beam/erl_time.h
+++ b/erts/emulator/beam/erl_time.h
@@ -20,11 +20,15 @@
#ifndef ERL_TIME_H__
#define ERL_TIME_H__
+extern erts_smp_atomic_t do_time; /* set at clock interrupt */
+extern SysTimeval erts_first_emu_time;
+
/*
** Timer entry:
*/
typedef struct erl_timer {
struct erl_timer* next; /* next entry tiw slot or chain */
+ struct erl_timer* prev; /* prev entry tiw slot or chain */
Uint slot; /* slot in timer wheel */
Uint count; /* number of loops remaining */
int active; /* 1=activated, 0=deactivated */
@@ -39,7 +43,6 @@ typedef void (*ErlTimeoutProc)(void*);
typedef void (*ErlCancelProc)(void*);
#ifdef ERTS_SMP
-
/*
* Process and port timer
*/
@@ -61,7 +64,66 @@ void erts_create_smp_ptimer(ErtsSmpPTimer **timer_ref,
ErlTimeoutProc timeout_func,
Uint timeout);
void erts_cancel_smp_ptimer(ErtsSmpPTimer *ptimer);
+#endif
+
+/* timer-wheel api */
+void erts_init_time(void);
+void erts_set_timer(ErlTimer*, ErlTimeoutProc, ErlCancelProc, void*, Uint);
+void erts_cancel_timer(ErlTimer*);
+void erts_bump_timer(erts_aint_t);
+Uint erts_timer_wheel_memory_size(void);
+Uint erts_time_left(ErlTimer *);
+erts_aint_t erts_next_time(void);
+
+#ifdef DEBUG
+void erts_p_slpq(void);
#endif
+ERTS_GLB_INLINE erts_aint_t erts_do_time_read_and_reset(void);
+ERTS_GLB_INLINE void erts_do_time_add(long);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+
+ERTS_GLB_INLINE erts_aint_t erts_do_time_read_and_reset(void) { return erts_smp_atomic_xchg(&do_time, 0L); }
+ERTS_GLB_INLINE void erts_do_time_add(long elapsed) { erts_smp_atomic_add(&do_time, elapsed); }
+
+#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
+
+
+/* time_sup */
+
+#if (defined(HAVE_GETHRVTIME) || defined(HAVE_CLOCK_GETTIME))
+# ifndef HAVE_ERTS_NOW_CPU
+# define HAVE_ERTS_NOW_CPU
+# ifdef HAVE_GETHRVTIME
+# define erts_start_now_cpu() sys_start_hrvtime()
+# define erts_stop_now_cpu() sys_stop_hrvtime()
+# endif
+# endif
+void erts_get_now_cpu(Uint* megasec, Uint* sec, Uint* microsec);
#endif
+
+void erts_get_timeval(SysTimeval *tv);
+long erts_get_time(void);
+void erts_get_emu_time(SysTimeval *);
+
+ERTS_GLB_INLINE int erts_cmp_timeval(SysTimeval *t1p, SysTimeval *t2p);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+
+ERTS_GLB_INLINE int
+erts_cmp_timeval(SysTimeval *t1p, SysTimeval *t2p)
+{
+ if (t1p->tv_sec == t2p->tv_sec) {
+ if (t1p->tv_usec < t2p->tv_usec)
+ return -1;
+ else if (t1p->tv_usec > t2p->tv_usec)
+ return 1;
+ return 0;
+ }
+ return t1p->tv_sec < t2p->tv_sec ? -1 : 1;
+}
+
+#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
+#endif /* ERL_TIME_H__ */
diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c
index 7b8706ea13..ca4b54188e 100644
--- a/erts/emulator/beam/erl_time_sup.c
+++ b/erts/emulator/beam/erl_time_sup.c
@@ -358,10 +358,6 @@ static int clock_resolution;
** instead of something like select.
*/
-#if defined(ERTS_TIMER_THREAD)
-static ERTS_INLINE void init_erts_deliver_time(const SysTimeval *inittv) { }
-static ERTS_INLINE void do_erts_deliver_time(const SysTimeval *current) { }
-#else
static SysTimeval last_delivered;
static void init_erts_deliver_time(const SysTimeval *inittv)
@@ -389,11 +385,10 @@ static void do_erts_deliver_time(const SysTimeval *current)
this by simply pretend as if the time stood still. :) */
if (elapsed > 0) {
- do_time_add(elapsed);
+ erts_do_time_add(elapsed);
last_delivered = cur_time;
}
}
-#endif
int
erts_init_time_sup(void)
@@ -786,7 +781,6 @@ get_sys_now(Uint* megasec, Uint* sec, Uint* microsec)
to a struct timeval representing current time (to save
a gettimeofday() where possible) or NULL */
-#if !defined(ERTS_TIMER_THREAD)
void erts_deliver_time(void) {
SysTimeval now;
@@ -797,7 +791,6 @@ void erts_deliver_time(void) {
erts_smp_mtx_unlock(&erts_timeofday_mtx);
}
-#endif
/* get *real* time (not ticks) remaining until next timeout - if there
isn't one, give a "long" time, that is guaranteed
@@ -806,14 +799,12 @@ void erts_deliver_time(void) {
void erts_time_remaining(SysTimeval *rem_time)
{
int ticks;
-#if !defined(ERTS_TIMER_THREAD)
SysTimeval cur_time;
-#endif
long elapsed;
- /* next_time() returns no of ticks to next timeout or -1 if none */
+ /* erts_next_time() returns no of ticks to next timeout or -1 if none */
- if ((ticks = next_time()) == -1) {
+ if ((ticks = erts_next_time()) == -1) {
/* timer queue empty */
/* this will cause at most 100000000 ticks */
rem_time->tv_sec = 100000;
@@ -822,9 +813,6 @@ void erts_time_remaining(SysTimeval *rem_time)
/* next timeout after ticks ticks */
ticks *= CLOCK_RESOLUTION;
-#if defined(ERTS_TIMER_THREAD)
- elapsed = 0;
-#else
erts_smp_mtx_lock(&erts_timeofday_mtx);
get_tolerant_timeofday(&cur_time);
@@ -839,7 +827,6 @@ void erts_time_remaining(SysTimeval *rem_time)
rem_time->tv_sec = rem_time->tv_usec = 0;
return;
}
-#endif
rem_time->tv_sec = (ticks - elapsed) / 1000;
rem_time->tv_usec = 1000 * ((ticks - elapsed) % 1000);
}
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 3043bb1e8c..c0397ca6c3 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1999-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -1668,7 +1668,7 @@ erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
return_flags = 0;
if (match_spec) {
pam_result = erts_match_set_run(p, match_spec, args, arity,
- &return_flags);
+ ERTS_PAM_TMP_RESULT, &return_flags);
if (is_non_value(pam_result)) {
erts_match_set_release_result(p);
#if !HEAP_ON_C_STACK
@@ -1815,7 +1815,7 @@ erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
return_flags = 0;
if (match_spec) {
pam_result = erts_match_set_run(p, match_spec, args, arity,
- &return_flags);
+ ERTS_PAM_TMP_RESULT, &return_flags);
if (is_non_value(pam_result)) {
erts_match_set_release_result(p);
UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index d01a3661f9..545b345a71 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -30,6 +30,8 @@
#include "big.h"
#include "erl_unicode.h"
+#include "erl_unicode_normalize.h"
+
typedef struct _restart_context {
byte *bytes;
@@ -54,13 +56,6 @@ static BIF_RETTYPE finalize_list_to_list(Process *p,
Uint num_resulting_chars,
int state, int left,
Eterm tail);
-static int analyze_utf8(byte *source, Uint size,
- byte **err_pos, Uint *num_chars, int *left);
-#define UTF8_OK 0
-#define UTF8_INCOMPLETE 1
-#define UTF8_ERROR 2
-#define UTF8_ANALYZE_MORE 3
-
static BIF_RETTYPE characters_to_utf8_trap(BIF_ALIST_3);
static BIF_RETTYPE characters_to_list_trap_1(BIF_ALIST_3);
static BIF_RETTYPE characters_to_list_trap_2(BIF_ALIST_3);
@@ -463,7 +458,7 @@ L_Again: /* Restart with sublist, old listend was pushed on stack */
}
objp = list_val(ioterm);
obj = CAR(objp);
- if (!is_byte(obj))
+ if (!is_small(obj))
break;
}
} else if (is_nil(obj)) {
@@ -970,11 +965,11 @@ static int is_valid_utf8(Eterm orig_bin)
bytes = erts_get_aligned_binary_bytes(orig_bin, &temp_alloc);
}
size = binary_size(orig_bin);
- ret = analyze_utf8(bytes,
+ ret = erts_analyze_utf8(bytes,
size,
&endpos,&numchar,NULL);
erts_free_aligned_binary_bytes(temp_alloc);
- return (ret == UTF8_OK);
+ return (ret == ERTS_UTF8_OK);
}
BIF_RETTYPE unicode_characters_to_binary_2(BIF_ALIST_2)
@@ -1084,14 +1079,14 @@ static BIF_RETTYPE build_list_return(Process *p, byte *bytes, int pos, Uint char
hp += 2;
rest_term = CONS(hp,leftover_bin,rest_term);
}
- BIF_RET(finalize_list_to_list(p, bytes, rest_term, 0U, pos, characters, UTF8_ERROR, left, NIL));
+ BIF_RET(finalize_list_to_list(p, bytes, rest_term, 0U, pos, characters, ERTS_UTF8_ERROR, left, NIL));
} else if (rest_term == NIL && num_leftovers != 0) {
Eterm leftover_bin = new_binary(p, leftover, num_leftovers);
if (check_leftovers(leftover,num_leftovers) != 0) {
- BIF_RET(finalize_list_to_list(p, bytes, leftover_bin, 0U, pos, characters, UTF8_ERROR,
+ BIF_RET(finalize_list_to_list(p, bytes, leftover_bin, 0U, pos, characters, ERTS_UTF8_ERROR,
left, NIL));
} else {
- BIF_RET(finalize_list_to_list(p, bytes, leftover_bin, 0U, pos, characters, UTF8_INCOMPLETE,
+ BIF_RET(finalize_list_to_list(p, bytes, leftover_bin, 0U, pos, characters, ERTS_UTF8_INCOMPLETE,
left, NIL));
}
} else { /* All OK */
@@ -1107,11 +1102,11 @@ static BIF_RETTYPE build_list_return(Process *p, byte *bytes, int pos, Uint char
rc.num_processed_bytes = 0; /* not used */
rc.num_bytes_to_process = pos;
rc.num_resulting_chars = characters;
- rc.state = UTF8_OK; /* not used */
+ rc.state = ERTS_UTF8_OK; /* not used */
BIF_TRAP3(&characters_to_list_trap_1_exp, p, make_magic_bin_for_restart(p,&rc),
rest_term, latin1);
} else { /* Success */
- BIF_RET(finalize_list_to_list(p, bytes, NIL, 0U, pos, characters, UTF8_OK, left, NIL));
+ BIF_RET(finalize_list_to_list(p, bytes, NIL, 0U, pos, characters, ERTS_UTF8_OK, left, NIL));
}
}
}
@@ -1205,7 +1200,7 @@ BIF_RETTYPE unicode_characters_to_list_2(BIF_ALIST_2)
* When input to characters_to_list is a plain binary and the format is 'unicode', we do
* a faster analyze and size count with this function.
*/
-static int analyze_utf8(byte *source, Uint size,
+int erts_analyze_utf8(byte *source, Uint size,
byte **err_pos, Uint *num_chars, int *left)
{
*err_pos = source;
@@ -1216,60 +1211,60 @@ static int analyze_utf8(byte *source, Uint size,
--size;
} else if (((*source) & ((byte) 0xE0)) == 0xC0) {
if (size < 2) {
- return UTF8_INCOMPLETE;
+ return ERTS_UTF8_INCOMPLETE;
}
if (((source[1] & ((byte) 0xC0)) != 0x80) ||
((*source) < 0xC2) /* overlong */) {
- return UTF8_ERROR;
+ return ERTS_UTF8_ERROR;
}
source += 2;
size -= 2;
} else if (((*source) & ((byte) 0xF0)) == 0xE0) {
if (size < 3) {
- return UTF8_INCOMPLETE;
+ return ERTS_UTF8_INCOMPLETE;
}
if (((source[1] & ((byte) 0xC0)) != 0x80) ||
((source[2] & ((byte) 0xC0)) != 0x80) ||
(((*source) == 0xE0) && (source[1] < 0xA0)) /* overlong */ ) {
- return UTF8_ERROR;
+ return ERTS_UTF8_ERROR;
}
if ((((*source) & ((byte) 0xF)) == 0xD) &&
((source[1] & 0x20) != 0)) {
- return UTF8_ERROR;
+ return ERTS_UTF8_ERROR;
}
if (((*source) == 0xEF) && (source[1] == 0xBF) &&
((source[2] == 0xBE) || (source[2] == 0xBF))) {
- return UTF8_ERROR;
+ return ERTS_UTF8_ERROR;
}
source += 3;
size -= 3;
} else if (((*source) & ((byte) 0xF8)) == 0xF0) {
if (size < 4) {
- return UTF8_INCOMPLETE;
+ return ERTS_UTF8_INCOMPLETE;
}
if (((source[1] & ((byte) 0xC0)) != 0x80) ||
((source[2] & ((byte) 0xC0)) != 0x80) ||
((source[3] & ((byte) 0xC0)) != 0x80) ||
(((*source) == 0xF0) && (source[1] < 0x90)) /* overlong */) {
- return UTF8_ERROR;
+ return ERTS_UTF8_ERROR;
}
if ((((*source) & ((byte)0x7)) > 0x4U) ||
((((*source) & ((byte)0x7)) == 0x4U) &&
((source[1] & ((byte)0x3F)) > 0xFU))) {
- return UTF8_ERROR;
+ return ERTS_UTF8_ERROR;
}
source += 4;
size -= 4;
} else {
- return UTF8_ERROR;
+ return ERTS_UTF8_ERROR;
}
++(*num_chars);
*err_pos = source;
if (left && --(*left) <= 0) {
- return UTF8_ANALYZE_MORE;
+ return ERTS_UTF8_ANALYZE_MORE;
}
}
- return UTF8_OK;
+ return ERTS_UTF8_OK;
}
/*
@@ -1304,7 +1299,7 @@ static Eterm do_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz,
} else if (((*source) & ((byte) 0xE0)) == 0xC0) {
unipoint =
(((Uint) ((*source) & ((byte) 0x1F))) << 6) |
- ((Uint) (source[1] & ((byte) 0x3F)));
+ ((Uint) (source[1] & ((byte) 0x3F)));
} else if (((*source) & ((byte) 0xF0)) == 0xE0) {
unipoint =
(((Uint) ((*source) & ((byte) 0xF))) << 12) |
@@ -1330,6 +1325,216 @@ static Eterm do_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz,
return ret;
}
+static int is_candidate(Uint cp)
+{
+ int index,pos;
+ if (cp < 768) return 0;
+ if (cp > 4023) {
+ if (cp == 12441 || cp == 12442) return 1;
+ return 0;
+ }
+ index = cp / 32 - COMP_CANDIDATE_MAP_OFFSET;
+ pos = cp % 32;
+ return !!(comp_candidate_map[index] & (1UL << pos));
+}
+
+static int hashsearch(int *htab, int htab_size, CompEntry *cv, Uint16 c)
+{
+ int bucket = c % htab_size;
+ while (htab[bucket] != -1 && cv[htab[bucket]].c != c)
+ bucket = (bucket + 1) % htab_size;
+ return htab[bucket];
+}
+
+#define TRANSLATE_NO 0
+#define TRANSLATE_MAYBE -1
+
+/* The s array is reversed */
+static int translate(Uint16 *s, int slen, Uint16 *res)
+{
+ /* Go backwards through buffer and match against tree */
+ int pos = 0;
+ CompEntry *cv = compose_tab;
+ int *hc = hash_compose_tab;
+ int cvs = compose_tab_size;
+ int x;
+ while (pos < slen) {
+ x = hashsearch(hc,cvs*HASH_SIZE_FACTOR,cv,s[pos]);
+ if (x < 0) {
+ return TRANSLATE_NO;
+ }
+ if (cv[x].res) {
+ *res = cv[x].res;
+ return pos;
+ }
+ cvs = cv[x].num_subs;
+ hc = cv[x].hash;
+ cv = cv[x].subs;
+ ++pos;
+ }
+ return TRANSLATE_MAYBE;
+}
+
+static void handle_first_norm(Uint16 *savepoints, int *numpointsp, Uint unipoint)
+{
+ /*erts_fprintf(stderr,"CP = %d, numpoints = %d\n",(int) unipoint,(int) *numpointsp);*/
+ *numpointsp = 1;
+ savepoints[0] = (Uint16) unipoint;
+}
+
+static void cleanup_norm(Eterm **hpp, Uint16 *savepoints, int numpoints, Eterm *retp)
+{
+ Eterm *hp = *hpp;
+ int res,i;
+ Uint16 newpoint;
+ Eterm ret = *retp;
+
+ ret = CONS(hp,make_small((Uint) savepoints[0]),ret);
+ hp += 2;
+
+ for (i = 1;i < numpoints;) {
+ if(!is_candidate(savepoints[i]) ||
+ ((res = translate(savepoints+i,numpoints - i, &newpoint)) <= 0)) {
+ ret = CONS(hp,make_small((Uint) savepoints[i]),ret);
+ hp += 2;
+ ++i;
+ } else {
+ ret = CONS(hp,make_small((Uint) newpoint),ret);
+ hp += 2;
+ i += res;
+ }
+ }
+ *retp = ret;
+}
+
+static void handle_potential_norm(Eterm **hpp, Uint16 *savepoints, int *numpointsp, Uint unipoint, Eterm *retp)
+{
+ Eterm *hp = *hpp;
+ int numpoints = *numpointsp;
+ int res,i;
+ Uint16 newpoint;
+ Eterm ret = *retp;
+
+ /* erts_fprintf(stderr,"CP = %d, numpoints = %d\n",(int) unipoint,(int) numpoints);*/
+ if ((unipoint >> 16) == 0) { /* otherwise we're done here */
+ savepoints[numpoints++] = (Uint16) unipoint;
+ res = translate(savepoints,numpoints,&newpoint);
+ if (res == TRANSLATE_NO) {
+ ret = CONS(hp,make_small((Uint) savepoints[0]),ret);
+ hp += 2;
+ for (i = 1;i < numpoints;) {
+ if(!is_candidate(savepoints[i]) ||
+ ((res = translate(savepoints+i,numpoints - i, &newpoint)) == 0)) {
+ ret = CONS(hp,make_small((Uint) savepoints[i]),ret);
+ hp += 2;
+ ++i;
+ } else if (res > 0) {
+ ret = CONS(hp,make_small((Uint) newpoint),ret);
+ hp += 2;
+ i += res;
+ } else { /* res < 0 */
+ /* A "maybe", means we are not done yet */
+ int j = 0;
+ while (i < numpoints) {
+ savepoints[j++] = savepoints[i++];
+ }
+ numpoints = j;
+ goto breakaway;
+ }
+ }
+ numpoints = 0;
+ breakaway:
+ ;
+ } else if (res > 0) {
+ numpoints = 0;
+ ret = CONS(hp,make_small((Uint) newpoint),ret);
+ hp += 2;
+ } /* < 0 means go on */
+ } else {
+ /* Unconditional rollup, this character is larger than 16 bit */
+ ret = CONS(hp,make_small((Uint) savepoints[0]),ret);
+ hp += 2;
+
+ for (i = 1;i < numpoints;) {
+ if(!is_candidate(savepoints[i]) ||
+ ((res = translate(savepoints+i,numpoints - i, &newpoint)) <= 0)) {
+ ret = CONS(hp,make_small((Uint) savepoints[i]),ret);
+ hp += 2;
+ ++i;
+ } else {
+ ret = CONS(hp,make_small((Uint) newpoint),ret);
+ hp += 2;
+ i += res;
+ }
+ }
+ ret = CONS(hp,make_small(unipoint),ret);
+ hp += 2;
+ numpoints = 0;
+ }
+ *hpp = hp;
+ *numpointsp = numpoints;
+ *retp = ret;
+}
+
+static Eterm do_utf8_to_list_normalize(Process *p, Uint num, byte *bytes, Uint sz)
+{
+ Eterm *hp,*hp_end;
+ Eterm ret;
+ byte *source;
+ Uint unipoint;
+ Uint16 savepoints[4];
+ int numpoints = 0;
+
+ ASSERT(num > 0);
+
+ hp = HAlloc(p,num * 2); /* May be to much */
+ hp_end = hp + num * 2;
+ ret = NIL;
+ source = bytes + sz;
+ while(--source >= bytes) {
+ if (((*source) & ((byte) 0x80)) == 0) {
+ unipoint = (Uint) *source;
+ } else if (((*source) & ((byte) 0xE0)) == 0xC0) {
+ unipoint =
+ (((Uint) ((*source) & ((byte) 0x1F))) << 6) |
+ ((Uint) (source[1] & ((byte) 0x3F)));
+ } else if (((*source) & ((byte) 0xF0)) == 0xE0) {
+ unipoint =
+ (((Uint) ((*source) & ((byte) 0xF))) << 12) |
+ (((Uint) (source[1] & ((byte) 0x3F))) << 6) |
+ ((Uint) (source[2] & ((byte) 0x3F)));
+ } else if (((*source) & ((byte) 0xF8)) == 0xF0) {
+ unipoint =
+ (((Uint) ((*source) & ((byte) 0x7))) << 18) |
+ (((Uint) (source[1] & ((byte) 0x3F))) << 12) |
+ (((Uint) (source[2] & ((byte) 0x3F))) << 6) |
+ ((Uint) (source[3] & ((byte) 0x3F)));
+ } else {
+ /* ignore 2#10XXXXXX */
+ continue;
+ }
+ if (numpoints) {
+ handle_potential_norm(&hp,savepoints,&numpoints,unipoint,&ret);
+ continue;
+ }
+ /* We are not building up any normalizations yet, look that we shouldn't start... */
+ if (is_candidate(unipoint)) {
+ handle_first_norm(savepoints,&numpoints,unipoint);
+ continue;
+ }
+ ret = CONS(hp,make_small(unipoint),ret);
+ hp += 2;
+ }
+ /* so, we'we looped to the beginning, do we have anything saved? */
+ if (numpoints) {
+ cleanup_norm(&hp,savepoints,numpoints,&ret);
+ }
+ if (hp_end != hp) {
+ HRelease(p,hp_end,hp);
+ }
+ return ret;
+}
+
/*
* The last step of characters_to_list, build a list from the buffer 'bytes' (created in the same way
* as for characters_to_utf8). All sizes are known in advance and most data will be held in a
@@ -1378,10 +1583,10 @@ static BIF_RETTYPE finalize_list_to_list(Process *p,
*/
free_restart(bytes);
- if (state == UTF8_INCOMPLETE) {
+ if (state == ERTS_UTF8_INCOMPLETE) {
hp = HAlloc(p,4);
ret = TUPLE3(hp,am_incomplete,converted,rest);
- } else if (state == UTF8_ERROR) {
+ } else if (state == ERTS_UTF8_ERROR) {
hp = HAlloc(p,4);
ret = TUPLE3(hp,am_error,converted,rest);
} else {
@@ -1408,7 +1613,7 @@ static BIF_RETTYPE characters_to_list_trap_2(BIF_ALIST_3)
/*
* Hooks into the process of decoding a binary depending on state.
- * If last_state is UTF8_ANALYZE_MORE, num_bytes_to_process
+ * If last_state is ERTS_UTF8_ANALYZE_MORE, num_bytes_to_process
* and num_resulting_chars will grow
* until we're done analyzing the binary. Then we'll eat
* the bytes to process, lowering num_bytes_to_process and num_resulting_chars,
@@ -1465,14 +1670,14 @@ static BIF_RETTYPE do_bif_utf8_to_list(Process *p,
left = allowed_iterations(p);
- if (state == UTF8_ANALYZE_MORE) {
- state = analyze_utf8(bytes + num_bytes_to_process,
+ if (state == ERTS_UTF8_ANALYZE_MORE) {
+ state = erts_analyze_utf8(bytes + num_bytes_to_process,
size - num_bytes_to_process,
&endpos,&numchar,&left);
cost_to_proc(p,numchar);
num_resulting_chars += numchar;
num_bytes_to_process = endpos - bytes;
- if (state == UTF8_ANALYZE_MORE) {
+ if (state == ERTS_UTF8_ANALYZE_MORE) {
Eterm epos = erts_make_integer(num_bytes_to_process,p);
Eterm enumchar = erts_make_integer(num_resulting_chars,p);
erts_free_aligned_binary_bytes(temp_alloc);
@@ -1528,7 +1733,7 @@ static BIF_RETTYPE do_bif_utf8_to_list(Process *p,
ErlSubBin *sb;
Eterm orig;
Uint offset;
- ASSERT(state != UTF8_OK);
+ ASSERT(state != ERTS_UTF8_OK);
hp = HAlloc(p, ERL_SUB_BIN_SIZE);
sb = (ErlSubBin *) hp;
ERTS_GET_REAL_BIN(orig_bin, orig, offset, bitoffs, bitsize);
@@ -1544,14 +1749,14 @@ static BIF_RETTYPE do_bif_utf8_to_list(Process *p,
/* Done */
- if (state == UTF8_INCOMPLETE) {
+ if (state == ERTS_UTF8_INCOMPLETE) {
if (check_leftovers(bytes + num_bytes_to_process + num_processed_bytes,
b_sz) != 0) {
goto error_return;
}
hp = HAlloc(p,4);
ret = TUPLE3(hp,am_incomplete,converted,rest);
- } else if (state == UTF8_ERROR) {
+ } else if (state == ERTS_UTF8_ERROR) {
error_return:
hp = HAlloc(p,4);
ret = TUPLE3(hp,am_error,converted,rest);
@@ -1589,7 +1794,7 @@ static BIF_RETTYPE characters_to_list_trap_3(BIF_ALIST_3)
0U, /* nothing processed yet */
num_bytes_to_process,
num_resulting_chars,
- UTF8_ANALYZE_MORE, /* always this state here */
+ ERTS_UTF8_ANALYZE_MORE, /* always this state here */
NIL); /* Nothing built -> no tail yet */
}
@@ -1642,7 +1847,7 @@ static BIF_RETTYPE utf8_to_list(BIF_ALIST_1)
BIF_ERROR(BIF_P,BADARG);
}
return do_bif_utf8_to_list(BIF_P, BIF_ARG_1, 0U, 0U, 0U,
- UTF8_ANALYZE_MORE,NIL);
+ ERTS_UTF8_ANALYZE_MORE,NIL);
}
@@ -1728,8 +1933,8 @@ binary_to_atom(Process* p, Eterm bin, Eterm enc, int must_exist)
Uint n;
int reds_left = bin_size+1; /* Number of reductions left. */
- if (analyze_utf8(bytes, bin_size, &err_pos,
- &n, &reds_left) == UTF8_OK) {
+ if (erts_analyze_utf8(bytes, bin_size, &err_pos,
+ &n, &reds_left) == ERTS_UTF8_OK) {
/*
* Correct UTF-8 encoding, but too many characters to
* fit in an atom.
@@ -1813,3 +2018,616 @@ BIF_RETTYPE binary_to_existing_atom_2(BIF_ALIST_2)
{
return binary_to_atom(BIF_P, BIF_ARG_1, BIF_ARG_2, 1);
}
+
+/**********************************************************
+ * Simpler non-interruptable routines for UTF-8 and
+ * Windowish UTF-16 (restricted)
+ **********************************************************/
+/*
+ * This function is the heart of the Unicode support for
+ * open_port - spawn_executable. It converts both the name
+ * of the executable and the arguments according to the same rules
+ * as for filename conversion. That means as if your arguments are
+ * to be raw, you supply binaries, else unicode characters are allowed up to
+ * the encoding maximum (256 of the unicode max).
+ * Depending on the filename encoding standard, the vector is then
+ * converted to whatever is used, which might mean win_utf16 if on windows.
+ * Do not peek into the argument vector or filenam with ordinary
+ * string routines, that will certainly fail on some OS.
+ */
+
+char *erts_convert_filename_to_native(Eterm name, ErtsAlcType_t alloc_type, int allow_empty)
+{
+ int encoding = erts_get_native_filename_encoding();
+ char* name_buf = NULL;
+
+ if (is_atom(name) || is_list(name) || (allow_empty && is_nil(name))) {
+ Sint need;
+ if ((need = erts_native_filename_need(name,encoding)) < 0) {
+ return NULL;
+ }
+ if (encoding == ERL_FILENAME_WIN_WCHAR) {
+ need += 2;
+ } else {
+ ++need;
+ }
+ name_buf = (char *) erts_alloc(alloc_type, need);
+ erts_native_filename_put(name,encoding,(byte *)name_buf);
+ name_buf[need-1] = 0;
+ if (encoding == ERL_FILENAME_WIN_WCHAR) {
+ name_buf[need-2] = 0;
+ }
+ } else if (is_binary(name)) {
+ byte *temp_alloc = NULL;
+ byte *bytes;
+ byte *err_pos;
+ Uint size,num_chars;
+
+ size = binary_size(name);
+ bytes = erts_get_aligned_binary_bytes(name, &temp_alloc);
+ if (encoding != ERL_FILENAME_WIN_WCHAR) {
+ /*Add 0 termination only*/
+ name_buf = (char *) erts_alloc(alloc_type, size+1);
+ memcpy(name_buf,bytes,size);
+ name_buf[size]=0;
+ } else if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK ||
+ erts_get_user_requested_filename_encoding() == ERL_FILENAME_LATIN1) {
+ byte *p;
+ /* What to do now? Maybe latin1, so just take byte for byte instead */
+ name_buf = (char *) erts_alloc(alloc_type, (size+1)*2);
+ p = (byte *) name_buf;
+ while (size--) {
+ *p++ = *bytes++;
+ *p++ = 0;
+ }
+ *p++ = 0;
+ *p++ = 0;
+ } else { /* WIN_WCHAR and valid UTF8 */
+ name_buf = (char *) erts_alloc(alloc_type, (num_chars+1)*2);
+ erts_copy_utf8_to_utf16_little((byte *) name_buf, bytes, num_chars);
+ name_buf[num_chars*2] = 0;
+ name_buf[num_chars*2+1] = 0;
+ }
+ erts_free_aligned_binary_bytes(temp_alloc);
+ } else {
+ return NULL;
+ }
+ return name_buf;
+}
+
+
+Sint erts_native_filename_need(Eterm ioterm, int encoding)
+{
+ Eterm *objp;
+ Eterm obj;
+ DECLARE_ESTACK(stack);
+ Sint need = 0;
+
+ if (is_atom(ioterm)) {
+ Atom* ap;
+ int i;
+ ap = atom_tab(atom_val(ioterm));
+ switch (encoding) {
+ case ERL_FILENAME_LATIN1:
+ need = ap->len;
+ break;
+ case ERL_FILENAME_UTF8_MAC:
+ case ERL_FILENAME_UTF8:
+ for (i = 0; i < ap->len; i++) {
+ need += (ap->name[i] >= 0x80) ? 2 : 1;
+ }
+ break;
+ case ERL_FILENAME_WIN_WCHAR:
+ need = 2*(ap->len);
+ break;
+ default:
+ need = -1;
+ }
+ DESTROY_ESTACK(stack);
+ return need;
+ }
+
+ if (is_nil(ioterm)) {
+ DESTROY_ESTACK(stack);
+ return need;
+ }
+ if (!is_list(ioterm)) {
+ DESTROY_ESTACK(stack);
+ return (Sint) -1;
+ }
+ /* OK a list, needs to be processed in order, handling each flat list-level
+ as they occur, just like io_list_to_binary would */
+ ESTACK_PUSH(stack,ioterm);
+ while (!ESTACK_ISEMPTY(stack)) {
+ ioterm = ESTACK_POP(stack);
+ if (is_nil(ioterm)) {
+ /* ignore empty lists */
+ continue;
+ }
+ if(is_list(ioterm)) {
+L_Again: /* Restart with sublist, old listend was pushed on stack */
+ objp = list_val(ioterm);
+ obj = CAR(objp);
+ for(;;) { /* loop over one flat list of bytes and binaries
+ until sublist or list end is encountered */
+ if (is_small(obj)) { /* Always small */
+ for(;;) {
+ Uint x = unsigned_val(obj);
+ switch (encoding) {
+ case ERL_FILENAME_LATIN1:
+ if (x > 255) {
+ DESTROY_ESTACK(stack);
+ return ((Sint) -1);
+ }
+ need += 1;
+ break;
+ case ERL_FILENAME_UTF8_MAC:
+ case ERL_FILENAME_UTF8:
+ if (x < 0x80) {
+ need +=1;
+ } else if (x < 0x800) {
+ need += 2;
+ } else if (x < 0x10000) {
+ if ((x >= 0xD800 && x <= 0xDFFF) ||
+ (x == 0xFFFE) ||
+ (x == 0xFFFF)) { /* Invalid unicode range */
+ DESTROY_ESTACK(stack);
+ return ((Sint) -1);
+ }
+ need += 3;
+ } else if (x < 0x110000) {
+ need += 4;
+ } else {
+ DESTROY_ESTACK(stack);
+ return ((Sint) -1);
+ }
+ break;
+ case ERL_FILENAME_WIN_WCHAR:
+ if (x <= 0xffff) {
+ need += 2;
+ break;
+ } /* else fall throug to error */
+ default:
+ DESTROY_ESTACK(stack);
+ return ((Sint) -1);
+ }
+
+ /* everything else will give badarg later
+ in the process, so we dont check */
+ ioterm = CDR(objp);
+ if (!is_list(ioterm)) {
+ break;
+ }
+ objp = list_val(ioterm);
+ obj = CAR(objp);
+ if (!is_small(obj))
+ break;
+ }
+ } else if (is_nil(obj)) {
+ ioterm = CDR(objp);
+ if (!is_list(ioterm)) {
+ break;
+ }
+ objp = list_val(ioterm);
+ obj = CAR(objp);
+ } else if (is_list(obj)) {
+ /* push rest of list for later processing, start
+ again with sublist */
+ ESTACK_PUSH(stack,CDR(objp));
+ ioterm = obj;
+ goto L_Again;
+ } else {
+ DESTROY_ESTACK(stack);
+ return ((Sint) -1);
+ }
+ if (is_nil(ioterm) || !is_list(ioterm)) {
+ break;
+ }
+ } /* for(;;) */
+ } /* is_list(ioterm) */
+
+ if (!is_list(ioterm) && !is_nil(ioterm)) {
+ /* inproper list end */
+ DESTROY_ESTACK(stack);
+ return ((Sint) -1);
+ }
+ } /* while not estack empty */
+ DESTROY_ESTACK(stack);
+ return need;
+}
+
+void erts_native_filename_put(Eterm ioterm, int encoding, byte *p)
+{
+ Eterm *objp;
+ Eterm obj;
+ DECLARE_ESTACK(stack);
+
+ if (is_atom(ioterm)) {
+ Atom* ap;
+ int i;
+ ap = atom_tab(atom_val(ioterm));
+ switch (encoding) {
+ case ERL_FILENAME_LATIN1:
+ for (i = 0; i < ap->len; i++) {
+ *p++ = ap->name[i];
+ }
+ break;
+ case ERL_FILENAME_UTF8_MAC:
+ case ERL_FILENAME_UTF8:
+ for (i = 0; i < ap->len; i++) {
+ if(ap->name[i] < 0x80) {
+ *p++ = ap->name[i];
+ } else {
+ *p++ = (((ap->name[i]) >> 6) | ((byte) 0xC0));
+ *p++ = (((ap->name[i]) & 0x3F) | ((byte) 0x80));
+ }
+ }
+ break;
+ case ERL_FILENAME_WIN_WCHAR:
+ for (i = 0; i < ap->len; i++) {
+ /* Little endian */
+ *p++ = ap->name[i];
+ *p++ = 0;
+ }
+ break;
+ default:
+ ASSERT(0);
+ }
+ DESTROY_ESTACK(stack);
+ return;
+ }
+
+ if (is_nil(ioterm)) {
+ DESTROY_ESTACK(stack);
+ return;
+ }
+ ASSERT(is_list(ioterm));
+ /* OK a list, needs to be processed in order, handling each flat list-level
+ as they occur, just like io_list_to_binary would */
+ ESTACK_PUSH(stack,ioterm);
+ while (!ESTACK_ISEMPTY(stack)) {
+ ioterm = ESTACK_POP(stack);
+ if (is_nil(ioterm)) {
+ /* ignore empty lists */
+ continue;
+ }
+ if(is_list(ioterm)) {
+L_Again: /* Restart with sublist, old listend was pushed on stack */
+ objp = list_val(ioterm);
+ obj = CAR(objp);
+ for(;;) { /* loop over one flat list of bytes and binaries
+ until sublist or list end is encountered */
+ if (is_small(obj)) { /* Always small */
+ for(;;) {
+ Uint x = unsigned_val(obj);
+ switch (encoding) {
+ case ERL_FILENAME_LATIN1:
+ ASSERT( x < 256);
+ *p++ = (byte) x;
+ break;
+ case ERL_FILENAME_UTF8_MAC:
+ case ERL_FILENAME_UTF8:
+ if (x < 0x80) {
+ *p++ = (byte) x;
+ }
+ else if (x < 0x800) {
+ *p++ = (((byte) (x >> 6)) |
+ ((byte) 0xC0));
+ *p++ = (((byte) (x & 0x3F)) |
+ ((byte) 0x80));
+ } else if (x < 0x10000) {
+ ASSERT(!((x >= 0xD800 && x <= 0xDFFF) ||
+ (x == 0xFFFE) ||
+ (x == 0xFFFF)));
+ *p++ = (((byte) (x >> 12)) |
+ ((byte) 0xE0));
+ *p++ = ((((byte) (x >> 6)) & 0x3F) |
+ ((byte) 0x80));
+ *p++ = (((byte) (x & 0x3F)) |
+ ((byte) 0x80));
+ } else {
+ ASSERT(x < 0x110000);
+ *p++ = (((byte) (x >> 18)) |
+ ((byte) 0xF0));
+ *p++ = ((((byte) (x >> 12)) & 0x3F) |
+ ((byte) 0x80));
+ *p++ = ((((byte) (x >> 6)) & 0x3F) |
+ ((byte) 0x80));
+ *p++ = (((byte) (x & 0x3F)) |
+ ((byte) 0x80));
+ }
+ break;
+ case ERL_FILENAME_WIN_WCHAR:
+ ASSERT(x <= 0xFFFF);
+ *p++ = (byte) (x & 0xFFU);
+ *p++ = (byte) ((x >> 8) & 0xFFU);
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ /* everything else will give badarg later
+ in the process, so we dont check */
+ ioterm = CDR(objp);
+ if (!is_list(ioterm)) {
+ break;
+ }
+ objp = list_val(ioterm);
+ obj = CAR(objp);
+ if (!is_small(obj))
+ break;
+ }
+ } else if (is_nil(obj)) {
+ ioterm = CDR(objp);
+ if (!is_list(ioterm)) {
+ break;
+ }
+ objp = list_val(ioterm);
+ obj = CAR(objp);
+ } else if (is_list(obj)) {
+ /* push rest of list for later processing, start
+ again with sublist */
+ ESTACK_PUSH(stack,CDR(objp));
+ ioterm = obj;
+ goto L_Again;
+ } else {
+ ASSERT(0);
+ }
+ if (is_nil(ioterm) || !is_list(ioterm)) {
+ break;
+ }
+ } /* for(;;) */
+ } /* is_list(ioterm) */
+
+ ASSERT(is_list(ioterm) || is_nil(ioterm));
+ } /* while not estack empty */
+ DESTROY_ESTACK(stack);
+ return;
+}
+void erts_copy_utf8_to_utf16_little(byte *target, byte *bytes, int num_chars)
+{
+ Uint unipoint;
+
+ while (num_chars--) {
+ if (((*bytes) & ((byte) 0x80)) == 0) {
+ unipoint = (Uint) *bytes;
+ ++bytes;
+ } else if (((*bytes) & ((byte) 0xE0)) == 0xC0) {
+ unipoint =
+ (((Uint) ((*bytes) & ((byte) 0x1F))) << 6) |
+ ((Uint) (bytes[1] & ((byte) 0x3F)));
+ bytes += 2;
+ } else if (((*bytes) & ((byte) 0xF0)) == 0xE0) {
+ unipoint =
+ (((Uint) ((*bytes) & ((byte) 0xF))) << 12) |
+ (((Uint) (bytes[1] & ((byte) 0x3F))) << 6) |
+ ((Uint) (bytes[2] & ((byte) 0x3F)));
+ bytes +=3;
+ } else if (((*bytes) & ((byte) 0xF8)) == 0xF0) {
+ unipoint =
+ (((Uint) ((*bytes) & ((byte) 0x7))) << 18) |
+ (((Uint) (bytes[1] & ((byte) 0x3F))) << 12) |
+ (((Uint) (bytes[2] & ((byte) 0x3F))) << 6) |
+ ((Uint) (bytes[3] & ((byte) 0x3F)));
+ bytes += 4;
+ } else {
+ erl_exit(1,"Internal unicode error in prim_file:internal_name2native/1");
+ }
+ *target++ = (byte) (unipoint & 0xFF);
+ *target++ = (byte) ((unipoint >> 8) & 0xFF);
+ }
+}
+
+/*
+ * This internal bif converts a filename to whatever format is suitable for the file driver
+ * It also adds zero termination so that prim_file needn't bother with the character encoding
+ * of the file driver
+ */
+BIF_RETTYPE prim_file_internal_name2native_1(BIF_ALIST_1)
+{
+ int encoding = erts_get_native_filename_encoding();
+ Sint need;
+ Eterm bin_term;
+ byte* bin_p;
+ /* Prim file explicitly does not allow atoms, although we could
+ very well cope with it. Instead of letting 'file' handle them,
+ it would probably be more efficient to handle them here. Subject to
+ change in R15. */
+ if (is_atom(BIF_ARG_1)) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ if (is_binary(BIF_ARG_1)) {
+ byte *temp_alloc = NULL;
+ byte *bytes;
+ byte *err_pos;
+ Uint size,num_chars;
+ /* Uninterpreted encoding except if windows widechar, in case we convert from
+ utf8 to win_wchar */
+ size = binary_size(BIF_ARG_1);
+ bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc);
+ if (encoding != ERL_FILENAME_WIN_WCHAR) {
+ /*Add 0 termination only*/
+ bin_term = new_binary(BIF_P, NULL, size+1);
+ bin_p = binary_bytes(bin_term);
+ memcpy(bin_p,bytes,size);
+ bin_p[size]=0;
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_RET(bin_term);
+ }
+ /* In a wchar world, the emulator flags only affect how
+ binaries are interpreted when sent from the user. */
+ /* Determine real length and create a new binary */
+ if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK ||
+ erts_get_user_requested_filename_encoding() == ERL_FILENAME_LATIN1) {
+ /* What to do now? Maybe latin1, so just take byte for byte instead */
+ bin_term = new_binary(BIF_P, 0, (size+1)*2);
+ bin_p = binary_bytes(bin_term);
+ while (size--) {
+ *bin_p++ = *bytes++;
+ *bin_p++ = 0;
+ }
+ *bin_p++ = 0;
+ *bin_p++ = 0;
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_RET(bin_term);
+ }
+ /* OK, UTF8 ok, number of characters is in num_chars */
+ bin_term = new_binary(BIF_P, 0, (num_chars+1)*2);
+ bin_p = binary_bytes(bin_term);
+ erts_copy_utf8_to_utf16_little(bin_p, bytes, num_chars);
+ /* zero termination */
+ bin_p[num_chars*2] = 0;
+ bin_p[num_chars*2+1] = 0;
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_RET(bin_term);
+ } /* binary */
+
+
+ if ((need = erts_native_filename_need(BIF_ARG_1,encoding)) < 0) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ if (encoding == ERL_FILENAME_WIN_WCHAR) {
+ need += 2;
+ } else {
+ ++need;
+ }
+
+ bin_term = new_binary(BIF_P, 0, need);
+ bin_p = binary_bytes(bin_term);
+ erts_native_filename_put(BIF_ARG_1,encoding,bin_p);
+ bin_p[need-1] = 0;
+ if (encoding == ERL_FILENAME_WIN_WCHAR) {
+ bin_p[need-2] = 0;
+ }
+ BIF_RET(bin_term);
+}
+
+BIF_RETTYPE prim_file_internal_native2name_1(BIF_ALIST_1)
+{
+ Eterm real_bin;
+ Uint offset;
+ Uint size,num_chars;
+ Uint bitsize;
+ Uint bitoffs;
+ Eterm *hp;
+ byte *temp_alloc = NULL;
+ byte *bytes;
+ byte *err_pos;
+ Uint num_built; /* characters */
+ Uint num_eaten; /* bytes */
+ Eterm ret;
+ int mac = 0;
+
+ if (is_not_binary(BIF_ARG_1)) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ size = binary_size(BIF_ARG_1);
+ ERTS_GET_REAL_BIN(BIF_ARG_1, real_bin, offset, bitoffs, bitsize);
+ if (bitsize != 0) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ if (size == 0) {
+ BIF_RET(NIL);
+ }
+ switch (erts_get_native_filename_encoding()) {
+ case ERL_FILENAME_LATIN1:
+ hp = HAlloc(BIF_P, 2 * size);
+ bytes = binary_bytes(real_bin)+offset;
+
+ BIF_RET(erts_bin_bytes_to_list(NIL, hp, bytes, size, bitoffs));
+ case ERL_FILENAME_UTF8_MAC:
+ mac = 1;
+ case ERL_FILENAME_UTF8:
+ bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc);
+ if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK) {
+ erts_free_aligned_binary_bytes(temp_alloc);
+ goto noconvert;
+ }
+ num_built = 0;
+ num_eaten = 0;
+ if (mac) {
+ ret = do_utf8_to_list_normalize(BIF_P, num_chars, bytes, size);
+ } else {
+ ret = do_utf8_to_list(BIF_P, num_chars, bytes, size, num_chars, &num_built, &num_eaten, NIL);
+ }
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_RET(ret);
+ case ERL_FILENAME_WIN_WCHAR:
+ bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc);
+ if ((size % 2) != 0) { /* Panic fixup to avoid crashing the emulator */
+ size--;
+ hp = HAlloc(BIF_P, size+2);
+ ret = CONS(hp,make_small((Uint) bytes[size]),NIL);
+ hp += 2;
+ } else {
+ hp = HAlloc(BIF_P, size);
+ ret = NIL;
+ }
+ bytes += size-1;
+ while (size > 0) {
+ Uint x = ((Uint) *bytes--) << 8;
+ x |= ((Uint) *bytes--);
+ size -= 2;
+ ret = CONS(hp,make_small(x),ret);
+ hp += 2;
+ }
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_RET(ret);
+ default:
+ goto noconvert;
+ }
+ noconvert:
+ BIF_RET(BIF_ARG_1);
+}
+
+BIF_RETTYPE prim_file_internal_normalize_utf8_1(BIF_ALIST_1)
+{
+ Eterm real_bin;
+ Uint offset;
+ Uint size,num_chars;
+ Uint bitsize;
+ Uint bitoffs;
+ Eterm ret;
+ byte *temp_alloc = NULL;
+ byte *bytes;
+ byte *err_pos;
+
+ if (is_not_binary(BIF_ARG_1)) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ size = binary_size(BIF_ARG_1);
+ ERTS_GET_REAL_BIN(BIF_ARG_1, real_bin, offset, bitoffs, bitsize);
+ if (bitsize != 0) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ if (size == 0) {
+ BIF_RET(NIL);
+ }
+ bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc);
+ if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK) {
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ ret = do_utf8_to_list_normalize(BIF_P, num_chars, bytes, size);
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_RET(ret);
+}
+
+BIF_RETTYPE file_native_name_encoding_0(BIF_ALIST_0)
+{
+ switch (erts_get_native_filename_encoding()) {
+ case ERL_FILENAME_LATIN1:
+ BIF_RET(am_latin1);
+ case ERL_FILENAME_UTF8_MAC:
+ case ERL_FILENAME_UTF8:
+ BIF_RET(am_utf8);
+ case ERL_FILENAME_WIN_WCHAR:
+ if (erts_get_user_requested_filename_encoding() == ERL_FILENAME_LATIN1) {
+ BIF_RET(am_latin1);
+ } else {
+ BIF_RET(am_utf8);
+ }
+ default:
+ BIF_RET(am_undefined);
+ }
+}
diff --git a/erts/emulator/beam/erl_unicode_normalize.h b/erts/emulator/beam/erl_unicode_normalize.h
new file mode 100644
index 0000000000..fb0a111ca2
--- /dev/null
+++ b/erts/emulator/beam/erl_unicode_normalize.h
@@ -0,0 +1,1687 @@
+/*
+* %CopyrightBegin%
+*
+* Copyright Ericsson AB 1999-2010. All Rights Reserved.
+*
+* The contents of this file are subject to the Erlang Public License,
+* Version 1.1, (the "License"); you may not use this file except in
+* compliance with the License. You should have received a copy of the
+* Erlang Public License along with this software. If not, it can be
+* retrieved online at http://www.erlang.org/.
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* %CopyrightEnd%
+*/
+/*
+* This file is automatically generated by dec.erl, do not edit manually
+*/
+#define HASH_SIZE_FACTOR 2
+typedef struct _compose_entry {
+ Uint16 c;
+ Uint16 res;
+ Uint16 num_subs;
+ struct _compose_entry *subs;
+ int *hash;
+} CompEntry;
+
+static int compose_tab_size = 61;
+static int hash_compose_tab_0_15[12] =
+{-1,3,-1,5,-1,0,4,2,-1,1,-1,-1}; /* hash_compose_tab_0_15 */
+static CompEntry compose_tab_0_15[] = {
+{65, 7846, 0, NULL, NULL},
+{69, 7872, 0, NULL, NULL},
+{79, 7890, 0, NULL, NULL},
+{97, 7847, 0, NULL, NULL},
+{101, 7873, 0, NULL, NULL},
+{111, 7891, 0, NULL, NULL}
+}; /* compose_tab_0_15 */
+static int hash_compose_tab_0_16[8] =
+{3,-1,-1,-1,-1,0,2,1}; /* hash_compose_tab_0_16 */
+static CompEntry compose_tab_0_16[] = {
+{69, 7700, 0, NULL, NULL},
+{79, 7760, 0, NULL, NULL},
+{101, 7701, 0, NULL, NULL},
+{111, 7761, 0, NULL, NULL}
+}; /* compose_tab_0_16 */
+static int hash_compose_tab_0_17[4] =
+{-1,0,1,-1}; /* hash_compose_tab_0_17 */
+static CompEntry compose_tab_0_17[] = {
+{65, 7856, 0, NULL, NULL},
+{97, 7857, 0, NULL, NULL}
+}; /* compose_tab_0_17 */
+static int hash_compose_tab_0_18[8] =
+{-1,2,-1,-1,-1,0,1,3}; /* hash_compose_tab_0_18 */
+static CompEntry compose_tab_0_18[] = {
+{85, 475, 0, NULL, NULL},
+{117, 476, 0, NULL, NULL},
+{953, 8146, 0, NULL, NULL},
+{965, 8162, 0, NULL, NULL}
+}; /* compose_tab_0_18 */
+static int hash_compose_tab_0_19_0[12] =
+{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_0_19_0 */
+static CompEntry compose_tab_0_19_0[] = {
+{913, 8074, 0, NULL, NULL},
+{919, 8090, 0, NULL, NULL},
+{937, 8106, 0, NULL, NULL},
+{945, 8066, 0, NULL, NULL},
+{951, 8082, 0, NULL, NULL},
+{969, 8098, 0, NULL, NULL}
+}; /* compose_tab_0_19_0 */
+static int hash_compose_tab_0_19[28] =
+{9,10,-1,5,-1,-1,-1,11,-1,-1,-1,-1,-1,6,12,-1,-1,1,13,-1,-1,2,7,3,-1,0,4,8}; /* hash_compose_tab_0_19 */
+static CompEntry compose_tab_0_19[] = {
+{837, 0, 6, compose_tab_0_19_0, hash_compose_tab_0_19_0},
+{913, 7946, 0, NULL, NULL},
+{917, 7962, 0, NULL, NULL},
+{919, 7978, 0, NULL, NULL},
+{921, 7994, 0, NULL, NULL},
+{927, 8010, 0, NULL, NULL},
+{937, 8042, 0, NULL, NULL},
+{945, 7938, 0, NULL, NULL},
+{949, 7954, 0, NULL, NULL},
+{951, 7970, 0, NULL, NULL},
+{953, 7986, 0, NULL, NULL},
+{959, 8002, 0, NULL, NULL},
+{965, 8018, 0, NULL, NULL},
+{969, 8034, 0, NULL, NULL}
+}; /* compose_tab_0_19 */
+static int hash_compose_tab_0_20_0[12] =
+{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_0_20_0 */
+static CompEntry compose_tab_0_20_0[] = {
+{913, 8075, 0, NULL, NULL},
+{919, 8091, 0, NULL, NULL},
+{937, 8107, 0, NULL, NULL},
+{945, 8067, 0, NULL, NULL},
+{951, 8083, 0, NULL, NULL},
+{969, 8099, 0, NULL, NULL}
+}; /* compose_tab_0_20_0 */
+static int hash_compose_tab_0_20[30] =
+{-1,-1,-1,6,-1,13,-1,7,-1,14,-1,-1,-1,1,-1,8,-1,2,-1,3,9,4,10,11,-1,-1,-1,0,5,
+ 12}; /* hash_compose_tab_0_20 */
+static CompEntry compose_tab_0_20[] = {
+{837, 0, 6, compose_tab_0_20_0, hash_compose_tab_0_20_0},
+{913, 7947, 0, NULL, NULL},
+{917, 7963, 0, NULL, NULL},
+{919, 7979, 0, NULL, NULL},
+{921, 7995, 0, NULL, NULL},
+{927, 8011, 0, NULL, NULL},
+{933, 8027, 0, NULL, NULL},
+{937, 8043, 0, NULL, NULL},
+{945, 7939, 0, NULL, NULL},
+{949, 7955, 0, NULL, NULL},
+{951, 7971, 0, NULL, NULL},
+{953, 7987, 0, NULL, NULL},
+{959, 8003, 0, NULL, NULL},
+{965, 8019, 0, NULL, NULL},
+{969, 8035, 0, NULL, NULL}
+}; /* compose_tab_0_20 */
+static int hash_compose_tab_0_21[8] =
+{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_0_21 */
+static CompEntry compose_tab_0_21[] = {
+{79, 7900, 0, NULL, NULL},
+{85, 7914, 0, NULL, NULL},
+{111, 7901, 0, NULL, NULL},
+{117, 7915, 0, NULL, NULL}
+}; /* compose_tab_0_21 */
+static int hash_compose_tab_0_22[6] =
+{-1,-1,-1,0,1,2}; /* hash_compose_tab_0_22 */
+static CompEntry compose_tab_0_22[] = {
+{945, 8114, 0, NULL, NULL},
+{951, 8130, 0, NULL, NULL},
+{969, 8178, 0, NULL, NULL}
+}; /* compose_tab_0_22 */
+static int hash_compose_tab_0[78] =
+{38,3,29,-1,-1,-1,-1,4,19,5,20,6,14,30,31,21,32,33,37,7,-1,-1,-1,8,34,-1,-1,9,
+ -1,35,-1,-1,-1,10,36,-1,-1,-1,-1,11,-1,12,-1,13,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,23,-1,22,-1,24,-1,25,-1,26,-1,0,-1,-1,15,1,16,27,17,2,18,28,-1,-1}; /* hash_compose_tab_0 */
+static CompEntry compose_tab_0[] = {
+{65, 192, 0, NULL, NULL},
+{69, 200, 0, NULL, NULL},
+{73, 204, 0, NULL, NULL},
+{79, 210, 0, NULL, NULL},
+{85, 217, 0, NULL, NULL},
+{87, 7808, 0, NULL, NULL},
+{89, 7922, 0, NULL, NULL},
+{97, 224, 0, NULL, NULL},
+{101, 232, 0, NULL, NULL},
+{105, 236, 0, NULL, NULL},
+{111, 242, 0, NULL, NULL},
+{117, 249, 0, NULL, NULL},
+{119, 7809, 0, NULL, NULL},
+{121, 7923, 0, NULL, NULL},
+{168, 8173, 0, NULL, NULL},
+{770, 0, 6, compose_tab_0_15, hash_compose_tab_0_15},
+{772, 0, 4, compose_tab_0_16, hash_compose_tab_0_16},
+{774, 0, 2, compose_tab_0_17, hash_compose_tab_0_17},
+{776, 0, 4, compose_tab_0_18, hash_compose_tab_0_18},
+{787, 0, 14, compose_tab_0_19, hash_compose_tab_0_19},
+{788, 0, 15, compose_tab_0_20, hash_compose_tab_0_20},
+{795, 0, 4, compose_tab_0_21, hash_compose_tab_0_21},
+{837, 0, 3, compose_tab_0_22, hash_compose_tab_0_22},
+{913, 8122, 0, NULL, NULL},
+{917, 8136, 0, NULL, NULL},
+{919, 8138, 0, NULL, NULL},
+{921, 8154, 0, NULL, NULL},
+{927, 8184, 0, NULL, NULL},
+{933, 8170, 0, NULL, NULL},
+{937, 8186, 0, NULL, NULL},
+{945, 8048, 0, NULL, NULL},
+{949, 8050, 0, NULL, NULL},
+{951, 8052, 0, NULL, NULL},
+{953, 8054, 0, NULL, NULL},
+{959, 8056, 0, NULL, NULL},
+{965, 8058, 0, NULL, NULL},
+{969, 8060, 0, NULL, NULL},
+{8127, 8141, 0, NULL, NULL},
+{8190, 8157, 0, NULL, NULL}
+}; /* compose_tab_0 */
+static int hash_compose_tab_1_39[12] =
+{-1,3,-1,5,-1,0,4,2,-1,1,-1,-1}; /* hash_compose_tab_1_39 */
+static CompEntry compose_tab_1_39[] = {
+{65, 7844, 0, NULL, NULL},
+{69, 7870, 0, NULL, NULL},
+{79, 7888, 0, NULL, NULL},
+{97, 7845, 0, NULL, NULL},
+{101, 7871, 0, NULL, NULL},
+{111, 7889, 0, NULL, NULL}
+}; /* compose_tab_1_39 */
+static int hash_compose_tab_1_40[8] =
+{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_1_40 */
+static CompEntry compose_tab_1_40[] = {
+{79, 7756, 0, NULL, NULL},
+{85, 7800, 0, NULL, NULL},
+{111, 7757, 0, NULL, NULL},
+{117, 7801, 0, NULL, NULL}
+}; /* compose_tab_1_40 */
+static int hash_compose_tab_1_41[8] =
+{3,-1,-1,-1,-1,0,2,1}; /* hash_compose_tab_1_41 */
+static CompEntry compose_tab_1_41[] = {
+{69, 7702, 0, NULL, NULL},
+{79, 7762, 0, NULL, NULL},
+{101, 7703, 0, NULL, NULL},
+{111, 7763, 0, NULL, NULL}
+}; /* compose_tab_1_41 */
+static int hash_compose_tab_1_42[4] =
+{-1,0,1,-1}; /* hash_compose_tab_1_42 */
+static CompEntry compose_tab_1_42[] = {
+{65, 7854, 0, NULL, NULL},
+{97, 7855, 0, NULL, NULL}
+}; /* compose_tab_1_42 */
+static int hash_compose_tab_1_43[12] =
+{-1,0,1,-1,-1,4,5,-1,-1,2,3,-1}; /* hash_compose_tab_1_43 */
+static CompEntry compose_tab_1_43[] = {
+{73, 7726, 0, NULL, NULL},
+{85, 471, 0, NULL, NULL},
+{105, 7727, 0, NULL, NULL},
+{117, 472, 0, NULL, NULL},
+{953, 8147, 0, NULL, NULL},
+{965, 8163, 0, NULL, NULL}
+}; /* compose_tab_1_43 */
+static int hash_compose_tab_1_44[4] =
+{-1,0,1,-1}; /* hash_compose_tab_1_44 */
+static CompEntry compose_tab_1_44[] = {
+{65, 506, 0, NULL, NULL},
+{97, 507, 0, NULL, NULL}
+}; /* compose_tab_1_44 */
+static int hash_compose_tab_1_45_0[12] =
+{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_1_45_0 */
+static CompEntry compose_tab_1_45_0[] = {
+{913, 8076, 0, NULL, NULL},
+{919, 8092, 0, NULL, NULL},
+{937, 8108, 0, NULL, NULL},
+{945, 8068, 0, NULL, NULL},
+{951, 8084, 0, NULL, NULL},
+{969, 8100, 0, NULL, NULL}
+}; /* compose_tab_1_45_0 */
+static int hash_compose_tab_1_45[28] =
+{9,10,-1,5,-1,-1,-1,11,-1,-1,-1,-1,-1,6,12,-1,-1,1,13,-1,-1,2,7,3,-1,0,4,8}; /* hash_compose_tab_1_45 */
+static CompEntry compose_tab_1_45[] = {
+{837, 0, 6, compose_tab_1_45_0, hash_compose_tab_1_45_0},
+{913, 7948, 0, NULL, NULL},
+{917, 7964, 0, NULL, NULL},
+{919, 7980, 0, NULL, NULL},
+{921, 7996, 0, NULL, NULL},
+{927, 8012, 0, NULL, NULL},
+{937, 8044, 0, NULL, NULL},
+{945, 7940, 0, NULL, NULL},
+{949, 7956, 0, NULL, NULL},
+{951, 7972, 0, NULL, NULL},
+{953, 7988, 0, NULL, NULL},
+{959, 8004, 0, NULL, NULL},
+{965, 8020, 0, NULL, NULL},
+{969, 8036, 0, NULL, NULL}
+}; /* compose_tab_1_45 */
+static int hash_compose_tab_1_46_0[12] =
+{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_1_46_0 */
+static CompEntry compose_tab_1_46_0[] = {
+{913, 8077, 0, NULL, NULL},
+{919, 8093, 0, NULL, NULL},
+{937, 8109, 0, NULL, NULL},
+{945, 8069, 0, NULL, NULL},
+{951, 8085, 0, NULL, NULL},
+{969, 8101, 0, NULL, NULL}
+}; /* compose_tab_1_46_0 */
+static int hash_compose_tab_1_46[30] =
+{-1,-1,-1,6,-1,13,-1,7,-1,14,-1,-1,-1,1,-1,8,-1,2,-1,3,9,4,10,11,-1,-1,-1,0,5,
+ 12}; /* hash_compose_tab_1_46 */
+static CompEntry compose_tab_1_46[] = {
+{837, 0, 6, compose_tab_1_46_0, hash_compose_tab_1_46_0},
+{913, 7949, 0, NULL, NULL},
+{917, 7965, 0, NULL, NULL},
+{919, 7981, 0, NULL, NULL},
+{921, 7997, 0, NULL, NULL},
+{927, 8013, 0, NULL, NULL},
+{933, 8029, 0, NULL, NULL},
+{937, 8045, 0, NULL, NULL},
+{945, 7941, 0, NULL, NULL},
+{949, 7957, 0, NULL, NULL},
+{951, 7973, 0, NULL, NULL},
+{953, 7989, 0, NULL, NULL},
+{959, 8005, 0, NULL, NULL},
+{965, 8021, 0, NULL, NULL},
+{969, 8037, 0, NULL, NULL}
+}; /* compose_tab_1_46 */
+static int hash_compose_tab_1_47[8] =
+{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_1_47 */
+static CompEntry compose_tab_1_47[] = {
+{79, 7898, 0, NULL, NULL},
+{85, 7912, 0, NULL, NULL},
+{111, 7899, 0, NULL, NULL},
+{117, 7913, 0, NULL, NULL}
+}; /* compose_tab_1_47 */
+static int hash_compose_tab_1_48[4] =
+{1,-1,-1,0}; /* hash_compose_tab_1_48 */
+static CompEntry compose_tab_1_48[] = {
+{67, 7688, 0, NULL, NULL},
+{99, 7689, 0, NULL, NULL}
+}; /* compose_tab_1_48 */
+static int hash_compose_tab_1_49[6] =
+{-1,-1,-1,0,1,2}; /* hash_compose_tab_1_49 */
+static CompEntry compose_tab_1_49[] = {
+{945, 8116, 0, NULL, NULL},
+{951, 8132, 0, NULL, NULL},
+{959, 8180, 0, NULL, NULL}
+}; /* compose_tab_1_49 */
+static int hash_compose_tab_1[140] =
+{-1,-1,-1,-1,-1,-1,-1,68,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,34,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,35,-1,-1,-1,-1,64,-1,0,-1,1,-1,2,39,3,40,4,41,5,6,7,
+ 8,9,10,36,11,12,42,13,43,14,44,15,16,37,45,46,50,47,51,17,52,18,53,19,54,20,
+ 55,21,56,22,23,24,25,26,27,38,28,29,48,30,57,31,58,32,33,59,60,61,62,65,66,
+ 63,67,69,-1,-1,-1,-1,-1,49,-1,-1}; /* hash_compose_tab_1 */
+static CompEntry compose_tab_1[] = {
+{65, 193, 0, NULL, NULL},
+{67, 262, 0, NULL, NULL},
+{69, 201, 0, NULL, NULL},
+{71, 500, 0, NULL, NULL},
+{73, 205, 0, NULL, NULL},
+{75, 7728, 0, NULL, NULL},
+{76, 313, 0, NULL, NULL},
+{77, 7742, 0, NULL, NULL},
+{78, 323, 0, NULL, NULL},
+{79, 211, 0, NULL, NULL},
+{80, 7764, 0, NULL, NULL},
+{82, 340, 0, NULL, NULL},
+{83, 346, 0, NULL, NULL},
+{85, 218, 0, NULL, NULL},
+{87, 7810, 0, NULL, NULL},
+{89, 221, 0, NULL, NULL},
+{90, 377, 0, NULL, NULL},
+{97, 225, 0, NULL, NULL},
+{99, 263, 0, NULL, NULL},
+{101, 233, 0, NULL, NULL},
+{103, 501, 0, NULL, NULL},
+{105, 237, 0, NULL, NULL},
+{107, 7729, 0, NULL, NULL},
+{108, 314, 0, NULL, NULL},
+{109, 7743, 0, NULL, NULL},
+{110, 324, 0, NULL, NULL},
+{111, 243, 0, NULL, NULL},
+{112, 7765, 0, NULL, NULL},
+{114, 341, 0, NULL, NULL},
+{115, 347, 0, NULL, NULL},
+{117, 250, 0, NULL, NULL},
+{119, 7811, 0, NULL, NULL},
+{121, 253, 0, NULL, NULL},
+{122, 378, 0, NULL, NULL},
+{168, 8174, 0, NULL, NULL},
+{198, 508, 0, NULL, NULL},
+{216, 510, 0, NULL, NULL},
+{230, 509, 0, NULL, NULL},
+{248, 511, 0, NULL, NULL},
+{770, 0, 6, compose_tab_1_39, hash_compose_tab_1_39},
+{771, 0, 4, compose_tab_1_40, hash_compose_tab_1_40},
+{772, 0, 4, compose_tab_1_41, hash_compose_tab_1_41},
+{774, 0, 2, compose_tab_1_42, hash_compose_tab_1_42},
+{776, 0, 6, compose_tab_1_43, hash_compose_tab_1_43},
+{778, 0, 2, compose_tab_1_44, hash_compose_tab_1_44},
+{787, 0, 14, compose_tab_1_45, hash_compose_tab_1_45},
+{788, 0, 15, compose_tab_1_46, hash_compose_tab_1_46},
+{795, 0, 4, compose_tab_1_47, hash_compose_tab_1_47},
+{807, 0, 2, compose_tab_1_48, hash_compose_tab_1_48},
+{837, 0, 3, compose_tab_1_49, hash_compose_tab_1_49},
+{913, 8123, 0, NULL, NULL},
+{917, 8137, 0, NULL, NULL},
+{919, 8139, 0, NULL, NULL},
+{921, 8155, 0, NULL, NULL},
+{927, 8185, 0, NULL, NULL},
+{933, 8171, 0, NULL, NULL},
+{937, 8187, 0, NULL, NULL},
+{945, 8049, 0, NULL, NULL},
+{949, 8051, 0, NULL, NULL},
+{951, 8053, 0, NULL, NULL},
+{953, 8055, 0, NULL, NULL},
+{959, 8057, 0, NULL, NULL},
+{965, 8059, 0, NULL, NULL},
+{969, 8061, 0, NULL, NULL},
+{1043, 1027, 0, NULL, NULL},
+{1050, 1036, 0, NULL, NULL},
+{1075, 1107, 0, NULL, NULL},
+{1082, 1116, 0, NULL, NULL},
+{8127, 8142, 0, NULL, NULL},
+{8190, 8158, 0, NULL, NULL}
+}; /* compose_tab_1 */
+static int hash_compose_tab_2_26[12] =
+{-1,3,-1,5,-1,0,4,2,-1,1,-1,-1}; /* hash_compose_tab_2_26 */
+static CompEntry compose_tab_2_26[] = {
+{65, 7852, 0, NULL, NULL},
+{69, 7878, 0, NULL, NULL},
+{79, 7896, 0, NULL, NULL},
+{97, 7853, 0, NULL, NULL},
+{101, 7879, 0, NULL, NULL},
+{111, 7897, 0, NULL, NULL}
+}; /* compose_tab_2_26 */
+static int hash_compose_tab_2[54] =
+{-1,-1,-1,20,-1,-1,-1,21,-1,22,-1,0,23,1,24,2,25,3,4,5,6,-1,-1,-1,-1,7,-1,-1,
+ -1,8,-1,9,-1,10,-1,11,12,-1,-1,-1,-1,-1,-1,13,-1,14,-1,15,26,16,17,18,19,-1}; /* hash_compose_tab_2 */
+static CompEntry compose_tab_2[] = {
+{65, 194, 0, NULL, NULL},
+{67, 264, 0, NULL, NULL},
+{69, 202, 0, NULL, NULL},
+{71, 284, 0, NULL, NULL},
+{72, 292, 0, NULL, NULL},
+{73, 206, 0, NULL, NULL},
+{74, 308, 0, NULL, NULL},
+{79, 212, 0, NULL, NULL},
+{83, 348, 0, NULL, NULL},
+{85, 219, 0, NULL, NULL},
+{87, 372, 0, NULL, NULL},
+{89, 374, 0, NULL, NULL},
+{90, 7824, 0, NULL, NULL},
+{97, 226, 0, NULL, NULL},
+{99, 265, 0, NULL, NULL},
+{101, 234, 0, NULL, NULL},
+{103, 285, 0, NULL, NULL},
+{104, 293, 0, NULL, NULL},
+{105, 238, 0, NULL, NULL},
+{106, 309, 0, NULL, NULL},
+{111, 244, 0, NULL, NULL},
+{115, 349, 0, NULL, NULL},
+{117, 251, 0, NULL, NULL},
+{119, 373, 0, NULL, NULL},
+{121, 375, 0, NULL, NULL},
+{122, 7825, 0, NULL, NULL},
+{803, 0, 6, compose_tab_2_26, hash_compose_tab_2_26}
+}; /* compose_tab_2 */
+static int hash_compose_tab_3_16[12] =
+{-1,3,-1,5,-1,0,4,2,-1,1,-1,-1}; /* hash_compose_tab_3_16 */
+static CompEntry compose_tab_3_16[] = {
+{65, 7850, 0, NULL, NULL},
+{69, 7876, 0, NULL, NULL},
+{79, 7894, 0, NULL, NULL},
+{97, 7851, 0, NULL, NULL},
+{101, 7877, 0, NULL, NULL},
+{111, 7895, 0, NULL, NULL}
+}; /* compose_tab_3_16 */
+static int hash_compose_tab_3_17[4] =
+{-1,0,1,-1}; /* hash_compose_tab_3_17 */
+static CompEntry compose_tab_3_17[] = {
+{65, 7860, 0, NULL, NULL},
+{97, 7861, 0, NULL, NULL}
+}; /* compose_tab_3_17 */
+static int hash_compose_tab_3_18[8] =
+{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_3_18 */
+static CompEntry compose_tab_3_18[] = {
+{79, 7904, 0, NULL, NULL},
+{85, 7918, 0, NULL, NULL},
+{111, 7905, 0, NULL, NULL},
+{117, 7919, 0, NULL, NULL}
+}; /* compose_tab_3_18 */
+static int hash_compose_tab_3[38] =
+{-1,-1,3,4,13,14,-1,15,-1,5,6,16,-1,7,17,-1,-1,-1,-1,-1,-1,8,-1,-1,-1,9,-1,0,
+ -1,10,-1,1,-1,-1,11,2,12,18}; /* hash_compose_tab_3 */
+static CompEntry compose_tab_3[] = {
+{65, 195, 0, NULL, NULL},
+{69, 7868, 0, NULL, NULL},
+{73, 296, 0, NULL, NULL},
+{78, 209, 0, NULL, NULL},
+{79, 213, 0, NULL, NULL},
+{85, 360, 0, NULL, NULL},
+{86, 7804, 0, NULL, NULL},
+{89, 7928, 0, NULL, NULL},
+{97, 227, 0, NULL, NULL},
+{101, 7869, 0, NULL, NULL},
+{105, 297, 0, NULL, NULL},
+{110, 241, 0, NULL, NULL},
+{111, 245, 0, NULL, NULL},
+{117, 361, 0, NULL, NULL},
+{118, 7805, 0, NULL, NULL},
+{121, 7929, 0, NULL, NULL},
+{770, 0, 6, compose_tab_3_16, hash_compose_tab_3_16},
+{774, 0, 2, compose_tab_3_17, hash_compose_tab_3_17},
+{795, 0, 4, compose_tab_3_18, hash_compose_tab_3_18}
+}; /* compose_tab_3 */
+static int hash_compose_tab_4_14[4] =
+{-1,0,1,-1}; /* hash_compose_tab_4_14 */
+static CompEntry compose_tab_4_14[] = {
+{65, 480, 0, NULL, NULL},
+{97, 481, 0, NULL, NULL}
+}; /* compose_tab_4_14 */
+static int hash_compose_tab_4_15[8] =
+{-1,0,2,-1,-1,1,3,-1}; /* hash_compose_tab_4_15 */
+static CompEntry compose_tab_4_15[] = {
+{65, 478, 0, NULL, NULL},
+{85, 469, 0, NULL, NULL},
+{97, 479, 0, NULL, NULL},
+{117, 470, 0, NULL, NULL}
+}; /* compose_tab_4_15 */
+static int hash_compose_tab_4_16[8] =
+{-1,-1,1,3,0,2,-1,-1}; /* hash_compose_tab_4_16 */
+static CompEntry compose_tab_4_16[] = {
+{76, 7736, 0, NULL, NULL},
+{82, 7772, 0, NULL, NULL},
+{108, 7737, 0, NULL, NULL},
+{114, 7773, 0, NULL, NULL}
+}; /* compose_tab_4_16 */
+static int hash_compose_tab_4_17[4] =
+{1,-1,-1,0}; /* hash_compose_tab_4_17 */
+static CompEntry compose_tab_4_17[] = {
+{79, 492, 0, NULL, NULL},
+{111, 493, 0, NULL, NULL}
+}; /* compose_tab_4_17 */
+static int hash_compose_tab_4[56] =
+{-1,22,-1,-1,-1,11,13,-1,-1,0,-1,-1,-1,1,23,2,26,3,18,16,-1,-1,-1,4,17,19,-1,
+ 27,-1,5,12,-1,-1,-1,-1,-1,-1,20,-1,-1,24,6,-1,-1,-1,7,-1,8,14,9,15,21,25,-1,
+ -1,10}; /* hash_compose_tab_4 */
+static CompEntry compose_tab_4[] = {
+{65, 256, 0, NULL, NULL},
+{69, 274, 0, NULL, NULL},
+{71, 7712, 0, NULL, NULL},
+{73, 298, 0, NULL, NULL},
+{79, 332, 0, NULL, NULL},
+{85, 362, 0, NULL, NULL},
+{97, 257, 0, NULL, NULL},
+{101, 275, 0, NULL, NULL},
+{103, 7713, 0, NULL, NULL},
+{105, 299, 0, NULL, NULL},
+{111, 333, 0, NULL, NULL},
+{117, 363, 0, NULL, NULL},
+{198, 482, 0, NULL, NULL},
+{230, 483, 0, NULL, NULL},
+{775, 0, 2, compose_tab_4_14, hash_compose_tab_4_14},
+{776, 0, 4, compose_tab_4_15, hash_compose_tab_4_15},
+{803, 0, 4, compose_tab_4_16, hash_compose_tab_4_16},
+{808, 0, 2, compose_tab_4_17, hash_compose_tab_4_17},
+{913, 8121, 0, NULL, NULL},
+{921, 8153, 0, NULL, NULL},
+{933, 8169, 0, NULL, NULL},
+{945, 8113, 0, NULL, NULL},
+{953, 8145, 0, NULL, NULL},
+{965, 8161, 0, NULL, NULL},
+{1048, 1250, 0, NULL, NULL},
+{1059, 1262, 0, NULL, NULL},
+{1080, 1251, 0, NULL, NULL},
+{1091, 1263, 0, NULL, NULL}
+}; /* compose_tab_4 */
+static int hash_compose_tab_5_12[4] =
+{-1,0,1,-1}; /* hash_compose_tab_5_12 */
+static CompEntry compose_tab_5_12[] = {
+{65, 7862, 0, NULL, NULL},
+{97, 7863, 0, NULL, NULL}
+}; /* compose_tab_5_12 */
+static int hash_compose_tab_5_13[4] =
+{-1,0,1,-1}; /* hash_compose_tab_5_13 */
+static CompEntry compose_tab_5_13[] = {
+{69, 7708, 0, NULL, NULL},
+{101, 7709, 0, NULL, NULL}
+}; /* compose_tab_5_13 */
+static int hash_compose_tab_5[60] =
+{28,-1,-1,-1,-1,0,19,-1,-1,1,-1,2,29,3,14,-1,-1,-1,-1,4,20,15,-1,12,-1,5,21,
+ 13,22,23,-1,-1,-1,16,-1,-1,-1,6,-1,24,-1,7,-1,8,-1,9,17,-1,-1,-1,-1,10,25,18,
+ -1,-1,-1,11,26,27}; /* hash_compose_tab_5 */
+static CompEntry compose_tab_5[] = {
+{65, 258, 0, NULL, NULL},
+{69, 276, 0, NULL, NULL},
+{71, 286, 0, NULL, NULL},
+{73, 300, 0, NULL, NULL},
+{79, 334, 0, NULL, NULL},
+{85, 364, 0, NULL, NULL},
+{97, 259, 0, NULL, NULL},
+{101, 277, 0, NULL, NULL},
+{103, 287, 0, NULL, NULL},
+{105, 301, 0, NULL, NULL},
+{111, 335, 0, NULL, NULL},
+{117, 365, 0, NULL, NULL},
+{803, 0, 2, compose_tab_5_12, hash_compose_tab_5_12},
+{807, 0, 2, compose_tab_5_13, hash_compose_tab_5_13},
+{913, 8120, 0, NULL, NULL},
+{921, 8152, 0, NULL, NULL},
+{933, 8168, 0, NULL, NULL},
+{945, 8112, 0, NULL, NULL},
+{953, 8144, 0, NULL, NULL},
+{965, 8160, 0, NULL, NULL},
+{1040, 1232, 0, NULL, NULL},
+{1045, 1238, 0, NULL, NULL},
+{1046, 1217, 0, NULL, NULL},
+{1048, 1049, 0, NULL, NULL},
+{1059, 1038, 0, NULL, NULL},
+{1072, 1233, 0, NULL, NULL},
+{1077, 1239, 0, NULL, NULL},
+{1078, 1218, 0, NULL, NULL},
+{1080, 1081, 0, NULL, NULL},
+{1091, 1118, 0, NULL, NULL}
+}; /* compose_tab_5 */
+static int hash_compose_tab_6_36[4] =
+{1,-1,-1,0}; /* hash_compose_tab_6_36 */
+static CompEntry compose_tab_6_36[] = {
+{83, 7780, 0, NULL, NULL},
+{115, 7781, 0, NULL, NULL}
+}; /* compose_tab_6_36 */
+static int hash_compose_tab_6_38[4] =
+{1,-1,-1,0}; /* hash_compose_tab_6_38 */
+static CompEntry compose_tab_6_38[] = {
+{83, 7782, 0, NULL, NULL},
+{115, 7783, 0, NULL, NULL}
+}; /* compose_tab_6_38 */
+static int hash_compose_tab_6_39[4] =
+{1,-1,-1,0}; /* hash_compose_tab_6_39 */
+static CompEntry compose_tab_6_39[] = {
+{83, 7784, 0, NULL, NULL},
+{115, 7785, 0, NULL, NULL}
+}; /* compose_tab_6_39 */
+static int hash_compose_tab_6[80] =
+{10,-1,11,12,13,39,-1,14,15,16,17,-1,-1,-1,-1,-1,-1,-1,18,19,20,21,22,23,24,
+ -1,-1,-1,-1,25,26,-1,27,-1,28,29,30,-1,-1,31,32,33,34,-1,-1,-1,-1,-1,-1,36,
+ -1,-1,-1,-1,37,-1,-1,-1,-1,-1,38,-1,-1,35,-1,-1,0,1,2,3,4,5,6,7,-1,-1,-1,8,9,
+ -1}; /* hash_compose_tab_6 */
+static CompEntry compose_tab_6[] = {
+{66, 7682, 0, NULL, NULL},
+{67, 266, 0, NULL, NULL},
+{68, 7690, 0, NULL, NULL},
+{69, 278, 0, NULL, NULL},
+{70, 7710, 0, NULL, NULL},
+{71, 288, 0, NULL, NULL},
+{72, 7714, 0, NULL, NULL},
+{73, 304, 0, NULL, NULL},
+{77, 7744, 0, NULL, NULL},
+{78, 7748, 0, NULL, NULL},
+{80, 7766, 0, NULL, NULL},
+{82, 7768, 0, NULL, NULL},
+{83, 7776, 0, NULL, NULL},
+{84, 7786, 0, NULL, NULL},
+{87, 7814, 0, NULL, NULL},
+{88, 7818, 0, NULL, NULL},
+{89, 7822, 0, NULL, NULL},
+{90, 379, 0, NULL, NULL},
+{98, 7683, 0, NULL, NULL},
+{99, 267, 0, NULL, NULL},
+{100, 7691, 0, NULL, NULL},
+{101, 279, 0, NULL, NULL},
+{102, 7711, 0, NULL, NULL},
+{103, 289, 0, NULL, NULL},
+{104, 7715, 0, NULL, NULL},
+{109, 7745, 0, NULL, NULL},
+{110, 7749, 0, NULL, NULL},
+{112, 7767, 0, NULL, NULL},
+{114, 7769, 0, NULL, NULL},
+{115, 7777, 0, NULL, NULL},
+{116, 7787, 0, NULL, NULL},
+{119, 7815, 0, NULL, NULL},
+{120, 7819, 0, NULL, NULL},
+{121, 7823, 0, NULL, NULL},
+{122, 380, 0, NULL, NULL},
+{383, 7835, 0, NULL, NULL},
+{769, 0, 2, compose_tab_6_36, hash_compose_tab_6_36},
+{774, 784, 0, NULL, NULL},
+{780, 0, 2, compose_tab_6_38, hash_compose_tab_6_38},
+{803, 0, 2, compose_tab_6_39, hash_compose_tab_6_39}
+}; /* compose_tab_6 */
+static int hash_compose_tab_7_23[4] =
+{1,-1,-1,0}; /* hash_compose_tab_7_23 */
+static CompEntry compose_tab_7_23[] = {
+{79, 7758, 0, NULL, NULL},
+{111, 7759, 0, NULL, NULL}
+}; /* compose_tab_7_23 */
+static int hash_compose_tab_7_24[4] =
+{-1,0,1,-1}; /* hash_compose_tab_7_24 */
+static CompEntry compose_tab_7_24[] = {
+{85, 7802, 0, NULL, NULL},
+{117, 7803, 0, NULL, NULL}
+}; /* compose_tab_7_24 */
+static int hash_compose_tab_7[100] =
+{48,10,21,-1,11,12,-1,-1,-1,-1,49,13,-1,-1,-1,20,14,15,-1,16,17,18,25,-1,-1,
+ -1,-1,-1,-1,22,30,-1,-1,26,-1,-1,-1,-1,-1,-1,31,-1,-1,-1,-1,32,33,34,35,-1,
+ -1,-1,-1,27,36,-1,-1,-1,-1,37,-1,-1,-1,38,-1,0,28,39,-1,1,-1,23,2,3,24,40,-1,
+ 41,29,4,42,43,44,-1,-1,5,45,6,7,8,-1,46,-1,-1,-1,47,-1,9,-1,19}; /* hash_compose_tab_7 */
+static CompEntry compose_tab_7[] = {
+{65, 196, 0, NULL, NULL},
+{69, 203, 0, NULL, NULL},
+{72, 7718, 0, NULL, NULL},
+{73, 207, 0, NULL, NULL},
+{79, 214, 0, NULL, NULL},
+{85, 220, 0, NULL, NULL},
+{87, 7812, 0, NULL, NULL},
+{88, 7820, 0, NULL, NULL},
+{89, 376, 0, NULL, NULL},
+{97, 228, 0, NULL, NULL},
+{101, 235, 0, NULL, NULL},
+{104, 7719, 0, NULL, NULL},
+{105, 239, 0, NULL, NULL},
+{111, 246, 0, NULL, NULL},
+{116, 7831, 0, NULL, NULL},
+{117, 252, 0, NULL, NULL},
+{119, 7813, 0, NULL, NULL},
+{120, 7821, 0, NULL, NULL},
+{121, 255, 0, NULL, NULL},
+{399, 1242, 0, NULL, NULL},
+{415, 1258, 0, NULL, NULL},
+{601, 1243, 0, NULL, NULL},
+{629, 1259, 0, NULL, NULL},
+{771, 0, 2, compose_tab_7_23, hash_compose_tab_7_23},
+{772, 0, 2, compose_tab_7_24, hash_compose_tab_7_24},
+{921, 938, 0, NULL, NULL},
+{933, 939, 0, NULL, NULL},
+{953, 970, 0, NULL, NULL},
+{965, 971, 0, NULL, NULL},
+{978, 980, 0, NULL, NULL},
+{1030, 1031, 0, NULL, NULL},
+{1040, 1234, 0, NULL, NULL},
+{1045, 1025, 0, NULL, NULL},
+{1046, 1244, 0, NULL, NULL},
+{1047, 1246, 0, NULL, NULL},
+{1048, 1252, 0, NULL, NULL},
+{1054, 1254, 0, NULL, NULL},
+{1059, 1264, 0, NULL, NULL},
+{1063, 1268, 0, NULL, NULL},
+{1067, 1272, 0, NULL, NULL},
+{1072, 1235, 0, NULL, NULL},
+{1077, 1105, 0, NULL, NULL},
+{1078, 1245, 0, NULL, NULL},
+{1079, 1247, 0, NULL, NULL},
+{1080, 1253, 0, NULL, NULL},
+{1086, 1255, 0, NULL, NULL},
+{1091, 1265, 0, NULL, NULL},
+{1095, 1269, 0, NULL, NULL},
+{1099, 1273, 0, NULL, NULL},
+{1110, 1111, 0, NULL, NULL}
+}; /* compose_tab_7 */
+static int hash_compose_tab_8_12[12] =
+{-1,3,-1,5,-1,0,4,2,-1,1,-1,-1}; /* hash_compose_tab_8_12 */
+static CompEntry compose_tab_8_12[] = {
+{65, 7848, 0, NULL, NULL},
+{69, 7874, 0, NULL, NULL},
+{79, 7892, 0, NULL, NULL},
+{97, 7849, 0, NULL, NULL},
+{101, 7875, 0, NULL, NULL},
+{111, 7893, 0, NULL, NULL}
+}; /* compose_tab_8_12 */
+static int hash_compose_tab_8_13[4] =
+{-1,0,1,-1}; /* hash_compose_tab_8_13 */
+static CompEntry compose_tab_8_13[] = {
+{65, 7858, 0, NULL, NULL},
+{97, 7859, 0, NULL, NULL}
+}; /* compose_tab_8_13 */
+static int hash_compose_tab_8_14[8] =
+{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_8_14 */
+static CompEntry compose_tab_8_14[] = {
+{79, 7902, 0, NULL, NULL},
+{85, 7916, 0, NULL, NULL},
+{111, 7903, 0, NULL, NULL},
+{117, 7917, 0, NULL, NULL}
+}; /* compose_tab_8_14 */
+static int hash_compose_tab_8[30] =
+{-1,11,-1,-1,-1,0,-1,6,-1,1,-1,7,-1,2,-1,8,14,-1,-1,3,12,9,-1,-1,13,4,-1,10,
+ -1,5}; /* hash_compose_tab_8 */
+static CompEntry compose_tab_8[] = {
+{65, 7842, 0, NULL, NULL},
+{69, 7866, 0, NULL, NULL},
+{73, 7880, 0, NULL, NULL},
+{79, 7886, 0, NULL, NULL},
+{85, 7910, 0, NULL, NULL},
+{89, 7926, 0, NULL, NULL},
+{97, 7843, 0, NULL, NULL},
+{101, 7867, 0, NULL, NULL},
+{105, 7881, 0, NULL, NULL},
+{111, 7887, 0, NULL, NULL},
+{117, 7911, 0, NULL, NULL},
+{121, 7927, 0, NULL, NULL},
+{770, 0, 6, compose_tab_8_12, hash_compose_tab_8_12},
+{774, 0, 2, compose_tab_8_13, hash_compose_tab_8_13},
+{795, 0, 4, compose_tab_8_14, hash_compose_tab_8_14}
+}; /* compose_tab_8 */
+static int hash_compose_tab_9[12] =
+{-1,1,2,5,-1,0,-1,-1,-1,3,-1,4}; /* hash_compose_tab_9 */
+static CompEntry compose_tab_9[] = {
+{65, 197, 0, NULL, NULL},
+{85, 366, 0, NULL, NULL},
+{97, 229, 0, NULL, NULL},
+{117, 367, 0, NULL, NULL},
+{119, 7832, 0, NULL, NULL},
+{121, 7833, 0, NULL, NULL}
+}; /* compose_tab_9 */
+static int hash_compose_tab_10[12] =
+{-1,1,-1,2,4,-1,-1,0,-1,3,-1,5}; /* hash_compose_tab_10 */
+static CompEntry compose_tab_10[] = {
+{79, 336, 0, NULL, NULL},
+{85, 368, 0, NULL, NULL},
+{111, 337, 0, NULL, NULL},
+{117, 369, 0, NULL, NULL},
+{1059, 1266, 0, NULL, NULL},
+{1091, 1267, 0, NULL, NULL}
+}; /* compose_tab_10 */
+static int hash_compose_tab_11_33[4] =
+{-1,0,1,-1}; /* hash_compose_tab_11_33 */
+static CompEntry compose_tab_11_33[] = {
+{85, 473, 0, NULL, NULL},
+{117, 474, 0, NULL, NULL}
+}; /* compose_tab_11_33 */
+static int hash_compose_tab_11[68] =
+{2,3,-1,4,-1,5,-1,6,7,-1,8,9,-1,-1,10,11,12,13,-1,-1,-1,-1,14,-1,-1,-1,-1,-1,
+ 33,15,-1,16,17,18,31,19,-1,20,21,22,23,-1,24,25,-1,-1,26,27,28,29,32,-1,-1,
+ -1,30,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,1}; /* hash_compose_tab_11 */
+static CompEntry compose_tab_11[] = {
+{65, 461, 0, NULL, NULL},
+{67, 268, 0, NULL, NULL},
+{68, 270, 0, NULL, NULL},
+{69, 282, 0, NULL, NULL},
+{71, 486, 0, NULL, NULL},
+{73, 463, 0, NULL, NULL},
+{75, 488, 0, NULL, NULL},
+{76, 317, 0, NULL, NULL},
+{78, 327, 0, NULL, NULL},
+{79, 465, 0, NULL, NULL},
+{82, 344, 0, NULL, NULL},
+{83, 352, 0, NULL, NULL},
+{84, 356, 0, NULL, NULL},
+{85, 467, 0, NULL, NULL},
+{90, 381, 0, NULL, NULL},
+{97, 462, 0, NULL, NULL},
+{99, 269, 0, NULL, NULL},
+{100, 271, 0, NULL, NULL},
+{101, 283, 0, NULL, NULL},
+{103, 487, 0, NULL, NULL},
+{105, 464, 0, NULL, NULL},
+{106, 496, 0, NULL, NULL},
+{107, 489, 0, NULL, NULL},
+{108, 318, 0, NULL, NULL},
+{110, 328, 0, NULL, NULL},
+{111, 466, 0, NULL, NULL},
+{114, 345, 0, NULL, NULL},
+{115, 353, 0, NULL, NULL},
+{116, 357, 0, NULL, NULL},
+{117, 468, 0, NULL, NULL},
+{122, 382, 0, NULL, NULL},
+{439, 494, 0, NULL, NULL},
+{658, 495, 0, NULL, NULL},
+{776, 0, 2, compose_tab_11_33, hash_compose_tab_11_33}
+}; /* compose_tab_11 */
+static int hash_compose_tab_12_1[4] =
+{-1,0,1,-1}; /* hash_compose_tab_12_1 */
+static CompEntry compose_tab_12_1[] = {
+{953, 912, 0, NULL, NULL},
+{965, 944, 0, NULL, NULL}
+}; /* compose_tab_12_1 */
+static int hash_compose_tab_12[34] =
+{11,4,12,5,-1,-1,-1,13,-1,6,-1,-1,-1,14,-1,7,-1,15,-1,8,-1,-1,-1,-1,-1,-1,16,
+ 9,1,2,-1,10,0,3}; /* hash_compose_tab_12 */
+static CompEntry compose_tab_12[] = {
+{168, 901, 0, NULL, NULL},
+{776, 0, 2, compose_tab_12_1, hash_compose_tab_12_1},
+{913, 902, 0, NULL, NULL},
+{917, 904, 0, NULL, NULL},
+{919, 905, 0, NULL, NULL},
+{921, 906, 0, NULL, NULL},
+{927, 908, 0, NULL, NULL},
+{933, 910, 0, NULL, NULL},
+{937, 911, 0, NULL, NULL},
+{945, 940, 0, NULL, NULL},
+{949, 941, 0, NULL, NULL},
+{951, 942, 0, NULL, NULL},
+{953, 943, 0, NULL, NULL},
+{959, 972, 0, NULL, NULL},
+{965, 973, 0, NULL, NULL},
+{969, 974, 0, NULL, NULL},
+{978, 979, 0, NULL, NULL}
+}; /* compose_tab_12 */
+static int hash_compose_tab_13[28] =
+{-1,5,10,-1,-1,11,-1,-1,-1,0,-1,-1,-1,1,6,-1,-1,2,7,-1,12,8,13,3,-1,-1,4,9}; /* hash_compose_tab_13 */
+static CompEntry compose_tab_13[] = {
+{65, 512, 0, NULL, NULL},
+{69, 516, 0, NULL, NULL},
+{73, 520, 0, NULL, NULL},
+{79, 524, 0, NULL, NULL},
+{82, 528, 0, NULL, NULL},
+{85, 532, 0, NULL, NULL},
+{97, 513, 0, NULL, NULL},
+{101, 517, 0, NULL, NULL},
+{105, 521, 0, NULL, NULL},
+{111, 525, 0, NULL, NULL},
+{114, 529, 0, NULL, NULL},
+{117, 533, 0, NULL, NULL},
+{1140, 1142, 0, NULL, NULL},
+{1141, 1143, 0, NULL, NULL}
+}; /* compose_tab_13 */
+static int hash_compose_tab_14[24] =
+{-1,2,6,-1,-1,7,-1,3,-1,8,4,-1,-1,5,-1,9,-1,0,10,-1,-1,1,11,-1}; /* hash_compose_tab_14 */
+static CompEntry compose_tab_14[] = {
+{65, 514, 0, NULL, NULL},
+{69, 518, 0, NULL, NULL},
+{73, 522, 0, NULL, NULL},
+{79, 526, 0, NULL, NULL},
+{82, 530, 0, NULL, NULL},
+{85, 534, 0, NULL, NULL},
+{97, 515, 0, NULL, NULL},
+{101, 519, 0, NULL, NULL},
+{105, 523, 0, NULL, NULL},
+{111, 527, 0, NULL, NULL},
+{114, 531, 0, NULL, NULL},
+{117, 535, 0, NULL, NULL}
+}; /* compose_tab_14 */
+static int hash_compose_tab_15_0[12] =
+{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_15_0 */
+static CompEntry compose_tab_15_0[] = {
+{913, 8072, 0, NULL, NULL},
+{919, 8088, 0, NULL, NULL},
+{937, 8104, 0, NULL, NULL},
+{945, 8064, 0, NULL, NULL},
+{951, 8080, 0, NULL, NULL},
+{969, 8096, 0, NULL, NULL}
+}; /* compose_tab_15_0 */
+static int hash_compose_tab_15[30] =
+{-1,12,-1,-1,-1,13,-1,6,-1,14,-1,-1,-1,1,-1,7,-1,2,-1,3,8,4,9,10,-1,-1,-1,0,5,
+ 11}; /* hash_compose_tab_15 */
+static CompEntry compose_tab_15[] = {
+{837, 0, 6, compose_tab_15_0, hash_compose_tab_15_0},
+{913, 7944, 0, NULL, NULL},
+{917, 7960, 0, NULL, NULL},
+{919, 7976, 0, NULL, NULL},
+{921, 7992, 0, NULL, NULL},
+{927, 8008, 0, NULL, NULL},
+{937, 8040, 0, NULL, NULL},
+{945, 7936, 0, NULL, NULL},
+{949, 7952, 0, NULL, NULL},
+{951, 7968, 0, NULL, NULL},
+{953, 7984, 0, NULL, NULL},
+{959, 8000, 0, NULL, NULL},
+{961, 8164, 0, NULL, NULL},
+{965, 8016, 0, NULL, NULL},
+{969, 8032, 0, NULL, NULL}
+}; /* compose_tab_15 */
+static int hash_compose_tab_16_0[12] =
+{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_16_0 */
+static CompEntry compose_tab_16_0[] = {
+{913, 8073, 0, NULL, NULL},
+{919, 8089, 0, NULL, NULL},
+{937, 8105, 0, NULL, NULL},
+{945, 8065, 0, NULL, NULL},
+{951, 8081, 0, NULL, NULL},
+{969, 8097, 0, NULL, NULL}
+}; /* compose_tab_16_0 */
+static int hash_compose_tab_16[34] =
+{11,3,12,4,-1,-1,-1,13,-1,5,14,6,-1,15,-1,7,-1,16,-1,8,-1,0,-1,-1,-1,-1,-1,9,
+ -1,1,-1,10,-1,2}; /* hash_compose_tab_16 */
+static CompEntry compose_tab_16[] = {
+{837, 0, 6, compose_tab_16_0, hash_compose_tab_16_0},
+{913, 7945, 0, NULL, NULL},
+{917, 7961, 0, NULL, NULL},
+{919, 7977, 0, NULL, NULL},
+{921, 7993, 0, NULL, NULL},
+{927, 8009, 0, NULL, NULL},
+{929, 8172, 0, NULL, NULL},
+{933, 8025, 0, NULL, NULL},
+{937, 8041, 0, NULL, NULL},
+{945, 7937, 0, NULL, NULL},
+{949, 7953, 0, NULL, NULL},
+{951, 7969, 0, NULL, NULL},
+{953, 7985, 0, NULL, NULL},
+{959, 8001, 0, NULL, NULL},
+{961, 8165, 0, NULL, NULL},
+{965, 8017, 0, NULL, NULL},
+{969, 8033, 0, NULL, NULL}
+}; /* compose_tab_16 */
+static int hash_compose_tab_17[8] =
+{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_17 */
+static CompEntry compose_tab_17[] = {
+{79, 416, 0, NULL, NULL},
+{85, 431, 0, NULL, NULL},
+{111, 417, 0, NULL, NULL},
+{117, 432, 0, NULL, NULL}
+}; /* compose_tab_17 */
+static int hash_compose_tab_18_38[8] =
+{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_18_38 */
+static CompEntry compose_tab_18_38[] = {
+{79, 7906, 0, NULL, NULL},
+{85, 7920, 0, NULL, NULL},
+{111, 7907, 0, NULL, NULL},
+{117, 7921, 0, NULL, NULL}
+}; /* compose_tab_18_38 */
+static int hash_compose_tab_18[78] =
+{9,10,-1,-1,11,12,13,14,15,16,-1,17,18,-1,-1,38,-1,-1,-1,19,20,-1,21,22,-1,-1,
+ 23,24,-1,25,26,27,28,29,-1,-1,30,31,32,33,34,35,-1,36,37,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,-1,2,3,-1,-1,4,5,-1,6,7,8}; /* hash_compose_tab_18 */
+static CompEntry compose_tab_18[] = {
+{65, 7840, 0, NULL, NULL},
+{66, 7684, 0, NULL, NULL},
+{68, 7692, 0, NULL, NULL},
+{69, 7864, 0, NULL, NULL},
+{72, 7716, 0, NULL, NULL},
+{73, 7882, 0, NULL, NULL},
+{75, 7730, 0, NULL, NULL},
+{76, 7734, 0, NULL, NULL},
+{77, 7746, 0, NULL, NULL},
+{78, 7750, 0, NULL, NULL},
+{79, 7884, 0, NULL, NULL},
+{82, 7770, 0, NULL, NULL},
+{83, 7778, 0, NULL, NULL},
+{84, 7788, 0, NULL, NULL},
+{85, 7908, 0, NULL, NULL},
+{86, 7806, 0, NULL, NULL},
+{87, 7816, 0, NULL, NULL},
+{89, 7924, 0, NULL, NULL},
+{90, 7826, 0, NULL, NULL},
+{97, 7841, 0, NULL, NULL},
+{98, 7685, 0, NULL, NULL},
+{100, 7693, 0, NULL, NULL},
+{101, 7865, 0, NULL, NULL},
+{104, 7717, 0, NULL, NULL},
+{105, 7883, 0, NULL, NULL},
+{107, 7731, 0, NULL, NULL},
+{108, 7735, 0, NULL, NULL},
+{109, 7747, 0, NULL, NULL},
+{110, 7751, 0, NULL, NULL},
+{111, 7885, 0, NULL, NULL},
+{114, 7771, 0, NULL, NULL},
+{115, 7779, 0, NULL, NULL},
+{116, 7789, 0, NULL, NULL},
+{117, 7909, 0, NULL, NULL},
+{118, 7807, 0, NULL, NULL},
+{119, 7817, 0, NULL, NULL},
+{121, 7925, 0, NULL, NULL},
+{122, 7827, 0, NULL, NULL},
+{795, 0, 4, compose_tab_18_38, hash_compose_tab_18_38}
+}; /* compose_tab_18 */
+static int hash_compose_tab_19[4] =
+{-1,0,1,-1}; /* hash_compose_tab_19 */
+static CompEntry compose_tab_19[] = {
+{85, 7794, 0, NULL, NULL},
+{117, 7795, 0, NULL, NULL}
+}; /* compose_tab_19 */
+static int hash_compose_tab_20[4] =
+{-1,0,1,-1}; /* hash_compose_tab_20 */
+static CompEntry compose_tab_20[] = {
+{65, 7680, 0, NULL, NULL},
+{97, 7681, 0, NULL, NULL}
+}; /* compose_tab_20 */
+static int hash_compose_tab_21[40] =
+{-1,-1,7,8,9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10,11,-1,-1,12,13,-1,
+ -1,0,1,14,15,2,3,16,17,4,5,18,6,19}; /* hash_compose_tab_21 */
+static CompEntry compose_tab_21[] = {
+{67, 199, 0, NULL, NULL},
+{68, 7696, 0, NULL, NULL},
+{71, 290, 0, NULL, NULL},
+{72, 7720, 0, NULL, NULL},
+{75, 310, 0, NULL, NULL},
+{76, 315, 0, NULL, NULL},
+{78, 325, 0, NULL, NULL},
+{82, 342, 0, NULL, NULL},
+{83, 350, 0, NULL, NULL},
+{84, 354, 0, NULL, NULL},
+{99, 231, 0, NULL, NULL},
+{100, 7697, 0, NULL, NULL},
+{103, 291, 0, NULL, NULL},
+{104, 7721, 0, NULL, NULL},
+{107, 311, 0, NULL, NULL},
+{108, 316, 0, NULL, NULL},
+{110, 326, 0, NULL, NULL},
+{114, 343, 0, NULL, NULL},
+{115, 351, 0, NULL, NULL},
+{116, 355, 0, NULL, NULL}
+}; /* compose_tab_21 */
+static int hash_compose_tab_22[20] =
+{-1,6,-1,-1,-1,0,4,7,-1,1,-1,8,-1,2,-1,-1,-1,5,9,3}; /* hash_compose_tab_22 */
+static CompEntry compose_tab_22[] = {
+{65, 260, 0, NULL, NULL},
+{69, 280, 0, NULL, NULL},
+{73, 302, 0, NULL, NULL},
+{79, 490, 0, NULL, NULL},
+{85, 370, 0, NULL, NULL},
+{97, 261, 0, NULL, NULL},
+{101, 281, 0, NULL, NULL},
+{105, 303, 0, NULL, NULL},
+{111, 491, 0, NULL, NULL},
+{117, 371, 0, NULL, NULL}
+}; /* compose_tab_22 */
+static int hash_compose_tab_23[24] =
+{-1,-1,-1,-1,2,6,3,7,-1,-1,-1,-1,4,5,8,9,-1,-1,-1,-1,0,1,10,11}; /* hash_compose_tab_23 */
+static CompEntry compose_tab_23[] = {
+{68, 7698, 0, NULL, NULL},
+{69, 7704, 0, NULL, NULL},
+{76, 7740, 0, NULL, NULL},
+{78, 7754, 0, NULL, NULL},
+{84, 7792, 0, NULL, NULL},
+{85, 7798, 0, NULL, NULL},
+{100, 7699, 0, NULL, NULL},
+{101, 7705, 0, NULL, NULL},
+{108, 7741, 0, NULL, NULL},
+{110, 7755, 0, NULL, NULL},
+{116, 7793, 0, NULL, NULL},
+{117, 7799, 0, NULL, NULL}
+}; /* compose_tab_23 */
+static int hash_compose_tab_24[4] =
+{0,1,-1,-1}; /* hash_compose_tab_24 */
+static CompEntry compose_tab_24[] = {
+{72, 7722, 0, NULL, NULL},
+{104, 7723, 0, NULL, NULL}
+}; /* compose_tab_24 */
+static int hash_compose_tab_25[12] =
+{-1,1,2,-1,-1,3,-1,-1,-1,0,4,5}; /* hash_compose_tab_25 */
+static CompEntry compose_tab_25[] = {
+{69, 7706, 0, NULL, NULL},
+{73, 7724, 0, NULL, NULL},
+{85, 7796, 0, NULL, NULL},
+{101, 7707, 0, NULL, NULL},
+{105, 7725, 0, NULL, NULL},
+{117, 7797, 0, NULL, NULL}
+}; /* compose_tab_25 */
+static int hash_compose_tab_26[34] =
+{1,-1,10,-1,-1,11,12,2,3,13,4,-1,14,-1,5,15,6,-1,-1,-1,16,-1,7,-1,-1,-1,-1,-1,
+ -1,-1,8,-1,0,9}; /* hash_compose_tab_26 */
+static CompEntry compose_tab_26[] = {
+{66, 7686, 0, NULL, NULL},
+{68, 7694, 0, NULL, NULL},
+{75, 7732, 0, NULL, NULL},
+{76, 7738, 0, NULL, NULL},
+{78, 7752, 0, NULL, NULL},
+{82, 7774, 0, NULL, NULL},
+{84, 7790, 0, NULL, NULL},
+{90, 7828, 0, NULL, NULL},
+{98, 7687, 0, NULL, NULL},
+{100, 7695, 0, NULL, NULL},
+{104, 7830, 0, NULL, NULL},
+{107, 7733, 0, NULL, NULL},
+{108, 7739, 0, NULL, NULL},
+{110, 7753, 0, NULL, NULL},
+{114, 7775, 0, NULL, NULL},
+{116, 7791, 0, NULL, NULL},
+{122, 7829, 0, NULL, NULL}
+}; /* compose_tab_26 */
+static int hash_compose_tab_27_1[4] =
+{-1,0,1,-1}; /* hash_compose_tab_27_1 */
+static CompEntry compose_tab_27_1[] = {
+{953, 8151, 0, NULL, NULL},
+{965, 8167, 0, NULL, NULL}
+}; /* compose_tab_27_1 */
+static int hash_compose_tab_27_2_0[12] =
+{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_27_2_0 */
+static CompEntry compose_tab_27_2_0[] = {
+{913, 8078, 0, NULL, NULL},
+{919, 8094, 0, NULL, NULL},
+{937, 8110, 0, NULL, NULL},
+{945, 8070, 0, NULL, NULL},
+{951, 8086, 0, NULL, NULL},
+{969, 8102, 0, NULL, NULL}
+}; /* compose_tab_27_2_0 */
+static int hash_compose_tab_27_2[20] =
+{-1,3,-1,-1,-1,5,8,-1,-1,9,-1,6,-1,1,7,-1,-1,0,4,2}; /* hash_compose_tab_27_2 */
+static CompEntry compose_tab_27_2[] = {
+{837, 0, 6, compose_tab_27_2_0, hash_compose_tab_27_2_0},
+{913, 7950, 0, NULL, NULL},
+{919, 7982, 0, NULL, NULL},
+{921, 7998, 0, NULL, NULL},
+{937, 8046, 0, NULL, NULL},
+{945, 7942, 0, NULL, NULL},
+{951, 7974, 0, NULL, NULL},
+{953, 7990, 0, NULL, NULL},
+{965, 8022, 0, NULL, NULL},
+{969, 8038, 0, NULL, NULL}
+}; /* compose_tab_27_2 */
+static int hash_compose_tab_27_3_0[12] =
+{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_27_3_0 */
+static CompEntry compose_tab_27_3_0[] = {
+{913, 8079, 0, NULL, NULL},
+{919, 8095, 0, NULL, NULL},
+{937, 8111, 0, NULL, NULL},
+{945, 8071, 0, NULL, NULL},
+{951, 8087, 0, NULL, NULL},
+{969, 8103, 0, NULL, NULL}
+}; /* compose_tab_27_3_0 */
+static int hash_compose_tab_27_3[22] =
+{-1,0,10,-1,-1,7,-1,8,-1,4,-1,1,-1,5,-1,-1,-1,2,-1,3,9,6}; /* hash_compose_tab_27_3 */
+static CompEntry compose_tab_27_3[] = {
+{837, 0, 6, compose_tab_27_3_0, hash_compose_tab_27_3_0},
+{913, 7951, 0, NULL, NULL},
+{919, 7983, 0, NULL, NULL},
+{921, 7999, 0, NULL, NULL},
+{933, 8031, 0, NULL, NULL},
+{937, 8047, 0, NULL, NULL},
+{945, 7943, 0, NULL, NULL},
+{951, 7975, 0, NULL, NULL},
+{953, 7991, 0, NULL, NULL},
+{965, 8023, 0, NULL, NULL},
+{969, 8039, 0, NULL, NULL}
+}; /* compose_tab_27_3 */
+static int hash_compose_tab_27_4[6] =
+{-1,-1,-1,0,1,2}; /* hash_compose_tab_27_4 */
+static CompEntry compose_tab_27_4[] = {
+{945, 8119, 0, NULL, NULL},
+{951, 8135, 0, NULL, NULL},
+{969, 8183, 0, NULL, NULL}
+}; /* compose_tab_27_4 */
+static int hash_compose_tab_27[24] =
+{0,-1,-1,-1,-1,8,11,-1,1,5,9,-1,-1,-1,-1,6,10,7,-1,2,3,4,-1,-1}; /* hash_compose_tab_27 */
+static CompEntry compose_tab_27[] = {
+{168, 8129, 0, NULL, NULL},
+{776, 0, 2, compose_tab_27_1, hash_compose_tab_27_1},
+{787, 0, 10, compose_tab_27_2, hash_compose_tab_27_2},
+{788, 0, 11, compose_tab_27_3, hash_compose_tab_27_3},
+{837, 0, 3, compose_tab_27_4, hash_compose_tab_27_4},
+{945, 8118, 0, NULL, NULL},
+{951, 8134, 0, NULL, NULL},
+{953, 8150, 0, NULL, NULL},
+{965, 8166, 0, NULL, NULL},
+{969, 8182, 0, NULL, NULL},
+{8127, 8143, 0, NULL, NULL},
+{8190, 8159, 0, NULL, NULL}
+}; /* compose_tab_27 */
+static int hash_compose_tab_28[12] =
+{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_28 */
+static CompEntry compose_tab_28[] = {
+{913, 8124, 0, NULL, NULL},
+{919, 8140, 0, NULL, NULL},
+{937, 8188, 0, NULL, NULL},
+{945, 8115, 0, NULL, NULL},
+{951, 8131, 0, NULL, NULL},
+{969, 8179, 0, NULL, NULL}
+}; /* compose_tab_28 */
+static int hash_compose_tab_29[4] =
+{0,-1,1,-1}; /* hash_compose_tab_29 */
+static CompEntry compose_tab_29[] = {
+{1488, 64302, 0, NULL, NULL},
+{1522, 64287, 0, NULL, NULL}
+}; /* compose_tab_29 */
+static int hash_compose_tab_30[2] =
+{0,-1}; /* hash_compose_tab_30 */
+static CompEntry compose_tab_30[] = {
+{1488, 64303, 0, NULL, NULL}
+}; /* compose_tab_30 */
+static int hash_compose_tab_31[2] =
+{-1,0}; /* hash_compose_tab_31 */
+static CompEntry compose_tab_31[] = {
+{1493, 64331, 0, NULL, NULL}
+}; /* compose_tab_31 */
+static int hash_compose_tab_32[44] =
+{7,8,9,10,11,-1,12,-1,13,14,-1,15,16,-1,17,18,19,20,21,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,-1}; /* hash_compose_tab_32 */
+static CompEntry compose_tab_32[] = {
+{1488, 64304, 0, NULL, NULL},
+{1489, 64305, 0, NULL, NULL},
+{1490, 64306, 0, NULL, NULL},
+{1491, 64307, 0, NULL, NULL},
+{1492, 64308, 0, NULL, NULL},
+{1493, 64309, 0, NULL, NULL},
+{1494, 64310, 0, NULL, NULL},
+{1496, 64312, 0, NULL, NULL},
+{1497, 64313, 0, NULL, NULL},
+{1498, 64314, 0, NULL, NULL},
+{1499, 64315, 0, NULL, NULL},
+{1500, 64316, 0, NULL, NULL},
+{1502, 64318, 0, NULL, NULL},
+{1504, 64320, 0, NULL, NULL},
+{1505, 64321, 0, NULL, NULL},
+{1507, 64323, 0, NULL, NULL},
+{1508, 64324, 0, NULL, NULL},
+{1510, 64326, 0, NULL, NULL},
+{1511, 64327, 0, NULL, NULL},
+{1512, 64328, 0, NULL, NULL},
+{1513, 64329, 0, NULL, NULL},
+{1514, 64330, 0, NULL, NULL}
+}; /* compose_tab_32 */
+static int hash_compose_tab_33[6] =
+{-1,0,2,-1,-1,1}; /* hash_compose_tab_33 */
+static CompEntry compose_tab_33[] = {
+{1489, 64332, 0, NULL, NULL},
+{1499, 64333, 0, NULL, NULL},
+{1508, 64334, 0, NULL, NULL}
+}; /* compose_tab_33 */
+static int hash_compose_tab_34_0[2] =
+{-1,0}; /* hash_compose_tab_34_0 */
+static CompEntry compose_tab_34_0[] = {
+{1513, 64300, 0, NULL, NULL}
+}; /* compose_tab_34_0 */
+static int hash_compose_tab_34[4] =
+{0,1,-1,-1}; /* hash_compose_tab_34 */
+static CompEntry compose_tab_34[] = {
+{1468, 0, 1, compose_tab_34_0, hash_compose_tab_34_0},
+{1513, 64298, 0, NULL, NULL}
+}; /* compose_tab_34 */
+static int hash_compose_tab_35_0[2] =
+{-1,0}; /* hash_compose_tab_35_0 */
+static CompEntry compose_tab_35_0[] = {
+{1513, 64301, 0, NULL, NULL}
+}; /* compose_tab_35_0 */
+static int hash_compose_tab_35[4] =
+{0,1,-1,-1}; /* hash_compose_tab_35 */
+static CompEntry compose_tab_35[] = {
+{1468, 0, 1, compose_tab_35_0, hash_compose_tab_35_0},
+{1513, 64299, 0, NULL, NULL}
+}; /* compose_tab_35 */
+static int hash_compose_tab_36[22] =
+{3,10,-1,-1,-1,4,5,-1,-1,-1,-1,-1,6,-1,-1,0,1,2,7,8,9,-1}; /* hash_compose_tab_36 */
+static CompEntry compose_tab_36[] = {
+{2325, 2392, 0, NULL, NULL},
+{2326, 2393, 0, NULL, NULL},
+{2327, 2394, 0, NULL, NULL},
+{2332, 2395, 0, NULL, NULL},
+{2337, 2396, 0, NULL, NULL},
+{2338, 2397, 0, NULL, NULL},
+{2344, 2345, 0, NULL, NULL},
+{2347, 2398, 0, NULL, NULL},
+{2351, 2399, 0, NULL, NULL},
+{2352, 2353, 0, NULL, NULL},
+{2355, 2356, 0, NULL, NULL}
+}; /* compose_tab_36 */
+static int hash_compose_tab_37[8] =
+{-1,0,1,-1,2,-1,-1,3}; /* hash_compose_tab_37 */
+static CompEntry compose_tab_37[] = {
+{2465, 2524, 0, NULL, NULL},
+{2466, 2525, 0, NULL, NULL},
+{2476, 2480, 0, NULL, NULL},
+{2479, 2527, 0, NULL, NULL}
+}; /* compose_tab_37 */
+static int hash_compose_tab_38[2] =
+{-1,0}; /* hash_compose_tab_38 */
+static CompEntry compose_tab_38[] = {
+{2503, 2507, 0, NULL, NULL}
+}; /* compose_tab_38 */
+static int hash_compose_tab_39[2] =
+{-1,0}; /* hash_compose_tab_39 */
+static CompEntry compose_tab_39[] = {
+{2503, 2508, 0, NULL, NULL}
+}; /* compose_tab_39 */
+static int hash_compose_tab_40[10] =
+{-1,-1,0,1,3,4,-1,-1,2,-1}; /* hash_compose_tab_40 */
+static CompEntry compose_tab_40[] = {
+{2582, 2649, 0, NULL, NULL},
+{2583, 2650, 0, NULL, NULL},
+{2588, 2651, 0, NULL, NULL},
+{2593, 2652, 0, NULL, NULL},
+{2603, 2654, 0, NULL, NULL}
+}; /* compose_tab_40 */
+static int hash_compose_tab_41[6] =
+{1,2,-1,-1,-1,0}; /* hash_compose_tab_41 */
+static CompEntry compose_tab_41[] = {
+{2849, 2908, 0, NULL, NULL},
+{2850, 2909, 0, NULL, NULL},
+{2863, 2911, 0, NULL, NULL}
+}; /* compose_tab_41 */
+static int hash_compose_tab_42[2] =
+{-1,0}; /* hash_compose_tab_42 */
+static CompEntry compose_tab_42[] = {
+{2887, 2891, 0, NULL, NULL}
+}; /* compose_tab_42 */
+static int hash_compose_tab_43[2] =
+{-1,0}; /* hash_compose_tab_43 */
+static CompEntry compose_tab_43[] = {
+{2887, 2888, 0, NULL, NULL}
+}; /* compose_tab_43 */
+static int hash_compose_tab_44[2] =
+{-1,0}; /* hash_compose_tab_44 */
+static CompEntry compose_tab_44[] = {
+{2887, 2892, 0, NULL, NULL}
+}; /* compose_tab_44 */
+static int hash_compose_tab_45[4] =
+{-1,-1,0,1}; /* hash_compose_tab_45 */
+static CompEntry compose_tab_45[] = {
+{3014, 3018, 0, NULL, NULL},
+{3015, 3019, 0, NULL, NULL}
+}; /* compose_tab_45 */
+static int hash_compose_tab_46[4] =
+{-1,-1,0,1}; /* hash_compose_tab_46 */
+static CompEntry compose_tab_46[] = {
+{2962, 2964, 0, NULL, NULL},
+{3014, 3020, 0, NULL, NULL}
+}; /* compose_tab_46 */
+static int hash_compose_tab_47[2] =
+{0,-1}; /* hash_compose_tab_47 */
+static CompEntry compose_tab_47[] = {
+{3142, 3144, 0, NULL, NULL}
+}; /* compose_tab_47 */
+static int hash_compose_tab_48[2] =
+{0,-1}; /* hash_compose_tab_48 */
+static CompEntry compose_tab_48[] = {
+{3270, 3274, 0, NULL, NULL}
+}; /* compose_tab_48 */
+static int hash_compose_tab_49_1[2] =
+{0,-1}; /* hash_compose_tab_49_1 */
+static CompEntry compose_tab_49_1[] = {
+{3270, 3275, 0, NULL, NULL}
+}; /* compose_tab_49_1 */
+static int hash_compose_tab_49[6] =
+{2,-1,1,-1,-1,0}; /* hash_compose_tab_49 */
+static CompEntry compose_tab_49[] = {
+{3263, 3264, 0, NULL, NULL},
+{3266, 0, 1, compose_tab_49_1, hash_compose_tab_49_1},
+{3270, 3271, 0, NULL, NULL}
+}; /* compose_tab_49 */
+static int hash_compose_tab_50[2] =
+{0,-1}; /* hash_compose_tab_50 */
+static CompEntry compose_tab_50[] = {
+{3270, 3272, 0, NULL, NULL}
+}; /* compose_tab_50 */
+static int hash_compose_tab_51[4] =
+{-1,-1,0,1}; /* hash_compose_tab_51 */
+static CompEntry compose_tab_51[] = {
+{3398, 3402, 0, NULL, NULL},
+{3399, 3403, 0, NULL, NULL}
+}; /* compose_tab_51 */
+static int hash_compose_tab_52[2] =
+{0,-1}; /* hash_compose_tab_52 */
+static CompEntry compose_tab_52[] = {
+{3398, 3404, 0, NULL, NULL}
+}; /* compose_tab_52 */
+static int hash_compose_tab_53[2] =
+{-1,0}; /* hash_compose_tab_53 */
+static CompEntry compose_tab_53[] = {
+{3661, 3635, 0, NULL, NULL}
+}; /* compose_tab_53 */
+static int hash_compose_tab_54[2] =
+{-1,0}; /* hash_compose_tab_54 */
+static CompEntry compose_tab_54[] = {
+{3789, 3763, 0, NULL, NULL}
+}; /* compose_tab_54 */
+static int hash_compose_tab_55_2[4] =
+{-1,-1,0,1}; /* hash_compose_tab_55_2 */
+static CompEntry compose_tab_55_2[] = {
+{4018, 3959, 0, NULL, NULL},
+{4019, 3961, 0, NULL, NULL}
+}; /* compose_tab_55_2 */
+static int hash_compose_tab_55[6] =
+{0,-1,1,2,-1,-1}; /* hash_compose_tab_55 */
+static CompEntry compose_tab_55[] = {
+{3954, 3955, 0, NULL, NULL},
+{3956, 3957, 0, NULL, NULL},
+{3968, 0, 2, compose_tab_55_2, hash_compose_tab_55_2}
+}; /* compose_tab_55 */
+static int hash_compose_tab_56[4] =
+{-1,-1,0,1}; /* hash_compose_tab_56 */
+static CompEntry compose_tab_56[] = {
+{4018, 3958, 0, NULL, NULL},
+{4019, 3960, 0, NULL, NULL}
+}; /* compose_tab_56 */
+static int hash_compose_tab_57[4] =
+{0,1,-1,-1}; /* hash_compose_tab_57 */
+static CompEntry compose_tab_57[] = {
+{3904, 3945, 0, NULL, NULL},
+{3984, 4025, 0, NULL, NULL}
+}; /* compose_tab_57 */
+static int hash_compose_tab_58[20] =
+{-1,2,7,-1,-1,-1,0,3,5,8,-1,4,9,-1,-1,-1,1,6,-1,-1}; /* hash_compose_tab_58 */
+static CompEntry compose_tab_58[] = {
+{3906, 3907, 0, NULL, NULL},
+{3916, 3917, 0, NULL, NULL},
+{3921, 3922, 0, NULL, NULL},
+{3926, 3927, 0, NULL, NULL},
+{3931, 3932, 0, NULL, NULL},
+{3986, 3987, 0, NULL, NULL},
+{3996, 3997, 0, NULL, NULL},
+{4001, 4002, 0, NULL, NULL},
+{4006, 4007, 0, NULL, NULL},
+{4011, 4012, 0, NULL, NULL}
+}; /* compose_tab_58 */
+static int hash_compose_tab_59[96] =
+{33,12,34,-1,13,35,14,36,15,37,-1,-1,-1,-1,-1,16,38,-1,17,39,-1,18,40,-1,19,
+ 41,-1,20,42,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,43,44,45,
+ 46,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,47,-1,-1,-1,-1,-1,-1,-1,0,22,-1,-1,-1,1,
+ 23,2,24,3,25,4,26,5,27,6,28,7,29,8,30,9,31,10,32,11}; /* hash_compose_tab_59 */
+static CompEntry compose_tab_59[] = {
+{12358, 12436, 0, NULL, NULL},
+{12363, 12364, 0, NULL, NULL},
+{12365, 12366, 0, NULL, NULL},
+{12367, 12368, 0, NULL, NULL},
+{12369, 12370, 0, NULL, NULL},
+{12371, 12372, 0, NULL, NULL},
+{12373, 12374, 0, NULL, NULL},
+{12375, 12376, 0, NULL, NULL},
+{12377, 12378, 0, NULL, NULL},
+{12379, 12380, 0, NULL, NULL},
+{12381, 12382, 0, NULL, NULL},
+{12383, 12384, 0, NULL, NULL},
+{12385, 12386, 0, NULL, NULL},
+{12388, 12389, 0, NULL, NULL},
+{12390, 12391, 0, NULL, NULL},
+{12392, 12393, 0, NULL, NULL},
+{12399, 12400, 0, NULL, NULL},
+{12402, 12403, 0, NULL, NULL},
+{12405, 12406, 0, NULL, NULL},
+{12408, 12409, 0, NULL, NULL},
+{12411, 12412, 0, NULL, NULL},
+{12445, 12446, 0, NULL, NULL},
+{12454, 12532, 0, NULL, NULL},
+{12459, 12460, 0, NULL, NULL},
+{12461, 12462, 0, NULL, NULL},
+{12463, 12464, 0, NULL, NULL},
+{12465, 12466, 0, NULL, NULL},
+{12467, 12468, 0, NULL, NULL},
+{12469, 12470, 0, NULL, NULL},
+{12471, 12472, 0, NULL, NULL},
+{12473, 12474, 0, NULL, NULL},
+{12475, 12476, 0, NULL, NULL},
+{12477, 12478, 0, NULL, NULL},
+{12479, 12480, 0, NULL, NULL},
+{12481, 12482, 0, NULL, NULL},
+{12484, 12485, 0, NULL, NULL},
+{12486, 12487, 0, NULL, NULL},
+{12488, 12489, 0, NULL, NULL},
+{12495, 12496, 0, NULL, NULL},
+{12498, 12499, 0, NULL, NULL},
+{12501, 12502, 0, NULL, NULL},
+{12504, 12505, 0, NULL, NULL},
+{12507, 12508, 0, NULL, NULL},
+{12527, 12535, 0, NULL, NULL},
+{12528, 12536, 0, NULL, NULL},
+{12529, 12537, 0, NULL, NULL},
+{12530, 12538, 0, NULL, NULL},
+{12541, 12542, 0, NULL, NULL}
+}; /* compose_tab_59 */
+static int hash_compose_tab_60[20] =
+{-1,7,1,-1,8,2,-1,9,3,-1,-1,4,-1,-1,-1,5,-1,-1,6,0}; /* hash_compose_tab_60 */
+static CompEntry compose_tab_60[] = {
+{12399, 12401, 0, NULL, NULL},
+{12402, 12404, 0, NULL, NULL},
+{12405, 12407, 0, NULL, NULL},
+{12408, 12410, 0, NULL, NULL},
+{12411, 12413, 0, NULL, NULL},
+{12495, 12497, 0, NULL, NULL},
+{12498, 12500, 0, NULL, NULL},
+{12501, 12503, 0, NULL, NULL},
+{12504, 12506, 0, NULL, NULL},
+{12507, 12509, 0, NULL, NULL}
+}; /* compose_tab_60 */
+static int hash_compose_tab[122] =
+{30,31,52,60,32,-1,-1,33,-1,34,35,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,-1,5,6,7,8,9,10,11,12,36,13,37,14,
+ 38,15,16,55,40,-1,-1,-1,-1,17,56,-1,-1,-1,-1,-1,41,18,19,20,42,21,22,-1,45,
+ 39,-1,23,24,-1,25,26,-1,-1,-1,-1,-1,-1,-1,-1,48,-1,43,44,51,53,-1,-1,27,46,
+ 54,28,-1,-1,47,-1,-1,-1,-1,49,50,-1,-1,57,-1,58,59,29}; /* hash_compose_tab */
+static CompEntry compose_tab[] = {
+{768, 0, 39, compose_tab_0, hash_compose_tab_0},
+{769, 0, 70, compose_tab_1, hash_compose_tab_1},
+{770, 0, 27, compose_tab_2, hash_compose_tab_2},
+{771, 0, 19, compose_tab_3, hash_compose_tab_3},
+{772, 0, 28, compose_tab_4, hash_compose_tab_4},
+{774, 0, 30, compose_tab_5, hash_compose_tab_5},
+{775, 0, 40, compose_tab_6, hash_compose_tab_6},
+{776, 0, 50, compose_tab_7, hash_compose_tab_7},
+{777, 0, 15, compose_tab_8, hash_compose_tab_8},
+{778, 0, 6, compose_tab_9, hash_compose_tab_9},
+{779, 0, 6, compose_tab_10, hash_compose_tab_10},
+{780, 0, 34, compose_tab_11, hash_compose_tab_11},
+{781, 0, 17, compose_tab_12, hash_compose_tab_12},
+{783, 0, 14, compose_tab_13, hash_compose_tab_13},
+{785, 0, 12, compose_tab_14, hash_compose_tab_14},
+{787, 0, 15, compose_tab_15, hash_compose_tab_15},
+{788, 0, 17, compose_tab_16, hash_compose_tab_16},
+{795, 0, 4, compose_tab_17, hash_compose_tab_17},
+{803, 0, 39, compose_tab_18, hash_compose_tab_18},
+{804, 0, 2, compose_tab_19, hash_compose_tab_19},
+{805, 0, 2, compose_tab_20, hash_compose_tab_20},
+{807, 0, 20, compose_tab_21, hash_compose_tab_21},
+{808, 0, 10, compose_tab_22, hash_compose_tab_22},
+{813, 0, 12, compose_tab_23, hash_compose_tab_23},
+{814, 0, 2, compose_tab_24, hash_compose_tab_24},
+{816, 0, 6, compose_tab_25, hash_compose_tab_25},
+{817, 0, 17, compose_tab_26, hash_compose_tab_26},
+{834, 0, 12, compose_tab_27, hash_compose_tab_27},
+{837, 0, 6, compose_tab_28, hash_compose_tab_28},
+{1463, 0, 2, compose_tab_29, hash_compose_tab_29},
+{1464, 0, 1, compose_tab_30, hash_compose_tab_30},
+{1465, 0, 1, compose_tab_31, hash_compose_tab_31},
+{1468, 0, 22, compose_tab_32, hash_compose_tab_32},
+{1471, 0, 3, compose_tab_33, hash_compose_tab_33},
+{1473, 0, 2, compose_tab_34, hash_compose_tab_34},
+{1474, 0, 2, compose_tab_35, hash_compose_tab_35},
+{2364, 0, 11, compose_tab_36, hash_compose_tab_36},
+{2492, 0, 4, compose_tab_37, hash_compose_tab_37},
+{2494, 0, 1, compose_tab_38, hash_compose_tab_38},
+{2519, 0, 1, compose_tab_39, hash_compose_tab_39},
+{2620, 0, 5, compose_tab_40, hash_compose_tab_40},
+{2876, 0, 3, compose_tab_41, hash_compose_tab_41},
+{2878, 0, 1, compose_tab_42, hash_compose_tab_42},
+{2902, 0, 1, compose_tab_43, hash_compose_tab_43},
+{2903, 0, 1, compose_tab_44, hash_compose_tab_44},
+{3006, 0, 2, compose_tab_45, hash_compose_tab_45},
+{3031, 0, 2, compose_tab_46, hash_compose_tab_46},
+{3158, 0, 1, compose_tab_47, hash_compose_tab_47},
+{3266, 0, 1, compose_tab_48, hash_compose_tab_48},
+{3285, 0, 3, compose_tab_49, hash_compose_tab_49},
+{3286, 0, 1, compose_tab_50, hash_compose_tab_50},
+{3390, 0, 2, compose_tab_51, hash_compose_tab_51},
+{3415, 0, 1, compose_tab_52, hash_compose_tab_52},
+{3634, 0, 1, compose_tab_53, hash_compose_tab_53},
+{3762, 0, 1, compose_tab_54, hash_compose_tab_54},
+{3953, 0, 3, compose_tab_55, hash_compose_tab_55},
+{3968, 0, 2, compose_tab_56, hash_compose_tab_56},
+{4021, 0, 2, compose_tab_57, hash_compose_tab_57},
+{4023, 0, 10, compose_tab_58, hash_compose_tab_58},
+{12441, 0, 48, compose_tab_59, hash_compose_tab_59},
+{12442, 0, 10, compose_tab_60, hash_compose_tab_60}
+}; /* compose_tab */
+#define COMP_CANDIDATE_MAP_OFFSET 24
+static Uint32 comp_candidate_map[] = {
+ 0x081ABFDFU,
+ 0x000361B8U,
+ 0x00000024U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x93800000U,
+ 0x00000006U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x10000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x50000000U,
+ 0x00800000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x10000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x50000000U,
+ 0x00C00000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x40000000U,
+ 0x00800000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00400000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00600004U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x40000000U,
+ 0x00800000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00040000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00040000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00000000U,
+ 0x00020000U,
+ 0x00000001U,
+ 0x00A00000U
+};
diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h
index cd63401581..e7fd144ec3 100644
--- a/erts/emulator/beam/erl_vm.h
+++ b/erts/emulator/beam/erl_vm.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -47,7 +47,7 @@
#define SEQ_TRACE 1
#define CONTEXT_REDS 2000 /* Swap process out after this number */
-#define MAX_ARG 256 /* Max number of arguments allowed */
+#define MAX_ARG 255 /* Max number of arguments allowed */
#define MAX_REG 1024 /* Max number of x(N) registers used */
/* Scheduler stores data for temporary heaps if
@@ -120,14 +120,15 @@
* Allocate heap memory, first on the ordinary heap;
* failing that, in a heap fragment.
*/
-#define HAlloc(p, sz) \
+#define HAllocX(p, sz, xtra) \
(ASSERT_EXPR((sz) >= 0), \
ErtsHAllocLockCheck(p), \
(IS_FORCE_HEAP_FRAGS || (((HEAP_LIMIT(p) - HEAP_TOP(p)) < (sz))) \
- ? erts_heap_alloc((p),(sz)) \
+ ? erts_heap_alloc((p),(sz),(xtra)) \
: (INIT_HEAP_MEM(p,sz), \
HEAP_TOP(p) = HEAP_TOP(p) + (sz), HEAP_TOP(p) - (sz))))
+#define HAlloc(P, SZ) HAllocX(P,SZ,0)
#define HRelease(p, endp, ptr) \
if ((ptr) == (endp)) { \
@@ -199,6 +200,7 @@ extern int BIN_VH_MIN_SIZE; /* minimum virtual (bin) heap */
extern int erts_atom_table_size;/* Atom table size */
#define ORIG_CREATION 0
+#define INTERNAL_CREATION 255
/* macros for extracting bytes from uint16's */
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index d7c8aa84e9..328aa2be6a 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -49,10 +49,8 @@
#define in_area(ptr,start,nbytes) ((Uint)((char*)(ptr) - (char*)(start)) < (nbytes))
#define MAX_STRING_LEN 0xffff
-#define dec_set_creation(nodename,creat) \
- (((nodename) == erts_this_node->sysname && (creat) == ORIG_CREATION) \
- ? erts_this_node->creation \
- : (creat))
+
+#define is_valid_creation(Cre) ((unsigned)(Cre) < MAX_CREATION || (Cre) == INTERNAL_CREATION)
#undef ERTS_DEBUG_USE_DIST_SEP
#ifdef DEBUG
@@ -83,14 +81,14 @@
*
*/
-static byte* enc_term(ErtsAtomCacheMap *, Eterm, byte*, Uint32);
+static byte* enc_term(ErtsAtomCacheMap *, Eterm, byte*, Uint32, struct erl_off_heap_header** off_heap);
static Uint is_external_string(Eterm obj, int* p_is_string);
static byte* enc_atom(ErtsAtomCacheMap *, Eterm, byte*, Uint32);
static byte* enc_pid(ErtsAtomCacheMap *, Eterm, byte*, Uint32);
static byte* dec_term(ErtsDistExternal *, Eterm**, byte*, ErlOffHeap*, Eterm*);
static byte* dec_atom(ErtsDistExternal *, byte*, Eterm*);
static byte* dec_pid(ErtsDistExternal *, Eterm**, byte*, ErlOffHeap*, Eterm*);
-static Sint decoded_size(byte *ep, byte* endp, int only_heap_bins);
+static Sint decoded_size(byte *ep, byte* endp, int only_heap_bins, int internal_tags);
static Uint encode_size_struct2(ErtsAtomCacheMap *, Eterm, unsigned);
@@ -461,6 +459,12 @@ Uint erts_encode_ext_size(Eterm term)
+ 1 /* VERSION_MAGIC */;
}
+Uint erts_encode_ext_size_ets(Eterm term)
+{
+ return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|DFLAGS_INTERNAL_TAGS);
+}
+
+
void erts_encode_dist_ext(Eterm term, byte **ext, Uint32 flags, ErtsAtomCacheMap *acmp)
{
byte *ep = *ext;
@@ -468,7 +472,7 @@ void erts_encode_dist_ext(Eterm term, byte **ext, Uint32 flags, ErtsAtomCacheMap
if (!(flags & DFLAG_DIST_HDR_ATOM_CACHE))
#endif
*ep++ = VERSION_MAGIC;
- ep = enc_term(acmp, term, ep, flags);
+ ep = enc_term(acmp, term, ep, flags, NULL);
if (!ep)
erl_exit(ERTS_ABORT_EXIT,
"%s:%d:erts_encode_dist_ext(): Internal data structure error\n",
@@ -480,7 +484,7 @@ void erts_encode_ext(Eterm term, byte **ext)
{
byte *ep = *ext;
*ep++ = VERSION_MAGIC;
- ep = enc_term(NULL, term, ep, TERM_TO_BINARY_DFLAGS);
+ ep = enc_term(NULL, term, ep, TERM_TO_BINARY_DFLAGS, NULL);
if (!ep)
erl_exit(ERTS_ABORT_EXIT,
"%s:%d:erts_encode_ext(): Internal data structure error\n",
@@ -488,6 +492,12 @@ void erts_encode_ext(Eterm term, byte **ext)
*ext = ep;
}
+byte* erts_encode_ext_ets(Eterm term, byte *ep, struct erl_off_heap_header** off_heap)
+{
+ return enc_term(NULL, term, ep, TERM_TO_BINARY_DFLAGS|DFLAGS_INTERNAL_TAGS,
+ off_heap);
+}
+
ErtsDistExternal *
erts_make_dist_ext_copy(ErtsDistExternal *edep, Uint xsize)
{
@@ -813,7 +823,7 @@ erts_decode_dist_ext_size(ErtsDistExternal *edep, int no_refc_bins)
goto fail;
ep = edep->extp+1;
}
- res = decoded_size(ep, edep->ext_endp, no_refc_bins);
+ res = decoded_size(ep, edep->ext_endp, no_refc_bins, 0);
if (res >= 0)
return res;
fail:
@@ -825,9 +835,17 @@ Sint erts_decode_ext_size(byte *ext, Uint size, int no_refc_bins)
{
if (size == 0 || *ext != VERSION_MAGIC)
return -1;
- return decoded_size(ext+1, ext+size, no_refc_bins);
+ return decoded_size(ext+1, ext+size, no_refc_bins, 0);
}
+Sint erts_decode_ext_size_ets(byte *ext, Uint size)
+{
+ Sint sz = decoded_size(ext, ext+size, 0, 1);
+ ASSERT(sz >= 0);
+ return sz;
+}
+
+
/*
** hpp is set to either a &p->htop or
** a pointer to a memory pointer (form message buffers)
@@ -887,7 +905,13 @@ Eterm erts_decode_ext(Eterm **hpp, ErlOffHeap *off_heap, byte **ext)
return obj;
}
-
+Eterm erts_decode_ext_ets(Eterm **hpp, ErlOffHeap *off_heap, byte *ext)
+{
+ Eterm obj;
+ ext = dec_term(NULL, hpp, ext, off_heap, &obj);
+ ASSERT(ext);
+ return obj;
+}
/**********************************************************************/
@@ -964,6 +988,7 @@ term_to_binary_1(Process* p, Eterm Term)
return erts_term_to_binary(p, Term, 0, TERM_TO_BINARY_DFLAGS);
}
+
Eterm
term_to_binary_2(Process* p, Eterm Term, Eterm Flags)
{
@@ -1075,7 +1100,7 @@ binary2term_prepare(ErtsBinary2TermState *state, byte *data, Sint data_size)
goto error;
size = (Sint) dest_len;
}
- res = decoded_size(state->extp, state->extp + size, 0);
+ res = decoded_size(state->extp, state->extp + size, 0, 0);
if (res < 0)
goto error;
return res;
@@ -1183,7 +1208,8 @@ BIF_RETTYPE binary_to_term_2(BIF_ALIST_2)
opt = CAR(list_val(opts));
if (opt == am_safe) {
fakedep.flags |= ERTS_DIST_EXT_BTT_SAFE;
- } else {
+ }
+ else {
goto error;
}
opts = CDR(list_val(opts));
@@ -1255,7 +1281,7 @@ erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags)
bytes = erts_alloc(ERTS_ALC_T_TMP, size);
}
- if ((endp = enc_term(NULL, Term, bytes, flags))
+ if ((endp = enc_term(NULL, Term, bytes, flags, NULL))
== NULL) {
erl_exit(1, "%s, line %d: bad term: %x\n",
__FILE__, __LINE__, Term);
@@ -1300,7 +1326,7 @@ erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags)
bin = new_binary(p, (byte *)NULL, size);
bytes = binary_bytes(bin);
bytes[0] = VERSION_MAGIC;
- if ((endp = enc_term(NULL, Term, bytes+1, flags))
+ if ((endp = enc_term(NULL, Term, bytes+1, flags, NULL))
== NULL) {
erl_exit(1, "%s, line %d: bad term: %x\n",
__FILE__, __LINE__, Term);
@@ -1330,6 +1356,21 @@ enc_atom(ErtsAtomCacheMap *acmp, Eterm atom, byte *ep, Uint32 dflags)
ASSERT(is_atom(atom));
+ if (dflags & DFLAGS_INTERNAL_TAGS) {
+ Uint aval = atom_val(atom);
+ ASSERT(aval < (1<<24));
+ if (aval >= (1 << 16)) {
+ *ep++ = ATOM_INTERNAL_REF3;
+ put_int24(aval, ep);
+ ep += 3;
+ }
+ else {
+ *ep++ = ATOM_INTERNAL_REF2;
+ put_int16(aval, ep);
+ ep += 2;
+ }
+ return ep;
+ }
/*
* term_to_binary/1,2 and the initial distribution message
* don't use the cache.
@@ -1379,7 +1420,8 @@ enc_pid(ErtsAtomCacheMap *acmp, Eterm pid, byte* ep, Uint32 dflags)
ep += 4;
put_int32(os, ep);
ep += 4;
- *ep++ = pid_creation(pid);
+ *ep++ = (is_internal_pid(pid) && (dflags & DFLAGS_INTERNAL_TAGS)) ?
+ INTERNAL_CREATION : pid_creation(pid);
return ep;
}
@@ -1418,6 +1460,23 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp)
}
ep += len;
break;
+ case ATOM_INTERNAL_REF2:
+ n = get_int16(ep);
+ ep += 2;
+ if (n >= atom_table_size()) {
+ goto error;
+ }
+ *objp = make_atom(n);
+ break;
+ case ATOM_INTERNAL_REF3:
+ n = get_int24(ep);
+ ep += 3;
+ if (n >= atom_table_size()) {
+ goto error;
+ }
+ *objp = make_atom(n);
+ break;
+
default:
error:
*objp = NIL; /* Don't leave a hole in the heap */
@@ -1426,6 +1485,19 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp)
return ep;
}
+static ERTS_INLINE ErlNode* dec_get_node(Eterm sysname, Uint creation)
+{
+ switch (creation) {
+ case INTERNAL_CREATION:
+ return erts_this_node;
+ case ORIG_CREATION:
+ if (sysname == erts_this_node->sysname) {
+ creation = erts_this_node->creation;
+ }
+ }
+ return erts_find_or_insert_node(sysname,creation);
+}
+
static byte*
dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Eterm* objp)
{
@@ -1449,18 +1521,20 @@ dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Ete
ep += 4;
if (ser > ERTS_MAX_PID_SERIAL)
return NULL;
- if ((cre = get_int8(ep)) >= MAX_CREATION)
- return NULL;
+ cre = get_int8(ep);
ep += 1;
+ if (!is_valid_creation(cre)) {
+ return NULL;
+ }
+ data = make_pid_data(ser, num);
+
/*
* We are careful to create the node entry only after all
* validity tests are done.
*/
- cre = dec_set_creation(sysname,cre);
- node = erts_find_or_insert_node(sysname,cre);
+ node = dec_get_node(sysname, cre);
- data = make_pid_data(ser, num);
if(node == erts_this_node) {
*objp = make_internal_pid(data);
} else {
@@ -1485,7 +1559,8 @@ dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Ete
#define ENC_LAST_ARRAY_ELEMENT ((Eterm) 3)
static byte*
-enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
+enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags,
+ struct erl_off_heap_header** off_heap)
{
DECLARE_WSTACK(s);
Uint n;
@@ -1637,12 +1712,14 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
Uint32 *ref_num;
ASSERT(dflags & DFLAG_EXTENDED_REFERENCES);
+
*ep++ = NEW_REFERENCE_EXT;
i = ref_no_of_numbers(obj);
put_int16(i, ep);
ep += 2;
ep = enc_atom(acmp,ref_node_name(obj),ep,dflags);
- *ep++ = ref_creation(obj);
+ *ep++ = ((dflags & DFLAGS_INTERNAL_TAGS) && is_internal_ref(obj)) ?
+ INTERNAL_CREATION : ref_creation(obj);
ref_num = ref_numbers(obj);
for (j = 0; j < i; j++) {
put_int32(ref_num[j], ep);
@@ -1658,7 +1735,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
j = port_number(obj);
put_int32(j, ep);
ep += 4;
- *ep++ = port_creation(obj);
+ *ep++ = ((dflags & DFLAGS_INTERNAL_TAGS) && is_internal_port(obj)) ?
+ INTERNAL_CREATION : port_creation(obj);
break;
case LIST_DEF:
@@ -1738,6 +1816,41 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
byte* bytes;
ERTS_GET_BINARY_BYTES(obj, bytes, bitoffs, bitsize);
+ if (dflags & DFLAGS_INTERNAL_TAGS) {
+ ProcBin* pb = (ProcBin*) binary_val(obj);
+ Uint bytesize = pb->size;
+ if (pb->thing_word == HEADER_SUB_BIN) {
+ ErlSubBin* sub = (ErlSubBin*)pb;
+ pb = (ProcBin*) binary_val(sub->orig);
+ ASSERT(bytesize == sub->size);
+ bytesize += (bitoffs + bitsize + 7) / 8;
+ }
+ if (pb->thing_word == HEADER_PROC_BIN
+ && heap_bin_size(bytesize) > PROC_BIN_SIZE) {
+ ProcBin tmp;
+ if (bitoffs || bitsize) {
+ *ep++ = BIT_BINARY_INTERNAL_REF;
+ *ep++ = bitoffs;
+ *ep++ = bitsize;
+ }
+ else {
+ *ep++ = BINARY_INTERNAL_REF;
+ }
+ if (pb->flags) {
+ erts_emasculate_writable_binary(pb);
+ }
+ erts_refc_inc(&pb->val->refc, 2);
+
+ sys_memcpy(&tmp, pb, sizeof(ProcBin));
+ tmp.next = *off_heap;
+ tmp.bytes = bytes;
+ tmp.size = bytesize;
+ sys_memcpy(ep, &tmp, sizeof(ProcBin));
+ *off_heap = (struct erl_off_heap_header*) ep;
+ ep += sizeof(ProcBin);
+ break;
+ }
+ }
if (bitsize == 0) {
/* Plain old byte-sized binary. */
*ep++ = BINARY_EXT;
@@ -1773,8 +1886,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
*ep++ = SMALL_INTEGER_EXT;
*ep++ = bitsize;
}
- break;
}
+ break;
case EXPORT_DEF:
{
Export* exp = *((Export **) (export_val(obj) + 1));
@@ -1782,7 +1895,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
*ep++ = EXPORT_EXT;
ep = enc_atom(acmp, exp->code[0], ep, dflags);
ep = enc_atom(acmp, exp->code[1], ep, dflags);
- ep = enc_term(acmp, make_small(exp->code[2]), ep, dflags);
+ ep = enc_term(acmp, make_small(exp->code[2]), ep, dflags, off_heap);
} else {
/* Tag, arity */
*ep++ = SMALL_TUPLE_EXT;
@@ -1818,8 +1931,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
put_int32(funp->num_free, ep);
ep += 4;
ep = enc_atom(acmp, funp->fe->module, ep, dflags);
- ep = enc_term(acmp, make_small(funp->fe->old_index), ep, dflags);
- ep = enc_term(acmp, make_small(funp->fe->old_uniq), ep, dflags);
+ ep = enc_term(acmp, make_small(funp->fe->old_index), ep, dflags, off_heap);
+ ep = enc_term(acmp, make_small(funp->fe->old_uniq), ep, dflags, off_heap);
ep = enc_pid(acmp, funp->creator, ep, dflags);
fun_env:
@@ -1872,7 +1985,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
return ep;
}
-static Uint
+static
+Uint
is_external_string(Eterm list, int* p_is_string)
{
Uint len = 0;
@@ -2162,13 +2276,13 @@ dec_term_atom_common:
goto error;
}
ep += 4;
- if ((cre = get_int8(ep)) >= MAX_CREATION) {
+ cre = get_int8(ep);
+ ep++;
+ if (!is_valid_creation(cre)) {
goto error;
}
- ep++;
- cre = dec_set_creation(sysname,cre);
- node = erts_find_or_insert_node(sysname, cre);
+ node = dec_get_node(sysname, cre);
if(node == erts_this_node) {
*objp = make_internal_port(num);
}
@@ -2205,9 +2319,11 @@ dec_term_atom_common:
goto error;
ep += 4;
- if ((cre = get_int8(ep)) >= MAX_CREATION)
- goto error;
+ cre = get_int8(ep);
ep += 1;
+ if (!is_valid_creation(cre)) {
+ goto error;
+ }
goto ref_ext_common;
case NEW_REFERENCE_EXT:
@@ -2220,10 +2336,11 @@ dec_term_atom_common:
if ((ep = dec_atom(edep, ep, &sysname)) == NULL)
goto error;
- if ((cre = get_int8(ep)) >= MAX_CREATION)
- goto error;
+ cre = get_int8(ep);
ep += 1;
-
+ if (!is_valid_creation(cre)) {
+ goto error;
+ }
r0 = get_int32(ep);
ep += 4;
if (r0 >= MAX_REFERENCE)
@@ -2231,8 +2348,7 @@ dec_term_atom_common:
ref_ext_common:
- cre = dec_set_creation(sysname, cre);
- node = erts_find_or_insert_node(sysname, cre);
+ node = dec_get_node(sysname, cre);
if(node == erts_this_node) {
RefThing *rtp = (RefThing *) hp;
ref_num = (Uint32 *) (hp + REF_THING_HEAD_SIZE);
@@ -2560,6 +2676,66 @@ dec_term_atom_common:
}
break;
}
+ case ATOM_INTERNAL_REF2:
+ n = get_int16(ep);
+ ep += 2;
+ if (n >= atom_table_size()) {
+ goto error;
+ }
+ *objp = make_atom(n);
+ break;
+ case ATOM_INTERNAL_REF3:
+ n = get_int24(ep);
+ ep += 3;
+ if (n >= atom_table_size()) {
+ goto error;
+ }
+ *objp = make_atom(n);
+ break;
+
+ case BINARY_INTERNAL_REF:
+ {
+ ProcBin* pb = (ProcBin*) hp;
+ sys_memcpy(pb, ep, sizeof(ProcBin));
+ ep += sizeof(ProcBin);
+
+ erts_refc_inc(&pb->val->refc, 1);
+ hp += PROC_BIN_SIZE;
+ pb->next = off_heap->first;
+ off_heap->first = (struct erl_off_heap_header*)pb;
+ pb->flags = 0;
+ *objp = make_binary(pb);
+ break;
+ }
+ case BIT_BINARY_INTERNAL_REF:
+ {
+ Sint bitoffs = *ep++;
+ Sint bitsize = *ep++;
+ ProcBin* pb = (ProcBin*) hp;
+ ErlSubBin* sub;
+ sys_memcpy(pb, ep, sizeof(ProcBin));
+ ep += sizeof(ProcBin);
+
+ erts_refc_inc(&pb->val->refc, 1);
+ hp += PROC_BIN_SIZE;
+ pb->next = off_heap->first;
+ off_heap->first = (struct erl_off_heap_header*)pb;
+ pb->flags = 0;
+
+ sub = (ErlSubBin*)hp;
+ sub->thing_word = HEADER_SUB_BIN;
+ sub->size = pb->size - (bitoffs + bitsize + 7)/8;
+ sub->offs = 0;
+ sub->bitoffs = bitoffs;
+ sub->bitsize = bitsize;
+ sub->is_writable = 0;
+ sub->orig = make_binary(pb);
+
+ hp += ERL_SUB_BIN_SIZE;
+ *objp = make_binary(sub);
+ break;
+ }
+
default:
error:
/* UNDO:
@@ -2642,20 +2818,29 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
case NIL_DEF:
result++;
break;
- case ATOM_DEF: {
- int alen = atom_tab(atom_val(obj))->len;
- if ((MAX_ATOM_LENGTH <= 255 || alen <= 255)
- && (dflags & DFLAG_SMALL_ATOM_TAGS)) {
- /* Make sure a SMALL_ATOM_EXT fits: SMALL_ATOM_EXT l t1 t2... */
- result += 1 + 1 + alen;
+ case ATOM_DEF:
+ if (dflags & DFLAGS_INTERNAL_TAGS) {
+ if (atom_val(obj) >= (1<<16)) {
+ result += 1 + 3;
+ }
+ else {
+ result += 1 + 2;
+ }
}
else {
- /* Make sure an ATOM_EXT fits: ATOM_EXT l1 l0 t1 t2... */
- result += 1 + 2 + alen;
+ int alen = atom_tab(atom_val(obj))->len;
+ if ((MAX_ATOM_LENGTH <= 255 || alen <= 255)
+ && (dflags & DFLAG_SMALL_ATOM_TAGS)) {
+ /* Make sure a SMALL_ATOM_EXT fits: SMALL_ATOM_EXT l t1 t2... */
+ result += 1 + 1 + alen;
+ }
+ else {
+ /* Make sure an ATOM_EXT fits: ATOM_EXT l1 l0 t1 t2... */
+ result += 1 + 2 + alen;
+ }
+ insert_acache_map(acmp, obj);
}
- insert_acache_map(acmp, obj);
break;
- }
case SMALL_DEF:
{
Sint val = signed_val(obj);
@@ -2734,8 +2919,25 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
}
break;
case BINARY_DEF:
+ if (dflags & DFLAGS_INTERNAL_TAGS) {
+ ProcBin* pb = (ProcBin*) binary_val(obj);
+ Uint sub_extra = 0;
+ Uint tot_bytes = pb->size;
+ if (pb->thing_word == HEADER_SUB_BIN) {
+ ErlSubBin* sub = (ErlSubBin*) pb;
+ pb = (ProcBin*) binary_val(sub->orig);
+ sub_extra = 2; /* bitoffs and bitsize */
+ tot_bytes += (sub->bitoffs + sub->bitsize+ 7) / 8;
+ }
+ if (pb->thing_word == HEADER_PROC_BIN
+ && heap_bin_size(tot_bytes) > PROC_BIN_SIZE) {
+
+ result += 1 + sub_extra + sizeof(ProcBin);
+ break;
+ }
+ }
result += 1 + 4 + binary_size(obj) +
- 5; /* For unaligned binary */
+ 5; /* For unaligned binary */
break;
case FUN_DEF:
{
@@ -2807,7 +3009,7 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
}
static Sint
-decoded_size(byte *ep, byte* endp, int no_refc_bins)
+decoded_size(byte *ep, byte* endp, int no_refc_bins, int internal_tags)
{
int heap_size = 0;
int terms;
@@ -3017,6 +3219,29 @@ decoded_size(byte *ep, byte* endp, int no_refc_bins)
heap_size += ERL_FUN_SIZE + num_free;
break;
}
+ case ATOM_INTERNAL_REF2:
+ SKIP(2+atom_extra_skip);
+ atom_extra_skip = 0;
+ break;
+ case ATOM_INTERNAL_REF3:
+ SKIP(3+atom_extra_skip);
+ atom_extra_skip = 0;
+ break;
+
+ case BINARY_INTERNAL_REF:
+ if (!internal_tags) {
+ return -1;
+ }
+ SKIP(sizeof(ProcBin));
+ heap_size += PROC_BIN_SIZE;
+ break;
+ case BIT_BINARY_INTERNAL_REF:
+ if (!internal_tags) {
+ return -1;
+ }
+ SKIP(2+sizeof(ProcBin));
+ heap_size += PROC_BIN_SIZE + ERL_SUB_BIN_SIZE;
+ break;
default:
return -1;
}
diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h
index cee48bbeb0..d8287b96a4 100644
--- a/erts/emulator/beam/external.h
+++ b/erts/emulator/beam/external.h
@@ -54,6 +54,10 @@
#define DIST_HEADER 'D'
#define ATOM_CACHE_REF 'R'
+#define ATOM_INTERNAL_REF2 'I'
+#define ATOM_INTERNAL_REF3 'K'
+#define BINARY_INTERNAL_REF 'J'
+#define BIT_BINARY_INTERNAL_REF 'L'
#define COMPRESSED 'P'
#if 0
@@ -156,7 +160,9 @@ Uint erts_encode_dist_ext_size(Eterm, Uint32, ErtsAtomCacheMap *);
void erts_encode_dist_ext(Eterm, byte **, Uint32, ErtsAtomCacheMap *);
Uint erts_encode_ext_size(Eterm);
+Uint erts_encode_ext_size_ets(Eterm);
void erts_encode_ext(Eterm, byte **);
+byte* erts_encode_ext_ets(Eterm, byte *, struct erl_off_heap_header** ext_off_heap);
#ifdef ERTS_WANT_EXTERNAL_TAGS
ERTS_GLB_INLINE void erts_peek_dist_header(ErtsDistHeaderPeek *, byte *, Uint);
@@ -172,7 +178,9 @@ Sint erts_decode_dist_ext_size(ErtsDistExternal *, int);
Eterm erts_decode_dist_ext(Eterm **, ErlOffHeap *, ErtsDistExternal *);
Sint erts_decode_ext_size(byte*, Uint, int);
+Sint erts_decode_ext_size_ets(byte*, Uint);
Eterm erts_decode_ext(Eterm **, ErlOffHeap *, byte**);
+Eterm erts_decode_ext_ets(Eterm **, ErlOffHeap *, byte*);
Eterm erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags);
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index ecd3c8f68a..bd540eaaa6 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -522,6 +522,7 @@ union erl_off_heap_ptr {
struct erl_fun_thing* fun;
struct external_thing_* ext;
Eterm* ep;
+ void* voidp;
};
/* arrays that get malloced at startup */
@@ -543,7 +544,7 @@ ERTS_GLB_INLINE void erts_may_save_closed_port(Port *prt)
if (prt->snapshot != erts_smp_atomic_read(&erts_ports_snapshot)) {
/* Dead ports are added from the end of the snapshot buffer */
Eterm* tombstone = (Eterm*) erts_smp_atomic_addtest(&erts_dead_ports_ptr,
- -(long)sizeof(Eterm));
+ -(erts_aint_t)sizeof(Eterm));
ASSERT(tombstone+1 != NULL);
ASSERT(prt->snapshot == (Uint32) erts_smp_atomic_read(&erts_ports_snapshot) - 1);
*tombstone = prt->id;
@@ -562,7 +563,7 @@ extern Uint display_items; /* no of items to display in traces etc */
extern Uint display_loads; /* print info about loaded modules */
extern int erts_backtrace_depth;
-extern erts_smp_atomic_t erts_max_gen_gcs;
+extern erts_smp_atomic32_t erts_max_gen_gcs;
extern int erts_disable_tolerant_timeofday;
@@ -889,9 +890,31 @@ void erl_error(char*, va_list);
/* copy.c */
void init_copy(void);
Eterm copy_object(Eterm, Process*);
+
+#if HALFWORD_HEAP
+Uint size_object_rel(Eterm, Eterm*);
+# define size_object(A) size_object_rel(A,NULL)
+
+Eterm copy_struct_rel(Eterm, Uint, Eterm**, ErlOffHeap*, Eterm* src_base, Eterm* dst_base);
+# define copy_struct(OBJ,SZ,HPP,OH) copy_struct_rel(OBJ,SZ,HPP,OH, NULL,NULL)
+
+Eterm copy_shallow_rel(Eterm*, Uint, Eterm**, ErlOffHeap*, Eterm* src_base);
+# define copy_shallow(A,B,C,D) copy_shallow_rel(A,B,C,D,NULL)
+
+#else /* !HALFWORD_HEAP */
+
Uint size_object(Eterm);
+# define size_object_rel(A,B) size_object(A)
+
Eterm copy_struct(Eterm, Uint, Eterm**, ErlOffHeap*);
+# define copy_struct_rel(OBJ,SZ,HPP,OH, SB,DB) copy_struct(OBJ,SZ,HPP,OH)
+
Eterm copy_shallow(Eterm*, Uint, Eterm**, ErlOffHeap*);
+# define copy_shallow_rel(A,B,C,D, BASE) copy_shallow(A,B,C,D)
+
+#endif
+
+
void move_multi_frags(Eterm** hpp, ErlOffHeap*, ErlHeapFragment* first,
Eterm* refs, unsigned nrefs);
@@ -1205,7 +1228,7 @@ ERTS_GLB_INLINE void
erts_smp_port_unlock(Port *prt)
{
#ifdef ERTS_SMP
- long refc;
+ erts_aint_t refc;
erts_smp_mtx_unlock(prt->lock);
refc = erts_smp_atomic_dectest(&prt->refc);
ASSERT(refc >= 0);
@@ -1424,84 +1447,6 @@ void erl_drv_thr_init(void);
/* time.c */
-ERTS_GLB_INLINE long do_time_read_and_reset(void);
-#ifdef ERTS_TIMER_THREAD
-ERTS_GLB_INLINE int next_time(void);
-ERTS_GLB_INLINE void bump_timer(long);
-#else
-int next_time(void);
-void bump_timer(long);
-extern erts_smp_atomic_t do_time; /* set at clock interrupt */
-ERTS_GLB_INLINE void do_time_add(long);
-#endif
-
-#if ERTS_GLB_INLINE_INCL_FUNC_DEF
-
-#ifdef ERTS_TIMER_THREAD
-ERTS_GLB_INLINE long do_time_read_and_reset(void) { return 0; }
-ERTS_GLB_INLINE int next_time(void) { return -1; }
-ERTS_GLB_INLINE void bump_timer(long ignore) { }
-#else
-ERTS_GLB_INLINE long do_time_read_and_reset(void)
-{
- return erts_smp_atomic_xchg(&do_time, 0L);
-}
-ERTS_GLB_INLINE void do_time_add(long elapsed)
-{
- erts_smp_atomic_add(&do_time, elapsed);
-}
-#endif
-
-#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
-
-void init_time(void);
-void erl_set_timer(ErlTimer*, ErlTimeoutProc, ErlCancelProc, void*, Uint);
-void erl_cancel_timer(ErlTimer*);
-Uint time_left(ErlTimer *);
-
-Uint erts_timer_wheel_memory_size(void);
-
-#if (defined(HAVE_GETHRVTIME) || defined(HAVE_CLOCK_GETTIME))
-# ifndef HAVE_ERTS_NOW_CPU
-# define HAVE_ERTS_NOW_CPU
-# ifdef HAVE_GETHRVTIME
-# define erts_start_now_cpu() sys_start_hrvtime()
-# define erts_stop_now_cpu() sys_stop_hrvtime()
-# endif
-# endif
-void erts_get_now_cpu(Uint* megasec, Uint* sec, Uint* microsec);
-#endif
-
-void erts_get_timeval(SysTimeval *tv);
-long erts_get_time(void);
-
-extern SysTimeval erts_first_emu_time;
-
-void erts_get_emu_time(SysTimeval *);
-
-ERTS_GLB_INLINE int erts_cmp_timeval(SysTimeval *t1p, SysTimeval *t2p);
-
-#if ERTS_GLB_INLINE_INCL_FUNC_DEF
-
-ERTS_GLB_INLINE int
-erts_cmp_timeval(SysTimeval *t1p, SysTimeval *t2p)
-{
- if (t1p->tv_sec == t2p->tv_sec) {
- if (t1p->tv_usec < t2p->tv_usec)
- return -1;
- else if (t1p->tv_usec > t2p->tv_usec)
- return 1;
- return 0;
- }
- return t1p->tv_sec < t2p->tv_sec ? -1 : 1;
-}
-
-#endif
-
-#ifdef DEBUG
-void p_slpq(void);
-#endif
-
/* utils.c */
/*
@@ -1560,16 +1505,30 @@ void erts_init_utils_mem(void);
erts_dsprintf_buf_t *erts_create_tmp_dsbuf(Uint);
void erts_destroy_tmp_dsbuf(erts_dsprintf_buf_t *);
+#if HALFWORD_HEAP
+int eq_rel(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base);
+# define eq(A,B) eq_rel(A,NULL,B,NULL)
+#else
int eq(Eterm, Eterm);
+# define eq_rel(A,A_BASE,B,B_BASE) eq(A,B)
+#endif
+
#define EQ(x,y) (((x) == (y)) || (is_not_both_immed((x),(y)) && eq((x),(y))))
+#if HALFWORD_HEAP
+Sint cmp_rel(Eterm, Eterm*, Eterm, Eterm*);
+#define CMP(A,B) cmp_rel(A,NULL,B,NULL)
+#else
Sint cmp(Eterm, Eterm);
-#define cmp_lt(a,b) (cmp((a),(b)) < 0)
-#define cmp_le(a,b) (cmp((a),(b)) <= 0)
-#define cmp_eq(a,b) (cmp((a),(b)) == 0)
-#define cmp_ne(a,b) (cmp((a),(b)) != 0)
-#define cmp_ge(a,b) (cmp((a),(b)) >= 0)
-#define cmp_gt(a,b) (cmp((a),(b)) > 0)
+#define cmp_rel(A,A_BASE,B,B_BASE) cmp(A,B)
+#define CMP(A,B) cmp(A,B)
+#endif
+#define cmp_lt(a,b) (CMP((a),(b)) < 0)
+#define cmp_le(a,b) (CMP((a),(b)) <= 0)
+#define cmp_eq(a,b) (CMP((a),(b)) == 0)
+#define cmp_ne(a,b) (CMP((a),(b)) != 0)
+#define cmp_ge(a,b) (CMP((a),(b)) >= 0)
+#define cmp_gt(a,b) (CMP((a),(b)) > 0)
#define CMP_LT(a,b) ((a) != (b) && cmp_lt((a),(b)))
#define CMP_GE(a,b) ((a) == (b) || cmp_ge((a),(b)))
@@ -1595,6 +1554,19 @@ Sint erts_binary_set_loop_limit(Sint limit);
/* erl_unicode.c */
void erts_init_unicode(void);
Sint erts_unicode_set_loop_limit(Sint limit);
+
+void erts_native_filename_put(Eterm ioterm, int encoding, byte *p) ;
+Sint erts_native_filename_need(Eterm ioterm, int encoding);
+void erts_copy_utf8_to_utf16_little(byte *target, byte *bytes, int num_chars);
+int erts_analyze_utf8(byte *source, Uint size,
+ byte **err_pos, Uint *num_chars, int *left);
+char *erts_convert_filename_to_native(Eterm name, ErtsAlcType_t alloc_type, int allow_empty);
+
+#define ERTS_UTF8_OK 0
+#define ERTS_UTF8_INCOMPLETE 1
+#define ERTS_UTF8_ERROR 2
+#define ERTS_UTF8_ANALYZE_MORE 3
+
/* erl_trace.c */
void erts_init_trace(void);
void erts_trace_check_exiting(Eterm exiting);
@@ -1728,11 +1700,6 @@ Uint erts_current_reductions(Process* current, Process *p);
int erts_print_system_version(int to, void *arg, Process *c_p);
-/*
- * Interface to erl_init
- */
-void erl_init(void);
-
#define seq_trace_output(token, msg, type, receiver, process) \
seq_trace_output_generic((token), (msg), (type), (receiver), (process), NIL)
#define seq_trace_output_exit(token, msg, type, receiver, exitfrom) \
@@ -1790,8 +1757,15 @@ do { \
extern Binary *erts_match_set_compile(Process *p, Eterm matchexpr);
Eterm erts_match_set_lint(Process *p, Eterm matchexpr);
extern void erts_match_set_release_result(Process* p);
+
+enum erts_pam_run_flags {
+ ERTS_PAM_TMP_RESULT=0,
+ ERTS_PAM_COPY_RESULT=1,
+ ERTS_PAM_CONTIGUOUS_TUPLE=2
+};
extern Eterm erts_match_set_run(Process *p, Binary *mpsp,
Eterm *args, int num_args,
+ enum erts_pam_run_flags in_flags,
Uint32 *return_flags);
extern Eterm erts_match_set_get_source(Binary *mpsp);
extern void erts_match_prog_foreach_offheap(Binary *b,
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 79022d5dd7..f21a96c754 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -428,7 +428,7 @@ setup_port(Port* prt, Eterm pid, erts_driver_t *driver,
old_name = prt->name;
prt->name = new_name;
#ifdef ERTS_SMP
- erts_smp_atomic_set(&prt->run_queue, (long) runq);
+ erts_smp_atomic_set(&prt->run_queue, (erts_aint_t) runq);
#endif
ASSERT(!prt->drv_ptr);
prt->drv_ptr = driver;
@@ -670,7 +670,7 @@ erts_open_driver(erts_driver_t* driver, /* Pointer to driver. */
#ifdef ERTS_SMP
erts_cancel_smp_ptimer(port->ptimer);
#else
- erl_cancel_timer(&(port->tm));
+ erts_cancel_timer(&(port->tm));
#endif
stopq(port);
kill_port(port);
@@ -1297,7 +1297,7 @@ void init_io(void)
erts_port[i].port_data_lock = NULL;
}
- erts_smp_atomic_init(&erts_ports_snapshot, (long) 0);
+ erts_smp_atomic_init(&erts_ports_snapshot, (erts_aint_t) 0);
last_port_num = 0;
erts_smp_spinlock_init(&get_free_port_lck, "get_free_port");
@@ -1839,7 +1839,7 @@ terminate_port(Port *prt)
#ifdef ERTS_SMP
erts_cancel_smp_ptimer(prt->ptimer);
#else
- erl_cancel_timer(&prt->tm);
+ erts_cancel_timer(&prt->tm);
#endif
drv = prt->drv_ptr;
@@ -2802,17 +2802,25 @@ driver_deliver_term(ErlDrvPort port,
break;
case ERL_DRV_INT: /* signed int argument */
ERTS_DDT_CHK_ENOUGH_ARGS(1);
+#if HALFWORD_HEAP
+ erts_bld_sint64(NULL, &need, (Sint64)ptr[0]);
+#else
/* check for bignum */
if (!IS_SSMALL((Sint)ptr[0]))
need += BIG_UINT_HEAP_SIZE; /* use small_to_big */
+#endif
ptr++;
depth++;
break;
case ERL_DRV_UINT: /* unsigned int argument */
ERTS_DDT_CHK_ENOUGH_ARGS(1);
+#if HALFWORD_HEAP
+ erts_bld_uint64(NULL, &need, (Uint64)ptr[0]);
+#else
/* check for bignum */
if (!IS_USMALL(0, (Uint)ptr[0]))
need += BIG_UINT_HEAP_SIZE; /* use small_to_big */
+#endif
ptr++;
depth++;
break;
@@ -2979,22 +2987,30 @@ driver_deliver_term(ErlDrvPort port,
break;
case ERL_DRV_INT: /* signed int argument */
+#if HALFWORD_HEAP
+ mess = erts_bld_sint64(&hp, NULL, (Sint64)ptr[0]);
+#else
if (IS_SSMALL((Sint)ptr[0]))
mess = make_small((Sint)ptr[0]);
else {
mess = small_to_big((Sint)ptr[0], hp);
hp += BIG_UINT_HEAP_SIZE;
}
+#endif
ptr++;
break;
case ERL_DRV_UINT: /* unsigned int argument */
+#if HALFWORD_HEAP
+ mess = erts_bld_uint64(&hp, NULL, (Uint64)ptr[0]);
+#else
if (IS_USMALL(0, (Uint)ptr[0]))
mess = make_small((Uint)ptr[0]);
else {
mess = uint_to_big((Uint)ptr[0], hp);
hp += BIG_UINT_HEAP_SIZE;
}
+#endif
ptr++;
break;
@@ -3236,7 +3252,7 @@ int driver_output_binary(ErlDrvPort ix, char* hbuf, int hlen,
return 0;
prt->bytes_in += (hlen + len);
- erts_smp_atomic_add(&erts_bytes_in, (long) (hlen + len));
+ erts_smp_atomic_add(&erts_bytes_in, (erts_aint_t) (hlen + len));
if (prt->status & ERTS_PORT_SFLG_DISTRIBUTION) {
return erts_net_message(prt,
prt->dist_entry,
@@ -3271,7 +3287,7 @@ int driver_output2(ErlDrvPort ix, char* hbuf, int hlen, char* buf, int len)
return 0;
prt->bytes_in += (hlen + len);
- erts_smp_atomic_add(&erts_bytes_in, (long) (hlen + len));
+ erts_smp_atomic_add(&erts_bytes_in, (erts_aint_t) (hlen + len));
if (prt->status & ERTS_PORT_SFLG_DISTRIBUTION) {
if (len == 0)
return erts_net_message(prt,
@@ -3348,7 +3364,7 @@ int driver_outputv(ErlDrvPort ix, char* hbuf, int hlen, ErlIOVec* vec, int skip)
/* XXX handle distribution !!! */
prt->bytes_in += (hlen + size);
- erts_smp_atomic_add(&erts_bytes_in, (long) (hlen + size));
+ erts_smp_atomic_add(&erts_bytes_in, (erts_aint_t) (hlen + size));
deliver_vec_message(prt, prt->connected, hbuf, hlen, binv, iov, n, size);
return 0;
}
@@ -3392,25 +3408,25 @@ int len;
* reference count on driver binaries...
*/
-long
+ErlDrvSInt
driver_binary_get_refc(ErlDrvBinary *dbp)
{
Binary* bp = ErlDrvBinary2Binary(dbp);
- return erts_refc_read(&bp->refc, 1);
+ return (ErlDrvSInt) erts_refc_read(&bp->refc, 1);
}
-long
+ErlDrvSInt
driver_binary_inc_refc(ErlDrvBinary *dbp)
{
Binary* bp = ErlDrvBinary2Binary(dbp);
- return erts_refc_inctest(&bp->refc, 2);
+ return (ErlDrvSInt) erts_refc_inctest(&bp->refc, 2);
}
-long
+ErlDrvSInt
driver_binary_dec_refc(ErlDrvBinary *dbp)
{
Binary* bp = ErlDrvBinary2Binary(dbp);
- return erts_refc_dectest(&bp->refc, 1);
+ return (ErlDrvSInt) erts_refc_dectest(&bp->refc, 1);
}
@@ -3525,12 +3541,12 @@ pdl_init_refc(ErlDrvPDL pdl)
erts_atomic_init(&pdl->refc, 1);
}
-static ERTS_INLINE long
+static ERTS_INLINE ErlDrvSInt
pdl_read_refc(ErlDrvPDL pdl)
{
- long refc = erts_atomic_read(&pdl->refc);
+ erts_aint_t refc = erts_atomic_read(&pdl->refc);
ERTS_LC_ASSERT(refc >= 0);
- return refc;
+ return (ErlDrvSInt) refc;
}
static ERTS_INLINE void
@@ -3540,12 +3556,12 @@ pdl_inc_refc(ErlDrvPDL pdl)
ERTS_LC_ASSERT(driver_pdl_get_refc(pdl) > 1);
}
-static ERTS_INLINE long
+static ERTS_INLINE ErlDrvSInt
pdl_inctest_refc(ErlDrvPDL pdl)
{
- long refc = erts_atomic_inctest(&pdl->refc);
+ erts_aint_t refc = erts_atomic_inctest(&pdl->refc);
ERTS_LC_ASSERT(refc > 1);
- return refc;
+ return (ErlDrvSInt) refc;
}
#if 0 /* unused */
@@ -3557,12 +3573,12 @@ pdl_dec_refc(ErlDrvPDL pdl)
}
#endif
-static ERTS_INLINE long
+static ERTS_INLINE ErlDrvSInt
pdl_dectest_refc(ErlDrvPDL pdl)
{
- long refc = erts_atomic_dectest(&pdl->refc);
+ erts_aint_t refc = erts_atomic_dectest(&pdl->refc);
ERTS_LC_ASSERT(refc >= 0);
- return refc;
+ return (ErlDrvSInt) refc;
}
static ERTS_INLINE void pdl_destroy(ErlDrvPDL pdl)
@@ -3633,7 +3649,7 @@ driver_pdl_lock(ErlDrvPDL pdl)
void
driver_pdl_unlock(ErlDrvPDL pdl)
{
- long refc;
+ ErlDrvSInt refc;
#ifdef HARDDEBUG
erts_fprintf(stderr, "driver_pdl_unlock(0x%08X)\r\n",(unsigned) pdl);
#endif
@@ -3643,28 +3659,30 @@ driver_pdl_unlock(ErlDrvPDL pdl)
pdl_destroy(pdl);
}
-long
+ErlDrvSInt
driver_pdl_get_refc(ErlDrvPDL pdl)
{
return pdl_read_refc(pdl);
}
-long
+ErlDrvSInt
driver_pdl_inc_refc(ErlDrvPDL pdl)
{
- long refc = pdl_inctest_refc(pdl);
+ ErlDrvSInt refc = pdl_inctest_refc(pdl);
#ifdef HARDDEBUG
- erts_fprintf(stderr, "driver_pdl_inc_refc(0x%08X) -> %ld\r\n",(unsigned) pdl, refc);
+ erts_fprintf(stderr, "driver_pdl_inc_refc(%p) -> %bpd\r\n",
+ pdl, refc);
#endif
return refc;
}
-long
+ErlDrvSInt
driver_pdl_dec_refc(ErlDrvPDL pdl)
{
- long refc = pdl_dectest_refc(pdl);
+ ErlDrvSInt refc = pdl_dectest_refc(pdl);
#ifdef HARDDEBUG
- erts_fprintf(stderr, "driver_pdl_dec_refc(0x%08X) -> %ld\r\n",(unsigned) pdl, refc);
+ erts_fprintf(stderr, "driver_pdl_dec_refc(%p) -> %bpd\r\n",
+ pdl, refc);
#endif
if (!refc)
pdl_destroy(pdl);
@@ -4050,7 +4068,7 @@ drv_cancel_timer(Port *prt)
#ifdef ERTS_SMP
erts_cancel_smp_ptimer(prt->ptimer);
#else
- erl_cancel_timer(&prt->tm);
+ erts_cancel_timer(&prt->tm);
#endif
if (erts_port_task_is_scheduled(&prt->timeout_task))
erts_port_task_abort(prt->id, &prt->timeout_task);
@@ -4074,7 +4092,7 @@ int driver_set_timer(ErlDrvPort ix, UWord t)
(ErlTimeoutProc) schedule_port_timeout,
t);
#else
- erl_set_timer(&prt->tm,
+ erts_set_timer(&prt->tm,
(ErlTimeoutProc) schedule_port_timeout,
NULL,
prt,
@@ -4105,9 +4123,9 @@ driver_read_timer(ErlDrvPort ix, unsigned long* t)
return -1;
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
#ifdef ERTS_SMP
- *t = prt->ptimer ? time_left(&prt->ptimer->timer.tm) : 0;
+ *t = prt->ptimer ? erts_time_left(&prt->ptimer->timer.tm) : 0;
#else
- *t = time_left(&prt->tm);
+ *t = erts_time_left(&prt->tm);
#endif
return 0;
}
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index a2439d5582..e861f97e7a 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -101,16 +101,16 @@ return
%macro: test_heap TestHeap -pack
allocate t t
-allocate_heap I I I
+allocate_heap t I t
deallocate I
init y
allocate_zero t t
-allocate_heap_zero I I I
+allocate_heap_zero t I t
trim N Remaining => i_trim N
i_trim I
-test_heap I I
+test_heap I t
allocate_heap S u==0 R => allocate S R
allocate_heap_zero S u==0 R => allocate_zero S R
@@ -124,7 +124,7 @@ init Y1 | init Y2 => init2 Y1 Y2
# Selecting values
-select_val S=q Fail=f Size=u Rest=* => const_select_val(S, Fail, Size, Rest)
+select_val S=aiq Fail=f Size=u Rest=* => const_select_val(S, Fail, Size, Rest)
select_val S=s Fail=f Size=u Rest=* | use_jump_tab(Size, Rest) => \
gen_jump_tab(S, Fail, Size, Rest)
@@ -132,34 +132,59 @@ select_val S=s Fail=f Size=u Rest=* | use_jump_tab(Size, Rest) => \
is_integer Fail=f S | select_val S=s Fail=f Size=u Rest=* | use_jump_tab(Size, Rest) => \
gen_jump_tab(S, Fail, Size, Rest)
+is_integer TypeFail=f S | select_val S=s Fail=f Size=u Rest=* | \
+ mixed_types(Size, Rest) => \
+ gen_split_values(S, TypeFail, Fail, Size, Rest)
+
select_val S=s Fail=f Size=u Rest=* | mixed_types(Size, Rest) => \
- gen_split_values(S, Fail, Size, Rest)
+ gen_split_values(S, Fail, Fail, Size, Rest)
-is_integer Fail=f S | select_val S=s Fail=f Size=u Rest=* | \
+is_integer Fail=f S | select_val S=d Fail=f Size=u Rest=* | \
fixed_size_values(Size, Rest) => gen_select_val(S, Fail, Size, Rest)
-is_atom Fail=f S | select_val S=s Fail=f Size=u Rest=* | \
+is_atom Fail=f S | select_val S=d Fail=f Size=u Rest=* | \
fixed_size_values(Size, Rest) => gen_select_val(S, Fail, Size, Rest)
-select_val S=s Fail=f Size=u Rest=* | fixed_size_values(Size, Rest) => \
- gen_select_val(S, Fail, Size, Rest)
+select_val S=s Fail=f Size=u Rest=* | floats_or_bignums(Size, Rest) => \
+ gen_select_literals(S, Fail, Size, Rest)
-select_val S=s Fail=f Size=u Rest=* | all_values_are_big(Size, Rest) => \
- gen_select_big(S, Fail, Size, Rest)
+select_val S=d Fail=f Size=u Rest=* | fixed_size_values(Size, Rest) => \
+ gen_select_val(S, Fail, Size, Rest)
-is_tuple Fail=f S | select_tuple_arity S=s Fail=f Size=u Rest=* => \
+is_tuple Fail=f S | select_tuple_arity S=d Fail=f Size=u Rest=* => \
gen_select_tuple_arity(S, Fail, Size, Rest)
-select_tuple_arity S=s Fail=f Size=u Rest=* => \
+select_tuple_arity S=d Fail=f Size=u Rest=* => \
gen_select_tuple_arity(S, Fail, Size, Rest)
-i_select_val s f I
-i_select_tuple_arity s f I
-i_select_big s f
-i_select_float s f I
+i_select_val r f I
+i_select_val x f I
+i_select_val y f I
+
+i_select_val2 r f c f c f
+i_select_val2 x f c f c f
+i_select_val2 y f c f c f
+
+i_select_tuple_arity2 r f A f A f
+i_select_tuple_arity2 x f A f A f
+i_select_tuple_arity2 y f A f A f
+
+i_select_tuple_arity r f I
+i_select_tuple_arity x f I
+i_select_tuple_arity y f I
+
+i_jump_on_val_zero r f I
+i_jump_on_val_zero x f I
+i_jump_on_val_zero y f I
+
+i_jump_on_val r f I I
+i_jump_on_val x f I I
+i_jump_on_val y f I I
-i_jump_on_val_zero s f I
-i_jump_on_val s f I I
+jump Target | label Lbl | same_label(Target, Lbl) => label Lbl
+
+is_ne_exact L1 S1 S2 | jump Fail | label L2 | same_label(L1, L2) => \
+ is_eq_exact Fail S1 S2 | label L2
%macro: get_list GetList -pack
get_list x x x
@@ -234,11 +259,17 @@ is_number Fail Literal=q => move Literal x | is_number Fail x
jump f
-case_end Literal=q => move Literal x | case_end x
-badmatch Literal=q => move Literal x | badmatch x
+case_end Literal=cq => move Literal x | case_end x
+badmatch Literal=cq => move Literal x | badmatch x
+
+case_end r
+case_end x
+case_end y
+
+badmatch r
+badmatch x
+badmatch y
-case_end s
-badmatch s
if_end
raise s s
@@ -248,12 +279,33 @@ system_limit j
move R R =>
+move C=cxy r | jump Lbl => move_jump Lbl C
+
+%macro: move_jump MoveJump -nonext
+move_jump f n
+move_jump f c
+move_jump f x
+move_jump f y
+
move X1=x Y1=y | move X2=x Y2=y => move2 X1 Y1 X2 Y2
move Y1=y X1=x | move Y2=y X2=x => move2 Y1 X1 Y2 X2
+move X1=x X2=x | move X3=x X4=x => move2 X1 X2 X3 X4
+
+move C=aiq X=x==1 => move_x1 C
+move C=aiq X=x==2 => move_x2 C
+
+move_x1 c
+move_x2 c
%macro: move2 Move2 -pack
move2 x y x y
move2 y x y x
+move2 x x x x
+
+# The compiler almost never generates a "move Literal y(Y)" instruction,
+# so let's cheat if we encounter one.
+move S=n D=y => init D
+move S=c D=y => move S x | move x D
%macro:move Move -pack -gen_dest
move x x
@@ -265,15 +317,10 @@ move r x
move r y
move c r
move c x
-move c y
move n x
move n r
move y y
-%cold
-move s d
-%hot
-
# Receive operations.
loop_rec Fail Src | smp_mark_target_label(Fail) => i_loop_rec Fail Src
@@ -306,55 +353,78 @@ i_wait_error_locked
send
#
-# Comparisions.
+# Optimized comparisons with one immediate/literal operand.
+#
+
+is_eq_exact Lbl R=rxy C=ian => i_is_eq_exact_immed Lbl R C
+is_eq_exact Lbl R=rxy C=q => i_is_eq_exact_literal R Lbl C
+
+is_ne_exact Lbl R=rxy C=ian => i_is_ne_exact_immed Lbl R C
+is_ne_exact Lbl R=rxy C=q => i_is_ne_exact_literal R Lbl C
+
+%macro: i_is_eq_exact_immed EqualImmed -fail_action
+i_is_eq_exact_immed f r c
+i_is_eq_exact_immed f x c
+i_is_eq_exact_immed f y c
+
+i_is_eq_exact_literal r f c
+i_is_eq_exact_literal x f c
+i_is_eq_exact_literal y f c
+
+%macro: i_is_ne_exact_immed NotEqualImmed -fail_action
+i_is_ne_exact_immed f r c
+i_is_ne_exact_immed f x c
+i_is_ne_exact_immed f y c
+
+i_is_ne_exact_literal r f c
+i_is_ne_exact_literal x f c
+i_is_ne_exact_literal y f c
+
+#
+# All other comparisons.
#
-is_eq_exact Lbl=f R=rxy C=ian => i_is_eq_immed Lbl R C
-is_eq Lbl=f R=rxy C=an => i_is_eq_immed Lbl R C
+is_eq_exact Lbl S1 S2 => i_fetch S1 S2 | i_is_eq_exact Lbl
+is_ne_exact Lbl S1 S2 => i_fetch S1 S2 | i_is_ne_exact Lbl
is_ge Lbl S1 S2 => i_fetch S1 S2 | i_is_ge Lbl
is_lt Lbl S1 S2 => i_fetch S1 S2 | i_is_lt Lbl
is_eq Lbl S1 S2 => i_fetch S1 S2 | i_is_eq Lbl
is_ne Lbl S1 S2 => i_fetch S1 S2 | i_is_ne Lbl
-is_eq_exact Lbl=f S1 S2 => i_fetch S1 S2 | i_is_eq_exact Lbl
-is_ne_exact Lbl S1 S2 => i_fetch S1 S2 | i_is_ne_exact Lbl
-
+i_is_eq_exact f
+i_is_ne_exact f
i_is_lt f
i_is_ge f
i_is_eq f
i_is_ne f
-i_is_eq_exact f
-i_is_ne_exact f
-
-%macro: i_is_eq_immed EqualImmed -fail_action
-i_is_eq_immed f r c
-i_is_eq_immed f x c
-i_is_eq_immed f y c
#
# Putting things.
#
-put_tuple Arity Dst | put V => i_put_tuple Arity V Dst
+put_tuple Arity Dst => i_put_tuple Dst u
-%macro: i_put_tuple PutTuple -pack
-i_put_tuple A x x
-i_put_tuple A y x
-i_put_tuple A r x
-i_put_tuple A n x
-i_put_tuple A c x
-i_put_tuple A x y
-i_put_tuple A x r
-i_put_tuple A y r
-i_put_tuple A n r
-i_put_tuple A c r
+i_put_tuple Dst Arity Puts=* | put S1 | put S2 | \
+ put S3 | put S4 | put S5 => \
+ tuple_append_put5(Arity, Dst, Puts, S1, S2, S3, S4, S5)
-%cold
-i_put_tuple A r y
-i_put_tuple A y y
-i_put_tuple A c y
-%hot
+i_put_tuple Dst Arity Puts=* | put S => \
+ tuple_append_put(Arity, Dst, Puts, S)
+
+i_put_tuple/2
+
+%macro:i_put_tuple PutTuple -pack -goto:do_put_tuple
+i_put_tuple r I
+i_put_tuple x I
+i_put_tuple y I
+
+#
+# The instruction "put_list Const [] Dst" will not be generated by
+# the current BEAM compiler. But until R15A, play it safe by handling
+# that instruction with the following transformation.
+#
+put_list Const=c n Dst => move Const x | put_list x n Dst
%macro:put_list PutList -pack -gen_dest
@@ -362,10 +432,8 @@ put_list x n x
put_list y n x
put_list x x x
put_list y x x
-put_list c n x
put_list x x r
put_list y r r
-put_list c n r
put_list y y x
put_list x y x
@@ -376,6 +444,13 @@ put_list y y r
put_list y r x
put_list r n x
+put_list x r x
+put_list x y r
+put_list y x r
+put_list y x x
+
+put_list x r r
+
# put_list SrcReg Constant Dst
put_list r c r
put_list r c x
@@ -403,17 +478,9 @@ put_list c y x
put_list c y y
%cold
-put_list x r r
put_list s s d
%hot
-%macro: put Put
-put x
-put r
-put y
-put c
-put n
-
%macro: i_fetch FetchArgs -pack
i_fetch c c
i_fetch c r
@@ -464,19 +531,20 @@ move_return n r
move S r | deallocate D | return => move_deallocate_return S r D
-%macro: move_deallocate_return MoveDeallocateReturn -nonext
-move_deallocate_return x r P
-move_deallocate_return y r P
-move_deallocate_return c r P
-move_deallocate_return n r P
+%macro: move_deallocate_return MoveDeallocateReturn -pack -nonext
+move_deallocate_return x r Q
+move_deallocate_return y r Q
+move_deallocate_return c r Q
+move_deallocate_return n r Q
deallocate D | return => deallocate_return D
%macro: deallocate_return DeallocateReturn -nonext
-deallocate_return P
+deallocate_return Q
test_heap Need u==1 | put_list Y=y r r => test_heap_1_put_list Need Y
+%macro: test_heap_1_put_list TestHeapPutList -pack
test_heap_1_put_list I y
# Test tuple & arity (head)
@@ -576,14 +644,14 @@ is_list f y
is_nonempty_list Fail=f S=rx | allocate Need Rs => is_nonempty_list_allocate Fail S Need Rs
-%macro:is_nonempty_list_allocate IsNonemptyListAllocate -fail_action
-is_nonempty_list_allocate f x I I
-is_nonempty_list_allocate f r I I
+%macro:is_nonempty_list_allocate IsNonemptyListAllocate -fail_action -pack
+is_nonempty_list_allocate f x I t
+is_nonempty_list_allocate f r I t
is_nonempty_list F=f r | test_heap I1 I2 => is_non_empty_list_test_heap F r I1 I2
-%macro: is_non_empty_list_test_heap IsNonemptyListTestHeap -fail_action
-is_non_empty_list_test_heap f r I I
+%macro: is_non_empty_list_test_heap IsNonemptyListTestHeap -fail_action -pack
+is_non_empty_list_test_heap f r I t
%macro: is_nonempty_list IsNonemptyList -fail_action
is_nonempty_list f x
@@ -912,8 +980,13 @@ node x
node y
%hot
-i_fast_element j I s d
-i_element j s s d
+i_fast_element r j I d
+i_fast_element x j I d
+i_fast_element y j I d
+
+i_element r j s d
+i_element x j s d
+i_element y j s d
bif1 f b s d
bif1_body b s d
@@ -940,11 +1013,11 @@ move S r | call_last Ar P=f D => move_call_last S r P D
i_move_call_last f P c r
-%macro:move_call_last MoveCallLast -arg_f -nonext
+%macro:move_call_last MoveCallLast -arg_f -nonext -pack
move_call_last/4
-move_call_last x r f P
-move_call_last y r f P
+move_call_last x r f Q
+move_call_last y r f Q
move S=c r | call_only Ar P=f => i_move_call_only P S r
move S=x r | call_only Ar P=f => move_call_only S r P
@@ -1307,6 +1380,8 @@ fconv Arg=iqan Dst=l => move Arg x | fconv x Dst
fmove q l
fmove d l
+fmove l d
+
fconv d l
i_fadd l l l
@@ -1322,12 +1397,6 @@ fcheckerror p => i_fcheckerror
i_fcheckerror
fclearerror
-fmove FR=l Dst=d | new_float_allocation() => fmove_new FR Dst
-
-# The new instruction for moving a float out of a floating point register.
-# (No allocation.)
-fmove_new l d
-
#
# New apply instructions in R10B.
#
@@ -1336,7 +1405,21 @@ apply I
apply_last I P
#
-# New GCing arithmetic instructions.
+# Optimize addition and subtraction of small literals using
+# the i_increment/4 instruction (in bodies, not in guards).
+#
+
+gc_bif2 p Live u$bif:erlang:splus/2 Int=i Reg=d Dst => \
+ gen_increment(Reg, Int, Live, Dst)
+gc_bif2 p Live u$bif:erlang:splus/2 Reg=d Int=i Dst => \
+ gen_increment(Reg, Int, Live, Dst)
+
+gc_bif2 p Live u$bif:erlang:sminus/2 Reg=d Int=i Dst | \
+ negation_is_small(Int) => \
+ gen_increment_from_minus(Reg, Int, Live, Dst)
+
+#
+# GCing arithmetic instructions.
#
gc_bif2 Fail I u$bif:erlang:splus/2 S1 S2 Dst=d => i_fetch S1 S2 | i_plus Fail I Dst
@@ -1359,6 +1442,10 @@ gc_bif1 Fail I u$bif:erlang:bnot/1 Src Dst=d => i_int_bnot Fail Src I Dst
gc_bif1 Fail I u$bif:erlang:sminus/1 Src Dst=d => i_fetch i Src | i_minus Fail I Dst
gc_bif1 Fail I u$bif:erlang:splus/1 Src Dst=d => i_fetch i Src | i_plus Fail I Dst
+i_increment r I I d
+i_increment x I I d
+i_increment y I I d
+
i_plus j I d
i_minus j I d
i_times j I d
diff --git a/erts/emulator/beam/packet_parser.c b/erts/emulator/beam/packet_parser.c
index 5bcd567b5f..a66d60aa22 100644
--- a/erts/emulator/beam/packet_parser.c
+++ b/erts/emulator/beam/packet_parser.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -47,11 +47,6 @@
(((unsigned char*) (s))[1] << 8) | \
(((unsigned char*) (s))[0]))
-#define put_int24(s, x) ((((unsigned char*)(s))[0] = ((x) >> 16) & 0xff), \
- (((unsigned char*)(s))[1] = ((x) >> 8) & 0xff), \
- (((unsigned char*)(s))[2] = (x) & 0xff))
-
-
#if !defined(__WIN32__) && !defined(HAVE_STRNCASECMP)
#define STRNCASECMP my_strncasecmp
@@ -833,7 +828,7 @@ int packet_parse_ssl(const char* buf, int len,
char prefix[4];
/* <<1:8,Length:24,Data/binary>> */
prefix[0] = 1;
- put_int24(&prefix[1],len-3);
+ put_int24(len-3,&prefix[1]);
return pcb->ssl_tls(arg, 22, major, minor, buf+3, len-3, prefix, sizeof(prefix));
}
else {
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 0031568af6..ff828ae889 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -39,13 +39,6 @@
#define ENABLE_CHILD_WAITER_THREAD 1
#endif
-/* The ERTS_TIMER_TREAD #define must be visible to the
- erl_${OS}_sys.h #include files: it controls whether
- certain optional facilities should be defined or not. */
-#if defined(ERTS_SMP) && 0
-#define ERTS_TIMER_THREAD
-#endif
-
#if defined (__WIN32__)
# include "erl_win_sys.h"
#elif defined (VXWORKS)
@@ -232,14 +225,14 @@ int real_printf(const char *fmt, ...);
#else
#error Neither 32 nor 64 bit architecture
#endif
-#ifdef ARCH_64
-# ifdef HALFWORD_HEAP_EMULATOR
+#if defined(ARCH_64) && defined(HALFWORD_HEAP_EMULATOR)
# define HALFWORD_HEAP 1
# define HALFWORD_ASSERT 0
-# else
+# define ASSERT_HALFWORD(COND) ASSERT(COND)
+#else
# define HALFWORD_HEAP 0
# define HALFWORD_ASSERT 0
-# endif
+# define ASSERT_HALFWORD(COND)
#endif
#if SIZEOF_VOID_P != SIZEOF_SIZE_T
@@ -338,12 +331,16 @@ typedef unsigned char byte;
(((size_t) 8) - (((size_t) (X)) & ((size_t) 7)))
#include "erl_lock_check.h"
+
+/* needed by erl_smp.h */
+int erts_send_warning_to_logger_str_nogl(char *);
+
#include "erl_smp.h"
#ifdef ERTS_WANT_BREAK_HANDLING
# ifdef ERTS_SMP
-extern erts_smp_atomic_t erts_break_requested;
-# define ERTS_BREAK_REQUESTED ((int) erts_smp_atomic_read(&erts_break_requested))
+extern erts_smp_atomic32_t erts_break_requested;
+# define ERTS_BREAK_REQUESTED ((int) erts_smp_atomic32_read(&erts_break_requested))
# else
extern volatile int erts_break_requested;
# define ERTS_BREAK_REQUESTED erts_break_requested
@@ -356,8 +353,8 @@ void erts_do_break_handling(void);
# define ERTS_GOT_SIGUSR1 0
# else
# ifdef ERTS_SMP
-extern erts_smp_atomic_t erts_got_sigusr1;
-# define ERTS_GOT_SIGUSR1 ((int) erts_smp_atomic_read(&erts_got_sigusr1))
+extern erts_smp_atomic32_t erts_got_sigusr1;
+# define ERTS_GOT_SIGUSR1 ((int) erts_smp_atomic32_read(&erts_got_sigusr1))
# else
extern volatile int erts_got_sigusr1;
# define ERTS_GOT_SIGUSR1 erts_got_sigusr1
@@ -466,8 +463,6 @@ static const int zero_value = 0, one_value = 1;
# endif /* !__WIN32__ */
#endif /* WANT_NONBLOCKING */
-extern erts_cpu_info_t *erts_cpuinfo; /* erl_init.c */
-
__decl_noreturn void __noreturn erl_exit(int n, char*, ...);
/* Some special erl_exit() codes: */
@@ -526,7 +521,8 @@ int erts_send_info_to_logger_nogl(erts_dsprintf_buf_t *);
int erts_send_warning_to_logger_nogl(erts_dsprintf_buf_t *);
int erts_send_error_to_logger_nogl(erts_dsprintf_buf_t *);
int erts_send_info_to_logger_str_nogl(char *);
-int erts_send_warning_to_logger_str_nogl(char *);
+/* needed by erl_smp.h (declared above)
+ int erts_send_warning_to_logger_str_nogl(char *); */
int erts_send_error_to_logger_str_nogl(char *);
typedef struct preload {
@@ -564,11 +560,7 @@ extern char *erts_default_arg0;
extern char os_type[];
extern int sys_init_time(void);
-#if defined(ERTS_TIMER_THREAD)
-#define erts_deliver_time()
-#else
extern void erts_deliver_time(void);
-#endif
extern void erts_time_remaining(SysTimeval *);
extern int erts_init_time_sup(void);
extern void erts_sys_init_float(void);
@@ -730,11 +722,11 @@ typedef enum {
} erts_activity_error_t;
typedef struct {
- erts_smp_atomic_t do_block;
+ erts_smp_atomic32_t do_block;
struct {
- erts_smp_atomic_t wait;
- erts_smp_atomic_t gc;
- erts_smp_atomic_t io;
+ erts_smp_atomic32_t wait;
+ erts_smp_atomic32_t gc;
+ erts_smp_atomic32_t io;
} in_activity;
} erts_system_block_state_t;
@@ -885,7 +877,7 @@ ERTS_GLB_INLINE int
erts_smp_pending_system_block(void)
{
#ifdef ERTS_SMP
- return erts_smp_atomic_read(&erts_system_block_state.do_block);
+ return (int) erts_smp_atomic32_read(&erts_system_block_state.do_block);
#else
return 0;
#endif
@@ -921,7 +913,7 @@ erts_smp_set_activity(erts_activity_t old_activity,
case ERTS_ACTIVITY_UNDEFINED:
break;
case ERTS_ACTIVITY_WAIT:
- erts_smp_atomic_dec(&erts_system_block_state.in_activity.wait);
+ erts_smp_atomic32_dec(&erts_system_block_state.in_activity.wait);
if (locked) {
/* You are not allowed to leave activity waiting
* without supplying the possibility to block
@@ -932,10 +924,10 @@ erts_smp_set_activity(erts_activity_t old_activity,
}
break;
case ERTS_ACTIVITY_GC:
- erts_smp_atomic_dec(&erts_system_block_state.in_activity.gc);
+ erts_smp_atomic32_dec(&erts_system_block_state.in_activity.gc);
break;
case ERTS_ACTIVITY_IO:
- erts_smp_atomic_dec(&erts_system_block_state.in_activity.io);
+ erts_smp_atomic32_dec(&erts_system_block_state.in_activity.io);
break;
default:
erts_set_activity_error(ERTS_ACT_ERR_LEAVE_UNKNOWN_ACTIVITY,
@@ -951,13 +943,13 @@ erts_smp_set_activity(erts_activity_t old_activity,
case ERTS_ACTIVITY_UNDEFINED:
break;
case ERTS_ACTIVITY_WAIT:
- erts_smp_atomic_inc(&erts_system_block_state.in_activity.wait);
+ erts_smp_atomic32_inc(&erts_system_block_state.in_activity.wait);
break;
case ERTS_ACTIVITY_GC:
- erts_smp_atomic_inc(&erts_system_block_state.in_activity.gc);
+ erts_smp_atomic32_inc(&erts_system_block_state.in_activity.gc);
break;
case ERTS_ACTIVITY_IO:
- erts_smp_atomic_inc(&erts_system_block_state.in_activity.io);
+ erts_smp_atomic32_inc(&erts_system_block_state.in_activity.io);
break;
default:
erts_set_activity_error(ERTS_ACT_ERR_ENTER_UNKNOWN_ACTIVITY,
@@ -992,27 +984,31 @@ erts_smp_set_activity(erts_activity_t old_activity,
typedef erts_smp_atomic_t erts_refc_t;
-ERTS_GLB_INLINE void erts_refc_init(erts_refc_t *refcp, long val);
-ERTS_GLB_INLINE void erts_refc_inc(erts_refc_t *refcp, long min_val);
-ERTS_GLB_INLINE long erts_refc_inctest(erts_refc_t *refcp, long min_val);
-ERTS_GLB_INLINE void erts_refc_dec(erts_refc_t *refcp, long min_val);
-ERTS_GLB_INLINE long erts_refc_dectest(erts_refc_t *refcp, long min_val);
-ERTS_GLB_INLINE void erts_refc_add(erts_refc_t *refcp, long diff, long min_val);
-ERTS_GLB_INLINE long erts_refc_read(erts_refc_t *refcp, long min_val);
+ERTS_GLB_INLINE void erts_refc_init(erts_refc_t *refcp, erts_aint_t val);
+ERTS_GLB_INLINE void erts_refc_inc(erts_refc_t *refcp, erts_aint_t min_val);
+ERTS_GLB_INLINE erts_aint_t erts_refc_inctest(erts_refc_t *refcp,
+ erts_aint_t min_val);
+ERTS_GLB_INLINE void erts_refc_dec(erts_refc_t *refcp, erts_aint_t min_val);
+ERTS_GLB_INLINE erts_aint_t erts_refc_dectest(erts_refc_t *refcp,
+ erts_aint_t min_val);
+ERTS_GLB_INLINE void erts_refc_add(erts_refc_t *refcp, erts_aint_t diff,
+ erts_aint_t min_val);
+ERTS_GLB_INLINE erts_aint_t erts_refc_read(erts_refc_t *refcp,
+ erts_aint_t min_val);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
ERTS_GLB_INLINE void
-erts_refc_init(erts_refc_t *refcp, long val)
+erts_refc_init(erts_refc_t *refcp, erts_aint_t val)
{
erts_smp_atomic_init((erts_smp_atomic_t *) refcp, val);
}
ERTS_GLB_INLINE void
-erts_refc_inc(erts_refc_t *refcp, long min_val)
+erts_refc_inc(erts_refc_t *refcp, erts_aint_t min_val)
{
#ifdef ERTS_REFC_DEBUG
- long val = erts_smp_atomic_inctest((erts_smp_atomic_t *) refcp);
+ erts_aint_t val = erts_smp_atomic_inctest((erts_smp_atomic_t *) refcp);
if (val < min_val)
erl_exit(ERTS_ABORT_EXIT,
"erts_refc_inc(): Bad refc found (refc=%ld < %ld)!\n",
@@ -1022,10 +1018,10 @@ erts_refc_inc(erts_refc_t *refcp, long min_val)
#endif
}
-ERTS_GLB_INLINE long
-erts_refc_inctest(erts_refc_t *refcp, long min_val)
+ERTS_GLB_INLINE erts_aint_t
+erts_refc_inctest(erts_refc_t *refcp, erts_aint_t min_val)
{
- long val = erts_smp_atomic_inctest((erts_smp_atomic_t *) refcp);
+ erts_aint_t val = erts_smp_atomic_inctest((erts_smp_atomic_t *) refcp);
#ifdef ERTS_REFC_DEBUG
if (val < min_val)
erl_exit(ERTS_ABORT_EXIT,
@@ -1036,10 +1032,10 @@ erts_refc_inctest(erts_refc_t *refcp, long min_val)
}
ERTS_GLB_INLINE void
-erts_refc_dec(erts_refc_t *refcp, long min_val)
+erts_refc_dec(erts_refc_t *refcp, erts_aint_t min_val)
{
#ifdef ERTS_REFC_DEBUG
- long val = erts_smp_atomic_dectest((erts_smp_atomic_t *) refcp);
+ erts_aint_t val = erts_smp_atomic_dectest((erts_smp_atomic_t *) refcp);
if (val < min_val)
erl_exit(ERTS_ABORT_EXIT,
"erts_refc_dec(): Bad refc found (refc=%ld < %ld)!\n",
@@ -1049,10 +1045,10 @@ erts_refc_dec(erts_refc_t *refcp, long min_val)
#endif
}
-ERTS_GLB_INLINE long
-erts_refc_dectest(erts_refc_t *refcp, long min_val)
+ERTS_GLB_INLINE erts_aint_t
+erts_refc_dectest(erts_refc_t *refcp, erts_aint_t min_val)
{
- long val = erts_smp_atomic_dectest((erts_smp_atomic_t *) refcp);
+ erts_aint_t val = erts_smp_atomic_dectest((erts_smp_atomic_t *) refcp);
#ifdef ERTS_REFC_DEBUG
if (val < min_val)
erl_exit(ERTS_ABORT_EXIT,
@@ -1063,10 +1059,10 @@ erts_refc_dectest(erts_refc_t *refcp, long min_val)
}
ERTS_GLB_INLINE void
-erts_refc_add(erts_refc_t *refcp, long diff, long min_val)
+erts_refc_add(erts_refc_t *refcp, erts_aint_t diff, erts_aint_t min_val)
{
#ifdef ERTS_REFC_DEBUG
- long val = erts_smp_atomic_addtest((erts_smp_atomic_t *) refcp, diff);
+ erts_aint_t val = erts_smp_atomic_addtest((erts_smp_atomic_t *) refcp, diff);
if (val < min_val)
erl_exit(ERTS_ABORT_EXIT,
"erts_refc_add(%ld): Bad refc found (refc=%ld < %ld)!\n",
@@ -1076,10 +1072,10 @@ erts_refc_add(erts_refc_t *refcp, long diff, long min_val)
#endif
}
-ERTS_GLB_INLINE long
-erts_refc_read(erts_refc_t *refcp, long min_val)
+ERTS_GLB_INLINE erts_aint_t
+erts_refc_read(erts_refc_t *refcp, erts_aint_t min_val)
{
- long val = erts_smp_atomic_read((erts_smp_atomic_t *) refcp);
+ erts_aint_t val = erts_smp_atomic_read((erts_smp_atomic_t *) refcp);
#ifdef ERTS_REFC_DEBUG
if (val < min_val)
erl_exit(ERTS_ABORT_EXIT,
@@ -1168,6 +1164,15 @@ void* sys_calloc2(Uint, Uint);
((char*)(s))[3] = (char)(i) & 0xff;} \
while (0)
+#define get_int24(s) ((((unsigned char*) (s))[0] << 16) | \
+ (((unsigned char*) (s))[1] << 8) | \
+ (((unsigned char*) (s))[2]))
+
+#define put_int24(i, s) do {((char*)(s))[0] = (char)((i) >> 16) & 0xff; \
+ ((char*)(s))[1] = (char)((i) >> 8) & 0xff; \
+ ((char*)(s))[2] = (char)(i) & 0xff;} \
+ while (0)
+
#define get_int16(s) ((((unsigned char*) (s))[0] << 8) | \
(((unsigned char*) (s))[1]))
@@ -1181,6 +1186,7 @@ void* sys_calloc2(Uint, Uint);
#define put_int8(i, s) do {((unsigned char*)(s))[0] = (i) & 0xff;} while (0)
+
/*
* Use DEBUGF as you would use printf, but use double parentheses:
*
@@ -1245,6 +1251,22 @@ char* win32_errorstr(int);
#endif
+/************************************************************************
+ * Find out the native filename encoding of the process (look at locale of
+ * Unix processes and just do UTF16 on windows
+ ************************************************************************/
+#define ERL_FILENAME_UNKNOWN 0
+#define ERL_FILENAME_LATIN1 1
+#define ERL_FILENAME_UTF8 2
+#define ERL_FILENAME_UTF8_MAC 3
+#define ERL_FILENAME_WIN_WCHAR 4
+
+int erts_get_native_filename_encoding(void);
+/* The set function is only to be used by erl_init! */
+void erts_set_user_requested_filename_encoding(int encoding);
+int erts_get_user_requested_filename_encoding(void);
+
+void erts_init_sys_common_misc(void);
#endif
diff --git a/erts/emulator/beam/time.c b/erts/emulator/beam/time.c
index 53d39aef0e..c65cc37fc6 100644
--- a/erts/emulator/beam/time.c
+++ b/erts/emulator/beam/time.c
@@ -99,80 +99,37 @@ static erts_smp_mtx_t tiw_lock;
static ErlTimer** tiw; /* the timing wheel, allocated in init_time() */
static Uint tiw_pos; /* current position in wheel */
static Uint tiw_nto; /* number of timeouts in wheel */
+static Uint tiw_min;
+static ErlTimer *tiw_min_ptr;
/* END tiw_lock protected variables */
/* Actual interval time chosen by sys_init_time() */
static int itime; /* Constant after init */
-#if defined(ERTS_TIMER_THREAD)
-static SysTimeval time_start; /* start of current time interval */
-static long ticks_end; /* time_start+ticks_end == time_wakeup */
-static long ticks_latest; /* delta from time_start at latest time update*/
-
-static ERTS_INLINE long time_gettimeofday(SysTimeval *now)
-{
- long elapsed;
-
- erts_get_timeval(now);
- now->tv_usec = 1000 * (now->tv_usec / 1000); /* ms resolution */
- elapsed = (1000 * (now->tv_sec - time_start.tv_sec) +
- (now->tv_usec - time_start.tv_usec) / 1000);
- // elapsed /= CLOCK_RESOLUTION;
- return elapsed;
-}
-
-static long do_time_update(void)
-{
- SysTimeval now;
- long elapsed;
-
- elapsed = time_gettimeofday(&now);
- ticks_latest = elapsed;
- return elapsed;
-}
-
-static ERTS_INLINE long do_time_read(void)
-{
- return ticks_latest;
-}
-
-static long do_time_reset(void)
-{
- SysTimeval now;
- long elapsed;
-
- elapsed = time_gettimeofday(&now);
- time_start = now;
- ticks_end = LONG_MAX;
- ticks_latest = 0;
- return elapsed;
-}
-
-static ERTS_INLINE void do_time_init(void)
-{
- (void)do_time_reset();
-}
-
-#else
erts_smp_atomic_t do_time; /* set at clock interrupt */
-static ERTS_INLINE long do_time_read(void) { return erts_smp_atomic_read(&do_time); }
-static ERTS_INLINE long do_time_update(void) { return do_time_read(); }
+static ERTS_INLINE erts_aint_t do_time_read(void) { return erts_smp_atomic_read(&do_time); }
+static ERTS_INLINE erts_aint_t do_time_update(void) { return do_time_read(); }
static ERTS_INLINE void do_time_init(void) { erts_smp_atomic_init(&do_time, 0L); }
-#endif
/* get the time (in units of itime) to the next timeout,
or -1 if there are no timeouts */
-static int next_time_internal(void) /* PRE: tiw_lock taken by caller */
+static erts_aint_t next_time_internal(void) /* PRE: tiw_lock taken by caller */
{
int i, tm, nto;
unsigned int min;
ErlTimer* p;
- long dt;
+ erts_aint_t dt;
if (tiw_nto == 0)
return -1; /* no timeouts in wheel */
+
+ if (tiw_min_ptr) {
+ min = tiw_min;
+ dt = do_time_read();
+ return ((min >= dt) ? (min - dt) : 0);
+ }
/* start going through wheel to find next timeout */
tm = nto = 0;
@@ -185,11 +142,17 @@ static int next_time_internal(void) /* PRE: tiw_lock taken by caller */
if (p->count == 0) {
/* found next timeout */
dt = do_time_read();
+ /* p->count is zero */
+ tiw_min_ptr = p;
+ tiw_min = tm;
return ((tm >= dt) ? (tm - dt) : 0);
} else {
/* keep shortest time in 'min' */
- if (tm + p->count*TIW_SIZE < min)
+ if (tm + p->count*TIW_SIZE < min) {
min = tm + p->count*TIW_SIZE;
+ tiw_min_ptr = p;
+ tiw_min = min;
+ }
}
p = p->next;
}
@@ -202,11 +165,35 @@ static int next_time_internal(void) /* PRE: tiw_lock taken by caller */
return ((min >= dt) ? (min - dt) : 0);
}
-#if !defined(ERTS_TIMER_THREAD)
+static void remove_timer(ErlTimer *p) {
+ /* first */
+ if (!p->prev) {
+ tiw[p->slot] = p->next;
+ if(p->next)
+ p->next->prev = NULL;
+ } else {
+ p->prev->next = p->next;
+ }
+
+ /* last */
+ if (!p->next) {
+ if (p->prev)
+ p->prev->next = NULL;
+ } else {
+ p->next->prev = p->prev;
+ }
+
+ p->next = NULL;
+ p->prev = NULL;
+ /* Make sure cancel callback isn't called */
+ p->active = 0;
+ tiw_nto--;
+}
+
/* Private export to erl_time_sup.c */
-int next_time(void)
+erts_aint_t erts_next_time(void)
{
- int ret;
+ erts_aint_t ret;
erts_smp_mtx_lock(&tiw_lock);
(void)do_time_update();
@@ -214,14 +201,13 @@ int next_time(void)
erts_smp_mtx_unlock(&tiw_lock);
return ret;
}
-#endif
-static ERTS_INLINE void bump_timer_internal(long dt) /* PRE: tiw_lock is write-locked */
+static ERTS_INLINE void bump_timer_internal(erts_aint_t dt) /* PRE: tiw_lock is write-locked */
{
Uint keep_pos;
Uint count;
ErlTimer *p, **prev, *timeout_head, **timeout_tail;
- Uint dtime = (unsigned long)dt;
+ Uint dtime = (Uint) dt;
/* no need to bump the position if there aren't any timeouts */
if (tiw_nto == 0) {
@@ -242,12 +228,16 @@ static ERTS_INLINE void bump_timer_internal(long dt) /* PRE: tiw_lock is write-l
if (tiw_pos == keep_pos) count--;
prev = &tiw[tiw_pos];
while ((p = *prev) != NULL) {
+ ASSERT( p != p->next);
if (p->count < count) { /* we have a timeout */
- *prev = p->next; /* Remove from list */
- tiw_nto--;
- p->next = NULL;
- p->active = 0; /* Make sure cancel callback
- isn't called */
+ /* remove min time */
+ if (tiw_min_ptr == p) {
+ tiw_min_ptr = NULL;
+ tiw_min = 0;
+ }
+
+ /* Remove from list */
+ remove_timer(p);
*timeout_tail = p; /* Insert in timeout queue */
timeout_tail = &p->next;
}
@@ -261,6 +251,8 @@ static ERTS_INLINE void bump_timer_internal(long dt) /* PRE: tiw_lock is write-l
dtime--;
}
tiw_pos = keep_pos;
+ if (tiw_min_ptr)
+ tiw_min -= dt;
erts_smp_mtx_unlock(&tiw_lock);
@@ -275,24 +267,17 @@ static ERTS_INLINE void bump_timer_internal(long dt) /* PRE: tiw_lock is write-l
* callback is called.
*/
p->next = NULL;
+ p->prev = NULL;
p->slot = 0;
(*p->timeout)(p->arg);
}
}
-#if defined(ERTS_TIMER_THREAD)
-static void timer_thread_bump_timer(void)
-{
- erts_smp_mtx_lock(&tiw_lock);
- bump_timer_internal(do_time_reset());
-}
-#else
-void bump_timer(long dt) /* dt is value from do_time */
+void erts_bump_timer(erts_aint_t dt) /* dt is value from do_time */
{
erts_smp_mtx_lock(&tiw_lock);
bump_timer_internal(dt);
}
-#endif
Uint
erts_timer_wheel_memory_size(void)
@@ -300,82 +285,10 @@ erts_timer_wheel_memory_size(void)
return (Uint) TIW_SIZE * sizeof(ErlTimer*);
}
-#if defined(ERTS_TIMER_THREAD)
-static struct erts_iwait *timer_thread_iwait;
-
-static int timer_thread_setup_delay(SysTimeval *rem_time)
-{
- long elapsed;
- int ticks;
-
- erts_smp_mtx_lock(&tiw_lock);
- elapsed = do_time_update();
- ticks = next_time_internal();
- if (ticks == -1) /* timer queue empty */
- ticks = 100*1000*1000;
- if (elapsed > ticks)
- elapsed = ticks;
- ticks -= elapsed;
- //ticks *= CLOCK_RESOLUTION;
- rem_time->tv_sec = ticks / 1000;
- rem_time->tv_usec = 1000 * (ticks % 1000);
- ticks_end = ticks;
- erts_smp_mtx_unlock(&tiw_lock);
- return ticks;
-}
-
-static void *timer_thread_start(void *ignore)
-{
- SysTimeval delay;
-
-#ifdef ERTS_ENABLE_LOCK_CHECK
- erts_lc_set_thread_name("timer");
-#endif
- erts_register_blockable_thread();
-
- for(;;) {
- if (timer_thread_setup_delay(&delay)) {
- erts_smp_activity_begin(ERTS_ACTIVITY_WAIT, NULL, NULL, NULL);
- ASSERT_NO_LOCKED_LOCKS;
- erts_iwait_wait(timer_thread_iwait, &delay);
- ASSERT_NO_LOCKED_LOCKS;
- erts_smp_activity_end(ERTS_ACTIVITY_WAIT, NULL, NULL, NULL);
- }
- else
- erts_smp_chk_system_block(NULL, NULL, NULL);
- timer_thread_bump_timer();
- ASSERT_NO_LOCKED_LOCKS;
- }
- /*NOTREACHED*/
- return NULL;
-}
-
-static ERTS_INLINE void timer_thread_post_insert(Uint ticks)
-{
- if ((Sint)ticks < ticks_end)
- erts_iwait_interrupt(timer_thread_iwait);
-}
-
-static void timer_thread_init(void)
-{
- erts_thr_opts_t opts = ERTS_THR_OPTS_DEFAULT_INITER;
- erts_tid_t tid;
-
- opts->detached = 1;
-
- timer_thread_iwait = erts_iwait_init();
- erts_thr_create(&tid, timer_thread_start, NULL, &opts);
-}
-
-#else
-static ERTS_INLINE void timer_thread_post_insert(Uint ticks) { }
-static ERTS_INLINE void timer_thread_init(void) { }
-#endif
-
/* this routine links the time cells into a free list at the start
and sets the time queue as empty */
void
-init_time(void)
+erts_init_time(void)
{
int i;
@@ -391,10 +304,13 @@ init_time(void)
tiw[i] = NULL;
do_time_init();
tiw_pos = tiw_nto = 0;
-
- timer_thread_init();
+ tiw_min_ptr = NULL;
+ tiw_min = 0;
}
+
+
+
/*
** Insert a process into the time queue, with a timeout 't'
*/
@@ -424,16 +340,31 @@ insert_timer(ErlTimer* p, Uint t)
/* insert at head of list at slot */
p->next = tiw[tm];
+ p->prev = NULL;
+ if (p->next != NULL)
+ p->next->prev = p;
tiw[tm] = p;
- tiw_nto++;
- timer_thread_post_insert(ticks);
+
+ /* insert min time */
+ if ((tiw_nto == 0) || ((tiw_min_ptr != NULL) && (ticks < tiw_min))) {
+ tiw_min = ticks;
+ tiw_min_ptr = p;
+ }
+ if ((tiw_min_ptr == p) && (ticks > tiw_min)) {
+ /* some other timer might be 'min' now */
+ tiw_min = 0;
+ tiw_min_ptr = NULL;
+ }
+
+ tiw_nto++;
}
void
-erl_set_timer(ErlTimer* p, ErlTimeoutProc timeout, ErlCancelProc cancel,
+erts_set_timer(ErlTimer* p, ErlTimeoutProc timeout, ErlCancelProc cancel,
void* arg, Uint t)
{
+
erts_deliver_time();
erts_smp_mtx_lock(&tiw_lock);
if (p->active) { /* XXX assert ? */
@@ -446,42 +377,34 @@ erl_set_timer(ErlTimer* p, ErlTimeoutProc timeout, ErlCancelProc cancel,
p->active = 1;
insert_timer(p, t);
erts_smp_mtx_unlock(&tiw_lock);
-#if defined(ERTS_SMP) && !defined(ERTS_TIMER_THREAD)
+#if defined(ERTS_SMP)
if (t <= (Uint) LONG_MAX)
erts_sys_schedule_interrupt_timed(1, (long) t);
#endif
}
void
-erl_cancel_timer(ErlTimer* p)
+erts_cancel_timer(ErlTimer* p)
{
- ErlTimer *tp;
- ErlTimer **prev;
-
erts_smp_mtx_lock(&tiw_lock);
if (!p->active) { /* allow repeated cancel (drivers) */
erts_smp_mtx_unlock(&tiw_lock);
return;
}
- /* find p in linked list at slot p->slot and remove it */
- prev = &tiw[p->slot];
- while ((tp = *prev) != NULL) {
- if (tp == p) {
- *prev = p->next; /* Remove from list */
- tiw_nto--;
- p->next = NULL;
- p->slot = p->count = 0;
- p->active = 0;
- if (p->cancel != NULL) {
- erts_smp_mtx_unlock(&tiw_lock);
- (*p->cancel)(p->arg);
- } else {
- erts_smp_mtx_unlock(&tiw_lock);
- }
- return;
- } else {
- prev = &tp->next;
- }
+
+ /* is it the 'min' timer, remove min */
+ if (p == tiw_min_ptr) {
+ tiw_min_ptr = NULL;
+ tiw_min = 0;
+ }
+
+ remove_timer(p);
+ p->slot = p->count = 0;
+
+ if (p->cancel != NULL) {
+ erts_smp_mtx_unlock(&tiw_lock);
+ (*p->cancel)(p->arg);
+ return;
}
erts_smp_mtx_unlock(&tiw_lock);
}
@@ -493,10 +416,10 @@ erl_cancel_timer(ErlTimer* p)
immediately if it hadn't been cancelled).
*/
Uint
-time_left(ErlTimer *p)
+erts_time_left(ErlTimer *p)
{
Uint left;
- long dt;
+ erts_aint_t dt;
erts_smp_mtx_lock(&tiw_lock);
@@ -517,12 +440,11 @@ time_left(ErlTimer *p)
erts_smp_mtx_unlock(&tiw_lock);
- return left * itime;
+ return (Uint) left * itime;
}
#ifdef DEBUG
-
-void p_slpq()
+void erts_p_slpq()
{
int i;
ErlTimer* p;
@@ -551,5 +473,4 @@ void p_slpq()
erts_smp_mtx_unlock(&tiw_lock);
}
-
#endif /* DEBUG */
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index ab5e8b5d4a..f531d1430b 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -59,13 +59,6 @@
/* profile_scheduler mini message queue */
-#ifdef ERTS_TIMER_THREAD
-/* A timer thread is not welcomed with this lock violation work around.
- * - Bj�rn-Egil
- */
-#error Timer thread may not be enabled due to lock violation.
-#endif
-
typedef struct {
Uint scheduler_id;
Uint no_schedulers;
@@ -98,7 +91,7 @@ dispatch_profile_msg_q(profile_sched_msg_q *psmq)
Eterm*
-erts_heap_alloc(Process* p, Uint need)
+erts_heap_alloc(Process* p, Uint need, Uint xtra)
{
ErlHeapFragment* bp;
Eterm* htop;
@@ -124,7 +117,7 @@ erts_heap_alloc(Process* p, Uint need)
p->space_verified_from = NULL;
#endif /* FORCE_HEAP_FRAGS */
- n = need;
+ n = need + xtra;
bp = MBUF(p);
if (bp != NULL && need <= (bp->alloc_size - bp->used_size)) {
Eterm* ret = bp->mem + bp->used_size;
@@ -160,7 +153,7 @@ erts_heap_alloc(Process* p, Uint need)
bp->next = MBUF(p);
MBUF(p) = bp;
bp->alloc_size = n;
- bp->used_size = n;
+ bp->used_size = need;
MBUF_SIZE(p) += n;
bp->off_heap.first = NULL;
bp->off_heap.overhead = 0;
@@ -1901,34 +1894,36 @@ erts_destroy_tmp_dsbuf(erts_dsprintf_buf_t *dsbufp)
erts_free(ERTS_ALC_T_TMP_DSBUF, (void *) dsbufp);
}
-
/* eq and cmp are written as separate functions a eq is a little faster */
/*
* Test for equality of two terms.
* Returns 0 if not equal, or a non-zero value otherwise.
*/
-
+#if HALFWORD_HEAP
+int eq_rel(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base)
+#else
int eq(Eterm a, Eterm b)
+#endif
{
DECLARE_WSTACK(stack);
Sint sz;
Eterm* aa;
- Eterm* bb;
+ Eterm* bb;
tailrecur:
- if (a == b) goto pop_next;
+ if (is_same(a, a_base, b, b_base)) goto pop_next;
tailrecur_ne:
switch (primary_tag(a)) {
case TAG_PRIMARY_LIST:
if (is_list(b)) {
- Eterm* aval = list_val(a);
- Eterm* bval = list_val(b);
+ Eterm* aval = list_val_rel(a, a_base);
+ Eterm* bval = list_val_rel(b, b_base);
while (1) {
Eterm atmp = CAR(aval);
Eterm btmp = CAR(bval);
- if (atmp != btmp) {
+ if (!is_same(atmp,a_base,btmp,b_base)) {
WSTACK_PUSH2(stack,(UWord) CDR(bval),(UWord) CDR(aval));
a = atmp;
b = btmp;
@@ -1936,7 +1931,7 @@ tailrecur_ne:
}
atmp = CDR(aval);
btmp = CDR(bval);
- if (atmp == btmp) {
+ if (is_same(atmp,a_base,btmp,b_base)) {
goto pop_next;
}
if (is_not_list(atmp) || is_not_list(btmp)) {
@@ -1944,22 +1939,22 @@ tailrecur_ne:
b = btmp;
goto tailrecur_ne;
}
- aval = list_val(atmp);
- bval = list_val(btmp);
+ aval = list_val_rel(atmp, a_base);
+ bval = list_val_rel(btmp, b_base);
}
}
break; /* not equal */
case TAG_PRIMARY_BOXED:
{
- Eterm hdr = *boxed_val(a);
+ Eterm hdr = *boxed_val_rel(a,a_base);
switch (hdr & _TAG_HEADER_MASK) {
case ARITYVAL_SUBTAG:
{
- aa = tuple_val(a);
- if (!is_boxed(b) || *boxed_val(b) != *aa)
+ aa = tuple_val_rel(a, a_base);
+ if (!is_boxed(b) || *boxed_val_rel(b,b_base) != *aa)
goto not_equal;
- bb = tuple_val(b);
+ bb = tuple_val_rel(b,b_base);
if ((sz = arityval(*aa)) == 0) goto pop_next;
++aa;
++bb;
@@ -1978,16 +1973,16 @@ tailrecur_ne:
Uint a_bitoffs;
Uint b_bitoffs;
- if (is_not_binary(b)) {
+ if (!is_binary_rel(b,b_base)) {
goto not_equal;
}
- a_size = binary_size(a);
- b_size = binary_size(b);
+ a_size = binary_size_rel(a,a_base);
+ b_size = binary_size_rel(b,b_base);
if (a_size != b_size) {
goto not_equal;
}
- ERTS_GET_BINARY_BYTES(a, a_ptr, a_bitoffs, a_bitsize);
- ERTS_GET_BINARY_BYTES(b, b_ptr, b_bitoffs, b_bitsize);
+ ERTS_GET_BINARY_BYTES_REL(a, a_ptr, a_bitoffs, a_bitsize, a_base);
+ ERTS_GET_BINARY_BYTES_REL(b, b_ptr, b_bitoffs, b_bitsize, b_base);
if ((a_bitsize | b_bitsize | a_bitoffs | b_bitoffs) == 0) {
if (sys_memcmp(a_ptr, b_ptr, a_size) == 0) goto pop_next;
} else if (a_bitsize == b_bitsize) {
@@ -1998,9 +1993,9 @@ tailrecur_ne:
}
case EXPORT_SUBTAG:
{
- if (is_export(b)) {
- Export* a_exp = *((Export **) (export_val(a) + 1));
- Export* b_exp = *((Export **) (export_val(b) + 1));
+ if (is_export_rel(b,b_base)) {
+ Export* a_exp = *((Export **) (export_val_rel(a,a_base) + 1));
+ Export* b_exp = *((Export **) (export_val_rel(b,b_base) + 1));
if (a_exp == b_exp) goto pop_next;
}
break; /* not equal */
@@ -2010,10 +2005,10 @@ tailrecur_ne:
ErlFunThing* f1;
ErlFunThing* f2;
- if (is_not_fun(b))
+ if (!is_fun_rel(b,b_base))
goto not_equal;
- f1 = (ErlFunThing *) fun_val(a);
- f2 = (ErlFunThing *) fun_val(b);
+ f1 = (ErlFunThing *) fun_val_rel(a,a_base);
+ f2 = (ErlFunThing *) fun_val_rel(b,b_base);
if (f1->fe->module != f2->fe->module ||
f1->fe->old_index != f2->fe->old_index ||
f1->fe->old_uniq != f2->fe->old_uniq ||
@@ -2031,15 +2026,15 @@ tailrecur_ne:
ExternalThing *ap;
ExternalThing *bp;
- if(is_not_external(b))
+ if(!is_external_rel(b,b_base))
goto not_equal;
- ap = external_thing_ptr(a);
- bp = external_thing_ptr(b);
+ ap = external_thing_ptr_rel(a,a_base);
+ bp = external_thing_ptr_rel(b,b_base);
if(ap->header == bp->header && ap->node == bp->node) {
- ASSERT(1 == external_data_words(a));
- ASSERT(1 == external_data_words(b));
+ ASSERT(1 == external_data_words_rel(a,a_base));
+ ASSERT(1 == external_data_words_rel(b,b_base));
if (ap->data.ui[0] == bp->data.ui[0]) goto pop_next;
}
@@ -2057,27 +2052,36 @@ tailrecur_ne:
Uint alen;
Uint blen;
Uint i;
+ ExternalThing* athing;
+ ExternalThing* bthing;
- if(is_not_external_ref(b))
+ if(!is_external_ref_rel(b,b_base))
goto not_equal;
- if(external_node(a) != external_node(b))
+ athing = external_thing_ptr_rel(a,a_base);
+ bthing = external_thing_ptr_rel(b,b_base);
+
+ if(athing->node != bthing->node)
goto not_equal;
- anum = external_ref_numbers(a);
- bnum = external_ref_numbers(b);
- alen = external_ref_no_of_numbers(a);
- blen = external_ref_no_of_numbers(b);
+ anum = external_thing_ref_numbers(athing);
+ bnum = external_thing_ref_numbers(bthing);
+ alen = external_thing_ref_no_of_numbers(athing);
+ blen = external_thing_ref_no_of_numbers(bthing);
goto ref_common;
case REF_SUBTAG:
-
- if (is_not_internal_ref(b))
+ if (!is_internal_ref_rel(b,b_base))
goto not_equal;
- alen = internal_ref_no_of_numbers(a);
- blen = internal_ref_no_of_numbers(b);
- anum = internal_ref_numbers(a);
- bnum = internal_ref_numbers(b);
+
+ {
+ RefThing* athing = ref_thing_ptr_rel(a,a_base);
+ RefThing* bthing = ref_thing_ptr_rel(b,b_base);
+ alen = internal_thing_ref_no_of_numbers(athing);
+ blen = internal_thing_ref_no_of_numbers(bthing);
+ anum = internal_thing_ref_numbers(athing);
+ bnum = internal_thing_ref_numbers(bthing);
+ }
ref_common:
ASSERT(alen > 0 && blen > 0);
@@ -2122,10 +2126,10 @@ tailrecur_ne:
{
int i;
- if (is_not_big(b))
+ if (!is_big_rel(b,b_base))
goto not_equal;
- aa = big_val(a); /* get pointer to thing */
- bb = big_val(b);
+ aa = big_val_rel(a,a_base);
+ bb = big_val_rel(b,b_base);
if (*aa != *bb)
goto not_equal;
i = BIG_ARITY(aa);
@@ -2140,9 +2144,9 @@ tailrecur_ne:
FloatDef af;
FloatDef bf;
- if (is_float(b)) {
- GET_DOUBLE(a, af);
- GET_DOUBLE(b, bf);
+ if (is_float_rel(b,b_base)) {
+ GET_DOUBLE_REL(a, af, a_base);
+ GET_DOUBLE_REL(b, bf, b_base);
if (af.fd == bf.fd) goto pop_next;
}
break; /* not equal */
@@ -2161,7 +2165,7 @@ term_array: /* arrays in 'aa' and 'bb', length in 'sz' */
Eterm* bp = bb;
Sint i = sz;
for (;;) {
- if (*ap != *bp) break;
+ if (!is_same(*ap,a_base,*bp,b_base)) break;
if (--i == 0) goto pop_next;
++ap;
++bp;
@@ -2250,7 +2254,11 @@ static int cmp_atoms(Eterm a, Eterm b)
bb->name+3, bb->len-3);
}
+#if HALFWORD_HEAP
+Sint cmp_rel(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base)
+#else
Sint cmp(Eterm a, Eterm b)
+#endif
{
DECLARE_WSTACK(stack);
Eterm* aa;
@@ -2284,7 +2292,7 @@ Sint cmp(Eterm a, Eterm b)
tailrecur:
- if (a == b) { /* Equal values or pointers. */
+ if (is_same(a,a_base,b,b_base)) { /* Equal values or pointers. */
goto pop_next;
}
tailrecur_ne:
@@ -2310,9 +2318,9 @@ tailrecur_ne:
if (is_internal_port(b)) {
bnode = erts_this_node;
bdata = internal_port_data(b);
- } else if (is_external_port(b)) {
- bnode = external_port_node(b);
- bdata = external_port_data(b);
+ } else if (is_external_port_rel(b,b_base)) {
+ bnode = external_port_node_rel(b,b_base);
+ bdata = external_port_data_rel(b,b_base);
} else {
a_tag = PORT_DEF;
goto mixed_types;
@@ -2328,9 +2336,9 @@ tailrecur_ne:
if (is_internal_pid(b)) {
bnode = erts_this_node;
bdata = internal_pid_data(b);
- } else if (is_external_pid(b)) {
- bnode = external_pid_node(b);
- bdata = external_pid_data(b);
+ } else if (is_external_pid_rel(b,b_base)) {
+ bnode = external_pid_node_rel(b,b_base);
+ bdata = external_pid_data_rel(b,b_base);
} else {
a_tag = PID_DEF;
goto mixed_types;
@@ -2363,12 +2371,12 @@ tailrecur_ne:
a_tag = LIST_DEF;
goto mixed_types;
}
- aa = list_val(a);
- bb = list_val(b);
+ aa = list_val_rel(a,a_base);
+ bb = list_val_rel(b,b_base);
while (1) {
Eterm atmp = CAR(aa);
Eterm btmp = CAR(bb);
- if (atmp != btmp) {
+ if (!is_same(atmp,a_base,btmp,b_base)) {
WSTACK_PUSH2(stack,(UWord) CDR(bb),(UWord) CDR(aa));
a = atmp;
b = btmp;
@@ -2376,7 +2384,7 @@ tailrecur_ne:
}
atmp = CDR(aa);
btmp = CDR(bb);
- if (atmp == btmp) {
+ if (is_same(atmp,a_base,btmp,b_base)) {
goto pop_next;
}
if (is_not_list(atmp) || is_not_list(btmp)) {
@@ -2384,20 +2392,20 @@ tailrecur_ne:
b = btmp;
goto tailrecur_ne;
}
- aa = list_val(atmp);
- bb = list_val(btmp);
+ aa = list_val_rel(atmp,a_base);
+ bb = list_val_rel(btmp,b_base);
}
case TAG_PRIMARY_BOXED:
{
- Eterm ahdr = *boxed_val(a);
+ Eterm ahdr = *boxed_val_rel(a,a_base);
switch ((ahdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {
case (_TAG_HEADER_ARITYVAL >> _TAG_PRIMARY_SIZE):
- if (is_not_tuple(b)) {
+ if (!is_tuple_rel(b,b_base)) {
a_tag = TUPLE_DEF;
goto mixed_types;
}
- aa = tuple_val(a);
- bb = tuple_val(b);
+ aa = tuple_val_rel(a,a_base);
+ bb = tuple_val_rel(b,b_base);
/* compare the arities */
i = arityval(ahdr); /* get the arity*/
if (i != arityval(*bb)) {
@@ -2411,31 +2419,31 @@ tailrecur_ne:
goto term_array;
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
- if (is_not_float(b)) {
+ if (!is_float_rel(b,b_base)) {
a_tag = FLOAT_DEF;
goto mixed_types;
} else {
FloatDef af;
FloatDef bf;
- GET_DOUBLE(a, af);
- GET_DOUBLE(b, bf);
+ GET_DOUBLE_REL(a, af, a_base);
+ GET_DOUBLE_REL(b, bf, b_base);
ON_CMP_GOTO(float_comp(af.fd, bf.fd));
}
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
- if (is_not_big(b)) {
+ if (!is_big_rel(b,b_base)) {
a_tag = BIG_DEF;
goto mixed_types;
}
- ON_CMP_GOTO(big_comp(a, b));
+ ON_CMP_GOTO(big_comp(rterm2wterm(a,a_base), rterm2wterm(b,b_base)));
case (_TAG_HEADER_EXPORT >> _TAG_PRIMARY_SIZE):
- if (is_not_export(b)) {
+ if (!is_export_rel(b,b_base)) {
a_tag = EXPORT_DEF;
goto mixed_types;
} else {
- Export* a_exp = *((Export **) (export_val(a) + 1));
- Export* b_exp = *((Export **) (export_val(b) + 1));
+ Export* a_exp = *((Export **) (export_val_rel(a,a_base) + 1));
+ Export* b_exp = *((Export **) (export_val_rel(b,b_base) + 1));
if ((j = cmp_atoms(a_exp->code[0], b_exp->code[0])) != 0) {
RETURN_NEQ(j);
@@ -2447,12 +2455,12 @@ tailrecur_ne:
}
break;
case (_TAG_HEADER_FUN >> _TAG_PRIMARY_SIZE):
- if (is_not_fun(b)) {
+ if (!is_fun_rel(b,b_base)) {
a_tag = FUN_DEF;
goto mixed_types;
} else {
- ErlFunThing* f1 = (ErlFunThing *) fun_val(a);
- ErlFunThing* f2 = (ErlFunThing *) fun_val(b);
+ ErlFunThing* f1 = (ErlFunThing *) fun_val_rel(a,a_base);
+ ErlFunThing* f2 = (ErlFunThing *) fun_val_rel(b,b_base);
Sint diff;
diff = cmpbytes(atom_tab(atom_val(f1->fe->module))->name,
@@ -2484,51 +2492,57 @@ tailrecur_ne:
if (is_internal_pid(b)) {
bnode = erts_this_node;
bdata = internal_pid_data(b);
- } else if (is_external_pid(b)) {
- bnode = external_pid_node(b);
- bdata = external_pid_data(b);
+ } else if (is_external_pid_rel(b,b_base)) {
+ bnode = external_pid_node_rel(b,b_base);
+ bdata = external_pid_data_rel(b,b_base);
} else {
a_tag = EXTERNAL_PID_DEF;
goto mixed_types;
}
- anode = external_pid_node(a);
- adata = external_pid_data(a);
+ anode = external_pid_node_rel(a,a_base);
+ adata = external_pid_data_rel(a,a_base);
goto pid_common;
case (_TAG_HEADER_EXTERNAL_PORT >> _TAG_PRIMARY_SIZE):
if (is_internal_port(b)) {
bnode = erts_this_node;
bdata = internal_port_data(b);
- } else if (is_external_port(b)) {
- bnode = external_port_node(b);
- bdata = external_port_data(b);
+ } else if (is_external_port_rel(b,b_base)) {
+ bnode = external_port_node_rel(b,b_base);
+ bdata = external_port_data_rel(b,b_base);
} else {
a_tag = EXTERNAL_PORT_DEF;
goto mixed_types;
}
- anode = external_port_node(a);
- adata = external_port_data(a);
+ anode = external_port_node_rel(a,a_base);
+ adata = external_port_data_rel(a,a_base);
goto port_common;
case (_TAG_HEADER_REF >> _TAG_PRIMARY_SIZE):
/*
* Note! When comparing refs we need to compare ref numbers
* (32-bit words), *not* ref data words.
*/
+
- if (is_internal_ref(b)) {
+ if (is_internal_ref_rel(b,b_base)) {
+ RefThing* bthing = ref_thing_ptr_rel(b,b_base);
bnode = erts_this_node;
- bnum = internal_ref_numbers(b);
- blen = internal_ref_no_of_numbers(b);
- } else if(is_external_ref(b)) {
- bnode = external_ref_node(b);
- bnum = external_ref_numbers(b);
- blen = external_ref_no_of_numbers(b);
+ bnum = internal_thing_ref_numbers(bthing);
+ blen = internal_thing_ref_no_of_numbers(bthing);
+ } else if(is_external_ref_rel(b,b_base)) {
+ ExternalThing* bthing = external_thing_ptr_rel(b,b_base);
+ bnode = bthing->node;
+ bnum = external_thing_ref_numbers(bthing);
+ blen = external_thing_ref_no_of_numbers(bthing);
} else {
a_tag = REF_DEF;
goto mixed_types;
}
- anode = erts_this_node;
- anum = internal_ref_numbers(a);
- alen = internal_ref_no_of_numbers(a);
+ {
+ RefThing* athing = ref_thing_ptr_rel(a,a_base);
+ anode = erts_this_node;
+ anum = internal_thing_ref_numbers(athing);
+ alen = internal_thing_ref_no_of_numbers(athing);
+ }
ref_common:
CMP_NODES(anode, bnode);
@@ -2557,31 +2571,36 @@ tailrecur_ne:
RETURN_NEQ((Sint32) (anum[i] - bnum[i]));
goto pop_next;
case (_TAG_HEADER_EXTERNAL_REF >> _TAG_PRIMARY_SIZE):
- if (is_internal_ref(b)) {
+ if (is_internal_ref_rel(b,b_base)) {
+ RefThing* bthing = ref_thing_ptr_rel(b,b_base);
bnode = erts_this_node;
- bnum = internal_ref_numbers(b);
- blen = internal_ref_no_of_numbers(b);
- } else if (is_external_ref(b)) {
- bnode = external_ref_node(b);
- bnum = external_ref_numbers(b);
- blen = external_ref_no_of_numbers(b);
+ bnum = internal_thing_ref_numbers(bthing);
+ blen = internal_thing_ref_no_of_numbers(bthing);
+ } else if (is_external_ref_rel(b,b_base)) {
+ ExternalThing* bthing = external_thing_ptr_rel(b,b_base);
+ bnode = bthing->node;
+ bnum = external_thing_ref_numbers(bthing);
+ blen = external_thing_ref_no_of_numbers(bthing);
} else {
a_tag = EXTERNAL_REF_DEF;
goto mixed_types;
}
- anode = external_ref_node(a);
- anum = external_ref_numbers(a);
- alen = external_ref_no_of_numbers(a);
+ {
+ ExternalThing* athing = external_thing_ptr_rel(a,a_base);
+ anode = athing->node;
+ anum = external_thing_ref_numbers(athing);
+ alen = external_thing_ref_no_of_numbers(athing);
+ }
goto ref_common;
default:
/* Must be a binary */
- ASSERT(is_binary(a));
- if (is_not_binary(b)) {
+ ASSERT(is_binary_rel(a,a_base));
+ if (!is_binary_rel(b,b_base)) {
a_tag = BINARY_DEF;
goto mixed_types;
} else {
- Uint a_size = binary_size(a);
- Uint b_size = binary_size(b);
+ Uint a_size = binary_size_rel(a,a_base);
+ Uint b_size = binary_size_rel(b,b_base);
Uint a_bitsize;
Uint b_bitsize;
Uint a_bitoffs;
@@ -2590,8 +2609,8 @@ tailrecur_ne:
int cmp;
byte* a_ptr;
byte* b_ptr;
- ERTS_GET_BINARY_BYTES(a, a_ptr, a_bitoffs, a_bitsize);
- ERTS_GET_BINARY_BYTES(b, b_ptr, b_bitoffs, b_bitsize);
+ ERTS_GET_BINARY_BYTES_REL(a, a_ptr, a_bitoffs, a_bitsize, a_base);
+ ERTS_GET_BINARY_BYTES_REL(b, b_ptr, b_bitoffs, b_bitsize, b_base);
if ((a_bitsize | b_bitsize | a_bitoffs | b_bitoffs) == 0) {
min_size = (a_size < b_size) ? a_size : b_size;
if ((cmp = sys_memcmp(a_ptr, b_ptr, min_size)) != 0) {
@@ -2618,7 +2637,6 @@ tailrecur_ne:
*/
mixed_types:
- b_tag = tag_val_def(b);
{
FloatDef f1, f2;
@@ -2628,39 +2646,47 @@ tailrecur_ne:
#else
Eterm *big_buf = erts_get_scheduler_data()->cmp_tmp_heap;
#endif
+#if HALFWORD_HEAP
+ Wterm aw = is_immed(a) ? a : rterm2wterm(a,a_base);
+ Wterm bw = is_immed(b) ? b : rterm2wterm(b,b_base);
+#else
+ Eterm aw = a;
+ Eterm bw = b;
+#endif
+ b_tag = tag_val_def(bw);
switch(_NUMBER_CODE(a_tag, b_tag)) {
case SMALL_BIG:
big = small_to_big(signed_val(a), big_buf);
- j = big_comp(big, b);
+ j = big_comp(big, bw);
break;
case SMALL_FLOAT:
f1.fd = signed_val(a);
- GET_DOUBLE(b, f2);
+ GET_DOUBLE(bw, f2);
j = float_comp(f1.fd, f2.fd);
break;
case BIG_SMALL:
big = small_to_big(signed_val(b), big_buf);
- j = big_comp(a, big);
+ j = big_comp(aw, big);
break;
case BIG_FLOAT:
- if (big_to_double(a, &f1.fd) < 0) {
+ if (big_to_double(aw, &f1.fd) < 0) {
j = big_sign(a) ? -1 : 1;
} else {
- GET_DOUBLE(b, f2);
+ GET_DOUBLE(bw, f2);
j = float_comp(f1.fd, f2.fd);
}
break;
case FLOAT_SMALL:
- GET_DOUBLE(a, f1);
+ GET_DOUBLE(aw, f1);
f2.fd = signed_val(b);
j = float_comp(f1.fd, f2.fd);
break;
case FLOAT_BIG:
- if (big_to_double(b, &f2.fd) < 0) {
+ if (big_to_double(bw, &f2.fd) < 0) {
j = big_sign(b) ? 1 : -1;
} else {
- GET_DOUBLE(a, f1);
+ GET_DOUBLE(aw, f1);
j = float_comp(f1.fd, f2.fd);
}
break;
@@ -3183,7 +3209,7 @@ erts_create_smp_ptimer(ErtsSmpPTimer **timer_ref,
*timer_ref = res;
- erl_set_timer(&res->timer.tm,
+ erts_set_timer(&res->timer.tm,
(ErlTimeoutProc) ptimer_timeout,
(ErlCancelProc) ptimer_cancelled,
(void*) res,
@@ -3197,7 +3223,7 @@ erts_cancel_smp_ptimer(ErtsSmpPTimer *ptimer)
ASSERT(*ptimer->timer.timer_ref == ptimer);
*ptimer->timer.timer_ref = NULL;
ptimer->timer.flags |= ERTS_PTMR_FLG_CANCELLED;
- erl_cancel_timer(&ptimer->timer.tm);
+ erts_cancel_timer(&ptimer->timer.tm);
}
}
@@ -3637,19 +3663,19 @@ erts_set_activity_error(erts_activity_error_t error, char *file, int line)
}
-static ERTS_INLINE int
+static ERTS_INLINE erts_aint32_t
threads_not_under_control(void)
{
- int res = system_block_state.threads_to_block;
+ erts_aint32_t res = system_block_state.threads_to_block;
/* Waiting is always an allowed activity... */
- res -= erts_smp_atomic_read(&erts_system_block_state.in_activity.wait);
+ res -= erts_smp_atomic32_read(&erts_system_block_state.in_activity.wait);
if (system_block_state.allowed_activities & ERTS_BS_FLG_ALLOW_GC)
- res -= erts_smp_atomic_read(&erts_system_block_state.in_activity.gc);
+ res -= erts_smp_atomic32_read(&erts_system_block_state.in_activity.gc);
if (system_block_state.allowed_activities & ERTS_BS_FLG_ALLOW_IO)
- res -= erts_smp_atomic_read(&erts_system_block_state.in_activity.io);
+ res -= erts_smp_atomic32_read(&erts_system_block_state.in_activity.io);
if (res < 0) {
ASSERT(0);
@@ -3709,7 +3735,7 @@ erts_block_system(Uint32 allowed_activities)
}
else {
- erts_smp_atomic_inc(&erts_system_block_state.do_block);
+ erts_smp_atomic32_inc(&erts_system_block_state.do_block);
/* Someone else might be waiting for us to block... */
if (do_block) {
@@ -3761,11 +3787,11 @@ erts_emergency_block_system(long timeout, Uint32 allowed_activities)
another_blocker = erts_smp_pending_system_block();
system_block_state.emergency = 1;
- erts_smp_atomic_inc(&erts_system_block_state.do_block);
+ erts_smp_atomic32_inc(&erts_system_block_state.do_block);
if (another_blocker) {
if (is_blocker()) {
- erts_smp_atomic_dec(&erts_system_block_state.do_block);
+ erts_smp_atomic32_dec(&erts_system_block_state.do_block);
res = 0;
goto done;
}
@@ -3822,7 +3848,7 @@ erts_release_system(void)
if (system_block_state.recursive_block)
system_block_state.recursive_block--;
else {
- do_block = erts_smp_atomic_dectest(&erts_system_block_state.do_block);
+ do_block = erts_smp_atomic32_dectest(&erts_system_block_state.do_block);
system_block_state.have_blocker = 0;
if (is_blockable_thread())
system_block_state.threads_to_block++;
@@ -3957,10 +3983,10 @@ erts_system_block_init(void)
/* Global state... */
- erts_smp_atomic_init(&erts_system_block_state.do_block, 0L);
- erts_smp_atomic_init(&erts_system_block_state.in_activity.wait, 0L);
- erts_smp_atomic_init(&erts_system_block_state.in_activity.gc, 0L);
- erts_smp_atomic_init(&erts_system_block_state.in_activity.io, 0L);
+ erts_smp_atomic32_init(&erts_system_block_state.do_block, 0);
+ erts_smp_atomic32_init(&erts_system_block_state.in_activity.wait, 0);
+ erts_smp_atomic32_init(&erts_system_block_state.in_activity.gc, 0);
+ erts_smp_atomic32_init(&erts_system_block_state.in_activity.io, 0);
/* Make sure blockable threads unregister when exiting... */
erts_smp_install_exit_handler(erts_unregister_blockable_thread);
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c
index c450f10f48..6449c6f506 100644
--- a/erts/emulator/drivers/common/efile_drv.c
+++ b/erts/emulator/drivers/common/efile_drv.c
@@ -67,6 +67,8 @@
#define FILE_RESP_LDATA 6
#define FILE_RESP_N2DATA 7
#define FILE_RESP_EOF 8
+#define FILE_RESP_FNAME 9
+#define FILE_RESP_ALL_DATA 10
/* Options */
@@ -109,11 +111,11 @@ void erl_exit(int n, char *fmt, ...);
static ErlDrvSysInfo sys_info;
-/*#define TRACE 1*/
+/* #define TRACE 1 */
#ifdef TRACE
-# define TRACE_C(c) (putchar(c))
-# define TRACE_S(s) (fputs((s), stdout))
-# define TRACE_F(args) (printf args)
+# define TRACE_C(c) do { putchar(c); fflush(stdout); } while (0)
+# define TRACE_S(s) do { fputs((s), stdout); fflush(stdout); } while (0)
+# define TRACE_F(args) do { printf args ;fflush(stdout); } while (0)
#else
# define TRACE_C(c) ((void)(0))
# define TRACE_S(s) ((void)(0))
@@ -137,24 +139,54 @@ static ErlDrvSysInfo sys_info;
#define MUTEX_UNLOCK(m)
#endif
-
-
#if 0
/* Experimental, for forcing all file operations to use the same thread. */
-static unsigned file_fixed_key = 1;
-#define KEY(desc) (&file_fixed_key)
+ static unsigned file_fixed_key = 1;
+# define KEY(desc) (&file_fixed_key)
#else
-#define KEY(desc) (&(desc)->key)
+# define KEY(desc) (&(desc)->key)
#endif
+#ifdef FILENAMES_16BIT
+# define FILENAME_BYTELEN(Str) filename_len_16bit(Str)
+# define FILENAME_COPY(To,From) filename_cpy_16bit((To),(From))
+# define FILENAME_CHARSIZE 2
+
+ static int filename_len_16bit(char *str)
+ {
+ char *p = str;
+ while(*p != '\0' || p[1] != '\0') {
+ p += 2;
+ }
+ return (p - str);
+ }
+
+ static void filename_cpy_16bit(char *to, char *from)
+ {
+ while(*from != '\0' || from[1] != '\0') {
+ *to++ = *from++;
+ *to++ = *from++;
+ }
+ *to++ = *from++;
+ *to++ = *from++;
+ }
+
+#else
+# define FILENAME_BYTELEN(Str) strlen(Str)
+# define FILENAME_COPY(To,From) strcpy(To,From)
+# define FILENAME_CHARSIZE 1
+#endif
-#if MAXPATHLEN >= BUFSIZ
-#define RESBUFSIZE MAXPATHLEN+1
+#if (MAXPATHLEN+1)*FILENAME_CHARSIZE+1 > BUFSIZ
+# define RESBUFSIZE ((MAXPATHLEN+1)*FILENAME_CHARSIZE+1)
#else
-#define RESBUFSIZE BUFSIZ
+# define RESBUFSIZE BUFSIZ
#endif
+
+
+
#define GET_TIME(i, b) \
(i).year = get_int32((b) + 0 * 4); \
(i).month = get_int32((b) + 1 * 4); \
@@ -286,9 +318,9 @@ struct t_preadv {
};
#define READDIR_BUFSIZE (8*1024)
-#if READDIR_BUFSIZE < (2*MAXPATHLEN)
-#undef READDIR_BUFSIZE
-#define READDIR_BUFSIZE (2*MAXPATHLEN)
+#if READDIR_BUFSIZE < (FILENAME_CHARSIZE*2*(MAXPATHLEN+1))
+# undef READDIR_BUFSIZE
+# define READDIR_BUFSIZE (FILENAME_CHARSIZE*2*(MAXPATHLEN+1))
#endif
struct t_readdir_buf {
@@ -353,7 +385,6 @@ struct t_data
ErlDrvBinary *binp;
int size;
int offset;
- char name[1];
} read_file;
struct {
struct t_readdir_buf *first_buf;
@@ -369,6 +400,7 @@ struct t_data
};
+
#define EF_ALLOC(S) driver_alloc((S))
#define EF_REALLOC(P, S) driver_realloc((P), (S))
#define EF_SAFE_ALLOC(S) ef_safe_alloc((S))
@@ -1084,7 +1116,7 @@ static void invoke_read_file(void *data)
Sint64 size;
if (! (d->result_ok =
- efile_openfile(&d->errInfo, d->c.read_file.name,
+ efile_openfile(&d->errInfo, d->b,
EFILE_MODE_READ, &fd, &size))) {
goto done;
}
@@ -1288,7 +1320,7 @@ static void invoke_writev(void *data) {
p < size && iovcnt < iovlen;
p += iov0[iovcnt++].iov_len)
;
- iov = EF_ALLOC(sizeof(SysIOVec)*iovcnt);
+ iov = EF_SAFE_ALLOC(sizeof(SysIOVec)*iovcnt);
memcpy(iov,iov0,iovcnt*sizeof(SysIOVec));
MUTEX_UNLOCK(d->c.writev.q_mtx);
/* Let go of lock until we deque from original vector */
@@ -1368,7 +1400,7 @@ static void invoke_readlink(void *data)
d->result_ok = efile_readlink(&d->errInfo, d->b, resbuf+1,
RESBUFSIZE-1);
if (d->result_ok != 0)
- strcpy((char *) d->b + 1, resbuf+1);
+ FILENAME_COPY((char *) d->b + 1, resbuf+1);
}
static void invoke_altname(void *data)
@@ -1380,7 +1412,7 @@ static void invoke_altname(void *data)
d->result_ok = efile_altname(&d->errInfo, d->b, resbuf+1,
RESBUFSIZE-1);
if (d->result_ok != 0)
- strcpy((char *) d->b + 1, resbuf+1);
+ FILENAME_COPY((char *) d->b + 1, resbuf+1);
}
static void invoke_pwritev(void *data) {
@@ -1405,7 +1437,7 @@ static void invoke_pwritev(void *data) {
/* Lock the queue just for a while, we don't want it locked during write */
MUTEX_LOCK(c->q_mtx);
iov0 = driver_peekq(c->port, &iovlen);
- iov = EF_ALLOC(sizeof(SysIOVec)*iovlen);
+ iov = EF_SAFE_ALLOC(sizeof(SysIOVec)*iovlen);
memcpy(iov,iov0,sizeof(SysIOVec)*iovlen);
MUTEX_UNLOCK(c->q_mtx);
@@ -1499,7 +1531,7 @@ static void invoke_link(void *data)
char *new_name;
d->again = 0;
- new_name = name+strlen(name)+1;
+ new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE;
d->result_ok = efile_link(&d->errInfo, name, new_name);
}
@@ -1510,7 +1542,7 @@ static void invoke_symlink(void *data)
char *new_name;
d->again = 0;
- new_name = name+strlen(name)+1;
+ new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE;
d->result_ok = efile_symlink(&d->errInfo, name, new_name);
}
@@ -1521,7 +1553,7 @@ static void invoke_rename(void *data)
char *new_name;
d->again = 0;
- new_name = name+strlen(name)+1;
+ new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE;
d->result_ok = efile_rename(&d->errInfo, name, new_name);
}
@@ -1569,13 +1601,15 @@ static void invoke_readdir(void *data)
int s;
char *p = NULL;
int buf_sz = 0;
+ size_t tmp_bs;
d->again = 0;
d->errInfo.posix_errno = 0;
while (1) {
char *str;
- if (buf_sz < (4 /* sz */ + 1 /* cmd */ + MAXPATHLEN + 1 /* '\0' */)) {
+ if (buf_sz < (4 /* sz */ + 1 /* cmd */ +
+ FILENAME_CHARSIZE*(MAXPATHLEN + 1))) {
struct t_readdir_buf *b;
if (p) {
put_int32(0, p); /* EOB */
@@ -1591,18 +1625,18 @@ static void invoke_readdir(void *data)
buf_sz = READDIR_BUFSIZE - 4/* EOB */;
}
- p[4] = FILE_RESP_OK;
+ p[4] = FILE_RESP_FNAME;
buf_sz -= 4 + 1;
str = p + 4 + 1;
ASSERT(buf_sz >= MAXPATHLEN + 1);
- s = efile_readdir(&d->errInfo, d->b, &d->dir_handle, str, buf_sz);
+ tmp_bs = buf_sz;
+ s = efile_readdir(&d->errInfo, d->b, &d->dir_handle, str, &tmp_bs);
if (s) {
- int str_sz = strlen(str);
- int sz = str_sz + 1;
- put_int32(sz, p);
- p += 4 + sz;
- buf_sz -= str_sz;
+ put_int32(tmp_bs + 1 /* 1 byte for opcode */, p);
+ p += 4 + tmp_bs + 1;
+ ASSERT(p == (str + tmp_bs));
+ buf_sz -= tmp_bs;
}
else {
put_int32(1, p);
@@ -1911,7 +1945,7 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
if (!d->result_ok)
reply_error(desc, &d->errInfo);
else {
- header[0] = FILE_RESP_OK;
+ header[0] = FILE_RESP_ALL_DATA;
TRACE_C('R');
driver_output_binary(desc->port, header, 1,
d->c.read_file.binp,
@@ -1968,10 +2002,10 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
if (!d->result_ok)
reply_error(desc, &d->errInfo);
else {
- resbuf[0] = FILE_RESP_OK;
- length = 1+strlen((char*) resbuf+1);
+ resbuf[0] = FILE_RESP_FNAME;
+ length = 1+FILENAME_BYTELEN((char*) resbuf+1);
TRACE_C('R');
- driver_output2(desc->port, resbuf, length, NULL, 0);
+ driver_output2(desc->port, resbuf, 1, resbuf+1, length-1);
}
free_data(data);
break;
@@ -2031,13 +2065,18 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
int sz = get_int32(p);
while (sz) { /* 0 == EOB */
p += 4;
- driver_output2(desc->port, p, sz, NULL, 0);
+ if (sz - 1 > 0) {
+ driver_output2(desc->port, p, 1, p+1, sz-1);
+ } else {
+ driver_output2(desc->port, p, 1, NULL, 0);
+ }
p += sz;
sz = get_int32(p);
}
b1 = b1->next;
EF_FREE(b2);
}
+
d->c.read_dir.first_buf = NULL;
d->c.read_dir.last_buf = NULL;
}
@@ -2113,9 +2152,9 @@ file_output(ErlDrvData e, char* buf, int count)
case FILE_MKDIR:
{
- d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1);
+ d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE);
- strcpy(d->b, name);
+ FILENAME_COPY(d->b, name);
d->command = command;
d->invoke = invoke_mkdir;
d->free = free_data;
@@ -2124,9 +2163,9 @@ file_output(ErlDrvData e, char* buf, int count)
}
case FILE_RMDIR:
{
- d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1);
+ d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE);
- strcpy(d->b, name);
+ FILENAME_COPY(d->b, name);
d->command = command;
d->invoke = invoke_rmdir;
d->free = free_data;
@@ -2135,9 +2174,9 @@ file_output(ErlDrvData e, char* buf, int count)
}
case FILE_DELETE:
{
- d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1);
+ d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE);
- strcpy(d->b, name);
+ FILENAME_COPY(d->b, name);
d->command = command;
d->invoke = invoke_delete_file;
d->free = free_data;
@@ -2147,14 +2186,14 @@ file_output(ErlDrvData e, char* buf, int count)
case FILE_RENAME:
{
char* new_name;
-
- new_name = name+strlen(name)+1;
+ int namelen = FILENAME_BYTELEN(name)+FILENAME_CHARSIZE;
+ new_name = name+namelen;
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1
- + strlen(name) + 1
- + strlen(new_name) + 1);
+ + namelen
+ + FILENAME_BYTELEN(new_name) + FILENAME_CHARSIZE);
- strcpy(d->b, name);
- strcpy(d->b + strlen(name) + 1, new_name);
+ FILENAME_COPY(d->b, name);
+ FILENAME_COPY(d->b + namelen, new_name);
d->flags = desc->flags;
d->fd = fd;
d->command = command;
@@ -2165,9 +2204,9 @@ file_output(ErlDrvData e, char* buf, int count)
}
case FILE_CHDIR:
{
- d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1);
+ d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE);
- strcpy(d->b, name);
+ FILENAME_COPY(d->b, name);
d->command = command;
d->invoke = invoke_chdir;
d->free = free_data;
@@ -2190,9 +2229,10 @@ file_output(ErlDrvData e, char* buf, int count)
#ifdef USE_THREADS
if (sys_info.async_threads > 0)
{
- d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1);
+ d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) +
+ FILENAME_CHARSIZE);
- strcpy(d->b, name);
+ FILENAME_COPY(d->b, name);
d->dir_handle = NULL;
d->command = command;
d->invoke = invoke_readdir;
@@ -2205,17 +2245,19 @@ file_output(ErlDrvData e, char* buf, int count)
else
#endif
{
+ size_t resbufsize;
char resbuf[RESBUFSIZE+1];
EFILE_DIR_HANDLE dir_handle; /* Handle to open directory. */
errInfo.posix_errno = 0;
dir_handle = NULL;
- resbuf[0] = FILE_RESP_OK;
+ resbuf[0] = FILE_RESP_FNAME;
+ resbufsize = RESBUFSIZE;
while (efile_readdir(&errInfo, name, &dir_handle,
- resbuf+1, RESBUFSIZE)) {
- int length = 1 + strlen(resbuf+1);
- driver_output2(desc->port, resbuf, length, NULL, 0);
+ resbuf+1, &resbufsize)) {
+ driver_output2(desc->port, resbuf, 1, resbuf+1, resbufsize);
+ resbufsize = RESBUFSIZE;
}
if (errInfo.posix_errno != 0) {
reply_error(desc, &errInfo);
@@ -2227,11 +2269,12 @@ file_output(ErlDrvData e, char* buf, int count)
}
case FILE_OPEN:
{
- d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(buf+4) + 1);
+ d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(buf+4) +
+ FILENAME_CHARSIZE);
d->flags = get_int32((uchar*)buf);
name = buf+4;
- strcpy(d->b, name);
+ FILENAME_COPY(d->b, name);
d->command = command;
d->invoke = invoke_open;
d->free = free_data;
@@ -2240,44 +2283,45 @@ file_output(ErlDrvData e, char* buf, int count)
}
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));
-
- d->fd = fd;
- d->command = command;
- d->invoke = invoke_fsync;
- d->free = free_data;
- d->level = 2;
- goto done;
- }
+ {
+ d = EF_SAFE_ALLOC(sizeof(struct t_data));
+
+ d->fd = fd;
+ d->command = command;
+ d->invoke = invoke_fsync;
+ d->free = free_data;
+ d->level = 2;
+ goto done;
+ }
case FILE_FSTAT:
case FILE_LSTAT:
- {
- d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1);
+ {
+ d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) +
+ FILENAME_CHARSIZE);
+
+ FILENAME_COPY(d->b, name);
+ d->fd = fd;
+ d->command = command;
+ d->invoke = invoke_flstat;
+ d->free = free_data;
+ d->level = 2;
+ goto done;
+ }
- strcpy(d->b, name);
- d->fd = fd;
- d->command = command;
- d->invoke = invoke_flstat;
- d->free = free_data;
- d->level = 2;
- goto done;
- }
-
case FILE_TRUNCATE:
{
d = EF_SAFE_ALLOC(sizeof(struct t_data));
@@ -2294,7 +2338,7 @@ file_output(ErlDrvData e, char* buf, int count)
case FILE_WRITE_INFO:
{
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1
- + strlen(buf+21*4) + 1);
+ + FILENAME_BYTELEN(buf+21*4) + FILENAME_CHARSIZE);
d->info.mode = get_int32(buf + 0 * 4);
d->info.uid = get_int32(buf + 1 * 4);
@@ -2302,7 +2346,7 @@ file_output(ErlDrvData e, char* buf, int count)
GET_TIME(d->info.accessTime, buf + 3 * 4);
GET_TIME(d->info.modifyTime, buf + 9 * 4);
GET_TIME(d->info.cTime, buf + 15 * 4);
- strcpy(d->b, buf+21*4);
+ FILENAME_COPY(d->b, buf+21*4);
d->command = command;
d->invoke = invoke_write_info;
d->free = free_data;
@@ -2314,7 +2358,7 @@ file_output(ErlDrvData e, char* buf, int count)
{
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + RESBUFSIZE + 1);
- strcpy(d->b, name);
+ FILENAME_COPY(d->b, name);
d->command = command;
d->invoke = invoke_readlink;
d->free = free_data;
@@ -2323,28 +2367,29 @@ file_output(ErlDrvData e, char* buf, int count)
}
case FILE_ALTNAME:
- {
- d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + RESBUFSIZE + 1);
- strcpy(d->b, name);
- d->command = command;
- d->invoke = invoke_altname;
- d->free = free_data;
- d->level = 2;
- goto done;
- }
+ {
+ d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + RESBUFSIZE + 1);
+ FILENAME_COPY(d->b, name);
+ d->command = command;
+ d->invoke = invoke_altname;
+ d->free = free_data;
+ d->level = 2;
+ goto done;
+ }
case FILE_LINK:
{
char* new_name;
+ int namelen = FILENAME_BYTELEN(name) + FILENAME_CHARSIZE;
- new_name = name+strlen(name)+1;
+ new_name = name+namelen;
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1
- + strlen(name) + 1
- + strlen(new_name) + 1);
+ + namelen
+ + FILENAME_BYTELEN(new_name) + FILENAME_CHARSIZE);
- strcpy(d->b, name);
- strcpy(d->b + strlen(name) + 1, new_name);
+ FILENAME_COPY(d->b, name);
+ FILENAME_COPY(d->b + namelen, new_name);
d->flags = desc->flags;
d->fd = fd;
d->command = command;
@@ -2357,14 +2402,15 @@ file_output(ErlDrvData e, char* buf, int count)
case FILE_SYMLINK:
{
char* new_name;
+ int namelen = FILENAME_BYTELEN(name) + FILENAME_CHARSIZE;
- new_name = name+strlen(name)+1;
+ new_name = name+namelen;
d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1
- + strlen(name) + 1
- + strlen(new_name) + 1);
+ + namelen
+ + FILENAME_BYTELEN(new_name) + FILENAME_CHARSIZE);
- strcpy(d->b, name);
- strcpy(d->b + strlen(name) + 1, new_name);
+ FILENAME_COPY(d->b, name);
+ FILENAME_COPY(d->b + namelen, new_name);
d->flags = desc->flags;
d->fd = fd;
d->command = command;
@@ -3004,6 +3050,7 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
case FILE_READ_FILE: {
struct t_data *d;
+ char *filename;
if (ev->size < 1+1) {
/* Buffer contains empty name */
reply_posix_error(desc, ENOENT);
@@ -3014,7 +3061,8 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
reply_posix_error(desc, EINVAL);
goto done;
}
- d = EF_ALLOC(sizeof(struct t_data) + ev->size);
+ filename = EV_CHAR_P(ev, p, q);
+ d = EF_ALLOC(sizeof(struct t_data) -1 + FILENAME_BYTELEN(filename) + FILENAME_CHARSIZE);
if (! d) {
reply_posix_error(desc, ENOMEM);
goto done;
@@ -3022,8 +3070,7 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) {
d->command = command;
d->reply = !0;
/* Copy name */
- memcpy(d->c.read_file.name, EV_CHAR_P(ev, p, q), ev->size-1);
- d->c.read_file.name[ev->size-1] = '\0';
+ FILENAME_COPY(d->b, filename);
d->c.read_file.binp = NULL;
d->invoke = invoke_read_file;
d->free = free_read_file;
diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h
index ac95c1f949..3097ded3f1 100644
--- a/erts/emulator/drivers/common/erl_efile.h
+++ b/erts/emulator/drivers/common/erl_efile.h
@@ -59,6 +59,14 @@
#define FA_WRITE 1
#define FA_READ 2
+/* Some OS'es (i.e. Windows) has filenames in wide charaqcters. That requires special handling */
+/* Note that we do *not* honor alignment in the communication to the OS specific driver, */
+/* which is not a problem on x86, but might be on other platforms. The OS specific efile */
+/* implementation is expected to align if needed */
+#ifdef __WIN32__
+#define FILENAMES_16BIT 1
+#endif
+
/*
* An handle to an open directory. To be cast to the correct type
* in the system-dependent directory functions.
@@ -123,7 +131,7 @@ int efile_getdcwd(Efile_error* errInfo, int drive,
char* buffer, size_t size);
int efile_readdir(Efile_error* errInfo, char* name,
EFILE_DIR_HANDLE* dir_handle,
- char* buffer, size_t size);
+ char* buffer, size_t *size);
int efile_openfile(Efile_error* errInfo, char* name, int flags,
int* pfd, Sint64* pSize);
void efile_closefile(int fd);
diff --git a/erts/emulator/drivers/common/gzio.c b/erts/emulator/drivers/common/gzio.c
index 801bc61d4d..5531a275ea 100644
--- a/erts/emulator/drivers/common/gzio.c
+++ b/erts/emulator/drivers/common/gzio.c
@@ -28,6 +28,7 @@
#ifdef __WIN32__
#define HAVE_CONFLICTING_FREAD_DECLARATION
+#define FILENAMES_16BIT 1
#endif
#ifdef STDC
@@ -102,6 +103,40 @@ local uLong getLong OF((gz_stream *s));
# define ERTS_GZREAD(File, Buf, Count) fread((Buf), 1, (Count), (File))
#endif
+/*
+ * Ripped from efile_drv.c
+ */
+
+#ifdef FILENAMES_16BIT
+# define FILENAME_BYTELEN(Str) filename_len_16bit(Str)
+# define FILENAME_COPY(To,From) filename_cpy_16bit((To),(From))
+# define FILENAME_CHARSIZE 2
+
+ static int filename_len_16bit(const char *str)
+ {
+ const char *p = str;
+ while(*p != '\0' || p[1] != '\0') {
+ p += 2;
+ }
+ return (p - str);
+ }
+
+ static void filename_cpy_16bit(char *to, const char *from)
+ {
+ while(*from != '\0' || from[1] != '\0') {
+ *to++ = *from++;
+ *to++ = *from++;
+ }
+ *to++ = *from++;
+ *to++ = *from++;
+ }
+
+#else
+# define FILENAME_BYTELEN(Str) strlen(Str)
+# define FILENAME_COPY(To,From) strcpy(To,From)
+# define FILENAME_CHARSIZE 1
+#endif
+
/* ===========================================================================
Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb"). The file is given either by file descriptor
@@ -144,11 +179,11 @@ local gzFile gz_open (path, mode)
s->position = 0;
s->destroy = destroy;
- s->path = (char*)ALLOC(strlen(path)+1);
+ s->path = (char*)ALLOC(FILENAME_BYTELEN(path)+FILENAME_CHARSIZE);
if (s->path == NULL) {
return s->destroy(s), (gzFile)Z_NULL;
}
- strcpy(s->path, path); /* do this early for debugging */
+ FILENAME_COPY(s->path, path); /* do this early for debugging */
s->mode = '\0';
do {
@@ -194,7 +229,22 @@ local gzFile gz_open (path, mode)
s->stream.avail_out = Z_BUFSIZE;
errno = 0;
-#ifdef UNIX
+#if defined(FILENAMES_16BIT)
+ {
+ char wfmode[160];
+ int i=0,j;
+ for(j=0;fmode[j] != '\0';++j) {
+ wfmode[i++]=fmode[j];
+ wfmode[i++]='\0';
+ }
+ wfmode[i++] = '\0';
+ wfmode[i++] = '\0';
+ s->file = F_OPEN(path, wfmode);
+ if (s->file == NULL) {
+ return s->destroy(s), (gzFile)Z_NULL;
+ }
+ }
+#elif defined(UNIX)
if (s->mode == 'r') {
s->file = open(path, O_RDONLY);
} else {
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 3de48194fb..b491242aea 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1997-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -54,6 +54,9 @@
#ifdef HAVE_IFADDRS_H
#include <ifaddrs.h>
#endif
+#ifdef HAVE_NETPACKET_PACKET_H
+#include <netpacket/packet.h>
+#endif
/* All platforms fail on malloc errors. */
#define FATAL_MALLOC
@@ -85,8 +88,21 @@
#include <winsock2.h>
#endif
#include <windows.h>
+#include <Ws2tcpip.h> /* NEED VC 6.0 or higher */
+
+/* Visual studio 2008+: NTDDI_VERSION needs to be set for iphlpapi.h
+ to define the right structures. It needs to be set to WINXP (or LONGHORN)
+ for IPV6 to work and it's set lower by default, so we need to change it. */
+#ifdef HAVE_SDKDDKVER_H
+# include <sdkddkver.h>
+# ifdef NTDDI_VERSION
+# undef NTDDI_VERSION
+# endif
+# define NTDDI_VERSION NTDDI_WINXP
+#endif
+
+#include <iphlpapi.h>
-#include <Ws2tcpip.h> /* NEED VC 6.0 !!! */
#undef WANT_NONBLOCKING
#include "sys.h"
@@ -467,6 +483,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)
#define INET_REQ_IFGET 22
#define INET_REQ_IFSET 23
#define INET_REQ_SUBSCRIBE 24
+#define INET_REQ_GETIFADDRS 25
/* TCP requests */
#define TCP_REQ_ACCEPT 40
#define TCP_REQ_LISTEN 41
@@ -632,15 +649,12 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)
#define IS_BUSY(d) \
(((d)->state & INET_F_BUSY) == INET_F_BUSY)
+#define INET_MAX_OPT_BUFFER (64*1024)
+
#define INET_DEF_BUFFER 1460 /* default buffer size */
#define INET_MIN_BUFFER 1 /* internal min buffer */
-#define INET_MAX_BUFFER (1024*64) /* internal max buffer */
-/* Note: INET_HIGH_WATERMARK MUST be less than 2*INET_MAX_BUFFER */
#define INET_HIGH_WATERMARK (1024*8) /* 8k pending high => busy */
-/* Note: INET_LOW_WATERMARK MUST be less than INET_MAX_BUFFER and
-** less than INET_HIGH_WATERMARK
-*/
#define INET_LOW_WATERMARK (1024*4) /* 4k pending => allow more */
#define INET_INFINITY 0xffffffff /* infinity value */
@@ -1251,139 +1265,136 @@ static int load_ip_and_port
LOAD_ATOM((spec), (i), (flag) ? am_true : am_false);
#endif /* HAVE_SCTP */
+/* Assume a cache line size of 64 bytes */
+#define INET_DRV_CACHE_LINE_SIZE ((ErlDrvUInt) 64)
+#define INET_DRV_CACHE_LINE_MASK (INET_DRV_CACHE_LINE_SIZE - 1)
+
/*
** Binary Buffer Managment
** We keep a stack of usable buffers
*/
-#define BUFFER_STACK_SIZE 16
-
-static erts_smp_spinlock_t inet_buffer_stack_lock;
-static ErlDrvBinary* buffer_stack[BUFFER_STACK_SIZE];
-static int buffer_stack_pos = 0;
+#define BUFFER_STACK_SIZE 14
+#define BUFFER_STACK_MAX_MEM_SIZE (1024*1024)
+ErlDrvTSDKey buffer_stack_key;
-/*
- * XXX
- * The erts_smp_spin_* functions should not be used by drivers (but this
- * driver is special). Replace when driver locking api has been implemented.
- * /rickard
- */
-#define BUFSTK_LOCK erts_smp_spin_lock(&inet_buffer_stack_lock);
-#define BUFSTK_UNLOCK erts_smp_spin_unlock(&inet_buffer_stack_lock);
-
-#ifdef DEBUG
-static int tot_buf_allocated = 0; /* memory in use for i_buf */
-static int tot_buf_stacked = 0; /* memory on stack */
-static int max_buf_allocated = 0; /* max allocated */
-
-#define COUNT_BUF_ALLOC(sz) do { \
- BUFSTK_LOCK; \
- tot_buf_allocated += (sz); \
- if (tot_buf_allocated > max_buf_allocated) \
- max_buf_allocated = tot_buf_allocated; \
- BUFSTK_UNLOCK; \
-} while(0)
-
-#define COUNT_BUF_FREE(sz) do { \
- BUFSTK_LOCK; \
- tot_buf_allocated -= (sz); \
- BUFSTK_UNLOCK; \
- } while(0)
-
-#define COUNT_BUF_STACK(sz) do { \
- BUFSTK_LOCK; \
- tot_buf_stacked += (sz); \
- BUFSTK_UNLOCK; \
- } while(0)
+typedef struct {
+ int mem_size;
+ int pos;
+ ErlDrvBinary* stk[BUFFER_STACK_SIZE];
+} InetDrvBufStkBase;
-#else
+typedef struct {
+ InetDrvBufStkBase buf;
+ char align[(((sizeof(InetDrvBufStkBase) - 1) / INET_DRV_CACHE_LINE_SIZE) + 1)
+ * INET_DRV_CACHE_LINE_SIZE];
+} InetDrvBufStk;
+
+static InetDrvBufStk *get_bufstk(void)
+{
+ InetDrvBufStk *bs = erl_drv_tsd_get(buffer_stack_key);
+ if (bs)
+ return bs;
+ bs = driver_alloc(sizeof(InetDrvBufStk)
+ + INET_DRV_CACHE_LINE_SIZE - 1);
+ if (!bs)
+ return NULL;
+ if ((((ErlDrvUInt) bs) & INET_DRV_CACHE_LINE_MASK) != 0)
+ bs = ((InetDrvBufStk *)
+ ((((ErlDrvUInt) bs) & ~INET_DRV_CACHE_LINE_MASK)
+ + INET_DRV_CACHE_LINE_SIZE));
+ erl_drv_tsd_set(buffer_stack_key, bs);
+ bs->buf.pos = 0;
+ bs->buf.mem_size = 0;
-#define COUNT_BUF_ALLOC(sz)
-#define COUNT_BUF_FREE(sz)
-#define COUNT_BUF_STACK(sz)
+ ASSERT(bs == erl_drv_tsd_get(buffer_stack_key));
-#endif
+ return bs;
+}
static ErlDrvBinary* alloc_buffer(long minsz)
{
- ErlDrvBinary* buf = NULL;
+ InetDrvBufStk *bs = get_bufstk();
+
+ DEBUGF(("alloc_buffer: %ld\r\n", minsz));
+
+ if (bs && bs->buf.pos > 0) {
+ long size;
+ ErlDrvBinary* buf = bs->buf.stk[--bs->buf.pos];
+ size = buf->orig_size;
+ bs->buf.mem_size -= size;
+ ASSERT(0 <= bs->buf.mem_size
+ && bs->buf.mem_size <= BUFFER_STACK_MAX_MEM_SIZE);
+ if (size >= minsz)
+ return buf;
- BUFSTK_LOCK;
+ driver_free_binary(buf);
+ }
- DEBUGF(("alloc_buffer: sz = %ld, tot = %d, max = %d\r\n",
- minsz, tot_buf_allocated, max_buf_allocated));
+ ASSERT(!bs || bs->buf.pos != 0 || bs->buf.mem_size == 0);
- if (buffer_stack_pos > 0) {
- int origsz;
+ return driver_alloc_binary(minsz);
+}
- buf = buffer_stack[--buffer_stack_pos];
- origsz = buf->orig_size;
- BUFSTK_UNLOCK;
- COUNT_BUF_STACK(-origsz);
- if (origsz < minsz) {
- if ((buf = driver_realloc_binary(buf, minsz)) == NULL)
- return NULL;
- COUNT_BUF_ALLOC(buf->orig_size - origsz);
+/*#define CHECK_DOUBLE_RELEASE 1*/
+#ifdef CHECK_DOUBLE_RELEASE
+static void
+check_double_release(InetDrvBufStk *bs, ErlDrvBinary* buf)
+{
+#ifdef __GNUC__
+#warning CHECK_DOUBLE_RELEASE is enabled, this is a custom build emulator
+#endif
+ int i;
+ for (i = 0; i < bs->buf.pos; ++i) {
+ if (bs->buf.stk[i] == buf) {
+ erl_exit(ERTS_ABORT_EXIT,
+ "Multiple buffer release in inet_drv, this "
+ "is a bug, save the core and send it to "
}
}
- else {
- BUFSTK_UNLOCK;
- if ((buf = driver_alloc_binary(minsz)) == NULL)
- return NULL;
- COUNT_BUF_ALLOC(buf->orig_size);
- }
- return buf;
}
+#endif
-/*
-** Max buffer memory "cached" BUFFER_STACK_SIZE * INET_MAX_BUFFER
-** (16 * 64k ~ 1M)
-*/
-/*#define CHECK_DOUBLE_RELEASE 1*/
static void release_buffer(ErlDrvBinary* buf)
{
+ InetDrvBufStk *bs;
+ long size;
+
DEBUGF(("release_buffer: %ld\r\n", (buf==NULL) ? 0 : buf->orig_size));
- if (buf == NULL)
+
+ if (!buf)
return;
- BUFSTK_LOCK;
- if ((buf->orig_size > INET_MAX_BUFFER) ||
- (buffer_stack_pos >= BUFFER_STACK_SIZE)) {
- BUFSTK_UNLOCK;
- COUNT_BUF_FREE(buf->orig_size);
+
+ size = buf->orig_size;
+
+ if (size > BUFFER_STACK_MAX_MEM_SIZE)
+ goto free_binary;
+
+ bs = get_bufstk();
+ if (!bs
+ || (bs->buf.mem_size + size > BUFFER_STACK_MAX_MEM_SIZE)
+ || (bs->buf.pos >= BUFFER_STACK_SIZE)) {
+ free_binary:
driver_free_binary(buf);
}
else {
#ifdef CHECK_DOUBLE_RELEASE
-#ifdef __GNUC__
-#warning CHECK_DOUBLE_RELEASE is enabled, this is a custom build emulator
+ check_double_release(bs, buf);
#endif
- int i;
- for (i = 0; i < buffer_stack_pos; ++i) {
- if (buffer_stack[i] == buf) {
- erl_exit(1,"Multiple buffer release in inet_drv, this is a "
- "bug, save the core and send it to "
- }
- }
-#endif
- buffer_stack[buffer_stack_pos++] = buf;
- BUFSTK_UNLOCK;
- COUNT_BUF_STACK(buf->orig_size);
+ ASSERT(bs->buf.pos != 0 || bs->buf.mem_size == 0);
+
+ bs->buf.mem_size += size;
+ bs->buf.stk[bs->buf.pos++] = buf;
+
+ ASSERT(0 <= bs->buf.mem_size
+ && bs->buf.mem_size <= BUFFER_STACK_MAX_MEM_SIZE);
}
}
static ErlDrvBinary* realloc_buffer(ErlDrvBinary* buf, long newsz)
{
- ErlDrvBinary* bin;
-#ifdef DEBUG
- long orig_size = buf->orig_size;
-#endif
-
- if ((bin = driver_realloc_binary(buf,newsz)) != NULL) {
- COUNT_BUF_ALLOC(newsz - orig_size);
- ;
- }
- return bin;
+ return driver_realloc_binary(buf, newsz);
}
/* use a TRICK, access the refc field to see if any one else has
@@ -1397,10 +1408,8 @@ static void free_buffer(ErlDrvBinary* buf)
if (buf != NULL) {
if (driver_binary_get_refc(buf) == 1)
release_buffer(buf);
- else {
- COUNT_BUF_FREE(buf->orig_size);
+ else
driver_free_binary(buf);
- }
}
}
@@ -3404,20 +3413,14 @@ static int inet_init()
if (!sock_init())
goto error;
- buffer_stack_pos = 0;
-
- erts_smp_spinlock_init(&inet_buffer_stack_lock, "inet_buffer_stack_lock");
+ if (0 != erl_drv_tsd_key_create("inet_buffer_stack_key", &buffer_stack_key))
+ goto error;
ASSERT(sizeof(struct in_addr) == 4);
# if defined(HAVE_IN6) && defined(AF_INET6)
ASSERT(sizeof(struct in6_addr) == 16);
# endif
-#ifdef DEBUG
- tot_buf_allocated = 0;
- max_buf_allocated = 0;
- tot_buf_stacked = 0;
-#endif
INIT_ATOM(ok);
INIT_ATOM(tcp);
INIT_ATOM(udp);
@@ -3824,39 +3827,81 @@ do { if ((end)-(ptr) < (n)) goto error; } while(0)
static char* sockaddr_to_buf(struct sockaddr* addr, char* ptr, char* end)
{
if (addr->sa_family == AF_INET || addr->sa_family == 0) {
- struct in_addr a;
- buf_check(ptr,end,sizeof(struct in_addr));
- a = ((struct sockaddr_in*) addr)->sin_addr;
- sys_memcpy(ptr, (char*)&a, sizeof(struct in_addr));
- return ptr + sizeof(struct in_addr);
+ struct in_addr *p = &(((struct sockaddr_in*) addr)->sin_addr);
+ buf_check(ptr, end, 1 + sizeof(struct in_addr));
+ *ptr = INET_AF_INET;
+ sys_memcpy(ptr+1, (char*)p, sizeof(struct in_addr));
+ return ptr + 1 + sizeof(struct in_addr);
}
#if defined(HAVE_IN6) && defined(AF_INET6)
else if (addr->sa_family == AF_INET6) {
- struct in6_addr a;
- buf_check(ptr,end,sizeof(struct in6_addr));
- a = ((struct sockaddr_in6*) addr)->sin6_addr;
- sys_memcpy(ptr, (char*)&a, sizeof(struct in6_addr));
- return ptr + sizeof(struct in6_addr);
+ struct in6_addr *p = &(((struct sockaddr_in6*) addr)->sin6_addr);
+ buf_check(ptr, end, 1 + sizeof(struct in6_addr));
+ *ptr = INET_AF_INET6;
+ sys_memcpy(ptr+1, (char*)p, sizeof(struct in6_addr));
+ return ptr + 1 + sizeof(struct in6_addr);
+ }
+#endif
+#if defined(AF_LINK)
+ else if (addr->sa_family == AF_LINK) {
+ struct sockaddr_dl *sdl_p = (struct sockaddr_dl*) addr;
+ buf_check(ptr, end, 2 + sdl_p->sdl_alen);
+ put_int16(sdl_p->sdl_alen, ptr); ptr += 2;
+ sys_memcpy(ptr, sdl_p->sdl_data + sdl_p->sdl_nlen, sdl_p->sdl_alen);
+ return ptr + sdl_p->sdl_alen;
+ }
+#endif
+#if defined(AF_PACKET) && defined(HAVE_NETPACKET_PACKET_H)
+ else if(addr->sa_family == AF_PACKET) {
+ struct sockaddr_ll *sll_p = (struct sockaddr_ll*) addr;
+ buf_check(ptr, end, 2 + sll_p->sll_halen);
+ put_int16(sll_p->sll_halen, ptr); ptr += 2;
+ sys_memcpy(ptr, sll_p->sll_addr, sll_p->sll_halen);
+ return ptr + sll_p->sll_halen;
}
#endif
+ return ptr;
error:
return NULL;
-
}
static char* buf_to_sockaddr(char* ptr, char* end, struct sockaddr* addr)
{
- buf_check(ptr,end,sizeof(struct in_addr));
- sys_memcpy((char*) &((struct sockaddr_in*)addr)->sin_addr, ptr,
- sizeof(struct in_addr));
- addr->sa_family = AF_INET;
- return ptr + sizeof(struct in_addr);
-
+ buf_check(ptr,end,1);
+ switch (*ptr++) {
+ case INET_AF_INET: {
+ struct in_addr *p = &((struct sockaddr_in*)addr)->sin_addr;
+ buf_check(ptr,end,sizeof(struct in_addr));
+ sys_memcpy((char*) p, ptr, sizeof(struct in_addr));
+ addr->sa_family = AF_INET;
+ return ptr + sizeof(struct in_addr);
+ }
+ case INET_AF_INET6: {
+ struct in6_addr *p = &((struct sockaddr_in6*)addr)->sin6_addr;
+ buf_check(ptr,end,sizeof(struct in6_addr));
+ sys_memcpy((char*) p, ptr, sizeof(struct in6_addr));
+ addr->sa_family = AF_INET6;
+ return ptr + sizeof(struct in6_addr);
+ }
+ }
error:
return NULL;
}
+#if defined (IFF_POINTOPOINT)
+#define IFGET_FLAGS(cflags) IFGET_FLAGS_P2P(cflags, IFF_POINTOPOINT)
+#elif defined IFF_POINTTOPOINT
+#define IFGET_FLAGS(cflags) IFGET_FLAGS_P2P(cflags, IFF_POINTTOPOINT)
+#endif
+
+#define IFGET_FLAGS_P2P(cflags, iff_ptp) \
+ ((((cflags) & IFF_UP) ? INET_IFF_UP : 0) | \
+ (((cflags) & IFF_BROADCAST) ? INET_IFF_BROADCAST : 0) | \
+ (((cflags) & IFF_LOOPBACK) ? INET_IFF_LOOPBACK : 0) | \
+ (((cflags) & iff_ptp) ? INET_IFF_POINTTOPOINT : 0) | \
+ (((cflags) & IFF_UP) ? INET_IFF_RUNNING : 0) | /* emulate running ? */ \
+ (((cflags) & IFF_MULTICAST) ? INET_IFF_MULTICAST : 0))
#if defined(__WIN32__) && defined(SIO_GET_INTERFACE_LIST)
@@ -3894,7 +3939,6 @@ static int inet_ctl_getiflist(inet_descriptor* desc, char** rbuf, int rsize)
return ctl_reply(INET_REP_OK, sbuf, sptr - sbuf, rbuf, rsize);
}
-
/* input is an ip-address in string format i.e A.B.C.D
** scan the INTERFACE_LIST to get the options
*/
@@ -3980,27 +4024,12 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len,
break;
case INET_IFOPT_FLAGS: {
- long eflags = 0;
int flags = ifp->iiFlags;
/* just enumerate the interfaces (no names) */
- /* translate flags */
- if (flags & IFF_UP)
- eflags |= INET_IFF_UP;
- if (flags & IFF_BROADCAST)
- eflags |= INET_IFF_BROADCAST;
- if (flags & IFF_LOOPBACK)
- eflags |= INET_IFF_LOOPBACK;
- if (flags & IFF_POINTTOPOINT)
- eflags |= INET_IFF_POINTTOPOINT;
- if (flags & IFF_UP) /* emulate runnign ? */
- eflags |= INET_IFF_RUNNING;
- if (flags & IFF_MULTICAST)
- eflags |= INET_IFF_MULTICAST;
-
buf_check(sptr, s_end, 5);
*sptr++ = INET_IFOPT_FLAGS;
- put_int32(eflags, sptr);
+ put_int32(IFGET_FLAGS(flags), sptr);
sptr += 4;
break;
}
@@ -4021,7 +4050,6 @@ static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len,
return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize);
}
-
#elif defined(SIOCGIFCONF) && defined(SIOCSIFFLAGS)
/* cygwin has SIOCGIFCONF but not SIOCSIFFLAGS (Nov 2002) */
@@ -4032,69 +4060,77 @@ static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len,
#define SIZEA(p) (sizeof (p))
#endif
-
-static int inet_ctl_getiflist(inet_descriptor* desc, char** rbuf, int rsize)
-{
- struct ifconf ifc;
- struct ifreq *ifr;
- char *buf;
- int buflen, ifc_len, i;
- char *sbuf, *sp;
-
- /* Courtesy of Per Bergqvist and W. Richard Stevens */
-
- ifc_len = 0;
- buflen = 100 * sizeof(struct ifreq);
- buf = ALLOC(buflen);
+static int get_ifconf(SOCKET s, struct ifconf *ifcp) {
+ int ifc_len = 0;
+ int buflen = 100 * sizeof(struct ifreq);
+ char *buf = ALLOC(buflen);
for (;;) {
- ifc.ifc_len = buflen;
- ifc.ifc_buf = buf;
- if (ioctl(desc->s, SIOCGIFCONF, (char *)&ifc) < 0) {
+ ifcp->ifc_len = buflen;
+ ifcp->ifc_buf = buf;
+ if (ioctl(s, SIOCGIFCONF, (char *)ifcp) < 0) {
int res = sock_errno();
if (res != EINVAL || ifc_len) {
FREE(buf);
- return ctl_error(res, rbuf, rsize);
+ return -1;
}
} else {
- if (ifc.ifc_len == ifc_len) break; /* buf large enough */
- ifc_len = ifc.ifc_len;
+ if (ifcp->ifc_len == ifc_len) break; /* buf large enough */
+ ifc_len = ifcp->ifc_len;
}
buflen += 10 * sizeof(struct ifreq);
buf = (char *)REALLOC(buf, buflen);
}
-
- sp = sbuf = ALLOC(ifc_len+1);
+ return 0;
+}
+
+static void free_ifconf(struct ifconf *ifcp) {
+ FREE(ifcp->ifc_buf);
+}
+
+static int inet_ctl_getiflist(inet_descriptor* desc, char** rbuf, int rsize)
+{
+ struct ifconf ifc;
+ struct ifreq *ifrp;
+ char *sbuf, *sp;
+ int i;
+
+ /* Courtesy of Per Bergqvist and W. Richard Stevens */
+
+ if (get_ifconf(desc->s, &ifc) < 0) {
+ return ctl_error(sock_errno(), rbuf, rsize);
+ }
+
+ sp = sbuf = ALLOC(ifc.ifc_len+1);
*sp++ = INET_REP_OK;
i = 0;
for (;;) {
int n;
-
- ifr = (struct ifreq *) VOIDP(buf + i);
- n = sizeof(ifr->ifr_name) + SIZEA(ifr->ifr_addr);
- if (n < sizeof(*ifr)) n = sizeof(*ifr);
- if (i+n > ifc_len) break;
+
+ ifrp = (struct ifreq *) VOIDP(ifc.ifc_buf + i);
+ n = sizeof(ifrp->ifr_name) + SIZEA(ifrp->ifr_addr);
+ if (n < sizeof(*ifrp)) n = sizeof(*ifrp);
+ if (i+n > ifc.ifc_len) break;
i += n;
-
- switch (ifr->ifr_addr.sa_family) {
+
+ switch (ifrp->ifr_addr.sa_family) {
#if defined(HAVE_IN6) && defined(AF_INET6)
case AF_INET6:
#endif
case AF_INET:
- ASSERT(sp+IFNAMSIZ+1 < sbuf+buflen+1)
- strncpy(sp, ifr->ifr_name, IFNAMSIZ);
+ ASSERT(sp+IFNAMSIZ+1 < sbuf+ifc.ifc_len+1)
+ strncpy(sp, ifrp->ifr_name, IFNAMSIZ);
sp[IFNAMSIZ] = '\0';
sp += strlen(sp), ++sp;
}
-
- if (i >= ifc_len) break;
+
+ if (i >= ifc.ifc_len) break;
}
- FREE(buf);
+ free_ifconf(&ifc);
*rbuf = sbuf;
return sp - sbuf;
}
-
/* FIXME: temporary hack */
#ifndef IFHWADDRLEN
#define IFHWADDRLEN 6
@@ -4133,37 +4169,52 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len,
#ifdef SIOCGIFHWADDR
if (ioctl(desc->s, SIOCGIFHWADDR, (char *)&ifreq) < 0)
break;
- buf_check(sptr, s_end, 1+IFHWADDRLEN);
+ buf_check(sptr, s_end, 1+2+IFHWADDRLEN);
*sptr++ = INET_IFOPT_HWADDR;
+ put_int16(IFHWADDRLEN, sptr); sptr += 2;
/* raw memcpy (fix include autoconf later) */
sys_memcpy(sptr, (char*)(&ifreq.ifr_hwaddr.sa_data), IFHWADDRLEN);
sptr += IFHWADDRLEN;
-#elif defined(HAVE_GETIFADDRS)
- struct ifaddrs *ifa, *ifp;
- int found = 0;
-
- if (getifaddrs(&ifa) == -1)
- goto error;
+#elif defined(SIOCGENADDR)
+ if (ioctl(desc->s, SIOCGENADDR, (char *)&ifreq) < 0)
+ break;
+ buf_check(sptr, s_end, 1+2+sizeof(ifreq.ifr_enaddr));
+ *sptr++ = INET_IFOPT_HWADDR;
+ put_int16(sizeof(ifreq.ifr_enaddr), sptr); sptr += 2;
+ /* raw memcpy (fix include autoconf later) */
+ sys_memcpy(sptr, (char*)(&ifreq.ifr_enaddr),
+ sizeof(ifreq.ifr_enaddr));
+ sptr += sizeof(ifreq.ifr_enaddr);
+#elif defined(HAVE_GETIFADDRS) && defined(AF_LINK)
+ struct ifaddrs *ifa, *ifp;
+ struct sockaddr_dl *sdlp;
+ int found = 0;
+
+ if (getifaddrs(&ifa) == -1)
+ goto error;
- for (ifp = ifa; ifp; ifp = ifp->ifa_next) {
- if ((ifp->ifa_addr->sa_family == AF_LINK) &&
- (sys_strcmp(ifp->ifa_name, ifreq.ifr_name) == 0)) {
- found = 1;
- break;
- }
- }
+ for (ifp = ifa; ifp; ifp = ifp->ifa_next) {
+ if ((ifp->ifa_addr->sa_family == AF_LINK) &&
+ (sys_strcmp(ifp->ifa_name, ifreq.ifr_name) == 0)) {
+ found = 1;
+ break;
+ }
+ }
- if (found == 0) {
- freeifaddrs(ifa);
- break;
- }
+ if (found == 0) {
+ freeifaddrs(ifa);
+ break;
+ }
+ sdlp = (struct sockaddr_dl *)ifp->ifa_addr;
- buf_check(sptr, s_end, 1+IFHWADDRLEN);
- *sptr++ = INET_IFOPT_HWADDR;
- sys_memcpy(sptr, ((struct sockaddr_dl *)ifp->ifa_addr)->sdl_data +
- ((struct sockaddr_dl *)ifp->ifa_addr)->sdl_nlen, IFHWADDRLEN);
- freeifaddrs(ifa);
- sptr += IFHWADDRLEN;
+ buf_check(sptr, s_end, 1+2+sdlp->sdl_alen);
+ *sptr++ = INET_IFOPT_HWADDR;
+ put_int16(sdlp->sdl_alen, sptr); sptr += 2;
+ sys_memcpy(sptr,
+ sdlp->sdl_data + sdlp->sdl_nlen,
+ sdlp->sdl_alen);
+ freeifaddrs(ifa);
+ sptr += sdlp->sdl_alen;
#endif
break;
}
@@ -4240,29 +4291,15 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len,
case INET_IFOPT_FLAGS: {
int flags;
- int eflags = 0;
if (ioctl(desc->s, SIOCGIFFLAGS, (char*)&ifreq) < 0)
flags = 0;
else
flags = ifreq.ifr_flags;
- /* translate flags */
- if (flags & IFF_UP)
- eflags |= INET_IFF_UP;
- if (flags & IFF_BROADCAST)
- eflags |= INET_IFF_BROADCAST;
- if (flags & IFF_LOOPBACK)
- eflags |= INET_IFF_LOOPBACK;
- if (flags & IFF_POINTOPOINT)
- eflags |= INET_IFF_POINTTOPOINT;
- if (flags & IFF_RUNNING)
- eflags |= INET_IFF_RUNNING;
- if (flags & IFF_MULTICAST)
- eflags |= INET_IFF_MULTICAST;
buf_check(sptr, s_end, 5);
*sptr++ = INET_IFOPT_FLAGS;
- put_int32(eflags, sptr);
+ put_int32(IFGET_FLAGS(flags), sptr);
sptr += 4;
break;
}
@@ -4300,17 +4337,22 @@ static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len,
(void) ioctl(desc->s, SIOCSIFADDR, (char*)&ifreq);
break;
- case INET_IFOPT_HWADDR:
- buf_check(buf, b_end, IFHWADDRLEN);
+ case INET_IFOPT_HWADDR: {
+ unsigned int len;
+ buf_check(buf, b_end, 2);
+ len = get_int16(buf); buf += 2;
+ buf_check(buf, b_end, len);
#ifdef SIOCSIFHWADDR
/* raw memcpy (fix include autoconf later) */
- sys_memcpy((char*)(&ifreq.ifr_hwaddr.sa_data), buf, IFHWADDRLEN);
+ sys_memset((char*)(&ifreq.ifr_hwaddr.sa_data),
+ '\0', sizeof(ifreq.ifr_hwaddr.sa_data));
+ sys_memcpy((char*)(&ifreq.ifr_hwaddr.sa_data), buf, len);
(void) ioctl(desc->s, SIOCSIFHWADDR, (char *)&ifreq);
#endif
- buf += IFHWADDRLEN;
+ buf += len;
break;
-
+ }
case INET_IFOPT_BROADADDR:
#ifdef SIOCSIFBRDADDR
@@ -4415,6 +4457,557 @@ static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len,
#endif
+
+
+/* Latin-1 to utf8 */
+
+static int utf8_len(const char *c, int m) {
+ int l;
+ for (l = 0; m; c++, l++, m--) {
+ if (*c == '\0') break;
+ if ((*c & 0x7f) != *c) l++;
+ }
+ return l;
+}
+
+static void utf8_encode(const char *c, int m, char *p) {
+ for (; m; c++, m--) {
+ if (*c == '\0') break;
+ if ((*c & 0x7f) != *c) {
+ *p++ = (char) (0xC0 | (0x03 & (*c >> 6)));
+ *p++ = (char) (0x80 | (0x3F & *c));
+ } else {
+ *p++ = (char) *c;
+ }
+ }
+}
+
+#if defined(__WIN32__)
+
+static void set_netmask_bytes(char *c, int len, int pref_len) {
+ int i, m;
+ for (i = 0, m = pref_len >> 3; i < m && i < len; i++) c[i] = '\xFF';
+ if (i < len) c[i++] = 0xFF << (8 - (pref_len & 7));
+ for (; i < len; i++) c[i] = '\0';
+}
+
+
+int eq_masked_bytes(char *a, char *b, int pref_len) {
+ int i, m;
+ for (i = 0, m = pref_len >> 3; i < m; i++) {
+ if (a[i] != b[i]) return 0;
+ }
+ m = pref_len & 7;
+ if (m) {
+ m = 0xFF & (0xFF << (8 - m));
+ if ((a[i] & m) != (b[i] & m)) return 0;
+ }
+ return !0;
+}
+
+static int inet_ctl_getifaddrs(inet_descriptor* desc_p,
+ char **rbuf_pp, int rsize)
+{
+ int i;
+ DWORD ret, n;
+ IP_INTERFACE_INFO *info_p;
+ MIB_IPADDRTABLE *ip_addrs_p;
+ IP_ADAPTER_ADDRESSES *ip_adaddrs_p, *ia_p;
+
+ char *buf_p;
+ char *buf_alloc_p;
+ int buf_size =512;
+# define BUF_ENSURE(Size) \
+ do { \
+ int NEED_, GOT_ = buf_p - buf_alloc_p; \
+ NEED_ = GOT_ + (Size); \
+ if (NEED_ > buf_size) { \
+ buf_size = NEED_ + 512; \
+ buf_alloc_p = REALLOC(buf_alloc_p, buf_size); \
+ buf_p = buf_alloc_p + GOT_; \
+ } \
+ } while(0)
+# define SOCKADDR_TO_BUF(opt, sa) \
+ do { \
+ if (sa) { \
+ char *P_; \
+ *buf_p++ = (opt); \
+ while (! (P_ = sockaddr_to_buf((sa), buf_p, \
+ buf_alloc_p+buf_size))) { \
+ int GOT_ = buf_p - buf_alloc_p; \
+ buf_size += 512; \
+ buf_alloc_p = REALLOC(buf_alloc_p, buf_size); \
+ buf_p = buf_alloc_p + GOT_; \
+ } \
+ if (P_ == buf_p) { \
+ buf_p--; \
+ } else { \
+ buf_p = P_; \
+ } \
+ } \
+ } while (0)
+
+ {
+ /* Try GetAdaptersAddresses, if it is available */
+ unsigned long ip_adaddrs_size = 16 * 1024;
+ ULONG family = AF_UNSPEC;
+ ULONG flags =
+ GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST |
+ GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME |
+ GAA_FLAG_SKIP_MULTICAST;
+ ULONG (WINAPI *fpGetAdaptersAddresses)
+ (ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
+ HMODULE iphlpapi = GetModuleHandle("iphlpapi");
+ fpGetAdaptersAddresses = (void *)
+ (iphlpapi ?
+ GetProcAddress(iphlpapi, "GetAdaptersAddresses") :
+ NULL);
+ if (fpGetAdaptersAddresses) {
+ ip_adaddrs_p = ALLOC(ip_adaddrs_size);
+ for (i = 17; i; i--) {
+ ret = fpGetAdaptersAddresses(
+ family, flags, NULL, ip_adaddrs_p, &ip_adaddrs_size);
+ ip_adaddrs_p = REALLOC(ip_adaddrs_p, ip_adaddrs_size);
+ if (ret == NO_ERROR) break;
+ if (ret == ERROR_BUFFER_OVERFLOW) continue;
+ i = 0;
+ }
+ if (! i) {
+ FREE(ip_adaddrs_p);
+ ip_adaddrs_p = NULL;
+ }
+ } else ip_adaddrs_p = NULL;
+ }
+
+ {
+ /* Load the IP_INTERFACE_INFO table (only IPv4 interfaces),
+ * reliable source of interface names on XP
+ */
+ unsigned long info_size = 4 * 1024;
+ info_p = ALLOC(info_size);
+ for (i = 17; i; i--) {
+ ret = GetInterfaceInfo(info_p, &info_size);
+ info_p = REALLOC(info_p, info_size);
+ if (ret == NO_ERROR) break;
+ if (ret == ERROR_INSUFFICIENT_BUFFER) continue;
+ i = 0;
+ }
+ if (! i) {
+ FREE(info_p);
+ info_p = NULL;
+ }
+ }
+
+ if (! ip_adaddrs_p) {
+ /* If GetAdaptersAddresses gave nothing we fall back to
+ * MIB_IPADDRTABLE (only IPv4 interfaces)
+ */
+ unsigned long ip_addrs_size = 16 * sizeof(*ip_addrs_p);
+ ip_addrs_p = ALLOC(ip_addrs_size);
+ for (i = 17; i; i--) {
+ ret = GetIpAddrTable(ip_addrs_p, &ip_addrs_size, FALSE);
+ ip_addrs_p = REALLOC(ip_addrs_p, ip_addrs_size);
+ if (ret == NO_ERROR) break;
+ if (ret == ERROR_INSUFFICIENT_BUFFER) continue;
+ i = 0;
+ }
+ if (! i) {
+ if (info_p) FREE(info_p);
+ FREE(ip_addrs_p);
+ return ctl_reply(INET_REP_OK, NULL, 0, rbuf_pp, rsize);
+ }
+ } else ip_addrs_p = NULL;
+
+ buf_p = buf_alloc_p = ALLOC(buf_size);
+ *buf_p++ = INET_REP_OK;
+
+ /* Iterate over MIB_IPADDRTABLE or IP_ADAPTER_ADDRESSES */
+ for (ia_p = NULL, ip_addrs_p ? ((void *)(i = 0)) : (ia_p = ip_adaddrs_p);
+ ip_addrs_p ? (i < ip_addrs_p->dwNumEntries) : (ia_p != NULL);
+ ip_addrs_p ? ((void *)(i++)) : (ia_p = ia_p->Next)) {
+ MIB_IPADDRROW *ipaddrrow_p = NULL;
+ DWORD flags = INET_IFF_MULTICAST;
+ DWORD index = 0;
+ WCHAR *wname_p = NULL;
+ MIB_IFROW ifrow;
+
+ if (ip_addrs_p) {
+ ipaddrrow_p = ip_addrs_p->table + i;
+ index = ipaddrrow_p->dwIndex;
+ } else {
+ index = ia_p->IfIndex;
+ if (ia_p->Flags & IP_ADAPTER_NO_MULTICAST) {
+ flags &= ~INET_IFF_MULTICAST;
+ }
+ }
+index:
+ if (! index) goto done;
+ sys_memzero(&ifrow, sizeof(ifrow));
+ ifrow.dwIndex = index;
+ if (GetIfEntry(&ifrow) != NO_ERROR) break;
+ /* Find the interface name - first try MIB_IFROW.wzname */
+ if (ifrow.wszName[0] != 0) {
+ wname_p = ifrow.wszName;
+ } else {
+ /* Then try IP_ADAPTER_INDEX_MAP.Name (only IPv4 adapters) */
+ int j;
+ for (j = 0; j < info_p->NumAdapters; j++) {
+ if (info_p->Adapter[j].Index == (ULONG) ifrow.dwIndex) {
+ if (info_p->Adapter[j].Name[0] != 0) {
+ wname_p = info_p->Adapter[j].Name;
+ }
+ break;
+ }
+ }
+ }
+ if (wname_p) {
+ int len;
+ /* Convert interface name to UTF-8 */
+ len =
+ WideCharToMultiByte(
+ CP_UTF8, 0, wname_p, -1, NULL, 0, NULL, NULL);
+ if (! len) break;
+ BUF_ENSURE(len);
+ WideCharToMultiByte(
+ CP_UTF8, 0, wname_p, -1, buf_p, len, NULL, NULL);
+ buf_p += len;
+ } else {
+ /* Found no name -
+ * use "MIB_IFROW.dwIndex: MIB_IFROW.bDescr" as name instead */
+ int l;
+ l = utf8_len(ifrow.bDescr, ifrow.dwDescrLen);
+ BUF_ENSURE(9 + l+1);
+ buf_p +=
+ erts_sprintf(
+ buf_p, "%lu: ", (unsigned long) ifrow.dwIndex);
+ utf8_encode(ifrow.bDescr, ifrow.dwDescrLen, buf_p);
+ buf_p += l;
+ *buf_p++ = '\0';
+ }
+ /* Interface flags, often make up broadcast and multicast flags */
+ switch (ifrow.dwType) {
+ case IF_TYPE_ETHERNET_CSMACD:
+ flags |= INET_IFF_BROADCAST;
+ break;
+ case IF_TYPE_SOFTWARE_LOOPBACK:
+ flags |= INET_IFF_LOOPBACK;
+ flags &= ~INET_IFF_MULTICAST;
+ break;
+ default:
+ flags &= ~INET_IFF_MULTICAST;
+ break;
+ }
+ if (ifrow.dwAdminStatus) {
+ flags |= INET_IFF_UP;
+ switch (ifrow.dwOperStatus) {
+ case IF_OPER_STATUS_CONNECTING:
+ flags |= INET_IFF_POINTTOPOINT;
+ break;
+ case IF_OPER_STATUS_CONNECTED:
+ flags |= INET_IFF_RUNNING | INET_IFF_POINTTOPOINT;
+ break;
+ case IF_OPER_STATUS_OPERATIONAL:
+ flags |= INET_IFF_RUNNING;
+ break;
+ }
+ }
+ BUF_ENSURE(1 + 4);
+ *buf_p++ = INET_IFOPT_FLAGS;
+ put_int32(flags, buf_p); buf_p += 4;
+ if (ipaddrrow_p) {
+ /* Legacy implementation through GetIpAddrTable */
+ struct sockaddr_in sin;
+ /* IP Address */
+ sys_memzero(&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = ipaddrrow_p->dwAddr;
+ BUF_ENSURE(1);
+ /* Netmask */
+ SOCKADDR_TO_BUF(INET_IFOPT_ADDR, (struct sockaddr *) &sin);
+ sin.sin_addr.s_addr = ipaddrrow_p->dwMask;
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_NETMASK, (struct sockaddr *) &sin);
+ if (flags & INET_IFF_BROADCAST) {
+ /* Broadcast address - fake it*/
+ sin.sin_addr.s_addr = ipaddrrow_p->dwAddr;
+ sin.sin_addr.s_addr |= ~ipaddrrow_p->dwMask;
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(
+ INET_IFOPT_BROADADDR, (struct sockaddr *) &sin);
+ }
+ } else {
+ IP_ADAPTER_UNICAST_ADDRESS *p;
+ /* IP Address(es) */
+ for (p = ia_p->FirstUnicastAddress;
+ p;
+ p = p->Next)
+ {
+ IP_ADAPTER_PREFIX *q;
+ ULONG shortest_length;
+ struct sockaddr *shortest_p, *sa_p = p->Address.lpSockaddr;
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_ADDR, sa_p);
+ shortest_p = NULL;
+ shortest_length = 0;
+ for (q = ia_p->FirstPrefix;
+ q;
+ q = q->Next) {
+ struct sockaddr *sp_p = q->Address.lpSockaddr;
+ if (sa_p->sa_family != sp_p->sa_family) continue;
+ switch (sa_p->sa_family) {
+ case AF_INET: {
+ struct sockaddr_in sin;
+ DWORD sa, sp, mask;
+ sa = ntohl((DWORD)
+ ((struct sockaddr_in *)
+ sa_p)->sin_addr.s_addr);
+ sp = ntohl((DWORD)
+ ((struct sockaddr_in *)
+ sp_p)->sin_addr.s_addr);
+ mask = 0xFFFFFFFF << (32 - q->PrefixLength);
+ if ((sa & mask) != (sp & mask)) continue;
+ if ((! shortest_p)
+ || q->PrefixLength < shortest_length) {
+ shortest_p = sp_p;
+ shortest_length = q->PrefixLength;
+ }
+ } break;
+ case AF_INET6: {
+ struct sockaddr_in6 sin6;
+ if (!eq_masked_bytes((char *)
+ &((struct sockaddr_in6 *)
+ sa_p)->sin6_addr,
+ (char *)
+ &((struct sockaddr_in6 *)
+ sp_p)->sin6_addr,
+ q->PrefixLength)) {
+ continue;
+ }
+ if ((! shortest_p)
+ || q->PrefixLength < shortest_length) {
+ shortest_p = sp_p;
+ shortest_length = q->PrefixLength;
+ }
+ } break;
+ }
+ }
+ if (! shortest_p) {
+ /* Found no shortest prefix */
+ shortest_p = sa_p;
+ switch (shortest_p->sa_family) {
+ case AF_INET: {
+ /* Fall back to old classfull network addresses */
+ DWORD addr = ntohl(((struct sockaddr_in *)shortest_p)
+ ->sin_addr.s_addr);
+ if (! (addr & 0x800000)) {
+ /* Class A */
+ shortest_length = 8;
+ } else if (! (addr & 0x400000)) {
+ /* Class B */
+ shortest_length = 16;
+ } else if (! (addr & 0x200000)) {
+ /* Class C */
+ shortest_length = 24;
+ } else {
+ shortest_length = 32;
+ }
+ } break;
+ case AF_INET6: {
+ /* Just play it safe */
+ shortest_length = 128;
+ } break;
+ }
+ }
+ switch (shortest_p->sa_family) {
+ case AF_INET: {
+ struct sockaddr_in sin;
+ DWORD mask = 0xFFFFFFFF << (32 - shortest_length);
+ sys_memzero(&sin, sizeof(sin));
+ sin.sin_family = shortest_p->sa_family;
+ sin.sin_addr.s_addr = htonl(mask);
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_NETMASK,
+ (struct sockaddr *) &sin);
+ if (flags & INET_IFF_BROADCAST) {
+ DWORD sp =
+ ntohl((DWORD)
+ ((struct sockaddr_in *)shortest_p)
+ -> sin_addr.s_addr);
+ sin.sin_addr.s_addr = htonl(sp | ~mask);
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_BROADADDR,
+ (struct sockaddr *) &sin);
+ }
+ } break;
+ case AF_INET6: {
+ struct sockaddr_in6 sin6;
+ sys_memzero(&sin6, sizeof(sin6));
+ sin6.sin6_family = shortest_p->sa_family;
+ set_netmask_bytes((char *) &sin6.sin6_addr,
+ 16,
+ shortest_length);
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_NETMASK,
+ (struct sockaddr *) &sin6);
+ } break;
+ }
+ }
+ }
+ if (ifrow.dwPhysAddrLen) {
+ /* Hardware Address */
+ BUF_ENSURE(1 + 2 + ifrow.dwPhysAddrLen);
+ *buf_p++ = INET_IFOPT_HWADDR;
+ put_int16(ifrow.dwPhysAddrLen, buf_p); buf_p += 2;
+ sys_memcpy(buf_p, ifrow.bPhysAddr, ifrow.dwPhysAddrLen);
+ buf_p += ifrow.dwPhysAddrLen;
+ }
+
+done:
+ /* That is all for this interface */
+ BUF_ENSURE(1);
+ *buf_p++ = '\0';
+ if (ia_p &&
+ ia_p->Ipv6IfIndex &&
+ ia_p->Ipv6IfIndex != index)
+ {
+ /* Oops, there was an other interface for IPv6. Possible? XXX */
+ index = ia_p->Ipv6IfIndex;
+ goto index;
+ }
+ }
+
+ if (ip_adaddrs_p) FREE(ip_adaddrs_p);
+ if (info_p) FREE(info_p);
+ if (ip_addrs_p) FREE(ip_addrs_p);
+
+ buf_size = buf_p - buf_alloc_p;
+ buf_alloc_p = REALLOC(buf_alloc_p, buf_size);
+ /* buf_p is now unreliable */
+ *rbuf_pp = buf_alloc_p;
+ return buf_size;
+# undef BUF_ENSURE
+}
+
+#elif defined(HAVE_GETIFADDRS)
+
+static int inet_ctl_getifaddrs(inet_descriptor* desc_p,
+ char **rbuf_pp, int rsize)
+{
+ struct ifaddrs *ifa_p, *ifa_free_p;
+
+ int buf_size;
+ char *buf_p;
+ char *buf_alloc_p;
+
+ buf_size = 512;
+ buf_alloc_p = ALLOC(buf_size);
+ buf_p = buf_alloc_p;
+# define BUF_ENSURE(Size) \
+ do { \
+ int NEED_, GOT_ = buf_p - buf_alloc_p; \
+ NEED_ = GOT_ + (Size); \
+ if (NEED_ > buf_size) { \
+ buf_size = NEED_ + 512; \
+ buf_alloc_p = REALLOC(buf_alloc_p, buf_size); \
+ buf_p = buf_alloc_p + GOT_; \
+ } \
+ } while (0)
+# define SOCKADDR_TO_BUF(opt, sa) \
+ do { \
+ if (sa) { \
+ char *P_; \
+ *buf_p++ = (opt); \
+ while (! (P_ = sockaddr_to_buf((sa), buf_p, \
+ buf_alloc_p+buf_size))) { \
+ int GOT_ = buf_p - buf_alloc_p; \
+ buf_size += 512; \
+ buf_alloc_p = REALLOC(buf_alloc_p, buf_size); \
+ buf_p = buf_alloc_p + GOT_; \
+ } \
+ if (P_ == buf_p) { \
+ buf_p--; \
+ } else { \
+ buf_p = P_; \
+ } \
+ } \
+ } while (0)
+
+ if (getifaddrs(&ifa_p) < 0) {
+ return ctl_error(sock_errno(), rbuf_pp, rsize);
+ }
+ ifa_free_p = ifa_p;
+ *buf_p++ = INET_REP_OK;
+ for (; ifa_p; ifa_p = ifa_p->ifa_next) {
+ int len = utf8_len(ifa_p->ifa_name, -1);
+ BUF_ENSURE(len+1 + 1+4 + 1);
+ utf8_encode(ifa_p->ifa_name, -1, buf_p);
+ buf_p += len;
+ *buf_p++ = '\0';
+ *buf_p++ = INET_IFOPT_FLAGS;
+ put_int32(IFGET_FLAGS(ifa_p->ifa_flags), buf_p); buf_p += 4;
+ if (ifa_p->ifa_addr) {
+ if (ifa_p->ifa_addr->sa_family == AF_INET
+#if defined(AF_INET6)
+ || ifa_p->ifa_addr->sa_family == AF_INET6
+#endif
+ ) {
+ SOCKADDR_TO_BUF(INET_IFOPT_ADDR, ifa_p->ifa_addr);
+ if (ifa_p->ifa_netmask) {
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_NETMASK, ifa_p->ifa_netmask);
+ }
+ if (ifa_p->ifa_dstaddr &&
+ (ifa_p->ifa_flags & IFF_POINTOPOINT)) {
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_DSTADDR, ifa_p->ifa_dstaddr);
+ } else if (ifa_p->ifa_broadaddr &&
+ (ifa_p->ifa_flags & IFF_BROADCAST)) {
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_BROADADDR, ifa_p->ifa_broadaddr);
+ }
+ }
+#if defined(AF_LINK) || defined(AF_PACKET)
+ else if (
+#if defined(AF_LINK)
+ ifa_p->ifa_addr->sa_family == AF_LINK
+#else
+ 0
+#endif
+#if defined(AF_PACKET)
+ || ifa_p->ifa_addr->sa_family == AF_PACKET
+#endif
+ ) {
+ char *bp = buf_p;
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_HWADDR, ifa_p->ifa_addr);
+ if (buf_p - bp < 4) buf_p = bp; /* Empty hwaddr */
+ }
+#endif
+ }
+ BUF_ENSURE(1);
+ *buf_p++ = '\0';
+ }
+ buf_size = buf_p - buf_alloc_p;
+ buf_alloc_p = REALLOC(buf_alloc_p, buf_size);
+ /* buf_p is now unreliable */
+ freeifaddrs(ifa_free_p);
+ *rbuf_pp = buf_alloc_p;
+ return buf_size;
+# undef BUF_ENSURE
+}
+
+#else
+
+static int inet_ctl_getifaddrs(inet_descriptor* desc_p,
+ char **rbuf_pp, int rsize)
+{
+ return ctl_error(ENOTSUP, rbuf_pp, rsize);
+}
+
+#endif
+
+
+
#ifdef VXWORKS
/*
** THIS is a terrible creature, a bug in the TCP part
@@ -4457,9 +5050,17 @@ static STATUS wrap_sockopt(STATUS (*function)() /* Yep, no parameter
}
#endif
+/* Per H @ Tail-f: The original code here had problems that possibly
+ only occur if you abuse it for non-INET sockets, but anyway:
+ a) If the getsockopt for SO_PRIORITY or IP_TOS failed, the actual
+ requested setsockopt was never even attempted.
+ b) If {get,set}sockopt for one of IP_TOS and SO_PRIORITY failed,
+ but ditto for the other worked and that was actually the requested
+ option, failure was still reported to erlang. */
+
#if defined(IP_TOS) && defined(SOL_IP) && defined(SO_PRIORITY)
static int setopt_prio_tos_trick
- (int fd, int proto, int type, char* arg_ptr, int arg_sz)
+ (int fd, int proto, int type, char* arg_ptr, int arg_sz, int propagate)
{
/* The relations between SO_PRIORITY, TOS and other options
is not what you (or at least I) would expect...:
@@ -4472,6 +5073,8 @@ static int setopt_prio_tos_trick
int tmp_ival_prio;
int tmp_ival_tos;
int res;
+ int res_prio;
+ int res_tos;
#ifdef HAVE_SOCKLEN_T
socklen_t
#else
@@ -4480,28 +5083,35 @@ static int setopt_prio_tos_trick
tmp_arg_sz_prio = sizeof(tmp_ival_prio),
tmp_arg_sz_tos = sizeof(tmp_ival_tos);
- res = sock_getopt(fd, SOL_SOCKET, SO_PRIORITY,
+ res_prio = sock_getopt(fd, SOL_SOCKET, SO_PRIORITY,
(char *) &tmp_ival_prio, &tmp_arg_sz_prio);
- if (res == 0) {
- res = sock_getopt(fd, SOL_IP, IP_TOS,
+ res_tos = sock_getopt(fd, SOL_IP, IP_TOS,
(char *) &tmp_ival_tos, &tmp_arg_sz_tos);
- if (res == 0) {
res = sock_setopt(fd, proto, type, arg_ptr, arg_sz);
if (res == 0) {
if (type != SO_PRIORITY) {
- if (type != IP_TOS) {
- res = sock_setopt(fd,
+ if (type != IP_TOS && res_tos == 0) {
+ res_tos = sock_setopt(fd,
SOL_IP,
IP_TOS,
(char *) &tmp_ival_tos,
tmp_arg_sz_tos);
+ if (propagate)
+ res = res_tos;
}
- if (res == 0) {
- res = sock_setopt(fd,
+ if (res == 0 && res_prio == 0) {
+ res_prio = sock_setopt(fd,
SOL_SOCKET,
SO_PRIORITY,
(char *) &tmp_ival_prio,
tmp_arg_sz_prio);
+ if (propagate) {
+ /* Some kernels set a SO_PRIORITY by default that you are not permitted to reset,
+ silently ignore this error condition */
+ if (res_prio != 0 && sock_errno() == EPERM) {
+ res = 0;
+ } else {
+ res = res_prio;
}
}
}
@@ -4576,8 +5186,7 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
case INET_LOPT_BUFFER:
DEBUGF(("inet_set_opts(%ld): s=%d, BUFFER=%d\r\n",
(long)desc->port, desc->s, ival));
- if (ival > INET_MAX_BUFFER) ival = INET_MAX_BUFFER;
- else if (ival < INET_MIN_BUFFER) ival = INET_MIN_BUFFER;
+ if (ival < INET_MIN_BUFFER) ival = INET_MIN_BUFFER;
desc->bufsz = ival;
continue;
@@ -4642,7 +5251,6 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
if (desc->stype == SOCK_STREAM) {
tcp_descriptor* tdesc = (tcp_descriptor*) desc;
if (ival < 0) ival = 0;
- else if (ival > INET_MAX_BUFFER*2) ival = INET_MAX_BUFFER*2;
if (tdesc->low > ival)
tdesc->low = ival;
tdesc->high = ival;
@@ -4653,7 +5261,6 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
if (desc->stype == SOCK_STREAM) {
tcp_descriptor* tdesc = (tcp_descriptor*) desc;
if (ival < 0) ival = 0;
- else if (ival > INET_MAX_BUFFER) ival = INET_MAX_BUFFER;
if (tdesc->high < ival)
tdesc->high = ival;
tdesc->low = ival;
@@ -4850,7 +5457,7 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
return -1;
}
#if defined(IP_TOS) && defined(SOL_IP) && defined(SO_PRIORITY)
- res = setopt_prio_tos_trick (desc->s, proto, type, arg_ptr, arg_sz);
+ res = setopt_prio_tos_trick (desc->s, proto, type, arg_ptr, arg_sz, propagate);
#else
res = sock_setopt (desc->s, proto, type, arg_ptr, arg_sz);
#endif
@@ -4999,9 +5606,6 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
case INET_LOPT_BUFFER:
desc->bufsz = get_int32(curr); curr += 4;
- if (desc->bufsz > INET_MAX_BUFFER)
- desc->bufsz = INET_MAX_BUFFER;
- else
if (desc->bufsz < INET_MIN_BUFFER)
desc->bufsz = INET_MIN_BUFFER;
res = 0; /* This does not affect the kernel buffer size */
@@ -5242,9 +5846,12 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
char *after;
# ifdef HAVE_STRUCT_SCTP_PADDRPARAMS_SPP_FLAGS
int eflags, cflags, hb_enable, hb_disable,
- pmtud_enable, pmtud_disable,
+ pmtud_enable, pmtud_disable;
+# ifdef HAVE_STRUCT_SCTP_PADDRPARAMS_SPP_SACKDELAY
+ int
sackdelay_enable, sackdelay_disable;
# endif
+# endif
CHKLEN(curr, ASSOC_ID_LEN);
arg.pap.spp_assoc_id = GET_ASSOC_ID(curr); curr += ASSOC_ID_LEN;
@@ -5293,12 +5900,15 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
if (pmtud_enable) cflags |= SPP_PMTUD_ENABLE;
if (pmtud_disable) cflags |= SPP_PMTUD_DISABLE;
+# ifdef HAVE_STRUCT_SCTP_PADDRPARAMS_SPP_SACKDELAY
+ /* The followings are missing in FreeBSD 7.1 */
sackdelay_enable =eflags& SCTP_FLAG_SACDELAY_ENABLE;
sackdelay_disable=eflags& SCTP_FLAG_SACDELAY_DISABLE;
if (sackdelay_enable && sackdelay_disable)
return -1;
if (sackdelay_enable) cflags |= SPP_SACKDELAY_ENABLE;
if (sackdelay_disable) cflags |= SPP_SACKDELAY_DISABLE;
+# endif
arg.pap.spp_flags = cflags;
# endif
@@ -5377,7 +5987,7 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
return -1;
}
#if defined(IP_TOS) && defined(SOL_IP) && defined(SO_PRIORITY)
- res = setopt_prio_tos_trick (desc->s, proto, type, arg_ptr, arg_sz);
+ res = setopt_prio_tos_trick (desc->s, proto, type, arg_ptr, arg_sz, 1);
#else
res = sock_setopt (desc->s, proto, type, arg_ptr, arg_sz);
#endif
@@ -5436,7 +6046,7 @@ static int inet_fill_opts(inet_descriptor* desc,
#define PLACE_FOR(Size,Ptr) \
do { \
int need = dest_used + (Size); \
- if (need > INET_MAX_BUFFER) { \
+ if (need > INET_MAX_OPT_BUFFER) { \
RETURN_ERROR(); \
} \
if (need > dest_allocated) { \
@@ -5660,7 +6270,7 @@ static int inet_fill_opts(inet_descriptor* desc,
buf += 4;
data_provided = (int) *buf++;
arg_sz = get_int32(buf);
- if (arg_sz > INET_MAX_BUFFER) {
+ if (arg_sz > INET_MAX_OPT_BUFFER) {
RETURN_ERROR();
}
buf += 4;
@@ -5774,7 +6384,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen,
"miscalculated buffer size"); \
} \
need = (Index) + (N); \
- if (need > INET_MAX_BUFFER/sizeof(ErlDrvTermData)) { \
+ if (need > INET_MAX_OPT_BUFFER/sizeof(ErlDrvTermData)) {\
RETURN_ERROR((Spec), -ENOMEM); \
} \
if (need > spec_allocated) { \
@@ -6199,13 +6809,15 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen,
if (ap.spp_flags & SPP_PMTUD_DISABLE)
{ i = LOAD_ATOM (spec, i, am_pmtud_disable); n++; }
-
+# ifdef HAVE_STRUCT_SCTP_PADDRPARAMS_SPP_SACKDELAY
+ /* SPP_SACKDELAY_* not in FreeBSD 7.1 */
if (ap.spp_flags & SPP_SACKDELAY_ENABLE)
{ i = LOAD_ATOM (spec, i, am_sackdelay_enable); n++; }
if (ap.spp_flags & SPP_SACKDELAY_DISABLE)
{ i = LOAD_ATOM (spec, i, am_sackdelay_disable); n++; }
# endif
+# endif
PLACE_FOR(spec, i,
LOAD_NIL_CNT + LOAD_LIST_CNT + 2*LOAD_TUPLE_CNT);
@@ -6625,7 +7237,7 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len,
}
}
DEBUGF(("inet_ctl(%ld): GETSTAT\r\n", (long) desc->port));
- if (dstlen > INET_MAX_BUFFER) /* sanity check */
+ if (dstlen > INET_MAX_OPT_BUFFER) /* sanity check */
return 0;
if (dstlen > rsize) {
if ((dst = (char*) ALLOC(dstlen)) == NULL)
@@ -6641,7 +7253,7 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len,
char* dst;
int dstlen = 1 /* Reply code */ + len*5;
DEBUGF(("inet_ctl(%ld): INET_REQ_SUBSCRIBE\r\n", (long) desc->port));
- if (dstlen > INET_MAX_BUFFER) /* sanity check */
+ if (dstlen > INET_MAX_OPT_BUFFER) /* sanity check */
return 0;
if (dstlen > rsize) {
if ((dst = (char*) ALLOC(dstlen)) == NULL)
@@ -6676,6 +7288,13 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len,
return inet_ctl_getiflist(desc, rbuf, rsize);
}
+ case INET_REQ_GETIFADDRS: {
+ DEBUGF(("inet_ctl(%ld): GETIFADDRS\r\n", (long)desc->port));
+ if (!IS_OPEN(desc))
+ return ctl_xerror(EXBADPORT, rbuf, rsize);
+ return inet_ctl_getifaddrs(desc, rbuf, rsize);
+ }
+
case INET_REQ_IFGET: {
DEBUGF(("inet_ctl(%ld): IFGET\r\n", (long)desc->port));
if (!IS_OPEN(desc))
diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index b19f632f52..4b3934657c 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -587,7 +587,8 @@ efile_readdir(Efile_error* errInfo, /* Where to return error codes. */
open directory.*/
char* buffer, /* Pointer to buffer for
one filename. */
- size_t size) /* Size of buffer. */
+ size_t *size) /* in-out Size of buffer, length
+ of name. */
{
DIR *dp; /* Pointer to directory structure. */
struct dirent* dirp; /* Pointer to directory entry. */
@@ -619,7 +620,8 @@ efile_readdir(Efile_error* errInfo, /* Where to return error codes. */
if (IS_DOT_OR_DOTDOT(dirp->d_name))
continue;
buffer[0] = '\0';
- strncat(buffer, dirp->d_name, size-1);
+ strncat(buffer, dirp->d_name, (*size)-1);
+ *size = strlen(dirp->d_name);
return 1;
}
}
diff --git a/erts/emulator/drivers/win32/win_con.c b/erts/emulator/drivers/win32/win_con.c
index 2202ca655f..14f7941643 100644
--- a/erts/emulator/drivers/win32/win_con.c
+++ b/erts/emulator/drivers/win32/win_con.c
@@ -704,6 +704,18 @@ FrameWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
}
write_inbuf(&c, 1);
return 0;
+ case WM_MOUSEWHEEL:
+ {
+ int delta = GET_WHEEL_DELTA_WPARAM(wParam);
+ if (delta < 0) {
+ PostMessage(hClientWnd, WM_VSCROLL, MAKELONG(SB_THUMBTRACK,
+ (iVscrollPos + 5)),0);
+ } else {
+ WORD pos = ((iVscrollPos - 5) < 0) ? 0 : (iVscrollPos - 5);
+ PostMessage(hClientWnd, WM_VSCROLL, MAKELONG(SB_THUMBTRACK,pos),0);
+ }
+ return 0;
+ }
case WM_CHAR:
c = (TCHAR)wParam;
write_inbuf(&c,1);
diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c
index 04bd1139f5..101853736a 100644..100755
--- a/erts/emulator/drivers/win32/win_efile.c
+++ b/erts/emulator/drivers/win32/win_efile.c
@@ -23,20 +23,20 @@
#include <windows.h>
#include "sys.h"
#include <ctype.h>
-
+#include <wchar.h>
#include "erl_efile.h"
/*
* Microsoft-specific function to map a WIN32 error code to a Posix errno.
*/
-#define ISSLASH(a) ((a) == '\\' || (a) == '/')
+#define ISSLASH(a) ((a) == L'\\' || (a) == L'/')
#define ISDIR(st) (((st).st_mode&S_IFMT) == S_IFDIR)
#define ISREG(st) (((st).st_mode&S_IFMT) == S_IFREG)
#define IS_DOT_OR_DOTDOT(s) \
- (s[0] == '.' && (s[1] == '\0' || (s[1] == '.' && s[2] == '\0')))
+ ((s)[0] == L'.' && ((s)[1] == L'\0' || ((s)[1] == L'.' && (s)[2] == L'\0')))
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD) 0xFFFFFFFF)
@@ -44,9 +44,9 @@
static int check_error(int result, Efile_error* errInfo);
static int set_error(Efile_error* errInfo);
-static int IsRootUNCName(const char* path);
-static int extract_root(char* name);
-static unsigned short dos_to_posix_mode(int attr, const char *name);
+static int is_root_unc_name(const WCHAR *path);
+static int extract_root(WCHAR *name);
+static unsigned short dos_to_posix_mode(int attr, const WCHAR *name);
static int errno_map(DWORD last_error) {
@@ -196,27 +196,26 @@ win_writev(Efile_error* errInfo,
int
-efile_mkdir(errInfo, name)
-Efile_error* errInfo; /* Where to return error codes. */
-char* name; /* Name of directory to create. */
+efile_mkdir(Efile_error* errInfo, /* Where to return error codes. */
+ char* name) /* Name of directory to create. */
{
- return check_error(mkdir(name), errInfo);
+ return check_error(_wmkdir((WCHAR *) name), errInfo);
}
int
-efile_rmdir(errInfo, name)
-Efile_error* errInfo; /* Where to return error codes. */
-char* name; /* Name of directory to delete. */
+efile_rmdir(Efile_error* errInfo, /* Where to return error codes. */
+ char* name) /* Name of directory to delete. */
{
OSVERSIONINFO os;
DWORD attr;
+ WCHAR *wname = (WCHAR *) name;
- if (RemoveDirectory(name) != FALSE) {
+ if (RemoveDirectoryW(wname) != FALSE) {
return 1;
}
errno = errno_map(GetLastError());
if (errno == EACCES) {
- attr = GetFileAttributes(name);
+ attr = GetFileAttributesW(wname);
if (attr != (DWORD) -1) {
if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
/*
@@ -238,21 +237,21 @@ char* name; /* Name of directory to delete. */
GetVersionEx(&os);
if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
HANDLE handle;
- WIN32_FIND_DATA data;
- char buffer[2*MAX_PATH];
+ WIN32_FIND_DATAW data;
+ WCHAR buffer[2*MAX_PATH];
int len;
- len = strlen(name);
- strcpy(buffer, name);
- if (buffer[0] && buffer[len-1] != '\\' && buffer[len-1] != '/') {
- strcat(buffer, "\\");
+ len = wcslen(wname);
+ wcscpy(buffer, wname);
+ if (buffer[0] && buffer[len-1] != L'\\' && buffer[len-1] != L'/') {
+ wcscat(buffer, L"\\");
}
- strcat(buffer, "*.*");
- handle = FindFirstFile(buffer, &data);
+ wcscat(buffer, L"*.*");
+ handle = FindFirstFileW(buffer, &data);
if (handle != INVALID_HANDLE_VALUE) {
while (1) {
- if ((strcmp(data.cFileName, ".") != 0)
- && (strcmp(data.cFileName, "..") != 0)) {
+ if ((wcscmp(data.cFileName, L".") != 0)
+ && (wcscmp(data.cFileName, L"..") != 0)) {
/*
* Found something in this directory.
*/
@@ -260,7 +259,7 @@ char* name; /* Name of directory to delete. */
errno = EEXIST;
break;
}
- if (FindNextFile(handle, &data) == FALSE) {
+ if (FindNextFileW(handle, &data) == FALSE) {
break;
}
}
@@ -284,19 +283,19 @@ char* name; /* Name of directory to delete. */
}
int
-efile_delete_file(errInfo, name)
-Efile_error* errInfo; /* Where to return error codes. */
-char* name; /* Name of file to delete. */
+efile_delete_file(Efile_error* errInfo, /* Where to return error codes. */
+ char* name) /* Name of file to delete. */
{
DWORD attr;
+ WCHAR *wname = (WCHAR *) name;
- if (DeleteFile(name) != FALSE) {
+ if (DeleteFileW(wname) != FALSE) {
return 1;
}
errno = errno_map(GetLastError());
if (errno == EACCES) {
- attr = GetFileAttributes(name);
+ attr = GetFileAttributesW(wname);
if (attr != (DWORD) -1) {
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
/*
@@ -308,7 +307,7 @@ char* name; /* Name of file to delete. */
}
}
} else if (errno == ENOENT) {
- attr = GetFileAttributes(name);
+ attr = GetFileAttributesW(wname);
if (attr != (DWORD) -1) {
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
/*
@@ -362,20 +361,21 @@ char* name; /* Name of file to delete. */
*/
int
-efile_rename(errInfo, src, dst)
-Efile_error* errInfo; /* Where to return error codes. */
-char* src; /* Original name. */
-char* dst; /* New name. */
+efile_rename(Efile_error* errInfo, /* Where to return error codes. */
+ char* src, /* Original name. */
+ char* dst) /* New name. */
{
DWORD srcAttr, dstAttr;
+ WCHAR *wsrc = (WCHAR *) src;
+ WCHAR *wdst = (WCHAR *) dst;
- if (MoveFile(src, dst) != FALSE) {
+ if (MoveFileW(wsrc, wdst) != FALSE) {
return 1;
}
errno = errno_map(GetLastError());
- srcAttr = GetFileAttributes(src);
- dstAttr = GetFileAttributes(dst);
+ srcAttr = GetFileAttributesW(wsrc);
+ dstAttr = GetFileAttributesW(wdst);
if (srcAttr == (DWORD) -1) {
srcAttr = 0;
}
@@ -390,22 +390,22 @@ char* dst; /* New name. */
if (errno == EACCES) {
decode:
if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) {
- char srcPath[MAX_PATH], dstPath[MAX_PATH];
- char *srcRest, *dstRest;
+ WCHAR srcPath[MAX_PATH], dstPath[MAX_PATH];
+ WCHAR *srcRest, *dstRest;
int size;
- size = GetFullPathName(src, sizeof(srcPath), srcPath, &srcRest);
- if ((size == 0) || (size > sizeof(srcPath))) {
+ size = GetFullPathNameW(wsrc, MAX_PATH, srcPath, &srcRest);
+ if ((size == 0) || (size > MAX_PATH)) {
return check_error(-1, errInfo);
}
- size = GetFullPathName(dst, sizeof(dstPath), dstPath, &dstRest);
- if ((size == 0) || (size > sizeof(dstPath))) {
+ size = GetFullPathNameW(wdst, MAX_PATH, dstPath, &dstRest);
+ if ((size == 0) || (size > MAX_PATH)) {
return check_error(-1, errInfo);
}
if (srcRest == NULL) {
- srcRest = srcPath + strlen(srcPath);
+ srcRest = srcPath + wcslen(srcPath);
}
- if (strnicmp(srcPath, dstPath, srcRest - srcPath) == 0) {
+ if (_wcsnicmp(srcPath, dstPath, srcRest - srcPath) == 0) {
/*
* Trying to move a directory into itself.
*/
@@ -420,14 +420,14 @@ char* dst; /* New name. */
}
(void) extract_root(dstPath);
- if (dstPath[0] == '\0') {
+ if (dstPath[0] == L'\0') {
/*
* The filename was invalid. (Don't know why,
* but play it safe.)
*/
errno = EINVAL;
}
- if (stricmp(srcPath, dstPath) != 0) {
+ if (_wcsicmp(srcPath, dstPath) != 0) {
/*
* If src is a directory and dst filesystem != src
* filesystem, errno should be EXDEV. It is very
@@ -463,14 +463,14 @@ char* dst; /* New name. */
* fails, it's because it wasn't empty.
*/
- if (RemoveDirectory(dst)) {
+ if (RemoveDirectoryW(wdst)) {
/*
* Now that that empty directory is gone, we can try
* renaming again. If that fails, we'll put this empty
* directory back, for completeness.
*/
- if (MoveFile(src, dst) != FALSE) {
+ if (MoveFileW(wsrc, wdst) != FALSE) {
return 1;
}
@@ -480,8 +480,8 @@ char* dst; /* New name. */
*/
errno = errno_map(GetLastError());
- CreateDirectory(dst, NULL);
- SetFileAttributes(dst, dstAttr);
+ CreateDirectoryW(wdst, NULL);
+ SetFileAttributesW(wdst, dstAttr);
if (errno == EACCES) {
/*
* Decode the EACCES to a more meaningful error.
@@ -506,17 +506,17 @@ char* dst; /* New name. */
* put temp file back to old name.
*/
- char tempName[MAX_PATH];
+ WCHAR tempName[MAX_PATH];
int result, size;
- char *rest;
+ WCHAR *rest;
- size = GetFullPathName(dst, sizeof(tempName), tempName, &rest);
- if ((size == 0) || (size > sizeof(tempName)) || (rest == NULL)) {
+ size = GetFullPathNameW(wdst, MAX_PATH, tempName, &rest);
+ if ((size == 0) || (size > MAX_PATH) || (rest == NULL)) {
return check_error(-1, errInfo);
}
- *rest = '\0';
+ *rest = L'\0';
result = -1;
- if (GetTempFileName(tempName, "erlr", 0, tempName) != 0) {
+ if (GetTempFileNameW(tempName, L"erlr", 0, tempName) != 0) {
/*
* Strictly speaking, need the following DeleteFile and
* MoveFile to be joined as an atomic operation so no
@@ -524,15 +524,15 @@ char* dst; /* New name. */
* same temp file.
*/
- DeleteFile(tempName);
- if (MoveFile(dst, tempName) != FALSE) {
- if (MoveFile(src, dst) != FALSE) {
- SetFileAttributes(tempName, FILE_ATTRIBUTE_NORMAL);
- DeleteFile(tempName);
+ DeleteFileW(tempName);
+ if (MoveFileW(wdst, tempName) != FALSE) {
+ if (MoveFileW(wsrc, wdst) != FALSE) {
+ SetFileAttributesW(tempName, FILE_ATTRIBUTE_NORMAL);
+ DeleteFileW(tempName);
return 1;
} else {
- DeleteFile(dst);
- MoveFile(tempName, dst);
+ DeleteFileW(wdst);
+ MoveFileW(tempName, wdst);
}
}
@@ -558,11 +558,10 @@ char* dst; /* New name. */
}
int
-efile_chdir(errInfo, name)
-Efile_error* errInfo; /* Where to return error codes. */
-char* name; /* Name of directory to make current. */
+efile_chdir(Efile_error* errInfo, /* Where to return error codes. */
+ char* name) /* Name of directory to make current. */
{
- int success = check_error(chdir(name), errInfo);
+ int success = check_error(_wchdir((WCHAR *) name), errInfo);
if (!success && errInfo->posix_errno == EINVAL)
/* POSIXification of errno */
errInfo->posix_errno = ENOENT;
@@ -570,59 +569,65 @@ char* name; /* Name of directory to make current. */
}
int
-efile_getdcwd(errInfo, drive, buffer, size)
-Efile_error* errInfo; /* Where to return error codes. */
-int drive; /* 0 - current, 1 - A, 2 - B etc. */
-char* buffer; /* Where to return the current directory. */
-size_t size; /* Size of buffer. */
+efile_getdcwd(Efile_error* errInfo, /* Where to return error codes. */
+ int drive, /* 0 - current, 1 - A, 2 - B etc. */
+ char* buffer, /* Where to return the current directory. */
+ size_t size) /* Size of buffer. */
{
- if (_getdcwd(drive, buffer, size) == NULL)
+ WCHAR *wbuffer = (WCHAR *) buffer;
+ size_t wbuffer_size = size / 2;
+ if (_wgetdcwd(drive, wbuffer, wbuffer_size) == NULL)
return check_error(-1, errInfo);
- for ( ; *buffer; buffer++)
- if (*buffer == '\\')
- *buffer = '/';
+ for ( ; *wbuffer; wbuffer++)
+ if (*wbuffer == L'\\')
+ *wbuffer = L'/';
return 1;
}
int
-efile_readdir(errInfo, name, dir_handle, buffer, size)
-Efile_error* errInfo; /* Where to return error codes. */
-char* name; /* Name of directory to open. */
-EFILE_DIR_HANDLE* dir_handle; /* Directory handle of open directory. */
-char* buffer; /* Pointer to buffer for one filename. */
-size_t size; /* Size of buffer. */
+efile_readdir(Efile_error* errInfo, /* Where to return error codes. */
+ char* name, /* Name of directory to list */
+ EFILE_DIR_HANDLE* dir_handle, /* Handle of opened directory or NULL */
+ char* buffer, /* Buffer to put one filename in */
+ size_t *size) /* in-out size of buffer/size of filename excluding zero
+ termination in bytes*/
{
HANDLE dir; /* Handle to directory. */
- char wildcard[MAX_PATH]; /* Wildcard to search for. */
- WIN32_FIND_DATA findData; /* Data found by FindFirstFile() or FindNext(). */
+ WCHAR wildcard[MAX_PATH]; /* Wildcard to search for. */
+ WIN32_FIND_DATAW findData; /* Data found by FindFirstFile() or FindNext(). */
+ /* Alignment is not honored, this works on x86 because of alignment fixup by processor.
+ Not perfect, but faster than alinging by hand (really) */
+ WCHAR *wname = (WCHAR *) name;
+ WCHAR *wbuffer = (WCHAR *) buffer;
/*
* First time we must setup everything.
*/
if (*dir_handle == NULL) {
- int length = strlen(name);
- char* s;
+ int length = wcslen(wname);
+ WCHAR* s;
if (length+3 >= MAX_PATH) {
errno = ENAMETOOLONG;
return check_error(-1, errInfo);
}
- strcpy(wildcard, name);
+ wcscpy(wildcard, wname);
s = wildcard+length-1;
- if (*s != '/' && *s != '\\')
- *++s = '\\';
- *++s = '*';
- *++s = '\0';
- DEBUGF(("Reading %s\n", wildcard));
- dir = FindFirstFile(wildcard, &findData);
+ if (*s != L'/' && *s != L'\\')
+ *++s = L'\\';
+ *++s = L'*';
+ *++s = L'\0';
+ DEBUGF(("Reading %ws\n", wildcard));
+ dir = FindFirstFileW(wildcard, &findData);
if (dir == INVALID_HANDLE_VALUE)
return set_error(errInfo);
*dir_handle = (EFILE_DIR_HANDLE) dir;
if (!IS_DOT_OR_DOTDOT(findData.cFileName)) {
- strcpy(buffer, findData.cFileName);
+ wcscpy(wbuffer, findData.cFileName);
+ *size = wcslen(wbuffer)*2;
return 1;
}
}
@@ -635,10 +640,11 @@ size_t size; /* Size of buffer. */
dir = (HANDLE) *dir_handle;
for (;;) {
- if (FindNextFile(dir, &findData)) {
+ if (FindNextFileW(dir, &findData)) {
if (IS_DOT_OR_DOTDOT(findData.cFileName))
continue;
- strcpy(buffer, findData.cFileName);
+ wcscpy(wbuffer, findData.cFileName);
+ *size = wcslen(wbuffer)*2;
return 1;
}
@@ -655,17 +661,17 @@ size_t size; /* Size of buffer. */
}
int
-efile_openfile(errInfo, name, flags, pfd, pSize)
-Efile_error* errInfo; /* Where to return error codes. */
-char* name; /* Name of directory to open. */
-int flags; /* Flags to use for opening. */
-int* pfd; /* Where to store the file descriptor. */
-Sint64* pSize; /* Where to store the size of the file. */
+efile_openfile(Efile_error* errInfo, /* Where to return error codes. */
+ char* name, /* Name of directory to open. */
+ int flags, /* Flags to use for opening. */
+ int* pfd, /* Where to store the file descriptor. */
+ Sint64* pSize) /* Where to store the size of the file. */
{
BY_HANDLE_FILE_INFORMATION fileInfo; /* File information from a handle. */
HANDLE fd; /* Handle to open file. */
DWORD access; /* Access mode: GENERIC_READ, GENERIC_WRITE. */
DWORD crFlags;
+ WCHAR *wname = (WCHAR *) name;
switch (flags & (EFILE_MODE_READ|EFILE_MODE_WRITE)) {
case EFILE_MODE_READ:
@@ -692,7 +698,7 @@ Sint64* pSize; /* Where to store the size of the file. */
if (flags & EFILE_MODE_EXCL) {
crFlags = CREATE_NEW;
}
- fd = CreateFile(name, access,
+ fd = CreateFileW(wname, access,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, crFlags, FILE_ATTRIBUTE_NORMAL, NULL);
@@ -711,7 +717,7 @@ Sint64* pSize; /* Where to store the size of the file. */
* to EISDIR.
*/
if (errInfo->posix_errno &&
- (attr = GetFileAttributes(name)) != INVALID_FILE_ATTRIBUTES &&
+ (attr = GetFileAttributesW(wname)) != INVALID_FILE_ATTRIBUTES &&
(attr & FILE_ATTRIBUTE_DIRECTORY)) {
errInfo->posix_errno = EISDIR;
}
@@ -735,9 +741,10 @@ Sint64* pSize; /* Where to store the size of the file. */
int
efile_may_openfile(Efile_error* errInfo, char *name) {
+ WCHAR *wname = (WCHAR *) name;
DWORD attr;
- if ((attr = GetFileAttributes(name)) == INVALID_FILE_ATTRIBUTES) {
+ if ((attr = GetFileAttributesW(wname)) == INVALID_FILE_ATTRIBUTES) {
return check_error(-1, errInfo);
}
@@ -746,18 +753,6 @@ efile_may_openfile(Efile_error* errInfo, char *name) {
return check_error(-1, errInfo);
}
return 1;
-#if 0
- struct stat statbuf;
-
- if (stat(name, &statbuf)) {
- return check_error(-1, errInfo);
- }
- if (ISDIR(statbuf)) {
- errno = EISDIR;
- return check_error(-1, errInfo);
- }
- return 1;
-#endif
}
void
@@ -792,16 +787,17 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,
char* orig_name, int info_for_link)
{
HANDLE findhandle; /* Handle returned by FindFirstFile(). */
- WIN32_FIND_DATA findbuf; /* Data return by FindFirstFile(). */
- char name[_MAX_PATH];
+ WIN32_FIND_DATAW findbuf; /* Data return by FindFirstFile(). */
+ WCHAR name[_MAX_PATH];
int name_len;
- char* path;
- char pathbuf[_MAX_PATH];
+ WCHAR *path;
+ WCHAR pathbuf[_MAX_PATH];
int drive; /* Drive for filename (1 = A:, 2 = B: etc). */
+ WCHAR *worig_name = (WCHAR *) orig_name;
/* Don't allow wildcards to be interpreted by system */
- if (strpbrk(orig_name, "?*")) {
+ if (wcspbrk(worig_name, L"?*")) {
enoent:
errInfo->posix_errno = ENOENT;
errInfo->os_errno = ERROR_FILE_NOT_FOUND;
@@ -813,25 +809,25 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,
* slash, because it causes FindFirstFile() to fail on Win95.
*/
- if ((name_len = strlen(orig_name)) >= _MAX_PATH) {
+ if ((name_len = wcslen(worig_name)) >= _MAX_PATH) {
goto enoent;
} else {
- strcpy(name, orig_name);
+ wcscpy(name, worig_name);
if (name_len > 2 && ISSLASH(name[name_len-1]) &&
- name[name_len-2] != ':') {
- name[name_len-1] = '\0';
+ name[name_len-2] != L':') {
+ name[name_len-1] = L'\0';
}
}
/* Try to get disk from name. If none, get current disk. */
- if (name[1] != ':') {
+ if (name[1] != L':') {
drive = 0;
- if (GetCurrentDirectory(sizeof(pathbuf), pathbuf) &&
- pathbuf[1] == ':') {
- drive = tolower(pathbuf[0]) - 'a' + 1;
+ if (GetCurrentDirectoryW(_MAX_PATH, pathbuf) &&
+ pathbuf[1] == L':') {
+ drive = towlower(pathbuf[0]) - L'a' + 1;
}
- } else if (*name && name[2] == '\0') {
+ } else if (*name && name[2] == L'\0') {
/*
* X: and nothing more is an error.
*/
@@ -839,15 +835,15 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,
errInfo->os_errno = ERROR_FILE_NOT_FOUND;
return 0;
} else
- drive = tolower(*name) - 'a' + 1;
+ drive = towlower(*name) - L'a' + 1;
- findhandle = FindFirstFile(name, &findbuf);
+ findhandle = FindFirstFileW(name, &findbuf);
if (findhandle == INVALID_HANDLE_VALUE) {
- if (!(strpbrk(name, "./\\") &&
- (path = _fullpath(pathbuf, name, _MAX_PATH)) &&
+ if (!(wcspbrk(name, L"./\\") &&
+ (path = _wfullpath(pathbuf, name, _MAX_PATH)) &&
/* root dir. ('C:\') or UNC root dir. ('\\server\share\') */
- ((strlen(path) == 3) || IsRootUNCName(path)) &&
- (GetDriveType(path) > 1) ) ) {
+ ((wcslen(path) == 3) || is_root_unc_name(path)) &&
+ (GetDriveTypeW(path) > 1) ) ) {
errInfo->posix_errno = ENOENT;
errInfo->os_errno = ERROR_FILE_NOT_FOUND;
return 0;
@@ -860,8 +856,9 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,
findbuf.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
findbuf.nFileSizeHigh = 0;
findbuf.nFileSizeLow = 0;
- findbuf.cFileName[0] = '\0';
+ findbuf.cFileName[0] = L'\0';
+ pInfo->links = 1;
pInfo->modifyTime.year = 1980;
pInfo->modifyTime.month = 1;
pInfo->modifyTime.day = 1;
@@ -874,6 +871,35 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,
SYSTEMTIME SystemTime;
FILETIME LocalFTime;
+ /*first check if we are a symlink */
+ if (!info_for_link && (findbuf.dwFileAttributes &
+ FILE_ATTRIBUTE_REPARSE_POINT)){
+ /*
+ * given that we know this is a symlink,
+ we should be able to find its target */
+ WCHAR target_name[_MAX_PATH];
+ if (efile_readlink(errInfo, (char *) name,
+ (char *) target_name,256) == 1) {
+ FindClose(findhandle);
+ return efile_fileinfo(errInfo, pInfo,
+ (char *) target_name, info_for_link);
+ }
+ }
+
+ /* number of links: */
+ {
+ HANDLE handle; /* Handle returned by CreateFile() */
+ BY_HANDLE_FILE_INFORMATION fileInfo; /* from CreateFile() */
+ if (handle = CreateFileW(name, GENERIC_READ, 0,NULL,
+ OPEN_EXISTING, 0, NULL)) {
+ GetFileInformationByHandle(handle, &fileInfo);
+ pInfo->links = fileInfo.nNumberOfLinks;
+ CloseHandle(handle);
+ } else {
+ pInfo->links = 1;
+ }
+ }
+
#define GET_TIME(dst, src) \
if (!FileTimeToLocalFileTime(&findbuf.src, &LocalFTime) || \
!FileTimeToSystemTime(&LocalFTime, &SystemTime)) { \
@@ -908,7 +934,10 @@ if (!FileTimeToLocalFileTime(&findbuf.src, &LocalFTime) || \
pInfo->size_low = findbuf.nFileSizeLow;
pInfo->size_high = findbuf.nFileSizeHigh;
- if (findbuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ if (info_for_link && (findbuf.dwFileAttributes &
+ FILE_ATTRIBUTE_REPARSE_POINT))
+ pInfo->type = FT_SYMLINK;
+ else if (findbuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
pInfo->type = FT_DIRECTORY;
else
pInfo->type = FT_REGULAR;
@@ -919,7 +948,6 @@ if (!FileTimeToLocalFileTime(&findbuf.src, &LocalFTime) || \
pInfo->access = FA_READ|FA_WRITE;
pInfo->mode = dos_to_posix_mode(findbuf.dwFileAttributes, name);
- pInfo->links = 1;
pInfo->major_device = drive;
pInfo->minor_device = 0;
pInfo->inode = 0;
@@ -930,10 +958,9 @@ if (!FileTimeToLocalFileTime(&findbuf.src, &LocalFTime) || \
}
int
-efile_write_info(errInfo, pInfo, name)
-Efile_error* errInfo;
-Efile_info* pInfo;
-char* name;
+efile_write_info(Efile_error* errInfo,
+ Efile_info* pInfo,
+ char* name)
{
SYSTEMTIME timebuf;
FILETIME LocalFileTime;
@@ -947,12 +974,13 @@ char* name;
DWORD attr;
DWORD tempAttr;
BOOL modifyTime = FALSE;
+ WCHAR *wname = (WCHAR *) name;
/*
* Get the attributes for the file.
*/
- tempAttr = attr = GetFileAttributes((LPTSTR)name);
+ tempAttr = attr = GetFileAttributesW(wname);
if (attr == 0xffffffff) {
return set_error(errInfo);
}
@@ -988,8 +1016,8 @@ char* name;
} \
}
- MKTIME(ModifyFileTime, pInfo->accessTime, mtime);
- MKTIME(AccessFileTime, pInfo->modifyTime, atime);
+ MKTIME(ModifyFileTime, pInfo->modifyTime, mtime);
+ MKTIME(AccessFileTime, pInfo->accessTime, atime);
MKTIME(CreationFileTime, pInfo->cTime, ctime);
#undef MKTIME
@@ -1006,12 +1034,12 @@ char* name;
if (tempAttr & FILE_ATTRIBUTE_READONLY) {
tempAttr &= ~FILE_ATTRIBUTE_READONLY;
- if (!SetFileAttributes((LPTSTR) name, tempAttr)) {
+ if (!SetFileAttributesW(wname, tempAttr)) {
return set_error(errInfo);
}
}
- fd = CreateFile(name, GENERIC_READ|GENERIC_WRITE,
+ fd = CreateFileW(wname, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fd != INVALID_HANDLE_VALUE) {
@@ -1029,7 +1057,7 @@ char* name;
*/
if (tempAttr != attr) {
- if (!SetFileAttributes((LPTSTR) name, attr)) {
+ if (!SetFileAttributesW(wname, attr)) {
return set_error(errInfo);
}
}
@@ -1082,12 +1110,17 @@ char* buf; /* Buffer to write. */
size_t count; /* Number of bytes to write. */
{
DWORD written; /* Bytes written in last operation. */
+ OVERLAPPED overlapped;
+ OVERLAPPED* pOverlapped = NULL;
if (flags & EFILE_MODE_APPEND) {
- (void) SetFilePointer((HANDLE) fd, 0, NULL, FILE_END);
+ memset(&overlapped, 0, sizeof(overlapped));
+ overlapped.Offset = 0xffffffff;
+ overlapped.OffsetHigh = 0xffffffff;
+ pOverlapped = &overlapped;
}
while (count > 0) {
- if (!WriteFile((HANDLE) fd, buf, count, &written, NULL))
+ if (!WriteFile((HANDLE) fd, buf, count, &written, pOverlapped))
return set_error(errInfo);
buf += written;
count -= written;
@@ -1107,11 +1140,16 @@ efile_writev(Efile_error* errInfo, /* Where to return error codes */
size_t size) /* Number of bytes to write */
{
int cnt; /* Buffers so far written */
+ OVERLAPPED overlapped;
+ OVERLAPPED* pOverlapped = NULL;
ASSERT(iovcnt >= 0);
if (flags & EFILE_MODE_APPEND) {
- (void) SetFilePointer((HANDLE) fd, 0, NULL, FILE_END);
+ memset(&overlapped, 0, sizeof(overlapped));
+ overlapped.Offset = 0xffffffff;
+ overlapped.OffsetHigh = 0xffffffff;
+ pOverlapped = &overlapped;
}
for (cnt = 0; cnt < iovcnt; cnt++) {
if (iov[cnt].iov_base && iov[cnt].iov_len > 0) {
@@ -1123,7 +1161,7 @@ efile_writev(Efile_error* errInfo, /* Where to return error codes */
iov[cnt].iov_base + p,
iov[cnt].iov_len - p,
&w,
- NULL))
+ pOverlapped))
return set_error(errInfo);
}
}
@@ -1195,7 +1233,7 @@ int flags;
/*
- * IsRootUNCName - returns TRUE if the argument is a UNC name specifying
+ * is_root_unc_name - returns TRUE if the argument is a UNC name specifying
* a root share. That is, if it is of the form \\server\share\.
* This routine will also return true if the argument is of the
* form \\server\share (no trailing slash) but Win32 currently
@@ -1205,16 +1243,16 @@ int flags;
*/
static int
-IsRootUNCName(const char* path)
+is_root_unc_name(const WCHAR *path)
{
/*
* If a root UNC name, path will start with 2 (but not 3) slashes
*/
- if ((strlen(path) >= 5) /* minimum string is "//x/y" */
+ if ((wcslen(path) >= 5) /* minimum string is "//x/y" */
&& ISSLASH(path[0]) && ISSLASH(path[1]))
{
- const char * p = path + 2 ;
+ const WCHAR *p = path + 2;
/*
* find the slash between the server name and share name
@@ -1257,19 +1295,19 @@ IsRootUNCName(const char* path)
*/
static int
-extract_root(char* name)
+extract_root(WCHAR* name)
{
- int len = strlen(name);
+ int len = wcslen(name);
- if (isalpha(name[0]) && name[1] == ':' && ISSLASH(name[2])) {
- int c = name[3];
- name[3] = '\0';
- return c == '\0';
+ if (iswalpha(name[0]) && name[1] == L':' && ISSLASH(name[2])) {
+ WCHAR c = name[3];
+ name[3] = L'\0';
+ return c == L'\0';
} else if (len < 5 || !ISSLASH(name[0]) || !ISSLASH(name[1])) {
goto error;
} else { /* Try to find the end of the UNC name. */
- char* p;
- int c;
+ WCHAR* p;
+ WCHAR c;
/*
* Find the slash between the server name and share name.
@@ -1278,7 +1316,7 @@ extract_root(char* name)
for (p = name + 2; *p; p++)
if (ISSLASH(*p))
break;
- if (*p == '\0')
+ if (*p == L'\0')
goto error;
/*
@@ -1289,24 +1327,24 @@ extract_root(char* name)
if (ISSLASH(*p))
break;
c = *p;
- *p = '\0';
- return c == '\0' || p[1] == '\0';
+ *p = L'\0';
+ return c == L'\0' || p[1] == L'\0';
}
error:
- *name = '\0';
+ *name = L'\0';
return 1;
}
static unsigned short
-dos_to_posix_mode(int attr, const char *name)
+dos_to_posix_mode(int attr, const WCHAR *name)
{
register unsigned short uxmode;
unsigned dosmode;
- register const char *p;
+ register const WCHAR *p;
dosmode = attr & 0xff;
- if ((p = name)[1] == ':')
+ if ((p = name)[1] == L':')
p += 2;
/* check to see if this is a directory - note we must make a special
@@ -1315,7 +1353,7 @@ dos_to_posix_mode(int attr, const char *name)
uxmode = (unsigned short)
(((ISSLASH(*p) && !p[1]) || (dosmode & FILE_ATTRIBUTE_DIRECTORY) ||
- *p == '\0') ? _S_IFDIR|_S_IEXEC : _S_IFREG);
+ *p == L'\0') ? _S_IFDIR|_S_IEXEC : _S_IFREG);
/* If attribute byte does not have read-only bit, it is read-write */
@@ -1324,11 +1362,11 @@ dos_to_posix_mode(int attr, const char *name)
/* see if file appears to be executable - check extension of name */
- if (p = strrchr(name, '.')) {
- if (!stricmp(p, ".exe") ||
- !stricmp(p, ".cmd") ||
- !stricmp(p, ".bat") ||
- !stricmp(p, ".com"))
+ if (p = wcsrchr(name, L'.')) {
+ if (!_wcsicmp(p, L".exe") ||
+ !_wcsicmp(p, L".cmd") ||
+ !_wcsicmp(p, L".bat") ||
+ !_wcsicmp(p, L".com"))
uxmode |= _S_IEXEC;
}
@@ -1343,6 +1381,60 @@ dos_to_posix_mode(int attr, const char *name)
int
efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size)
{
+ /*
+ * load dll and see if we have CreateSymbolicLink at runtime:
+ * (Vista only)
+ */
+ HINSTANCE hModule = NULL;
+ WCHAR *wname = (WCHAR *) name;
+ WCHAR *wbuffer = (WCHAR *) buffer;
+ if ((hModule = LoadLibrary("kernel32.dll")) != NULL) {
+ typedef DWORD (WINAPI * GETFINALPATHNAMEBYHANDLEPTR)(
+ HANDLE hFile,
+ LPCWSTR lpFilePath,
+ DWORD cchFilePath,
+ DWORD dwFlags);
+
+ GETFINALPATHNAMEBYHANDLEPTR pGetFinalPathNameByHandle =
+ (GETFINALPATHNAMEBYHANDLEPTR)GetProcAddress(hModule, "GetFinalPathNameByHandleW");
+
+ if (pGetFinalPathNameByHandle == NULL) {
+ FreeLibrary(hModule);
+ } else {
+ /* first check if file is a symlink; {error, einval} otherwise */
+ DWORD fileAttributes = GetFileAttributesW(wname);
+ if ((fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
+ BOOLEAN success = 0;
+ HANDLE h = CreateFileW(wname, GENERIC_READ, 0,NULL, OPEN_EXISTING, 0, NULL);
+ int len;
+ if(h != INVALID_HANDLE_VALUE) {
+ success = pGetFinalPathNameByHandle(h, wbuffer, size,0);
+ /* GetFinalPathNameByHandle prepends path with "\\?\": */
+ len = wcslen(wbuffer);
+ wmemmove(wbuffer,wbuffer+4,len-3);
+ if (len - 4 >= 2 && wbuffer[1] == L':' && wbuffer[0] >= L'A' &&
+ wbuffer[0] <= L'Z') {
+ wbuffer[0] = wbuffer[0] + L'a' - L'A';
+ }
+
+ for ( ; *wbuffer; wbuffer++)
+ if (*wbuffer == L'\\')
+ *wbuffer = L'/';
+ CloseHandle(h);
+ }
+ FreeLibrary(hModule);
+ if (success) {
+ return 1;
+ } else {
+ return set_error(errInfo);
+ }
+ } else {
+ FreeLibrary(hModule);
+ errno = EINVAL;
+ return check_error(-1, errInfo);
+ }
+ }
+ }
errno = ENOTSUP;
return check_error(-1, errInfo);
}
@@ -1351,17 +1443,20 @@ efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size)
int
efile_altname(Efile_error* errInfo, char* orig_name, char* buffer, size_t size)
{
- WIN32_FIND_DATA wfd;
+ WIN32_FIND_DATAW wfd;
HANDLE fh;
- char name[_MAX_PATH];
+ WCHAR name[_MAX_PATH+1];
int name_len;
- char* path;
- char pathbuf[_MAX_PATH];
+ WCHAR* path;
+ WCHAR pathbuf[_MAX_PATH+1]; /* Unclear weather GetCurrentDirectory will access one char after
+ _MAX_PATH */
+ WCHAR *worig_name = (WCHAR *) orig_name;
+ WCHAR *wbuffer = (WCHAR *) buffer;
int drive; /* Drive for filename (1 = A:, 2 = B: etc). */
/* Don't allow wildcards to be interpreted by system */
- if (strpbrk(orig_name, "?*")) {
+ if (wcspbrk(worig_name, L"?*")) {
enoent:
errInfo->posix_errno = ENOENT;
errInfo->os_errno = ERROR_FILE_NOT_FOUND;
@@ -1373,67 +1468,105 @@ efile_altname(Efile_error* errInfo, char* orig_name, char* buffer, size_t size)
* slash, because it causes FindFirstFile() to fail on Win95.
*/
- if ((name_len = strlen(orig_name)) >= _MAX_PATH) {
+ if ((name_len = wcslen(worig_name)) >= _MAX_PATH) {
goto enoent;
} else {
- strcpy(name, orig_name);
+ wcscpy(name, worig_name);
if (name_len > 2 && ISSLASH(name[name_len-1]) &&
- name[name_len-2] != ':') {
- name[name_len-1] = '\0';
+ name[name_len-2] != L':') {
+ name[name_len-1] = L'\0';
}
}
/* Try to get disk from name. If none, get current disk. */
- if (name[1] != ':') {
+ if (name[1] != L':') {
drive = 0;
- if (GetCurrentDirectory(sizeof(pathbuf), pathbuf) &&
- pathbuf[1] == ':') {
- drive = tolower(pathbuf[0]) - 'a' + 1;
+ if (GetCurrentDirectoryW(_MAX_PATH, pathbuf) &&
+ pathbuf[1] == L':') {
+ drive = towlower(pathbuf[0]) - L'a' + 1;
}
- } else if (*name && name[2] == '\0') {
+ } else if (*name && name[2] == L'\0') {
/*
* X: and nothing more is an error.
*/
goto enoent;
} else {
- drive = tolower(*name) - 'a' + 1;
+ drive = towlower(*name) - L'a' + 1;
}
- fh = FindFirstFile(name,&wfd);
+ fh = FindFirstFileW(name,&wfd);
if (fh == INVALID_HANDLE_VALUE) {
- if (!(strpbrk(name, "./\\") &&
- (path = _fullpath(pathbuf, name, _MAX_PATH)) &&
+ if (!(wcspbrk(name, L"./\\") &&
+ (path = _wfullpath(pathbuf, name, _MAX_PATH)) &&
/* root dir. ('C:\') or UNC root dir. ('\\server\share\') */
- ((strlen(path) == 3) || IsRootUNCName(path)) &&
- (GetDriveType(path) > 1) ) ) {
+ ((wcslen(path) == 3) || is_root_unc_name(path)) &&
+ (GetDriveTypeW(path) > 1) ) ) {
errno = errno_map(GetLastError());
return check_error(-1, errInfo);
}
/*
* Root directories (such as C:\ or \\server\share\ are fabricated.
*/
- strcpy(buffer,name);
+ wcscpy(wbuffer,name);
return 1;
}
- strcpy(buffer,wfd.cAlternateFileName);
- if (!*buffer) {
- strcpy(buffer,wfd.cFileName);
+ wcscpy(wbuffer,wfd.cAlternateFileName);
+ if (!*wbuffer) {
+ wcscpy(wbuffer,wfd.cFileName);
}
-
+ FindClose(fh);
return 1;
}
+
int
efile_link(Efile_error* errInfo, char* old, char* new)
{
- errno = ENOTSUP;
- return check_error(-1, errInfo);
+ WCHAR *wold = (WCHAR *) old;
+ WCHAR *wnew = (WCHAR *) new;
+ if(!CreateHardLinkW(wnew, wold, NULL)) {
+ return set_error(errInfo);
+ }
+ return 1;
}
int
efile_symlink(Efile_error* errInfo, char* old, char* new)
{
+ /*
+ * Load dll and see if we have CreateSymbolicLink at runtime:
+ * (Vista only)
+ */
+ HINSTANCE hModule = NULL;
+ WCHAR *wold = (WCHAR *) old;
+ WCHAR *wnew = (WCHAR *) new;
+ if ((hModule = LoadLibrary("kernel32.dll")) != NULL) {
+ typedef BOOLEAN (WINAPI * CREATESYMBOLICLINKFUNCPTR) (
+ LPCWSTR lpSymlinkFileName,
+ LPCWSTR lpTargetFileName,
+ DWORD dwFlags);
+
+ CREATESYMBOLICLINKFUNCPTR pCreateSymbolicLink =
+ (CREATESYMBOLICLINKFUNCPTR) GetProcAddress(hModule,
+ "CreateSymbolicLinkW");
+ /* A for MBCS, W for UNICODE... char* above implies 'W'! */
+ if (pCreateSymbolicLink != NULL) {
+ DWORD attr = GetFileAttributesW(wold);
+ int flag = (attr != INVALID_FILE_ATTRIBUTES &&
+ attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
+ /* SYMBOLIC_LINK_FLAG_DIRECTORY = 1 */
+ BOOLEAN success = pCreateSymbolicLink(wnew, wold, flag);
+ FreeLibrary(hModule);
+
+ if (success) {
+ return 1;
+ } else {
+ return set_error(errInfo);
+ }
+ } else
+ FreeLibrary(hModule);
+ }
errno = ENOTSUP;
return check_error(-1, errInfo);
}
diff --git a/erts/emulator/hipe/hipe_amd64_glue.S b/erts/emulator/hipe/hipe_amd64_glue.S
index ede762aae0..3376487292 100644
--- a/erts/emulator/hipe/hipe_amd64_glue.S
+++ b/erts/emulator/hipe/hipe_amd64_glue.S
@@ -402,7 +402,7 @@ nbif_3_simple_exception:
* - the native heap/stack/reds registers are saved in P
*/
.handle_trap:
- movq %rax, P_NARITY(P)
+ movl %eax, P_NARITY(P) # Note: narity is a 32-bit field
movl $HIPE_MODE_SWITCH_RES_TRAP, %eax
jmp .nosave_exit
diff --git a/erts/emulator/hipe/hipe_ppc_glue.S b/erts/emulator/hipe/hipe_ppc_glue.S
index 0651963294..c010f4f047 100644
--- a/erts/emulator/hipe/hipe_ppc_glue.S
+++ b/erts/emulator/hipe/hipe_ppc_glue.S
@@ -541,7 +541,7 @@ CSYM(nbif_3_simple_exception):
.handle_trap:
li r3, HIPE_MODE_SWITCH_RES_TRAP
STORE NSP, P_NSP(P)
- STORE r4, P_NARITY(P)
+ stw r4, P_NARITY(P) /* Note: narity is a 32-bit field */
STORE TEMP_LR, P_NRA(P)
b .nosave_exit
diff --git a/erts/emulator/internal_doc/dec.dat b/erts/emulator/internal_doc/dec.dat
new file mode 100644
index 0000000000..771ef51baa
--- /dev/null
+++ b/erts/emulator/internal_doc/dec.dat
@@ -0,0 +1,942 @@
+{[59],894}.
+{[96],8175}.
+{[180],8189}.
+{[183],903}.
+{[198],1236}.
+{[230],1237}.
+{[399],1240}.
+{[415],1256}.
+{[439],1248}.
+{[601],1241}.
+{[629],1257}.
+{[658],1249}.
+{[697],884}.
+{[768],832}.
+{[768,65],192}.
+{[768,69],200}.
+{[768,73],204}.
+{[768,79],210}.
+{[768,85],217}.
+{[768,87],7808}.
+{[768,89],7922}.
+{[768,97],224}.
+{[768,101],232}.
+{[768,105],236}.
+{[768,111],242}.
+{[768,117],249}.
+{[768,119],7809}.
+{[768,121],7923}.
+{[768,168],8173}.
+{[768,770,65],7846}.
+{[768,770,69],7872}.
+{[768,770,79],7890}.
+{[768,770,97],7847}.
+{[768,770,101],7873}.
+{[768,770,111],7891}.
+{[768,772,69],7700}.
+{[768,772,79],7760}.
+{[768,772,101],7701}.
+{[768,772,111],7761}.
+{[768,774,65],7856}.
+{[768,774,97],7857}.
+{[768,776,85],475}.
+{[768,776,117],476}.
+{[768,776,953],8146}.
+{[768,776,965],8162}.
+{[768,787,837,913],8074}.
+{[768,787,837,919],8090}.
+{[768,787,837,937],8106}.
+{[768,787,837,945],8066}.
+{[768,787,837,951],8082}.
+{[768,787,837,969],8098}.
+{[768,787,913],7946}.
+{[768,787,917],7962}.
+{[768,787,919],7978}.
+{[768,787,921],7994}.
+{[768,787,927],8010}.
+{[768,787,937],8042}.
+{[768,787,945],7938}.
+{[768,787,949],7954}.
+{[768,787,951],7970}.
+{[768,787,953],7986}.
+{[768,787,959],8002}.
+{[768,787,965],8018}.
+{[768,787,969],8034}.
+{[768,788,837,913],8075}.
+{[768,788,837,919],8091}.
+{[768,788,837,937],8107}.
+{[768,788,837,945],8067}.
+{[768,788,837,951],8083}.
+{[768,788,837,969],8099}.
+{[768,788,913],7947}.
+{[768,788,917],7963}.
+{[768,788,919],7979}.
+{[768,788,921],7995}.
+{[768,788,927],8011}.
+{[768,788,933],8027}.
+{[768,788,937],8043}.
+{[768,788,945],7939}.
+{[768,788,949],7955}.
+{[768,788,951],7971}.
+{[768,788,953],7987}.
+{[768,788,959],8003}.
+{[768,788,965],8019}.
+{[768,788,969],8035}.
+{[768,795,79],7900}.
+{[768,795,85],7914}.
+{[768,795,111],7901}.
+{[768,795,117],7915}.
+{[768,837,945],8114}.
+{[768,837,951],8130}.
+{[768,837,969],8178}.
+{[768,913],8122}.
+{[768,917],8136}.
+{[768,919],8138}.
+{[768,921],8154}.
+{[768,927],8184}.
+{[768,933],8170}.
+{[768,937],8186}.
+{[768,945],8048}.
+{[768,949],8050}.
+{[768,951],8052}.
+{[768,953],8054}.
+{[768,959],8056}.
+{[768,965],8058}.
+{[768,969],8060}.
+{[768,8127],8141}.
+{[768,8190],8157}.
+{[769],833}.
+{[769,65],193}.
+{[769,67],262}.
+{[769,69],201}.
+{[769,71],500}.
+{[769,73],205}.
+{[769,75],7728}.
+{[769,76],313}.
+{[769,77],7742}.
+{[769,78],323}.
+{[769,79],211}.
+{[769,80],7764}.
+{[769,82],340}.
+{[769,83],346}.
+{[769,85],218}.
+{[769,87],7810}.
+{[769,89],221}.
+{[769,90],377}.
+{[769,97],225}.
+{[769,99],263}.
+{[769,101],233}.
+{[769,103],501}.
+{[769,105],237}.
+{[769,107],7729}.
+{[769,108],314}.
+{[769,109],7743}.
+{[769,110],324}.
+{[769,111],243}.
+{[769,112],7765}.
+{[769,114],341}.
+{[769,115],347}.
+{[769,117],250}.
+{[769,119],7811}.
+{[769,121],253}.
+{[769,122],378}.
+{[769,168],8174}.
+{[769,198],508}.
+{[769,216],510}.
+{[769,230],509}.
+{[769,248],511}.
+{[769,770,65],7844}.
+{[769,770,69],7870}.
+{[769,770,79],7888}.
+{[769,770,97],7845}.
+{[769,770,101],7871}.
+{[769,770,111],7889}.
+{[769,771,79],7756}.
+{[769,771,85],7800}.
+{[769,771,111],7757}.
+{[769,771,117],7801}.
+{[769,772,69],7702}.
+{[769,772,79],7762}.
+{[769,772,101],7703}.
+{[769,772,111],7763}.
+{[769,774,65],7854}.
+{[769,774,97],7855}.
+{[769,776,73],7726}.
+{[769,776,85],471}.
+{[769,776,105],7727}.
+{[769,776,117],472}.
+{[769,776,953],8147}.
+{[769,776,965],8163}.
+{[769,778,65],506}.
+{[769,778,97],507}.
+{[769,787,837,913],8076}.
+{[769,787,837,919],8092}.
+{[769,787,837,937],8108}.
+{[769,787,837,945],8068}.
+{[769,787,837,951],8084}.
+{[769,787,837,969],8100}.
+{[769,787,913],7948}.
+{[769,787,917],7964}.
+{[769,787,919],7980}.
+{[769,787,921],7996}.
+{[769,787,927],8012}.
+{[769,787,937],8044}.
+{[769,787,945],7940}.
+{[769,787,949],7956}.
+{[769,787,951],7972}.
+{[769,787,953],7988}.
+{[769,787,959],8004}.
+{[769,787,965],8020}.
+{[769,787,969],8036}.
+{[769,788,837,913],8077}.
+{[769,788,837,919],8093}.
+{[769,788,837,937],8109}.
+{[769,788,837,945],8069}.
+{[769,788,837,951],8085}.
+{[769,788,837,969],8101}.
+{[769,788,913],7949}.
+{[769,788,917],7965}.
+{[769,788,919],7981}.
+{[769,788,921],7997}.
+{[769,788,927],8013}.
+{[769,788,933],8029}.
+{[769,788,937],8045}.
+{[769,788,945],7941}.
+{[769,788,949],7957}.
+{[769,788,951],7973}.
+{[769,788,953],7989}.
+{[769,788,959],8005}.
+{[769,788,965],8021}.
+{[769,788,969],8037}.
+{[769,795,79],7898}.
+{[769,795,85],7912}.
+{[769,795,111],7899}.
+{[769,795,117],7913}.
+{[769,807,67],7688}.
+{[769,807,99],7689}.
+{[769,837,945],8116}.
+{[769,837,951],8132}.
+{[769,837,959],8180}.
+{[769,913],8123}.
+{[769,917],8137}.
+{[769,919],8139}.
+{[769,921],8155}.
+{[769,927],8185}.
+{[769,933],8171}.
+{[769,937],8187}.
+{[769,945],8049}.
+{[769,949],8051}.
+{[769,951],8053}.
+{[769,953],8055}.
+{[769,959],8057}.
+{[769,965],8059}.
+{[769,969],8061}.
+{[769,1043],1027}.
+{[769,1050],1036}.
+{[769,1075],1107}.
+{[769,1082],1116}.
+{[769,8127],8142}.
+{[769,8190],8158}.
+{[770,65],194}.
+{[770,67],264}.
+{[770,69],202}.
+{[770,71],284}.
+{[770,72],292}.
+{[770,73],206}.
+{[770,74],308}.
+{[770,79],212}.
+{[770,83],348}.
+{[770,85],219}.
+{[770,87],372}.
+{[770,89],374}.
+{[770,90],7824}.
+{[770,97],226}.
+{[770,99],265}.
+{[770,101],234}.
+{[770,103],285}.
+{[770,104],293}.
+{[770,105],238}.
+{[770,106],309}.
+{[770,111],244}.
+{[770,115],349}.
+{[770,117],251}.
+{[770,119],373}.
+{[770,121],375}.
+{[770,122],7825}.
+{[770,803,65],7852}.
+{[770,803,69],7878}.
+{[770,803,79],7896}.
+{[770,803,97],7853}.
+{[770,803,101],7879}.
+{[770,803,111],7897}.
+{[771,65],195}.
+{[771,69],7868}.
+{[771,73],296}.
+{[771,78],209}.
+{[771,79],213}.
+{[771,85],360}.
+{[771,86],7804}.
+{[771,89],7928}.
+{[771,97],227}.
+{[771,101],7869}.
+{[771,105],297}.
+{[771,110],241}.
+{[771,111],245}.
+{[771,117],361}.
+{[771,118],7805}.
+{[771,121],7929}.
+{[771,770,65],7850}.
+{[771,770,69],7876}.
+{[771,770,79],7894}.
+{[771,770,97],7851}.
+{[771,770,101],7877}.
+{[771,770,111],7895}.
+{[771,774,65],7860}.
+{[771,774,97],7861}.
+{[771,795,79],7904}.
+{[771,795,85],7918}.
+{[771,795,111],7905}.
+{[771,795,117],7919}.
+{[772,65],256}.
+{[772,69],274}.
+{[772,71],7712}.
+{[772,73],298}.
+{[772,79],332}.
+{[772,85],362}.
+{[772,97],257}.
+{[772,101],275}.
+{[772,103],7713}.
+{[772,105],299}.
+{[772,111],333}.
+{[772,117],363}.
+{[772,198],482}.
+{[772,230],483}.
+{[772,775,65],480}.
+{[772,775,97],481}.
+{[772,776,65],478}.
+{[772,776,85],469}.
+{[772,776,97],479}.
+{[772,776,117],470}.
+{[772,803,76],7736}.
+{[772,803,82],7772}.
+{[772,803,108],7737}.
+{[772,803,114],7773}.
+{[772,808,79],492}.
+{[772,808,111],493}.
+{[772,913],8121}.
+{[772,921],8153}.
+{[772,933],8169}.
+{[772,945],8113}.
+{[772,953],8145}.
+{[772,965],8161}.
+{[772,1048],1250}.
+{[772,1059],1262}.
+{[772,1080],1251}.
+{[772,1091],1263}.
+{[774,65],258}.
+{[774,69],276}.
+{[774,71],286}.
+{[774,73],300}.
+{[774,79],334}.
+{[774,85],364}.
+{[774,97],259}.
+{[774,101],277}.
+{[774,103],287}.
+{[774,105],301}.
+{[774,111],335}.
+{[774,117],365}.
+{[774,803,65],7862}.
+{[774,803,97],7863}.
+{[774,807,69],7708}.
+{[774,807,101],7709}.
+{[774,913],8120}.
+{[774,921],8152}.
+{[774,933],8168}.
+{[774,945],8112}.
+{[774,953],8144}.
+{[774,965],8160}.
+{[774,1040],1232}.
+{[774,1045],1238}.
+{[774,1046],1217}.
+{[774,1048],1049}.
+{[774,1059],1038}.
+{[774,1072],1233}.
+{[774,1077],1239}.
+{[774,1078],1218}.
+{[774,1080],1081}.
+{[774,1091],1118}.
+{[775,66],7682}.
+{[775,67],266}.
+{[775,68],7690}.
+{[775,69],278}.
+{[775,70],7710}.
+{[775,71],288}.
+{[775,72],7714}.
+{[775,73],304}.
+{[775,77],7744}.
+{[775,78],7748}.
+{[775,80],7766}.
+{[775,82],7768}.
+{[775,83],7776}.
+{[775,84],7786}.
+{[775,87],7814}.
+{[775,88],7818}.
+{[775,89],7822}.
+{[775,90],379}.
+{[775,98],7683}.
+{[775,99],267}.
+{[775,100],7691}.
+{[775,101],279}.
+{[775,102],7711}.
+{[775,103],289}.
+{[775,104],7715}.
+{[775,109],7745}.
+{[775,110],7749}.
+{[775,112],7767}.
+{[775,114],7769}.
+{[775,115],7777}.
+{[775,116],7787}.
+{[775,119],7815}.
+{[775,120],7819}.
+{[775,121],7823}.
+{[775,122],380}.
+{[775,383],7835}.
+{[775,769,83],7780}.
+{[775,769,115],7781}.
+{[775,774],784}.
+{[775,780,83],7782}.
+{[775,780,115],7783}.
+{[775,803,83],7784}.
+{[775,803,115],7785}.
+{[776,65],196}.
+{[776,69],203}.
+{[776,72],7718}.
+{[776,73],207}.
+{[776,79],214}.
+{[776,85],220}.
+{[776,87],7812}.
+{[776,88],7820}.
+{[776,89],376}.
+{[776,97],228}.
+{[776,101],235}.
+{[776,104],7719}.
+{[776,105],239}.
+{[776,111],246}.
+{[776,116],7831}.
+{[776,117],252}.
+{[776,119],7813}.
+{[776,120],7821}.
+{[776,121],255}.
+{[776,399],1242}.
+{[776,415],1258}.
+{[776,601],1243}.
+{[776,629],1259}.
+{[776,771,79],7758}.
+{[776,771,111],7759}.
+{[776,772,85],7802}.
+{[776,772,117],7803}.
+{[776,921],938}.
+{[776,933],939}.
+{[776,953],970}.
+{[776,965],971}.
+{[776,978],980}.
+{[776,1030],1031}.
+{[776,1040],1234}.
+{[776,1045],1025}.
+{[776,1046],1244}.
+{[776,1047],1246}.
+{[776,1048],1252}.
+{[776,1054],1254}.
+{[776,1059],1264}.
+{[776,1063],1268}.
+{[776,1067],1272}.
+{[776,1072],1235}.
+{[776,1077],1105}.
+{[776,1078],1245}.
+{[776,1079],1247}.
+{[776,1080],1253}.
+{[776,1086],1255}.
+{[776,1091],1265}.
+{[776,1095],1269}.
+{[776,1099],1273}.
+{[776,1110],1111}.
+{[777,65],7842}.
+{[777,69],7866}.
+{[777,73],7880}.
+{[777,79],7886}.
+{[777,85],7910}.
+{[777,89],7926}.
+{[777,97],7843}.
+{[777,101],7867}.
+{[777,105],7881}.
+{[777,111],7887}.
+{[777,117],7911}.
+{[777,121],7927}.
+{[777,770,65],7848}.
+{[777,770,69],7874}.
+{[777,770,79],7892}.
+{[777,770,97],7849}.
+{[777,770,101],7875}.
+{[777,770,111],7893}.
+{[777,774,65],7858}.
+{[777,774,97],7859}.
+{[777,795,79],7902}.
+{[777,795,85],7916}.
+{[777,795,111],7903}.
+{[777,795,117],7917}.
+{[778,65],197}.
+{[778,85],366}.
+{[778,97],229}.
+{[778,117],367}.
+{[778,119],7832}.
+{[778,121],7833}.
+{[779,79],336}.
+{[779,85],368}.
+{[779,111],337}.
+{[779,117],369}.
+{[779,1059],1266}.
+{[779,1091],1267}.
+{[780,65],461}.
+{[780,67],268}.
+{[780,68],270}.
+{[780,69],282}.
+{[780,71],486}.
+{[780,73],463}.
+{[780,75],488}.
+{[780,76],317}.
+{[780,78],327}.
+{[780,79],465}.
+{[780,82],344}.
+{[780,83],352}.
+{[780,84],356}.
+{[780,85],467}.
+{[780,90],381}.
+{[780,97],462}.
+{[780,99],269}.
+{[780,100],271}.
+{[780,101],283}.
+{[780,103],487}.
+{[780,105],464}.
+{[780,106],496}.
+{[780,107],489}.
+{[780,108],318}.
+{[780,110],328}.
+{[780,111],466}.
+{[780,114],345}.
+{[780,115],353}.
+{[780,116],357}.
+{[780,117],468}.
+{[780,122],382}.
+{[780,439],494}.
+{[780,658],495}.
+{[780,776,85],473}.
+{[780,776,117],474}.
+{[781,168],901}.
+{[781,776],836}.
+{[781,776,953],912}.
+{[781,776,965],944}.
+{[781,913],902}.
+{[781,917],904}.
+{[781,919],905}.
+{[781,921],906}.
+{[781,927],908}.
+{[781,933],910}.
+{[781,937],911}.
+{[781,945],940}.
+{[781,949],941}.
+{[781,951],942}.
+{[781,953],943}.
+{[781,959],972}.
+{[781,965],973}.
+{[781,969],974}.
+{[781,978],979}.
+{[783,65],512}.
+{[783,69],516}.
+{[783,73],520}.
+{[783,79],524}.
+{[783,82],528}.
+{[783,85],532}.
+{[783,97],513}.
+{[783,101],517}.
+{[783,105],521}.
+{[783,111],525}.
+{[783,114],529}.
+{[783,117],533}.
+{[783,1140],1142}.
+{[783,1141],1143}.
+{[785,65],514}.
+{[785,69],518}.
+{[785,73],522}.
+{[785,79],526}.
+{[785,82],530}.
+{[785,85],534}.
+{[785,97],515}.
+{[785,101],519}.
+{[785,105],523}.
+{[785,111],527}.
+{[785,114],531}.
+{[785,117],535}.
+{[787],835}.
+{[787,837,913],8072}.
+{[787,837,919],8088}.
+{[787,837,937],8104}.
+{[787,837,945],8064}.
+{[787,837,951],8080}.
+{[787,837,969],8096}.
+{[787,913],7944}.
+{[787,917],7960}.
+{[787,919],7976}.
+{[787,921],7992}.
+{[787,927],8008}.
+{[787,937],8040}.
+{[787,945],7936}.
+{[787,949],7952}.
+{[787,951],7968}.
+{[787,953],7984}.
+{[787,959],8000}.
+{[787,961],8164}.
+{[787,965],8016}.
+{[787,969],8032}.
+{[788,837,913],8073}.
+{[788,837,919],8089}.
+{[788,837,937],8105}.
+{[788,837,945],8065}.
+{[788,837,951],8081}.
+{[788,837,969],8097}.
+{[788,913],7945}.
+{[788,917],7961}.
+{[788,919],7977}.
+{[788,921],7993}.
+{[788,927],8009}.
+{[788,929],8172}.
+{[788,933],8025}.
+{[788,937],8041}.
+{[788,945],7937}.
+{[788,949],7953}.
+{[788,951],7969}.
+{[788,953],7985}.
+{[788,959],8001}.
+{[788,961],8165}.
+{[788,965],8017}.
+{[788,969],8033}.
+{[795,79],416}.
+{[795,85],431}.
+{[795,111],417}.
+{[795,117],432}.
+{[803,65],7840}.
+{[803,66],7684}.
+{[803,68],7692}.
+{[803,69],7864}.
+{[803,72],7716}.
+{[803,73],7882}.
+{[803,75],7730}.
+{[803,76],7734}.
+{[803,77],7746}.
+{[803,78],7750}.
+{[803,79],7884}.
+{[803,82],7770}.
+{[803,83],7778}.
+{[803,84],7788}.
+{[803,85],7908}.
+{[803,86],7806}.
+{[803,87],7816}.
+{[803,89],7924}.
+{[803,90],7826}.
+{[803,97],7841}.
+{[803,98],7685}.
+{[803,100],7693}.
+{[803,101],7865}.
+{[803,104],7717}.
+{[803,105],7883}.
+{[803,107],7731}.
+{[803,108],7735}.
+{[803,109],7747}.
+{[803,110],7751}.
+{[803,111],7885}.
+{[803,114],7771}.
+{[803,115],7779}.
+{[803,116],7789}.
+{[803,117],7909}.
+{[803,118],7807}.
+{[803,119],7817}.
+{[803,121],7925}.
+{[803,122],7827}.
+{[803,795,79],7906}.
+{[803,795,85],7920}.
+{[803,795,111],7907}.
+{[803,795,117],7921}.
+{[804,85],7794}.
+{[804,117],7795}.
+{[805,65],7680}.
+{[805,97],7681}.
+{[807,67],199}.
+{[807,68],7696}.
+{[807,71],290}.
+{[807,72],7720}.
+{[807,75],310}.
+{[807,76],315}.
+{[807,78],325}.
+{[807,82],342}.
+{[807,83],350}.
+{[807,84],354}.
+{[807,99],231}.
+{[807,100],7697}.
+{[807,103],291}.
+{[807,104],7721}.
+{[807,107],311}.
+{[807,108],316}.
+{[807,110],326}.
+{[807,114],343}.
+{[807,115],351}.
+{[807,116],355}.
+{[808,65],260}.
+{[808,69],280}.
+{[808,73],302}.
+{[808,79],490}.
+{[808,85],370}.
+{[808,97],261}.
+{[808,101],281}.
+{[808,105],303}.
+{[808,111],491}.
+{[808,117],371}.
+{[813,68],7698}.
+{[813,69],7704}.
+{[813,76],7740}.
+{[813,78],7754}.
+{[813,84],7792}.
+{[813,85],7798}.
+{[813,100],7699}.
+{[813,101],7705}.
+{[813,108],7741}.
+{[813,110],7755}.
+{[813,116],7793}.
+{[813,117],7799}.
+{[814,72],7722}.
+{[814,104],7723}.
+{[816,69],7706}.
+{[816,73],7724}.
+{[816,85],7796}.
+{[816,101],7707}.
+{[816,105],7725}.
+{[816,117],7797}.
+{[817,66],7686}.
+{[817,68],7694}.
+{[817,75],7732}.
+{[817,76],7738}.
+{[817,78],7752}.
+{[817,82],7774}.
+{[817,84],7790}.
+{[817,90],7828}.
+{[817,98],7687}.
+{[817,100],7695}.
+{[817,104],7830}.
+{[817,107],7733}.
+{[817,108],7739}.
+{[817,110],7753}.
+{[817,114],7775}.
+{[817,116],7791}.
+{[817,122],7829}.
+{[834,168],8129}.
+{[834,776,953],8151}.
+{[834,776,965],8167}.
+{[834,787,837,913],8078}.
+{[834,787,837,919],8094}.
+{[834,787,837,937],8110}.
+{[834,787,837,945],8070}.
+{[834,787,837,951],8086}.
+{[834,787,837,969],8102}.
+{[834,787,913],7950}.
+{[834,787,919],7982}.
+{[834,787,921],7998}.
+{[834,787,937],8046}.
+{[834,787,945],7942}.
+{[834,787,951],7974}.
+{[834,787,953],7990}.
+{[834,787,965],8022}.
+{[834,787,969],8038}.
+{[834,788,837,913],8079}.
+{[834,788,837,919],8095}.
+{[834,788,837,937],8111}.
+{[834,788,837,945],8071}.
+{[834,788,837,951],8087}.
+{[834,788,837,969],8103}.
+{[834,788,913],7951}.
+{[834,788,919],7983}.
+{[834,788,921],7999}.
+{[834,788,933],8031}.
+{[834,788,937],8047}.
+{[834,788,945],7943}.
+{[834,788,951],7975}.
+{[834,788,953],7991}.
+{[834,788,965],8023}.
+{[834,788,969],8039}.
+{[834,837,945],8119}.
+{[834,837,951],8135}.
+{[834,837,969],8183}.
+{[834,945],8118}.
+{[834,951],8134}.
+{[834,953],8150}.
+{[834,965],8166}.
+{[834,969],8182}.
+{[834,8127],8143}.
+{[834,8190],8159}.
+{[837,913],8124}.
+{[837,919],8140}.
+{[837,937],8188}.
+{[837,945],8115}.
+{[837,951],8131}.
+{[837,969],8179}.
+{[953],8126}.
+{[1463,1488],64302}.
+{[1463,1522],64287}.
+{[1464,1488],64303}.
+{[1465,1493],64331}.
+{[1468,1488],64304}.
+{[1468,1489],64305}.
+{[1468,1490],64306}.
+{[1468,1491],64307}.
+{[1468,1492],64308}.
+{[1468,1493],64309}.
+{[1468,1494],64310}.
+{[1468,1496],64312}.
+{[1468,1497],64313}.
+{[1468,1498],64314}.
+{[1468,1499],64315}.
+{[1468,1500],64316}.
+{[1468,1502],64318}.
+{[1468,1504],64320}.
+{[1468,1505],64321}.
+{[1468,1507],64323}.
+{[1468,1508],64324}.
+{[1468,1510],64326}.
+{[1468,1511],64327}.
+{[1468,1512],64328}.
+{[1468,1513],64329}.
+{[1468,1514],64330}.
+{[1471,1489],64332}.
+{[1471,1499],64333}.
+{[1471,1508],64334}.
+{[1473,1468,1513],64300}.
+{[1473,1513],64298}.
+{[1474,1468,1513],64301}.
+{[1474,1513],64299}.
+{[2364,2325],2392}.
+{[2364,2326],2393}.
+{[2364,2327],2394}.
+{[2364,2332],2395}.
+{[2364,2337],2396}.
+{[2364,2338],2397}.
+{[2364,2344],2345}.
+{[2364,2347],2398}.
+{[2364,2351],2399}.
+{[2364,2352],2353}.
+{[2364,2355],2356}.
+{[2492,2465],2524}.
+{[2492,2466],2525}.
+{[2492,2476],2480}.
+{[2492,2479],2527}.
+{[2494,2503],2507}.
+{[2519,2503],2508}.
+{[2620,2582],2649}.
+{[2620,2583],2650}.
+{[2620,2588],2651}.
+{[2620,2593],2652}.
+{[2620,2603],2654}.
+{[2876,2849],2908}.
+{[2876,2850],2909}.
+{[2876,2863],2911}.
+{[2878,2887],2891}.
+{[2902,2887],2888}.
+{[2903,2887],2892}.
+{[3006,3014],3018}.
+{[3006,3015],3019}.
+{[3031,2962],2964}.
+{[3031,3014],3020}.
+{[3158,3142],3144}.
+{[3266,3270],3274}.
+{[3285,3263],3264}.
+{[3285,3266,3270],3275}.
+{[3285,3270],3271}.
+{[3286,3270],3272}.
+{[3390,3398],3402}.
+{[3390,3399],3403}.
+{[3415,3398],3404}.
+{[3634,3661],3635}.
+{[3762,3789],3763}.
+{[3953,3954],3955}.
+{[3953,3956],3957}.
+{[3953,3968],3969}.
+{[3953,3968,4018],3959}.
+{[3953,3968,4019],3961}.
+{[3968,4018],3958}.
+{[3968,4019],3960}.
+{[4021,3904],3945}.
+{[4021,3984],4025}.
+{[4023,3906],3907}.
+{[4023,3916],3917}.
+{[4023,3921],3922}.
+{[4023,3926],3927}.
+{[4023,3931],3932}.
+{[4023,3986],3987}.
+{[4023,3996],3997}.
+{[4023,4001],4002}.
+{[4023,4006],4007}.
+{[4023,4011],4012}.
+{[12441,12358],12436}.
+{[12441,12363],12364}.
+{[12441,12365],12366}.
+{[12441,12367],12368}.
+{[12441,12369],12370}.
+{[12441,12371],12372}.
+{[12441,12373],12374}.
+{[12441,12375],12376}.
+{[12441,12377],12378}.
+{[12441,12379],12380}.
+{[12441,12381],12382}.
+{[12441,12383],12384}.
+{[12441,12385],12386}.
+{[12441,12388],12389}.
+{[12441,12390],12391}.
+{[12441,12392],12393}.
+{[12441,12399],12400}.
+{[12441,12402],12403}.
+{[12441,12405],12406}.
+{[12441,12408],12409}.
+{[12441,12411],12412}.
+{[12441,12445],12446}.
+{[12441,12454],12532}.
+{[12441,12459],12460}.
+{[12441,12461],12462}.
+{[12441,12463],12464}.
+{[12441,12465],12466}.
+{[12441,12467],12468}.
+{[12441,12469],12470}.
+{[12441,12471],12472}.
+{[12441,12473],12474}.
+{[12441,12475],12476}.
+{[12441,12477],12478}.
+{[12441,12479],12480}.
+{[12441,12481],12482}.
+{[12441,12484],12485}.
+{[12441,12486],12487}.
+{[12441,12488],12489}.
+{[12441,12495],12496}.
+{[12441,12498],12499}.
+{[12441,12501],12502}.
+{[12441,12504],12505}.
+{[12441,12507],12508}.
+{[12441,12527],12535}.
+{[12441,12528],12536}.
+{[12441,12529],12537}.
+{[12441,12530],12538}.
+{[12441,12541],12542}.
+{[12442,12399],12401}.
+{[12442,12402],12404}.
+{[12442,12405],12407}.
+{[12442,12408],12410}.
+{[12442,12411],12413}.
+{[12442,12495],12497}.
+{[12442,12498],12500}.
+{[12442,12501],12503}.
+{[12442,12504],12506}.
+{[12442,12507],12509}.
diff --git a/erts/emulator/internal_doc/dec.erl b/erts/emulator/internal_doc/dec.erl
new file mode 100644
index 0000000000..0315f2a52d
--- /dev/null
+++ b/erts/emulator/internal_doc/dec.erl
@@ -0,0 +1,237 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%% This program is used to generate a header file with data for
+%% normalizing denormalized unicode.
+
+%% The C header is generated from a text file containing tuples in the
+%% following format:
+%% {RevList,Translation}
+%% Where 'RevList' is a reversed list of the denormalized repressentation of
+%% the character 'Translation'. An example would be the swedish character
+%% '�', which would be represented in the file as:
+%% {[776,111],246}, as the denormalized representation of codepoint 246
+%% is [111,776] (i.e an 'o' followed by the "double dot accent character 776),
+%% while '�' instead is represented as {[776,97],228}, as the denormalized
+%% form would be [97,776] (same accent but an 'a' instead).
+%% The datafile is generated from the table on Apple's developer connection
+%% http://developer.apple.com/library/mac/#technotes/tn/tn1150table.html
+%% The generating is done whenever new data is present (i.e. dec.dat has
+%% to be changed) and not for every build. The product (the C header) is copied
+%% to $ERL_TOP/erts/beam after generation and checked in.
+%% The program and the data file is included for reference.
+
+-module(dec).
+
+-compile(export_all).
+
+-define(HASH_SIZE_FACTOR,2).
+-define(BIG_PREFIX_SIZE,392).
+
+-define(INPUT_FILE_NAME,"dec.dat").
+-define(OUTPUT_FILE_NAME,"erl_unicode_normalize.h").
+
+read(FName) ->
+ {ok,L} = file:consult(FName),
+ [{A,B} || {A,B} <- L,
+ length(A) > 1% , hd(A) < 769
+ ].
+
+dec() ->
+ L = read(?INPUT_FILE_NAME),
+ G = group(L),
+ {ok,Out} = file:open(?OUTPUT_FILE_NAME,[write]),
+ io:format
+ (Out,
+ "/*~n"
+ "* %CopyrightBegin%~n"
+ "*~n"
+ "* Copyright Ericsson AB 1999-2010. All Rights Reserved.~n"
+ "*~n"
+ "* The contents of this file are subject to the Erlang Public License,~n"
+ "* Version 1.1, (the \"License\"); you may not use this file except in~n"
+ "* compliance with the License. You should have received a copy of the~n"
+ "* Erlang Public License along with this software. If not, it can be~n"
+ "* retrieved online at http://www.erlang.org/.~n"
+ "*~n"
+ "* Software distributed under the License is distributed on an "
+ "\"AS IS\"~n"
+ "* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See~n"
+ "* the License for the specific language governing rights and "
+ "limitations~n"
+ "* under the License.~n"
+ "*~n"
+ "* %CopyrightEnd%~n"
+ "*/~n"
+ "/*~n"
+ "* This file is automatically generated by ~p.erl, "
+ "do not edit manually~n"
+ "*/~n",
+ [?MODULE]),
+
+ io:format(Out,
+ "#define HASH_SIZE_FACTOR ~w~n"
+ "typedef struct _compose_entry {~n"
+ " Uint16 c;~n"
+ " Uint16 res;~n"
+ " Uint16 num_subs;~n"
+ " struct _compose_entry *subs;~n"
+ " int *hash;~n"
+ "} CompEntry;~n~n"
+ "static int compose_tab_size = ~p;~n",
+ [?HASH_SIZE_FACTOR,length(G)]),
+ d(Out,G,[],0),
+ PreTab = tuple_to_list(make_prefix_table(G,erlang:make_tuple(102,0))),
+ dump_prefixes(Out,PreTab),
+%% Using this cuts down on the searching in the
+%% actual implementation, but wastes memory with little real gain..
+%% LL = lists:flatten([PartList || {PartList,_} <- L]),
+%% BigPreTab = tuple_to_list(
+%% make_big_prefixes(LL,
+%% erlang:make_tuple(?BIG_PREFIX_SIZE,0))),
+%% dump_big_prefixes(Out,BigPreTab),
+ file:close(Out),
+ ok.
+
+
+
+d(Out,List,D,C) ->
+ d_sub(Out,List,D,C),
+ d_top_hash(Out,List,D,C),
+ d_top(Out,List,D,C).
+d_sub(_Out,[],_D,_C) ->
+ ok;
+d_sub(Out,[{_CP,[],_Res}|T],D,C) ->
+ d_sub(Out,T,D,C+1);
+d_sub(Out,[{_CP,Subs,_Res0}|T],D,C) ->
+ d(Out,Subs,[C|D],0),
+ d_sub(Out,T,D,C+1).
+d_top(Out,L,D,C) ->
+ io:format(Out,"static CompEntry ~s[] = {~n",[format_depth(D)]),
+ d_top_1(Out,L,D,C),
+ io:format(Out,"}; /* ~s */ ~n",[format_depth(D)]).
+
+d_top_1(_Out,[],_D,_C) ->
+ ok;
+d_top_1(Out,[{CP,[],Res}|T],D,C) ->
+ io:format(Out,
+ "{~w, ~w, 0, NULL, NULL}",[CP,Res]),
+ if
+ T =:= [] ->
+ io:format(Out,"~n",[]);
+ true ->
+ io:format(Out,",~n",[])
+ end,
+ d_top_1(Out,T,D,C+1);
+d_top_1(Out,[{CP,Subs,_Res}|T],D,C) ->
+ io:format(Out,
+ "{~w, 0, ~w, ~s, ~s}",[CP,length(Subs),
+ format_depth([C|D]),
+ "hash_"++format_depth([C|D])]),
+ if
+ T =:= [] ->
+ io:format(Out,"~n",[]);
+ true ->
+ io:format(Out,",~n",[])
+ end,
+ d_top_1(Out,T,D,C+1).
+
+
+d_top_hash(Out,List,D,_C) ->
+ HSize = length(List)*?HASH_SIZE_FACTOR,
+ io:format(Out,"static int ~s[~p] = ~n",["hash_"++format_depth(D),HSize]),
+ Tup = d_top_hash_1(List,0,erlang:make_tuple(HSize,-1),HSize),
+ io:format(Out,"~p; /* ~s */ ~n",[Tup,"hash_"++format_depth(D)]).
+
+d_top_hash_1([],_,Hash,_HSize) ->
+ Hash;
+d_top_hash_1([{CP,_,_}|T],Index,Hash,HSize) ->
+ Bucket = hash_search(Hash,HSize,CP rem HSize),
+ d_top_hash_1(T,Index+1,erlang:setelement(Bucket+1,Hash,Index),HSize).
+
+hash_search(Hash,_HSize,Bucket) when element(Bucket+1,Hash) =:= -1 ->
+ Bucket;
+hash_search(Hash,HSize,Bucket) ->
+ hash_search(Hash,HSize,(Bucket + 1) rem HSize).
+
+format_depth(D) ->
+ lists:reverse(tl(lists:reverse(lists:flatten(["compose_tab_",[ integer_to_list(X) ++ "_" || X <- lists:reverse(D) ]])))).
+
+
+
+
+make_prefix_table([],Table) ->
+ Table;
+make_prefix_table([{C,_,_}|T],Table) when C =< 4023 ->
+ Index = (C div 32) + 1 - 24,
+ Pos = C rem 32,
+ X = element(Index,Table),
+ Y = X bor (1 bsl Pos),
+ NewTab = setelement(Index,Table,Y),
+ make_prefix_table(T,NewTab);
+make_prefix_table([_|T],Tab) ->
+ make_prefix_table(T,Tab).
+
+dump_prefixes(Out,L) ->
+ io:format(Out,"#define COMP_CANDIDATE_MAP_OFFSET 24~n",[]),
+ io:format(Out,"static Uint32 comp_candidate_map[] = {~n",[]),
+ dump_prefixes_1(Out,L).
+dump_prefixes_1(Out,[H]) ->
+ io:format(Out," 0x~8.16.0BU~n",[H]),
+ io:format(Out,"};~n",[]);
+dump_prefixes_1(Out,[H|T]) ->
+ io:format(Out," 0x~8.16.0BU,~n",[H]),
+ dump_prefixes_1(Out,T).
+
+%% make_big_prefixes([],Table) ->
+%% Table;
+%% make_big_prefixes([C|T],Table) ->
+%% Index = (C div 32) + 1,
+%% Pos = C rem 32,
+%% X = element(Index,Table),
+%% Y = X bor (1 bsl Pos),
+%% NewTab = setelement(Index,Table,Y),
+%% make_big_prefixes(T,NewTab).
+
+%% dump_big_prefixes(Out,L) ->
+%% io:format(Out,"#define BIG_COMP_CANDIDATE_SIZE ~w~n", [?BIG_PREFIX_SIZE]),
+%% io:format(Out,"static Uint32 big_comp_candidate_map[] = {~n",[]),
+%% dump_prefixes_1(Out,L).
+
+pick([],_,Acc) ->
+ {lists:reverse(Acc),[]};
+pick([{[H|TT],N}|T],H,Acc) ->
+ pick(T,H,[{TT,N}|Acc]);
+pick([{[H|_],_}|_]=L,M,Acc) when H =/= M ->
+ {lists:reverse(Acc),L}.
+
+
+group([]) ->
+ [];
+group([{[H],N}|T]) ->
+ {Part,Rest} = pick(T,H,[]),
+ [{H,group(Part),N}| group(Rest)];
+group([{[H|_],_}|_]=L) ->
+ {Part,Rest} = pick(L,H,[]),
+ [{H,group(Part),0}| group(Rest)].
+
+
+
+
+
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index b1ee165489..8421eb415c 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -35,6 +35,7 @@
#include "global.h"
#include "erl_threads.h"
#include "erl_mtrace.h"
+#include "erl_time.h"
#include "big.h"
#if HAVE_ERTS_MSEG
@@ -76,8 +77,10 @@ static int atoms_initialized;
static Uint cache_check_interval;
+typedef struct mem_kind_t MemKind;
+
static void check_cache(void *unused);
-static void mseg_clear_cache(void);
+static void mseg_clear_cache(MemKind*);
static int is_cache_check_scheduled;
#ifdef ERTS_THREADS_NO_SMP
static int is_cache_check_requested;
@@ -159,14 +162,43 @@ static struct {
CallCounter check_cache;
} calls;
-static cache_desc_t cache_descs[MAX_CACHE_SIZE];
-static cache_desc_t *free_cache_descs;
-static cache_desc_t *cache;
-static cache_desc_t *cache_end;
-static Uint cache_hits;
-static Uint cache_size;
-static Uint min_cached_seg_size;
-static Uint max_cached_seg_size;
+struct mem_kind_t {
+ cache_desc_t cache_descs[MAX_CACHE_SIZE];
+ cache_desc_t *free_cache_descs;
+ cache_desc_t *cache;
+ cache_desc_t *cache_end;
+
+ Uint cache_size;
+ Uint min_cached_seg_size;
+ Uint max_cached_seg_size;
+ Uint cache_hits;
+
+ struct {
+ struct {
+ Uint watermark;
+ Uint no;
+ Uint sz;
+ } current;
+ struct {
+ Uint no;
+ Uint sz;
+ } max;
+ struct {
+ Uint no;
+ Uint sz;
+ } max_ever;
+ } segments;
+
+ const char* name;
+ MemKind* next;
+};/*MemKind*/
+
+#if HALFWORD_HEAP
+static MemKind low_mem, hi_mem;
+#else
+static MemKind the_mem;
+#endif
+static MemKind* mk_list = NULL;
static Uint max_cache_size;
static Uint abs_max_cache_bad_fit;
@@ -176,47 +208,32 @@ static Uint rel_max_cache_bad_fit;
static Uint min_seg_size;
#endif
-struct {
- struct {
- Uint watermark;
- Uint no;
- Uint sz;
- } current;
- struct {
- Uint no;
- Uint sz;
- } max;
- struct {
- Uint no;
- Uint sz;
- } max_ever;
-} segments;
-#define ERTS_MSEG_ALLOC_STAT(SZ) \
+#define ERTS_MSEG_ALLOC_STAT(C,SZ) \
do { \
- segments.current.no++; \
- if (segments.max.no < segments.current.no) \
- segments.max.no = segments.current.no; \
- if (segments.current.watermark < segments.current.no) \
- segments.current.watermark = segments.current.no; \
- segments.current.sz += (SZ); \
- if (segments.max.sz < segments.current.sz) \
- segments.max.sz = segments.current.sz; \
+ C->segments.current.no++; \
+ if (C->segments.max.no < C->segments.current.no) \
+ C->segments.max.no = C->segments.current.no; \
+ if (C->segments.current.watermark < C->segments.current.no) \
+ C->segments.current.watermark = C->segments.current.no; \
+ C->segments.current.sz += (SZ); \
+ if (C->segments.max.sz < C->segments.current.sz) \
+ C->segments.max.sz = C->segments.current.sz; \
} while (0)
-#define ERTS_MSEG_DEALLOC_STAT(SZ) \
+#define ERTS_MSEG_DEALLOC_STAT(C,SZ) \
do { \
- ASSERT(segments.current.no > 0); \
- segments.current.no--; \
- ASSERT(segments.current.sz >= (SZ)); \
- segments.current.sz -= (SZ); \
+ ASSERT(C->segments.current.no > 0); \
+ C->segments.current.no--; \
+ ASSERT(C->segments.current.sz >= (SZ)); \
+ C->segments.current.sz -= (SZ); \
} while (0)
-#define ERTS_MSEG_REALLOC_STAT(OSZ, NSZ) \
+#define ERTS_MSEG_REALLOC_STAT(C,OSZ, NSZ) \
do { \
- ASSERT(segments.current.sz >= (OSZ)); \
- segments.current.sz -= (OSZ); \
- segments.current.sz += (NSZ); \
+ ASSERT(C->segments.current.sz >= (OSZ)); \
+ C->segments.current.sz -= (OSZ); \
+ C->segments.current.sz += (NSZ); \
} while (0)
#define ONE_GIGA (1000000000)
@@ -271,7 +288,7 @@ schedule_cache_check(void)
#endif
{
cache_check_timer.active = 0;
- erl_set_timer(&cache_check_timer,
+ erts_set_timer(&cache_check_timer,
check_cache,
NULL,
NULL,
@@ -302,13 +319,16 @@ check_schedule_cache_check(void)
static void
mseg_shutdown(void)
{
+ MemKind* mk;
erts_mtx_lock(&mseg_mutex);
- mseg_clear_cache();
+ for (mk=mk_list; mk; mk=mk->next) {
+ mseg_clear_cache(mk);
+ }
erts_mtx_unlock(&mseg_mutex);
}
static ERTS_INLINE void *
-mseg_create(Uint size)
+mseg_create(MemKind* mk, Uint size)
{
void *seg;
@@ -318,19 +338,21 @@ mseg_create(Uint size)
seg = erts_sys_alloc(ERTS_ALC_N_INVALID, NULL, size);
#elif HAVE_MMAP
#if HALFWORD_HEAP
- seg = pmmap(size);
-#else
- seg = (void *) mmap((void *) 0, (size_t) size,
- MMAP_PROT, MMAP_FLAGS, MMAP_FD, 0);
- if (seg == (void *) MAP_FAILED)
- seg = NULL;
-#endif
-#if HALFWORD_HEAP
- if ((unsigned long) seg & CHECK_POINTER_MASK) {
- erts_fprintf(stderr,"Pointer mask failure (0x%08lx)\n",(unsigned long) seg);
- return NULL;
+ if (mk == &low_mem) {
+ seg = pmmap(size);
+ if ((unsigned long) seg & CHECK_POINTER_MASK) {
+ erts_fprintf(stderr,"Pointer mask failure (0x%08lx)\n",(unsigned long) seg);
+ return NULL;
+ }
}
+ else
#endif
+ {
+ seg = (void *) mmap((void *) 0, (size_t) size,
+ MMAP_PROT, MMAP_FLAGS, MMAP_FD, 0);
+ if (seg == (void *) MAP_FAILED)
+ seg = NULL;
+ }
#else
#error "Missing mseg_create() implementation"
#endif
@@ -341,20 +363,23 @@ mseg_create(Uint size)
}
static ERTS_INLINE void
-mseg_destroy(void *seg, Uint size)
+mseg_destroy(MemKind* mk, void *seg, Uint size)
{
#if defined(ERTS_MSEG_FAKE_SEGMENTS)
erts_sys_free(ERTS_ALC_N_INVALID, NULL, seg);
#elif HAVE_MMAP
+ int res;
-#ifdef DEBUG
- int res =
-#endif
#if HALFWORD_HEAP
- pmunmap((void *) seg, size);
-#else
- munmap((void *) seg, size);
+ if (mk == &low_mem) {
+ res = pmunmap((void *) seg, size);
+ }
+ else
#endif
+ {
+ res = munmap((void *) seg, size);
+ }
+
ASSERT(size % page_size == 0);
ASSERT(res == 0);
#else
@@ -368,7 +393,7 @@ mseg_destroy(void *seg, Uint size)
#if HAVE_MSEG_RECREATE
static ERTS_INLINE void *
-mseg_recreate(void *old_seg, Uint old_size, Uint new_size)
+mseg_recreate(MemKind* mk, void *old_seg, Uint old_size, Uint new_size)
{
void *new_seg;
@@ -379,25 +404,29 @@ mseg_recreate(void *old_seg, Uint old_size, Uint new_size)
new_seg = erts_sys_realloc(ERTS_ALC_N_INVALID, NULL, old_seg, new_size);
#elif HAVE_MREMAP
#if HALFWORD_HEAP
- new_seg = (void *) pmremap((void *) old_seg,
- (size_t) old_size,
- (size_t) new_size);
-#elif defined(__NetBSD__)
- new_seg = (void *) mremap((void *) old_seg,
- (size_t) old_size,
- NULL,
- (size_t) new_size,
- 0);
- if (new_seg == (void *) MAP_FAILED)
- new_seg = NULL;
-#else
- new_seg = (void *) mremap((void *) old_seg,
- (size_t) old_size,
- (size_t) new_size,
- MREMAP_MAYMOVE);
- if (new_seg == (void *) MAP_FAILED)
- new_seg = NULL;
+ if (mk == &low_mem) {
+ new_seg = (void *) pmremap((void *) old_seg,
+ (size_t) old_size,
+ (size_t) new_size);
+ }
+ else
#endif
+ {
+ #if defined(__NetBSD__)
+ new_seg = (void *) mremap((void *) old_seg,
+ (size_t) old_size,
+ NULL,
+ (size_t) new_size,
+ 0);
+ #else
+ new_seg = (void *) mremap((void *) old_seg,
+ (size_t) old_size,
+ (size_t) new_size,
+ MREMAP_MAYMOVE);
+ #endif
+ if (new_seg == (void *) MAP_FAILED)
+ new_seg = NULL;
+ }
#else
#error "Missing mseg_recreate() implementation"
#endif
@@ -411,134 +440,142 @@ mseg_recreate(void *old_seg, Uint old_size, Uint new_size)
static ERTS_INLINE cache_desc_t *
-alloc_cd(void)
+alloc_cd(MemKind* mk)
{
- cache_desc_t *cd = free_cache_descs;
+ cache_desc_t *cd = mk->free_cache_descs;
ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
if (cd)
- free_cache_descs = cd->next;
+ mk->free_cache_descs = cd->next;
return cd;
}
static ERTS_INLINE void
-free_cd(cache_desc_t *cd)
+free_cd(MemKind* mk, cache_desc_t *cd)
{
ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
- cd->next = free_cache_descs;
- free_cache_descs = cd;
+ cd->next = mk->free_cache_descs;
+ mk->free_cache_descs = cd;
}
static ERTS_INLINE void
-link_cd(cache_desc_t *cd)
+link_cd(MemKind* mk, cache_desc_t *cd)
{
ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
- if (cache)
- cache->prev = cd;
- cd->next = cache;
+ if (mk->cache)
+ mk->cache->prev = cd;
+ cd->next = mk->cache;
cd->prev = NULL;
- cache = cd;
+ mk->cache = cd;
- if (!cache_end) {
+ if (!mk->cache_end) {
ASSERT(!cd->next);
- cache_end = cd;
+ mk->cache_end = cd;
}
- cache_size++;
+ mk->cache_size++;
}
+#if CAN_PARTLY_DESTROY
static ERTS_INLINE void
-end_link_cd(cache_desc_t *cd)
+end_link_cd(MemKind* mk, cache_desc_t *cd)
{
ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
- if (cache_end)
- cache_end->next = cd;
+ if (mk->cache_end)
+ mk->cache_end->next = cd;
cd->next = NULL;
- cd->prev = cache_end;
- cache_end = cd;
+ cd->prev = mk->cache_end;
+ mk->cache_end = cd;
- if (!cache) {
+ if (!mk->cache) {
ASSERT(!cd->prev);
- cache = cd;
+ mk->cache = cd;
}
- cache_size++;
+ mk->cache_size++;
}
+#endif
static ERTS_INLINE void
-unlink_cd(cache_desc_t *cd)
+unlink_cd(MemKind* mk, cache_desc_t *cd)
{
ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
if (cd->next)
cd->next->prev = cd->prev;
else
- cache_end = cd->prev;
+ mk->cache_end = cd->prev;
if (cd->prev)
cd->prev->next = cd->next;
else
- cache = cd->next;
- ASSERT(cache_size > 0);
- cache_size--;
+ mk->cache = cd->next;
+ ASSERT(mk->cache_size > 0);
+ mk->cache_size--;
}
static ERTS_INLINE void
-check_cache_limits(void)
+check_cache_limits(MemKind* mk)
{
cache_desc_t *cd;
ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
- max_cached_seg_size = 0;
- min_cached_seg_size = ~((Uint) 0);
- for (cd = cache; cd; cd = cd->next) {
- if (cd->size < min_cached_seg_size)
- min_cached_seg_size = cd->size;
- if (cd->size > max_cached_seg_size)
- max_cached_seg_size = cd->size;
+ mk->max_cached_seg_size = 0;
+ mk->min_cached_seg_size = ~((Uint) 0);
+ for (cd = mk->cache; cd; cd = cd->next) {
+ if (cd->size < mk->min_cached_seg_size)
+ mk->min_cached_seg_size = cd->size;
+ if (cd->size > mk->max_cached_seg_size)
+ mk->max_cached_seg_size = cd->size;
}
-
}
static ERTS_INLINE void
-adjust_cache_size(int force_check_limits)
+adjust_cache_size(MemKind* mk, int force_check_limits)
{
cache_desc_t *cd;
int check_limits = force_check_limits;
- Sint max_cached = ((Sint) segments.current.watermark
- - (Sint) segments.current.no);
+ Sint max_cached = ((Sint) mk->segments.current.watermark
+ - (Sint) mk->segments.current.no);
ERTS_LC_ASSERT(erts_lc_mtx_is_locked(&mseg_mutex));
- while (((Sint) cache_size) > max_cached && ((Sint) cache_size) > 0) {
- ASSERT(cache_end);
- cd = cache_end;
+ while (((Sint) mk->cache_size) > max_cached && ((Sint) mk->cache_size) > 0) {
+ ASSERT(mk->cache_end);
+ cd = mk->cache_end;
if (!check_limits &&
- !(min_cached_seg_size < cd->size
- && cd->size < max_cached_seg_size)) {
+ !(mk->min_cached_seg_size < cd->size
+ && cd->size < mk->max_cached_seg_size)) {
check_limits = 1;
}
if (erts_mtrace_enabled)
erts_mtrace_crr_free(SEGTYPE, SEGTYPE, cd->seg);
- mseg_destroy(cd->seg, cd->size);
- unlink_cd(cd);
- free_cd(cd);
+ mseg_destroy(mk, cd->seg, cd->size);
+ unlink_cd(mk,cd);
+ free_cd(mk,cd);
}
if (check_limits)
- check_cache_limits();
-
+ check_cache_limits(mk);
}
static void
-check_cache(void *unused)
+check_one_cache(MemKind* mk)
{
+ if (mk->segments.current.watermark > mk->segments.current.no)
+ mk->segments.current.watermark--;
+ adjust_cache_size(mk, 0);
+
+ if (mk->cache_size)
+ schedule_cache_check();
+}
+
+static void check_cache(void* unused)
+{
+ MemKind* mk;
erts_mtx_lock(&mseg_mutex);
is_cache_check_scheduled = 0;
- if (segments.current.watermark > segments.current.no)
- segments.current.watermark--;
- adjust_cache_size(0);
-
- if (cache_size)
- schedule_cache_check();
+ for (mk=mk_list; mk; mk=mk->next) {
+ check_one_cache(mk);
+ }
INC_CC(check_cache);
@@ -546,28 +583,45 @@ check_cache(void *unused)
}
static void
-mseg_clear_cache(void)
+mseg_clear_cache(MemKind* mk)
{
- segments.current.watermark = 0;
+ mk->segments.current.watermark = 0;
- adjust_cache_size(1);
+ adjust_cache_size(mk, 1);
- ASSERT(!cache);
- ASSERT(!cache_end);
- ASSERT(!cache_size);
+ ASSERT(!mk->cache);
+ ASSERT(!mk->cache_end);
+ ASSERT(!mk->cache_size);
- segments.current.watermark = segments.current.no;
+ mk->segments.current.watermark = mk->segments.current.no;
INC_CC(clear_cache);
}
+static ERTS_INLINE MemKind* type2mk(ErtsAlcType_t atype)
+{
+#if HALFWORD_HEAP
+ switch (atype) {
+ case ERTS_ALC_A_ETS:
+ case ERTS_ALC_A_BINARY:
+ case ERTS_ALC_A_FIXED_SIZE:
+ case ERTS_ALC_A_DRIVER:
+ return &hi_mem;
+ default:
+ return &low_mem;
+ }
+#else
+ return &the_mem;
+#endif
+}
+
static void *
mseg_alloc(ErtsAlcType_t atype, Uint *size_p, const ErtsMsegOpt_t *opt)
{
-
Uint max, min, diff_size, size;
cache_desc_t *cd, *cand_cd;
void *seg;
+ MemKind* mk = type2mk(atype);
INC_CC(alloc);
@@ -580,11 +634,11 @@ mseg_alloc(ErtsAlcType_t atype, Uint *size_p, const ErtsMsegOpt_t *opt)
if (!opt->cache) {
create_seg:
- adjust_cache_size(0);
- seg = mseg_create(size);
+ adjust_cache_size(mk,0);
+ seg = mseg_create(mk, size);
if (!seg) {
- mseg_clear_cache();
- seg = mseg_create(size);
+ mseg_clear_cache(mk);
+ seg = mseg_create(mk, size);
if (!seg)
size = 0;
}
@@ -593,17 +647,17 @@ mseg_alloc(ErtsAlcType_t atype, Uint *size_p, const ErtsMsegOpt_t *opt)
if (seg) {
if (erts_mtrace_enabled)
erts_mtrace_crr_alloc(seg, atype, ERTS_MTRACE_SEGMENT_ID, size);
- ERTS_MSEG_ALLOC_STAT(size);
+ ERTS_MSEG_ALLOC_STAT(mk,size);
}
return seg;
}
- if (size > max_cached_seg_size)
+ if (size > mk->max_cached_seg_size)
goto create_seg;
- if (size < min_cached_seg_size) {
+ if (size < mk->min_cached_seg_size) {
- diff_size = min_cached_seg_size - size;
+ diff_size = mk->min_cached_seg_size - size;
if (diff_size > abs_max_cache_bad_fit)
goto create_seg;
@@ -617,7 +671,7 @@ mseg_alloc(ErtsAlcType_t atype, Uint *size_p, const ErtsMsegOpt_t *opt)
min = ~((Uint) 0);
cand_cd = NULL;
- for (cd = cache; cd; cd = cd->next) {
+ for (cd = mk->cache; cd; cd = cd->next) {
if (cd->size >= size) {
if (!cand_cd) {
cand_cd = cd;
@@ -638,8 +692,8 @@ mseg_alloc(ErtsAlcType_t atype, Uint *size_p, const ErtsMsegOpt_t *opt)
min = cd->size;
}
- min_cached_seg_size = min;
- max_cached_seg_size = max;
+ mk->min_cached_seg_size = min;
+ mk->max_cached_seg_size = max;
if (!cand_cd)
goto create_seg;
@@ -648,20 +702,20 @@ mseg_alloc(ErtsAlcType_t atype, Uint *size_p, const ErtsMsegOpt_t *opt)
if (diff_size > abs_max_cache_bad_fit
|| 100*PAGES(diff_size) > rel_max_cache_bad_fit*PAGES(size)) {
- if (max_cached_seg_size < cand_cd->size)
- max_cached_seg_size = cand_cd->size;
- if (min_cached_seg_size > cand_cd->size)
- min_cached_seg_size = cand_cd->size;
+ if (mk->max_cached_seg_size < cand_cd->size)
+ mk->max_cached_seg_size = cand_cd->size;
+ if (mk->min_cached_seg_size > cand_cd->size)
+ mk->min_cached_seg_size = cand_cd->size;
goto create_seg;
}
- cache_hits++;
+ mk->cache_hits++;
size = cand_cd->size;
seg = cand_cd->seg;
- unlink_cd(cand_cd);
- free_cd(cand_cd);
+ unlink_cd(mk,cand_cd);
+ free_cd(mk,cand_cd);
*size_p = size;
@@ -671,7 +725,7 @@ mseg_alloc(ErtsAlcType_t atype, Uint *size_p, const ErtsMsegOpt_t *opt)
}
if (seg)
- ERTS_MSEG_ALLOC_STAT(size);
+ ERTS_MSEG_ALLOC_STAT(mk,size);
return seg;
}
@@ -680,41 +734,42 @@ static void
mseg_dealloc(ErtsAlcType_t atype, void *seg, Uint size,
const ErtsMsegOpt_t *opt)
{
+ MemKind* mk = type2mk(atype);
cache_desc_t *cd;
- ERTS_MSEG_DEALLOC_STAT(size);
+ ERTS_MSEG_DEALLOC_STAT(mk,size);
if (!opt->cache || max_cache_size == 0) {
if (erts_mtrace_enabled)
erts_mtrace_crr_free(atype, SEGTYPE, seg);
- mseg_destroy(seg, size);
+ mseg_destroy(mk, seg, size);
}
else {
int check_limits = 0;
- if (size < min_cached_seg_size)
- min_cached_seg_size = size;
- if (size > max_cached_seg_size)
- max_cached_seg_size = size;
-
- if (!free_cache_descs) {
- cd = cache_end;
- if (!(min_cached_seg_size < cd->size
- && cd->size < max_cached_seg_size)) {
+ if (size < mk->min_cached_seg_size)
+ mk->min_cached_seg_size = size;
+ if (size > mk->max_cached_seg_size)
+ mk->max_cached_seg_size = size;
+
+ if (!mk->free_cache_descs) {
+ cd = mk->cache_end;
+ if (!(mk->min_cached_seg_size < cd->size
+ && cd->size < mk->max_cached_seg_size)) {
check_limits = 1;
}
if (erts_mtrace_enabled)
erts_mtrace_crr_free(SEGTYPE, SEGTYPE, cd->seg);
- mseg_destroy(cd->seg, cd->size);
- unlink_cd(cd);
- free_cd(cd);
+ mseg_destroy(mk, cd->seg, cd->size);
+ unlink_cd(mk,cd);
+ free_cd(mk,cd);
}
- cd = alloc_cd();
+ cd = alloc_cd(mk);
ASSERT(cd);
cd->seg = seg;
cd->size = size;
- link_cd(cd);
+ link_cd(mk,cd);
if (erts_mtrace_enabled) {
erts_mtrace_crr_free(atype, SEGTYPE, seg);
@@ -724,7 +779,7 @@ mseg_dealloc(ErtsAlcType_t atype, void *seg, Uint size,
/* ASSERT(segments.current.watermark >= segments.current.no + cache_size); */
if (check_limits)
- check_cache_limits();
+ check_cache_limits(mk);
schedule_cache_check();
@@ -737,6 +792,7 @@ static void *
mseg_realloc(ErtsAlcType_t atype, void *seg, Uint old_size, Uint *new_size_p,
const ErtsMsegOpt_t *opt)
{
+ MemKind* mk = type2mk(atype);
void *new_seg;
Uint new_size;
@@ -774,15 +830,15 @@ mseg_realloc(ErtsAlcType_t atype, void *seg, Uint old_size, Uint *new_size_p,
#if CAN_PARTLY_DESTROY
if (shrink_sz > min_seg_size
- && free_cache_descs
+ && mk->free_cache_descs
&& opt->cache) {
cache_desc_t *cd;
- cd = alloc_cd();
+ cd = alloc_cd(mk);
ASSERT(cd);
cd->seg = ((char *) seg) + new_size;
cd->size = shrink_sz;
- end_link_cd(cd);
+ end_link_cd(mk,cd);
if (erts_mtrace_enabled) {
erts_mtrace_crr_realloc(new_seg,
@@ -801,7 +857,7 @@ mseg_realloc(ErtsAlcType_t atype, void *seg, Uint old_size, Uint *new_size_p,
SEGTYPE,
seg,
new_size);
- mseg_destroy(((char *) seg) + new_size, shrink_sz);
+ mseg_destroy(mk, ((char *) seg) + new_size, shrink_sz);
}
#elif HAVE_MSEG_RECREATE
@@ -835,7 +891,7 @@ mseg_realloc(ErtsAlcType_t atype, void *seg, Uint old_size, Uint *new_size_p,
#if !CAN_PARTLY_DESTROY
do_recreate:
#endif
- new_seg = mseg_recreate((void *) seg, old_size, new_size);
+ new_seg = mseg_recreate(mk, (void *) seg, old_size, new_size);
if (erts_mtrace_enabled)
erts_mtrace_crr_realloc(new_seg, atype, SEGTYPE, seg, new_size);
if (!new_seg)
@@ -858,7 +914,7 @@ mseg_realloc(ErtsAlcType_t atype, void *seg, Uint old_size, Uint *new_size_p,
*new_size_p = new_size;
- ERTS_MSEG_REALLOC_STAT(old_size, new_size);
+ ERTS_MSEG_REALLOC_STAT(mk, old_size, new_size);
return new_seg;
}
@@ -874,6 +930,8 @@ static struct {
Eterm mcs;
Eterm cci;
+ Eterm memkind;
+ Eterm name;
Eterm status;
Eterm cached_segments;
Eterm cache_hits;
@@ -923,6 +981,8 @@ init_atoms(void)
#endif
AM_INIT(version);
+ AM_INIT(memkind);
+ AM_INIT(name);
AM_INIT(options);
AM_INIT(amcbf);
@@ -1133,65 +1193,88 @@ info_calls(int *print_to_p, void *print_to_arg, Uint **hpp, Uint *szp)
}
static Eterm
-info_status(int *print_to_p,
- void *print_to_arg,
- int begin_new_max_period,
- Uint **hpp,
- Uint *szp)
+info_status(MemKind* mk, int *print_to_p, void *print_to_arg,
+ int begin_new_max_period, Uint **hpp, Uint *szp)
{
Eterm res = THE_NON_VALUE;
- if (segments.max_ever.no < segments.max.no)
- segments.max_ever.no = segments.max.no;
- if (segments.max_ever.sz < segments.max.sz)
- segments.max_ever.sz = segments.max.sz;
+ if (mk->segments.max_ever.no < mk->segments.max.no)
+ mk->segments.max_ever.no = mk->segments.max.no;
+ if (mk->segments.max_ever.sz < mk->segments.max.sz)
+ mk->segments.max_ever.sz = mk->segments.max.sz;
if (print_to_p) {
int to = *print_to_p;
void *arg = print_to_arg;
- erts_print(to, arg, "cached_segments: %bpu\n", cache_size);
- erts_print(to, arg, "cache_hits: %bpu\n", cache_hits);
+ erts_print(to, arg, "cached_segments: %bpu\n", mk->cache_size);
+ erts_print(to, arg, "cache_hits: %bpu\n", mk->cache_hits);
erts_print(to, arg, "segments: %bpu %bpu %bpu\n",
- segments.current.no, segments.max.no, segments.max_ever.no);
+ mk->segments.current.no, mk->segments.max.no, mk->segments.max_ever.no);
erts_print(to, arg, "segments_size: %bpu %bpu %bpu\n",
- segments.current.sz, segments.max.sz, segments.max_ever.sz);
+ mk->segments.current.sz, mk->segments.max.sz, mk->segments.max_ever.sz);
erts_print(to, arg, "segments_watermark: %bpu\n",
- segments.current.watermark);
+ mk->segments.current.watermark);
}
if (hpp || szp) {
res = NIL;
add_2tup(hpp, szp, &res,
am.segments_watermark,
- bld_unstable_uint(hpp, szp, segments.current.watermark));
+ bld_unstable_uint(hpp, szp, mk->segments.current.watermark));
add_4tup(hpp, szp, &res,
am.segments_size,
- bld_unstable_uint(hpp, szp, segments.current.sz),
- bld_unstable_uint(hpp, szp, segments.max.sz),
- bld_unstable_uint(hpp, szp, segments.max_ever.sz));
+ bld_unstable_uint(hpp, szp, mk->segments.current.sz),
+ bld_unstable_uint(hpp, szp, mk->segments.max.sz),
+ bld_unstable_uint(hpp, szp, mk->segments.max_ever.sz));
add_4tup(hpp, szp, &res,
am.segments,
- bld_unstable_uint(hpp, szp, segments.current.no),
- bld_unstable_uint(hpp, szp, segments.max.no),
- bld_unstable_uint(hpp, szp, segments.max_ever.no));
+ bld_unstable_uint(hpp, szp, mk->segments.current.no),
+ bld_unstable_uint(hpp, szp, mk->segments.max.no),
+ bld_unstable_uint(hpp, szp, mk->segments.max_ever.no));
add_2tup(hpp, szp, &res,
am.cache_hits,
- bld_unstable_uint(hpp, szp, cache_hits));
+ bld_unstable_uint(hpp, szp, mk->cache_hits));
add_2tup(hpp, szp, &res,
am.cached_segments,
- bld_unstable_uint(hpp, szp, cache_size));
+ bld_unstable_uint(hpp, szp, mk->cache_size));
}
if (begin_new_max_period) {
- segments.max.no = segments.current.no;
- segments.max.sz = segments.current.sz;
+ mk->segments.max.no = mk->segments.current.no;
+ mk->segments.max.sz = mk->segments.current.sz;
}
return res;
}
+static Eterm info_memkind(MemKind* mk, int *print_to_p, void *print_to_arg,
+ int begin_max_per, Uint **hpp, Uint *szp)
+{
+ Eterm res = THE_NON_VALUE;
+ Eterm atoms[3];
+ Eterm values[3];
+
+ if (print_to_p) {
+ erts_print(*print_to_p, print_to_arg, "memory kind: %s\n", mk->name);
+ }
+ if (hpp || szp) {
+ atoms[0] = am.name;
+ atoms[1] = am.status;
+ atoms[2] = am.calls;
+ values[0] = erts_bld_string(hpp, szp, mk->name);
+ }
+ values[1] = info_status(mk, print_to_p, print_to_arg, begin_max_per, hpp, szp);
+ values[2] = info_calls(print_to_p, print_to_arg, hpp, szp);
+
+ if (hpp || szp)
+ res = bld_2tup_list(hpp, szp, 3, atoms, values);
+
+ return res;
+}
+
+
static Eterm
info_version(int *print_to_p, void *print_to_arg, Uint **hpp, Uint *szp)
{
@@ -1238,6 +1321,7 @@ erts_mseg_info(int *print_to_p,
Eterm res = THE_NON_VALUE;
Eterm atoms[4];
Eterm values[4];
+ Uint n = 0;
erts_mtx_lock(&mseg_mutex);
@@ -1248,17 +1332,19 @@ erts_mseg_info(int *print_to_p,
atoms[0] = am.version;
atoms[1] = am.options;
- atoms[2] = am.status;
- atoms[3] = am.calls;
+ atoms[2] = am.memkind;
+ atoms[3] = am.memkind;
}
-
- values[0] = info_version(print_to_p, print_to_arg, hpp, szp);
- values[1] = info_options("option ", print_to_p, print_to_arg, hpp, szp);
- values[2] = info_status(print_to_p, print_to_arg, begin_max_per, hpp, szp);
- values[3] = info_calls(print_to_p, print_to_arg, hpp, szp);
-
+ values[n++] = info_version(print_to_p, print_to_arg, hpp, szp);
+ values[n++] = info_options("option ", print_to_p, print_to_arg, hpp, szp);
+#if HALFWORD_HEAP
+ values[n++] = info_memkind(&low_mem, print_to_p, print_to_arg, begin_max_per, hpp, szp);
+ values[n++] = info_memkind(&hi_mem, print_to_p, print_to_arg, begin_max_per, hpp, szp);
+#else
+ values[n++] = info_memkind(&the_mem, print_to_p, print_to_arg, begin_max_per, hpp, szp);
+#endif
if (hpp || szp)
- res = bld_2tup_list(hpp, szp, 4, atoms, values);
+ res = bld_2tup_list(hpp, szp, n, atoms, values);
erts_mtx_unlock(&mseg_mutex);
@@ -1317,17 +1403,23 @@ erts_mseg_realloc(ErtsAlcType_t atype, void *seg, Uint old_size,
void
erts_mseg_clear_cache(void)
{
+ MemKind* mk;
erts_mtx_lock(&mseg_mutex);
- mseg_clear_cache();
+ for (mk=mk_list; mk; mk=mk->next) {
+ mseg_clear_cache(mk);
+ }
erts_mtx_unlock(&mseg_mutex);
}
Uint
erts_mseg_no(void)
{
- Uint n;
+ MemKind* mk;
+ Uint n = 0;
erts_mtx_lock(&mseg_mutex);
- n = segments.current.no;
+ for (mk=mk_list; mk; mk=mk->next) {
+ n += mk->segments.current.no;
+ }
erts_mtx_unlock(&mseg_mutex);
return n;
}
@@ -1338,11 +1430,43 @@ erts_mseg_unit_size(void)
return page_size;
}
-void
-erts_mseg_init(ErtsMsegInit_t *init)
+static void mem_kind_init(MemKind* mk, const char* name)
{
unsigned i;
+ mk->cache = NULL;
+ mk->cache_end = NULL;
+ mk->max_cached_seg_size = 0;
+ mk->min_cached_seg_size = ~((Uint) 0);
+ mk->cache_size = 0;
+ mk->cache_hits = 0;
+
+ if (max_cache_size > 0) {
+ for (i = 0; i < max_cache_size - 1; i++)
+ mk->cache_descs[i].next = &mk->cache_descs[i + 1];
+ mk->cache_descs[max_cache_size - 1].next = NULL;
+ mk->free_cache_descs = &mk->cache_descs[0];
+ }
+ else
+ mk->free_cache_descs = NULL;
+
+ mk->segments.current.watermark = 0;
+ mk->segments.current.no = 0;
+ mk->segments.current.sz = 0;
+ mk->segments.max.no = 0;
+ mk->segments.max.sz = 0;
+ mk->segments.max_ever.no = 0;
+ mk->segments.max_ever.sz = 0;
+
+ mk->name = name;
+ mk->next = mk_list;
+ mk_list = mk;
+}
+
+
+void
+erts_mseg_init(ErtsMsegInit_t *init)
+{
atoms_initialized = 0;
is_init_done = 0;
@@ -1385,40 +1509,33 @@ erts_mseg_init(ErtsMsegInit_t *init)
min_seg_size = ~((Uint) 0);
#endif
- cache = NULL;
- cache_end = NULL;
- cache_hits = 0;
- max_cached_seg_size = 0;
- min_cached_seg_size = ~((Uint) 0);
- cache_size = 0;
+ if (max_cache_size > MAX_CACHE_SIZE)
+ max_cache_size = MAX_CACHE_SIZE;
+
+#if HALFWORD_HEAP
+ mem_kind_init(&low_mem, "low memory");
+ mem_kind_init(&hi_mem, "high memory");
+#else
+ mem_kind_init(&the_mem, "all memory");
+#endif
is_cache_check_scheduled = 0;
#ifdef ERTS_THREADS_NO_SMP
is_cache_check_requested = 0;
#endif
+}
- if (max_cache_size > MAX_CACHE_SIZE)
- max_cache_size = MAX_CACHE_SIZE;
- if (max_cache_size > 0) {
- for (i = 0; i < max_cache_size - 1; i++)
- cache_descs[i].next = &cache_descs[i + 1];
- cache_descs[max_cache_size - 1].next = NULL;
- free_cache_descs = &cache_descs[0];
+static ERTS_INLINE Uint tot_cache_size(void)
+{
+ MemKind* mk;
+ Uint sz = 0;
+ for (mk=mk_list; mk; mk=mk->next) {
+ sz += mk->cache_size;
}
- else
- free_cache_descs = NULL;
-
- segments.current.watermark = 0;
- segments.current.no = 0;
- segments.current.sz = 0;
- segments.max.no = 0;
- segments.max.sz = 0;
- segments.max_ever.no = 0;
- segments.max_ever.sz = 0;
+ return sz;
}
-
/*
* erts_mseg_late_init() have to be called after all allocators,
* threads and timers have been initialized.
@@ -1436,7 +1553,7 @@ erts_mseg_late_init(void)
#ifdef ERTS_THREADS_NO_SMP
async_handle = handle;
#endif
- if (cache_size)
+ if (tot_cache_size())
schedule_cache_check();
erts_mtx_unlock(&mseg_mutex);
}
@@ -1477,7 +1594,7 @@ erts_mseg_test(unsigned long op,
case 0x406: {
unsigned long res;
erts_mtx_lock(&mseg_mutex);
- res = (unsigned long) cache_size;
+ res = (unsigned long) tot_cache_size();
erts_mtx_unlock(&mseg_mutex);
return res;
}
@@ -1756,6 +1873,7 @@ static int pmunmap(void *p, size_t size)
FreeBlock *last;
FreeBlock *nb = (FreeBlock *) p;
+ ASSERT(((unsigned long)p & CHECK_POINTER_MASK)==0);
if (real_size > pagsz) {
if (do_unmap(((char *) p) + pagsz,real_size - pagsz)) {
return 1;
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index c17806d96c..77ac2de5f6 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2006-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -124,25 +124,11 @@
erts_smp_mtx_unlock(&(PS)->mtx)
#define ERTS_POLLSET_SET_POLLED_CHK(PS) \
- ((int) erts_smp_atomic_xchg(&(PS)->polled, (long) 1))
+ ((int) erts_atomic32_xchg(&(PS)->polled, (erts_aint32_t) 1))
#define ERTS_POLLSET_UNSET_POLLED(PS) \
- erts_smp_atomic_set(&(PS)->polled, (long) 0)
+ erts_atomic32_set(&(PS)->polled, (erts_aint32_t) 0)
#define ERTS_POLLSET_IS_POLLED(PS) \
- ((int) erts_smp_atomic_read(&(PS)->polled))
-
-#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))
+ ((int) erts_atomic32_read(&(PS)->polled))
#else
@@ -152,69 +138,21 @@ do { \
#define ERTS_POLLSET_UNSET_POLLED(PS)
#define ERTS_POLLSET_IS_POLLED(PS) 0
-#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
-
-/*
- * Ideally, the ERTS_POLLSET_SET_POLLER_WOKEN_CHK(PS) operation would
- * be atomic. This operation isn't, but we will do okay anyway. The
- * "woken check" is only an optimization. The only requirement we have:
- * If (PS)->woken is set to a value != 0 when interrupting, we have to
- * write on the the wakeup pipe at least once. Multiple writes are okay.
- */
-#define ERTS_POLLSET_SET_POLLER_WOKEN_CHK(PS) ((PS)->woken++)
-#define ERTS_POLLSET_SET_POLLER_WOKEN(PS) ((PS)->woken = 1, (void) 0)
-#define ERTS_POLLSET_UNSET_POLLER_WOKEN(PS) ((PS)->woken = 0, (void) 0)
-#define ERTS_POLLSET_IS_POLLER_WOKEN(PS) ((PS)->woken)
-
-#else
-
-#define ERTS_POLLSET_SET_POLLER_WOKEN_CHK(PS) 1
-#define ERTS_POLLSET_SET_POLLER_WOKEN(PS)
-#define ERTS_POLLSET_UNSET_POLLER_WOKEN(PS)
-#define ERTS_POLLSET_IS_POLLER_WOKEN(PS) 1
-
-#endif
-
#endif
#if ERTS_POLL_USE_UPDATE_REQUESTS_QUEUE
#define ERTS_POLLSET_SET_HAVE_UPDATE_REQUESTS(PS) \
- erts_smp_atomic_set(&(PS)->have_update_requests, (long) 1)
+ erts_smp_atomic32_set(&(PS)->have_update_requests, (erts_aint32_t) 1)
#define ERTS_POLLSET_UNSET_HAVE_UPDATE_REQUESTS(PS) \
- erts_smp_atomic_set(&(PS)->have_update_requests, (long) 0)
+ erts_smp_atomic32_set(&(PS)->have_update_requests, (erts_aint32_t) 0)
#define ERTS_POLLSET_HAVE_UPDATE_REQUESTS(PS) \
- ((int) erts_smp_atomic_read(&(PS)->have_update_requests))
+ ((int) erts_smp_atomic32_read(&(PS)->have_update_requests))
#else
#define ERTS_POLLSET_SET_HAVE_UPDATE_REQUESTS(PS)
#define ERTS_POLLSET_UNSET_HAVE_UPDATE_REQUESTS(PS)
#define ERTS_POLLSET_HAVE_UPDATE_REQUESTS(PS) 0
#endif
-#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT && !defined(ERTS_SMP)
-
-#define ERTS_POLLSET_UNSET_INTERRUPTED_CHK(PS) unset_interrupted_chk((PS))
-#define ERTS_POLLSET_UNSET_INTERRUPTED(PS) ((PS)->interrupt = 0, (void) 0)
-#define ERTS_POLLSET_SET_INTERRUPTED(PS) ((PS)->interrupt = 1, (void) 0)
-#define ERTS_POLLSET_IS_INTERRUPTED(PS) ((PS)->interrupt)
-
-#else
-
-#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
-
#if ERTS_POLL_USE_FALLBACK
# if ERTS_POLL_USE_POLL
# define ERTS_POLL_NEED_FALLBACK(PS) ((PS)->no_poll_fds > 1)
@@ -318,14 +256,12 @@ struct ErtsPollSet_ {
#if ERTS_POLL_USE_UPDATE_REQUESTS_QUEUE
ErtsPollSetUpdateRequestsBlock update_requests;
ErtsPollSetUpdateRequestsBlock *curr_upd_req_block;
- erts_smp_atomic_t have_update_requests;
+ erts_smp_atomic32_t have_update_requests;
#endif
#ifdef ERTS_SMP
- erts_smp_atomic_t polled;
- erts_smp_atomic_t woken;
+ erts_atomic32_t polled;
erts_smp_mtx_t mtx;
#elif ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
- volatile int woken;
#endif
#if ERTS_POLL_USE_WAKEUP_PIPE
int wake_fds[2];
@@ -333,12 +269,12 @@ struct ErtsPollSet_ {
#if ERTS_POLL_USE_FALLBACK
int fallback_used;
#endif
-#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT && !defined(ERTS_SMP)
- volatile int interrupt;
-#else
- erts_smp_atomic_t interrupt;
+#ifdef ERTS_SMP
+ erts_atomic32_t wakeup_state;
+#elif ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
+ volatile int wakeup_state;
#endif
- erts_smp_atomic_t timeout;
+ erts_smp_atomic32_t timeout;
#ifdef ERTS_POLL_COUNT_AVOIDED_WAKEUPS
erts_smp_atomic_t no_avoided_wakeups;
erts_smp_atomic_t no_avoided_interrupts;
@@ -346,34 +282,6 @@ struct ErtsPollSet_ {
#endif
};
-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... */
- 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
-
void erts_silence_warn_unused_result(long unused);
static void fatal_error(char *format, ...);
static void fatal_error_async_signal_safe(char *error_str);
@@ -430,6 +338,63 @@ static void check_poll_status(ErtsPollSet ps);
static void print_misc_debug_info(void);
#endif
+#define ERTS_POLL_NOT_WOKEN 0
+#define ERTS_POLL_WOKEN -1
+#define ERTS_POLL_WOKEN_INTR 1
+
+static ERTS_INLINE void
+reset_wakeup_state(ErtsPollSet ps)
+{
+#ifdef ERTS_SMP
+ erts_atomic32_set(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN);
+#elif ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
+ ps->wakeup_state = 0;
+#endif
+}
+
+static ERTS_INLINE int
+is_woken(ErtsPollSet ps)
+{
+#ifdef ERTS_SMP
+ return erts_atomic32_read_acqb(&ps->wakeup_state) != ERTS_POLL_NOT_WOKEN;
+#elif ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
+ return ps->wakeup_state != ERTS_POLL_NOT_WOKEN;
+#else
+ return 0;
+#endif
+}
+
+static ERTS_INLINE int
+is_interrupted_reset(ErtsPollSet ps)
+{
+#ifdef ERTS_SMP
+ return (erts_atomic32_xchg(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN)
+ == ERTS_POLL_WOKEN_INTR);
+#elif ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
+ int res = ps->wakeup_state == ERTS_POLL_WOKEN_INTR;
+ ps->wakeup_state = ERTS_POLL_NOT_WOKEN;
+ return res;
+#else
+ return 0;
+#endif
+}
+
+static ERTS_INLINE void
+woke_up(ErtsPollSet ps)
+{
+#ifdef ERTS_SMP
+ erts_aint32_t wakeup_state = erts_atomic32_read(&ps->wakeup_state);
+ if (wakeup_state == ERTS_POLL_NOT_WOKEN)
+ (void) erts_atomic32_cmpxchg(&ps->wakeup_state,
+ ERTS_POLL_WOKEN,
+ ERTS_POLL_NOT_WOKEN);
+ ASSERT(erts_atomic32_read(&ps->wakeup_state) != ERTS_POLL_NOT_WOKEN);
+#elif ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
+ if (ps->wakeup_state == ERTS_POLL_NOT_WOKEN)
+ ps->wakeup_state = ERTS_POLL_WOKEN;
+#endif
+}
+
/*
* --- Wakeup pipe -----------------------------------------------------------
*/
@@ -437,14 +402,34 @@ static void print_misc_debug_info(void);
#if ERTS_POLL_USE_WAKEUP_PIPE
static ERTS_INLINE void
-wake_poller(ErtsPollSet ps)
+wake_poller(ErtsPollSet ps, int interrupted)
{
+ int wake;
+#ifdef ERTS_SMP
+ erts_aint32_t wakeup_state;
+ if (!interrupted)
+ wakeup_state = erts_atomic32_cmpxchg_relb(&ps->wakeup_state,
+ ERTS_POLL_WOKEN,
+ ERTS_POLL_NOT_WOKEN);
+ else {
+ /*
+ * We might unnecessarily write to the pipe, however,
+ * that isn't problematic.
+ */
+ wakeup_state = erts_atomic32_read(&ps->wakeup_state);
+ erts_atomic32_set_relb(&ps->wakeup_state, ERTS_POLL_WOKEN_INTR);
+ }
+ wake = wakeup_state == ERTS_POLL_NOT_WOKEN;
+#elif ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
+ wake = ps->wakeup_state == ERTS_POLL_NOT_WOKEN;
+ ps->wakeup_state = interrupted ? ERTS_POLL_WOKEN_INTR : ERTS_POLL_NOT_WOKEN;
+#endif
/*
* NOTE: This function might be called from signal handlers in the
* non-smp case; therefore, it has to be async-signal safe in
* the non-smp case.
*/
- if (!ERTS_POLLSET_SET_POLLER_WOKEN_CHK(ps)) {
+ if (wake) {
ssize_t res;
if (ps->wake_fds[1] < 0)
return; /* Not initialized yet */
@@ -1387,9 +1372,7 @@ handle_update_requests(ErtsPollSet ps)
#endif /* ERTS_POLL_USE_UPDATE_REQUESTS_QUEUE */
static ERTS_INLINE ErtsPollEvents
-poll_control(ErtsPollSet ps, int fd, ErtsPollEvents events, int on,
- int *have_set_have_update_requests,
- int *do_wake)
+poll_control(ErtsPollSet ps, int fd, ErtsPollEvents events, int on, int *do_wake)
{
ErtsPollEvents new_events;
@@ -1493,7 +1476,6 @@ ERTS_POLL_EXPORT(erts_poll_controlv)(ErtsPollSet ps,
int len)
{
int i;
- int hshur = 0;
int do_wake;
int final_do_wake = 0;
@@ -1505,17 +1487,17 @@ ERTS_POLL_EXPORT(erts_poll_controlv)(ErtsPollSet ps,
pcev[i].fd,
pcev[i].events,
pcev[i].on,
- &hshur,
&do_wake);
final_do_wake |= do_wake;
}
+ ERTS_POLLSET_UNLOCK(ps);
+
#ifdef ERTS_SMP
if (final_do_wake)
- wake_poller(ps);
+ wake_poller(ps, 0);
#endif /* ERTS_SMP */
- ERTS_POLLSET_UNLOCK(ps);
}
ErtsPollEvents
@@ -1526,20 +1508,20 @@ ERTS_POLL_EXPORT(erts_poll_control)(ErtsPollSet ps,
int* do_wake) /* In: Wake up polling thread */
/* Out: Poller is woken */
{
- int hshur = 0;
ErtsPollEvents res;
ERTS_POLLSET_LOCK(ps);
- res = poll_control(ps, fd, events, on, &hshur, do_wake);
+ res = poll_control(ps, fd, events, on, do_wake);
+
+ ERTS_POLLSET_UNLOCK(ps);
#ifdef ERTS_SMP
if (*do_wake) {
- wake_poller(ps);
+ wake_poller(ps, 0);
}
#endif /* ERTS_SMP */
- ERTS_POLLSET_UNLOCK(ps);
return res;
}
@@ -1919,8 +1901,10 @@ check_fd_events(ErtsPollSet ps, SysTimeval *tv, int max_res, int *ps_locked)
}
else {
long timeout = tv->tv_sec*1000 + tv->tv_usec/1000;
+ if (timeout > ERTS_AINT32_T_MAX)
+ timeout = ERTS_AINT32_T_MAX;
ASSERT(timeout >= 0);
- erts_smp_atomic_set(&ps->timeout, timeout);
+ erts_smp_atomic32_set_relb(&ps->timeout, (erts_aint32_t) timeout);
#if ERTS_POLL_USE_FALLBACK
if (!(ps->fallback_used = ERTS_POLL_NEED_FALLBACK(ps))) {
@@ -2042,15 +2026,14 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
(int) tv->tv_sec*1000 + tv->tv_usec/1000);
#endif
- ERTS_POLLSET_UNSET_POLLER_WOKEN(ps);
if (ERTS_POLLSET_SET_POLLED_CHK(ps)) {
res = EINVAL; /* Another thread is in erts_poll_wait()
on this pollset... */
goto done;
}
- if (ERTS_POLLSET_IS_INTERRUPTED(ps)) {
- /* Interrupt use zero timeout */
+ if (is_woken(ps)) {
+ /* Use zero timeout */
itv.tv_sec = 0;
itv.tv_usec = 0;
tvp = &itv;
@@ -2067,7 +2050,7 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
ps_locked = 0;
res = check_fd_events(ps, tvp, no_fds, &ps_locked);
- ERTS_POLLSET_SET_POLLER_WOKEN(ps);
+ woke_up(ps);
if (res == 0) {
res = ETIMEDOUT;
@@ -2099,9 +2082,7 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
check_poll_result(pr, no_fds);
#endif
- res = (no_fds == 0
- ? (ERTS_POLLSET_UNSET_INTERRUPTED_CHK(ps) ? EINTR : EAGAIN)
- : 0);
+ res = (no_fds == 0 ? (is_interrupted_reset(ps) ? EINTR : EAGAIN) : 0);
*len = no_fds;
}
@@ -2112,7 +2093,7 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
#endif
done:
- erts_smp_atomic_set(&ps->timeout, LONG_MAX);
+ erts_smp_atomic32_set_relb(&ps->timeout, ERTS_AINT32_T_MAX);
#ifdef ERTS_POLL_DEBUG_PRINT
erts_printf("Leaving %s = erts_poll_wait()\n",
res == 0 ? "0" : erl_errno_id(res));
@@ -2128,20 +2109,17 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet ps,
void
ERTS_POLL_EXPORT(erts_poll_interrupt)(ErtsPollSet ps, int set)
{
+#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT || defined(ERTS_SMP)
/*
* NOTE: This function might be called from signal handlers in the
* non-smp case; therefore, it has to be async-signal safe in
* the non-smp case.
*/
- if (set) {
- ERTS_POLLSET_SET_INTERRUPTED(ps);
-#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT || defined(ERTS_SMP)
- wake_poller(ps);
+ if (!set)
+ reset_wakeup_state(ps);
+ else
+ wake_poller(ps, 1);
#endif
- }
- else {
- ERTS_POLLSET_UNSET_INTERRUPTED(ps);
- }
}
/*
@@ -2150,15 +2128,16 @@ ERTS_POLL_EXPORT(erts_poll_interrupt)(ErtsPollSet ps, int set)
* is not guaranteed that it will timeout before 'msec' milli seconds.
*/
void
-ERTS_POLL_EXPORT(erts_poll_interrupt_timed)(ErtsPollSet ps, int set, long msec)
+ERTS_POLL_EXPORT(erts_poll_interrupt_timed)(ErtsPollSet ps,
+ int set,
+ long msec)
{
- if (set) {
- if (erts_smp_atomic_read(&ps->timeout) > msec) {
- ERTS_POLLSET_SET_INTERRUPTED(ps);
#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT || defined(ERTS_SMP)
- wake_poller(ps);
-#endif
- }
+ if (!set)
+ reset_wakeup_state(ps);
+ else {
+ if (erts_smp_atomic32_read_acqb(&ps->timeout) > (erts_aint32_t) msec)
+ wake_poller(ps, 1);
#ifdef ERTS_POLL_COUNT_AVOIDED_WAKEUPS
else {
if (ERTS_POLLSET_IS_POLLED(ps))
@@ -2168,9 +2147,7 @@ ERTS_POLL_EXPORT(erts_poll_interrupt_timed)(ErtsPollSet ps, int set, long msec)
erts_smp_atomic_inc(&ps->no_interrupt_timed);
#endif
}
- else {
- ERTS_POLLSET_UNSET_INTERRUPTED(ps);
- }
+#endif
}
int
@@ -2281,14 +2258,16 @@ ERTS_POLL_EXPORT(erts_poll_create_pollset)(void)
ps->update_requests.next = NULL;
ps->update_requests.len = 0;
ps->curr_upd_req_block = &ps->update_requests;
- erts_smp_atomic_init(&ps->have_update_requests, 0);
+ erts_smp_atomic32_init(&ps->have_update_requests, 0);
#endif
#ifdef ERTS_SMP
- erts_smp_atomic_init(&ps->polled, 0);
- erts_smp_atomic_init(&ps->woken, 0);
+ erts_atomic32_init(&ps->polled, 0);
erts_smp_mtx_init(&ps->mtx, "pollset");
+#endif
+#ifdef ERTS_SMP
+ erts_atomic32_init(&ps->wakeup_state, (erts_aint32_t) 0);
#elif ERTS_POLL_ASYNC_INTERRUPT_SUPPORT
- ps->woken = 0;
+ ps->wakeup_state = 0;
#endif
#if ERTS_POLL_USE_WAKEUP_PIPE
create_wakeup_pipe(ps);
@@ -2310,12 +2289,7 @@ ERTS_POLL_EXPORT(erts_poll_create_pollset)(void)
ps->internal_fd_limit = kp_fd + 1;
ps->kp_fd = kp_fd;
#endif
-#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT && !defined(ERTS_SMP)
- ps->interrupt = 0;
-#else
- erts_smp_atomic_init(&ps->interrupt, 0);
-#endif
- erts_smp_atomic_init(&ps->timeout, LONG_MAX);
+ erts_smp_atomic32_init(&ps->timeout, ERTS_AINT32_T_MAX);
#ifdef ERTS_POLL_COUNT_AVOIDED_WAKEUPS
erts_smp_atomic_init(&ps->no_avoided_wakeups, 0);
erts_smp_atomic_init(&ps->no_avoided_interrupts, 0);
diff --git a/erts/emulator/sys/common/erl_sys_common_misc.c b/erts/emulator/sys/common/erl_sys_common_misc.c
new file mode 100644
index 0000000000..461e763f03
--- /dev/null
+++ b/erts/emulator/sys/common/erl_sys_common_misc.c
@@ -0,0 +1,107 @@
+/*
+ * %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%
+ */
+
+
+
+/*
+ * Darwin needs conversion!
+ * http://developer.apple.com/library/mac/#qa/qa2001/qa1235.html
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "sys.h"
+#include "global.h"
+
+#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
+#define __DARWIN__ 1
+#endif
+
+#if !defined(__WIN32__)
+#include <locale.h>
+#if !defined(HAVE_SETLOCALE) || !defined(HAVE_NL_LANGINFO) || !defined(HAVE_LANGINFO_H)
+#define PRIMITIVE_UTF8_CHECK 1
+#else
+#include <langinfo.h>
+#endif
+#endif
+
+/* Written once and only once */
+
+static int filename_encoding = ERL_FILENAME_UNKNOWN;
+#if defined(__WIN32__) || defined(__DARWIN__)
+static int user_filename_encoding = ERL_FILENAME_UTF8; /* Default unicode on windows */
+#else
+static int user_filename_encoding = ERL_FILENAME_LATIN1;
+#endif
+void erts_set_user_requested_filename_encoding(int encoding)
+{
+ user_filename_encoding = encoding;
+}
+
+int erts_get_user_requested_filename_encoding(void)
+{
+ return user_filename_encoding;
+}
+
+void erts_init_sys_common_misc(void)
+{
+#if defined(__WIN32__)
+ /* win_efile will totally fail if this is not set. */
+ filename_encoding = ERL_FILENAME_WIN_WCHAR;
+#else
+ if (user_filename_encoding != ERL_FILENAME_UNKNOWN) {
+ filename_encoding = user_filename_encoding;
+ } else {
+ char *l;
+ filename_encoding = ERL_FILENAME_LATIN1;
+# ifdef PRIMITIVE_UTF8_CHECK
+ setlocale(LC_CTYPE, ""); /* Set international environment,
+ ignore result */
+ if (((l = getenv("LC_ALL")) && *l) ||
+ ((l = getenv("LC_CTYPE")) && *l) ||
+ ((l = getenv("LANG")) && *l)) {
+ if (strstr(l, "UTF-8")) {
+ filename_encoding = ERL_FILENAME_UTF8;
+ }
+ }
+
+# else
+ l = setlocale(LC_CTYPE, ""); /* Set international environment */
+ if (l != NULL) {
+ if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
+ filename_encoding = ERL_FILENAME_UTF8;
+ }
+ }
+# endif
+ }
+# if defined(__DARWIN__)
+ if (filename_encoding == ERL_FILENAME_UTF8) {
+ filename_encoding = ERL_FILENAME_UTF8_MAC;
+ }
+# endif
+#endif
+}
+
+int erts_get_native_filename_encoding(void)
+{
+ return filename_encoding;
+}
diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h
index 2d5ef882f6..824678a0bb 100644
--- a/erts/emulator/sys/unix/erl_unix_sys.h
+++ b/erts/emulator/sys/unix/erl_unix_sys.h
@@ -329,11 +329,4 @@ extern int exit_async(void);
#define ERTS_EXIT_AFTER_DUMP _exit
-#ifdef ERTS_TIMER_THREAD
-struct erts_iwait; /* opaque for clients */
-extern struct erts_iwait *erts_iwait_init(void);
-extern void erts_iwait_wait(struct erts_iwait *iwait, struct timeval *delay);
-extern void erts_iwait_interrupt(struct erts_iwait *iwait);
-#endif /* ERTS_TIMER_THREAD */
-
#endif /* #ifndef _ERL_UNIX_SYS_H */
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index af4ab693dc..bafbbb0f6c 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -53,6 +53,11 @@
#define WANT_NONBLOCKING /* must define this to pull in defs from sys.h */
#include "sys.h"
+#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
+#define __DARWIN__ 1
+#endif
+
+
#ifdef USE_THREADS
#include "erl_threads.h"
#endif
@@ -75,6 +80,7 @@ static erts_smp_rwmtx_t environ_rwmtx;
#include "erl_sys_driver.h"
#include "erl_check_io.h"
+#include "erl_cpu_topology.h"
#ifndef DISABLE_VFORK
#define DISABLE_VFORK 0
@@ -159,14 +165,14 @@ static int debug_log = 0;
#endif
#ifdef ERTS_SMP
-erts_smp_atomic_t erts_got_sigusr1;
+erts_smp_atomic32_t erts_got_sigusr1;
#define ERTS_SET_GOT_SIGUSR1 \
- erts_smp_atomic_set(&erts_got_sigusr1, 1)
+ erts_smp_atomic32_set(&erts_got_sigusr1, 1)
#define ERTS_UNSET_GOT_SIGUSR1 \
- erts_smp_atomic_set(&erts_got_sigusr1, 0)
-static erts_smp_atomic_t have_prepared_crash_dump;
+ erts_smp_atomic32_set(&erts_got_sigusr1, 0)
+static erts_smp_atomic32_t have_prepared_crash_dump;
#define ERTS_PREPARED_CRASH_DUMP \
- ((int) erts_smp_atomic_xchg(&have_prepared_crash_dump, 1))
+ ((int) erts_smp_atomic32_xchg(&have_prepared_crash_dump, 1))
#else
volatile int erts_got_sigusr1;
#define ERTS_SET_GOT_SIGUSR1 (erts_got_sigusr1 = 1)
@@ -234,11 +240,11 @@ static int max_files = -1;
* a few variables used by the break handler
*/
#ifdef ERTS_SMP
-erts_smp_atomic_t erts_break_requested;
+erts_smp_atomic32_t erts_break_requested;
#define ERTS_SET_BREAK_REQUESTED \
- erts_smp_atomic_set(&erts_break_requested, (long) 1)
+ erts_smp_atomic32_set(&erts_break_requested, (erts_aint32_t) 1)
#define ERTS_UNSET_BREAK_REQUESTED \
- erts_smp_atomic_set(&erts_break_requested, (long) 0)
+ erts_smp_atomic32_set(&erts_break_requested, (erts_aint32_t) 0)
#else
volatile int erts_break_requested = 0;
#define ERTS_SET_BREAK_REQUESTED (erts_break_requested = 1)
@@ -399,7 +405,7 @@ typedef struct {
#ifdef ERTS_THR_HAVE_SIG_FUNCS
sigset_t saved_sigmask;
#endif
- int unbind_child;
+ int sched_bind_data;
} erts_thr_create_data_t;
/*
@@ -410,15 +416,13 @@ static void *
thr_create_prepare(void)
{
erts_thr_create_data_t *tcdp;
- ErtsSchedulerData *esdp;
tcdp = erts_alloc(ERTS_ALC_T_TMP, sizeof(erts_thr_create_data_t));
#ifdef ERTS_THR_HAVE_SIG_FUNCS
erts_thr_sigmask(SIG_BLOCK, &thr_create_sigmask, &tcdp->saved_sigmask);
#endif
- esdp = erts_get_scheduler_data();
- tcdp->unbind_child = esdp && erts_is_scheduler_bound(esdp);
+ tcdp->sched_bind_data = erts_sched_bind_atthrcreate_prepare();
return (void *) tcdp;
}
@@ -430,6 +434,8 @@ thr_create_cleanup(void *vtcdp)
{
erts_thr_create_data_t *tcdp = (erts_thr_create_data_t *) vtcdp;
+ erts_sched_bind_atthrcreate_parent(tcdp->sched_bind_data);
+
#ifdef ERTS_THR_HAVE_SIG_FUNCS
/* Restore signalmask... */
erts_thr_sigmask(SIG_SETMASK, &tcdp->saved_sigmask, NULL);
@@ -456,12 +462,7 @@ thr_create_prepare_child(void *vtcdp)
erts_thread_disable_fpe();
#endif
- if (tcdp->unbind_child) {
- erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx);
- erts_unbind_from_cpu(erts_cpuinfo);
- erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx);
- }
-
+ erts_sched_bind_atthrcreate_child(tcdp->sched_bind_data);
}
#endif /* #ifdef USE_THREADS */
@@ -508,9 +509,9 @@ erts_sys_pre_init(void)
#endif
}
#ifdef ERTS_SMP
- erts_smp_atomic_init(&erts_break_requested, 0);
- erts_smp_atomic_init(&erts_got_sigusr1, 0);
- erts_smp_atomic_init(&have_prepared_crash_dump, 0);
+ erts_smp_atomic32_init(&erts_break_requested, 0);
+ erts_smp_atomic32_init(&erts_got_sigusr1, 0);
+ erts_smp_atomic32_init(&have_prepared_crash_dump, 0);
#else
erts_break_requested = 0;
erts_got_sigusr1 = 0;
@@ -1461,9 +1462,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op
CHLD_STAT_LOCK;
- unbind = erts_is_scheduler_bound(NULL);
- if (unbind)
- erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx);
+ unbind = erts_sched_bind_atfork_prepare();
#if !DISABLE_VFORK
/* See fork/vfork discussion before this function. */
@@ -1476,7 +1475,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op
if (pid == 0) {
/* The child! Setup child... */
- if (unbind && erts_unbind_from_cpu(erts_cpuinfo) != 0)
+ if (erts_sched_bind_atfork_child(unbind) != 0)
goto child_error;
/* OBSERVE!
@@ -1577,8 +1576,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op
cs_argv[CS_ARGV_PROGNAME_IX] = child_setup_prog;
cs_argv[CS_ARGV_WD_IX] = opts->wd ? opts->wd : ".";
- cs_argv[CS_ARGV_UNBIND_IX]
- = (unbind ? erts_get_unbind_from_cpu_str(erts_cpuinfo) : "false");
+ cs_argv[CS_ARGV_UNBIND_IX] = erts_sched_bind_atvfork_child(unbind);
cs_argv[CS_ARGV_FD_CR_IX] = fd_close_range;
for (i = 0; i < CS_ARGV_NO_OF_DUP2_OPS; i++)
cs_argv[CS_ARGV_DUP2_OP_IX(i)] = &dup2_op[i][0];
@@ -1627,8 +1625,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op
}
#endif
- if (unbind)
- erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx);
+ erts_sched_bind_atfork_parent(unbind);
if (pid == -1) {
saved_errno = errno;
@@ -2997,11 +2994,27 @@ init_smp_sig_notify(void)
NULL,
&thr_opts);
}
+#ifdef __DARWIN__
+
+int erts_darwin_main_thread_pipe[2];
+int erts_darwin_main_thread_result_pipe[2];
+static void initialize_darwin_main_thread_pipes(void)
+{
+ if (pipe(erts_darwin_main_thread_pipe) < 0 ||
+ pipe(erts_darwin_main_thread_result_pipe) < 0) {
+ erl_exit(1,"Fatal error initializing Darwin main thread stealing");
+ }
+}
+
+#endif
void
erts_sys_main_thread(void)
{
erts_thread_disable_fpe();
+#ifdef __DARWIN__
+ initialize_darwin_main_thread_pipes();
+#endif
/* Become signal receiver thread... */
#ifdef ERTS_ENABLE_LOCK_CHECK
erts_lc_set_thread_name("signal_receiver");
@@ -3010,6 +3023,27 @@ erts_sys_main_thread(void)
smp_sig_notify(0); /* Notify initialized */
while (1) {
/* Wait for a signal to arrive... */
+#ifdef __DARWIN__
+ /*
+ * The wx driver needs to be able to steal the main thread for Cocoa to
+ * work properly.
+ */
+ fd_set readfds;
+ int res;
+
+ FD_ZERO(&readfds);
+ FD_SET(erts_darwin_main_thread_pipe[0], &readfds);
+ res = select(erts_darwin_main_thread_pipe[0] + 1, &readfds, NULL, NULL, NULL);
+ if (res > 0 && FD_ISSET(erts_darwin_main_thread_pipe[0],&readfds)) {
+ void* (*func)(void*);
+ void* arg;
+ void *resp;
+ read(erts_darwin_main_thread_pipe[0],&func,sizeof(void* (*)(void*)));
+ read(erts_darwin_main_thread_pipe[0],&arg, sizeof(void*));
+ resp = (*func)(arg);
+ write(erts_darwin_main_thread_result_pipe[1],&resp,sizeof(void *));
+ }
+#else
#ifdef DEBUG
int res =
#else
@@ -3018,6 +3052,7 @@ erts_sys_main_thread(void)
select(0, NULL, NULL, NULL, NULL);
ASSERT(res < 0);
ASSERT(errno == EINTR);
+#endif
}
}
@@ -3117,226 +3152,3 @@ erl_sys_args(int* argc, char** argv)
}
*argc = j;
}
-
-#ifdef ERTS_TIMER_THREAD
-
-/*
- * Interruptible-wait facility: low-level synchronisation state
- * and methods that are implementation dependent.
- *
- * Constraint: Every implementation must define 'struct erts_iwait'
- * with a field 'erts_smp_atomic_t state;'.
- */
-
-/* values for struct erts_iwait's state field */
-#define IWAIT_WAITING 0
-#define IWAIT_AWAKE 1
-#define IWAIT_INTERRUPT 2
-
-#if 0 /* XXX: needs feature test in erts/configure.in */
-
-/*
- * This is an implementation of the interruptible wait facility on
- * top of Linux-specific futexes.
- */
-#include <asm/unistd.h>
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-static int sys_futex(void *futex, int op, int val, const struct timespec *timeout)
-{
- return syscall(__NR_futex, futex, op, val, timeout);
-}
-
-struct erts_iwait {
- erts_smp_atomic_t state; /* &state.counter is our futex */
-};
-
-static void iwait_lowlevel_init(struct erts_iwait *iwait) { /* empty */ }
-
-static void iwait_lowlevel_wait(struct erts_iwait *iwait, struct timeval *delay)
-{
- struct timespec timeout;
- int res;
-
- timeout.tv_sec = delay->tv_sec;
- timeout.tv_nsec = delay->tv_usec * 1000;
- res = sys_futex((void*)&iwait->state.counter, FUTEX_WAIT, IWAIT_WAITING, &timeout);
- if (res < 0 && errno != ETIMEDOUT && errno != EWOULDBLOCK && errno != EINTR)
- perror("FUTEX_WAIT");
-}
-
-static void iwait_lowlevel_interrupt(struct erts_iwait *iwait)
-{
- int res = sys_futex((void*)&iwait->state.counter, FUTEX_WAKE, 1, NULL);
- if (res < 0)
- perror("FUTEX_WAKE");
-}
-
-#else /* using poll() or select() */
-
-/*
- * This is an implementation of the interruptible wait facility on
- * top of pipe(), poll() or select(), read(), and write().
- */
-struct erts_iwait {
- erts_smp_atomic_t state;
- int read_fd; /* wait polls and reads this fd */
- int write_fd; /* interrupt writes this fd */
-};
-
-static void iwait_lowlevel_init(struct erts_iwait *iwait)
-{
- int fds[2];
-
- if (pipe(fds) < 0) {
- perror("pipe()");
- exit(1);
- }
- iwait->read_fd = fds[0];
- iwait->write_fd = fds[1];
-}
-
-#if defined(ERTS_USE_POLL)
-
-#include <sys/poll.h>
-#define PERROR_POLL "poll()"
-
-static int iwait_lowlevel_poll(int read_fd, struct timeval *delay)
-{
- struct pollfd pollfd;
- int timeout;
-
- pollfd.fd = read_fd;
- pollfd.events = POLLIN;
- pollfd.revents = 0;
- timeout = delay->tv_sec * 1000 + delay->tv_usec / 1000;
- return poll(&pollfd, 1, timeout);
-}
-
-#else /* !ERTS_USE_POLL */
-
-#include <sys/select.h>
-#define PERROR_POLL "select()"
-
-static int iwait_lowlevel_poll(int read_fd, struct timeval *delay)
-{
- fd_set readfds;
-
- FD_ZERO(&readfds);
- FD_SET(read_fd, &readfds);
- return select(read_fd + 1, &readfds, NULL, NULL, delay);
-}
-
-#endif /* !ERTS_USE_POLL */
-
-static void iwait_lowlevel_wait(struct erts_iwait *iwait, struct timeval *delay)
-{
- int res;
- char buf[64];
-
- res = iwait_lowlevel_poll(iwait->read_fd, delay);
- if (res > 0)
- (void)read(iwait->read_fd, buf, sizeof buf);
- else if (res < 0 && errno != EINTR)
- perror(PERROR_POLL);
-}
-
-static void iwait_lowlevel_interrupt(struct erts_iwait *iwait)
-{
- int res = write(iwait->write_fd, "!", 1);
- if (res < 0)
- perror("write()");
-}
-
-#endif /* using poll() or select() */
-
-#if 0 /* not using poll() or select() */
-/*
- * This is an implementation of the interruptible wait facility on
- * top of pthread_cond_timedwait(). This has two problems:
- * 1. pthread_cond_timedwait() requires an absolute time point,
- * so the relative delay must be converted to absolute time.
- * Worse, this breaks if the machine's time is adjusted while
- * we're preparing to wait.
- * 2. Each cond operation requires additional mutex lock/unlock operations.
- *
- * Problem 2 is probably not too bad on Linux (they'll just become
- * relatively cheap futex operations), but problem 1 is the real killer.
- * Only use this implementation if no better alternatives are available!
- */
-struct erts_iwait {
- erts_smp_atomic_t state;
- pthread_cond_t cond;
- pthread_mutex_t mutex;
-};
-
-static void iwait_lowlevel_init(struct erts_iwait *iwait)
-{
- iwait->cond = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
- iwait->mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
-}
-
-static void iwait_lowlevel_wait(struct erts_iwait *iwait, struct timeval *delay)
-{
- struct timeval tmp;
- struct timespec timeout;
-
- /* Due to pthread_cond_timedwait()'s use of absolute
- time, this must be the real gettimeofday(), _not_
- the "smoothed" one beam/erl_time_sup.c implements. */
- gettimeofday(&tmp, NULL);
-
- tmp.tv_sec += delay->tv_sec;
- tmp.tv_usec += delay->tv_usec;
- if (tmp.tv_usec >= 1000*1000) {
- tmp.tv_usec -= 1000*1000;
- tmp.tv_sec += 1;
- }
- timeout.tv_sec = tmp.tv_sec;
- timeout.tv_nsec = tmp.tv_usec * 1000;
- pthread_mutex_lock(&iwait->mutex);
- pthread_cond_timedwait(&iwait->cond, &iwait->mutex, &timeout);
- pthread_mutex_unlock(&iwait->mutex);
-}
-
-static void iwait_lowlevel_interrupt(struct erts_iwait *iwait)
-{
- pthread_mutex_lock(&iwait->mutex);
- pthread_cond_signal(&iwait->cond);
- pthread_mutex_unlock(&iwait->mutex);
-}
-
-#endif /* not using POLL */
-
-/*
- * Interruptible-wait facility. This is just a wrapper around the
- * low-level synchronisation code, where we maintain our logical
- * state in order to suppress some state transitions.
- */
-
-struct erts_iwait *erts_iwait_init(void)
-{
- struct erts_iwait *iwait = malloc(sizeof *iwait);
- if (!iwait) {
- perror("malloc");
- exit(1);
- }
- iwait_lowlevel_init(iwait);
- erts_smp_atomic_init(&iwait->state, IWAIT_AWAKE);
- return iwait;
-}
-
-void erts_iwait_wait(struct erts_iwait *iwait, struct timeval *delay)
-{
- if (erts_smp_atomic_xchg(&iwait->state, IWAIT_WAITING) != IWAIT_INTERRUPT)
- iwait_lowlevel_wait(iwait, delay);
- erts_smp_atomic_set(&iwait->state, IWAIT_AWAKE);
-}
-
-void erts_iwait_interrupt(struct erts_iwait *iwait)
-{
- if (erts_smp_atomic_xchg(&iwait->state, IWAIT_INTERRUPT) == IWAIT_WAITING)
- iwait_lowlevel_interrupt(iwait);
-}
-
-#endif /* ERTS_TIMER_THREAD */
diff --git a/erts/emulator/sys/unix/sys_float.c b/erts/emulator/sys/unix/sys_float.c
index 6e9376b0f3..8ec7b31ce0 100644
--- a/erts/emulator/sys/unix/sys_float.c
+++ b/erts/emulator/sys/unix/sys_float.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -36,11 +36,6 @@ erts_sys_init_float(void)
# endif
}
-static ERTS_INLINE void set_current_fp_exception(unsigned long pc)
-{
- /* nothing to do */
-}
-
#else /* !NO_FPE_SIGNALS */
#ifdef ERTS_SMP
diff --git a/erts/emulator/sys/vxworks/sys.c b/erts/emulator/sys/vxworks/sys.c
index 411b4b37cf..c6e7b65f32 100644
--- a/erts/emulator/sys/vxworks/sys.c
+++ b/erts/emulator/sys/vxworks/sys.c
@@ -85,7 +85,7 @@ EXTERN_FUNCTION(void, erl_exit, (int n, char*, _DOTS_));
EXTERN_FUNCTION(void, erl_error, (char*, va_list));
EXTERN_FUNCTION(int, driver_interrupt, (int, int));
EXTERN_FUNCTION(void, increment_time, (int));
-EXTERN_FUNCTION(int, next_time, (_VOID_));
+EXTERN_FUNCTION(int, erts_next_time, (_VOID_));
EXTERN_FUNCTION(void, set_reclaim_free_function, (FreeFunction));
EXTERN_FUNCTION(int, erl_mem_info_get, (MEM_PART_STATS *));
EXTERN_FUNCTION(void, erl_crash_dump, (char* file, int line, char* fmt, ...));
diff --git a/erts/emulator/sys/win32/erl_poll.c b/erts/emulator/sys/win32/erl_poll.c
index a766fe9575..1f2877b682 100644
--- a/erts/emulator/sys/win32/erl_poll.c
+++ b/erts/emulator/sys/win32/erl_poll.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2007-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2007-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -274,7 +274,6 @@ struct ErtsPollSet_ {
Waiter** waiter;
int allocated_waiters; /* Size ow waiter array */
int num_waiters; /* Number of waiter threads. */
- erts_atomic_t sys_io_ready; /* Tells us there is I/O ready (already). */
int restore_events; /* Tells us to restore waiters events
next time around */
HANDLE event_io_ready; /* To be used when waiting for io */
@@ -282,12 +281,11 @@ struct ErtsPollSet_ {
volatile int standby_wait_counter; /* Number of threads to wait for */
CRITICAL_SECTION standby_crit; /* CS to guard the counter */
HANDLE standby_wait_event; /* Event signalled when counte == 0 */
+ erts_atomic32_t wakeup_state;
#ifdef ERTS_SMP
- erts_smp_atomic_t woken;
erts_smp_mtx_t mtx;
- erts_smp_atomic_t interrupt;
#endif
- erts_smp_atomic_t timeout;
+ erts_smp_atomic32_t timeout;
};
#ifdef ERTS_SMP
@@ -296,126 +294,24 @@ struct ErtsPollSet_ {
erts_smp_mtx_lock(&(PS)->mtx)
#define ERTS_POLLSET_UNLOCK(PS) \
erts_smp_mtx_unlock(&(PS)->mtx)
-#define ERTS_POLLSET_SET_POLLED_CHK(PS) \
- ((int) erts_smp_atomic_xchg(&(PS)->polled, (long) 1))
-#define ERTS_POLLSET_SET_POLLED(PS) \
- erts_smp_atomic_set(&(PS)->polled, (long) 1)
-#define ERTS_POLLSET_UNSET_POLLED(PS) \
- 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) 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) 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)
#define ERTS_POLLSET_UNLOCK(PS)
-#define ERTS_POLLSET_SET_POLLED_CHK(PS) 0
-#define ERTS_POLLSET_UNSET_POLLED(PS)
-#define ERTS_POLLSET_IS_POLLED(PS) 0
-#define ERTS_POLLSET_SET_POLLER_WOKEN_CHK(PS) 1
-#define ERTS_POLLSET_SET_POLLER_WOKEN(PS)
-#define ERTS_POLLSET_UNSET_POLLER_WOKEN(PS)
-#define ERTS_POLLSET_IS_POLLER_WOKEN(PS) 1
-
#endif
/*
- * While atomics are not yet implemented for windows in the common library...
- *
- * MSDN doc states that SMP machines and old compilers require
- * InterLockedExchange to properly read and write interlocked
- * variables, otherwise the processors might reschedule
- * the access and order of atomics access is destroyed...
- * While they only mention it in white-papers, the problem
- * in VS2003 is due to the IA64 arch, so we can still count
- * on the CPU not rescheduling the access to volatile in X86 arch using
- * even the slightly older compiler...
- *
- * So here's (hopefully) a subset of the generally working atomic
- * variable access...
- */
-
-#if defined(__GNUC__)
-# if defined(__i386__) || defined(__x86_64__)
-# define VOLATILE_IN_SEQUENCE 1
-# else
-# define VOLATILE_IN_SEQUENCE 0
-# endif
-#elif defined(_MSC_VER)
-# if _MSC_VER < 1300
-# define VOLATILE_IN_SEQUENCE 0 /* Dont trust really old compilers */
-# else
-# if defined(_M_IX86)
-# define VOLATILE_IN_SEQUENCE 1
-# else /* I.e. IA64 */
-# if _MSC_VER >= 1400
-# define VOLATILE_IN_SEQUENCE 1
-# else
-# define VOLATILE_IN_SEQUENCE 0
-# endif
-# endif
-# endif
-#else
-# define VOLATILE_IN_SEQUENCE 0
-#endif
-
-
-
-/*
* Communication with sys_interrupt
*/
#ifdef ERTS_SMP
-extern erts_smp_atomic_t erts_break_requested;
+extern erts_smp_atomic32_t erts_break_requested;
#define ERTS_SET_BREAK_REQUESTED \
- erts_smp_atomic_set(&erts_break_requested, (long) 1)
+ erts_smp_atomic32_set(&erts_break_requested, (erts_aint32_t) 1)
#define ERTS_UNSET_BREAK_REQUESTED \
- erts_smp_atomic_set(&erts_break_requested, (long) 0)
+ erts_smp_atomic32_set(&erts_break_requested, (erts_aint32_t) 0)
#else
extern volatile int erts_break_requested;
#define ERTS_SET_BREAK_REQUESTED (erts_break_requested = 1)
@@ -424,7 +320,7 @@ extern volatile int erts_break_requested;
static erts_mtx_t break_waiter_lock;
static HANDLE break_happened_event;
-static erts_atomic_t break_waiter_state;
+static erts_atomic32_t break_waiter_state;
#define BREAK_WAITER_GOT_BREAK 1
#define BREAK_WAITER_GOT_HALT 2
@@ -467,29 +363,168 @@ do { \
wait_standby(PS); \
} while(0)
-#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT && !defined(ERTS_SMP)
+#define ERTS_POLL_NOT_WOKEN ((erts_aint32_t) 0)
+#define ERTS_POLL_WOKEN_IO_READY ((erts_aint32_t) 1)
+#define ERTS_POLL_WOKEN_INTR ((erts_aint32_t) 2)
+#define ERTS_POLL_WOKEN_TIMEDOUT ((erts_aint32_t) 3)
static ERTS_INLINE int
-unset_interrupted_chk(ErtsPollSet ps)
+is_io_ready(ErtsPollSet ps)
{
- /* This operation isn't atomic, but we have no need at all for an
- atomic operation here... */
- int res = ps->interrupt;
- ps->interrupt = 0;
- return res;
+ return erts_atomic32_read(&ps->wakeup_state) == ERTS_POLL_WOKEN_IO_READY;
}
+static ERTS_INLINE void
+woke_up(ErtsPollSet ps)
+{
+ if (erts_atomic32_read(&ps->wakeup_state) == ERTS_POLL_NOT_WOKEN)
+ erts_atomic32_cmpxchg(&ps->wakeup_state,
+ ERTS_POLL_WOKEN_TIMEDOUT,
+ ERTS_POLL_NOT_WOKEN);
+#ifdef DEBUG
+ {
+ erts_aint32_t wakeup_state = erts_atomic32_read(&ps->wakeup_state);
+ switch (wakeup_state) {
+ case ERTS_POLL_WOKEN_IO_READY:
+ case ERTS_POLL_WOKEN_INTR:
+ case ERTS_POLL_WOKEN_TIMEDOUT:
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
#endif
+}
+
+static ERTS_INLINE int
+wakeup_cause(ErtsPollSet ps)
+{
+ int res;
+ erts_aint32_t wakeup_state = erts_atomic32_read(&ps->wakeup_state);
+ switch (wakeup_state) {
+ case ERTS_POLL_WOKEN_IO_READY:
+ res = 0;
+ break;
+ case ERTS_POLL_WOKEN_INTR:
+ res = EINTR;
+ break;
+ case ERTS_POLL_WOKEN_TIMEDOUT:
+ res = ETIMEDOUT;
+ break;
+ default:
+ res = 0;
+ erl_exit(ERTS_ABORT_EXIT,
+ "%s:%d: Internal error: Invalid wakeup_state=%d\n",
+ __FILE__, __LINE__, (int) wakeup_state);
+ }
+ return res;
+}
+
+static ERTS_INLINE DWORD
+poll_wait_timeout(ErtsPollSet ps, SysTimeval *tvp)
+{
+ time_t timeout = tvp->tv_sec * 1000 + tvp->tv_usec / 1000;
+
+ if (timeout <= 0) {
+ woke_up(ps);
+ return (DWORD) 0;
+ }
+
+ ResetEvent(ps->event_io_ready);
+ /*
+ * Since we don't know the internals of ResetEvent() we issue
+ * a memory barrier as a safety precaution ensuring that
+ * the load of wakeup_state wont be reordered with stores made
+ * by ResetEvent().
+ */
+ ERTS_THR_MEMORY_BARRIER;
+ if (erts_atomic32_read(&ps->wakeup_state) != ERTS_POLL_NOT_WOKEN)
+ return (DWORD) 0;
+
+ if (timeout > ERTS_AINT32_T_MAX) /* Also prevents DWORD overflow */
+ timeout = ERTS_AINT32_T_MAX;
+
+ erts_smp_atomic32_set_relb(&ps->timeout, (erts_aint32_t) timeout);
+ return (DWORD) timeout;
+}
-#ifdef ERTS_SMP
static ERTS_INLINE void
-wake_poller(ErtsPollSet ps)
+wake_poller(ErtsPollSet ps, int io_ready)
{
- if (!ERTS_POLLSET_SET_POLLER_WOKEN_CHK(ps)) {
+ erts_aint32_t wakeup_state = erts_atomic32_read(&ps->wakeup_state);
+ if (io_ready) {
+ /* We may set the event multiple times. This is, however, harmless. */
+ erts_atomic32_set(&ps->wakeup_state, ERTS_POLL_WOKEN_IO_READY);
+ }
+ else {
+ while (wakeup_state != ERTS_POLL_WOKEN_IO_READY
+ && wakeup_state != ERTS_POLL_WOKEN_INTR) {
+ erts_aint32_t act = erts_atomic32_cmpxchg(&ps->wakeup_state,
+ ERTS_POLL_WOKEN_INTR,
+ wakeup_state);
+ if (act == wakeup_state) {
+ wakeup_state = act;
+ break;
+ }
+ wakeup_state = act;
+ }
+ }
+ if (wakeup_state == ERTS_POLL_NOT_WOKEN) {
+ /*
+ * Since we don't know the internals of SetEvent() we issue
+ * a memory barrier as a safety precaution ensuring that
+ * the store we just made to wakeup_state wont be reordered
+ * with loads in SetEvent().
+ */
+ ERTS_THR_MEMORY_BARRIER;
SetEvent(ps->event_io_ready);
}
}
-#endif
+
+static ERTS_INLINE void
+reset_io_ready(ErtsPollSet ps)
+{
+ erts_atomic32_set(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN);
+}
+
+static ERTS_INLINE void
+restore_io_ready(ErtsPollSet ps)
+{
+ erts_atomic32_set(&ps->wakeup_state, ERTS_POLL_WOKEN_IO_READY);
+}
+
+/*
+ * notify_io_ready() is used by threads waiting for events, when
+ * notifying a poller thread about I/O ready.
+ */
+static ERTS_INLINE void
+notify_io_ready(ErtsPollSet ps)
+{
+ wake_poller(ps, 1);
+}
+
+static ERTS_INLINE void
+reset_interrupt(ErtsPollSet ps)
+{
+ /* We need to keep io-ready if set */
+ erts_aint32_t wakeup_state = erts_atomic32_read(&ps->wakeup_state);
+ while (wakeup_state != ERTS_POLL_WOKEN_IO_READY
+ && wakeup_state != ERTS_POLL_NOT_WOKEN) {
+ erts_aint32_t act = erts_atomic32_cmpxchg(&ps->wakeup_state,
+ ERTS_POLL_NOT_WOKEN,
+ wakeup_state);
+ if (wakeup_state == act)
+ break;
+ wakeup_state = act;
+ }
+}
+
+static ERTS_INLINE void
+set_interrupt(ErtsPollSet ps)
+{
+ wake_poller(ps, 0);
+}
static void setup_standby_wait(ErtsPollSet ps, int num_threads)
{
@@ -653,14 +688,14 @@ static void *break_waiter(void *param)
case WAIT_OBJECT_0:
ResetEvent(harr[0]);
erts_mtx_lock(&break_waiter_lock);
- erts_atomic_set(&break_waiter_state,BREAK_WAITER_GOT_BREAK);
+ erts_atomic32_set(&break_waiter_state,BREAK_WAITER_GOT_BREAK);
SetEvent(break_happened_event);
erts_mtx_unlock(&break_waiter_lock);
break;
case (WAIT_OBJECT_0+1):
ResetEvent(harr[1]);
erts_mtx_lock(&break_waiter_lock);
- erts_atomic_set(&break_waiter_state,BREAK_WAITER_GOT_HALT);
+ erts_atomic32_set(&break_waiter_state,BREAK_WAITER_GOT_HALT);
SetEvent(break_happened_event);
erts_mtx_unlock(&break_waiter_lock);
break;
@@ -767,12 +802,7 @@ event_happened:
consistency_check(w);
#endif
ASSERT(WAIT_OBJECT_0 < i && i < WAIT_OBJECT_0+w->active_events);
- if (!erts_atomic_xchg(&ps->sys_io_ready,1)) {
- HARDDEBUGF(("SET EventIoReady (%d)",erts_atomic_read(&ps->sys_io_ready)));
- SetEvent(ps->event_io_ready);
- } else {
- HARDDEBUGF(("DONT SET EventIoReady"));
- }
+ notify_io_ready(ps);
/*
* The main thread wont start working on our arrays untill we're
@@ -967,15 +997,10 @@ static int cancel_driver_select(ErtsPollSet ps, HANDLE event)
void erts_poll_interrupt(ErtsPollSet ps, int set /* bool */)
{
HARDTRACEF(("In erts_poll_interrupt(%d)",set));
-#ifdef ERTS_SMP
- if (set) {
- ERTS_POLLSET_SET_INTERRUPTED(ps);
- wake_poller(ps);
- }
- else {
- ERTS_POLLSET_UNSET_INTERRUPTED(ps);
- }
-#endif
+ if (!set)
+ reset_interrupt(ps);
+ else
+ set_interrupt(ps);
HARDTRACEF(("Out erts_poll_interrupt(%d)",set));
}
@@ -984,17 +1009,10 @@ void erts_poll_interrupt_timed(ErtsPollSet ps,
long msec)
{
HARDTRACEF(("In erts_poll_interrupt_timed(%d,%ld)",set,msec));
-#ifdef ERTS_SMP
- if (set) {
- if (erts_smp_atomic_read(&ps->timeout) > msec) {
- ERTS_POLLSET_SET_INTERRUPTED(ps);
- wake_poller(ps);
- }
- }
- else {
- ERTS_POLLSET_UNSET_INTERRUPTED(ps);
- }
-#endif
+ if (!set)
+ reset_interrupt(ps);
+ else if (erts_smp_atomic32_read_acqb(&ps->timeout) > (erts_aint32_t) msec)
+ set_interrupt(ps);
HARDTRACEF(("Out erts_poll_interrupt_timed"));
}
@@ -1068,10 +1086,8 @@ void erts_poll_controlv(ErtsPollSet ps,
int erts_poll_wait(ErtsPollSet ps,
ErtsPollResFd pr[],
int *len,
- SysTimeval *utvp)
+ SysTimeval *tvp)
{
- SysTimeval *tvp = utvp;
- SysTimeval itv;
int no_fds;
DWORD timeout;
EventData* ev;
@@ -1084,7 +1100,7 @@ int erts_poll_wait(ErtsPollSet ps,
HARDTRACEF(("In erts_poll_wait"));
ERTS_POLLSET_LOCK(ps);
- if (!erts_atomic_read(&ps->sys_io_ready) && ps->restore_events) {
+ if (!is_io_ready(ps) && ps->restore_events) {
HARDDEBUGF(("Restore events: %d",ps->num_waiters));
ps->restore_events = 0;
for (i = 0; i < ps->num_waiters; ++i) {
@@ -1102,7 +1118,7 @@ int erts_poll_wait(ErtsPollSet ps,
if (w->highwater != w->active_events) {
HARDDEBUGF(("Oups!"));
/* Oups, got signalled before we took the lock, can't reset */
- if(erts_atomic_read(&ps->sys_io_ready) == 0) {
+ if(!is_io_ready(ps)) {
erl_exit(1,"Internal error: "
"Inconsistent io structures in erl_poll.\n");
}
@@ -1127,39 +1143,27 @@ int erts_poll_wait(ErtsPollSet ps,
no_fds = ERTS_POLL_MAX_RES;
#endif
+ timeout = poll_wait_timeout(ps, tvp);
- ResetEvent(ps->event_io_ready);
- ERTS_POLLSET_UNSET_POLLER_WOKEN(ps);
-
-#ifdef ERTS_SMP
- if (ERTS_POLLSET_IS_INTERRUPTED(ps)) {
- /* Interrupt use zero timeout */
- itv.tv_sec = 0;
- itv.tv_usec = 0;
- tvp = &itv;
- }
-#endif
-
- timeout = tvp->tv_sec * 1000 + tvp->tv_usec / 1000;
/*HARDDEBUGF(("timeout = %ld",(long) timeout));*/
- erts_smp_atomic_set(&ps->timeout, timeout);
- if (timeout > 0 && ! erts_atomic_read(&ps->sys_io_ready) && ! erts_atomic_read(&break_waiter_state)) {
+ if (timeout > 0 && !erts_atomic32_read(&break_waiter_state)) {
HANDLE harr[2] = {ps->event_io_ready, break_happened_event};
int num_h = 2;
- HARDDEBUGF(("Start waiting %d [%d]",num_h, (long) timeout));
+ HARDDEBUGF(("Start waiting %d [%d]",num_h, (int) timeout));
ERTS_POLLSET_UNLOCK(ps);
WaitForMultipleObjects(num_h, harr, FALSE, timeout);
ERTS_POLLSET_LOCK(ps);
- HARDDEBUGF(("Stop waiting %d [%d]",num_h, (long) timeout));
+ HARDDEBUGF(("Stop waiting %d [%d]",num_h, (int) timeout));
+ woke_up(ps);
}
ERTS_UNSET_BREAK_REQUESTED;
- if(erts_atomic_read(&break_waiter_state)) {
+ if(erts_atomic32_read(&break_waiter_state)) {
erts_mtx_lock(&break_waiter_lock);
- break_state = erts_atomic_read(&break_waiter_state);
- erts_atomic_set(&break_waiter_state,0);
+ break_state = erts_atomic32_read(&break_waiter_state);
+ erts_atomic32_set(&break_waiter_state,0);
ResetEvent(break_happened_event);
erts_mtx_unlock(&break_waiter_lock);
switch (break_state) {
@@ -1174,15 +1178,13 @@ int erts_poll_wait(ErtsPollSet ps,
}
}
- ERTS_POLLSET_SET_POLLER_WOKEN(ps);
-
- if (!erts_atomic_read(&ps->sys_io_ready)) {
- res = EINTR;
- HARDDEBUGF(("EINTR!"));
- goto done;
+ res = wakeup_cause(ps);
+ if (res != 0) {
+ HARDDEBUGF(("%s!", res == EINTR ? "EINTR" : "ETIMEDOUT"));
+ goto done;
}
- erts_atomic_set(&ps->sys_io_ready,0);
+ reset_io_ready(ps);
n = ps->num_waiters;
@@ -1204,9 +1206,9 @@ int erts_poll_wait(ErtsPollSet ps,
if (num >= no_fds) {
w->highwater=j+1;
erts_mtx_unlock(&w->mtx);
- /* This might mean we still have data to report, set
- back the global flag! */
- erts_atomic_set(&ps->sys_io_ready,1);
+ /* This might mean we still have data to report,
+ restore flag indicating I/O ready! */
+ restore_io_ready(ps);
HARDDEBUGF(("To many FD's to report!"));
goto done;
}
@@ -1228,7 +1230,7 @@ int erts_poll_wait(ErtsPollSet ps,
erts_mtx_unlock(&w->mtx);
}
done:
- erts_smp_atomic_set(&ps->timeout, LONG_MAX);
+ erts_smp_atomic32_set(&ps->timeout, ERTS_AINT32_T_MAX);
*len = num;
ERTS_POLLSET_UNLOCK(ps);
HARDTRACEF(("Out erts_poll_wait"));
@@ -1306,15 +1308,13 @@ ErtsPollSet erts_poll_create_pollset(void)
ps->standby_wait_counter = 0;
ps->event_io_ready = CreateManualEvent(FALSE);
ps->standby_wait_event = CreateManualEvent(FALSE);
- erts_atomic_init(&ps->sys_io_ready,0);
ps->restore_events = 0;
+ erts_atomic32_init(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN);
#ifdef ERTS_SMP
- erts_smp_atomic_init(&ps->woken, 0);
erts_smp_mtx_init(&ps->mtx, "pollset");
- erts_smp_atomic_init(&ps->interrupt, 0);
#endif
- erts_smp_atomic_init(&ps->timeout, LONG_MAX);
+ erts_smp_atomic32_init(&ps->timeout, ERTS_AINT32_T_MAX);
HARDTRACEF(("Out erts_poll_create_pollset"));
return ps;
@@ -1366,7 +1366,7 @@ void erts_poll_init(void)
erts_mtx_init(&break_waiter_lock,"break_waiter_lock");
break_happened_event = CreateManualEvent(FALSE);
- erts_atomic_init(&break_waiter_state, 0);
+ erts_atomic32_init(&break_waiter_state, 0);
erts_thr_create(&thread, &break_waiter, NULL, NULL);
ERTS_UNSET_BREAK_REQUESTED;
diff --git a/erts/emulator/sys/win32/erl_win_dyn_driver.h b/erts/emulator/sys/win32/erl_win_dyn_driver.h
index 4949998abc..1347eead91 100644
--- a/erts/emulator/sys/win32/erl_win_dyn_driver.h
+++ b/erts/emulator/sys/win32/erl_win_dyn_driver.h
@@ -87,15 +87,15 @@ WDD_TYPEDEF(unsigned long, erts_alc_test, (unsigned long,
unsigned long,
unsigned long,
unsigned long));
-WDD_TYPEDEF(long, driver_binary_get_refc, (ErlDrvBinary *dbp));
-WDD_TYPEDEF(long, driver_binary_inc_refc, (ErlDrvBinary *dbp));
-WDD_TYPEDEF(long, driver_binary_dec_refc, (ErlDrvBinary *dbp));
+WDD_TYPEDEF(ErlDrvSInt, driver_binary_get_refc, (ErlDrvBinary *dbp));
+WDD_TYPEDEF(ErlDrvSInt, driver_binary_inc_refc, (ErlDrvBinary *dbp));
+WDD_TYPEDEF(ErlDrvSInt, driver_binary_dec_refc, (ErlDrvBinary *dbp));
WDD_TYPEDEF(ErlDrvPDL, driver_pdl_create, (ErlDrvPort));
WDD_TYPEDEF(void, driver_pdl_lock, (ErlDrvPDL));
WDD_TYPEDEF(void, driver_pdl_unlock, (ErlDrvPDL));
-WDD_TYPEDEF(long, driver_pdl_get_refc, (ErlDrvPDL));
-WDD_TYPEDEF(long, driver_pdl_inc_refc, (ErlDrvPDL));
-WDD_TYPEDEF(long, driver_pdl_dec_refc, (ErlDrvPDL));
+WDD_TYPEDEF(ErlDrvSInt, driver_pdl_get_refc, (ErlDrvPDL));
+WDD_TYPEDEF(ErlDrvSInt, driver_pdl_inc_refc, (ErlDrvPDL));
+WDD_TYPEDEF(ErlDrvSInt, driver_pdl_dec_refc, (ErlDrvPDL));
WDD_TYPEDEF(void, driver_system_info, (ErlDrvSysInfo *, size_t));
WDD_TYPEDEF(int, driver_get_now, (ErlDrvNowData *));
WDD_TYPEDEF(int, driver_monitor_process, (ErlDrvPort port,
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index 15d4cd7361..37041ed987 100644
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -31,7 +31,7 @@
#include "global.h"
#include "erl_threads.h"
#include "../../drivers/win32/win_con.h"
-
+#include "erl_cpu_topology.h"
void erts_sys_init_float(void);
@@ -67,14 +67,17 @@ static void async_read_file(struct async_io* aio, LPVOID buf, DWORD numToRead);
static int async_write_file(struct async_io* aio, LPVOID buf, DWORD numToWrite);
static int get_overlapped_result(struct async_io* aio,
LPDWORD pBytesRead, BOOL wait);
-static BOOL CreateChildProcess(char *, HANDLE, HANDLE,
+static BOOL create_child_process(char *, HANDLE, HANDLE,
HANDLE, LPHANDLE, BOOL,
LPVOID, LPTSTR, unsigned,
char **, int *);
static int create_pipe(LPHANDLE, LPHANDLE, BOOL, BOOL);
-static int ApplicationType(const char* originalName, char fullPath[MAX_PATH],
+static int application_type(const char* originalName, char fullPath[MAX_PATH],
BOOL search_in_path, BOOL handle_quotes,
int *error_return);
+static int application_type_w(const char* originalName, WCHAR fullPath[MAX_PATH],
+ BOOL search_in_path, BOOL handle_quotes,
+ int *error_return);
HANDLE erts_service_event;
@@ -87,7 +90,7 @@ static erts_smp_atomic_t pipe_creation_counter;
static erts_smp_mtx_t sys_driver_data_lock;
-/* Results from ApplicationType is one of */
+/* Results from application_type(_w) is one of */
#define APPL_NONE 0
#define APPL_DOS 1
#define APPL_WIN3X 2
@@ -97,7 +100,7 @@ static 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 void close_active_handle(ErlDrvPort, HANDLE handle);
static DWORD WINAPI threaded_handle_closer(LPVOID param);
#endif
static DWORD WINAPI threaded_reader(LPVOID param);
@@ -137,7 +140,11 @@ static BOOL win_console = FALSE;
static OSVERSIONINFO int_os_version; /* Version information for Win32. */
-#ifdef ERTS_SMP
+/*#define USE_CANCELIOEX
+ Disabled the use of CancelIoEx as its been seen to cause problem with some
+ drivers. Not sure what to blame; faulty drivers or some form of invalid use.
+*/
+#if defined(ERTS_SMP) && defined(USE_CANCELIOEX)
static BOOL (WINAPI *fpCancelIoEx)(HANDLE,LPOVERLAPPED);
#endif
@@ -684,6 +691,7 @@ release_driver_data(DriverData* dp)
erts_smp_mtx_lock(&sys_driver_data_lock);
#ifdef ERTS_SMP
+#ifdef USE_CANCELIOEX
if (fpCancelIoEx != NULL) {
if (dp->in.thread == (HANDLE) -1 && dp->in.fd != INVALID_HANDLE_VALUE) {
(*fpCancelIoEx)(dp->in.fd, NULL);
@@ -692,10 +700,12 @@ release_driver_data(DriverData* dp)
(*fpCancelIoEx)(dp->out.fd, NULL);
}
}
- else {
+ else
+#endif
+ {
/* 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.
+ CancelIoEx as that's only available 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];
@@ -706,7 +716,7 @@ release_driver_data(DriverData* dp)
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;
+ close_active_handle(dp->port_num, dp->in.ov.hEvent);
dp->in.ov.hEvent = NULL;
timeout = 0;
}
@@ -717,14 +727,11 @@ release_driver_data(DriverData* dp)
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;
+ close_active_handle(dp->port_num, 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->in.thread == (HANDLE) -1 && dp->in.fd != INVALID_HANDLE_VALUE) {
@@ -772,42 +779,82 @@ release_driver_data(DriverData* dp)
#ifdef ERTS_SMP
-struct handles_to_be_closed
-{
- int cnt;
- HANDLE handles[2];
+struct handles_to_be_closed {
+ HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+ unsigned cnt;
};
+static struct handles_to_be_closed* htbc_curr = NULL;
+CRITICAL_SECTION htbc_lock;
-static void close_active_handles(ErlDrvPort port_num, const HANDLE* handles, int cnt)
+static void close_active_handle(ErlDrvPort port_num, HANDLE handle)
{
- DWORD tid;
- HANDLE thread;
+ struct handles_to_be_closed* htbc;
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);
+ EnterCriticalSection(&htbc_lock);
+ htbc = htbc_curr;
+ if (htbc == NULL || htbc->cnt >= MAXIMUM_WAIT_OBJECTS) {
+ DWORD tid;
+ HANDLE thread;
+
+ htbc = (struct handles_to_be_closed*) erts_alloc(ERTS_ALC_T_DRV_TAB,
+ sizeof(*htbc));
+ htbc->handles[0] = CreateAutoEvent(FALSE);
+ htbc->cnt = 1;
+ thread = (HANDLE *) _beginthreadex(NULL, 0, threaded_handle_closer, htbc, 0, &tid);
+ CloseHandle(thread);
}
- thread = (HANDLE *) _beginthreadex(NULL, 0, threaded_handle_closer, htbc, 0, &tid);
- CloseHandle(thread);
+ htbc->handles[htbc->cnt++] = handle;
+ driver_select(port_num, (ErlDrvEvent)handle, ERL_DRV_USE_NO_CALLBACK, 0);
+ SetEvent(htbc->handles[0]);
+ htbc_curr = htbc;
+ LeaveCriticalSection(&htbc_lock);
}
-
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]);
+ unsigned ix;
+ DWORD res;
+ DEBUGF(("threaded_handle_closer %p started\r\n", htbc));
+ EnterCriticalSection(&htbc_lock);
+ for (;;) {
+ {
+ HANDLE* handles = htbc->handles;
+ unsigned cnt = htbc->cnt;
+ DWORD timeout = (htbc == htbc_curr) ? INFINITE : 10*1000;
+
+ LeaveCriticalSection(&htbc_lock);
+ DEBUGF(("threaded_handle_closer %p waiting for %d handles\r\n", htbc, cnt));
+ res = WaitForMultipleObjects(cnt, handles, FALSE, timeout);
+ }
+ EnterCriticalSection(&htbc_lock);
+ switch (res) {
+ case WAIT_OBJECT_0:
+ case WAIT_TIMEOUT:
+ break; /* got some more handles to wait for maybe */
+ default:
+ ix = res - WAIT_OBJECT_0;
+ if (ix > 0 && ix < htbc->cnt) {
+ CloseHandle(htbc->handles[ix]);
+ htbc->handles[ix] = htbc->handles[--htbc->cnt];
+ }
+ }
+ if (htbc != htbc_curr) {
+ if (htbc->cnt == 1) { /* no real handles left */
+ break;
+ }
+ /* The thread with most free slots will be "current" */
+ if (htbc->cnt < htbc_curr->cnt) {
+ htbc_curr = htbc;
+ DEBUGF(("threaded_handle_closer %p made current\r\n", htbc));
+ }
+ }
}
+ LeaveCriticalSection(&htbc_lock);
+ CloseHandle(htbc->handles[0]);
erts_free(ERTS_ALC_T_DRV_TAB, htbc);
- DEBUGF(("threaded_handle_closer terminating\r\n"));
+ DEBUGF(("threaded_handle_closer %p terminating\r\n", htbc));
return 0;
}
#endif /* ERTS_SMP */
@@ -1101,11 +1148,10 @@ static int
spawn_init()
{
int i;
-#ifdef ERTS_SMP
+#if defined(ERTS_SMP) && defined(USE_CANCELIOEX)
HMODULE module = GetModuleHandle("kernel32");
- fpCancelIoEx = (module != NULL) ?
- (BOOL (WINAPI *)(HANDLE,LPOVERLAPPED))
- GetProcAddress(module,"CancelIoEx") : NULL;
+ fpCancelIoEx = (BOOL (WINAPI *)(HANDLE,LPOVERLAPPED))
+ ((module != NULL) ? GetProcAddress(module,"CancelIoEx") : NULL);
DEBUGF(("fpCancelIoEx = %p\r\n", fpCancelIoEx));
#endif
driver_data = (struct driver_data *)
@@ -1192,8 +1238,10 @@ spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* opts)
*/
DEBUGF(("Spawning \"%s\"\n", name));
- envir = win_build_environment(envir);
- ok = CreateChildProcess(name,
+ envir = win_build_environment(envir); /* Still an ansi environment, could be
+ converted to unicode for spawn_executable, but
+ that is not done (yet) */
+ ok = create_child_process(name,
hChildStdin,
hChildStdout,
hChildStderr,
@@ -1272,7 +1320,7 @@ create_file_thread(AsyncIo* aio, int mode)
}
/*
- * A helper function used by CreateChildProcess().
+ * A helper function used by create_child_process().
* Parses a command line with arguments and returns the length of the
* first part containing the program name.
* Example: input = "\"Program Files\"\\erl arg1 arg2"
@@ -1313,24 +1361,25 @@ int parse_command(char* cmd){
return i;
}
-BOOL need_quotes(char *str)
+static BOOL need_quotes(WCHAR *str)
{
int in_quote = 0;
int backslashed = 0;
int naked_space = 0;
- while (*str != '\0') {
+
+ while (*str != L'\0') {
switch (*str) {
- case '\\' :
+ case L'\\' :
backslashed = !backslashed;
break;
- case '"':
+ case L'"':
if (backslashed) {
backslashed=0;
} else {
in_quote = !in_quote;
}
break;
- case ' ':
+ case L' ':
backslashed = 0;
if (!(backslashed || in_quote)) {
naked_space++;
@@ -1349,7 +1398,7 @@ BOOL need_quotes(char *str)
/*
*----------------------------------------------------------------------
*
- * CreateChildProcess --
+ * create_child_process --
*
* Create a child process that has pipes as its
* standard input, output, and error. The child process runs
@@ -1374,7 +1423,7 @@ BOOL need_quotes(char *str)
*/
static BOOL
-CreateChildProcess
+create_child_process
(
char *origcmd, /* Command line for child process (including
* name of executable). Or whole executable if st is
@@ -1393,14 +1442,12 @@ CreateChildProcess
)
{
PROCESS_INFORMATION piProcInfo = {0};
- STARTUPINFO siStartInfo = {0};
BOOL ok = FALSE;
int applType;
/* Not to be changed for different types of executables */
int staticCreateFlags = GetPriorityClass(GetCurrentProcess());
int createFlags = DETACHED_PROCESS;
char *newcmdline = NULL;
- char execPath[MAX_PATH];
int cmdlength;
char* thecommand;
LPTSTR appname = NULL;
@@ -1408,14 +1455,17 @@ CreateChildProcess
*errno_return = -1;
- siStartInfo.cb = sizeof(STARTUPINFO);
- siStartInfo.dwFlags = STARTF_USESTDHANDLES;
- siStartInfo.hStdInput = hStdin;
- siStartInfo.hStdOutput = hStdout;
- siStartInfo.hStdError = hStderr;
-
if (st != ERTS_SPAWN_EXECUTABLE) {
+ STARTUPINFO siStartInfo = {0};
+ char execPath[MAX_PATH];
+
+ siStartInfo.cb = sizeof(STARTUPINFO);
+ siStartInfo.dwFlags = STARTF_USESTDHANDLES;
+ siStartInfo.hStdInput = hStdin;
+ siStartInfo.hStdOutput = hStdout;
+ siStartInfo.hStdError = hStderr;
+
/*
* Parse out the program name from the command line (it can be quoted and
* contain spaces).
@@ -1427,9 +1477,9 @@ CreateChildProcess
thecommand[cmdlength] = '\0';
DEBUGF(("spawn command: %s\n", thecommand));
- applType = ApplicationType(thecommand, execPath, TRUE,
+ applType = application_type(thecommand, execPath, TRUE,
TRUE, errno_return);
- DEBUGF(("ApplicationType returned for (%s) is %d\n", thecommand, applType));
+ DEBUGF(("application_type returned for (%s) is %d\n", thecommand, applType));
erts_free(ERTS_ALC_T_TMP, (void *) thecommand);
if (applType == APPL_NONE) {
erts_free(ERTS_ALC_T_TMP,newcmdline);
@@ -1458,126 +1508,147 @@ CreateChildProcess
strcat(newcmdline, execPath);
strcat(newcmdline, origcmd+cmdlength);
- } else { /* ERTS_SPAWN_EXECUTABLE */
+ DEBUGF(("Creating child process: %s, createFlags = %d\n", newcmdline, createFlags));
+ ok = CreateProcessA(appname,
+ newcmdline,
+ NULL,
+ NULL,
+ TRUE,
+ createFlags | staticCreateFlags,
+ env,
+ wd,
+ &siStartInfo,
+ &piProcInfo);
+
+ } else { /* ERTS_SPAWN_EXECUTABLE, filename and args are in unicode ({utf16,little}) */
int run_cmd = 0;
- applType = ApplicationType(origcmd, execPath, FALSE, FALSE,
- errno_return);
+ STARTUPINFOW siStartInfo = {0};
+ WCHAR execPath[MAX_PATH];
+
+
+ siStartInfo.cb = sizeof(STARTUPINFOW);
+ siStartInfo.dwFlags = STARTF_USESTDHANDLES;
+ siStartInfo.hStdInput = hStdin;
+ siStartInfo.hStdOutput = hStdout;
+ siStartInfo.hStdError = hStderr;
+
+ applType = application_type_w(origcmd, (char *) execPath, FALSE, FALSE,
+ errno_return);
if (applType == APPL_NONE) {
return FALSE;
}
if (applType == APPL_DOS) {
- /*
- * See comment above
- */
+ /*
+ * See comment above
+ */
- siStartInfo.wShowWindow = SW_HIDE;
- siStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
- createFlags = CREATE_NEW_CONSOLE;
- run_cmd = 1;
+ siStartInfo.wShowWindow = SW_HIDE;
+ siStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
+ createFlags = CREATE_NEW_CONSOLE;
+ run_cmd = 1;
} else if (hide) {
- DEBUGF(("hiding window\n"));
- siStartInfo.wShowWindow = SW_HIDE;
- siStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
- createFlags = 0;
+ DEBUGF(("hiding window\n"));
+ siStartInfo.wShowWindow = SW_HIDE;
+ siStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
+ createFlags = 0;
}
if (run_cmd) {
- char cmdPath[MAX_PATH];
+ WCHAR cmdPath[MAX_PATH];
int cmdType;
- cmdType = ApplicationType("cmd.exe", cmdPath, TRUE, FALSE, errno_return);
+ cmdType = application_type_w((char *) L"cmd.exe", (char *) cmdPath, TRUE, FALSE, errno_return);
if (cmdType == APPL_NONE || cmdType == APPL_DOS) {
return FALSE;
}
- appname = (char *) erts_alloc(ERTS_ALC_T_TMP, strlen(cmdPath)+1);
- strcpy(appname,cmdPath);
+ appname = (char *) erts_alloc(ERTS_ALC_T_TMP, (wcslen(cmdPath)+1)*sizeof(WCHAR));
+ wcscpy((WCHAR *) appname,cmdPath);
} else {
- appname = (char *) erts_alloc(ERTS_ALC_T_TMP, strlen(execPath)+1);
- strcpy(appname,execPath);
+ appname = (char *) erts_alloc(ERTS_ALC_T_TMP, (wcslen(execPath)+1)*sizeof(WCHAR));
+ wcscpy((WCHAR *) appname, execPath);
}
- if (argv == NULL) {
+ if (argv == NULL) {
BOOL orig_need_q = need_quotes(execPath);
- char *ptr;
- int ocl = strlen(execPath);
+ WCHAR *ptr;
+ int ocl = wcslen(execPath);
if (run_cmd) {
newcmdline = (char *) erts_alloc(ERTS_ALC_T_TMP,
- ocl + ((orig_need_q) ? 3 : 1)
- + 11);
- memcpy(newcmdline,"cmd.exe /c ",11);
- ptr = newcmdline + 11;
+ (ocl + ((orig_need_q) ? 3 : 1)
+ + 11)*sizeof(WCHAR));
+ memcpy(newcmdline,L"cmd.exe /c ",11*sizeof(WCHAR));
+ ptr = (WCHAR *) (newcmdline + (11*sizeof(WCHAR)));
} else {
newcmdline = (char *) erts_alloc(ERTS_ALC_T_TMP,
- ocl + ((orig_need_q) ? 3 : 1));
- ptr = newcmdline;
+ (ocl + ((orig_need_q) ? 3 : 1))*sizeof(WCHAR));
+ ptr = (WCHAR *) newcmdline;
}
if (orig_need_q) {
- *ptr++ = '"';
+ *ptr++ = L'"';
}
- memcpy(ptr,execPath,ocl);
+ memcpy(ptr,execPath,ocl*sizeof(WCHAR));
ptr += ocl;
if (orig_need_q) {
- *ptr++ = '"';
+ *ptr++ = L'"';
}
- *ptr = '\0';
+ *ptr = L'\0';
} else {
int sum = 1; /* '\0' */
- char **ar = argv;
- char *n;
+ WCHAR **ar = (WCHAR **) argv;
+ WCHAR *n;
char *save_arg0 = NULL;
if (argv[0] == erts_default_arg0 || run_cmd) {
save_arg0 = argv[0];
- argv[0] = execPath;
+ argv[0] = (char *) execPath;
}
if (run_cmd) {
sum += 11; /* cmd.exe /c */
}
while (*ar != NULL) {
- sum += strlen(*ar);
+ sum += wcslen(*ar);
if (need_quotes(*ar)) {
sum += 2; /* quotes */
}
sum++; /* space */
++ar;
}
- ar = argv;
- newcmdline = erts_alloc(ERTS_ALC_T_TMP, sum);
- n = newcmdline;
+ ar = (WCHAR **) argv;
+ newcmdline = erts_alloc(ERTS_ALC_T_TMP, sum*sizeof(WCHAR));
+ n = (WCHAR *) newcmdline;
if (run_cmd) {
- memcpy(n,"cmd.exe /c ",11);
+ memcpy(n,L"cmd.exe /c ",11*sizeof(WCHAR));
n += 11;
}
while (*ar != NULL) {
int q = need_quotes(*ar);
- sum = strlen(*ar);
+ sum = wcslen(*ar);
if (q) {
- *n++ = '"';
+ *n++ = L'"';
}
- memcpy(n,*ar,sum);
+ memcpy(n,*ar,sum*sizeof(WCHAR));
n += sum;
if (q) {
- *n++ = '"';
+ *n++ = L'"';
}
- *n++ = ' ';
+ *n++ = L' ';
++ar;
}
- ASSERT(n > newcmdline);
- *(n-1) = '\0';
+ *(n-1) = L'\0';
if (save_arg0 != NULL) {
argv[0] = save_arg0;
}
}
- }
- DEBUGF(("Creating child process: %s, createFlags = %d\n", newcmdline, createFlags));
- ok = CreateProcess(appname,
- newcmdline,
- NULL,
- NULL,
- TRUE,
- createFlags | staticCreateFlags,
- env,
- wd,
- &siStartInfo,
- &piProcInfo);
-
+ DEBUGF(("Creating child process: %s, createFlags = %d\n", newcmdline, createFlags));
+ ok = CreateProcessW((WCHAR *) appname,
+ (WCHAR *) newcmdline,
+ NULL,
+ NULL,
+ TRUE,
+ createFlags | staticCreateFlags,
+ env,
+ (WCHAR *) wd,
+ &siStartInfo,
+ &piProcInfo);
+
+ } /* end SPAWN_EXECUTABLE */
if (newcmdline != NULL) {
erts_free(ERTS_ALC_T_TMP,newcmdline);
}
@@ -1696,7 +1767,7 @@ static int create_pipe(HANDLE *phRead, HANDLE *phWrite, BOOL inheritRead, BOOL o
-static int ApplicationType
+static int application_type
(
const char *originalName, /* Name of the application to find. */
char fullPath[MAX_PATH], /* Filled with complete path to
@@ -1850,6 +1921,146 @@ static int ApplicationType
return applType;
}
+static int application_type_w (const char *originalName, /* Name of the application to find. */
+ WCHAR wfullpath[MAX_PATH],/* Filled with complete path to
+ * application. */
+ BOOL search_in_path, /* If we should search the system wide path */
+ BOOL handle_quotes, /* If we should handle quotes around executable */
+ int *error_return) /* A place to put an error code */
+{
+ int applType, i;
+ HANDLE hFile;
+ WCHAR *ext, *rest;
+ char buf[2];
+ DWORD read;
+ IMAGE_DOS_HEADER header;
+ static WCHAR extensions[][5] = {L"", L".com", L".exe", L".bat"};
+ int is_quoted;
+ int len;
+ WCHAR *wname = (WCHAR *) originalName;
+ WCHAR xfullpath[MAX_PATH];
+
+ len = wcslen(wname);
+ is_quoted = handle_quotes && len > 0 && wname[0] == L'"' &&
+ wname[len-1] == L'"';
+
+ applType = APPL_NONE;
+ *error_return = ENOENT;
+ for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) {
+ if(is_quoted) {
+ lstrcpynW(xfullpath, wname+1, MAX_PATH - 7); /* Cannot start using StringCchCopy yet, we support
+ older platforms */
+ len = wcslen(xfullpath);
+ if(len > 0) {
+ xfullpath[len-1] = L'\0';
+ }
+ } else {
+ lstrcpynW(xfullpath, wname, MAX_PATH - 5);
+ }
+ wcscat(xfullpath, extensions[i]);
+ /* It seems that the Unicode version does not allow in and out parameter to overlap. */
+ SearchPathW((search_in_path) ? NULL : L".", xfullpath, NULL, MAX_PATH, wfullpath, &rest);
+
+ /*
+ * Ignore matches on directories or data files, return if identified
+ * a known type.
+ */
+
+ if (GetFileAttributesW(wfullpath) & FILE_ATTRIBUTE_DIRECTORY) {
+ continue;
+ }
+
+ ext = wcsrchr(wfullpath, L'.');
+ if ((ext != NULL) && (_wcsicmp(ext, L".bat") == 0)) {
+ *error_return = EACCES;
+ applType = APPL_DOS;
+ break;
+ }
+
+ hFile = CreateFileW(wfullpath, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ continue;
+ }
+
+ *error_return = EACCES; /* If considered an error,
+ it's an access error */
+ header.e_magic = 0;
+ ReadFile(hFile, (void *) &header, sizeof(header), &read, NULL);
+ if (header.e_magic != IMAGE_DOS_SIGNATURE) {
+ /*
+ * Doesn't have the magic number for relocatable executables. If
+ * filename ends with .com, assume it's a DOS application anyhow.
+ * Note that we didn't make this assumption at first, because some
+ * supposed .com files are really 32-bit executables with all the
+ * magic numbers and everything.
+ */
+
+ CloseHandle(hFile);
+ if ((ext != NULL) && (_wcsicmp(ext, L".com") == 0)) {
+ applType = APPL_DOS;
+ break;
+ }
+ continue;
+ }
+ if (header.e_lfarlc != sizeof(header)) {
+ /*
+ * All Windows 3.X and Win32 and some DOS programs have this value
+ * set here. If it doesn't, assume that since it already had the
+ * other magic number it was a DOS application.
+ */
+
+ CloseHandle(hFile);
+ applType = APPL_DOS;
+ break;
+ }
+
+ /*
+ * The DWORD at header.e_lfanew points to yet another magic number.
+ */
+
+ buf[0] = '\0';
+ SetFilePointer(hFile, header.e_lfanew, NULL, FILE_BEGIN);
+ ReadFile(hFile, (void *) buf, 2, &read, NULL);
+ CloseHandle(hFile);
+
+ if ((buf[0] == 'L') && (buf[1] == 'E')) {
+ applType = APPL_DOS;
+ } else if ((buf[0] == 'N') && (buf[1] == 'E')) {
+ applType = APPL_WIN3X;
+ } else if ((buf[0] == 'P') && (buf[1] == 'E')) {
+ applType = APPL_WIN32;
+ } else {
+ continue;
+ }
+ break;
+ }
+
+ if (applType == APPL_NONE) {
+ return APPL_NONE;
+ }
+
+ if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) {
+ /*
+ * Replace long path name of executable with short path name for
+ * 16-bit applications. Otherwise the application may not be able
+ * to correctly parse its own command line to separate off the
+ * application name from the arguments.
+ */
+
+ GetShortPathNameW(wfullpath, wfullpath, MAX_PATH);
+ }
+ if (is_quoted) {
+ /* restore quotes on quoted program name */
+ len = wcslen(wfullpath);
+ memmove(wfullpath+1,wfullpath,len*sizeof(WCHAR));
+ wfullpath[0]=L'"';
+ wfullpath[len+1]=L'"';
+ wfullpath[len+2]=L'\0';
+ }
+ return applType;
+}
+
/*
* Thread function used to emulate overlapped reading.
*/
@@ -2973,13 +3184,50 @@ check_supported_os_version(void)
}
#ifdef USE_THREADS
-#ifdef ERTS_ENABLE_LOCK_COUNT
+
+typedef struct {
+ int sched_bind_data;
+} erts_thr_create_data_t;
+
+/*
+ * thr_create_prepare() is called in parent thread before thread creation.
+ * Returned value is passed as argument to thr_create_cleanup().
+ */
+static void *
+thr_create_prepare(void)
+{
+ erts_thr_create_data_t *tcdp;
+
+ tcdp = erts_alloc(ERTS_ALC_T_TMP, sizeof(erts_thr_create_data_t));
+ tcdp->sched_bind_data = erts_sched_bind_atthrcreate_prepare();
+
+ return (void *) tcdp;
+}
+
+
+/* thr_create_cleanup() is called in parent thread after thread creation. */
+static void
+thr_create_cleanup(void *vtcdp)
+{
+ erts_thr_create_data_t *tcdp = (erts_thr_create_data_t *) vtcdp;
+
+ erts_sched_bind_atthrcreate_parent(tcdp->sched_bind_data);
+
+ erts_free(ERTS_ALC_T_TMP, tcdp);
+}
+
static void
thr_create_prepare_child(void *vtcdp)
{
+ erts_thr_create_data_t *tcdp = (erts_thr_create_data_t *) vtcdp;
+
+#ifdef ERTS_ENABLE_LOCK_COUNT
erts_lcnt_thread_setup();
-}
#endif /* ERTS_ENABLE_LOCK_COUNT */
+
+ erts_sched_bind_atthrcreate_child(tcdp->sched_bind_data);
+}
+
#endif /* USE_THREADS */
void
@@ -2991,9 +3239,13 @@ erts_sys_pre_init(void)
#ifdef USE_THREADS
{
erts_thr_init_data_t eid = ERTS_THR_INIT_DATA_DEF_INITER;
-#ifdef ERTS_ENABLE_LOCK_COUNT
+
eid.thread_create_child_func = thr_create_prepare_child;
-#endif
+ /* Before creation in parent */
+ eid.thread_create_prepare_func = thr_create_prepare;
+ /* After creation in parent */
+ eid.thread_create_parent_func = thr_create_cleanup,
+
erts_thr_init(&eid);
#ifdef ERTS_ENABLE_LOCK_COUNT
erts_lcnt_init();
@@ -3027,6 +3279,7 @@ void erl_sys_init(void)
#ifdef ERTS_SMP
erts_smp_tsd_key_create(&win32_errstr_key);
+ InitializeCriticalSection(&htbc_lock);
#endif
erts_smp_atomic_init(&pipe_creation_counter,0);
/*
diff --git a/erts/emulator/sys/win32/sys_interrupt.c b/erts/emulator/sys/win32/sys_interrupt.c
index d2449a1bdb..943c338794 100644
--- a/erts/emulator/sys/win32/sys_interrupt.c
+++ b/erts/emulator/sys/win32/sys_interrupt.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ * Copyright Ericsson AB 1997-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -31,11 +31,11 @@
#endif
#ifdef ERTS_SMP
-erts_smp_atomic_t erts_break_requested;
+erts_smp_atomic32_t erts_break_requested;
#define ERTS_SET_BREAK_REQUESTED \
- erts_smp_atomic_set(&erts_break_requested, (long) 1)
+ erts_smp_atomic32_set(&erts_break_requested, (erts_aint32_t) 1)
#define ERTS_UNSET_BREAK_REQUESTED \
- erts_smp_atomic_set(&erts_break_requested, (long) 0)
+ erts_smp_atomic32_set(&erts_break_requested, (erts_aint32_t) 0)
#else
volatile int erts_break_requested = 0;
#define ERTS_SET_BREAK_REQUESTED (erts_break_requested = 1)
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index a4c02da626..7259e1b84d 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -83,6 +83,7 @@ MODULES= \
receive_SUITE \
ref_SUITE \
register_SUITE \
+ mtx_SUITE \
save_calls_SUITE \
send_term_SUITE \
sensitive_SUITE \
diff --git a/erts/emulator/test/a_SUITE.erl b/erts/emulator/test/a_SUITE.erl
index e9d653a7c4..784869251a 100644
--- a/erts/emulator/test/a_SUITE.erl
+++ b/erts/emulator/test/a_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,15 +26,32 @@
%%%-------------------------------------------------------------------
-module(a_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1, long_timers/1, pollset_size/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, long_timers/1, pollset_size/1]).
-all(doc) ->
- [];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[long_timers, pollset_size].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
long_timers(doc) ->
[];
long_timers(suite) ->
diff --git a/erts/emulator/test/after_SUITE.erl b/erts/emulator/test/after_SUITE.erl
index 3e1a871408..78ac099792 100644
--- a/erts/emulator/test/after_SUITE.erl
+++ b/erts/emulator/test/after_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,27 +21,48 @@
%% Tests receive after.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1, t_after/1, receive_after/1, receive_after_big/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ t_after/1, receive_after/1, receive_after_big/1,
receive_after_errors/1, receive_var_zero/1, receive_zero/1,
multi_timeout/1, receive_after_32bit/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%% Internal exports.
-export([timeout_g/0]).
-all(suite) ->
- [t_after, receive_after, receive_after_big, receive_after_errors,
- receive_var_zero, receive_zero, multi_timeout, receive_after_32bit].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [t_after, receive_after, receive_after_big,
+ receive_after_errors, receive_var_zero, receive_zero,
+ multi_timeout, receive_after_32bit].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(3)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index 94766dc6e9..687a4f0d5a 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,7 +18,8 @@
-module(alloc_SUITE).
-author('[email protected]').
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([basic/1,
coalesce/1,
@@ -29,28 +30,40 @@
rbtree/1,
mseg_clear_cache/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(DEFAULT_TIMETRAP_SECS, 240).
-all(doc) -> [];
-all(suite) -> [basic,
- coalesce,
- threads,
- realloc_copy,
- bucket_index,
- bucket_mask,
- rbtree,
- mseg_clear_cache].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic, coalesce, threads, realloc_copy, bucket_index,
+ bucket_mask, rbtree, mseg_clear_cache].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?t:seconds(?DEFAULT_TIMETRAP_SECS)),
[{watchdog, Dog},{testcase, Case}|Config].
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
diff --git a/erts/emulator/test/beam_SUITE.erl b/erts/emulator/test/beam_SUITE.erl
index 228ff15341..3643750883 100644
--- a/erts/emulator/test/beam_SUITE.erl
+++ b/erts/emulator/test/beam_SUITE.erl
@@ -19,16 +19,37 @@
-module(beam_SUITE).
--export([all/1, packed_registers/1, apply_last/1, apply_last_bif/1,
- buildo_mucho/1, heap_sizes/1, big_lists/1, fconv/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ packed_registers/1, apply_last/1, apply_last_bif/1,
+ buildo_mucho/1, heap_sizes/1, big_lists/1, fconv/1,
+ select_val/1]).
-export([applied/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [packed_registers, apply_last, apply_last_bif,
+ buildo_mucho, heap_sizes, big_lists, select_val].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [packed_registers, apply_last, apply_last_bif, buildo_mucho,
- heap_sizes, big_lists].
%% Verify that apply(M, F, A) is really tail recursive.
@@ -302,3 +323,19 @@ do_fconv(nil, Float) when is_float(Float) ->
Float + [];
do_fconv(tuple_literal, Float) when is_float(Float) ->
Float + {a,b}.
+
+select_val(Config) when is_list(Config) ->
+ ?line zero = do_select_val(0),
+ ?line big = do_select_val(1 bsl 64),
+ ?line integer = do_select_val(42),
+ ok.
+
+do_select_val(X) ->
+ case X of
+ 0 ->
+ zero;
+ 1 bsl 64 ->
+ big;
+ Int when is_integer(Int) ->
+ integer
+ end.
diff --git a/erts/emulator/test/beam_literals_SUITE.erl b/erts/emulator/test/beam_literals_SUITE.erl
index 75841adbfc..3ab7fc615b 100644
--- a/erts/emulator/test/beam_literals_SUITE.erl
+++ b/erts/emulator/test/beam_literals_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,21 +18,41 @@
%%
-module(beam_literals_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([putting/1, matching_smalls/1, matching_smalls_jt/1,
matching_bigs/1, matching_more_bigs/1,
matching_bigs_and_smalls/1, badmatch/1, case_clause/1,
receiving/1, literal_type_tests/1,
- put_list/1, fconv/1, literal_case_expression/1]).
+ put_list/1, fconv/1, literal_case_expression/1,
+ increment/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[putting, matching_smalls, matching_smalls_jt,
matching_bigs, matching_more_bigs,
matching_bigs_and_smalls, badmatch, case_clause,
- receiving, literal_type_tests,
- put_list, fconv, literal_case_expression].
+ receiving, literal_type_tests, put_list, fconv,
+ literal_case_expression, increment].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
putting(doc) -> "Test creating lists and tuples containing big number literals.";
putting(Config) when is_list(Config) ->
@@ -48,6 +68,7 @@ matching_bigs(doc) -> "Test matching of a few big number literals (in Beam,"
matching_bigs(Config) when is_list(Config) ->
a = matching1(3972907842873739),
b = matching1(-389789298378939783333333333333333333784),
+ other = matching1(3141699999999999999999999999999999999),
other = matching1(42).
matching_smalls(doc) -> "Test matching small numbers (both positive and negative).";
@@ -236,14 +257,14 @@ make_test([{T,L}|Ts]) ->
make_test([]) -> [].
test(T, L) ->
- S = lists:flatten(io_lib:format("begin io:format(\"~~p~~n\", [{~p,~p}]), if ~w(~w) -> true; true -> false end end. ", [T, L, T, L])),
+ S = lists:flatten(io_lib:format("begin io:format(\"~~p~n\", [{~p,~p}]), if ~w(~w) -> true; true -> false end end. ", [T, L, T, L])),
{ok,Toks,_Line} = erl_scan:string(S),
{ok,E} = erl_parse:parse_exprs(Toks),
{value,Val,_Bs} = erl_eval:exprs(E, []),
{match,0,{atom,0,Val},hd(E)}.
test(T, A, L) ->
- S = lists:flatten(io_lib:format("begin io:format(\"~~p~~n\", [{~p,~p,~p}]), if ~w(~w, ~w) -> true; true -> false end end. ",
+ S = lists:flatten(io_lib:format("begin io:format(\"~~p~n\", [{~p,~p,~p}]), if ~w(~w, ~w) -> true; true -> false end end. ",
[T,L,A,T,L,A])),
{ok,Toks,_Line} = erl_scan:string(S),
{ok,E} = erl_parse:parse_exprs(Toks),
@@ -405,14 +426,51 @@ fconv_2(F) when is_float(F) ->
literal_case_expression(Config) when is_list(Config) ->
?line DataDir = ?config(data_dir, Config),
?line Src = filename:join(DataDir, "literal_case_expression"),
- ?line {ok,literal_case_expression=Mod,Code} = compile:file(Src, [from_asm,binary]),
+ ?line {ok,literal_case_expression=Mod,Code} =
+ compile:file(Src, [from_asm,binary]),
?line {module,Mod} = code:load_binary(Mod, Src, Code),
?line ok = Mod:x(),
?line ok = Mod:y(),
+ ?line ok = Mod:zi1(),
+ ?line ok = Mod:zi2(),
+ ?line ok = Mod:za1(),
+ ?line ok = Mod:za2(),
?line true = code:delete(Mod),
?line code:purge(Mod),
ok.
+%% Test the i_increment instruction.
+increment(Config) when is_list(Config) ->
+ %% In the 32-bit emulator, Neg32 can be represented as a small,
+ %% but -Neg32 cannot. Therefore the i_increment instruction must
+ %% not be used in the subtraction that follows (since i_increment
+ %% cannot handle a bignum literal).
+ Neg32 = -(1 bsl 27),
+ Big32 = id(1 bsl 32),
+ Result32 = (1 bsl 32) + (1 bsl 27),
+ ?line Result32 = Big32 + (1 bsl 27),
+ ?line Result32 = Big32 - Neg32,
+
+ %% Same thing, but for the 64-bit emulator.
+ Neg64 = -(1 bsl 59),
+ Big64 = id(1 bsl 64),
+ Result64 = (1 bsl 64) + (1 bsl 59),
+ ?line Result64 = Big64 + (1 bsl 59),
+ ?line Result64 = Big64 - Neg64,
+
+ %% Test error handling for the i_increment instruction.
+ Bad = id(bad),
+ ?line {'EXIT',{badarith,_}} = (catch Bad + 42),
+
+ %% Small operands, but a big result.
+ Res32 = 1 bsl 27,
+ Small32 = id(Res32-1),
+ ?line Res32 = Small32 + 1,
+ Res64 = 1 bsl 59,
+ Small64 = id(Res64-1),
+ ?line Res64 = Small64 + 1,
+ ok.
+
%% Help functions.
chksum(Term) ->
diff --git a/erts/emulator/test/beam_literals_SUITE_data/literal_case_expression.S b/erts/emulator/test/beam_literals_SUITE_data/literal_case_expression.S
index c0ffe9ab53..bfdfc079dc 100644
--- a/erts/emulator/test/beam_literals_SUITE_data/literal_case_expression.S
+++ b/erts/emulator/test/beam_literals_SUITE_data/literal_case_expression.S
@@ -1,10 +1,11 @@
{module, literal_case_expression}. %% version = 0
-{exports, [{module_info,0},{module_info,1},{x,0},{y,0}]}.
+{exports, [{module_info,0},{module_info,1},{x,0},{y,0},
+ {zi1,0},{zi2,0},{za1,0},{za2,0}]}.
{attributes, []}.
-{labels, 15}.
+{labels, 32}.
{function, x, 0, 2}.
@@ -52,6 +53,81 @@
{label,10}.
{case_end,{float,34.0000}}.
+{function, zi1, 0, 16}.
+ {label,15}.
+ {func_info,{atom,literal_case_expression},{atom,zi1},0}.
+ {label,16}.
+ {test,is_integer,{f,19},[{integer,42}]}.
+ {select_val,{integer,42},
+ {f,18},
+ {list,[{integer,42},
+ {f,17},
+ {integer,1000},
+ {f,18}]}}.
+ {label,17}.
+ {move,{atom,ok},{x,0}}.
+ return.
+ {label,18}.
+ {move,{atom,error},{x,0}}.
+ return.
+ {label,19}.
+ {case_end,{integer,42}}.
+
+{function, zi2, 0, 16}.
+ {label,20}.
+ {func_info,{atom,literal_case_expression},{atom,zi2},0}.
+ {label,21}.
+ {test,is_integer,{f,23},[{integer,42}]}.
+ {select_val,{integer,42},
+ {f,23},
+ {list,[{integer,42},
+ {f,22},
+ {integer,1000},
+ {f,23}]}}.
+ {label,22}.
+ {move,{atom,ok},{x,0}}.
+ return.
+ {label,23}.
+ {move,{atom,error},{x,0}}.
+ return.
+
+{function, za1, 0, 25}.
+ {label,24}.
+ {func_info,{atom,literal_case_expression},{atom,za1},0}.
+ {label,25}.
+ {test,is_atom,{f,28},[{atom,x}]}.
+ {select_val,{atom,x},
+ {f,27},
+ {list,[{atom,a},
+ {f,27},
+ {atom,x},
+ {f,26}]}}.
+ {label,26}.
+ {move,{atom,ok},{x,0}}.
+ return.
+ {label,27}.
+ {move,{atom,error},{x,0}}.
+ return.
+ {label,28}.
+ {case_end,{atom,x}}.
+
+{function, za2, 0, 30}.
+ {label,29}.
+ {func_info,{atom,literal_case_expression},{atom,za2},0}.
+ {label,30}.
+ {test,is_atom,{f,32},[{atom,x}]}.
+ {select_val,{atom,x},
+ {f,32},
+ {list,[{atom,a},
+ {f,32},
+ {atom,x},
+ {f,31}]}}.
+ {label,31}.
+ {move,{atom,ok},{x,0}}.
+ return.
+ {label,32}.
+ {move,{atom,error},{x,0}}.
+ return.
{function, module_info, 0, 12}.
{label,11}.
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index b4ef0e6d5a..016befdced 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -19,24 +19,44 @@
-module(bif_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
types/1,
t_list_to_existing_atom/1,os_env/1,otp_7526/1,
binary_to_atom/1,binary_to_existing_atom/1,
atom_to_binary/1,min_max/1]).
-all(suite) ->
- [types,t_list_to_existing_atom,os_env,otp_7526,
- atom_to_binary,binary_to_atom,binary_to_existing_atom,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [types, t_list_to_existing_atom, os_env, otp_7526,
+ atom_to_binary, binary_to_atom, binary_to_existing_atom,
min_max].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(1)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
diff --git a/erts/emulator/test/big_SUITE.erl b/erts/emulator/test/big_SUITE.erl
index 6cedd39009..60b19af68e 100644
--- a/erts/emulator/test/big_SUITE.erl
+++ b/erts/emulator/test/big_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,9 +19,10 @@
-module(big_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([t_div/1, eq_28/1, eq_32/1, eq_big/1, eq_math/1, big_literals/1,
- borders/1, negative/1, big_float/1, big_float_1/1, big_float_2/1,
+ borders/1, negative/1, big_float_1/1, big_float_2/1,
shift_limit_1/1, powmod/1, system_limit/1, otp_6692/1]).
%% Internal exports.
@@ -30,19 +31,38 @@
-export([fac/1, fib/1, pow/2, gcd/2, lcm/2]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [t_div, eq_28, eq_32, eq_big, eq_math, big_literals,
+ borders, negative, {group, big_float}, shift_limit_1,
+ powmod, system_limit, otp_6692].
+
+groups() ->
+ [{big_float, [], [big_float_1, big_float_2]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [t_div, eq_28, eq_32, eq_big, eq_math, big_literals, borders,
- negative, big_float, shift_limit_1, powmod, system_limit, otp_6692].
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) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
@@ -260,10 +280,6 @@ big_literals(Config) when is_list(Config) ->
?line ok = Mod:t(),
ok.
-big_float(doc) ->
- ["Test cases for mixing bignums and floats"];
-big_float(suite) ->
- [big_float_1, big_float_2].
big_float_1(doc) ->
["OTP-2436, part 1"];
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 77d2579848..7e409f053e 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -40,9 +40,11 @@
%% phash2(Binary, N)
%%
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1, init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
copy_terms/1, conversions/1, deep_lists/1, deep_bitstr_lists/1,
bad_list_to_binary/1, bad_binary_to_list/1,
t_split_binary/1, bad_split/1, t_concat_binary/1,
@@ -61,24 +63,42 @@
%% Internal exports.
-export([sleeper/0]).
-all(suite) ->
- [copy_terms,conversions,deep_lists,deep_bitstr_lists,
+suite() -> [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,2}}].
+
+all() ->
+ [copy_terms, conversions, deep_lists, deep_bitstr_lists,
t_split_binary, bad_split, t_concat_binary,
- bad_list_to_binary, bad_binary_to_list, terms, terms_float,
- external_size, t_iolist_size,
- bad_binary_to_term_2,safe_binary_to_term2,
- bad_binary_to_term, bad_terms, t_hash, bad_size, bad_term_to_binary,
- more_bad_terms, otp_5484, otp_5933, ordering, unaligned_order,
- gc_test, bit_sized_binary_sizes, otp_6817, otp_8117,
- deep,obsolete_funs,robustness,otp_8180].
+ bad_list_to_binary, bad_binary_to_list, terms,
+ terms_float, external_size, t_iolist_size,
+ bad_binary_to_term_2, safe_binary_to_term2,
+ bad_binary_to_term, bad_terms, t_hash, bad_size,
+ bad_term_to_binary, more_bad_terms, otp_5484, otp_5933,
+ ordering, unaligned_order, gc_test,
+ bit_sized_binary_sizes, otp_6817, otp_8117, deep,
+ obsolete_funs, robustness, otp_8180].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
- Dog=?t:timetrap(?t:minutes(2)),
- [{watchdog, Dog}|Config].
+ Config.
-fin_per_testcase(_Func, Config) ->
- Dog=?config(watchdog, Config),
- ?t:timetrap_cancel(Dog).
+end_per_testcase(_Func, _Config) ->
+ ok.
-define(heap_binary_size, 64).
@@ -1041,7 +1061,7 @@ test_terms(Test_Func) ->
?line Test_Func(F = fun(A) -> 42*A end),
?line Test_Func(lists:duplicate(32, F)),
- ?line Test_Func(FF = fun binary_SUITE:all/1),
+ ?line Test_Func(FF = fun binary_SUITE:all/0),
?line Test_Func(lists:duplicate(32, FF)),
ok.
@@ -1301,11 +1321,4 @@ unaligned_sub_bin(Bin0, Offs) ->
<<_:Offs,Bin:Sz/binary,_:Roffs>> = id(Bin1),
Bin.
-hostname() ->
- from($@, atom_to_list(node())).
-
-from(H, [H | T]) -> T;
-from(H, [_ | T]) -> from(H, T);
-from(_, []) -> [].
-
id(I) -> I.
diff --git a/erts/emulator/test/bs_bincomp_SUITE.erl b/erts/emulator/test/bs_bincomp_SUITE.erl
index 4e83d97689..c0d64c263e 100644
--- a/erts/emulator/test/bs_bincomp_SUITE.erl
+++ b/erts/emulator/test/bs_bincomp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,15 +22,34 @@
-module(bs_bincomp_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
byte_aligned/1,bit_aligned/1,extended_byte_aligned/1,
extended_bit_aligned/1,mixed/1,tracing/1]).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [byte_aligned, bit_aligned, extended_byte_aligned,
+ extended_bit_aligned, mixed, tracing].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [byte_aligned,bit_aligned,extended_byte_aligned,
- extended_bit_aligned,mixed,tracing].
byte_aligned(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/bs_bit_binaries_SUITE.erl b/erts/emulator/test/bs_bit_binaries_SUITE.erl
index 52bb925385..76d2661592 100644
--- a/erts/emulator/test/bs_bit_binaries_SUITE.erl
+++ b/erts/emulator/test/bs_bit_binaries_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,18 +22,38 @@
-module(bs_bit_binaries_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
misc/1,horrid_match/1,test_bitstr/1,test_bit_size/1,asymmetric_tests/1,
big_asymmetric_tests/1,binary_to_and_from_list/1,
big_binary_to_and_from_list/1,send_and_receive/1,
send_and_receive_alot/1,append/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [misc, horrid_match, test_bitstr, test_bit_size,
+ asymmetric_tests, big_asymmetric_tests,
+ binary_to_and_from_list, big_binary_to_and_from_list,
+ send_and_receive, send_and_receive_alot, append].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [misc,horrid_match,test_bitstr,test_bit_size,asymmetric_tests,
- big_asymmetric_tests,binary_to_and_from_list,big_binary_to_and_from_list,
- send_and_receive,send_and_receive_alot,append].
misc(Config) when is_list(Config) ->
?line <<1:100>> = id(<<1:100>>),
diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl
index 3d9b51d278..dd77278307 100644
--- a/erts/emulator/test/bs_construct_SUITE.erl
+++ b/erts/emulator/test/bs_construct_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,22 +21,39 @@
-module(bs_construct_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
test1/1, test2/1, test3/1, test4/1, test5/1, testf/1,
not_used/1, in_guard/1,
mem_leak/1, coerce_to_float/1, bjorn/1,
huge_float_field/1, huge_binary/1, system_limit/1, badarg/1,
copy_writable_binary/1, kostis/1, dynamic/1, bs_add/1,
- otp_7422/1]).
+ otp_7422/1, zero_width/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [test1, test2, test3, test4, test5, testf,
- not_used, in_guard, mem_leak, coerce_to_float, bjorn,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [test1, test2, test3, test4, test5, testf, not_used,
+ in_guard, mem_leak, coerce_to_float, bjorn,
huge_float_field, huge_binary, system_limit, badarg,
- copy_writable_binary, kostis, dynamic, bs_add,
- otp_7422].
+ copy_writable_binary, kostis, dynamic, bs_add, otp_7422, zero_width].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
big(1) ->
57285702734876389752897683.
@@ -786,5 +803,20 @@ otp_7422_bin(N) when N < 512 ->
end),
otp_7422_bin(N+1);
otp_7422_bin(_) -> ok.
+
+zero_width(Config) when is_list(Config) ->
+ ?line Z = id(0),
+ Small = id(42),
+ Big = id(1 bsl 128),
+ ?line <<>> = <<Small:Z>>,
+ ?line <<>> = <<Small:0>>,
+ ?line <<>> = <<Big:Z>>,
+ ?line <<>> = <<Big:0>>,
+
+ ?line {'EXIT',{badarg,_}} = (catch <<not_a_number:0>>),
+ ?line {'EXIT',{badarg,_}} = (catch <<(id(not_a_number)):Z>>),
+ ?line {'EXIT',{badarg,_}} = (catch <<(id(not_a_number)):0>>),
+
+ ok.
id(I) -> I.
diff --git a/erts/emulator/test/bs_match_bin_SUITE.erl b/erts/emulator/test/bs_match_bin_SUITE.erl
index 3d054a279f..5a028835e6 100644
--- a/erts/emulator/test/bs_match_bin_SUITE.erl
+++ b/erts/emulator/test/bs_match_bin_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,12 +19,32 @@
-module(bs_match_bin_SUITE).
--export([all/1,byte_split_binary/1,bit_split_binary/1,match_huge_bin/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ byte_split_binary/1,bit_split_binary/1,match_huge_bin/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [byte_split_binary, bit_split_binary, match_huge_bin].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [byte_split_binary,bit_split_binary,match_huge_bin].
byte_split_binary(doc) -> "Tries to split a binary at all byte-aligned positions.";
byte_split_binary(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/bs_match_int_SUITE.erl b/erts/emulator/test/bs_match_int_SUITE.erl
index 99dee7c7bc..093ef906c8 100644
--- a/erts/emulator/test/bs_match_int_SUITE.erl
+++ b/erts/emulator/test/bs_match_int_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,16 +18,36 @@
-module(bs_match_int_SUITE).
--export([all/1,integer/1,signed_integer/1,dynamic/1,more_dynamic/1,mml/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ integer/1,signed_integer/1,dynamic/1,more_dynamic/1,mml/1,
match_huge_int/1,bignum/1,unaligned_32_bit/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-import(lists, [seq/2]).
-all(suite) ->
- [integer,signed_integer,dynamic,more_dynamic,mml,match_huge_int,bignum,
- unaligned_32_bit].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [integer, signed_integer, dynamic, more_dynamic, mml,
+ match_huge_int, bignum, unaligned_32_bit].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
integer(Config) when is_list(Config) ->
?line 0 = get_int(mkbin([])),
diff --git a/erts/emulator/test/bs_match_misc_SUITE.erl b/erts/emulator/test/bs_match_misc_SUITE.erl
index 6de2ef67e5..ad21e01f7e 100644
--- a/erts/emulator/test/bs_match_misc_SUITE.erl
+++ b/erts/emulator/test/bs_match_misc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -18,18 +18,38 @@
%%
-module(bs_match_misc_SUITE).
--export([all/1,bound_var/1,bound_tail/1,t_float/1,little_float/1,sean/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ bound_var/1,bound_tail/1,t_float/1,little_float/1,sean/1,
kenneth/1,encode_binary/1,native/1,happi/1,
size_var/1,wiger/1,x0_context/1,huge_float_field/1,
writable_binary_matched/1,otp_7198/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [bound_var, bound_tail, t_float, little_float, sean,
+ kenneth, encode_binary, native, happi, size_var, wiger,
+ x0_context, huge_float_field, writable_binary_matched,
+ otp_7198].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [bound_var,bound_tail,t_float,little_float,sean,
- kenneth,encode_binary,native,happi,
- size_var,wiger,x0_context,huge_float_field,
- writable_binary_matched,otp_7198].
bound_var(doc) -> "Test matching of bound variables.";
bound_var(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/bs_match_tail_SUITE.erl b/erts/emulator/test/bs_match_tail_SUITE.erl
index b0b0779b65..b8f7789f60 100644
--- a/erts/emulator/test/bs_match_tail_SUITE.erl
+++ b/erts/emulator/test/bs_match_tail_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,11 +20,31 @@
-module(bs_match_tail_SUITE).
-author('[email protected]').
--export([all/1,aligned/1,unaligned/1,zero_tail/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,aligned/1,unaligned/1,zero_tail/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [aligned, unaligned, zero_tail].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [aligned,unaligned,zero_tail].
aligned(doc) -> "Test aligned tails.";
aligned(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/bs_utf_SUITE.erl b/erts/emulator/test/bs_utf_SUITE.erl
index 87adc5197b..626a8b4cb6 100644
--- a/erts/emulator/test/bs_utf_SUITE.erl
+++ b/erts/emulator/test/bs_utf_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,13 +19,15 @@
-module(bs_utf_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
utf8_roundtrip/1,utf16_roundtrip/1,utf32_roundtrip/1,
utf8_illegal_sequences/1,utf16_illegal_sequences/1,
utf32_illegal_sequences/1,
bad_construction/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(FAIL(Expr), ?line fail_check(catch Expr, ??Expr, [])).
@@ -33,14 +35,32 @@ init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(6)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog).
-all(suite) ->
- [utf8_roundtrip,utf16_roundtrip,utf32_roundtrip,
- utf8_illegal_sequences,utf16_illegal_sequences,
- utf32_illegal_sequences,bad_construction].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [utf8_roundtrip, utf16_roundtrip, utf32_roundtrip,
+ utf8_illegal_sequences, utf16_illegal_sequences,
+ utf32_illegal_sequences, bad_construction].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
utf8_roundtrip(Config) when is_list(Config) ->
?line utf8_roundtrip(0, 16#D7FF),
diff --git a/erts/emulator/test/busy_port_SUITE.erl b/erts/emulator/test/busy_port_SUITE.erl
index 7350aef4ec..e754d161a3 100644
--- a/erts/emulator/test/busy_port_SUITE.erl
+++ b/erts/emulator/test/busy_port_SUITE.erl
@@ -19,21 +19,40 @@
-module(busy_port_SUITE).
--export([all/1, io_to_busy/1, message_order/1, send_3/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ io_to_busy/1, message_order/1, send_3/1,
system_monitor/1, no_trap_exit/1,
no_trap_exit_unlinked/1, trap_exit/1, multiple_writers/1,
hard_busy_driver/1, soft_busy_driver/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Internal exports.
-export([init/2]).
-all(suite) -> {req, [dynamic_loading],
- [io_to_busy, message_order, send_3,
- system_monitor, no_trap_exit,
- no_trap_exit_unlinked, trap_exit, multiple_writers,
- hard_busy_driver, soft_busy_driver]}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [io_to_busy, message_order, send_3, system_monitor,
+ no_trap_exit, no_trap_exit_unlinked, trap_exit,
+ multiple_writers, hard_busy_driver, soft_busy_driver].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Tests I/O operations to a busy port, to make sure a suspended send
%% operation is correctly restarted. This used to crash Beam.
diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl
index e0528955b0..11e8085cff 100644
--- a/erts/emulator/test/call_trace_SUITE.erl
+++ b/erts/emulator/test/call_trace_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,9 @@
-module(call_trace_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
hipe/1,process_specs/1,basic/1,flags/1,errors/1,pam/1,change_pam/1,
return_trace/1,exception_trace/1,on_load/1,deep_exception/1,
exception_nocatch/1,bit_syntax/1]).
@@ -35,25 +37,44 @@
-export([abbr/1,abbr/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(P, 20).
-all(suite) ->
- Common = [errors,on_load],
- NotHipe = [process_specs,basic,flags,pam,change_pam,return_trace,
- exception_trace,deep_exception,exception_nocatch,bit_syntax],
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ Common = [errors, on_load],
+ NotHipe = [process_specs, basic, flags, pam, change_pam,
+ return_trace, exception_trace, deep_exception,
+ exception_nocatch, bit_syntax],
Hipe = [hipe],
- case test_server:is_native(?MODULE) of
+ case test_server:is_native(call_trace_SUITE) of
true -> Hipe ++ Common;
false -> NotHipe ++ Common
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog = ?t:timetrap(?t:seconds(30)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog).
diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl
index 33351a3cc9..703a00a598 100644
--- a/erts/emulator/test/code_SUITE.erl
+++ b/erts/emulator/test/code_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,18 +18,38 @@
%%
-module(code_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
new_binary_types/1,t_check_process_code/1,t_check_process_code_ets/1,
external_fun/1,get_chunk/1,module_md5/1,make_stub/1,
make_stub_many_funs/1,constant_pools/1,
false_dependency/1,coverage/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [new_binary_types, t_check_process_code,
+ t_check_process_code_ets, external_fun, get_chunk,
+ module_md5, make_stub, make_stub_many_funs,
+ constant_pools, false_dependency, coverage].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [new_binary_types,t_check_process_code,t_check_process_code_ets,
- external_fun,get_chunk,module_md5,make_stub,make_stub_many_funs,
- constant_pools,false_dependency,coverage].
new_binary_types(Config) when is_list(Config) ->
?line Data = ?config(data_dir, Config),
@@ -320,6 +340,9 @@ make_stub(Config) when is_list(Config) ->
(catch code:make_stub_module(my_code_test,
bit_sized_binary(Code),
{[],[]})),
+ ?line {'EXIT',{badarg,_}} =
+ (catch code:make_stub_module(my_code_test_with_wrong_name,
+ Code, {[],[]})),
ok.
make_stub_many_funs(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/crypto_SUITE.erl b/erts/emulator/test/crypto_SUITE.erl
index e3d34b923d..a8cc175303 100644
--- a/erts/emulator/test/crypto_SUITE.erl
+++ b/erts/emulator/test/crypto_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,14 +19,34 @@
-module(crypto_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
t_md5/1,t_md5_update/1,error/1,unaligned_context/1,random_lists/1,
misc_errors/1]).
-all(suite) ->
- [t_md5,t_md5_update,error,unaligned_context,random_lists,misc_errors].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [t_md5, t_md5_update, error, unaligned_context,
+ random_lists, misc_errors].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
misc_errors(doc) ->
diff --git a/erts/emulator/test/crypto_reference.erl b/erts/emulator/test/crypto_reference.erl
index 99107e3b57..b91535a50e 100644
--- a/erts/emulator/test/crypto_reference.erl
+++ b/erts/emulator/test/crypto_reference.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/test/ddll_SUITE.erl b/erts/emulator/test/ddll_SUITE.erl
index 79047d7de5..ef607bf407 100644
--- a/erts/emulator/test/ddll_SUITE.erl
+++ b/erts/emulator/test/ddll_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -30,7 +30,8 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--export([all/1, ddll_test/1, errors/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, ddll_test/1, errors/1,
reference_count/1,
kill_port/1, dont_kill_port/1]).
-export([unload_on_process_exit/1, delayed_unload_with_ports/1,
@@ -50,35 +51,39 @@
-import(ordsets, [subtract/2]).
--include("test_server.hrl").
-
-all(suite) ->
- [ddll_test, errors,
- reference_count,
- kill_port,
- dont_kill_port,
- properties,
- load_and_unload,
- unload_on_process_exit,
- delayed_unload_with_ports,
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [ddll_test, errors, reference_count, kill_port,
+ dont_kill_port, properties, load_and_unload,
+ unload_on_process_exit, delayed_unload_with_ports,
unload_due_to_process_exit,
- no_unload_due_to_process_exit,
- no_unload_due_to_process_exit_2,
- unload_reload_thingie,
- unload_reload_thingie_2,
- unload_reload_thingie_3,
- reload_pending,
- load_fail_init,
- reload_pending_fail_init,
- reload_pending_kill,
- more_error_codes,
- forced_port_killing,
- no_trap_exit_and_kill_ports,
- monitor_demonitor,
- monitor_demonitor_load,
- new_interface,
- lock_driver
- ].
+ no_unload_due_to_process_exit,
+ no_unload_due_to_process_exit_2, unload_reload_thingie,
+ unload_reload_thingie_2, unload_reload_thingie_3,
+ reload_pending, load_fail_init,
+ reload_pending_fail_init, reload_pending_kill,
+ more_error_codes, forced_port_killing,
+ no_trap_exit_and_kill_ports, monitor_demonitor,
+ monitor_demonitor_load, new_interface, lock_driver].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
unload_on_process_exit(suite) ->
[];
diff --git a/erts/emulator/test/decode_packet_SUITE.erl b/erts/emulator/test/decode_packet_SUITE.erl
index d9e961be2f..97ab470a3e 100644
--- a/erts/emulator/test/decode_packet_SUITE.erl
+++ b/erts/emulator/test/decode_packet_SUITE.erl
@@ -21,14 +21,34 @@
-module(decode_packet_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
basic/1, packet_size/1, neg/1, http/1, line/1, ssl/1, otp_8536/1]).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[basic, packet_size, neg, http, line, ssl, otp_8536].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Seed = {S1,S2,S3} = now(),
random:seed(S1,S2,S3),
@@ -36,7 +56,7 @@ init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(1)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
diff --git a/erts/emulator/test/dgawd_handler.erl b/erts/emulator/test/dgawd_handler.erl
index 881354b9da..27085b7b7e 100644
--- a/erts/emulator/test/dgawd_handler.erl
+++ b/erts/emulator/test/dgawd_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index 7c19274696..d62eb00919 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -22,45 +22,71 @@
%% Tests distribution and the tcp driver.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
- ping/1, bulk_send/1, bulk_send_small/1,
- bulk_send_big/1,
- local_send/1, local_send_small/1, local_send_big/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ ping/1, bulk_send_small/1,
+ bulk_send_big/1, bulk_send_bigbig/1,
+ local_send_small/1, local_send_big/1,
local_send_legal/1, link_to_busy/1, exit_to_busy/1,
lost_exit/1, link_to_dead/1, link_to_dead_new_node/1,
applied_monitor_node/1, ref_port_roundtrip/1, nil_roundtrip/1,
- trap_bif/1, trap_bif_1/1, trap_bif_2/1, trap_bif_3/1,
- stop_dist/1, dist_auto_connect/1,
+ trap_bif_1/1, trap_bif_2/1, trap_bif_3/1,
+ stop_dist/1,
dist_auto_connect_never/1, dist_auto_connect_once/1,
dist_parallel_send/1,
atom_roundtrip/1,
atom_roundtrip_r12b/1,
contended_atom_cache_entry/1,
- bad_dist_ext/1,
+ bad_dist_structure/1,
bad_dist_ext_receive/1,
bad_dist_ext_process_info/1,
bad_dist_ext_control/1,
bad_dist_ext_connection_id/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%% Internal exports.
-export([sender/3, receiver2/2, dummy_waiter/0, dead_process/0,
roundtrip/1, bounce/1, do_dist_auto_connect/1, inet_rpc_server/1,
dist_parallel_sender/3, dist_parallel_receiver/0,
- dist_evil_parallel_receiver/0]).
-
-all(suite) -> [
- ping, bulk_send, local_send, link_to_busy, exit_to_busy,
- lost_exit, link_to_dead, link_to_dead_new_node,
- applied_monitor_node, ref_port_roundtrip, nil_roundtrip,
- stop_dist, trap_bif, dist_auto_connect, dist_parallel_send,
- atom_roundtrip, atom_roundtrip_r12b,
- contended_atom_cache_entry,
- bad_dist_ext
- ].
+ dist_evil_parallel_receiver/0,
+ sendersender/4, sendersender2/4]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [ping, {group, bulk_send}, {group, local_send},
+ link_to_busy, exit_to_busy, lost_exit, link_to_dead,
+ link_to_dead_new_node, applied_monitor_node,
+ ref_port_roundtrip, nil_roundtrip, stop_dist,
+ {group, trap_bif}, {group, dist_auto_connect},
+ dist_parallel_send, atom_roundtrip, atom_roundtrip_r12b,
+ contended_atom_cache_entry, bad_dist_structure, {group, bad_dist_ext}].
+
+groups() ->
+ [{bulk_send, [], [bulk_send_small, bulk_send_big, bulk_send_bigbig]},
+ {local_send, [],
+ [local_send_small, local_send_big, local_send_legal]},
+ {trap_bif, [], [trap_bif_1, trap_bif_2, trap_bif_3]},
+ {dist_auto_connect, [],
+ [dist_auto_connect_never, dist_auto_connect_once]},
+ {bad_dist_ext, [],
+ [bad_dist_ext_receive, bad_dist_ext_process_info,
+ bad_dist_ext_control, bad_dist_ext_connection_id]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-define(DEFAULT_TIMETRAP, 4*60*1000).
@@ -68,7 +94,7 @@ init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?DEFAULT_TIMETRAP),
[{watchdog, Dog},{testcase, Func}|Config].
-fin_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+end_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
@@ -116,19 +142,15 @@ ping(Config) when is_list(Config) ->
ok.
-bulk_send(doc) ->
- ["Tests sending large amount of data to another node and measure",
- "the time. This tests that a process that is suspended on a ",
- "busy port will eventually be resumed."];
-bulk_send(suite) ->
- [bulk_send_small, bulk_send_big].
-
bulk_send_small(Config) when is_list(Config) ->
?line bulk_send(64, 32).
bulk_send_big(Config) when is_list(Config) ->
?line bulk_send(32, 64).
+bulk_send_bigbig(Config) when is_list(Config) ->
+ ?line bulk_sendsend(32*5, 4).
+
bulk_send(Terms, BinSize) ->
?line Dog = test_server:timetrap(test_server:seconds(30)),
@@ -145,6 +167,53 @@ bulk_send(Terms, BinSize) ->
?line test_server:timetrap_cancel(Dog),
{comment, integer_to_list(trunc(Size/1024/Elapsed+0.5)) ++ " K/s"}.
+bulk_sendsend(Terms, BinSize) ->
+ {Rate1, MonitorCount1} = bulk_sendsend2(Terms, BinSize, 5),
+ {Rate2, MonitorCount2} = bulk_sendsend2(Terms, BinSize, 995),
+ Ratio = if MonitorCount2 == 0 -> MonitorCount1 / 1.0;
+ true -> MonitorCount1 / MonitorCount2
+ end,
+ %% A somewhat arbitrary ratio, but hopefully one that will accomodate
+ %% a wide range of CPU speeds.
+ true = (Ratio > 8.0),
+ {comment,
+ integer_to_list(Rate1) ++ " K/s, " ++
+ integer_to_list(Rate2) ++ " K/s, " ++
+ integer_to_list(MonitorCount1) ++ " monitor msgs, " ++
+ integer_to_list(MonitorCount2) ++ " monitor msgs, " ++
+ float_to_list(Ratio) ++ " monitor ratio"}.
+
+bulk_sendsend2(Terms, BinSize, BusyBufSize) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(30)),
+
+ ?line io:format("Sending ~w binaries, each of size ~w K",
+ [Terms, BinSize]),
+ ?line {ok, NodeRecv} = start_node(bulk_receiver),
+ ?line Recv = spawn(NodeRecv, erlang, apply, [fun receiver/2, [0, 0]]),
+ ?line Bin = list_to_binary(lists:duplicate(BinSize*1024, 253)),
+ %%?line Size = Terms*size(Bin),
+
+ %% SLF LEFT OFF HERE.
+ %% When the caller uses small hunks, like 4k via
+ %% bulk_sendsend(32*5, 4), then (on my laptop at least), we get
+ %% zero monitor messages. But if we use "+zdbbl 5", then we
+ %% get a lot of monitor messages. So, if we can count up the
+ %% total number of monitor messages that we get when running both
+ %% default busy size and "+zdbbl 5", and if the 5 case gets
+ %% "many many more" monitor messages, then we know we're working.
+
+ ?line {ok, NodeSend} = start_node(bulk_sender, "+zdbbl " ++ integer_to_list(BusyBufSize)),
+ ?line _Send = spawn(NodeSend, erlang, apply, [fun sendersender/4, [self(), Recv, Bin, Terms]]),
+ ?line {Elapsed, {_TermsN, SizeN}, MonitorCount} =
+ receive {sendersender, BigRes} ->
+ BigRes
+ end,
+ ?line stop_node(NodeRecv),
+ ?line stop_node(NodeSend),
+
+ ?line test_server:timetrap_cancel(Dog),
+ {trunc(SizeN/1024/Elapsed+0.5), MonitorCount}.
+
sender(To, _Bin, 0) ->
To ! {done, self()},
receive
@@ -155,6 +224,43 @@ sender(To, Bin, Left) ->
To ! {term, Bin},
sender(To, Bin, Left-1).
+%% Sender process to be run on a slave node
+
+sendersender(Parent, To, Bin, Left) ->
+ erlang:system_monitor(self(), [busy_dist_port]),
+ [spawn(fun() -> sendersender2(To, Bin, Left, false) end) ||
+ _ <- lists:seq(1,1)],
+ {USec, {Res, MonitorCount}} =
+ timer:tc(?MODULE, sendersender2, [To, Bin, Left, true]),
+ Parent ! {sendersender, {USec/1000000, Res, MonitorCount}}.
+
+sendersender2(To, Bin, Left, SendDone) ->
+ sendersender3(To, Bin, Left, SendDone, 0).
+
+sendersender3(To, _Bin, 0, SendDone, MonitorCount) ->
+ if SendDone ->
+ To ! {done, self()};
+ true ->
+ ok
+ end,
+ receive
+ {monitor, _Pid, _Type, _Info} ->
+ sendersender3(To, _Bin, 0, SendDone, MonitorCount + 1)
+ after 0 ->
+ if SendDone ->
+ receive
+ Any when is_tuple(Any), size(Any) == 2 ->
+ {Any, MonitorCount}
+ end;
+ true ->
+ exit(normal)
+ end
+ end;
+sendersender3(To, Bin, Left, SendDone, MonitorCount) ->
+ To ! {term, Bin},
+ %%timer:sleep(50),
+ sendersender3(To, Bin, Left-1, SendDone, MonitorCount).
+
%% Receiver process to be run on a slave node.
receiver(Terms, Size) ->
@@ -166,17 +272,14 @@ receiver(Terms, Size) ->
end.
-local_send(suite) ->
- [local_send_small, local_send_big, local_send_legal];
-local_send(doc) ->
- ["Tests sending small and big messages to a non-existing ",
- "local registered process."].
local_send_big(doc) ->
["Sends several big message to an non-registered process on ",
"the local node."];
local_send_big(Config) when is_list(Config) ->
- Data0=local_send_big(doc)++local_send(doc),
+ Data0=local_send_big(doc)++
+ ["Tests sending small and big messages to a non-existing ",
+ "local registered process."],
Data1=[Data0,[Data0, Data0, [Data0], Data0],Data0],
Data2=Data0++lists:flatten(Data1)++
list_to_binary(lists:flatten(Data1)),
@@ -433,7 +536,7 @@ sink1() ->
lost_exit(doc) ->
"Test that EXIT and DOWN messages send to another node are not lost if "
- "if the distribution port is busy.";
+ "the distribution port is busy.";
lost_exit(Config) when is_list(Config) ->
?line {ok, Node} = start_node(lost_exit),
@@ -662,9 +765,6 @@ stop_dist(Config) when is_list(Config) ->
ok.
-trap_bif(doc) ->
- ["Verifies that BIFs which are traps to Erlang work (OTP-2680)."];
-trap_bif(suite) -> [trap_bif_1, trap_bif_2, trap_bif_3].
trap_bif_1(doc) ->
[""];
@@ -701,10 +801,6 @@ tr3() ->
-dist_auto_connect(doc) ->
- ["Tests the kernel parameter 'dist_auto_connect'."];
-dist_auto_connect(suite) ->
- [dist_auto_connect_never, dist_auto_connect_once].
% This has to be done by nodes with differrent cookies, otherwise global
% will connect nodes, which is correct, but makes it hard to test.
@@ -1054,8 +1150,7 @@ contended_atom_cache_entry(Config) when is_list(Config) ->
?line {ok, SNode} = start_node(Config),
?line {ok, RNode} = start_node(Config),
?line Success = make_ref(),
- ?line Mstr
- = spawn_link(
+ ?line spawn_link(
SNode,
fun () ->
erts_debug:set_internal_state(available_internal_state,
@@ -1112,13 +1207,13 @@ contended_atom_cache_entry(Config) when is_list(Config) ->
?line stop_node(RNode),
?line ok.
-send_ref_atom(To, Ref, Atom, 0) ->
+send_ref_atom(_To, _Ref, _Atom, 0) ->
ok;
send_ref_atom(To, Ref, Atom, N) ->
To ! {Ref, Atom},
send_ref_atom(To, Ref, Atom, N-1).
-receive_ref_atom(Ref, Atom, 0) ->
+receive_ref_atom(_Ref, _Atom, 0) ->
ok;
receive_ref_atom(Ref, Atom, N) ->
receive
@@ -1153,7 +1248,7 @@ unwanted_cixs() ->
nodes()).
-get_conflicting_atoms(CIX, 0) ->
+get_conflicting_atoms(_CIX, 0) ->
[];
get_conflicting_atoms(CIX, N) ->
{A, B, C} = now(),
@@ -1167,13 +1262,187 @@ get_conflicting_atoms(CIX, N) ->
get_conflicting_atoms(CIX, N)
end.
+-define(COOKIE, '').
+-define(DOP_LINK, 1).
+-define(DOP_SEND, 2).
+-define(DOP_EXIT, 3).
+-define(DOP_UNLINK, 4).
+-define(DOP_REG_SEND, 6).
+-define(DOP_GROUP_LEADER, 7).
+-define(DOP_EXIT2, 8).
+
+-define(DOP_SEND_TT, 12).
+-define(DOP_EXIT_TT, 13).
+-define(DOP_REG_SEND_TT, 16).
+-define(DOP_EXIT2_TT, 18).
+
+-define(DOP_MONITOR_P, 19).
+-define(DOP_DEMONITOR_P, 20).
+-define(DOP_MONITOR_P_EXIT, 21).
+
+start_monitor(Offender,P) ->
+ ?line Parent = self(),
+ ?line Q = spawn(Offender,
+ fun () ->
+ Ref = erlang:monitor(process,P),
+ Parent ! {self(),ref,Ref},
+ receive
+ just_stay_alive -> ok
+ end
+ end),
+ ?line Ref = receive
+ {Q,ref,R} ->
+ R
+ after 5000 ->
+ error
+ end,
+ io:format("Ref is ~p~n",[Ref]),
+ ok.
+start_link(Offender,P) ->
+ ?line Parent = self(),
+ ?line Q = spawn(Offender,
+ fun () ->
+ process_flag(trap_exit,true),
+ link(P),
+ Parent ! {self(),ref,P},
+ receive
+ just_stay_alive -> ok
+ end
+ end),
+ ?line Ref = receive
+ {Q,ref,R} ->
+ R
+ after 5000 ->
+ error
+ end,
+ io:format("Ref is ~p~n",[Ref]),
+ ok.
+
+bad_dist_structure(suite) ->
+ [];
+bad_dist_structure(doc) ->
+ ["Test dist messages with valid structure (binary to term ok) but malformed"
+ "control content"];
+bad_dist_structure(Config) when is_list(Config) ->
+ %process_flag(trap_exit,true),
+ ODog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(ODog),
+ Dog = ?t:timetrap(?t:seconds(15)),
+
+ ?line {ok, Offender} = start_node(bad_dist_structure_offender),
+ ?line {ok, Victim} = start_node(bad_dist_structure_victim),
+ ?line start_node_monitors([Offender,Victim]),
+ ?line Parent = self(),
+ ?line P = spawn(Victim,
+ fun () ->
+ process_flag(trap_exit,true),
+ Parent ! {self(), started},
+ receive check_msgs -> ok end,
+ bad_dist_struct_check_msgs([one,
+ two]),
+ Parent ! {self(), messages_checked},
+ receive done -> ok end
+ end),
+ ?line receive {P, started} -> ok end,
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line verify_up(Offender, Victim),
+ ?line true = lists:member(Offender, rpc:call(Victim, erlang, nodes, [])),
+ ?line start_monitor(Offender,P),
+ ?line P ! one,
+ ?line send_bad_structure(Offender, P,{?DOP_MONITOR_P_EXIT,'replace',P,normal},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_monitor(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_MONITOR_P_EXIT,'replace',P,normal,normal},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_link(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_LINK},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_link(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_UNLINK,'replace'},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_link(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_UNLINK,'replace',make_ref()},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_link(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_UNLINK,make_ref(),P},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_link(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_UNLINK,normal,normal},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_monitor(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_MONITOR_P,'replace',P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_monitor(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_MONITOR_P,'replace',P,normal},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_monitor(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_DEMONITOR_P,'replace',P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_monitor(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_DEMONITOR_P,'replace',P,normal},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT,'replace',P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT,make_ref(),normal,normal},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT_TT,'replace',token,P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT_TT,make_ref(),token,normal,normal},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT2,'replace',P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT2,make_ref(),normal,normal},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT2_TT,'replace',token,P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT2_TT,make_ref(),token,normal,normal},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_GROUP_LEADER,'replace'},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_GROUP_LEADER,'replace','atomic'},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_GROUP_LEADER,'replace',P},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND_TT,'replace','',name},2,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND_TT,'replace','',name,token},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace',''},2,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace','',P},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace','',name},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace','',name,{token}},2,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_SEND_TT,'',P},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_SEND_TT,'',name,token},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_SEND,''},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_SEND,'',name},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_SEND,'',P,{token}},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line P ! two,
+ ?line P ! check_msgs,
+ ?line receive
+ {P, messages_checked} -> ok
+ after 5000 ->
+ exit(victim_is_dead)
+ end,
+
+ ?line {message_queue_len, 0}
+ = rpc:call(Victim, erlang, process_info, [P, message_queue_len]),
+
+ ?line unlink(P),
+ ?line P ! done,
+ ?line stop_node(Offender),
+ ?line stop_node(Victim),
+ ?t:timetrap_cancel(Dog),
+ ok.
-bad_dist_ext(doc) -> [];
-bad_dist_ext(suite) ->
- [bad_dist_ext_receive,
- bad_dist_ext_process_info,
- bad_dist_ext_control,
- bad_dist_ext_connection_id].
bad_dist_ext_receive(Config) when is_list(Config) ->
@@ -1394,6 +1663,22 @@ bad_dist_ext_connection_id(Config) when is_list(Config) ->
?line stop_node(Victim).
+bad_dist_struct_check_msgs([]) ->
+ receive
+ Msg ->
+ exit({unexpected_message, Msg})
+ after 0 ->
+ ok
+ end;
+bad_dist_struct_check_msgs([M|Ms]) ->
+ receive
+ {'EXIT',_,_} = EM ->
+ io:format("Ignoring exit message: ~p~n",[EM]),
+ bad_dist_struct_check_msgs([M|Ms]);
+ Msg ->
+ M = Msg,
+ bad_dist_struct_check_msgs(Ms)
+ end.
bad_dist_ext_check_msgs([]) ->
receive
Msg ->
@@ -1408,24 +1693,6 @@ bad_dist_ext_check_msgs([M|Ms]) ->
bad_dist_ext_check_msgs(Ms)
end.
--define(COOKIE, '').
--define(DOP_LINK, 1).
--define(DOP_SEND, 2).
--define(DOP_EXIT, 3).
--define(DOP_UNLINK, 4).
--define(DOP_NODE_LINK, 5).
--define(DOP_REG_SEND, 6).
--define(DOP_GROUP_LEADER, 7).
--define(DOP_EXIT2, 8).
-
--define(DOP_SEND_TT, 12).
--define(DOP_EXIT_TT, 13).
--define(DOP_REG_SEND_TT, 16).
--define(DOP_EXIT2_TT, 18).
-
--define(DOP_MONITOR_P, 19).
--define(DOP_DEMONITOR_P, 20).
--define(DOP_MONITOR_P_EXIT, 21).
dport_reg_send(Node, Name, Msg) ->
DPrt = case dport(Node) of
@@ -1457,6 +1724,39 @@ dport_send(To, Msg) ->
?COOKIE,
To}),
dmsg_ext(Msg)]).
+send_bad_structure(Offender,Victim,Bad,WhereToPutSelf) ->
+ send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,[]).
+send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,PayLoad) ->
+ Parent = self(),
+ Done = make_ref(),
+ spawn(Offender,
+ fun () ->
+ Node = node(Victim),
+ pong = net_adm:ping(Node),
+ DPrt = dport(Node),
+ Bad1 = case WhereToPutSelf of
+ 0 ->
+ Bad;
+ N when N > 0 ->
+ setelement(N,Bad,self())
+ end,
+ DData = [dmsg_hdr(),
+ dmsg_ext(Bad1)] ++
+ case PayLoad of
+ [] -> [];
+ _Other -> [dmsg_ext(PayLoad)]
+ end,
+ port_command(DPrt, DData),
+ Parent ! {DData,Done}
+ end),
+ receive
+ {WhatSent,Done} ->
+ io:format("Offender sent ~p~n",[WhatSent]),
+ ok
+ after 5000 ->
+ exit(unable_to_send)
+ end.
+
%% send_bad_msgs():
%% Send a valid distribution header and control message
@@ -1540,10 +1840,10 @@ dmsg_bad_hdr() ->
255]. % 255 atom references
-dmsg_fake_hdr1() ->
- A = <<"fake header atom 1">>,
- [131, % Version Magic
- $D, 1, 16#8, 0, size(A), A]. % Fake header
+%% dmsg_fake_hdr1() ->
+%% A = <<"fake header atom 1">>,
+%% [131, % Version Magic
+%% $D, 1, 16#8, 0, size(A), A]. % Fake header
dmsg_fake_hdr2() ->
A1 = <<"fake header atom 1">>,
@@ -1728,7 +2028,7 @@ flush_node_changes() ->
node_monitor_loop(Master) ->
receive
- {nodeup, Node, InfoList} = Msg ->
+ {nodeup, Node, _InfoList} = Msg ->
Master ! {nodeup, node(), Node},
?t:format("~p ~p: ~p~n", [node(), erlang:now(), Msg]),
node_monitor_loop(Master);
@@ -1765,9 +2065,9 @@ verify_no_down(A, B) ->
ok
end.
-verify_down(A, B) ->
- receive {nodedown, A, B, _} -> ok end,
- receive {nodedown, B, A, _} -> ok end.
+%% verify_down(A, B) ->
+%% receive {nodedown, A, B, _} -> ok end,
+%% receive {nodedown, B, A, _} -> ok end.
verify_down(A, ReasonA, B, ReasonB) ->
receive
@@ -1787,11 +2087,11 @@ from(H, [H | T]) -> T;
from(H, [_ | T]) -> from(H, T);
from(_, []) -> [].
-fun_spawn(Fun) ->
- fun_spawn(Fun, []).
+%% fun_spawn(Fun) ->
+%% fun_spawn(Fun, []).
-fun_spawn(Fun, Args) ->
- spawn_link(erlang, apply, [Fun, Args]).
+%% fun_spawn(Fun, Args) ->
+%% spawn_link(erlang, apply, [Fun, Args]).
long_or_short() ->
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl
index 39b2ed395f..7600a44988 100644
--- a/erts/emulator/test/driver_SUITE.erl
+++ b/erts/emulator/test/driver_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -27,12 +27,12 @@
%%% - queueing
-module(driver_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1,
+ end_per_suite/1, init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
- end_per_suite/1,
+ end_per_testcase/2,
outputv_echo/1,
- timer/1,
+
timer_measure/1,
timer_cancel/1,
timer_change/1,
@@ -51,7 +51,7 @@
'driver_system_info_ver1.1'/1,
driver_system_info_current_ver/1,
driver_monitor/1,
- ioq_exit/1,
+
ioq_exit_ready_input/1,
ioq_exit_ready_output/1,
ioq_exit_timeout/1,
@@ -78,7 +78,7 @@
-export([bin_prefix/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% First byte in communication with the timer driver
@@ -120,49 +120,51 @@ init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
?line 0 = erts_debug:get_internal_state(check_io_debug),
[{watchdog, Dog},{testcase, Case}|Config].
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
Dog = ?config(watchdog, Config),
- erlang:display({fin_per_testcase, Case}),
+ erlang:display({end_per_testcase, Case}),
?line 0 = erts_debug:get_internal_state(check_io_debug),
?t:timetrap_cancel(Dog).
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [fun_to_port, outputv_echo, queue_echo, {group, timer},
+ driver_unloaded, io_ready_exit, use_fallback_pollset,
+ bad_fd_in_pollset, driver_event, fd_change,
+ steal_control, otp_6602, 'driver_system_info_ver1.0',
+ 'driver_system_info_ver1.1',
+ driver_system_info_current_ver, driver_monitor,
+ {group, ioq_exit}, zero_extended_marker_garb_drv,
+ invalid_extended_marker_drv, larger_major_vsn_drv,
+ larger_minor_vsn_drv, smaller_major_vsn_drv,
+ smaller_minor_vsn_drv, peek_non_existing_queue,
+ otp_6879, caller, many_events, missing_callbacks,
+ smp_select, driver_select_use,
+ thread_mseg_alloc_cache_clean].
+
+groups() ->
+ [{timer, [],
+ [timer_measure, timer_cancel, timer_delay,
+ timer_change]},
+ {ioq_exit, [],
+ [ioq_exit_ready_input, ioq_exit_ready_output,
+ ioq_exit_timeout, ioq_exit_ready_async, ioq_exit_event,
+ ioq_exit_ready_input_async, ioq_exit_ready_output_async,
+ ioq_exit_timeout_async, ioq_exit_event_async]}].
+
+init_per_suite(Config) ->
+ Config.
+
end_per_suite(_Config) ->
catch erts_debug:set_internal_state(available_internal_state, false).
-all(suite) ->
- [
- fun_to_port,
- outputv_echo,
- queue_echo,
- timer,
- driver_unloaded,
- io_ready_exit,
- use_fallback_pollset,
- bad_fd_in_pollset,
- driver_event,
- fd_change,
- steal_control,
- otp_6602,
- 'driver_system_info_ver1.0',
- 'driver_system_info_ver1.1',
- driver_system_info_current_ver,
- driver_monitor,
- ioq_exit,
- zero_extended_marker_garb_drv,
- invalid_extended_marker_drv,
- larger_major_vsn_drv,
- larger_minor_vsn_drv,
- smaller_major_vsn_drv,
- smaller_minor_vsn_drv,
- peek_non_existing_queue,
- otp_6879,
- caller,
- many_events,
- missing_callbacks,
- smp_select,
- driver_select_use,
- thread_mseg_alloc_cache_clean
- ].
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
fun_to_port(doc) -> "Test sending a fun to port with an outputv-capable driver.";
fun_to_port(Config) when is_list(Config) ->
@@ -308,7 +310,6 @@ compare(Got, Expected) ->
%% Driver timer test suites
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-timer(suite) -> [timer_measure,timer_cancel,timer_delay,timer_change].
timer_measure(doc) -> ["Check that timers time out in good time."];
timer_measure(Config) when is_list(Config) ->
@@ -1299,17 +1300,6 @@ driver_monitor(Config) when is_list(Config) ->
?line stop_driver(Port, Name),
?line ok.
-ioq_exit(doc) -> [];
-ioq_exit(suite) ->
- [ioq_exit_ready_input,
- ioq_exit_ready_output,
- ioq_exit_timeout,
- ioq_exit_ready_async,
- ioq_exit_event,
- ioq_exit_ready_input_async,
- ioq_exit_ready_output_async,
- ioq_exit_timeout_async,
- ioq_exit_event_async].
-define(IOQ_EXIT_READY_INPUT, 1).
-define(IOQ_EXIT_READY_OUTPUT, 2).
@@ -1682,7 +1672,7 @@ smp_select0(Config) ->
ProcFun = fun()-> io:format("Worker ~p starting\n",[self()]),
?line Port = open_port({spawn, DrvName}, []),
smp_select_loop(Port, 100000),
- sleep(500), % wait for driver to handle pending events
+ sleep(1000), % wait for driver to handle pending events
?line true = erlang:port_close(Port),
Master ! {ok,self()},
io:format("Worker ~p finished\n",[self()])
@@ -1790,8 +1780,8 @@ mseg_alloc_ccc() ->
mseg_alloc_ccc(erlang:system_info({allocator,mseg_alloc})).
mseg_alloc_ccc(MsegAllocInfo) ->
- ?line {value,{calls, CL}}
- = lists:keysearch(calls, 1, MsegAllocInfo),
+ ?line {value,{memkind, MKL}} = lists:keysearch(memkind,1,MsegAllocInfo),
+ ?line {value,{calls, CL}} = lists:keysearch(calls, 1, MKL),
?line {value,{mseg_check_cache, GigaCCC, CCC}}
= lists:keysearch(mseg_check_cache, 1, CL),
?line GigaCCC*1000000000 + CCC.
@@ -1800,12 +1790,28 @@ mseg_alloc_cached_segments() ->
mseg_alloc_cached_segments(erlang:system_info({allocator,mseg_alloc})).
mseg_alloc_cached_segments(MsegAllocInfo) ->
+ MemName = case is_halfword_vm() of
+ true -> "high memory";
+ false -> "all memory"
+ end,
+ ?line [{memkind,DrvMem}]
+ = lists:filter(fun(E) -> case E of
+ {memkind, [{name, MemName} | _]} -> true;
+ _ -> false
+ end end, MsegAllocInfo),
?line {value,{status, SL}}
- = lists:keysearch(status, 1, MsegAllocInfo),
+ = lists:keysearch(status, 1, DrvMem),
?line {value,{cached_segments, CS}}
= lists:keysearch(cached_segments, 1, SL),
?line CS.
+is_halfword_vm() ->
+ case {erlang:system_info({wordsize, internal}),
+ erlang:system_info({wordsize, external})} of
+ {4, 8} -> true;
+ {WS, WS} -> false
+ end.
+
driver_alloc_sbct() ->
{_, _, _, As} = erlang:system_info(allocator),
case lists:keysearch(driver_alloc, 1, As) of
diff --git a/erts/emulator/test/driver_SUITE_data/chkio_drv.c b/erts/emulator/test/driver_SUITE_data/chkio_drv.c
index b571cb30e6..bbdb09cfcb 100644
--- a/erts/emulator/test/driver_SUITE_data/chkio_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/chkio_drv.c
@@ -102,6 +102,7 @@ typedef struct chkio_smp_select {
int write_fd;
int next_read;
int next_write;
+ int first_write;
enum {Closed, Opened, Selected, Waiting} state;
int wasSelected;
unsigned rand_state;
@@ -577,9 +578,16 @@ chkio_drv_ready_input(ErlDrvData drv_data, ErlDrvEvent event)
inPipe = (pip->next_write - pip->next_read);
if (inPipe == 0) {
bytes = read(pip->read_fd, &word, sizeof(word));
- printf("Unexpected empty pipe, expected %u -> %u, bytes=%d, word=%d\n",
- pip->next_read, pip->next_write-1, bytes, word);
- abort();
+ printf("Unexpected empty pipe, expected %u -> %u, bytes=%d, word=%d, written=%d\n",
+ pip->next_read, pip->next_write-1, bytes, word,
+ (pip->next_write - pip->first_write));
+ /*abort();
+ Allow unexpected events as it's been seen to be triggered by epoll
+ on Linux. Most of the time the unwanted events are filtered by
+ the erl_check_io layer. But when fd's are reused the events may
+ slip up to the driver.
+ */
+ break;
}
n = rand_r(&pip->rand_state) % (inPipe*4);
@@ -1252,6 +1260,7 @@ chkio_drv_control(ErlDrvData drv_data,
pip->state = Opened;
pip->wasSelected = 0;
pip->next_write = pip->next_read = rand_r(&pip->rand_state) % 1024;
+ pip->first_write = pip->next_write;
if (op & 1) break;
op >>= 1;
}/*fall through*/
diff --git a/erts/emulator/test/efile_SUITE.erl b/erts/emulator/test/efile_SUITE.erl
index 1d66b6ef70..0cac0636e0 100644
--- a/erts/emulator/test/efile_SUITE.erl
+++ b/erts/emulator/test/efile_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -17,12 +17,32 @@
%% %CopyrightEnd%
-module(efile_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([iter_max_files/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [iter_max_files].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [iter_max_files].
%%
%% Open as many files as possible. Do this several times and check
diff --git a/erts/emulator/test/emulator.spec b/erts/emulator/test/emulator.spec
index ed5bd48e84..1ea751cc3b 100644
--- a/erts/emulator/test/emulator.spec
+++ b/erts/emulator/test/emulator.spec
@@ -1 +1 @@
-{topcase, {dir, "../emulator_test"}}.
+{suites,"../emulator_test",all}.
diff --git a/erts/emulator/test/erl_drv_thread_SUITE.erl b/erts/emulator/test/erl_drv_thread_SUITE.erl
index ea618e9feb..bc9e610af3 100644
--- a/erts/emulator/test/erl_drv_thread_SUITE.erl
+++ b/erts/emulator/test/erl_drv_thread_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -19,18 +19,36 @@
-module(erl_drv_thread_SUITE).
-author('[email protected]').
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([basic/1, rwlock/1, tsd/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(DEFAULT_TIMETRAP_SECS, 240).
-all(doc) -> [];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[basic, rwlock, tsd].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%
%% Testcases %%
diff --git a/erts/emulator/test/erl_link_SUITE.erl b/erts/emulator/test/erl_link_SUITE.erl
index 542c8dffbe..84d17c9596 100644
--- a/erts/emulator/test/erl_link_SUITE.erl
+++ b/erts/emulator/test/erl_link_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -28,9 +28,10 @@
-author('[email protected]').
%-define(line_trace, 1).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
% Test cases
-export([links/1,
@@ -46,7 +47,7 @@
otp_5772_dist_monitor/1,
otp_7946/1]).
--export([init_per_testcase/2, fin_per_testcase/2, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
% Internal exports
-export([test_proc/0]).
@@ -77,11 +78,29 @@
-all(suite) -> [links, dist_links, monitor_nodes, process_monitors,
- dist_process_monitors, busy_dist_port_monitor,
- busy_dist_port_link, otp_5772_link, otp_5772_dist_link,
- otp_5772_monitor, otp_5772_dist_monitor,
- otp_7946].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [links, dist_links, monitor_nodes, process_monitors,
+ dist_process_monitors, busy_dist_port_monitor,
+ busy_dist_port_link, otp_5772_link, otp_5772_dist_link,
+ otp_5772_monitor, otp_5772_dist_monitor, otp_7946].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ catch erts_debug:set_internal_state(available_internal_state, false).
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
links(doc) -> ["Tests node local links"];
links(suite) -> [];
@@ -678,13 +697,10 @@ init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
end,
?line [{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
?line Dog = ?config(watchdog, Config),
?line ?t:timetrap_cancel(Dog).
-end_per_suite(_Config) ->
- catch erts_debug:set_internal_state(available_internal_state, false).
-
tp_call(Tp, Fun) ->
?line R = make_ref(),
?line Tp ! {call, self(), R, Fun},
@@ -1050,7 +1066,6 @@ stop_node(Node) ->
-define(DOP_SEND, 2).
-define(DOP_EXIT, 3).
-define(DOP_UNLINK, 4).
--define(DOP_NODE_LINK, 5).
-define(DOP_REG_SEND, 6).
-define(DOP_GROUP_LEADER, 7).
-define(DOP_EXIT2, 8).
diff --git a/erts/emulator/test/erts_debug_SUITE.erl b/erts/emulator/test/erts_debug_SUITE.erl
index e60a999df1..9a6a6f4c05 100644
--- a/erts/emulator/test/erts_debug_SUITE.erl
+++ b/erts/emulator/test/erts_debug_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -18,19 +18,40 @@
%%
-module(erts_debug_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
- flat_size/1,flat_size_big/1,df/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ flat_size/1,flat_size_big/1,df/1,
+ instructions/1]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [flat_size, flat_size_big, df, instructions].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [flat_size,flat_size_big,df].
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(2)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
@@ -70,3 +91,8 @@ df(Config) when is_list(Config) ->
pps() ->
{erlang:ports()}.
+
+instructions(Config) when is_list(Config) ->
+ ?line Is = erts_debug:instructions(),
+ ?line _ = [list_to_atom(I) || I <- Is],
+ ok.
diff --git a/erts/emulator/test/estone_SUITE.erl b/erts/emulator/test/estone_SUITE.erl
index 7fb92faf0d..a4cb76dde1 100644
--- a/erts/emulator/test/estone_SUITE.erl
+++ b/erts/emulator/test/estone_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,8 +18,9 @@
-module(estone_SUITE).
%% Test functions
--export([all/1,estone/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,estone/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%% Internal exports for EStone tests
-export([lists/1,
@@ -44,7 +45,7 @@
run_micro/3,p1/1,ppp/3,macro/2,micros/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test suite defines
-define(default_timeout, ?t:minutes(10)).
@@ -68,12 +69,31 @@
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(suite) -> [estone].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [estone].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
estone(suite) ->
[];
diff --git a/erts/emulator/test/evil_SUITE.erl b/erts/emulator/test/evil_SUITE.erl
index a8288584f4..5c59184fe2 100644
--- a/erts/emulator/test/evil_SUITE.erl
+++ b/erts/emulator/test/evil_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,7 +18,9 @@
-module(evil_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
heap_frag/1,
encode_decode_ext/1,
decode_integer_ext/1,
@@ -30,26 +32,37 @@
decode_pos_neg_zero/1
]).
--include("test_server.hrl").
-
-all(suite) ->
- [
- heap_frag,
- encode_decode_ext,
- decode_integer_ext,
- decode_small_big_ext,
- decode_large_big_ext,
- decode_small_big_ext_neg,
- decode_large_big_ext_neg,
- decode_too_small,
- decode_pos_neg_zero
- ].
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [heap_frag, encode_decode_ext, decode_integer_ext,
+ decode_small_big_ext, decode_large_big_ext,
+ decode_small_big_ext_neg, decode_large_big_ext_neg,
+ decode_too_small, decode_pos_neg_zero].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog = test_server:timetrap(?t:minutes(0.5)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/erts/emulator/test/exception_SUITE.erl b/erts/emulator/test/exception_SUITE.erl
index f1e6e004ad..7041ad32de 100644
--- a/erts/emulator/test/exception_SUITE.erl
+++ b/erts/emulator/test/exception_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,20 +19,40 @@
-module(exception_SUITE).
--export([all/1, badmatch/1, pending_errors/1, nil_arith/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ badmatch/1, pending_errors/1, nil_arith/1,
stacktrace/1, nested_stacktrace/1, raise/1, gunilla/1, per/1,
exception_with_heap_frag/1]).
-export([bad_guy/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-import(lists, [foreach/2]).
-all(suite) ->
- [badmatch, pending_errors, nil_arith,
- stacktrace, nested_stacktrace, raise, gunilla, per,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [badmatch, pending_errors, nil_arith, stacktrace,
+ nested_stacktrace, raise, gunilla, per,
exception_with_heap_frag].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
-define(try_match(E),
catch ?MODULE:bar(),
{'EXIT', {{badmatch, nomatch}, _}} = (catch E = id(nomatch))).
diff --git a/erts/emulator/test/float_SUITE.erl b/erts/emulator/test/float_SUITE.erl
index 99e9457985..c79a1d9900 100644
--- a/erts/emulator/test/float_SUITE.erl
+++ b/erts/emulator/test/float_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,9 +19,11 @@
-module(float_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
fpe/1,fp_drv/1,fp_drv_thread/1,denormalized/1,match/1,
bad_float_unpack/1]).
-export([otp_7178/1]).
@@ -31,18 +33,31 @@ init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(3)),
[{watchdog, Dog},{testcase,Func}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog).
-all(suite) ->
- [fpe,
- fp_drv,
- fp_drv_thread,
- otp_7178,
- denormalized,
- match,
- bad_float_unpack].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [fpe, fp_drv, fp_drv_thread, otp_7178, denormalized,
+ match, bad_float_unpack].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%
%% OTP-7178, list_to_float on very small numbers should give 0.0
diff --git a/erts/emulator/test/fun_SUITE.erl b/erts/emulator/test/fun_SUITE.erl
index a7889dfe90..4b59bfd6a5 100644
--- a/erts/emulator/test/fun_SUITE.erl
+++ b/erts/emulator/test/fun_SUITE.erl
@@ -22,7 +22,9 @@
-define(default_timeout, ?t:minutes(1)).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
bad_apply/1,bad_fun_call/1,badarity/1,ext_badarity/1,
equality/1,ordering/1,
fun_to_port/1,t_hash/1,t_phash/1,t_phash2/1,md5/1,
@@ -32,19 +34,37 @@
-export([nothing/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [bad_apply, bad_fun_call, badarity, ext_badarity,
+ equality, ordering, fun_to_port, t_hash, t_phash,
+ t_phash2, md5, refc, refc_ets, refc_dist,
+ const_propagation, t_arity, t_is_function2, t_fun_info].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [bad_apply,bad_fun_call,badarity,ext_badarity,equality,ordering,
- fun_to_port,t_hash,t_phash,t_phash2,md5,
- refc,refc_ets,refc_dist,const_propagation,
- t_arity,t_is_function2,t_fun_info].
init_per_testcase(_Case, Config) ->
?line Dog = test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/erts/emulator/test/fun_r12_SUITE.erl b/erts/emulator/test/fun_r12_SUITE.erl
index 9262731dcb..9421b60f49 100644
--- a/erts/emulator/test/fun_r12_SUITE.erl
+++ b/erts/emulator/test/fun_r12_SUITE.erl
@@ -20,18 +20,39 @@
-module(fun_r12_SUITE).
-compile(r12).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,dist_old_release/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,dist_old_release/1]).
-define(default_timeout, ?t:minutes(1)).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [dist_old_release].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [dist_old_release].
init_per_testcase(_Case, Config) ->
?line Dog = test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl
index 066aa215b2..9ce8d18346 100644
--- a/erts/emulator/test/gc_SUITE.erl
+++ b/erts/emulator/test/gc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,15 +21,34 @@
-module(gc_SUITE).
--include("test_server.hrl").
--export([all/1]).
+-include_lib("test_server/include/test_server.hrl").
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-define(default_timeout, ?t:minutes(10)).
-export([grow_heap/1, grow_stack/1, grow_stack_heap/1]).
-all(suite) ->
- [grow_heap,grow_stack, grow_stack_heap].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [grow_heap, grow_stack, grow_stack_heap].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
grow_heap(doc) -> ["Produce a growing list of elements, ",
"for X calls, then drop one item per call",
diff --git a/erts/emulator/test/guard_SUITE.erl b/erts/emulator/test/guard_SUITE.erl
index 8fef36dfaf..a3be387a5b 100644
--- a/erts/emulator/test/guard_SUITE.erl
+++ b/erts/emulator/test/guard_SUITE.erl
@@ -19,16 +19,37 @@
-module(guard_SUITE).
--export([all/1, bad_arith/1, bad_tuple/1, test_heap_guards/1, guard_bifs/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, bad_arith/1, bad_tuple/1,
+ test_heap_guards/1, guard_bifs/1,
type_tests/1,guard_bif_binary_part/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-export([init/3]).
-import(lists, [member/2]).
-all(suite) -> [bad_arith, bad_tuple, test_heap_guards, guard_bifs,
- type_tests, guard_bif_binary_part].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [bad_arith, bad_tuple, test_heap_guards, guard_bifs,
+ type_tests, guard_bif_binary_part].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
bad_arith(doc) -> "Test that a bad arithmetic operation in a guard works correctly.";
bad_arith(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/hash_SUITE.erl b/erts/emulator/test/hash_SUITE.erl
index f5d1871bfb..257bee0b78 100644
--- a/erts/emulator/test/hash_SUITE.erl
+++ b/erts/emulator/test/hash_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -49,7 +49,7 @@
-define(config(A,B),config(A,B)).
-export([config/2]).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-endif.
-ifdef(debug).
@@ -69,22 +69,40 @@ config(priv_dir,_) ->
".".
-else.
%% When run in test server.
--export([all/1,test_basic/1,test_cmp/1,test_range/1,test_spread/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ test_basic/1,test_cmp/1,test_range/1,test_spread/1,
test_phash2/1,otp_5292/1,bit_level_binaries/1,otp_7127/1,
- fin_per_testcase/2,init_per_testcase/2]).
+ end_per_testcase/2,init_per_testcase/2]).
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(test_server:minutes(10)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test erlang:phash"];
-all(suite) ->
- [test_basic, test_cmp, test_range, test_spread, test_phash2, otp_5292,
- bit_level_binaries, otp_7127].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [test_basic, test_cmp, test_range, test_spread,
+ test_phash2, otp_5292, bit_level_binaries, otp_7127].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
test_basic(suite) ->
[];
diff --git a/erts/emulator/test/hibernate_SUITE.erl b/erts/emulator/test/hibernate_SUITE.erl
index 4d36076d12..b8dc87db7f 100644
--- a/erts/emulator/test/hibernate_SUITE.erl
+++ b/erts/emulator/test/hibernate_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,23 +19,44 @@
-module(hibernate_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
basic/1,min_heap_size/1,bad_args/1,
messages_in_queue/1,undefined_mfa/1, no_heap/1]).
%% Used by test cases.
-export([basic_hibernator/1,messages_in_queue_restart/2, no_heap_loop/0]).
-all(suite) ->
- [basic,min_heap_size,bad_args,messages_in_queue,undefined_mfa,no_heap].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic, min_heap_size, bad_args, messages_in_queue,
+ undefined_mfa, no_heap].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(3)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
diff --git a/erts/emulator/test/ignore_cores.erl b/erts/emulator/test/ignore_cores.erl
index 1d738cbafd..8b1ac0fe6c 120000..100644
--- a/erts/emulator/test/ignore_cores.erl
+++ b/erts/emulator/test/ignore_cores.erl
@@ -1 +1,158 @@
-../../test/ignore_cores.erl \ No newline at end of file
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File : ignore_cores.erl
+%%% Author : Rickard Green <[email protected]>
+%%% Description :
+%%%
+%%% Created : 11 Feb 2008 by Rickard Green <[email protected]>
+%%%-------------------------------------------------------------------
+
+-module(ignore_cores).
+
+-include_lib("test_server/include/test_server.hrl").
+
+-export([init/1, fini/1, setup/3, setup/4, restore/1, dir/1]).
+
+-record(ignore_cores, {org_cwd,
+ org_path,
+ org_pwd_env,
+ ign_dir = false,
+ cores_dir = false}).
+
+%%
+%% Takes a testcase config
+%%
+
+init(Config) ->
+ {ok, OrgCWD} = file:get_cwd(),
+ [{ignore_cores,
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = code:get_path(),
+ org_pwd_env = os:getenv("PWD")}}
+ | lists:keydelete(ignore_cores, 1, Config)].
+
+fini(Config) ->
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD} = ?config(ignore_cores, Config),
+ ok = file:set_cwd(OrgCWD),
+ true = code:set_path(OrgPath),
+ case OrgPWD of
+ false -> ok;
+ _ -> true = os:putenv("PWD", OrgPWD)
+ end,
+ lists:keydelete(ignore_cores, 1, Config).
+
+setup(Suite, Testcase, Config) ->
+ setup(Suite, Testcase, Config, false).
+
+setup(Suite, Testcase, Config, SetCwd) when is_atom(Suite),
+ is_atom(Testcase),
+ is_list(Config) ->
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD} = ?config(ignore_cores, Config),
+ Path = lists:map(fun (".") -> OrgCWD; (Dir) -> Dir end, OrgPath),
+ true = code:set_path(Path),
+ PrivDir = ?config(priv_dir, Config),
+ IgnDir = filename:join([PrivDir,
+ atom_to_list(Suite)
+ ++ "_"
+ ++ atom_to_list(Testcase)
+ ++ "_wd"]),
+ ok = file:make_dir(IgnDir),
+ case SetCwd of
+ false ->
+ ok;
+ _ ->
+ ok = file:set_cwd(IgnDir),
+ OrgPWD = case os:getenv("PWD") of
+ false -> false;
+ PWD ->
+ os:putenv("PWD", IgnDir),
+ PWD
+ end
+ end,
+ ok = file:write_file(filename:join([IgnDir, "ignore_core_files"]), <<>>),
+ %% cores are dumped in /cores on MacOS X
+ CoresDir = case {?t:os_type(), filelib:is_dir("/cores")} of
+ {{unix,darwin}, true} ->
+ filelib:fold_files("/cores",
+ "^core.*$",
+ false,
+ fun (C,Cs) -> [C|Cs] end,
+ []);
+ _ ->
+ false
+ end,
+ lists:keyreplace(ignore_cores,
+ 1,
+ Config,
+ {ignore_cores,
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD,
+ ign_dir = IgnDir,
+ cores_dir = CoresDir}}).
+
+restore(Config) ->
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD,
+ ign_dir = IgnDir,
+ cores_dir = CoresDir} = ?config(ignore_cores, Config),
+ try
+ case CoresDir of
+ false ->
+ ok;
+ _ ->
+ %% Move cores dumped by these testcases in /cores
+ %% to cwd.
+ lists:foreach(fun (C) ->
+ case lists:member(C, CoresDir) of
+ true -> ok;
+ _ ->
+ Dst = filename:join(
+ [IgnDir,
+ filename:basename(C)]),
+ {ok, _} = file:copy(C, Dst),
+ file:delete(C)
+ end
+ end,
+ filelib:fold_files("/cores",
+ "^core.*$",
+ false,
+ fun (C,Cs) -> [C|Cs] end,
+ []))
+ end
+ after
+ catch file:set_cwd(OrgCWD),
+ catch code:set_path(OrgPath),
+ case OrgPWD of
+ false -> ok;
+ _ -> catch os:putenv("PWD", OrgPWD)
+ end
+ end.
+
+
+dir(Config) ->
+ #ignore_cores{ign_dir = Dir} = ?config(ignore_cores, Config),
+ Dir.
diff --git a/erts/emulator/test/list_bif_SUITE.erl b/erts/emulator/test/list_bif_SUITE.erl
index 65ea88eb2f..ef0929e769 100644
--- a/erts/emulator/test/list_bif_SUITE.erl
+++ b/erts/emulator/test/list_bif_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,21 +18,42 @@
%%
-module(list_bif_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2]).
-export([hd_test/1,tl_test/1,t_length/1,t_list_to_pid/1,
t_list_to_float/1,t_list_to_integer/1]).
-all(suite) ->
- [hd_test,tl_test,t_length,t_list_to_pid,t_list_to_float,t_list_to_integer].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [hd_test, tl_test, t_length, t_list_to_pid,
+ t_list_to_float, t_list_to_integer].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog = test_server:timetrap(test_server:seconds(60)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/erts/emulator/test/long_timers_test.erl b/erts/emulator/test/long_timers_test.erl
index 28626d26fb..28a4fba9f6 100644
--- a/erts/emulator/test/long_timers_test.erl
+++ b/erts/emulator/test/long_timers_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl
index 69c89f5d2d..2b21fa58f4 100644
--- a/erts/emulator/test/match_spec_SUITE.erl
+++ b/erts/emulator/test/match_spec_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,7 +19,8 @@
-module(match_spec_SUITE).
--export([all/1, not_run/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, not_run/1]).
-export([test_1/1, test_2/1, test_3/1, bad_match_spec_bin/1,
trace_control_word/1, silent/1, silent_no_ms/1,
ms_trace2/1, ms_trace3/1, boxed_and_small/1,
@@ -34,29 +35,48 @@
% This test suite assumes that tracing in general works. What we test is
% the match spec functionality.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:seconds(10)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
-all(suite) ->
- case test_server:is_native(?MODULE) of
- false -> [test_1, test_2, test_3, bad_match_spec_bin,
- trace_control_word, silent, silent_no_ms,
- ms_trace2, ms_trace3, boxed_and_small,
- destructive_in_test_bif, guard_exceptions,
- unary_plus, unary_minus, fpe, moving_labels];
- true -> [not_run]
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:is_native(match_spec_SUITE) of
+ false ->
+ [test_1, test_2, test_3, bad_match_spec_bin,
+ trace_control_word, silent, silent_no_ms, ms_trace2,
+ ms_trace3, boxed_and_small, destructive_in_test_bif,
+ guard_exceptions, unary_plus, unary_minus, fpe,
+ moving_labels];
+ true -> [not_run]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
not_run(Config) when is_list(Config) ->
{skipped, "Native Code"}.
@@ -345,15 +365,15 @@ silent_no_ms(Config) when is_list(Config) ->
fun () ->
?MODULE:f1(a),
?MODULE:f2(b, c),
- erlang:integer_to_list(id(1)),
+ _ = erlang:integer_to_list(id(1)),
?MODULE:f3(d, e),
?MODULE:f1(start),
?MODULE:f2(f, g),
- erlang:integer_to_list(id(2)),
+ _ = erlang:integer_to_list(id(2)),
?MODULE:f3(h, i),
?MODULE:f1(stop),
?MODULE:f2(j, k),
- erlang:integer_to_list(id(3)),
+ _ = erlang:integer_to_list(id(3)),
?MODULE:f3(l, m)
end,
fun (Tracee) ->
@@ -393,15 +413,15 @@ silent_no_ms(Config) when is_list(Config) ->
fun () ->
?MODULE:f1(a),
?MODULE:f2(b, c),
- erlang:integer_to_list(id(1)),
+ _ = erlang:integer_to_list(id(1)),
?MODULE:f3(d, e),
?MODULE:f1(start),
?MODULE:f2(f, g),
- erlang:integer_to_list(id(2)),
+ _ = erlang:integer_to_list(id(2)),
?MODULE:f3(h, i),
?MODULE:f1(stop),
?MODULE:f2(j, k),
- erlang:integer_to_list(id(3)),
+ _ = erlang:integer_to_list(id(3)),
?MODULE:f3(l, m)
end,
fun (Tracee) ->
@@ -455,18 +475,18 @@ ms_trace2(Config) when is_list(Config) ->
fun () ->
?MODULE:f1(a),
?MODULE:f2(b, c),
- erlang:integer_to_list(id(1)),
+ _ = erlang:integer_to_list(id(1)),
?MODULE:f3(d, e),
fn([all], [call,return_to,{tracer,Tracer}]),
?MODULE:f1(f),
f2(g, h),
f1(i),
- erlang:integer_to_list(id(2)),
+ _ = erlang:integer_to_list(id(2)),
?MODULE:f3(j, k),
fn([call,return_to], []),
?MODULE:f1(l),
?MODULE:f2(m, n),
- erlang:integer_to_list(id(3)),
+ _ = erlang:integer_to_list(id(3)),
?MODULE:f3(o, p)
end,
fun (Tracee) ->
@@ -551,26 +571,26 @@ ms_trace3(Config) when is_list(Config) ->
register(TraceeName, self()),
?MODULE:f1(a),
?MODULE:f2(b, c),
- erlang:integer_to_list(id(1)),
+ _ = erlang:integer_to_list(id(1)),
?MODULE:f3(d, e),
Controller ! {self(),Tag,start},
receive {Controller,Tag,started} -> ok end,
?MODULE:f1(f),
f2(g, h),
f1(i),
- erlang:integer_to_list(id(2)),
+ _ = erlang:integer_to_list(id(2)),
?MODULE:f3(j, k),
Controller ! {self(),Tag,stop_1},
receive {Controller,Tag,stopped_1} -> ok end,
?MODULE:f1(l),
?MODULE:f2(m, n),
- erlang:integer_to_list(id(3)),
+ _ = erlang:integer_to_list(id(3)),
?MODULE:f3(o, p),
Controller ! {self(),Tag,stop_2},
receive {Controller,Tag,stopped_2} -> ok end,
?MODULE:f1(q),
?MODULE:f2(r, s),
- erlang:integer_to_list(id(4)),
+ _ = erlang:integer_to_list(id(4)),
?MODULE:f3(t, u)
end,
diff --git a/erts/emulator/test/module_info_SUITE.erl b/erts/emulator/test/module_info_SUITE.erl
index f34a2b496c..a2a052671f 100644
--- a/erts/emulator/test/module_info_SUITE.erl
+++ b/erts/emulator/test/module_info_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -19,9 +19,11 @@
-module(module_info_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,end_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
exports/1,functions/1,native/1]).
%%-compile(native).
@@ -29,8 +31,29 @@
%% Helper.
-export([native_proj/1,native_filter/1]).
-all(suite) ->
- [exports,functions,native].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ modules().
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+modules() ->
+ [exports, functions, native].
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(3)),
@@ -42,14 +65,18 @@ end_per_testcase(_Func, Config) ->
%% Should return all functions exported from this module. (local)
all_exported() ->
- All = add_arity(all(suite)),
- lists:sort([{all,1},{init_per_testcase,2},{end_per_testcase,2},
+ All = add_arity(modules()),
+ lists:sort([{all,0},{suite,0},{groups,0},
+ {init_per_suite,1},{end_per_suite,1},
+ {init_per_group,2},{end_per_group,2},
+ {init_per_testcase,2},{end_per_testcase,2},
{module_info,0},{module_info,1},{native_proj,1},
{native_filter,1}|All]).
%% Should return all functions in this module. (local)
all_functions() ->
- Locals = [{add_arity,1},{add_arity,2},{all_exported,0},{all_functions,0}],
+ Locals = [{add_arity,1},{add_arity,2},{all_exported,0},{all_functions,0},
+ {modules,0}],
lists:sort(Locals++all_exported()).
%% Test that the list of exported functions from this module is correct.
diff --git a/erts/emulator/test/monitor_SUITE.erl b/erts/emulator/test/monitor_SUITE.erl
index 68e378dfec..9cf4ed702a 100644
--- a/erts/emulator/test/monitor_SUITE.erl
+++ b/erts/emulator/test/monitor_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,29 +19,49 @@
-module(monitor_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
case_1/1, case_1a/1, case_2/1, case_2a/1, mon_e_1/1, demon_e_1/1, demon_1/1,
- demon_2/1, demon_3/1, demonitor_flush/1, remove_monitor/1,
+ demon_2/1, demon_3/1, demonitor_flush/1,
local_remove_monitor/1, remote_remove_monitor/1, mon_1/1, mon_2/1,
large_exit/1, list_cleanup/1, mixer/1, named_down/1, otp_5827/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([y2/1, g/1, g0/0, g1/0, large_exit_sub/1]).
-all(suite) ->
- [case_1, case_1a, case_2, case_2a, mon_e_1, demon_e_1, demon_1, mon_1,
- mon_2, demon_2, demon_3, demonitor_flush, remove_monitor,
- large_exit, list_cleanup, mixer, named_down,
- otp_5827].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [case_1, case_1a, case_2, case_2a, mon_e_1, demon_e_1,
+ demon_1, mon_1, mon_2, demon_2, demon_3,
+ demonitor_flush, {group, remove_monitor}, large_exit,
+ list_cleanup, mixer, named_down, otp_5827].
+
+groups() ->
+ [{remove_monitor, [],
+ [local_remove_monitor, remote_remove_monitor]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(15)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
@@ -315,8 +335,6 @@ demonitor_flush_test(Node) ->
-define(RM_MON_GROUPS, 100).
-define(RM_MON_GPROCS, 100).
-remove_monitor(suite) ->
- [local_remove_monitor, remote_remove_monitor].
local_remove_monitor(Config) when is_list(Config) ->
Gs = generate(fun () -> start_remove_monitor_group(node()) end,
diff --git a/erts/emulator/test/mtx_SUITE.erl b/erts/emulator/test/mtx_SUITE.erl
new file mode 100644
index 0000000000..d379b8a7fa
--- /dev/null
+++ b/erts/emulator/test/mtx_SUITE.erl
@@ -0,0 +1,479 @@
+%%
+%% %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%
+%%
+
+%%
+%% Stress tests of rwmutex implementation.
+%%
+%% Author: Rickard Green
+%%
+-module(mtx_SUITE).
+
+%%-define(line_trace,true).
+
+-include_lib("common_test/include/ct.hrl").
+
+-export([all/0,suite/0,groups/0,
+ init_per_group/2,end_per_group/2, init_per_suite/1,
+ end_per_suite/1, init_per_testcase/2, end_per_testcase/2]).
+
+-export([long_rwlock/1,
+ hammer_ets_rwlock/1,
+ hammer_rwlock/1,
+ hammer_rwlock_check/1,
+ hammer_tryrwlock/1,
+ hammer_tryrwlock_check/1,
+ hammer_sched_long_rwlock/1,
+ hammer_sched_long_rwlock_check/1,
+ hammer_sched_long_freqread_rwlock/1,
+ hammer_sched_long_freqread_rwlock_check/1,
+ hammer_sched_long_tryrwlock/1,
+ hammer_sched_long_tryrwlock_check/1,
+ hammer_sched_long_freqread_tryrwlock/1,
+ hammer_sched_long_freqread_tryrwlock_check/1,
+ hammer_sched_rwlock/1,
+ hammer_sched_rwlock_check/1,
+ hammer_sched_freqread_rwlock/1,
+ hammer_sched_freqread_rwlock_check/1,
+ hammer_sched_tryrwlock/1,
+ hammer_sched_tryrwlock_check/1,
+ hammer_sched_freqread_tryrwlock/1,
+ hammer_sched_freqread_tryrwlock_check/1]).
+
+init_per_suite(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Lib = filename:join([DataDir, atom_to_list(?MODULE)]),
+ ok = erlang:load_nif(Lib, none),
+ Config.
+
+end_per_suite(Config) when is_list(Config) ->
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?t:minutes(15)),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(_Func, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [long_rwlock, hammer_rwlock_check, hammer_rwlock,
+ hammer_tryrwlock_check, hammer_tryrwlock,
+ hammer_ets_rwlock, hammer_sched_long_rwlock_check,
+ hammer_sched_long_rwlock,
+ hammer_sched_long_freqread_rwlock_check,
+ hammer_sched_long_freqread_rwlock,
+ hammer_sched_long_tryrwlock_check,
+ hammer_sched_long_tryrwlock,
+ hammer_sched_long_freqread_tryrwlock_check,
+ hammer_sched_long_freqread_tryrwlock,
+ hammer_sched_rwlock_check, hammer_sched_rwlock,
+ hammer_sched_freqread_rwlock_check,
+ hammer_sched_freqread_rwlock,
+ hammer_sched_tryrwlock_check, hammer_sched_tryrwlock,
+ hammer_sched_freqread_tryrwlock_check,
+ hammer_sched_freqread_tryrwlock].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+long_rwlock(Config) when is_list(Config) ->
+ statistics(runtime),
+ LLRes = long_rw_test(),
+ {_, RunTime} = statistics(runtime),
+ %% A very short run time is expected, since
+ %% threads in the test mostly wait
+ ?t:format("RunTime=~p~n", [RunTime]),
+ ?line true = RunTime < 100,
+ ?line RunTimeStr = "Run-time during test was "++integer_to_list(RunTime)++" ms.",
+ case LLRes of
+ ok ->
+ {comment, RunTimeStr};
+ {comment, Comment} ->
+ {comment, Comment ++ " " ++ RunTimeStr}
+ end.
+
+hammer_rwlock(Config) when is_list(Config) ->
+ hammer_rw_test(false).
+
+hammer_rwlock_check(Config) when is_list(Config) ->
+ hammer_rw_test(true).
+
+hammer_tryrwlock(Config) when is_list(Config) ->
+ hammer_tryrw_test(false).
+
+hammer_tryrwlock_check(Config) when is_list(Config) ->
+ hammer_tryrw_test(true).
+
+hammer_sched_rwlock(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(false, false, true, 0, 0).
+
+hammer_sched_rwlock_check(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(false, true, true, 0, 0).
+
+hammer_sched_freqread_rwlock(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(true, false, true, 0, 0).
+
+hammer_sched_freqread_rwlock_check(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(true, true, true, 0, 0).
+
+hammer_sched_tryrwlock(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(false, false, false, 0, 100).
+
+hammer_sched_tryrwlock_check(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(false, true, false, 0, 100).
+
+hammer_sched_freqread_tryrwlock(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(true, false, false, 0, 100).
+
+hammer_sched_freqread_tryrwlock_check(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(true, true, false, 0, 100).
+
+hammer_sched_long_rwlock(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(false, false, true, 100, 0).
+
+hammer_sched_long_rwlock_check(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(false, true, true, 100, 0).
+
+hammer_sched_long_freqread_rwlock(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(true, false, true, 100, 0).
+
+hammer_sched_long_freqread_rwlock_check(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(true, true, true, 100, 0).
+
+hammer_sched_long_tryrwlock(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(false, false, false, 100, 100).
+
+hammer_sched_long_tryrwlock_check(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(false, true, false, 100, 100).
+
+hammer_sched_long_freqread_tryrwlock(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(true, false, false, 100, 100).
+
+hammer_sched_long_freqread_tryrwlock_check(Config) when is_list(Config) ->
+ hammer_sched_rwlock_test(true, true, false, 100, 100).
+
+hammer_sched_rwlock_test(FreqRead, LockCheck, Blocking, WaitLocked, WaitUnlocked) ->
+ case create_rwlock(FreqRead, LockCheck) of
+ enotsup ->
+ {skipped, "Not supported."};
+ RWLock ->
+ Onln = erlang:system_info(schedulers_online),
+ NWPs = case Onln div 3 of
+ 1 -> case Onln < 4 of
+ true -> 1;
+ false -> 2
+ end;
+ X -> X
+ end,
+ NRPs = Onln - NWPs,
+ NoLockOps = ((((50000000 div Onln)
+ div case {Blocking, WaitLocked} of
+ {false, 0} -> 1;
+ _ -> 10
+ end)
+ div (case WaitLocked == 0 of
+ true -> 1;
+ false -> WaitLocked*250
+ end))
+ div handicap()),
+ ?t:format("NoLockOps=~p~n", [NoLockOps]),
+ Sleep = case Blocking of
+ true -> NoLockOps;
+ false -> NoLockOps div 10
+ end,
+ WPs = lists:map(
+ fun (Sched) ->
+ spawn_opt(
+ fun () ->
+ io:format("Writer on scheduler ~p.~n",
+ [Sched]),
+ Sched = erlang:system_info(scheduler_id),
+ receive go -> gone end,
+ hammer_sched_rwlock_proc(RWLock,
+ Blocking,
+ true,
+ WaitLocked,
+ WaitUnlocked,
+ NoLockOps,
+ Sleep),
+ Sched = erlang:system_info(scheduler_id)
+ end,
+ [link, {scheduler, Sched}])
+ end,
+ lists:seq(1, NWPs)),
+ RPs = lists:map(
+ fun (Sched) ->
+ spawn_opt(
+ fun () ->
+ io:format("Reader on scheduler ~p.~n",
+ [Sched]),
+ Sched = erlang:system_info(scheduler_id),
+ receive go -> gone end,
+ hammer_sched_rwlock_proc(RWLock,
+ Blocking,
+ false,
+ WaitLocked,
+ WaitUnlocked,
+ NoLockOps,
+ Sleep),
+ Sched = erlang:system_info(scheduler_id)
+ end,
+ [link, {scheduler, Sched}])
+ end,
+ lists:seq(NWPs + 1, NWPs + NRPs)),
+ Procs = WPs ++ RPs,
+ case {Blocking, WaitLocked} of
+ {_, 0} -> ok;
+ {false, _} -> ok;
+ _ -> statistics(runtime)
+ end,
+ lists:foreach(fun (P) -> P ! go end, Procs),
+ lists:foreach(fun (P) ->
+ M = erlang:monitor(process, P),
+ receive
+ {'DOWN', M, process, P, _} ->
+ ok
+ end
+ end,
+ Procs),
+ case {Blocking, WaitLocked} of
+ {_, 0} -> ok;
+ {false, _} -> ok;
+ _ ->
+ {_, RunTime} = statistics(runtime),
+ ?t:format("RunTime=~p~n", [RunTime]),
+ ?line true = RunTime < 500,
+ {comment,
+ "Run-time during test was "
+ ++ integer_to_list(RunTime)
+ ++ " ms."}
+ end
+ end.
+
+hammer_sched_rwlock_proc(_RWLock,
+ _Blocking,
+ _WriteOp,
+ _WaitLocked,
+ _WaitUnlocked,
+ 0,
+ _Sleep) ->
+ ok;
+hammer_sched_rwlock_proc(RWLock,
+ Blocking,
+ WriteOp,
+ WaitLocked,
+ WaitUnlocked,
+ Times,
+ Sleep) when Times rem Sleep == 0 ->
+ rwlock_op(RWLock, Blocking, WriteOp, WaitLocked, WaitUnlocked),
+ hammer_sched_rwlock_proc(RWLock,
+ Blocking,
+ WriteOp,
+ WaitLocked,
+ WaitUnlocked,
+ Times - 1,
+ Sleep);
+hammer_sched_rwlock_proc(RWLock,
+ Blocking,
+ WriteOp,
+ WaitLocked,
+ WaitUnlocked,
+ Times,
+ Sleep) ->
+ rwlock_op(RWLock, Blocking, WriteOp, WaitLocked, 0),
+ hammer_sched_rwlock_proc(RWLock,
+ Blocking,
+ WriteOp,
+ WaitLocked,
+ WaitUnlocked,
+ Times - 1,
+ Sleep).
+
+-define(HAMMER_ETS_RWLOCK_REPEAT_TIMES, 1).
+-define(HAMMER_ETS_RWLOCK_TSIZE, 500).
+
+hammer_ets_rwlock(Config) when is_list(Config) ->
+ {Ops, Procs} = case handicap() of
+ 1 -> {20000, 500};
+ 2 -> {20000, 50};
+ 3 -> {2000, 50};
+ _ -> {200, 50}
+ end,
+ ?t:format("Procs=~p~nOps=~p~n", [Procs, Ops]),
+ lists:foreach(fun (XOpts) ->
+ ?t:format("Running with extra opts: ~p", [XOpts]),
+ hammer_ets_rwlock_test(XOpts, true, 2, Ops,
+ Procs, false)
+ end,
+ [[],
+ [{read_concurrency, true}],
+ [{write_concurrency, true}],
+ [{read_concurrency, true},{write_concurrency, true}]]),
+ ok.
+
+%% Aux funcs
+
+long_rw_test() ->
+ exit(no_nif_implementation).
+
+hammer_rw_test(_Arg) ->
+ exit(no_nif_implementation).
+
+hammer_tryrw_test(_Arg) ->
+ exit(no_nif_implementation).
+
+create_rwlock(_FreqRead, _LockCheck) ->
+ exit(no_nif_implementation).
+
+rwlock_op(_RWLock, _Blocking, _WriteOp, _WaitLocked, _WaitUnlocked) ->
+ exit(no_nif_implementation).
+
+hammer_ets_rwlock_put_data() ->
+ put(?MODULE, {"here are some", data, "to store", make_ref()}).
+
+hammer_ets_rwlock_get_data() ->
+ get(?MODULE).
+
+hammer_ets_rwlock_ops(_T, _UW, _N, _C, _SC, 0) ->
+ ok;
+hammer_ets_rwlock_ops(T, UW, N, C, SC, Tot) when N >= ?HAMMER_ETS_RWLOCK_TSIZE ->
+ hammer_ets_rwlock_ops(T, UW, 0, C, SC, Tot);
+hammer_ets_rwlock_ops(T, UW, N, 0, SC, Tot) ->
+ case UW of
+ true ->
+ true = ets:insert(T, {N, Tot, hammer_ets_rwlock_get_data()});
+ false ->
+ [{N, _, _}] = ets:lookup(T, N)
+ end,
+ hammer_ets_rwlock_ops(T, UW, N+1, SC, SC, Tot-1);
+hammer_ets_rwlock_ops(T, UW, N, C, SC, Tot) ->
+ case UW of
+ false ->
+ true = ets:insert(T, {N, Tot, hammer_ets_rwlock_get_data()});
+ true ->
+ [{N, _, _}] = ets:lookup(T, N)
+ end,
+ hammer_ets_rwlock_ops(T, UW, N+1, C-1, SC, Tot-1).
+
+hammer_ets_rwlock_init(T, N) when N < ?HAMMER_ETS_RWLOCK_TSIZE ->
+ ets:insert(T, {N, N, N}),
+ hammer_ets_rwlock_init(T, N+1);
+hammer_ets_rwlock_init(_T, _N) ->
+ ok.
+
+hammer_ets_rwlock_test(XOpts, UW, C, N, NP, SC) ->
+ receive after 100 -> ok end,
+ {TP, TM} = spawn_monitor(
+ fun () ->
+ _L = repeat_list(
+ fun () ->
+ Caller = self(),
+ T = fun () ->
+ Parent = self(),
+ hammer_ets_rwlock_put_data(),
+ T=ets:new(x, [public | XOpts]),
+ hammer_ets_rwlock_init(T, 0),
+ Ps0 = repeat_list(
+ fun () ->
+ spawn_link(
+ fun () ->
+ hammer_ets_rwlock_put_data(),
+ receive go -> ok end,
+ hammer_ets_rwlock_ops(T, UW, N, C, C, N),
+ Parent ! {done, self()},
+ receive after infinity -> ok end
+ end)
+ end,
+ NP - case SC of
+ false -> 0;
+ _ -> 1
+ end),
+ Ps = case SC of
+ false -> Ps0;
+ _ -> [spawn_link(fun () ->
+ hammer_ets_rwlock_put_data(),
+ receive go -> ok end,
+ hammer_ets_rwlock_ops(T, UW, N, SC, SC, N),
+ Parent ! {done, self()},
+ receive after infinity -> ok end
+ end) | Ps0]
+ end,
+ Start = now(),
+ lists:foreach(fun (P) -> P ! go end, Ps),
+ lists:foreach(fun (P) -> receive {done, P} -> ok end end, Ps),
+ Stop = now(),
+ lists:foreach(fun (P) ->
+ unlink(P),
+ exit(P, bang),
+ M = erlang:monitor(process, P),
+ receive
+ {'DOWN', M, process, P, _} -> ok
+ end
+ end, Ps),
+ Res = timer:now_diff(Stop, Start)/1000000,
+ Caller ! {?MODULE, self(), Res}
+ end,
+ TP = spawn_link(T),
+ receive
+ {?MODULE, TP, Res} ->
+ Res
+ end
+ end,
+ ?HAMMER_ETS_RWLOCK_REPEAT_TIMES)
+ end),
+ receive
+ {'DOWN', TM, process, TP, _} -> ok
+ end.
+
+repeat_list(Fun, N) ->
+ repeat_list(Fun, N, []).
+
+repeat_list(_Fun, 0, Acc) ->
+ Acc;
+repeat_list(Fun, N, Acc) ->
+ repeat_list(Fun, N-1, [Fun()|Acc]).
+
+
+handicap() ->
+ X0 = case catch (erlang:system_info(logical_processors_available) >=
+ erlang:system_info(schedulers_online)) of
+ true -> 1;
+ _ -> 2
+ end,
+ case erlang:system_info(build_type) of
+ opt ->
+ X0;
+ ReallySlow when ReallySlow == debug;
+ ReallySlow == valgrind;
+ ReallySlow == purify ->
+ X0*3;
+ _Slow ->
+ X0*2
+ end.
+
diff --git a/erts/emulator/test/mtx_SUITE_data/Makefile.src b/erts/emulator/test/mtx_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..b6c843269c
--- /dev/null
+++ b/erts/emulator/test/mtx_SUITE_data/Makefile.src
@@ -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%
+#
+
+include @erts_lib_include_internal_generated@@[email protected]
+include @erts_lib_include_internal_generated@@DS@erts_internal.mk
+
+NIF_LIBS = mtx_SUITE@dll@
+
+SHLIB_EXTRA_CFLAGS = $(ETHR_DEFS) -I@erts_lib_include_internal@ -I@erts_lib_include_internal_generated@
+LIBS = @ERTS_LIBS@
+
+all: $(NIF_LIBS)
+
+@SHLIB_RULES@
diff --git a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
new file mode 100644
index 0000000000..818023211c
--- /dev/null
+++ b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
@@ -0,0 +1,692 @@
+/*
+ * %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%
+ */
+
+/*
+ * Stress tests of rwmutex implementation.
+ *
+ * Author: Rickard Green
+ */
+
+#include "erl_nif.h"
+
+#ifdef __WIN32__
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+#else
+# include "ethread.h"
+# include "erl_misc_utils.h"
+# include <unistd.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+
+static int
+fail(const char *file, int line, const char *function, const char *assertion);
+
+#undef ASSERT
+#define ASSERT(X) ((void) ((X) ? 1 : fail(__FILE__, __LINE__, __func__, #X)))
+
+#ifdef __WIN32__
+/*
+ * We cannot access the ethread symbols directly; test
+ * what we got in the nif api instead...
+ */
+#define HAVE_FREQREAD_SUPPORT 0
+#define RWMUTEX_T ErlNifRWLock
+#define RWMUTEX_CREATE(FR) enif_rwlock_create("dummy")
+#define RWMUTEX_DESTROY enif_rwlock_destroy
+#define RWMUTEX_WLOCK enif_rwlock_rwlock
+#define RWMUTEX_TRYWLOCK enif_rwlock_tryrwlock
+#define RWMUTEX_WUNLOCK enif_rwlock_rwunlock
+#define RWMUTEX_TRYRLOCK enif_rwlock_tryrlock
+#define RWMUTEX_RLOCK enif_rwlock_rlock
+#define RWMUTEX_RUNLOCK enif_rwlock_runlock
+#define THR_ID ErlNifTid
+#define THR_CREATE(A, B, C, D) enif_thread_create("dummy", (A), (B), (C), (D))
+#define THR_JOIN enif_thread_join
+#define ATOMIC_T volatile LONG
+#define ATOMIC_INIT(VarP, Val) (*(VarP) = (Val))
+#define ATOMIC_SET(VarP, Val) (*(VarP) = (Val))
+#define ATOMIC_READ(VarP) (*(VarP))
+#define ATOMIC_INC InterlockedIncrement
+#define ATOMIC_DEC InterlockedDecrement
+
+#else
+
+#ifdef ETHR_USE_OWN_RWMTX_IMPL__
+# define HAVE_FREQREAD_SUPPORT 1
+#else
+# define HAVE_FREQREAD_SUPPORT 0
+#endif
+
+#define RWMUTEX_T ethr_rwmutex
+static ethr_rwmutex *
+RWMUTEX_CREATE(int freqread)
+{
+ ethr_rwmutex *rwmtx = enif_alloc(sizeof(ethr_rwmutex));
+ ethr_rwmutex_opt rwmtx_opt = ETHR_RWMUTEX_OPT_DEFAULT_INITER;
+ if (freqread)
+ rwmtx_opt.type = ETHR_RWMUTEX_TYPE_FREQUENT_READ;
+ ASSERT(rwmtx);
+ ASSERT(ethr_rwmutex_init_opt(rwmtx, &rwmtx_opt) == 0);
+ return rwmtx;
+}
+static void
+RWMUTEX_DESTROY(ethr_rwmutex *rwmtx)
+{
+ ASSERT(ethr_rwmutex_destroy(rwmtx) == 0);
+ enif_free(rwmtx);
+}
+#define RWMUTEX_TRYWLOCK ethr_rwmutex_tryrwlock
+#define RWMUTEX_WLOCK ethr_rwmutex_rwlock
+#define RWMUTEX_WUNLOCK ethr_rwmutex_rwunlock
+#define RWMUTEX_TRYRLOCK ethr_rwmutex_tryrlock
+#define RWMUTEX_RLOCK ethr_rwmutex_rlock
+#define RWMUTEX_RUNLOCK ethr_rwmutex_runlock
+#define THR_ID ethr_tid
+#define THR_CREATE ethr_thr_create
+#define THR_JOIN ethr_thr_join
+#define ATOMIC_T ethr_atomic_t
+#define ATOMIC_INIT ethr_atomic_init
+#define ATOMIC_SET ethr_atomic_set
+#define ATOMIC_READ ethr_atomic_read
+#define ATOMIC_INC ethr_atomic_inc
+#define ATOMIC_DEC ethr_atomic_dec
+
+#endif
+
+
+#if !defined(__func__)
+# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
+# if !defined(__GNUC__) || __GNUC__ < 2
+# define __func__ "[unknown_function]"
+# else
+# define __func__ __FUNCTION__
+# endif
+# endif
+#endif
+
+static void milli_sleep(int ms);
+static int get_bool(ErlNifEnv* env, ERL_NIF_TERM term);
+
+/*
+ * Long rwlock testcase
+ */
+
+#define LONG_RW_NO_W_THREADS 6
+#define LONG_RW_NO_THREADS 20
+#define LONG_RW_NO_WLOCK_COUNT 100
+
+typedef struct {
+ RWMUTEX_T *rwlock;
+ ATOMIC_T *is_wlocked;
+ ATOMIC_T *is_rlocked;
+ int *stop;
+ int *count;
+ int sleep;
+} long_rw_t;
+
+static void *
+long_rw_w(void *varg)
+{
+ long_rw_t *arg = varg;
+ int stop = 0;
+ do {
+ RWMUTEX_WLOCK(arg->rwlock);
+ ASSERT(!ATOMIC_READ(arg->is_wlocked));
+ ATOMIC_SET(arg->is_wlocked, 1);
+ ASSERT(!ATOMIC_READ(arg->is_rlocked));
+ milli_sleep(arg->sleep);
+ if (++(*arg->count) > LONG_RW_NO_WLOCK_COUNT)
+ stop = *arg->stop = 1;
+ ATOMIC_SET(arg->is_wlocked, 0);
+ ASSERT(!ATOMIC_READ(arg->is_rlocked));
+ RWMUTEX_WUNLOCK(arg->rwlock);
+ } while (!stop);
+ return NULL;
+}
+
+static void *
+long_rw_r(void *varg)
+{
+ long_rw_t *arg = varg;
+ int stop;
+ do {
+ RWMUTEX_RLOCK(arg->rwlock);
+ ASSERT(!ATOMIC_READ(arg->is_wlocked));
+ ATOMIC_INC(arg->is_rlocked);
+ milli_sleep(arg->sleep);
+ stop = *arg->stop;
+ ATOMIC_DEC(arg->is_rlocked);
+ ASSERT(!ATOMIC_READ(arg->is_wlocked));
+ RWMUTEX_RUNLOCK(arg->rwlock);
+ } while (!stop);
+ return NULL;
+}
+
+
+static ERL_NIF_TERM long_rw_test(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
+{
+ int res, freqread, i, count, stop;
+ ATOMIC_T is_wlocked, is_rlocked;
+ THR_ID tid[LONG_RW_NO_THREADS];
+ long_rw_t arg;
+ long_rw_t targ[LONG_RW_NO_THREADS];
+
+ ATOMIC_INIT(&is_wlocked, 0);
+ ATOMIC_INIT(&is_rlocked, 0);
+
+ freqread = 0;
+
+ arg.is_wlocked = &is_wlocked;
+ arg.is_rlocked = &is_rlocked;
+ arg.count = &count;
+ arg.stop = &stop;
+
+ restart:
+
+ stop = 0;
+ count = 0;
+
+ arg.rwlock = RWMUTEX_CREATE(freqread);
+
+ ASSERT(arg.rwlock);
+
+ for (i = 0; i < LONG_RW_NO_W_THREADS; i++) {
+ targ[i] = arg;
+ targ[i].sleep = 100 + i*10;
+ ASSERT(THR_CREATE(&tid[i], long_rw_w, &targ[i], NULL) == 0);
+ }
+ for (; i < LONG_RW_NO_THREADS; i++) {
+ targ[i] = arg;
+ targ[i].sleep = 100;
+ ASSERT(THR_CREATE(&tid[i], long_rw_r, &targ[i], NULL) == 0);
+ }
+ for (i = 0; i < LONG_RW_NO_THREADS; i++)
+ ASSERT(THR_JOIN(tid[i], NULL) == 0);
+
+ ASSERT(!ATOMIC_READ(arg.is_wlocked));
+ ASSERT(!ATOMIC_READ(arg.is_rlocked));
+
+ RWMUTEX_DESTROY(arg.rwlock);
+
+ if (HAVE_FREQREAD_SUPPORT && !freqread) {
+ freqread = 1;
+ goto restart;
+ }
+
+ if (freqread)
+ return enif_make_atom(env, "ok");
+ else
+ return enif_make_tuple2(env,
+ enif_make_atom(env,
+ "comment"),
+ enif_make_string(env,
+ "No frequent read test made.",
+ ERL_NIF_LATIN1));
+}
+
+/*
+ * Hammer rwlock testcase
+ */
+
+#define HAMMER_RW_NO_W_THREADS 6
+#define HAMMER_RW_NO_THREADS 20
+#define HAMMER_RW_NO_WLOCK_COUNT 1000000
+
+typedef struct {
+ RWMUTEX_T *rwlock;
+ ATOMIC_T is_locked;
+ int lock_check;
+ int stop;
+ int count;
+} hammer_rw_t;
+
+static void *
+hammer_rw_w(void *varg)
+{
+ hammer_rw_t *arg = varg;
+ int stop = 0;
+ do {
+ RWMUTEX_WLOCK(arg->rwlock);
+ if (arg->lock_check) {
+ ASSERT(!ATOMIC_READ(&arg->is_locked));
+ ATOMIC_SET(&arg->is_locked, -1);
+ }
+ if (++arg->count > HAMMER_RW_NO_WLOCK_COUNT)
+ stop = arg->stop = 1;
+ if (arg->lock_check) {
+ ASSERT(ATOMIC_READ(&arg->is_locked) == -1);
+ ATOMIC_SET(&arg->is_locked, 0);
+ }
+ RWMUTEX_WUNLOCK(arg->rwlock);
+ } while (!stop);
+ return NULL;
+}
+
+static void *
+hammer_rw_r(void *varg)
+{
+ hammer_rw_t *arg = varg;
+ int stop;
+ do {
+ RWMUTEX_RLOCK(arg->rwlock);
+ if (arg->lock_check) {
+ ASSERT(ATOMIC_READ(&arg->is_locked) >= 0);
+ ATOMIC_INC(&arg->is_locked);
+ }
+ stop = arg->stop;
+ if (arg->lock_check) {
+ ASSERT(ATOMIC_READ(&arg->is_locked) > 0);
+ ATOMIC_DEC(&arg->is_locked);
+ }
+ RWMUTEX_RUNLOCK(arg->rwlock);
+ } while (!stop);
+ return NULL;
+}
+
+
+static ERL_NIF_TERM hammer_rw_test(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
+{
+ hammer_rw_t arg;
+ char buf[10];
+ int res, freqread, i;
+ THR_ID tid[HAMMER_RW_NO_THREADS];
+
+ if (argc != 1)
+ goto badarg;
+
+ arg.lock_check = get_bool(env, argv[0]);
+ if (arg.lock_check < 0)
+ goto badarg;
+
+ ATOMIC_INIT(&arg.is_locked, 0);
+
+ freqread = 0;
+
+ restart:
+ arg.stop = 0;
+ arg.count = 0;
+
+ arg.rwlock = RWMUTEX_CREATE(freqread);
+
+ ASSERT(arg.rwlock);
+
+ for (i = 0; i < HAMMER_RW_NO_W_THREADS; i++)
+ ASSERT(THR_CREATE(&tid[i], hammer_rw_w, &arg, NULL) == 0);
+ for (; i < HAMMER_RW_NO_THREADS; i++)
+ ASSERT(THR_CREATE(&tid[i], hammer_rw_r, &arg, NULL) == 0);
+ for (i = 0; i < HAMMER_RW_NO_THREADS; i++)
+ ASSERT(THR_JOIN(tid[i], NULL) == 0);
+
+ ASSERT(!ATOMIC_READ(&arg.is_locked));
+
+ RWMUTEX_DESTROY(arg.rwlock);
+
+ if (HAVE_FREQREAD_SUPPORT && !freqread) {
+ freqread = 1;
+ goto restart;
+ }
+
+ if (freqread)
+ return enif_make_atom(env, "ok");
+ else
+ return enif_make_tuple2(env,
+ enif_make_atom(env,
+ "comment"),
+ enif_make_string(env,
+ "No frequent read test made.",
+ ERL_NIF_LATIN1));
+ badarg:
+ return enif_make_badarg(env);
+}
+
+/*
+ * Hammer try rwlock testcase
+ */
+
+#define HAMMER_TRYRW_NO_W_THREADS 10
+#define HAMMER_TRYRW_NO_THREADS 20
+#define HAMMER_TRYRW_NO_WLOCK_COUNT 10000000
+#define HAMMER_TRYRW_NO_RLOCK_COUNT 10000000
+#define HAMMER_TRYRW_NO_WLOCK_WAIT_COUNT ((10*HAMMER_TRYRW_NO_WLOCK_COUNT)/8)
+#define HAMMER_TRYRW_NO_RLOCK_WAIT_COUNT ((10*HAMMER_TRYRW_NO_RLOCK_COUNT)/8)
+
+typedef struct {
+ RWMUTEX_T *rwlock;
+ ATOMIC_T is_locked;
+ int lock_check;
+ int w_count;
+ ATOMIC_T r_count;
+} hammer_tryrw_t;
+
+static void *
+hammer_tryrw_w(void *varg)
+{
+ hammer_tryrw_t *arg = varg;
+ int stop = 0;
+ int wait = 0;
+ do {
+ while (EBUSY == RWMUTEX_TRYWLOCK(arg->rwlock));
+ if (arg->lock_check) {
+ ASSERT(!ATOMIC_READ(&arg->is_locked));
+ ATOMIC_SET(&arg->is_locked, -1);
+ }
+ if (++arg->w_count > HAMMER_TRYRW_NO_WLOCK_COUNT)
+ stop = 1;
+ else if (arg->w_count > HAMMER_TRYRW_NO_RLOCK_WAIT_COUNT)
+ wait = 1;
+ if (arg->lock_check) {
+ ASSERT(ATOMIC_READ(&arg->is_locked) == -1);
+ ATOMIC_SET(&arg->is_locked, 0);
+ }
+ RWMUTEX_WUNLOCK(arg->rwlock);
+ if (wait)
+ milli_sleep(1);
+ } while (!stop);
+ return NULL;
+}
+
+static void *
+hammer_tryrw_r(void *varg)
+{
+ hammer_tryrw_t *arg = varg;
+ long r_count;
+ int stop = 0;
+ int wait = 0;
+ do {
+ while (EBUSY == RWMUTEX_TRYRLOCK(arg->rwlock));
+ if (arg->lock_check) {
+ ASSERT(ATOMIC_READ(&arg->is_locked) >= 0);
+ ATOMIC_INC(&arg->is_locked);
+ }
+ ATOMIC_INC(&arg->r_count);
+ r_count = ATOMIC_READ(&arg->r_count);
+ if (r_count > HAMMER_TRYRW_NO_RLOCK_COUNT)
+ stop = 1;
+ else if (r_count > HAMMER_TRYRW_NO_RLOCK_WAIT_COUNT)
+ wait = 1;
+ if (arg->lock_check) {
+ ASSERT(ATOMIC_READ(&arg->is_locked) > 0);
+ ATOMIC_DEC(&arg->is_locked);
+ }
+ RWMUTEX_RUNLOCK(arg->rwlock);
+ if (wait)
+ milli_sleep(1);
+ } while (!stop);
+ return NULL;
+}
+
+
+static ERL_NIF_TERM hammer_tryrw_test(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
+{
+ hammer_tryrw_t arg;
+ char buf[10];
+ int res, freqread, i;
+ THR_ID tid[HAMMER_TRYRW_NO_THREADS];
+
+ if (argc != 1)
+ goto badarg;
+
+ arg.lock_check = get_bool(env, argv[0]);
+ if (arg.lock_check < 0)
+ goto badarg;
+
+ ATOMIC_INIT(&arg.is_locked, 0);
+ freqread = 0;
+
+ restart:
+
+ arg.w_count = 0;
+ ATOMIC_INIT(&arg.r_count, 0);
+
+ arg.rwlock = RWMUTEX_CREATE(freqread);
+
+ ASSERT(arg.rwlock);
+
+ for (i = 0; i < HAMMER_TRYRW_NO_W_THREADS; i++)
+ ASSERT(THR_CREATE(&tid[i], hammer_tryrw_w, &arg, NULL) == 0);
+ for (; i < HAMMER_TRYRW_NO_THREADS; i++)
+ ASSERT(THR_CREATE(&tid[i], hammer_tryrw_r, &arg, NULL) == 0);
+ for (i = 0; i < HAMMER_TRYRW_NO_THREADS; i++)
+ ASSERT(THR_JOIN(tid[i], NULL) == 0);
+
+ ASSERT(!ATOMIC_READ(&arg.is_locked));
+
+ RWMUTEX_DESTROY(arg.rwlock);
+
+ if (HAVE_FREQREAD_SUPPORT && !freqread) {
+ freqread = 1;
+ goto restart;
+ }
+
+ if (freqread)
+ return enif_make_atom(env, "ok");
+ else
+ return enif_make_tuple2(env,
+ enif_make_atom(env,
+ "comment"),
+ enif_make_string(env,
+ "No frequent read test made.",
+ ERL_NIF_LATIN1));
+ badarg:
+ return enif_make_badarg(env);
+}
+
+typedef struct {
+ int lock_check;
+ ATOMIC_T is_locked;
+ RWMUTEX_T *rwlock;
+} rwlock_resource_t;
+
+static void
+rwlock_destructor(ErlNifEnv* env, void* obj)
+{
+ rwlock_resource_t *rwlr = obj;
+ if (rwlr->lock_check)
+ ASSERT(!ATOMIC_READ(&rwlr->is_locked));
+ RWMUTEX_DESTROY(rwlr->rwlock);
+}
+
+/*
+ * create_rwlock(FreqRead, LockCheck)
+ */
+
+static ERL_NIF_TERM
+create_rwlock(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
+{
+ int lock_check, freqread;
+ ERL_NIF_TERM rwlock_term;
+ rwlock_resource_t *rwlr;
+ char buf[100];
+
+ if (argc != 2)
+ goto badarg;
+
+ freqread = get_bool(env, argv[0]);
+ if (freqread < 0)
+ goto badarg;
+
+ if (!HAVE_FREQREAD_SUPPORT && freqread)
+ return enif_make_atom(env, "enotsup");
+
+ lock_check = get_bool(env, argv[1]);
+ if (lock_check < 0)
+ goto badarg;
+
+ rwlr = enif_alloc_resource(enif_priv_data(env), sizeof(rwlock_resource_t));
+ rwlr->lock_check = lock_check;
+ ATOMIC_INIT(&rwlr->is_locked, 0);
+ rwlr->rwlock = RWMUTEX_CREATE(freqread);
+ rwlock_term = enif_make_resource(env, rwlr);
+ enif_release_resource(rwlr);
+ return rwlock_term;
+
+ badarg:
+ return enif_make_badarg(env);
+}
+
+/*
+ * rwlock_op(RWLock, Blocking, WriteOp, WaitTime)
+ */
+
+static ERL_NIF_TERM
+rwlock_op(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
+{
+ rwlock_resource_t *rwlr;
+ int blocking, write, wait_locked, wait_unlocked;
+
+ if (argc != 5)
+ goto badarg;
+
+ if (!enif_get_resource(env, argv[0], enif_priv_data(env), (void **) &rwlr))
+ goto badarg;
+
+ blocking = get_bool(env, argv[1]);
+ if (blocking < 0)
+ goto badarg;
+
+ write = get_bool(env, argv[2]);
+ if (write < 0)
+ goto badarg;
+
+ if (!enif_get_int(env, argv[3], &wait_locked))
+ goto badarg;
+ if (wait_locked < 0)
+ goto badarg;
+
+ if (!enif_get_int(env, argv[4], &wait_unlocked))
+ goto badarg;
+ if (wait_unlocked < 0)
+ goto badarg;
+
+ if (write) {
+ if (blocking)
+ RWMUTEX_WLOCK(rwlr->rwlock);
+ else
+ while (EBUSY == RWMUTEX_TRYWLOCK(rwlr->rwlock));
+ if (rwlr->lock_check) {
+ ASSERT(!ATOMIC_READ(&rwlr->is_locked));
+ ATOMIC_SET(&rwlr->is_locked, -1);
+ }
+ }
+ else {
+ if (blocking)
+ RWMUTEX_RLOCK(rwlr->rwlock);
+ else
+ while (EBUSY == RWMUTEX_TRYRLOCK(rwlr->rwlock));
+ if (rwlr->lock_check) {
+ ASSERT(ATOMIC_READ(&rwlr->is_locked) >= 0);
+ ATOMIC_INC(&rwlr->is_locked);
+ }
+ }
+
+ if (wait_locked)
+ milli_sleep(wait_locked);
+
+ if (write) {
+ if (rwlr->lock_check) {
+ ASSERT(ATOMIC_READ(&rwlr->is_locked) == -1);
+ ATOMIC_SET(&rwlr->is_locked, 0);
+ }
+ RWMUTEX_WUNLOCK(rwlr->rwlock);
+ }
+ else {
+ if (rwlr->lock_check) {
+ ASSERT(ATOMIC_READ(&rwlr->is_locked) > 0);
+ ATOMIC_DEC(&rwlr->is_locked);
+ }
+ RWMUTEX_RUNLOCK(rwlr->rwlock);
+ }
+
+ if (wait_unlocked)
+ milli_sleep(wait_unlocked);
+
+ return enif_make_atom(env, "ok");
+ badarg:
+ return enif_make_badarg(env);
+}
+
+static int load_nif_lib(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
+{
+ *priv_data = enif_open_resource_type(env,
+ NULL,
+ "rwlock_resource",
+ rwlock_destructor,
+ ERL_NIF_RT_CREATE,
+ NULL);
+ if (*priv_data)
+ return 0;
+ else
+ return -1;
+}
+
+/*
+ * 0 -> false
+ * >0 -> true
+ * <0 -> error
+ */
+
+static int
+get_bool(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ int res;
+ char buf[10];
+
+ res = enif_get_atom(env, term, buf, sizeof(buf), ERL_NIF_LATIN1);
+ if (res == 0)
+ return -1;
+ if (strcmp("false", buf) == 0)
+ return 0;
+ else if (strcmp("true", buf) == 0)
+ return 1;
+ else
+ return -1;
+}
+
+static int
+fail(const char *file, int line, const char *function, const char *assertion)
+{
+ fprintf(stderr, "%s:%d: Assertion failed in %s(): %s\n",
+ file, line, function, assertion);
+ abort();
+}
+
+static void
+milli_sleep(int ms)
+{
+#ifdef __WIN32__
+ Sleep(ms);
+#else
+ while (erts_milli_sleep(ms) != 0);
+#endif
+}
+
+static ErlNifFunc nif_funcs[] = {
+ {"long_rw_test", 0, long_rw_test},
+ {"hammer_rw_test", 1, hammer_rw_test},
+ {"hammer_tryrw_test", 1, hammer_tryrw_test},
+ {"create_rwlock", 2, create_rwlock},
+ {"rwlock_op", 5, rwlock_op}
+};
+
+ERL_NIF_INIT(mtx_SUITE, nif_funcs, load_nif_lib, NULL, NULL, NULL)
diff --git a/erts/emulator/test/nested_SUITE.erl b/erts/emulator/test/nested_SUITE.erl
index 310892424e..f889712f46 100644
--- a/erts/emulator/test/nested_SUITE.erl
+++ b/erts/emulator/test/nested_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,11 +19,33 @@
-module(nested_SUITE).
--export([all/1, case_in_case/1, case_in_after/1, catch_in_catch/1, bif_in_bif/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ case_in_case/1, case_in_after/1, catch_in_catch/1, bif_in_bif/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [case_in_case, case_in_after, catch_in_catch,
+ bif_in_bif].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [case_in_case, case_in_after, catch_in_catch, bif_in_bif].
case_in_case(suite) -> [];
case_in_case(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index f45cfa3e4a..54cbf6b974 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,14 +23,18 @@
-define(CHECK(Exp,Got), check(Exp,Got,?LINE)).
%%-define(CHECK(Exp,Got), ?line Exp = Got).
--include("test_server.hrl").
-
--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_binary/1, resource_takeover/1,
- threading/1, send/1, send2/1, send3/1, send_threaded/1, neg/1, is_checks/1,
+-include_lib("test_server/include/test_server.hrl").
+
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2, basic/1, 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_binary/1,
+ resource_takeover/1,
+ threading/1, send/1, send2/1, send3/1, send_threaded/1, neg/1,
+ is_checks/1,
get_length/1, make_atom/1, make_string/1]).
-export([many_args_100/100]).
@@ -40,7 +44,7 @@
%% 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_resource/1,get_resource/2,release_resource/1,last_resource_dtor_call/0, suite/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]).
@@ -48,17 +52,37 @@
-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_binary,
- resource_takeover, threading, send, send2, send3, send_threaded, neg, is_checks,
- get_length, make_atom, make_string].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic, reload, upgrade, heap_frag, types, many_args,
+ binaries, get_string, get_atom, api_macros, from_array,
+ iolist_as_binary, resource, resource_binary,
+ resource_takeover, threading, send, send2, send3,
+ send_threaded, neg, is_checks, get_length, make_atom,
+ make_string].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-%%init_per_testcase(_Case, Config) ->
-%% ?line Dog = ?t:timetrap(?t:seconds(60*60*24)),
-%% [{watchdog, Dog}|Config].
+init_per_testcase(_Case, Config) ->
+% ?line Dog = ?t:timetrap(?t:seconds(60*60*24)),
+ Config.
-fin_per_testcase(_Func, _Config) ->
+end_per_testcase(_Func, _Config) ->
%%Dog = ?config(watchdog, Config),
%%?t:timetrap_cancel(Dog),
P1 = code:purge(nif_mod),
@@ -73,7 +97,7 @@ basic(Config) when is_list(Config) ->
?line true = (lib_version() =/= undefined),
?line [{load,1,1,101},{lib_version,1,2,102}] = call_history(),
?line [] = call_history(),
- ?line [?MODULE] = erlang:system_info(taints),
+ ?line true = lists:member(?MODULE, erlang:system_info(taints)),
ok.
reload(doc) -> ["Test reload callback in nif lib"];
@@ -107,7 +131,8 @@ reload(Config) when is_list(Config) ->
?line true = erlang:purge_module(nif_mod),
?line [{unload,1,3,103}] = nif_mod_call_history(),
- ?line [?MODULE, nif_mod] = erlang:system_info(taints),
+ ?line true = lists:member(?MODULE, erlang:system_info(taints)),
+ ?line true = lists:member(nif_mod, erlang:system_info(taints)),
?line verify_tmpmem(TmpMem),
ok.
@@ -197,7 +222,8 @@ upgrade(Config) when is_list(Config) ->
?line true = erlang:purge_module(nif_mod),
?line [{unload,2,4,204}] = nif_mod_call_history(),
- ?line [?MODULE, nif_mod] = erlang:system_info(taints),
+ ?line true = lists:member(?MODULE, erlang:system_info(taints)),
+ ?line true = lists:member(nif_mod, erlang:system_info(taints)),
?line verify_tmpmem(TmpMem),
ok.
@@ -727,7 +753,8 @@ resource_takeover(Config) when is_list(Config) ->
?line ok = forget_resource(AN4),
?line [] = nif_mod_call_history(),
- ?line [?MODULE, nif_mod] = erlang:system_info(taints),
+ ?line true = lists:member(?MODULE, erlang:system_info(taints)),
+ ?line true = lists:member(nif_mod, erlang:system_info(taints)),
?line verify_tmpmem(TmpMem),
ok.
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.erl b/erts/emulator/test/nif_SUITE_data/nif_mod.erl
index 7888a589e7..b99a2c90ee 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.erl
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.erl
@@ -19,7 +19,7 @@
-module(nif_mod).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-export([load_nif_lib/2, load_nif_lib/3, start/0, lib_version/0, call_history/0,
get_priv_data_ptr/0, make_new_resource/2, get_resource/2]).
diff --git a/erts/emulator/test/nif_SUITE_data/tester.erl b/erts/emulator/test/nif_SUITE_data/tester.erl
index 9df2158200..b393e29b82 100644
--- a/erts/emulator/test/nif_SUITE_data/tester.erl
+++ b/erts/emulator/test/nif_SUITE_data/tester.erl
@@ -1,6 +1,6 @@
-module(tester).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-export([load_nif_lib/2, run/0]).
diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl
index f3d9eb783b..416fdad941 100644
--- a/erts/emulator/test/node_container_SUITE.erl
+++ b/erts/emulator/test/node_container_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -29,10 +29,12 @@
%-define(line_trace, 1).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%-compile(export_all).
--export([all/1, init_per_testcase/2, fin_per_testcase/2, end_per_suite/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, init_per_testcase/2,
+ end_per_testcase/2,
node_container_refc_check/1]).
-export([term_to_binary_to_term_eq/1,
@@ -55,25 +57,30 @@
-define(DEFAULT_TIMEOUT, ?t:minutes(10)).
-all(doc) -> [];
-all(suite) ->
- [term_to_binary_to_term_eq,
- round_trip_eq,
- cmp,
- ref_eq,
- node_table_gc,
- dist_link_refc,
- dist_monitor_refc,
- node_controller_refc,
- ets_refc,
- match_spec_refc,
- timer_refc,
- otp_4715,
- pid_wrap,
- port_wrap,
- bad_nc,
- unique_pid,
- iter_max_procs].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [term_to_binary_to_term_eq, round_trip_eq, cmp, ref_eq,
+ node_table_gc, dist_link_refc, dist_monitor_refc,
+ node_controller_refc, ets_refc, match_spec_refc,
+ timer_refc, otp_4715, pid_wrap, port_wrap, bad_nc,
+ unique_pid, iter_max_procs].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ available_internal_state(false).
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
available_internal_state(Bool) when Bool == true; Bool == false ->
case {Bool,
@@ -95,14 +102,11 @@ init_per_testcase(_Case, Config) when is_list(Config) ->
available_internal_state(true),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-end_per_suite(_Config) ->
- available_internal_state(false).
-
%%%
%%% The test cases -------------------------------------------------------------
%%%
diff --git a/erts/emulator/test/nofrag_SUITE.erl b/erts/emulator/test/nofrag_SUITE.erl
index ece55f433c..9287158981 100644
--- a/erts/emulator/test/nofrag_SUITE.erl
+++ b/erts/emulator/test/nofrag_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -19,9 +19,11 @@
-module(nofrag_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,end_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
error_handler/1,error_handler_apply/1,
error_handler_fixed_apply/1,error_handler_fun/1,
error_handler_tuple_fun/1,
@@ -30,9 +32,28 @@
%% Exported functions for an error_handler module.
-export([undefined_function/3,undefined_lambda/3,breakpoint/3]).
-all(suite) ->
- [error_handler,error_handler_apply,error_handler_fixed_apply,
- error_handler_fun,error_handler_tuple_fun,debug_breakpoint].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [error_handler, error_handler_apply,
+ error_handler_fixed_apply, error_handler_fun,
+ error_handler_tuple_fun, debug_breakpoint].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(3)),
diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl
index d009994e2d..bf101b038d 100644
--- a/erts/emulator/test/num_bif_SUITE.erl
+++ b/erts/emulator/test/num_bif_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-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
@@ -19,7 +19,7 @@
-module(num_bif_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Tests the BIFs:
%% abs/1
@@ -31,15 +31,36 @@
%% round/1
%% trunc/1
--export([all/1, t_abs/1, t_float/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, t_abs/1, t_float/1,
t_float_to_list/1, t_integer_to_list/1,
t_list_to_integer/1,
- t_list_to_float/1, t_list_to_float_safe/1, t_list_to_float_risky/1,
+ t_list_to_float_safe/1, t_list_to_float_risky/1,
t_round/1, t_trunc/1]).
-all(suite) -> [t_abs, t_float, t_float_to_list, t_integer_to_list,
- t_list_to_float, t_list_to_integer,
- t_round, t_trunc].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [t_abs, t_float, t_float_to_list, t_integer_to_list,
+ {group, t_list_to_float}, t_list_to_integer, t_round,
+ t_trunc].
+
+groups() ->
+ [{t_list_to_float, [],
+ [t_list_to_float_safe, t_list_to_float_risky]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
t_abs(Config) when is_list(Config) ->
%% Floats.
@@ -140,7 +161,6 @@ t_integer_to_list(Config) when is_list(Config) ->
%% Tests list_to_float/1.
-t_list_to_float(suite) -> [t_list_to_float_safe, t_list_to_float_risky].
t_list_to_float_safe(Config) when is_list(Config) ->
?line 0.0 = list_to_float(id("0.0")),
diff --git a/erts/emulator/test/old_mod.erl b/erts/emulator/test/old_mod.erl
index 6c47ba6f8f..124842390a 100644
--- a/erts/emulator/test/old_mod.erl
+++ b/erts/emulator/test/old_mod.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/test/old_scheduler_SUITE.erl b/erts/emulator/test/old_scheduler_SUITE.erl
index 70348f64db..6f9c0a9dab 100644
--- a/erts/emulator/test/old_scheduler_SUITE.erl
+++ b/erts/emulator/test/old_scheduler_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,24 +19,44 @@
-module(old_scheduler_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
-export([equal/1, many_low/1, few_low/1, max/1, high/1]).
-define(default_timeout, ?t:minutes(11)).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
case catch erlang:system_info(modified_timing_level) of
Level when is_integer(Level) ->
{skipped,
- "Modified timing (level " ++ integer_to_list(Level)
- ++ ") is enabled. Testcases gets messed up by modfied "
- "timing."};
- _ ->
- [equal, many_low, few_low, max, high]
+ "Modified timing (level " ++
+ integer_to_list(Level) ++
+ ") is enabled. Testcases gets messed "
+ "up by modfied timing."};
+ _ -> [equal, many_low, few_low, max, high]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------------------------
%% TEST SUITE DESCRIPTION
%%
@@ -63,7 +83,7 @@ init_per_testcase(_Case, Config) ->
?line MS = erlang:system_flag(multi_scheduling, block),
[{prio,Prio},{watchdog,Dog},{multi_scheduling, MS}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
erlang:system_flag(multi_scheduling, unblock),
Dog=?config(watchdog, Config),
Prio=?config(prio, Config),
diff --git a/erts/emulator/test/op_SUITE.erl b/erts/emulator/test/op_SUITE.erl
index 55d8d9ab0f..7bea35e980 100644
--- a/erts/emulator/test/op_SUITE.erl
+++ b/erts/emulator/test/op_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,22 +19,43 @@
-module(op_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
bsl_bsr/1,logical/1,t_not/1,relop_simple/1,relop/1,complex_relop/1]).
-export([]).
-import(lists, [foldl/3,flatmap/2]).
-all(suite) ->
- [bsl_bsr,logical,t_not,relop_simple,relop,complex_relop].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [bsl_bsr, logical, t_not, relop_simple, relop,
+ complex_relop].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(3)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index a7476ca9bb..6da9a7e0ad 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.erl
@@ -73,18 +73,19 @@
%%
--export([all/1, init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
init_per_suite/1, end_per_suite/1,
- stream/1, stream_small/1, stream_big/1,
+ stream_small/1, stream_big/1,
basic_ping/1, slow_writes/1, bad_packet/1, bad_port_messages/1,
- multiple_packets/1, mul_basic/1, mul_slow_writes/1,
+ mul_basic/1, mul_slow_writes/1,
dying_port/1, port_program_with_path/1,
open_input_file_port/1, open_output_file_port/1,
iter_max_ports/1, eof/1, input_only/1, output_only/1,
name1/1,
- t_binary/1, options/1, parallell/1, t_exit/1,
+ t_binary/1, parallell/1, t_exit/1,
env/1, bad_env/1, cd/1, exit_status/1,
- tps/1, tps_16_bytes/1, tps_1K/1, line/1, stderr_to_stdout/1,
+ tps_16_bytes/1, tps_1K/1, line/1, stderr_to_stdout/1,
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,
@@ -98,31 +99,42 @@
-export([otp_3906_forker/5, otp_3906_start_forker_starter/4]).
-export([env_slave_main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
-all(suite) ->
- [
- otp_6224, stream, basic_ping, slow_writes, bad_packet,
- bad_port_messages, options, multiple_packets, parallell,
- dying_port, port_program_with_path,
- open_input_file_port, open_output_file_port,
- name1,
- env, bad_env, cd, exit_status,
- iter_max_ports, t_exit, tps, line, stderr_to_stdout,
- otp_3906, otp_4389, win_massive, mix_up_ports,
- otp_5112, otp_5119,
- exit_status_multi_scheduling_block,
- ports, spawn_driver, spawn_executable, close_deaf_port,
- unregister_name
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [otp_6224, {group, stream}, basic_ping, slow_writes,
+ bad_packet, bad_port_messages, {group, options},
+ {group, multiple_packets}, parallell, dying_port,
+ port_program_with_path, open_input_file_port,
+ open_output_file_port, name1, env, bad_env, cd,
+ exit_status, iter_max_ports, t_exit, {group, tps}, line,
+ stderr_to_stdout, otp_3906, otp_4389, win_massive,
+ mix_up_ports, otp_5112, otp_5119,
+ exit_status_multi_scheduling_block, ports, spawn_driver,
+ spawn_executable, close_deaf_port, unregister_name].
+
+groups() ->
+ [{stream, [], [stream_small, stream_big]},
+ {options, [], [t_binary, eof, input_only, output_only]},
+ {multiple_packets, [], [mul_basic, mul_slow_writes]},
+ {tps, [], [tps_16_bytes, tps_1K]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-define(DEFAULT_TIMEOUT, ?t:minutes(5)).
init_per_testcase(Case, Config) ->
[{testcase, Case} |Config].
-fin_per_testcase(_Case, _Config) ->
+end_per_testcase(_Case, _Config) ->
ok.
init_per_suite(Config) when is_list(Config) ->
@@ -191,7 +203,6 @@ win_massive_loop(P,N) ->
-stream(suite) -> [stream_small, stream_big].
%% Test that we can send a stream of bytes and get it back.
%% We will send only a small amount of data, to avoid deadlock.
@@ -304,7 +315,6 @@ bad_message(PortTest, Message) ->
%% Tests various options (stream and {packet, Number} are implicitly
%% tested in other test cases).
-options(suite) -> [t_binary, eof, input_only, output_only].
%% Tests the 'binary' option for a port.
@@ -416,7 +426,6 @@ output_and_verify(Config, Filename, Options, Data) ->
%% Test that receiving several packages written in the same
%% write operation works.
-multiple_packets(suite) -> [mul_basic, mul_slow_writes].
%% Basic test of receiving multiple packages, written in
%% one operation by the other end.
@@ -740,7 +749,6 @@ suicide_port(Config) when is_list(Config) ->
?line exit(Port, die),
?line receive after infinity -> ok end.
-tps(suite) -> [tps_16_bytes, tps_1K].
tps_16_bytes(doc) -> "";
tps_16_bytes(suite) -> [];
@@ -1049,8 +1057,10 @@ otp_3906(Config) when is_list(Config) ->
-define(OTP_3906_MAX_CONC_OSP, 50).
otp_3906(Config, OSName) ->
- ?line TSDir = filename:dirname(code:which(test_server)),
- ?line {ok, Variables} = file:consult(filename:join(TSDir, "variables")),
+ ?line DataDir = filename:dirname(proplists:get_value(data_dir,Config)),
+ ?line {ok, Variables} = file:consult(
+ filename:join([DataDir,"..","..",
+ "test_server","variables"])),
case lists:keysearch('CC', 1, Variables) of
{value,{'CC', CC}} ->
SuiteDir = filename:dirname(code:which(?MODULE)),
@@ -2302,14 +2312,35 @@ load_driver(Dir, Driver) ->
end.
-close_deaf_port(doc) -> ["Send data to port program that does not read it, then close port."];
+close_deaf_port(doc) -> ["Send data to port program that does not read it, then close port."
+ "Primary targeting Windows to test threaded_handle_closer in sys.c"];
close_deaf_port(suite) -> [];
close_deaf_port(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(100)),
?line DataDir = ?config(data_dir, Config),
?line DeadPort = os:find_executable("dead_port", DataDir),
-
?line Port = open_port({spawn,DeadPort++" 60"},[]),
?line erlang:port_command(Port,"Hello, can you hear me!?!?"),
?line port_close(Port),
- ok.
+
+ Res = close_deaf_port_1(0, DeadPort),
+ io:format("Waiting for OS procs to terminate...\n"),
+ receive after 5*1000 -> ok end,
+ ?line test_server:timetrap_cancel(Dog),
+ Res.
+
+close_deaf_port_1(1000, _) ->
+ ok;
+close_deaf_port_1(N, Cmd) ->
+ Timeout = integer_to_list(random:uniform(5*1000)),
+ ?line try open_port({spawn_executable,Cmd},[{args,[Timeout]}]) of
+ Port ->
+ ?line erlang:port_command(Port,"Hello, can you hear me!?!?"),
+ ?line port_close(Port),
+ close_deaf_port_1(N+1, Cmd)
+ catch
+ _:eagain ->
+ {comment, "Could not spawn more than " ++ integer_to_list(N) ++ " OS processes."}
+ end.
+
+
diff --git a/erts/emulator/test/port_SUITE_data/dead_port.c b/erts/emulator/test/port_SUITE_data/dead_port.c
index 6fa77112be..68e96fbf14 100644
--- a/erts/emulator/test/port_SUITE_data/dead_port.c
+++ b/erts/emulator/test/port_SUITE_data/dead_port.c
@@ -72,14 +72,14 @@ char *argv[];
{
int x;
if (argc < 2) {
- fprintf(stderr,"Usage %s <seconds>\n",argv[0]);
+ fprintf(stderr,"Usage %s <milliseconds>\n",argv[0]);
return 1;
}
if ((x = atoi(argv[1])) <= 0) {
- fprintf(stderr,"Usage %s <seconds>\n",argv[0]);
+ fprintf(stderr,"Usage %s <milliseconds>\n",argv[0]);
return 1;
}
- delay(x*1000);
+ delay(x);
return 0;
}
diff --git a/erts/emulator/test/port_bif_SUITE.erl b/erts/emulator/test/port_bif_SUITE.erl
index f4e0bb9fa8..946978c580 100644
--- a/erts/emulator/test/port_bif_SUITE.erl
+++ b/erts/emulator/test/port_bif_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,25 +20,47 @@
-module(port_bif_SUITE).
--export([all/1, command/1, command_e/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, command/1,
command_e_1/1, command_e_2/1, command_e_3/1, command_e_4/1,
- port_info/1, port_info1/1, port_info2/1,
+ port_info1/1, port_info2/1,
connect/1, control/1, echo_to_busy/1]).
-export([do_command_e_1/1, do_command_e_2/1, do_command_e_4/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [command, {group, port_info}, connect, control,
+ echo_to_busy].
+
+groups() ->
+ [{command_e, [],
+ [command_e_1, command_e_2, command_e_3, command_e_4]},
+ {port_info, [], [port_info1, port_info2]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [command, port_info, connect, control, echo_to_busy].
init_per_testcase(_Func, Config) when is_list(Config) ->
Dog=test_server:timetrap(test_server:minutes(10)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) when is_list(Config) ->
+end_per_testcase(_Func, Config) when is_list(Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
@@ -69,11 +91,6 @@ do_command(P, Data) ->
end.
-command_e(suite) -> [command_e_1,
- command_e_2,
- command_e_3,
- command_e_4];
-command_e(doc) -> "Tests port_command/2 with errors".
%% port_command/2: badarg 1st arg
command_e_1(Config) when is_list(Config) ->
@@ -161,7 +178,6 @@ do_command_e_4(Program) ->
?line erlang:port_command(P, Data),
exit(survived).
-port_info(suite) -> [port_info1, port_info2].
%% Tests the port_info/1 BIF
port_info1(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index 77f850d0fb..f7553e5815 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -25,12 +25,13 @@
%% process_info/1,2
%% register/2 (partially)
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(heap_binary_size, 64).
--export([all/1, spawn_with_binaries/1,
- t_exit_1/1, t_exit_2/1, t_exit_2_other/1, t_exit_2_other_normal/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, spawn_with_binaries/1,
+ t_exit_1/1, t_exit_2_other/1, t_exit_2_other_normal/1,
self_exit/1, normal_suicide_exit/1, abnormal_suicide_exit/1,
t_exit_2_catch/1, trap_exit_badarg/1, trap_exit_badarg_in_bif/1,
exit_and_timeout/1, exit_twice/1,
@@ -46,39 +47,67 @@
processes_large_tab/1, processes_default_tab/1, processes_small_tab/1,
processes_this_tab/1, processes_apply_trap/1,
processes_last_call_trap/1, processes_gc_trap/1,
- processes_term_proc_list/1, processes_bif/1,
- otp_7738/1, otp_7738_waiting/1, otp_7738_suspended/1,
+ processes_term_proc_list/1,
+ otp_7738_waiting/1, otp_7738_suspended/1,
otp_7738_resume/1]).
-export([prio_server/2, prio_client/2]).
--export([init_per_testcase/2, fin_per_testcase/2, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([hangaround/2, processes_bif_test/0, do_processes/1,
processes_term_proc_list_test/1]).
-all(suite) ->
- [spawn_with_binaries, t_exit_1, t_exit_2,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [spawn_with_binaries, t_exit_1, {group, t_exit_2},
trap_exit_badarg, trap_exit_badarg_in_bif,
- t_process_info, process_info_other_msg, process_info_other_dist_msg,
- process_info_2_list,
- process_info_lock_reschedule, process_info_lock_reschedule2,
- process_status_exiting,
- bump_reductions, low_prio, yield, yield2, otp_4725, bad_register,
- garbage_collect, process_info_messages, process_flag_badarg, process_flag_heap_size,
- spawn_opt_heap_size, otp_6237, processes_bif, otp_7738].
+ t_process_info, process_info_other_msg,
+ process_info_other_dist_msg, process_info_2_list,
+ process_info_lock_reschedule,
+ process_info_lock_reschedule2, process_status_exiting,
+ bump_reductions, low_prio, yield, yield2, otp_4725,
+ bad_register, garbage_collect, process_info_messages,
+ process_flag_badarg, process_flag_heap_size,
+ spawn_opt_heap_size, otp_6237, {group, processes_bif},
+ {group, otp_7738}].
+
+groups() ->
+ [{t_exit_2, [],
+ [t_exit_2_other, t_exit_2_other_normal, self_exit,
+ normal_suicide_exit, abnormal_suicide_exit,
+ t_exit_2_catch, exit_and_timeout, exit_twice]},
+ {processes_bif, [],
+ [processes_large_tab, processes_default_tab,
+ processes_small_tab, processes_this_tab,
+ processes_last_call_trap, processes_apply_trap,
+ processes_gc_trap, processes_term_proc_list]},
+ {otp_7738, [],
+ [otp_7738_waiting, otp_7738_suspended,
+ otp_7738_resume]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ catch erts_debug:set_internal_state(available_internal_state, false),
+ Config.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(10)),
[{watchdog, Dog},{testcase, Func}|Config].
-fin_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+end_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
-end_per_suite(Config) ->
- catch erts_debug:set_internal_state(available_internal_state, false),
- Config.
-
fun_spawn(Fun) ->
spawn_link(erlang, apply, [Fun, []]).
@@ -117,10 +146,6 @@ t_exit_1() ->
{'EXIT', Pid, Garbage} -> ok
end.
-t_exit_2(suite) -> [t_exit_2_other, t_exit_2_other_normal,
- self_exit, normal_suicide_exit,
- abnormal_suicide_exit, t_exit_2_catch,
- exit_and_timeout, exit_twice].
%% Tests exit/2 with a lot of data in the exit message.
t_exit_2_other(Config) when is_list(Config) ->
@@ -1227,17 +1252,6 @@ otp_6237_select_loop() ->
otp_6237_select_loop().
-processes_bif(doc) ->
- [];
-processes_bif(suite) ->
- [processes_large_tab,
- processes_default_tab,
- processes_small_tab,
- processes_this_tab,
- processes_last_call_trap,
- processes_apply_trap,
- processes_gc_trap,
- processes_term_proc_list].
-define(NoTestProcs, 10000).
-record(processes_bif_info, {min_start_reds,
@@ -1965,10 +1979,6 @@ processes_term_proc_list_test(MustChk) ->
?line erlang:system_flag(multi_scheduling, unblock),
?line as_expected.
-otp_7738(doc) ->
- [];
-otp_7738(suite) ->
- [otp_7738_waiting, otp_7738_suspended, otp_7738_resume].
otp_7738_waiting(doc) ->
[];
diff --git a/erts/emulator/test/pseudoknot_SUITE.erl b/erts/emulator/test/pseudoknot_SUITE.erl
index 907204cf93..5a7cdcecd5 100644
--- a/erts/emulator/test/pseudoknot_SUITE.erl
+++ b/erts/emulator/test/pseudoknot_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,9 +19,29 @@
-module(pseudoknot_SUITE).
--export([all/1,test/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,test/1]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [test].
test(Config) when is_list(Config) ->
statistics(runtime),
@@ -3274,13 +3294,13 @@ most_distant_atom(Sols) ->
maximum(map(sol_most_distant_atom, Sols)).
maximum([H|T]) ->
- max(T,H).
+ max1(T,H).
-max([H|T],M) when is_float(H), is_float(M), H > M ->
- max(T,H);
-max([_|T],M) ->
- max(T,M);
-max([],M) -> M.
+max1([H|T],M) when is_float(H), is_float(M), H > M ->
+ max1(T,H);
+max1([_|T],M) ->
+ max1(T,M);
+max1([],M) -> M.
map(_Func,[]) -> [];
map(Func,[H|T]) ->
diff --git a/erts/emulator/test/random_iolist.erl b/erts/emulator/test/random_iolist.erl
index 4bce347d9a..8f21b5a3b3 100644
--- a/erts/emulator/test/random_iolist.erl
+++ b/erts/emulator/test/random_iolist.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl
index 40ebf2bd21..2ac696b4c7 100644
--- a/erts/emulator/test/receive_SUITE.erl
+++ b/erts/emulator/test/receive_SUITE.erl
@@ -21,21 +21,40 @@
%% Tests receive after.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
call_with_huge_message_queue/1,receive_in_between/1]).
--export([init_per_testcase/2,fin_per_testcase/2]).
+-export([init_per_testcase/2,end_per_testcase/2]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [call_with_huge_message_queue, receive_in_between].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-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) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
diff --git a/erts/emulator/test/ref_SUITE.erl b/erts/emulator/test/ref_SUITE.erl
index fa77095efd..327d55fead 100644
--- a/erts/emulator/test/ref_SUITE.erl
+++ b/erts/emulator/test/ref_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,23 +19,44 @@
-module(ref_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2]).
-export([wrap_1/1]).
-export([loop_ref/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(_, Config) ->
?line Dog=test_server:timetrap(test_server:minutes(2)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_, Config) ->
+end_per_testcase(_, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) -> [wrap_1].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [wrap_1].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
wrap_1(doc) -> "Check that refs don't wrap around easily.";
wrap_1(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/register_SUITE.erl b/erts/emulator/test/register_SUITE.erl
index c03ee23b2e..d88df8d59d 100644
--- a/erts/emulator/test/register_SUITE.erl
+++ b/erts/emulator/test/register_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% 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
@@ -22,24 +22,43 @@
%-define(line_trace, 1).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%-compile(export_all).
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
-export([otp_8099/1]).
-define(DEFAULT_TIMEOUT, ?t:minutes(2)).
-all(doc) -> [];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[otp_8099].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, Dog}, {testcase, Case} | Config].
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
diff --git a/erts/emulator/test/save_calls_SUITE.erl b/erts/emulator/test/save_calls_SUITE.erl
index b56c4ad0b0..4929031794 100644
--- a/erts/emulator/test/save_calls_SUITE.erl
+++ b/erts/emulator/test/save_calls_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-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
@@ -19,17 +19,36 @@
-module(save_calls_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([save_calls_1/1,dont_break_reductions/1]).
-export([do_bopp/1, do_bipp/0, do_bepp/0]).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[save_calls_1, dont_break_reductions].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
dont_break_reductions(suite) ->
[];
dont_break_reductions(doc) ->
diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl
index 06442bfad6..f16d0ea429 100644
--- a/erts/emulator/test/scheduler_SUITE.erl
+++ b/erts/emulator/test/scheduler_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -30,10 +30,12 @@
%-define(line_trace, 1).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%-compile(export_all).
--export([all/1, init_per_testcase/2, fin_per_testcase/2, end_per_suite/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2, end_per_suite/1]).
-export([equal/1,
few_low/1,
@@ -44,7 +46,7 @@
equal_with_high/1,
equal_with_high_max/1,
bound_process/1,
- scheduler_bind/1,
+
scheduler_bind_types/1,
cpu_topology/1,
update_cpu_info/1,
@@ -57,21 +59,35 @@
-define(MIN_SCHEDULER_TEST_TIMEOUT, ?t:minutes(1)).
-all(doc) -> [];
-all(suite) ->
- [equal,
- few_low,
- many_low,
- equal_with_part_time_high,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [equal, few_low, many_low, equal_with_part_time_high,
equal_with_part_time_max,
- equal_and_high_with_part_time_max,
- equal_with_high,
- equal_with_high_max,
- bound_process,
- scheduler_bind,
- scheduler_suspend,
+ equal_and_high_with_part_time_max, equal_with_high,
+ equal_with_high_max, bound_process,
+ {group, scheduler_bind}, scheduler_suspend,
reader_groups].
+groups() ->
+ [{scheduler_bind, [],
+ [scheduler_bind_types, cpu_topology, update_cpu_info,
+ sct_cmd, sbt_cmd]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ catch erts_debug:set_internal_state(available_internal_state, false),
+ Config.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
process_flag(priority, max),
@@ -79,15 +95,11 @@ init_per_testcase(Case, Config) when is_list(Config) ->
OkRes = ok,
[{watchdog, Dog}, {testcase, Case}, {ok_res, OkRes} |Config].
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-end_per_suite(Config) ->
- catch erts_debug:set_internal_state(available_internal_state, false),
- Config.
-
-define(ERTS_RUNQ_CHECK_BALANCE_REDS_PER_SCHED, (2000*2000)).
-define(DEFAULT_TEST_REDS_PER_SCHED, 200000000).
@@ -247,12 +259,6 @@ bound_loop(NS, N, M, Sched) ->
Sched = erlang:system_info(scheduler_id),
bound_loop(NS, N-1, M, Sched).
-scheduler_bind(suite) ->
- [scheduler_bind_types,
- cpu_topology,
- update_cpu_info,
- sct_cmd,
- sbt_cmd].
-define(TOPOLOGY_A_CMD,
"+sct"
@@ -856,9 +862,9 @@ get_affinity_mask(Port, Status, Affinity) when Status == unknown;
{Port,{exit_status,S}} ->
get_affinity_mask(Port, S, Affinity)
end;
-get_affinity_mask(Port, Status, bad) ->
+get_affinity_mask(_Port, _Status, bad) ->
unknown;
-get_affinity_mask(Port, Status, Affinity) ->
+get_affinity_mask(_Port, _Status, Affinity) ->
Affinity.
get_affinity_mask() ->
@@ -1383,67 +1389,6 @@ reader_groups_map(CPUT, Groups) ->
%% Utils
%%
-tilera_cpu_topology() ->
- [{processor,[{node,[{core,{logical,0}},
- {core,{logical,1}},
- {core,{logical,2}},
- {core,{logical,8}},
- {core,{logical,9}},
- {core,{logical,10}},
- {core,{logical,11}},
- {core,{logical,16}},
- {core,{logical,17}},
- {core,{logical,18}},
- {core,{logical,19}},
- {core,{logical,24}},
- {core,{logical,25}},
- {core,{logical,27}},
- {core,{logical,29}}]},
- {node,[{core,{logical,3}},
- {core,{logical,4}},
- {core,{logical,5}},
- {core,{logical,6}},
- {core,{logical,7}},
- {core,{logical,12}},
- {core,{logical,13}},
- {core,{logical,14}},
- {core,{logical,15}},
- {core,{logical,20}},
- {core,{logical,21}},
- {core,{logical,22}},
- {core,{logical,23}},
- {core,{logical,28}},
- {core,{logical,30}}]},
- {node,[{core,{logical,31}},
- {core,{logical,36}},
- {core,{logical,37}},
- {core,{logical,38}},
- {core,{logical,44}},
- {core,{logical,45}},
- {core,{logical,46}},
- {core,{logical,47}},
- {core,{logical,51}},
- {core,{logical,52}},
- {core,{logical,53}},
- {core,{logical,54}},
- {core,{logical,55}},
- {core,{logical,60}},
- {core,{logical,61}}]},
- {node,[{core,{logical,26}},
- {core,{logical,32}},
- {core,{logical,33}},
- {core,{logical,34}},
- {core,{logical,35}},
- {core,{logical,39}},
- {core,{logical,40}},
- {core,{logical,41}},
- {core,{logical,42}},
- {core,{logical,43}},
- {core,{logical,48}},
- {core,{logical,49}},
- {core,{logical,50}},
- {core,{logical,58}}]}]}].
-
l(Id) ->
{logical, Id}.
diff --git a/erts/emulator/test/send_term_SUITE.erl b/erts/emulator/test/send_term_SUITE.erl
index 5fd01a9ac5..84352f78ad 100644
--- a/erts/emulator/test/send_term_SUITE.erl
+++ b/erts/emulator/test/send_term_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -19,24 +19,43 @@
-module(send_term_SUITE).
--export([all/1,basic/1]).
--export([init_per_testcase/2,fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,basic/1]).
+-export([init_per_testcase/2,end_per_testcase/2]).
-export([generate_external_terms_files/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
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) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[basic].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
basic(Config) when is_list(Config) ->
Drv = "send_term_drv",
?line P = start_driver(Config, Drv),
@@ -61,7 +80,7 @@ basic(Config) when is_list(Config) ->
?line ExpectExt2Term = term(P, 5),
%% ERL_DRV_INT, ERL_DRV_UINT
- ?line case erlang:system_info(wordsize) of
+ ?line case erlang:system_info({wordsize, external}) of
4 ->
?line {-1, 4294967295} = term(P, 6);
8 ->
diff --git a/erts/emulator/test/sensitive_SUITE.erl b/erts/emulator/test/sensitive_SUITE.erl
index 458275af81..57bc6ce08e 100644
--- a/erts/emulator/test/sensitive_SUITE.erl
+++ b/erts/emulator/test/sensitive_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -19,9 +19,11 @@
-module(sensitive_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
stickiness/1,send_trace/1,recv_trace/1,proc_trace/1,call_trace/1,
meta_trace/1,running_trace/1,gc_trace/1,seq_trace/1,
t_process_info/1,t_process_display/1,save_calls/1]).
@@ -34,14 +36,33 @@ init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(5)),
[{watchdog,Dog}|Config].
-fin_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+end_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog).
-all(suite) ->
- [stickiness,send_trace,recv_trace,proc_trace,call_trace,
- meta_trace,running_trace,gc_trace,seq_trace,
- t_process_info,t_process_display,save_calls].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [stickiness, send_trace, recv_trace, proc_trace,
+ call_trace, meta_trace, running_trace, gc_trace,
+ seq_trace, t_process_info, t_process_display,
+ save_calls].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
stickiness(Config) when is_list(Config) ->
?line {Tracer,Mref} = spawn_monitor(fun() ->
diff --git a/erts/emulator/test/signal_SUITE.erl b/erts/emulator/test/signal_SUITE.erl
index e9103ca3c1..682a9d03fc 100644
--- a/erts/emulator/test/signal_SUITE.erl
+++ b/erts/emulator/test/signal_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -30,8 +30,9 @@
-define(DEFAULT_TIMEOUT_SECONDS, 120).
%-define(line_trace, 1).
--include("test_server.hrl").
--export([all/1]).
+-include_lib("test_server/include/test_server.hrl").
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
% Test cases
-export([xm_sig_order/1,
@@ -49,38 +50,48 @@
pending_exit_group_leader/1,
exit_before_pending_exit/1]).
--export([init_per_testcase/2, fin_per_testcase/2, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
?line Dog = ?t:timetrap(?t:seconds(?DEFAULT_TIMEOUT_SECONDS)),
available_internal_state(true),
?line [{testcase, Func},{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
?line Dog = ?config(watchdog, Config),
?line ?t:timetrap_cancel(Dog).
+init_per_suite(Config) ->
+ Config.
+
end_per_suite(_Config) ->
available_internal_state(true),
- erts_debug:set_internal_state(not_running_optimization, true),
+ catch erts_debug:set_internal_state(not_running_optimization, true),
available_internal_state(false).
-all(suite) ->
- [xm_sig_order,
- pending_exit_unlink_process,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [xm_sig_order, pending_exit_unlink_process,
pending_exit_unlink_dist_process,
- pending_exit_unlink_port,
- pending_exit_trap_exit,
- pending_exit_receive,
- pending_exit_trap_exit,
- pending_exit_gc,
- pending_exit_is_process_alive,
+ pending_exit_unlink_port, pending_exit_trap_exit,
+ pending_exit_receive, pending_exit_trap_exit,
+ pending_exit_gc, pending_exit_is_process_alive,
pending_exit_process_display,
pending_exit_process_info_1,
- pending_exit_process_info_2,
- pending_exit_group_leader,
+ pending_exit_process_info_2, pending_exit_group_leader,
exit_before_pending_exit].
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
xm_sig_order(doc) -> ["Test that exit signals and messages are received "
"in correct order"];
xm_sig_order(suite) -> [];
diff --git a/erts/emulator/test/statistics_SUITE.erl b/erts/emulator/test/statistics_SUITE.erl
index 898908c40f..b543491471 100644
--- a/erts/emulator/test/statistics_SUITE.erl
+++ b/erts/emulator/test/statistics_SUITE.erl
@@ -21,13 +21,14 @@
%% Tests the statistics/1 bif.
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
- wall_clock/1, wall_clock_zero_diff/1, wall_clock_update/1,
- runtime/1, runtime_zero_diff/1,
+ end_per_testcase/2,
+ wall_clock_zero_diff/1, wall_clock_update/1,
+ runtime_zero_diff/1,
runtime_update/1, runtime_diff/1,
- run_queue/1, run_queue_one/1,
+ run_queue_one/1,
reductions/1, reductions_big/1, garbage_collection/1, io/1,
badarg/1]).
@@ -35,24 +36,47 @@
-export([hog/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(_, Config) ->
?line Dog = test_server:timetrap(test_server:seconds(300)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_, Config) ->
+end_per_testcase(_, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) -> [wall_clock, runtime, reductions, reductions_big, run_queue,
- garbage_collection, io, badarg].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, wall_clock}, {group, runtime}, reductions,
+ reductions_big, {group, run_queue}, garbage_collection,
+ io, badarg].
+
+groups() ->
+ [{wall_clock, [],
+ [wall_clock_zero_diff, wall_clock_update]},
+ {runtime, [],
+ [runtime_zero_diff, runtime_update, runtime_diff]},
+ {run_queue, [], [run_queue_one]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%% Testing statistics(wall_clock).
-wall_clock(suite) -> [wall_clock_zero_diff, wall_clock_update].
wall_clock_zero_diff(doc) ->
@@ -99,7 +123,6 @@ wall_clock_update1(0) ->
%%% Test statistics(runtime).
-runtime(suite) -> [runtime_zero_diff, runtime_update, runtime_diff].
runtime_zero_diff(doc) ->
"Tests that the difference between the times returned from two consectuitive "
@@ -225,7 +248,6 @@ reductions_big_loop() ->
%%% Tests of statistics(run_queue).
-run_queue(suite) -> [run_queue_one].
run_queue_one(doc) ->
"Tests that statistics(run_queue) returns 1 if we start a "
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl
index ba433d4e11..0293341eac 100644
--- a/erts/emulator/test/system_info_SUITE.erl
+++ b/erts/emulator/test/system_info_SUITE.erl
@@ -30,23 +30,44 @@
%-define(line_trace, 1).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%-compile(export_all).
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
-export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1, wordsize/1]).
-define(DEFAULT_TIMEOUT, ?t:minutes(2)).
-all(doc) -> [];
-all(suite) -> [process_count, system_version, misc_smoke_tests, heap_size, wordsize].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [process_count, system_version, misc_smoke_tests,
+ heap_size, wordsize].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
@@ -132,6 +153,7 @@ misc_smoke_tests(Config) when is_list(Config) ->
?line true = is_binary(erlang:system_info(procs)),
?line true = is_binary(erlang:system_info(loaded)),
?line true = is_binary(erlang:system_info(dist)),
+ ?line ok = try erlang:system_info({cpu_topology,erts_get_cpu_topology_error_case}), fail catch error:badarg -> ok end,
?line ok.
diff --git a/erts/emulator/test/system_profile_SUITE.erl b/erts/emulator/test/system_profile_SUITE.erl
index 7b0d6d19fe..e4cfa56d88 100644
--- a/erts/emulator/test/system_profile_SUITE.erl
+++ b/erts/emulator/test/system_profile_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,35 +22,52 @@
-module(system_profile_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
system_profile_on_and_off/1,
runnable_procs/1,
runnable_ports/1,
scheduler/1
]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--export([profiler_process/1, ring_loop/1, port_echo_start/0, list_load/0, run_load/2]).
+-export([profiler_process/1, ring_loop/1, port_echo_start/0,
+ list_load/0, run_load/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(default_timeout, ?t:minutes(1)).
init_per_testcase(_Case, Config) ->
?line Dog=?t:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- %% Test specification on test suite level
- [system_profile_on_and_off,
- runnable_procs,
- runnable_ports,
- scheduler].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [system_profile_on_and_off, runnable_procs,
+ runnable_ports, scheduler].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% No specification clause needed for an init function in a conf case!!!
diff --git a/erts/emulator/test/time_SUITE.erl b/erts/emulator/test/time_SUITE.erl
index 095e9dd1af..43dccc6ecb 100644
--- a/erts/emulator/test/time_SUITE.erl
+++ b/erts/emulator/test/time_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -29,14 +29,15 @@
%% now/0
%%
--export([all/1, univ_to_local/1, local_to_univ/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, univ_to_local/1, local_to_univ/1,
bad_univ_to_local/1, bad_local_to_univ/1,
consistency/1,
- now/1, now_unique/1, now_update/1, timestamp/1]).
+ now_unique/1, now_update/1, timestamp/1]).
-export([local_to_univ_utc/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-export([linear_time/1]).
@@ -54,10 +55,28 @@
-define(dst_timezone, 2).
-all(suite) -> [univ_to_local, local_to_univ,
- local_to_univ_utc,
- bad_univ_to_local, bad_local_to_univ,
- consistency, now, timestamp].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [univ_to_local, local_to_univ, local_to_univ_utc,
+ bad_univ_to_local, bad_local_to_univ, consistency,
+ {group, now}, timestamp].
+
+groups() ->
+ [{now, [], [now_unique, now_update]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
local_to_univ_utc(suite) ->
[];
@@ -283,7 +302,6 @@ repeating_timestamp_check(N) ->
%% Test now/0.
-now(suite) -> [now_unique, now_update].
%% Tests that successive calls to now/0 returns different values.
%% Also returns a comment string with the median difference between
diff --git a/erts/emulator/test/timer_bif_SUITE.erl b/erts/emulator/test/timer_bif_SUITE.erl
index 9ac5afcc45..6c421253af 100644
--- a/erts/emulator/test/timer_bif_SUITE.erl
+++ b/erts/emulator/test/timer_bif_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-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
@@ -19,7 +19,9 @@
-module(timer_bif_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,end_per_suite/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2]).
-export([start_timer_1/1, send_after_1/1, send_after_2/1, send_after_3/1,
cancel_timer_1/1,
start_timer_big/1, send_after_big/1,
@@ -27,7 +29,7 @@
read_timer_trivial/1, read_timer/1,
cleanup/1, evil_timers/1, registered_process/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(test_server:seconds(30)),
@@ -37,19 +39,35 @@ init_per_testcase(_Case, Config) ->
end,
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
+init_per_suite(Config) ->
+ Config.
+
end_per_suite(_Config) ->
catch erts_debug:set_internal_state(available_internal_state, false).
-all(suite) ->
- [start_timer_1, send_after_1, send_after_2, cancel_timer_1,
- start_timer_e, send_after_e, cancel_timer_e,
- start_timer_big, send_after_big, read_timer_trivial, read_timer,
- cleanup, evil_timers, registered_process].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [start_timer_1, send_after_1, send_after_2,
+ cancel_timer_1, start_timer_e, send_after_e,
+ cancel_timer_e, start_timer_big, send_after_big,
+ read_timer_trivial, read_timer, cleanup, evil_timers,
+ registered_process].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
start_timer_1(doc) -> ["Basic start_timer/3 functionality"];
start_timer_1(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl
index e9713fcf0f..d200fdaf4c 100644
--- a/erts/emulator/test/trace_SUITE.erl
+++ b/erts/emulator/test/trace_SUITE.erl
@@ -23,7 +23,8 @@
%%% Tests the trace BIF.
%%%
--export([all/1, receive_trace/1, self_send/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, receive_trace/1, self_send/1,
timeout_trace/1, send_trace/1,
procs_trace/1, dist_procs_trace/1,
suspend/1, mutual_suspend/1, suspend_exit/1, suspender_exit/1,
@@ -35,22 +36,39 @@
system_monitor_large_heap_1/1, system_monitor_large_heap_2/1,
bad_flag/1, trace_delivered/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%%% Internal exports
-export([process/1]).
-all(suite) ->
- [cpu_timestamp, receive_trace, self_send, timeout_trace, send_trace,
- procs_trace, dist_procs_trace,
- suspend, mutual_suspend, suspend_exit, suspender_exit,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [cpu_timestamp, receive_trace, self_send, timeout_trace,
+ send_trace, procs_trace, dist_procs_trace, suspend,
+ mutual_suspend, suspend_exit, suspender_exit,
suspend_system_limit, suspend_opts, suspend_waiting,
- new_clear, existing_clear,
- set_on_spawn, set_on_first_spawn,
- system_monitor_args, more_system_monitor_args,
- system_monitor_long_gc_1, system_monitor_long_gc_2,
- system_monitor_large_heap_1, system_monitor_large_heap_2,
- bad_flag, trace_delivered].
+ new_clear, existing_clear, set_on_spawn,
+ set_on_first_spawn, system_monitor_args,
+ more_system_monitor_args, system_monitor_long_gc_1,
+ system_monitor_long_gc_2, system_monitor_large_heap_1,
+ system_monitor_large_heap_2, bad_flag, trace_delivered].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% No longer testing anything, just reporting whether cpu_timestamp
diff --git a/erts/emulator/test/trace_bif_SUITE.erl b/erts/emulator/test/trace_bif_SUITE.erl
index 3f91f8dc08..263db065b3 100644
--- a/erts/emulator/test/trace_bif_SUITE.erl
+++ b/erts/emulator/test/trace_bif_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,24 +19,44 @@
-module(trace_bif_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
--export([trace_bif/1, trace_bif_timestamp/1, trace_on_and_off/1, trace_bif_local/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([trace_bif/1, trace_bif_timestamp/1, trace_on_and_off/1,
+ trace_bif_local/1,
trace_bif_timestamp_local/1, trace_bif_return/1, not_run/1,
trace_info_old_code/1]).
-export([bif_process/0]).
-all(suite) ->
- case test_server:is_native(?MODULE) of
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:is_native(trace_bif_SUITE) of
true -> [not_run];
false ->
[trace_bif, trace_bif_timestamp, trace_on_and_off,
- trace_bif_local, trace_bif_timestamp_local,
+ trace_bif_local, trace_bif_timestamp_local,
trace_bif_return, trace_info_old_code]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
not_run(Config) when is_list(Config) ->
{skipped,"Native code"}.
diff --git a/erts/emulator/test/trace_call_count_SUITE.erl b/erts/emulator/test/trace_call_count_SUITE.erl
index 07aa7c8d8d..55d9b2b288 100644
--- a/erts/emulator/test/trace_call_count_SUITE.erl
+++ b/erts/emulator/test/trace_call_count_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -42,7 +42,7 @@
-define(config(A,B),config(A,B)).
-export([config/2]).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-endif.
-ifdef(debug).
@@ -62,7 +62,9 @@ config(priv_dir,_) ->
".".
-else.
%% When run in test server.
--export([all/1, init_per_testcase/2, fin_per_testcase/2, not_run/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2, not_run/1]).
-export([basic/1, on_and_off/1, info/1,
pause_and_restart/1, combo/1]).
@@ -70,7 +72,7 @@ init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(test_server:seconds(30)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
erlang:trace_pattern({'_','_','_'}, false, [local,meta,call_count]),
erlang:trace_pattern(on_load, false, [local,meta,call_count]),
erlang:trace(all, false, [all]),
@@ -78,15 +80,31 @@ fin_per_testcase(_Case, Config) ->
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test call count tracing of local function calls."];
-all(suite) ->
- case test_server:is_native(?MODULE) of
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:is_native(trace_call_count_SUITE) of
true -> [not_run];
- false -> [basic, on_and_off, info,
- pause_and_restart, combo]
+ false ->
+ [basic, on_and_off, info, pause_and_restart, combo]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
not_run(Config) when is_list(Config) ->
{skipped,"Native code"}.
diff --git a/erts/emulator/test/trace_call_time_SUITE.erl b/erts/emulator/test/trace_call_time_SUITE.erl
index 7bc91addde..5dfa87bbee 100644
--- a/erts/emulator/test/trace_call_time_SUITE.erl
+++ b/erts/emulator/test/trace_call_time_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% Copyright Ericsson AB 2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -57,12 +57,15 @@
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% When run in test server.
--export([all/1, init_per_testcase/2, fin_per_testcase/2, not_run/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2, not_run/1]).
-export([basic/1, on_and_off/1, info/1,
- pause_and_restart/1, scheduling/1, called_function/1, combo/1, bif/1, nif/1]).
+ pause_and_restart/1, scheduling/1, called_function/1, combo/1,
+ bif/1, nif/1]).
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(test_server:seconds(400)),
@@ -71,7 +74,7 @@ init_per_testcase(_Case, Config) ->
timer:now_diff(now(),now()),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
erlang:trace_pattern({'_','_','_'}, false, [local,meta,call_time,call_count]),
erlang:trace_pattern(on_load, false, [local,meta,call_time,call_count]),
erlang:trace(all, false, [all]),
@@ -79,15 +82,32 @@ fin_per_testcase(_Case, Config) ->
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test call count tracing of local function calls."];
-all(suite) ->
- case test_server:is_native(?MODULE) of
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:is_native(trace_call_time_SUITE) of
true -> [not_run];
- false -> [basic, on_and_off, info,
- pause_and_restart, scheduling, combo, bif, nif, called_function]
+ false ->
+ [basic, on_and_off, info, pause_and_restart, scheduling,
+ combo, bif, nif, called_function]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
not_run(Config) when is_list(Config) ->
{skipped,"Native code"}.
@@ -407,7 +427,7 @@ nif(Config) when is_list(Config) ->
?line 1 = erlang:trace_pattern({?MODULE, nif_dec, '_'}, true, [call_time]),
?line 1 = erlang:trace_pattern({?MODULE, with_nif, '_'}, true, [call_time]),
?line Pid = setup(),
- ?line {L, T1} = execute(Pid, fun() -> with_nif(M) end),
+ ?line {_, T1} = execute(Pid, fun() -> with_nif(M) end),
% the nif is called M - 1 times, the last time the function with 'with_nif'
% returns ok and does not call the nif.
@@ -486,7 +506,7 @@ with_nif(N) ->
with_nif(?MODULE:nif_dec(N)).
-nif_dec(N) -> 0.
+nif_dec(_) -> 0.
dec(N) ->
loaded(10000),
diff --git a/erts/emulator/test/trace_local_SUITE.erl b/erts/emulator/test/trace_local_SUITE.erl
index 24005774ba..091e960610 100644
--- a/erts/emulator/test/trace_local_SUITE.erl
+++ b/erts/emulator/test/trace_local_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -45,7 +45,7 @@
-export([config/2]).
-define(DEFAULT_RECEIVE_TIMEOUT, 1000).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(DEFAULT_RECEIVE_TIMEOUT, infinity).
-endif.
@@ -68,7 +68,8 @@ config(priv_dir,_) ->
%%% When run in test server %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--export([all/1, basic/1, bit_syntax/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, basic/1, bit_syntax/1,
return/1, on_and_off/1, stack_grow/1,info/1, delete/1,
exception/1, exception_apply/1,
exception_function/1, exception_apply_function/1,
@@ -79,34 +80,51 @@ config(priv_dir,_) ->
exception_meta_nocatch/1, exception_meta_nocatch_apply/1,
exception_meta_nocatch_function/1,
exception_meta_nocatch_apply_function/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(test_server:minutes(2)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
shutdown(),
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test tracing of local function calls and return traces."];
-all(suite) ->
- case test_server:is_native(?MODULE) of
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:is_native(trace_local_SUITE) of
true -> [not_run];
- false -> [basic, bit_syntax, return, on_and_off, stack_grow, info, delete,
- exception, exception_apply,
- exception_function, exception_apply_function,
- exception_nocatch, exception_nocatch_apply,
- exception_nocatch_function,
- exception_nocatch_apply_function,
- exception_meta, exception_meta_apply,
- exception_meta_function, exception_meta_apply_function,
- exception_meta_nocatch, exception_meta_nocatch_apply,
- exception_meta_nocatch_function,
- exception_meta_nocatch_apply_function]
+ false ->
+ [basic, bit_syntax, return, on_and_off, stack_grow,
+ info, delete, exception, exception_apply,
+ exception_function, exception_apply_function,
+ exception_nocatch, exception_nocatch_apply,
+ exception_nocatch_function,
+ exception_nocatch_apply_function, exception_meta,
+ exception_meta_apply, exception_meta_function,
+ exception_meta_apply_function, exception_meta_nocatch,
+ exception_meta_nocatch_apply,
+ exception_meta_nocatch_function,
+ exception_meta_nocatch_apply_function]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
not_run(Config) when is_list(Config) ->
{skipped,"Native code"}.
@@ -796,9 +814,6 @@ loop(D1,D2,D3,0) ->
loop(D1,D2,D3,N) ->
max(N,loop(D1,D2,D3,N-1)).
-max(A, B) when A > B -> A;
-max(_, B) -> B.
-
exported_wrap(Val) ->
exported(Val).
diff --git a/erts/emulator/test/trace_meta_SUITE.erl b/erts/emulator/test/trace_meta_SUITE.erl
index d84cb3cdf2..45987cc319 100644
--- a/erts/emulator/test/trace_meta_SUITE.erl
+++ b/erts/emulator/test/trace_meta_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -45,7 +45,7 @@
-define(config(A,B),config(A,B)).
-export([config/2]).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-endif.
-ifdef(debug).
@@ -65,7 +65,9 @@ config(priv_dir,_) ->
".".
-else.
%% When run in test server.
--export([all/1, init_per_testcase/2, fin_per_testcase/2, not_run/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2, not_run/1]).
-export([basic/1, return/1, on_and_off/1, stack_grow/1,
info/1, tracer/1, combo/1, nosilent/1]).
@@ -73,19 +75,36 @@ init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(test_server:minutes(5)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
shutdown(),
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test meta tracing of local function calls and return trace."];
-all(suite) ->
- case test_server:is_native(?MODULE) of
- true -> [not_run];
- false -> [basic, return, on_and_off, stack_grow,
- info, tracer, combo, nosilent]
- end.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+case test_server:is_native(trace_meta_SUITE) of
+ true -> [not_run];
+ false ->
+ [basic, return, on_and_off, stack_grow, info, tracer,
+ combo, nosilent]
+end.
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
not_run(Config) when is_list(Config) ->
{skipped,"Native code"}.
@@ -594,11 +613,6 @@ loop(D1,D2,D3,0) ->
loop(D1,D2,D3,N) ->
max(N,loop(D1,D2,D3,N-1)).
-max(A,B) when A > B ->
- A;
-max(_A,B) ->
- B.
-
id(X) ->
X.
diff --git a/erts/emulator/test/trace_nif_SUITE.erl b/erts/emulator/test/trace_nif_SUITE.erl
index 587cc08979..a52ee15e0e 100644
--- a/erts/emulator/test/trace_nif_SUITE.erl
+++ b/erts/emulator/test/trace_nif_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% 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
@@ -19,9 +19,10 @@
-module(trace_nif_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([trace_nif/1,
trace_nif_timestamp/1,
trace_nif_local/1,
@@ -32,19 +33,33 @@
-export([nif_process/0, nif/0, nif/1]).
-all(suite) ->
- case test_server:is_native(?MODULE) of
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:is_native(trace_nif_SUITE) of
true -> [not_run];
false ->
- [trace_nif,
- trace_nif_timestamp,
- trace_nif_local,
- trace_nif_meta,
- trace_nif_timestamp_local,
- trace_nif_return
- ]
+ [trace_nif, trace_nif_timestamp, trace_nif_local,
+ trace_nif_meta, trace_nif_timestamp_local,
+ trace_nif_return]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
not_run(Config) when is_list(Config) ->
{skipped,"Native code"}.
diff --git a/erts/emulator/test/trace_port_SUITE.erl b/erts/emulator/test/trace_port_SUITE.erl
index 5febe177f9..d94fc0aa20 100644
--- a/erts/emulator/test/trace_port_SUITE.erl
+++ b/erts/emulator/test/trace_port_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,9 @@
-module(trace_port_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
call_trace/1,
return_trace/1,
send/1,
@@ -34,29 +36,42 @@
gc/1,
default_tracer/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-test_cases() ->
- [call_trace,
- return_trace,
- send,
- receive_trace,
- process_events,
- schedule,
- fake_schedule,
+test_cases() ->
+ [call_trace, return_trace, send, receive_trace,
+ process_events, schedule, fake_schedule,
fake_schedule_after_register,
fake_schedule_after_getting_linked,
- fake_schedule_after_getting_unlinked,
- gc,
+ fake_schedule_after_getting_unlinked, gc,
default_tracer].
-all(suite) -> test_cases().
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_cases().
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog = ?t:timetrap(?t:seconds(30)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog).
diff --git a/erts/emulator/test/tuple_SUITE.erl b/erts/emulator/test/tuple_SUITE.erl
index c4edb16d68..bfc3910742 100644
--- a/erts/emulator/test/tuple_SUITE.erl
+++ b/erts/emulator/test/tuple_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -17,11 +17,13 @@
%% %CopyrightEnd%
%%
-module(tuple_SUITE).
--export([all/1, t_size/1, t_tuple_size/1, t_element/1, t_setelement/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ t_size/1, t_tuple_size/1, t_element/1, t_setelement/1,
t_list_to_tuple/1, t_tuple_to_list/1,
t_make_tuple_2/1, t_make_tuple_3/1, t_append_element/1,
build_and_match/1, tuple_with_case/1, tuple_in_guard/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Tests tuples and the BIFs:
%%
@@ -33,13 +35,30 @@
%% make_tuple/2
%%
-all(suite) ->
- [build_and_match, t_size, t_tuple_size,
- t_list_to_tuple, t_tuple_to_list,
- t_element, t_setelement, t_make_tuple_2,
- t_make_tuple_3, t_append_element,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [build_and_match, t_size, t_tuple_size, t_list_to_tuple,
+ t_tuple_to_list, t_element, t_setelement,
+ t_make_tuple_2, t_make_tuple_3, t_append_element,
tuple_with_case, tuple_in_guard].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
build_and_match(Config) when is_list(Config) ->
?line {} = id({}),
?line {1} = id({1}),
@@ -80,7 +99,7 @@ t_tuple_size(Config) when is_list(Config) ->
ludicrous_tuple_size(T)
when tuple_size(T) =:= 16#7777777777777777777777777777777777 -> ok;
-ludicrous_tuple_size(T) -> error.
+ludicrous_tuple_size(_) -> error.
%% Tests element/2.
diff --git a/erts/emulator/test/z_SUITE.erl b/erts/emulator/test/z_SUITE.erl
index 67d2b288a2..9637ecd87e 100644
--- a/erts/emulator/test/z_SUITE.erl
+++ b/erts/emulator/test/z_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -29,10 +29,12 @@
%-define(line_trace, 1).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%-compile(export_all).
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, init_per_testcase/2,
+ end_per_testcase/2]).
-export([schedulers_alive/1, node_container_refc_check/1,
long_timers/1, pollset_size/1,
@@ -40,19 +42,33 @@
-define(DEFAULT_TIMEOUT, ?t:minutes(5)).
-all(doc) -> [];
-all(suite) ->
- [schedulers_alive,
- node_container_refc_check,
- long_timers,
- pollset_size,
- check_io_debug].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [schedulers_alive, node_container_refc_check,
+ long_timers, pollset_size, check_io_debug].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops
index de19a2e35b..e7c57142c0 100755
--- a/erts/emulator/utils/beam_makeops
+++ b/erts/emulator/utils/beam_makeops
@@ -27,6 +27,7 @@ my $outdir = "."; # Directory for output files.
my $verbose = 0;
my $hot = 1;
my $num_file_opcodes = 0;
+my $wordsize = 32;
# This is shift counts and mask for the packer.
my $WHOLE_WORD = '';
@@ -36,12 +37,20 @@ my @pack_mask;
$pack_instr[2] = ['6', 'i'];
$pack_instr[3] = ['0', '0', 'i'];
+$pack_instr[4] = ['6', '6', '6', 'i']; # Only for 64 bit wordsize
$pack_shift[2] = ['0', 'BEAM_LOOSE_SHIFT'];
$pack_shift[3] = ['0', 'BEAM_TIGHT_SHIFT', '(2*BEAM_TIGHT_SHIFT)'];
+$pack_shift[4] = ['0', 'BEAM_LOOSE_SHIFT', # Only for 64 bit wordsize
+ '(2*BEAM_LOOSE_SHIFT)',
+ '(3*BEAM_LOOSE_SHIFT)'];
$pack_mask[2] = ['BEAM_LOOSE_MASK', $WHOLE_WORD];
$pack_mask[3] = ['BEAM_TIGHT_MASK', 'BEAM_TIGHT_MASK', 'BEAM_TIGHT_MASK'];
+$pack_mask[4] = ['BEAM_LOOSE_MASK', # Only for 64 bit wordsize
+ 'BEAM_LOOSE_MASK',
+ 'BEAM_LOOSE_MASK',
+ $WHOLE_WORD];
# There are two types of instructions: generic and specific.
# The generic instructions are those generated by the Beam compiler.
@@ -80,6 +89,8 @@ my %cold_code;
my @unnumbered_generic;
my %unnumbered;
+my %is_transformed;
+
#
# Code transformations.
#
@@ -118,7 +129,8 @@ my %arg_size = ('r' => 0, # x(0) - x register zero
't' => 1, # untagged integer -- can be packed
'b' => 1, # pointer to bif
'A' => 1, # arity value
- 'P' => 1, # byte offset into tuple
+ 'P' => 1, # byte offset into tuple or stack
+ 'Q' => 1, # like 'P', but packable
'h' => 1, # character
'l' => 1, # float reg
'q' => 1, # literal term
@@ -157,6 +169,7 @@ my @tag_type;
$type_bit{'U'} = $type_bit{'u'};
$type_bit{'e'} = $type_bit{'u'};
$type_bit{'P'} = $type_bit{'u'};
+ $type_bit{'Q'} = $type_bit{'u'};
}
#
@@ -169,6 +182,7 @@ while (@ARGV && $ARGV[0] =~ /^-(.*)/) {
($target = \&emulator_output), next if /^emulator/;
($target = \&compiler_output), next if /^compiler/;
($outdir = shift), next if /^outdir/;
+ ($wordsize = shift), next if /^wordsize/;
($verbose = 1), next if /^v/;
die "$0: Bad option: -$_\n";
}
@@ -474,8 +488,9 @@ sub emulator_output {
$gen_transform_offset{$key} : -1;
my($spec_op) = $gen_to_spec{$key};
my($num_specific) = $num_specific{$key};
- defined $spec_op or $tr != -1 or
+ defined $spec_op or
$obsolete[$gen_opnum{$name,$arity}] or
+ $is_transformed{$name,$arity} or
error("instruction $key has no specific instruction");
$spec_op = -1 unless defined $spec_op;
&init_item($name, $arity, $spec_op, $num_specific, $tr, $min_window{$key});
@@ -498,12 +513,14 @@ sub emulator_output {
print "#define NUM_SPECIFIC_OPS ", scalar(@op_to_name), "\n";
print "\n";
print "#ifdef ARCH_64\n";
+ print "# define BEAM_WIDE_MASK 0xFFFFUL\n";
print "# define BEAM_LOOSE_MASK 0x1FFFUL\n";
print "#if HALFWORD_HEAP\n";
print "# define BEAM_TIGHT_MASK 0x1FFCUL\n";
print "#else\n";
print "# define BEAM_TIGHT_MASK 0x1FF8UL\n";
print "#endif\n";
+ print "# define BEAM_WIDE_SHIFT 32\n";
print "# define BEAM_LOOSE_SHIFT 16\n";
print "# define BEAM_TIGHT_SHIFT 16\n";
print "#else\n";
@@ -796,6 +813,7 @@ sub basic_generator {
'I' => 1,
't' => 1,
'P' => 1,
+ 'Q' => 1,
);
# Pick up the macro to use and its flags (if any).
@@ -916,7 +934,18 @@ sub basic_generator {
$var_decls .= "BeamInstr tmp_packed2;"
if $macro_code =~ /tmp_packed2/;
if ($flags =~ /-nonext/) {
- $code = "$macro_code\n";
+ $code = join("\n",
+ "{ $var_decls",
+ $macro_code,
+ "}");
+ } elsif ($flags =~ /-goto:(\S*)/) {
+ my $goto = $1;
+ $code = join("\n",
+ "{ $var_decls",
+ $macro_code,
+ "I += $size + 1;",
+ "goto $goto;",
+ "}");
} else {
$code = join("\n",
"{ $var_decls",
@@ -935,18 +964,31 @@ sub basic_generator {
sub do_pack {
my(@args) = @_;
- my($i);
my($packable_args) = 0;
+ my @is_packable; # Packability (boolean) for each argument.
+ my $wide_packing = 0;
#
# Count the number of packable arguments. If we encounter any 's' or 'd'
# arguments, packing is not possible.
#
- for ($i = 0; $i < @args; $i++) {
- if ($args[$i] =~ /[xyt]/) {
+ my $packable_types = "xytQ";
+ foreach my $arg (@args) {
+ if ($arg =~ /^[$packable_types]/) {
$packable_args++;
- } elsif ($args[$i] =~ /[sd]/) {
+ push @is_packable, 1;
+ } elsif ($arg =~ /^I/ and $wordsize == 64 and $packable_args < 2) {
+ $wide_packing = 1;
+ push @is_packable, 1;
+ if (++$packable_args == 2) {
+ # We can only pack two arguments. Turn off packing
+ # for the rest of the arguments.
+ $packable_types = "\xFF";
+ }
+ } elsif ($arg =~ /^[sd]/) {
return ('', '', @args);
+ } else {
+ push @is_packable, 0;
}
}
@@ -962,10 +1004,27 @@ sub do_pack {
# beginning).
my($up) = ''; # Pack commands (storing back while
# moving forward).
- my($args_per_word) = $packable_args < 4 ? $packable_args : 2;
- my(@shift) = @{$pack_shift[$args_per_word]};
- my(@mask) = @{$pack_mask[$args_per_word]};
- my(@pack_instr) = @{$pack_instr[$args_per_word]};
+ my $args_per_word;
+ if ($packable_args < 4 or $wordsize == 64) {
+ $args_per_word = $packable_args;
+ } else {
+ # 4 packable argument, 32 bit wordsize. Need 2 words.
+ $args_per_word = 2;
+ }
+
+ my @shift;
+ my @mask;
+ my @instr;
+
+ if ($wide_packing) {
+ @shift = ('0', 'BEAM_WIDE_SHIFT');
+ @mask = ('BEAM_WIDE_MASK', $WHOLE_WORD);
+ @instr = ('w', 'i');
+ } else {
+ @shift = @{$pack_shift[$args_per_word]};
+ @mask = @{$pack_mask[$args_per_word]};
+ @instr = @{$pack_instr[$args_per_word]};
+ }
#
# Now generate the packing instructions. One complication is that
@@ -979,10 +1038,10 @@ sub do_pack {
my($ap) = 0; # Argument number within word.
my($tmpnum) = 1; # Number of temporary variable.
my($expr) = '';
- for ($i = 0; $i < @args; $i++) {
+ for (my $i = 0; $i < @args; $i++) {
my($reg) = $args[$i];
my($this_size) = $arg_size{$reg};
- if ($reg =~ /[xyt]/) {
+ if ($is_packable[$i]) {
$this_size = 0;
$did_some_packing = 1;
@@ -993,7 +1052,7 @@ sub do_pack {
$this_size = 1;
}
- $down = "$pack_instr[$ap]$down";
+ $down = "$instr[$ap]$down";
my($unpack) = &make_unpack($tmpnum, $shift[$ap], $mask[$ap]);
$args[$i] = "pack:$this_size:$reg" . "b($unpack)";
@@ -1103,6 +1162,10 @@ sub compile_transform {
if ($obsolete[$gen_opnum{$name,$arity}]) {
error("obsolete function must not be used in transformations");
}
+
+ if ($src) {
+ $is_transformed{$name,$arity} = 1;
+ }
[$name,$arity,@ops];
}
@@ -1291,13 +1354,28 @@ sub tr_gen_from {
my($var, $type, $type_val, $cond, $val) = @$op;
if ($type ne '' && $type ne '*') {
- my($types) = '';
- my($type_mask) = 0;
- foreach (split('', $type)) {
- $types .= "$_ ";
- $type_mask |= $type_bit{$_};
+ #
+ # The is_bif, is_not_bif, and is_func instructions have
+ # their own built-in type test and don't need to
+ # be guarded with a type test instruction.
+ #
+ unless ($cond eq 'is_bif' or
+ $cond eq 'is_not_bif' or
+ $cond eq 'is_func') {
+ my($types) = '';
+ my($type_mask) = 0;
+ foreach (split('', $type)) {
+ $types .= "$_ ";
+ $type_mask |= $type_bit{$_};
+ }
+ if ($cond ne 'is_eq') {
+ push(@code, &make_op($types, 'is_type', $type_mask));
+ } else {
+ $cond = '';
+ push(@code, &make_op($types, 'is_type_eq',
+ $type_mask, $val));
+ }
}
- push(@code, &make_op($types, 'is_type', $type_mask));
}
if ($cond eq 'is_func') {
diff --git a/erts/emulator/utils/count b/erts/emulator/utils/count
new file mode 100755
index 0000000000..617f5c25e8
--- /dev/null
+++ b/erts/emulator/utils/count
@@ -0,0 +1,127 @@
+%% -*- erlang -*-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-mode(compile).
+
+main(_) ->
+ DisDir = "./dis",
+ ok = filelib:ensure_dir(filename:join(DisDir, "dummy")),
+ io:format("Dissambling to ~s\n", [DisDir]),
+ ok = file:set_cwd(DisDir),
+ Path = code:get_path() -- ["."],
+ Beams0 = [filelib:wildcard(filename:join(Dir, "*.beam")) ||
+ Dir <- Path],
+ Beams = lists:append(Beams0),
+ Mods0 = [list_to_atom(filename:rootname(filename:basename(F))) ||
+ F <- Beams],
+ Mods = lists:usort(Mods0),
+ start_sem(),
+ Ps = [begin
+ {_,Ref} = spawn_monitor(fun() -> count(M) end),
+ Ref
+ end || M <- Mods],
+ [put(list_to_atom(I), 0) || I <- erts_debug:instructions()],
+ Res = wait_for_all(Ps, 1),
+ OutFile = "count",
+ {ok,Out} = file:open(OutFile, [write]),
+ [io:format(Out, "~s ~p\n", [I,C]) || {I,C} <- Res],
+ ok = file:close(Out),
+ io:format("\nResult written to ~s\n",
+ [filename:join(DisDir, OutFile)]),
+ ok.
+
+wait_for_all([], _) ->
+ lists:reverse(lists:keysort(2, get()));
+wait_for_all([_|_]=Ps, I) ->
+ receive
+ {'DOWN',Ref,process,_,Result} ->
+ io:format("\r~p", [I]),
+ [increment(Key, Count) || {Key,Count} <- Result],
+ wait_for_all(Ps -- [Ref], I+1)
+ end.
+
+count(M) ->
+ down(),
+ erts_debug:df(M),
+ {ok,Fd} = file:open(atom_to_list(M) ++ ".dis", [read,raw]),
+ count_is(Fd),
+ ok = file:close(Fd),
+ exit(get()).
+
+count_is(Fd) ->
+ case file:read_line(Fd) of
+ {ok,Line} ->
+ count_instr(Line),
+ count_is(Fd);
+ eof ->
+ ok
+ end.
+
+count_instr([$\s|T]) ->
+ count_instr_1(T, []);
+count_instr([_|T]) ->
+ count_instr(T);
+count_instr([]) ->
+ %% Empty line.
+ ok.
+
+count_instr_1([$\s|_], Acc) ->
+ Instr = list_to_atom(lists:reverse(Acc)),
+ increment(Instr, 1);
+count_instr_1([H|T], Acc) ->
+ count_instr_1(T, [H|Acc]).
+
+increment(Key, Inc) ->
+ case get(Key) of
+ undefined ->
+ put(Key, Inc);
+ Count ->
+ put(Key, Count+Inc)
+ end.
+
+%%%
+%%% Counting sempahore to limit the number of processes that
+%%% can run concurrently.
+%%%
+
+down() ->
+ sem ! {down,self()},
+ receive
+ sem_taken -> ok
+ end.
+
+start_sem() ->
+ spawn(fun() ->
+ register(sem, self()),
+ process_flag(trap_exit, true),
+ do_sem(erlang:system_info(schedulers)+1) end).
+
+do_sem(0) ->
+ receive
+ {'EXIT',_,_} ->
+ do_sem(1)
+ end;
+do_sem(C) ->
+ receive
+ {down,Pid} ->
+ link(Pid),
+ Pid ! sem_taken,
+ do_sem(C-1)
+ end.
diff --git a/erts/emulator/utils/loaded b/erts/emulator/utils/loaded
new file mode 100644
index 0000000000..d124a64a78
--- /dev/null
+++ b/erts/emulator/utils/loaded
@@ -0,0 +1,44 @@
+%% -*- erlang -*-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%% Run like:
+%% $ERL_TOP/bin/escript erts/emulator/utils/loaded
+
+-mode(compile).
+
+main(_) ->
+ LibDir = code:lib_dir(),
+ io:format("Library root is ~s\n", [LibDir]),
+ Wc = filename:join(LibDir, "*/ebin/*.beam"),
+ Beams = filelib:wildcard(Wc),
+ BeamFileSize = lists:sum([filelib:file_size(Beam) || Beam <- Beams]),
+ io:format("~w BEAM files containing ~w bytes\n",
+ [length(Beams),BeamFileSize]),
+ Ms = [list_to_atom(filename:rootname(filename:basename(Beam))) ||
+ Beam <- Beams],
+ [{module,_} = code:ensure_loaded(M) || M <- Ms],
+ <<"Current code: ",T/binary>> = erlang:system_info(loaded),
+ Digits = grab_digits(T),
+ io:format("~w modules comprising ~s words when loaded\n",
+ [length(Ms),Digits]).
+
+grab_digits(<<H,T/binary>>) when $0 =< H, H =< $9 ->
+ [H|grab_digits(T)];
+grab_digits(<<$\n,_/binary>>) -> [].
diff --git a/erts/emulator/zlib/zutil.h b/erts/emulator/zlib/zutil.h
index d560382691..a8872e1c88 100644
--- a/erts/emulator/zlib/zutil.h
+++ b/erts/emulator/zlib/zutil.h
@@ -142,6 +142,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#ifdef WIN32
# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
# define OS_CODE 0x0b
+# define F_OPEN(name, mode) _wfopen((WCHAR *)(name), (WCHAR *)(mode)) /* Unicode */
# endif
#endif
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index df4d1a5715..3499ab2934 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -2,7 +2,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -39,8 +39,10 @@
* server keeps the socket open where the request for registration was
* made.
*
- * The protocol is briefly documented in "erl_ext_dist.txt". All requests
- * to this server are done with a packet
+ * The protocol is briefly documented in the ERTS User's Guide, see
+ * http://www.erlang.org/doc/apps/erts/erl_dist_protocol.html
+ *
+ * All requests to this server are done with a packet
*
* 2 n
* +--------+---------+
@@ -155,8 +157,10 @@ void run(EpmdVars *g)
dbg_printf(g,2,"starting");
- listen(listensock, SOMAXCONN);
-
+ if(listen(listensock, SOMAXCONN) < 0) {
+ dbg_perror(g,"failed to listen on socket");
+ epmd_cleanup_exit(g,1);
+ }
FD_ZERO(&g->orig_read_mask);
FD_SET(listensock,&g->orig_read_mask);
diff --git a/erts/epmd/test/epmd.spec b/erts/epmd/test/epmd.spec
index 0e2496bc72..e72272cf94 100644
--- a/erts/epmd/test/epmd.spec
+++ b/erts/epmd/test/epmd.spec
@@ -1 +1 @@
-{topcase, {dir, "../epmd_test"}}.
+{suites,"../epmd_test",all}.
diff --git a/erts/epmd/test/epmd_SUITE.erl b/erts/epmd/test/epmd_SUITE.erl
index da69412e12..ec566f817b 100644
--- a/erts/epmd/test/epmd_SUITE.erl
+++ b/erts/epmd/test/epmd_SUITE.erl
@@ -17,7 +17,7 @@
%% %CopyrightEnd%
%%
-module(epmd_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
@@ -35,7 +35,9 @@
-record(node_info, {port, node_type, prot, lvsn, hvsn, node_name, extra}).
% Test server specific exports
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
-export(
[
@@ -64,7 +66,7 @@
returns_valid_empty_extra/1,
returns_valid_populated_extra_with_nulls/1,
- buffer_overrun/1,
+
buffer_overrun_1/1,
buffer_overrun_2/1,
no_nonlocal_register/1,
@@ -101,42 +103,37 @@
%% all/1
%%
-all(suite) ->
- [
- register_name,
- register_names_1,
- register_names_2,
- register_duplicate_name,
- get_port_nr,
- slow_get_port_nr,
- unregister_others_name_1,
- unregister_others_name_2,
- register_overflow,
- name_with_null_inside,
- name_null_terminated,
- stupid_names_req,
-
- no_data,
- one_byte,
- two_bytes,
- partial_packet,
- zero_length,
- too_large,
- alive_req_too_small_1,
- alive_req_too_small_2,
- alive_req_too_large,
-
- returns_valid_empty_extra,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [register_name, register_names_1, register_names_2,
+ register_duplicate_name, get_port_nr, slow_get_port_nr,
+ unregister_others_name_1, unregister_others_name_2,
+ register_overflow, name_with_null_inside,
+ name_null_terminated, stupid_names_req, no_data,
+ one_byte, two_bytes, partial_packet, zero_length,
+ too_large, alive_req_too_small_1, alive_req_too_small_2,
+ alive_req_too_large, returns_valid_empty_extra,
returns_valid_populated_extra_with_nulls,
+ {group, buffer_overrun}, no_nonlocal_register,
+ no_nonlocal_kill, no_live_killing].
+
+groups() ->
+ [{buffer_overrun, [],
+ [buffer_overrun_1, buffer_overrun_2]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
- buffer_overrun,
- %buffer_overrun_1,
- %buffer_overrun_2,
+end_per_group(_GroupName, Config) ->
+ Config.
- no_nonlocal_register,
- no_nonlocal_kill,
- no_live_killing
- ].
%%
%% Run before and after each test case
@@ -147,7 +144,7 @@ init_per_testcase(_Func, Config) ->
cleanup(),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
cleanup(),
Dog = ?config(watchdog, Config),
catch test_server:timetrap_cancel(Dog), % We may have canceled already
@@ -725,8 +722,6 @@ returns_valid_populated_extra_with_nulls(Config) when is_list(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-buffer_overrun(suite) ->
- [buffer_overrun_1,buffer_overrun_2].
buffer_overrun_1(suite) ->
[];
diff --git a/erts/etc/common/Makefile.in b/erts/etc/common/Makefile.in
index 96655662b8..4754328c0b 100644
--- a/erts/etc/common/Makefile.in
+++ b/erts/etc/common/Makefile.in
@@ -178,7 +178,7 @@ MC_OUTPUTS= \
MT_FLAG="-MD"
endif
INET_GETHOST = $(BINDIR)/inet_gethost.exe
-INSTALL_EMBEDDED_PROGS += $(BINDIR)/typer.exe $(BINDIR)/dialyzer.exe $(BINDIR)/erlc.exe $(BINDIR)/start_erl.exe $(BINDIR)/escript.exe $(BINDIR)/run_test.exe
+INSTALL_EMBEDDED_PROGS += $(BINDIR)/typer.exe $(BINDIR)/dialyzer.exe $(BINDIR)/erlc.exe $(BINDIR)/start_erl.exe $(BINDIR)/escript.exe $(BINDIR)/ct_run.exe
INSTALL_SRC = $(WINETC)/start_erl.c $(WINETC)/Nmakefile.start_erl
ERLEXECDIR=.
INSTALL_LIBS =
@@ -211,7 +211,7 @@ ERLSRV_OBJECTS=
MC_OUTPUTS=
INET_GETHOST = $(BINDIR)/inet_gethost@EXEEXT@
INSTALL_EMBEDDED_PROGS += $(BINDIR)/typer@EXEEXT@ $(BINDIR)/dialyzer@EXEEXT@ \
- $(BINDIR)/erlc@EXEEXT@ $(BINDIR)/escript@EXEEXT@ $(BINDIR)/run_test@EXEEXT@ \
+ $(BINDIR)/erlc@EXEEXT@ $(BINDIR)/escript@EXEEXT@ $(BINDIR)/ct_run@EXEEXT@ \
$(BINDIR)/run_erl $(BINDIR)/to_erl $(BINDIR)/dyn_erl
INSTALL_EMBEDDED_DATA = ../unix/start.src ../unix/start_erl.src
INSTALL_TOP = Install
@@ -274,7 +274,7 @@ endif
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/dyn_erl.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/safe_string.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/typer.o
- rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/run_test.o
+ rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/ct_run.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/vxcall.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/erl.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/werl.o
@@ -327,34 +327,34 @@ $(OBJDIR)/$(ERLEXEC).o: $(ERLEXECDIR)/$(ERLEXEC).c
$(CC) -I$(EMUDIR) $(CFLAGS) -o $@ -c $(ERLEXECDIR)/$(ERLEXEC).c
endif
$(BINDIR)/erlc@EXEEXT@: $(OBJDIR)/erlc.o
- $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/erlc.o -L$(OBJDIR) $(LIBS)
+ $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/erlc.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS)
$(OBJDIR)/erlc.o: erlc.c
$(CC) $(CFLAGS) -o $@ -c erlc.c
$(BINDIR)/dialyzer@EXEEXT@: $(OBJDIR)/dialyzer.o
- $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/dialyzer.o -L$(OBJDIR) $(LIBS)
+ $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/dialyzer.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS)
$(OBJDIR)/dialyzer.o: dialyzer.c
$(CC) $(CFLAGS) -o $@ -c dialyzer.c
$(BINDIR)/typer@EXEEXT@: $(OBJDIR)/typer.o
- $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/typer.o -L$(OBJDIR) $(LIBS)
+ $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/typer.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS)
$(OBJDIR)/typer.o: typer.c
$(CC) $(CFLAGS) -o $@ -c typer.c
$(BINDIR)/escript@EXEEXT@: $(OBJDIR)/escript.o
- $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/escript.o -L$(OBJDIR) $(LIBS)
+ $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/escript.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS)
$(OBJDIR)/escript.o: escript.c
$(CC) $(CFLAGS) -o $@ -c escript.c
-$(BINDIR)/run_test@EXEEXT@: $(OBJDIR)/run_test.o
- $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/run_test.o -L$(OBJDIR) $(LIBS)
+$(BINDIR)/ct_run@EXEEXT@: $(OBJDIR)/ct_run.o
+ $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/ct_run.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS)
-$(OBJDIR)/run_test.o: run_test.c
- $(CC) $(CFLAGS) -o $@ -c run_test.c
+$(OBJDIR)/ct_run.o: ct_run.c
+ $(CC) $(CFLAGS) -o $@ -c ct_run.c
#------------------------------------------------------------------------
diff --git a/erts/etc/common/run_test.c b/erts/etc/common/ct_run.c
index 016d9c6afd..7aaab716f7 100644
--- a/erts/etc/common/run_test.c
+++ b/erts/etc/common/ct_run.c
@@ -85,6 +85,7 @@ static char* strsave(char* string);
static void push_words(char* src);
static int run_erlang(char* name, char** argv);
static char* get_default_emulator(char* progname);
+static void print_deprecation_warning(char *progname);
#ifdef __WIN32__
static char* possibly_quote(char* arg);
#endif
@@ -131,6 +132,8 @@ main(int argc, char** argv)
int erl_args;
char** argv0 = argv;
+ print_deprecation_warning(argv[0]);
+
emulator = get_default_emulator(argv[0]);
/*
@@ -164,11 +167,13 @@ main(int argc, char** argv)
erl_args = cnt;
}
else if (strcmp(argv[1], "-sname") == 0) {
- strcpy(nodename, argv[2]);
+ strncpy(nodename, argv[2], sizeof(nodename));
+ nodename[sizeof(nodename)-1] = '\0';
cnt++, argv++;
}
else if (strcmp(argv[1], "-name") == 0) {
- strcpy(nodename, argv[2]);
+ strncpy(nodename, argv[2], sizeof(nodename));
+ nodename[sizeof(nodename)-1] = '\0';
dist_mode = FULL_NAME;
cnt++, argv++;
}
@@ -178,7 +183,8 @@ main(int argc, char** argv)
ct_mode = VTS_MODE;
}
else if (strcmp(argv[1], "-browser") == 0) {
- strcpy(browser, argv[2]);
+ strncpy(browser, argv[2], sizeof(browser));
+ browser[sizeof(browser)-1] = '\0';
cnt++, argv++;
}
else if (strcmp(argv[1], "-shell") == 0) {
@@ -189,7 +195,8 @@ main(int argc, char** argv)
ct_mode = MASTER_MODE;
}
else if (strcmp(argv[1], "-ctname") == 0) {
- strcpy(nodename, argv[2]);
+ strncpy(nodename, argv[2], sizeof(nodename));
+ nodename[sizeof(nodename)-1] = '\0';
ct_mode = ERL_SHELL_MODE;
cnt++, argv++;
}
@@ -273,7 +280,7 @@ main(int argc, char** argv)
static void
push_words(char* src)
{
- char sbuf[1024];
+ char sbuf[MAXPATHLEN];
char* dst;
dst = sbuf;
@@ -387,7 +394,7 @@ run_erlang(char* progname, char** argv)
status = my_spawnvp(argv)/*_spawnvp(_P_WAIT,progname,argv)*/;
if (status == -1) {
- fprintf(stderr, "run_test: Error executing '%s': %d", progname,
+ fprintf(stderr, "ct_run: Error executing '%s': %d", progname,
GetLastError());
}
return status;
@@ -405,9 +412,9 @@ error(char* format, ...)
va_list ap;
va_start(ap, format);
- vsprintf(sbuf, format, ap);
+ erts_vsnprintf(sbuf, sizeof(sbuf), format, ap);
va_end(ap);
- fprintf(stderr, "run_test: %s\n", sbuf);
+ fprintf(stderr, "ct_run: %s\n", sbuf);
exit(1);
}
@@ -428,12 +435,36 @@ strsave(char* string)
return p;
}
+/* Instead of making sure basename exists, we do our own */
+static char *simple_basename(char *path)
+{
+ char *ptr;
+ for (ptr = path; *ptr != '\0'; ++ptr) {
+ if (*ptr == '/' || *ptr == '\\') {
+ path = ptr + 1;
+ }
+ }
+ return path;
+}
+
+static void print_deprecation_warning(char* progpath)
+{
+ char *basename = simple_basename(progpath);
+ if(strcmp(basename,"run_test") == 0 ||
+ strcmp(basename, "run_test.exe") == 0) {
+ printf("---***---\nDeprecated: run_test is deprecated and will be removed in R16B,\n please use ct_run instead\n---***---\n");
+ }
+}
+
static char*
get_default_emulator(char* progname)
{
char sbuf[MAXPATHLEN];
char* s;
+ if (strlen(progname) >= sizeof(sbuf))
+ return ERL_NAME;
+
strcpy(sbuf, progname);
for (s = sbuf+strlen(sbuf); s >= sbuf; s--) {
if (IS_DIRSEP(*s)) {
diff --git a/erts/etc/common/dialyzer.c b/erts/etc/common/dialyzer.c
index 4b4c1124f1..4453e63f1c 100644
--- a/erts/etc/common/dialyzer.c
+++ b/erts/etc/common/dialyzer.c
@@ -147,6 +147,9 @@ main(int argc, char** argv)
env = get_env("DIALYZER_EMULATOR");
emulator = env ? env : get_default_emulator(argv[0]);
+ if (strlen(emulator) >= MAXPATHLEN)
+ error("Value of environment variable DIALYZER_EMULATOR is too large");
+
/*
* Allocate the argv vector to be used for arguments to Erlang.
* Arrange for starting to pushing information in the middle of
@@ -228,7 +231,7 @@ main(int argc, char** argv)
static void
push_words(char* src)
{
- char sbuf[1024];
+ char sbuf[MAXPATHLEN];
char* dst;
dst = sbuf;
@@ -360,7 +363,7 @@ error(char* format, ...)
va_list ap;
va_start(ap, format);
- vsprintf(sbuf, format, ap);
+ erts_vsnprintf(sbuf, sizeof(sbuf), format, ap);
va_end(ap);
fprintf(stderr, "dialyzer: %s\n", sbuf);
exit(1);
@@ -389,6 +392,9 @@ get_default_emulator(char* progname)
char sbuf[MAXPATHLEN];
char* s;
+ if (strlen(progname) >= sizeof(sbuf))
+ return ERL_NAME;
+
strcpy(sbuf, progname);
for (s = sbuf+strlen(sbuf); s >= sbuf; s--) {
if (IS_DIRSEP(*s)) {
diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c
index 09aca19e6c..35c360a99d 100644
--- a/erts/etc/common/erlc.c
+++ b/erts/etc/common/erlc.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1997-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -28,6 +28,7 @@
#include <winbase.h>
/* FIXE ME config_win32.h? */
#define HAVE_STRERROR 1
+#define snprintf _snprintf
#endif
#include <ctype.h>
@@ -148,10 +149,6 @@ int
main(int argc, char** argv)
{
char cwd[MAXPATHLEN]; /* Current working directory. */
- char** rpc_eargv; /* Pointer to the beginning of arguments
- * if calling a running Erlang system
- * via erl_rpc().
- */
int eargv_size;
int eargc_base; /* How many arguments in the base of eargv. */
char* emulator;
@@ -160,6 +157,9 @@ main(int argc, char** argv)
env = get_env("ERLC_EMULATOR");
emulator = env ? env : get_default_emulator(argv[0]);
+ if (strlen(emulator) >= MAXPATHLEN)
+ error("Value of environment variable ERLC_EMULATOR is too large");
+
/*
* Allocate the argv vector to be used for arguments to Erlang.
* Arrange for starting to pushing information in the middle of
@@ -170,7 +170,7 @@ main(int argc, char** argv)
* base of the eargv vector, and move it up later.
*/
- eargv_size = argc*4+100;
+ eargv_size = argc*6+100;
eargv_base = (char **) emalloc(eargv_size*sizeof(char*));
eargv = eargv_base;
eargc = 0;
@@ -189,7 +189,6 @@ main(int argc, char** argv)
PUSH2("-mode", "minimal");
PUSH2("-boot", "start_clean");
PUSH3("-s", "erl_compile", "compile_cmdline");
- rpc_eargv = eargv+eargc;
/*
* Push standard arguments to Erlang.
@@ -262,6 +261,95 @@ main(int argc, char** argv)
case 'I':
PUSH2("@i", process_opt(&argc, &argv, 0));
break;
+ case 'M':
+ {
+ char *buf, *key, *val;
+ size_t buf_len;
+
+ if (argv[1][2] == '\0') { /* -M */
+ /* Push the following options:
+ * o 'makedep'
+ * o {makedep_output, standard_io}
+ */
+ buf = strsave("makedep");
+ PUSH2("@option", buf);
+
+ key = "makedep_output";
+ val = "standard_io";
+ buf_len = 1 + strlen(key) + 1 + strlen(val) + 1 + 1;
+ buf = emalloc(buf_len);
+ snprintf(buf, buf_len, "{%s,%s}", key, val);
+ PUSH2("@option", buf);
+ } else if (argv[1][3] == '\0') {
+ switch(argv[1][2]) {
+ case 'D': /* -MD */
+ /* Push the following options:
+ * o 'makedep'
+ */
+ buf = strsave("makedep");
+ PUSH2("@option", buf);
+ break;
+ case 'F': /* -MF <file> */
+ /* Push the following options:
+ * o 'makedep'
+ * o {makedep_output, <file>}
+ */
+ buf = strsave("makedep");
+ PUSH2("@option", buf);
+
+ key = "makedep_output";
+ val = process_opt(&argc, &argv, 1);
+ buf_len = 1 + strlen(key) + 2 + strlen(val) + 2 + 1;
+ buf = emalloc(buf_len);
+ snprintf(buf, buf_len, "{%s,\"%s\"}", key, val);
+ PUSH2("@option", buf);
+ break;
+ case 'T': /* -MT <target> */
+ /* Push the following options:
+ * o {makedep_target, <target>}
+ */
+ key = "makedep_target";
+ val = process_opt(&argc, &argv, 1);
+ buf_len = 1 + strlen(key) + 2 + strlen(val) + 2 + 1;
+ buf = emalloc(buf_len);
+ snprintf(buf, buf_len, "{%s,\"%s\"}", key, val);
+ PUSH2("@option", buf);
+ break;
+ case 'Q': /* -MQ <target> */
+ /* Push the following options:
+ * o {makedep_target, <target>}
+ * o makedep_quote_target
+ */
+ key = "makedep_target";
+ val = process_opt(&argc, &argv, 1);
+ buf_len = 1 + strlen(key) + 2 + strlen(val) + 2 + 1;
+ buf = emalloc(buf_len);
+ snprintf(buf, buf_len, "{%s,\"%s\"}", key, val);
+ PUSH2("@option", buf);
+
+ buf = strsave("makedep_quote_target");
+ PUSH2("@option", buf);
+ break;
+ case 'G': /* -MG */
+ /* Push the following options:
+ * o makedep_add_missing
+ */
+ buf = strsave("makedep_add_missing");
+ PUSH2("@option", buf);
+ break;
+ case 'P': /* -MP */
+ /* Push the following options:
+ * o makedep_phony
+ */
+ buf = strsave("makedep_add_missing");
+ PUSH2("@option", buf);
+ break;
+ default:
+ goto error;
+ }
+ }
+ }
+ break;
case 'o':
PUSH2("@outdir", process_opt(&argc, &argv, 0));
break;
@@ -419,7 +507,7 @@ process_opt(int* pArgc, char*** pArgv, int offset)
static void
push_words(char* src)
{
- char sbuf[1024];
+ char sbuf[MAXPATHLEN];
char* dst;
dst = sbuf;
@@ -563,6 +651,15 @@ usage(void)
{"-hybrid", "compile using hybrid-heap emulator"},
{"-help", "shows this help text"},
{"-I path", "where to search for include files"},
+ {"-M", "generate a rule for make(1) describing the dependencies"},
+ {"-MF file", "write the dependencies to 'file'"},
+ {"-MT target", "change the target of the rule emitted by dependency "
+ "generation"},
+ {"-MQ target", "same as -MT but quote characters special to make(1)"},
+ {"-MG", "consider missing headers as generated files and add them to "
+ "the dependencies"},
+ {"-MP", "add a phony target for each dependency"},
+ {"-MD", "same as -M -MT file (with default 'file')"},
{"-o name", "name output directory or file"},
{"-pa path", "add path to the front of Erlang's code path"},
{"-pz path", "add path to the end of Erlang's code path"},
@@ -595,7 +692,7 @@ error(char* format, ...)
va_list ap;
va_start(ap, format);
- vsprintf(sbuf, format, ap);
+ erts_vsnprintf(sbuf, sizeof(sbuf), format, ap);
va_end(ap);
fprintf(stderr, "erlc: %s\n", sbuf);
exit(1);
@@ -624,6 +721,9 @@ get_default_emulator(char* progname)
char sbuf[MAXPATHLEN];
char* s;
+ if (strlen(progname) >= sizeof(sbuf))
+ return ERL_NAME;
+
strcpy(sbuf, progname);
for (s = sbuf+strlen(sbuf); s >= sbuf; s--) {
if (IS_DIRSEP(*s)) {
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index c1fc2aebee..60b3af7db7 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -138,6 +138,12 @@ static char *plusr_val_switches[] = {
NULL
};
+/* +z arguments with values */
+static char *plusz_val_switches[] = {
+ "dbbl",
+ NULL
+};
+
/*
* Define sleep(seconds) in terms of Sleep() on Windows.
@@ -309,7 +315,7 @@ free_env_val(char *value)
}
/*
- * Add the arcitecture suffix to the program name if needed,
+ * Add the architecture suffix to the program name if needed,
* except on Windows, where we insert it just before ".DLL".
*/
static char*
@@ -560,7 +566,7 @@ int main(int argc, char **argv)
usage("+MYm");
}
emu = add_extra_suffixes(emu, emu_type);
- sprintf(tmpStr, "%s" DIRSEP "%s" BINARY_EXT, bindir, emu);
+ erts_snprintf(tmpStr, sizeof(tmpStr), "%s" DIRSEP "%s" BINARY_EXT, bindir, emu);
emu = strsave(tmpStr);
add_Eargs(emu); /* Will be argv[0] -- necessary! */
@@ -571,12 +577,12 @@ int main(int argc, char **argv)
s = get_env("PATH");
if (!s) {
- sprintf(tmpStr, "%s" PATHSEP "%s" DIRSEP "bin", bindir, rootdir);
+ erts_snprintf(tmpStr, sizeof(tmpStr), "%s" PATHSEP "%s" DIRSEP "bin", bindir, rootdir);
} else if (strstr(s, bindir) == NULL) {
- sprintf(tmpStr, "%s" PATHSEP "%s" DIRSEP "bin" PATHSEP "%s", bindir,
+ erts_snprintf(tmpStr, sizeof(tmpStr), "%s" PATHSEP "%s" DIRSEP "bin" PATHSEP "%s", bindir,
rootdir, s);
} else {
- sprintf(tmpStr, "%s", s);
+ erts_snprintf(tmpStr, sizeof(tmpStr), "%s", s);
}
free_env_val(s);
set_env("PATH", tmpStr);
@@ -714,7 +720,7 @@ int main(int argc, char **argv)
error("-man not supported on Windows");
#else
argv[i] = "man";
- sprintf(tmpStr, "%s/man", rootdir);
+ erts_snprintf(tmpStr, sizeof(tmpStr), "%s/man", rootdir);
set_env("MANPATH", tmpStr);
execvp("man", argv+i);
error("Could not execute the 'man' command.");
@@ -909,6 +915,20 @@ int main(int argc, char **argv)
i++;
}
break;
+ case 'z':
+ if (!is_one_of_strings(&argv[i][2], plusz_val_switches)) {
+ goto the_default;
+ } else {
+ if (i+1 >= argc
+ || argv[i+1][0] == '-'
+ || argv[i+1][0] == '+')
+ usage(argv[i]);
+ argv[i][0] = '-';
+ add_Eargs(argv[i]);
+ add_Eargs(argv[i+1]);
+ i++;
+ }
+ break;
default:
the_default:
argv[i][0] = '-'; /* Change +option to -option. */
@@ -1096,7 +1116,7 @@ usage_aux(void)
"[+l] [+M<SUBSWITCH> <ARGUMENT>] [+P MAX_PROCS] [+R COMPAT_REL] "
"[+r] [+rg READER_GROUPS_LIMIT] [+s SCHEDULER_OPTION] "
"[+S NO_SCHEDULERS:NO_SCHEDULERS_ONLINE] [+T LEVEL] [+V] [+v] "
- "[+W<i|w>] [args ...]\n");
+ "[+W<i|w>] [+z MISC_OPTION] [args ...]\n");
exit(1);
}
@@ -1145,10 +1165,10 @@ start_epmd(char *epmd)
if (!epmd) {
epmd = epmd_cmd;
#ifdef __WIN32__
- sprintf(epmd_cmd, "%s" DIRSEP "epmd", bindir);
+ erts_snprintf(epmd_cmd, sizeof(epmd_cmd), "%s" DIRSEP "epmd", bindir);
arg1 = "-daemon";
#else
- sprintf(epmd_cmd, "%s" DIRSEP "epmd -daemon", bindir);
+ erts_snprintf(epmd_cmd, sizeof(epmd_cmd), "%s" DIRSEP "epmd -daemon", bindir);
#endif
}
#ifdef __WIN32__
@@ -1224,7 +1244,7 @@ void error(char* format, ...)
va_list ap;
va_start(ap, format);
- vsprintf(sbuf, format, ap);
+ erts_vsnprintf(sbuf, sizeof(sbuf), format, ap);
va_end(ap);
fprintf(stderr, "erlexec: %s\n", sbuf);
exit(1);
@@ -1304,14 +1324,14 @@ static void get_start_erl_data(char *file)
if (env)
reldir = strsave(env);
else {
- sprintf(tmpbuffer, "%s/releases", rootdir);
+ erts_snprintf(tmpbuffer, sizeof(tmpbuffer), "%s/releases", rootdir);
reldir = strsave(tmpbuffer);
}
free_env_val(env);
if (file == NULL)
- sprintf(start_erl_data, "%s/start_erl.data", reldir);
+ erts_snprintf(start_erl_data, sizeof(start_erl_data), "%s/start_erl.data", reldir);
else
- sprintf(start_erl_data, "%s", file);
+ erts_snprintf(start_erl_data, sizeof(start_erl_data), "%s", file);
fp = _open(start_erl_data, _O_RDONLY );
if( fp == -1 )
error( "open failed on %s",start_erl_data );
@@ -1341,16 +1361,16 @@ static void get_start_erl_data(char *file)
}
bindir = emalloc(512);
- sprintf(bindir,"%s/erts-%s/bin",rootdir,tmpbuffer);
+ erts_snprintf(bindir,512,"%s/erts-%s/bin",rootdir,tmpbuffer);
/* BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin */
tprogname = progname;
progname = emalloc(strlen(tprogname) + 20);
- sprintf(progname,"%s -start_erl",tprogname);
+ erts_snprintf(progname,strlen(tprogname) + 20,"%s -start_erl",tprogname);
boot_script = emalloc(512);
config_script = emalloc(512);
- sprintf(boot_script, "%s/%s/start", reldir, otpstring);
- sprintf(config_script, "%s/%s/sys", reldir, otpstring);
+ erts_snprintf(boot_script, 512, "%s/%s/start", reldir, otpstring);
+ erts_snprintf(config_script, 512, "%s/%s/sys", reldir, otpstring);
}
@@ -1358,7 +1378,7 @@ static void get_start_erl_data(char *file)
static char *replace_filename(char *path, char *new_base)
{
int plen = strlen(path);
- char *res = malloc((plen+strlen(new_base)+1)*sizeof(char));
+ char *res = emalloc((plen+strlen(new_base)+1)*sizeof(char));
char *p;
strcpy(res,path);
@@ -1373,7 +1393,7 @@ static char *path_massage(char *long_path)
{
char *p;
- p = malloc(MAX_PATH+1);
+ p = emalloc(MAX_PATH+1);
strcpy(p, long_path);
GetShortPathName(p, p, MAX_PATH);
return p;
@@ -1509,7 +1529,8 @@ get_parameters(int argc, char** argv)
/* Determine bindir from absolute path to executable */
char *p;
char buffer[PATH_MAX];
- strcpy(buffer, argv[0]);
+ strncpy(buffer, argv[0], sizeof(buffer));
+ buffer[sizeof(buffer)-1] = '\0';
for (p = buffer+strlen(buffer)-1 ; p >= buffer && *p != '/'; --p)
;
@@ -1522,7 +1543,8 @@ get_parameters(int argc, char** argv)
/* Determine rootdir from absolute path to bindir */
char *p;
char buffer[PATH_MAX];
- strcpy(buffer, bindir);
+ strncpy(buffer, bindir, sizeof(buffer));
+ buffer[sizeof(buffer)-1] = '\0';
for (p = buffer+strlen(buffer)-1; p >= buffer && *p != '/'; --p)
;
diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index 1bc5eb7651..6ed79c91e3 100644
--- a/erts/etc/common/escript.c
+++ b/erts/etc/common/escript.c
@@ -151,6 +151,9 @@ find_prog(char *origpath)
char relpath[PMAX];
char abspath[PMAX];
+ if (strlen(origpath) >= sizeof(relpath))
+ error("Path too long");
+
strcpy(relpath, origpath);
if (strstr(relpath, DIRSEPSTR) == NULL) {
@@ -180,19 +183,21 @@ find_prog(char *origpath)
end = strstr(beg, PATHSEPSTR);
if (end != NULL) {
sz = end - beg;
- strncpy(dir, beg, sz);
- dir[sz] = '\0';
} else {
sz = strlen(beg);
- strcpy(dir, beg);
look_for_sep = FALSE;
}
+ if (sz >= sizeof(dir)) {
+ beg = end + 1;
+ continue;
+ }
+ strncpy(dir, beg, sz);
+ dir[sz] = '\0';
beg = end + 1;
#ifdef __WIN32__
- strcpy(wildcard, dir);
- strcat(wildcard, DIRSEPSTR);
- strcat(wildcard, relpath); /* basename */
+ erts_snprintf(wildcard, sizeof(wildcard), "%s" DIRSEPSTR "%s",
+ dir, relpath /* basename */);
dir_handle = FindFirstFile(wildcard, &find_data);
if (dir_handle == INVALID_HANDLE_VALUE) {
/* Try next directory in path */
@@ -217,9 +222,8 @@ find_prog(char *origpath)
if (strcmp(origpath, dirp->d_name) == 0) {
/* Wow we found the executable. */
- strcpy(relpath, dir);
- strcat(relpath, DIRSEPSTR);
- strcat(relpath, dirp->d_name);
+ erts_snprintf(relpath, sizeof(relpath), "%s" DIRSEPSTR "%s",
+ dir, dirp->d_name);
closedir(dp);
look_for_sep = FALSE;
break;
@@ -291,7 +295,7 @@ append_shebang_args(char* scriptname)
/* Find end of arg */
end = beg;
- while (end && end[0] != ' ') {
+ while (end && end < (linebuf+LINEBUFSZ-1) && end[0] != ' ') {
if (end[0] == '\n') {
newline = TRUE;
end[0]= '\0';
@@ -335,13 +339,16 @@ main(int argc, char** argv)
emulator = get_default_emulator(argv[0]);
}
+ if (strlen(emulator) >= PMAX)
+ error("Value of environment variable ESCRIPT_EMULATOR is too large");
+
/*
* Allocate the argv vector to be used for arguments to Erlang.
* Arrange for starting to pushing information in the middle of
* the array, to allow easy addition of commands in the beginning.
*/
- eargv_size = argc*4+1000;
+ eargv_size = argc*4+1000+LINEBUFSZ/2;
eargv_base = (char **) emalloc(eargv_size*sizeof(char*));
eargv = eargv_base;
eargc = 0;
@@ -387,7 +394,8 @@ main(int argc, char** argv)
if (argc <= 1) {
error("Missing filename\n");
}
- strcpy(scriptname, argv[1]);
+ strncpy(scriptname, argv[1], sizeof(scriptname));
+ scriptname[sizeof(scriptname)-1] = '\0';
argc--;
argv++;
} else {
@@ -395,16 +403,17 @@ main(int argc, char** argv)
int len;
#endif
absname = find_prog(argv[0]);
- strcpy(scriptname, absname);
- efree(absname);
#ifdef __WIN32__
- len = strlen(scriptname);
- if (len >= 4 && _stricmp(scriptname+len-4, ".exe") == 0) {
- scriptname[len-4] = '\0';
+ len = strlen(absname);
+ if (len >= 4 && _stricmp(absname+len-4, ".exe") == 0) {
+ absname[len-4] = '\0';
}
#endif
- strcat(scriptname, ".escript");
+ erts_snprintf(scriptname, sizeof(scriptname), "%s.escript",
+ absname);
+ efree(absname);
+
}
/*
@@ -455,7 +464,7 @@ main(int argc, char** argv)
static void
push_words(char* src)
{
- char sbuf[1024];
+ char sbuf[PMAX];
char* dst;
dst = sbuf;
@@ -584,7 +593,7 @@ error(char* format, ...)
va_list ap;
va_start(ap, format);
- vsprintf(sbuf, format, ap);
+ erts_vsnprintf(sbuf, sizeof(sbuf), format, ap);
va_end(ap);
fprintf(stderr, "escript: %s\n", sbuf);
exit(1);
@@ -619,6 +628,9 @@ get_default_emulator(char* progname)
char sbuf[MAXPATHLEN];
char* s;
+ if (strlen(progname) >= sizeof(sbuf))
+ return ERL_NAME;
+
strcpy(sbuf, progname);
for (s = sbuf+strlen(sbuf); s >= sbuf; s--) {
if (IS_DIRSEP(*s)) {
diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c
index 4f738947b7..3e19e5f386 100644
--- a/erts/etc/common/heart.c
+++ b/erts/etc/common/heart.c
@@ -375,7 +375,8 @@ main(int argc, char **argv)
_setmode(erlin_fd,_O_BINARY);
_setmode(erlout_fd,_O_BINARY);
#endif
- strcpy(program_name, argv[0]);
+ strncpy(program_name, argv[0], sizeof(program_name));
+ program_name[sizeof(program_name)-1] = '\0';
notify_ack(erlout_fd);
cmd[0] = '\0';
do_terminate(message_loop(erlin_fd,erlout_fd));
@@ -728,7 +729,11 @@ heart_cmd_reply(int fd, char *s)
struct msg m;
int len = strlen(s) + 1; /* Include \0 */
- /* FIXME if s >= MSG_BODY_SIZE error */
+ /* if s >= MSG_BODY_SIZE, return a write
+ * failure immediately.
+ */
+ if (len > sizeof(m.fill))
+ return -1;
m.op = HEART_CMD;
m.len = htons(len + 2); /* Include Op */
diff --git a/erts/etc/common/inet_gethost.c b/erts/etc/common/inet_gethost.c
index d3ff4874ac..8bd9368aa1 100644
--- a/erts/etc/common/inet_gethost.c
+++ b/erts/etc/common/inet_gethost.c
@@ -59,15 +59,14 @@
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <windows.h>
+#include <ws2tcpip.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
/* These are not used even if they would exist which they should not */
-#undef HAVE_GETADDRINFO
#undef HAVE_GETIPNODEBYNAME
#undef HAVE_GETHOSTBYNAME2
-#undef HAVE_GETNAMEINFO
#undef HAVE_GETIPNODEBYADDR
#else /* Unix */
@@ -1761,7 +1760,7 @@ static int worker_loop(void)
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
- hints.ai_flags = (AI_CANONNAME|AI_V4MAPPED|AI_ADDRCONFIG);
+ hints.ai_flags = AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_INET6;
DEBUGF(5, ("Starting getaddrinfo(%s, ...)", data));
diff --git a/erts/etc/common/typer.c b/erts/etc/common/typer.c
index c2567cb8b4..de48daf002 100644
--- a/erts/etc/common/typer.c
+++ b/erts/etc/common/typer.c
@@ -175,7 +175,7 @@ main(int argc, char** argv)
static void
push_words(char* src)
{
- char sbuf[1024];
+ char sbuf[MAXPATHLEN];
char* dst;
dst = sbuf;
@@ -307,7 +307,7 @@ error(char* format, ...)
va_list ap;
va_start(ap, format);
- vsprintf(sbuf, format, ap);
+ erts_vsnprintf(sbuf, sizeof(sbuf), format, ap);
va_end(ap);
fprintf(stderr, "typer: %s\n", sbuf);
exit(1);
@@ -336,6 +336,9 @@ get_default_emulator(char* progname)
char sbuf[MAXPATHLEN];
char* s;
+ if (strlen(progname) >= sizeof(sbuf))
+ return ERL_NAME;
+
strcpy(sbuf, progname);
for (s = sbuf+strlen(sbuf); s >= sbuf; s--) {
if (IS_DIRSEP(*s)) {
diff --git a/erts/etc/unix/Install.src b/erts/etc/unix/Install.src
index 7dead62ab0..8f40c43874 100644
--- a/erts/etc/unix/Install.src
+++ b/erts/etc/unix/Install.src
@@ -89,9 +89,12 @@ cp -p $ERL_ROOT/erts-%I_VSN%/bin/erl .
cp -p $ERL_ROOT/erts-%I_VSN%/bin/erlc .
cp -p $ERL_ROOT/erts-%I_VSN%/bin/dialyzer .
cp -p $ERL_ROOT/erts-%I_VSN%/bin/typer .
-cp -p $ERL_ROOT/erts-%I_VSN%/bin/run_test .
+cp -p $ERL_ROOT/erts-%I_VSN%/bin/ct_run .
cp -p $ERL_ROOT/erts-%I_VSN%/bin/escript .
+# Remove in R16B
+ln -s ct_run run_test
+
#
# Set a soft link to epmd
# This should not be done for an embedded system!
diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src
index 9dab9fcfcc..69840daf69 100644
--- a/erts/etc/unix/cerl.src
+++ b/erts/etc/unix/cerl.src
@@ -66,6 +66,7 @@ core=
GDB=
GDBBP=
+GDBARGS=
TYPE=
EMU_TYPE=
debug=
@@ -227,17 +228,30 @@ if [ $run_valgrind != yes ]; then
fi
if [ "x$GDB" = "x" ]; then
if [ $run_valgrind = yes ]; then
+ valversion=`valgrind --version`
+ valmajor=`echo $valversion | sed 's,[a-z]*\-\([0-9]*\).*,\1,'`
+ valminor=`echo $valversion | sed 's,[a-z]*\-[0-9]*.\([0-9]*\).*,\1,'`
emu_xargs=`echo $xargs | sed "s|+|-|g"`
- if [ "x$VALGRIND_LOG_DIR" = "x" ]; then
- valgrind_log=
- else
- valgrind_log="--log-file=$VALGRIND_LOG_DIR/$VALGRIND_LOGFILE_PREFIX$VALGRIND_LOGFILE_INFIX$EMU.log"
- fi
if [ "x$VALGRIND_LOG_XML" = "x" ]; then
valgrind_xml=
+ log_file_prefix="--log-file="
else
export VALGRIND_LOG_XML
valgrind_xml="--xml=yes"
+ if [ $valmajor -gt 2 -a $valminor -gt 4 ]; then
+ log_file_prefix="--xml-file="
+ else
+ log_file_prefix="--log-file="
+ fi
+ fi
+ if [ "x$VALGRIND_LOG_DIR" = "x" ]; then
+ valgrind_log=
+ else
+ if [ $valmajor -gt 2 -a $valminor -gt 4 ]; then
+ valgrind_log="$log_file_prefix$VALGRIND_LOG_DIR/$VALGRIND_LOGFILE_PREFIX$VALGRIND_LOGFILE_INFIX$EMU.log.$$"
+ else
+ valgrind_log="$log_file_prefix$VALGRIND_LOG_DIR/$VALGRIND_LOGFILE_PREFIX$VALGRIND_LOGFILE_INFIX$EMU.log"
+ fi
fi
if [ "x$VALGRIND_MISC_FLAGS" = "x" ]; then
valgrind_misc_flags=
@@ -280,16 +294,11 @@ else
# Set annotation level for gdb in emacs 22 and higher.
emacs_major=`$EMACS --version | head -1 | sed 's,^[^0-9]*\([0-9]*\).*,\1,g'`
if [ '!' -z "$emacs_major" -a $emacs_major -gt 21 ]; then
- # Hack - wait for etp-commands to be loaded and then set
- # annotation level, could be done more beautifully than with sit-for...
- gdbcmd="$gdbcmd \
- (sit-for 1) \
- (insert-string \"set annotate 3\") \
- (comint-send-input)"
+ GDBARGS="--annotate=3 "
fi
gdbcmd="$gdbcmd $GDBBP \
(insert-string \"source $ROOTDIR/erts/etc/unix/etp-commands\") \
(comint-send-input)"
# Fire up gdb in emacs...
- exec $EMACS --eval "(progn (gdb \"gdb $EMU\") $gdbcmd)"
+ exec $EMACS --eval "(progn (gdb \"gdb $GDBARGS$EMU\") $gdbcmd)"
fi
diff --git a/erts/etc/unix/format_man_pages b/erts/etc/unix/format_man_pages
index 2c4f6eee4f..93dcdcd8fa 100644
--- a/erts/etc/unix/format_man_pages
+++ b/erts/etc/unix/format_man_pages
@@ -3,7 +3,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2009. All Rights Reserved.
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -59,34 +59,21 @@ esac
# Create the 'cat' directories (probably not needed)
#
-cd $ERL_ROOT
+cd $ERL_ROOT/man
-if [ ! -d man/cat1 ]
-then
- mkdir man/cat1
-fi
+for d in 0 1 2 3 4 5 6 7 8 9
+do
+ if [ ! -d cat$d ]
+ then
+ mkdir cat$d
+ fi
-if [ ! -d man/cat3 ]
-then
- mkdir man/cat3
-fi
-
-if [ ! -d man/cat4 ]
-then
- mkdir man/cat4
-fi
-
-if [ ! -d man/cat6 ]
-then
- mkdir man/cat6
-fi
+done
#
# Cleanup old formatting
#
-cd $ERL_ROOT/man
-
rm -f whatis windex
# Remove old cat files
diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c
index 4bb148df98..cadff12c6f 100644
--- a/erts/etc/unix/run_erl.c
+++ b/erts/etc/unix/run_erl.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -75,6 +75,9 @@
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
+#if defined(__sun) && defined(__SVR4)
+# include <stropts.h>
+#endif
#include "run_erl.h"
#include "safe_string.h" /* sn_printf, strn_cpy, strn_cat, etc */
@@ -864,8 +867,12 @@ static int open_pty_master(char **ptyslave)
/* Use the posix_openpt if working, as this guarantees creation of the
slave device properly. */
-#ifdef HAVE_WORKING_POSIX_OPENPT
+#if defined(HAVE_WORKING_POSIX_OPENPT) || (defined(__sun) && defined(__SVR4))
+# ifdef HAVE_WORKING_POSIX_OPENPT
if ((mfd = posix_openpt(O_RDWR)) >= 0) {
+# elif defined(__sun) && defined(__SVR4)
+ if ((mfd = open("/dev/ptmx", O_RDWR)) >= 0) {
+# endif
if ((*ptyslave = ptsname(mfd)) != NULL &&
grantpt(mfd) == 0 &&
unlockpt(mfd) == 0) {
@@ -981,8 +988,28 @@ static int open_pty_slave(char *name)
return -1;
}
+#if defined(__sun) && defined(__SVR4)
+ /* Load the necessary STREAMS modules for Solaris */
+ if ((ioctl(sfd, I_FIND, "ldterm")) < 0) {
+ ERROR0(LOG_ERR, "Failed to find ldterm STREAMS module");
+ return -1;
+ }
+ if (ioctl(sfd, I_PUSH, "ptem") < 0) {
+ ERROR0(LOG_ERR, "Failed to push ptem STREAMS module");
+ return -1;
+ }
+ if (ioctl(sfd, I_PUSH, "ldterm") < 0) {
+ ERROR0(LOG_ERR, "Failed to push ldterm STREAMS module");
+ return -1;
+ }
+ if (ioctl(sfd, I_PUSH, "ttcompat") < 0) {
+ ERROR0(LOG_ERR, "Failed to push ttcompat STREAMS module");
+ return -1;
+ }
+#endif
+
#ifdef DEBUG
- if (tcgetattr(sfd, &tty_rmode) , 0) {
+ if (tcgetattr(sfd, &tty_rmode) < 0) {
fprintf(stderr, "Cannot get terminals current mode\n");
exit(-1);
}
diff --git a/erts/etc/win32/Install.c b/erts/etc/win32/Install.c
index ca814e3f80..6e60512f6d 100644
--- a/erts/etc/win32/Install.c
+++ b/erts/etc/win32/Install.c
@@ -46,7 +46,7 @@ int main(int argc, char **argv)
HANDLE module = GetModuleHandle(NULL);
char *binaries[] = { "erl.exe", "werl.exe", "erlc.exe",
"dialyzer.exe", "typer.exe",
- "escript.exe", "run_test.exe", NULL };
+ "escript.exe", "ct_run.exe", NULL };
char *scripts[] = { "start_clean.boot", "start_sasl.boot", NULL };
char fromname[MAX_PATH];
char toname[MAX_PATH];
@@ -172,6 +172,20 @@ int main(int argc, char **argv)
}
}
+ // Remove in R16B
+ sprintf(fromname,"%s\\%s",bin_dir,"ct_run.exe");
+ sprintf(toname,"%s\\%s",bin_dir,"run_test.exe");
+ if (GetFileAttributes(fromname) == 0xFFFFFFFF) {
+ fprintf(stderr,"Could not find file %s\n",
+ fromname);
+ exit(1);
+ }
+ if (!CopyFile(fromname,toname,FALSE)) {
+ fprintf(stderr,"Could not copy file %s to %s\n",
+ fromname,toname);
+ fprintf(stderr,"Continuing installation anyway...\n");
+ }
+
for (i = 0; scripts[i] != NULL; ++i) {
sprintf(fromname,"%s\\%s",release_dir,scripts[i]);
sprintf(toname,"%s\\%s",bin_dir,scripts[i]);
diff --git a/erts/etc/win32/cygwin_tools/vc/ld.sh b/erts/etc/win32/cygwin_tools/vc/ld.sh
index b04935ed9b..406c63ffee 100755
--- a/erts/etc/win32/cygwin_tools/vc/ld.sh
+++ b/erts/etc/win32/cygwin_tools/vc/ld.sh
@@ -53,7 +53,7 @@ while test -n "$1" ; do
STDLIB_FORCED=true;
STDLIB=LIBCMTD.LIB;;
-lsocket)
- DEFAULT_LIBRARIES="$DEFAULT_LIBRARIES WS2_32.LIB";;
+ DEFAULT_LIBRARIES="$DEFAULT_LIBRARIES WS2_32.LIB IPHLPAPI.LIB";;
-l*)
y=`echo $x | sed 's,^-l\(.*\),\1,g'`;
MPATH=`cygpath -m $y`;
@@ -158,7 +158,7 @@ else
fi
p=$$
-CMD="$linktype -nologo -incremental:no $CMD $STDLIB $DEFAULT_LIBRARIES"
+CMD="$linktype -nologo -incremental:no -largeaddressaware $CMD $STDLIB $DEFAULT_LIBRARIES"
if [ "X$LD_SH_DEBUG_LOG" != "X" ]; then
echo ld.sh "$SAVE" >>$LD_SH_DEBUG_LOG
echo link.exe $CMD >>$LD_SH_DEBUG_LOG
@@ -168,6 +168,7 @@ RES=$?
CMANIFEST=`cygpath $MANIFEST`
if [ "$RES" = "0" -a -f "$CMANIFEST" ]; then
# Add stuff to manifest to turn off "virtualization"
+ sed -n -i '1h;1!H;${;g;s,<trustInfo.*</trustInfo>.,,g;p;}' $CMANIFEST
sed -i "s/<\/assembly>/ <ms_asmv2:trustInfo xmlns:ms_asmv2=\"urn:schemas-microsoft-com:asm.v2\">\n <ms_asmv2:security>\n <ms_asmv2:requestedPrivileges>\n <ms_asmv2:requestedExecutionLevel level=\"AsInvoker\" uiAccess=\"false\"\/>\n <\/ms_asmv2:requestedPrivileges>\n <\/ms_asmv2:security>\n <\/ms_asmv2:trustInfo>\n<\/assembly>/" $CMANIFEST
eval mt.exe -nologo -manifest "$MANIFEST" -outputresource:"$OUTPUTRES" >>/tmp/link.exe.${p}.1 2>>/tmp/link.exe.${p}.2
diff --git a/erts/etc/win32/nsis/Makefile b/erts/etc/win32/nsis/Makefile
index ebb3ad9a96..981a232c69 100644
--- a/erts/etc/win32/nsis/Makefile
+++ b/erts/etc/win32/nsis/Makefile
@@ -45,6 +45,7 @@ WTARGET_DIR=$(shell (cygpath -d $(TARGET_DIR) 2>/dev/null || cygpath -d $(TARGET
REDIST_FILE=$(shell (sh ./find_redist.sh || echo ""))
REDIST_DLL_VERSION=$(shell (sh ./dll_version_helper.sh || echo ""))
+REDIST_DLL_NAME=$(shell (sh ./dll_version_helper.sh -n || echo ""))
release_spec:
@NSIS_VER=`makensis /hdrinfo | head -1 | awk '{print $$2}'`; \
@@ -73,6 +74,7 @@ release_spec:
cp $(REDIST_FILE) $(RELEASE_PATH)/vcredist_x86.exe;\
echo '!define HAVE_REDIST_FILE 1' >> $(VERSION_HEADER); \
echo '!define REDIST_DLL_VERSION "$(REDIST_DLL_VERSION)"' >> $(VERSION_HEADER);\
+ echo '!define REDIST_DLL_NAME "$(REDIST_DLL_NAME)"' >> $(VERSION_HEADER);\
fi;\
if [ -f $(RELEASE_PATH)/docs/doc/index.html ];\
then \
diff --git a/erts/etc/win32/nsis/dll_version_helper.sh b/erts/etc/win32/nsis/dll_version_helper.sh
index e0047dea8b..571ee3e39e 100755
--- a/erts/etc/win32/nsis/dll_version_helper.sh
+++ b/erts/etc/win32/nsis/dll_version_helper.sh
@@ -2,7 +2,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2007-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
@@ -41,9 +41,15 @@ if [ '!' -f hello.exe.manifest ]; then
exit 0
fi
VERSION=`grep '<assemblyIdentity' hello.exe.manifest | sed 's,.*version=.\([0-9\.]*\).*,\1,g' | grep -v '<'`
+NAME=`grep '<assemblyIdentity' hello.exe.manifest | sed 's,.*name=.[A-Za-z\.]*\([0-9]*\).*,msvcr\1.dll,g' | grep -v '<'`
rm -f hello.c hello.obj hello.exe hello.exe.manifest
-if [ -z "$VERSION" ]; then
+if [ "$1" = "-n" ]; then
+ ASKEDFOR=$NAME
+else
+ ASKEDFOR=$VERSION
+fi
+if [ -z "$ASKEDFOR" ]; then
exit 1
fi
-echo $VERSION
+echo $ASKEDFOR
exit 0
diff --git a/erts/etc/win32/nsis/erlang20.nsi b/erts/etc/win32/nsis/erlang20.nsi
index 43e5d91604..941e8e6f5d 100644
--- a/erts/etc/win32/nsis/erlang20.nsi
+++ b/erts/etc/win32/nsis/erlang20.nsi
@@ -311,23 +311,23 @@ FunctionEnd
Function .onInit
SectionGetFlags 0 $MYTEMP
-; MessageBox MB_YESNO "Found $SYSDIR\msvcr80.dll" IDYES FoundLbl
- IfFileExists $SYSDIR\msvcr80.dll MaybeFoundInSystemLbl
+ ;MessageBox MB_YESNO "Found $SYSDIR\${REDIST_DLL_NAME}" IDYES FoundLbl
+ IfFileExists $SYSDIR\${REDIST_DLL_NAME} MaybeFoundInSystemLbl
SearchSxsLbl:
FindFirst $0 $1 $WINDIR\WinSxS\x86*
LoopLbl:
StrCmp $1 "" NotFoundLbl
- IfFileExists $WINDIR\WinSxS\$1\msvcr80.dll MaybeFoundInSxsLbl
+ IfFileExists $WINDIR\WinSxS\$1\${REDIST_DLL_NAME} MaybeFoundInSxsLbl
FindNext $0 $1
Goto LoopLbl
MaybeFoundInSxsLbl:
- GetDllVersion $WINDIR\WinSxS\$1\msvcr80.dll $R0 $R1
+ GetDllVersion $WINDIR\WinSxS\$1\${REDIST_DLL_NAME} $R0 $R1
Call DllVersionGoodEnough
FindNext $0 $1
IntCmp 2 $R0 LoopLbl
Goto FoundLbl
MaybeFoundInSystemLbl:
- GetDllVersion $SYSDIR\msvcr80.dll $R0 $R1
+ GetDllVersion $SYSDIR\${REDIST_DLL_NAME} $R0 $R1
Call DllVersionGoodEnough
IntCmp 2 $R0 SearchSxSLbl
FoundLbl:
diff --git a/erts/etc/win32/nsis/find_redist.sh b/erts/etc/win32/nsis/find_redist.sh
index c5572839c5..153977ded5 100755
--- a/erts/etc/win32/nsis/find_redist.sh
+++ b/erts/etc/win32/nsis/find_redist.sh
@@ -2,7 +2,7 @@
#
# %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
@@ -107,16 +107,56 @@ for x in cl bin vc; do
fi
BPATH="$NBPATH"
done
+BPATH_LIST=$BPATH
+
+# rc.exe is in the Microsoft SDK directory of VS2008
+RCPATH=`lookup_prog_in_path rc`
+fail=false
+if [ '!' -z "$RCPATH" ]; then
+ BPATH=$RCPATH
+ for x in rc bin v6.0A ; do
+ NBPATH=`remove_path_element $x "$BPATH"`
+ if [ "$NBPATH" = "$BPATH" ]; then
+ fail=true
+ break;
+ fi
+ BPATH="$NBPATH"
+ done
+ if [ $fail = false ]; then
+ BPATH_LIST="$BPATH_LIST $BPATH"
+ fi
+fi
+
+# Frantic search through two roots with different
+# version directories. We want to be very specific about the
+# directory structures as we woildnt want to find the wrong
+# redistributables...
+
#echo $BPATH
-for x in sdk v2.0 bootstrapper packages vcredist_x86 vcredist_x86.exe; do
- #echo "x=$x"
- #echo "BPATH=$BPATH"
- NBPATH=`add_path_element $x "$BPATH"`
- if [ "$NBPATH" = "$BPATH" ]; then
- echo "Failed to locate vcredist_x86.exe because directory structure was unexpected" >&2
- exit 3
+for BP in $BPATH_LIST; do
+ for verdir in "sdk v2.0" "sdk v3.5" "v6.0A"; do
+ BPATH=$BP
+ fail=false
+ for x in $verdir bootstrapper packages vcredist_x86 vcredist_x86.exe; do
+ #echo "x=$x"
+ #echo "BPATH=$BPATH"
+ NBPATH=`add_path_element $x "$BPATH"`
+ if [ "$NBPATH" = "$BPATH" ]; then
+ fail=true
+ break;
+ fi
+ BPATH="$NBPATH"
+ done
+ if [ $fail = false ]; then
+ break;
+ fi
+ done
+ if [ $fail = false ]; then
+ echo $BPATH
+ exit 0
fi
- BPATH="$NBPATH"
done
-echo $BPATH
-exit 0 \ No newline at end of file
+
+echo "Failed to locate vcredist_x86.exe because directory structure was unexpected" >&2
+exit 3
+
diff --git a/erts/include/internal/ethr_atomics.h b/erts/include/internal/ethr_atomics.h
new file mode 100644
index 0000000000..1caf4d0567
--- /dev/null
+++ b/erts/include/internal/ethr_atomics.h
@@ -0,0 +1,726 @@
+/*
+ * %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: The ethread atomic API
+ * Author: Rickard Green
+ */
+
+#ifndef ETHR_ATOMIC_H__
+#define ETHR_ATOMIC_H__
+
+#if !defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
+# define ETHR_NEED_ATOMIC_PROTOTYPES__
+#endif
+
+#ifndef ETHR_HAVE_NATIVE_ATOMICS
+/*
+ * No native atomic implementation available. :(
+ * Use fallback...
+ */
+typedef ethr_sint32_t ethr_atomic32_t;
+typedef ethr_sint_t ethr_atomic_t;
+#else
+/*
+ * Map ethread native atomics to ethread API atomics.
+ *
+ * We do at least have a native atomic implementation that
+ * can handle integers of a size larger than or equal to
+ * the size of pointers.
+ */
+
+/* -- Pointer size atomics -- */
+
+#undef ETHR_NAINT_T__
+#undef ETHR_NATMC_FUNC__
+#undef ETHR_NATMC_ADDR_FUNC__
+#if ETHR_SIZEOF_PTR == 8
+# if defined(ETHR_HAVE_NATIVE_ATOMIC64)
+# define ETHR_NATMC_ADDR_FUNC__ ethr_native_atomic64_addr
+typedef ethr_native_atomic64_t ethr_atomic_t;
+# define ETHR_NAINT_T__ ethr_sint64_t
+# define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
+# else
+# error "Missing native atomic implementation"
+# endif
+#elif ETHR_SIZEOF_PTR == 4
+# define ETHR_NATMC_ADDR_FUNC__ ethr_native_atomic32_addr
+# ifdef ETHR_HAVE_NATIVE_ATOMIC32
+typedef ethr_native_atomic32_t ethr_atomic_t;
+# define ETHR_NAINT_T__ ethr_sint32_t
+# define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
+# elif defined(ETHR_HAVE_NATIVE_ATOMIC64)
+typedef ethr_native_atomic64_t ethr_atomic_t;
+# define ETHR_NATMC_T__ ethr_native_atomic64_t
+# define ETHR_NAINT_T__ ethr_sint64_t
+# define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
+# else
+# error "Missing native atomic implementation"
+# endif
+#endif
+
+/* -- 32-bit atomics -- */
+
+#undef ETHR_NAINT32_T__
+#undef ETHR_NATMC32_FUNC__
+#if defined(ETHR_HAVE_NATIVE_ATOMIC32)
+typedef ethr_native_atomic32_t ethr_atomic32_t;
+# define ETHR_NAINT32_T__ ethr_sint32_t
+# define ETHR_NATMC32_FUNC__(X) ethr_native_atomic32_ ## X
+#elif defined(ETHR_HAVE_NATIVE_ATOMIC64)
+typedef ethr_native_atomic64_t ethr_atomic32_t;
+# define ETHR_NAINT32_T__ ethr_sint64_t
+# define ETHR_NATMC32_FUNC__(X) ethr_native_atomic64_ ## X
+#else
+# error "Missing native atomic implementation"
+#endif
+
+#endif
+
+#ifdef ETHR_NEED_ATOMIC_PROTOTYPES__
+ethr_sint_t *ethr_atomic_addr(ethr_atomic_t *);
+void ethr_atomic_init(ethr_atomic_t *, ethr_sint_t);
+void ethr_atomic_set(ethr_atomic_t *, ethr_sint_t);
+ethr_sint_t ethr_atomic_read(ethr_atomic_t *);
+ethr_sint_t ethr_atomic_inc_read(ethr_atomic_t *);
+ethr_sint_t ethr_atomic_dec_read(ethr_atomic_t *);
+void ethr_atomic_inc(ethr_atomic_t *);
+void ethr_atomic_dec(ethr_atomic_t *);
+ethr_sint_t ethr_atomic_add_read(ethr_atomic_t *, ethr_sint_t);
+void ethr_atomic_add(ethr_atomic_t *, ethr_sint_t);
+ethr_sint_t ethr_atomic_read_band(ethr_atomic_t *, ethr_sint_t);
+ethr_sint_t ethr_atomic_read_bor(ethr_atomic_t *, ethr_sint_t);
+ethr_sint_t ethr_atomic_xchg(ethr_atomic_t *, ethr_sint_t);
+ethr_sint_t ethr_atomic_cmpxchg(ethr_atomic_t *, ethr_sint_t, ethr_sint_t);
+ethr_sint_t ethr_atomic_read_acqb(ethr_atomic_t *);
+ethr_sint_t ethr_atomic_inc_read_acqb(ethr_atomic_t *);
+void ethr_atomic_set_relb(ethr_atomic_t *, ethr_sint_t);
+void ethr_atomic_dec_relb(ethr_atomic_t *);
+ethr_sint_t ethr_atomic_dec_read_relb(ethr_atomic_t *);
+ethr_sint_t ethr_atomic_cmpxchg_acqb(ethr_atomic_t *, ethr_sint_t, ethr_sint_t);
+ethr_sint_t ethr_atomic_cmpxchg_relb(ethr_atomic_t *, ethr_sint_t, ethr_sint_t);
+
+ethr_sint32_t *ethr_atomic32_addr(ethr_atomic32_t *);
+void ethr_atomic32_init(ethr_atomic32_t *, ethr_sint32_t);
+void ethr_atomic32_set(ethr_atomic32_t *, ethr_sint32_t);
+ethr_sint32_t ethr_atomic32_read(ethr_atomic32_t *);
+ethr_sint32_t ethr_atomic32_inc_read(ethr_atomic32_t *);
+ethr_sint32_t ethr_atomic32_dec_read(ethr_atomic32_t *);
+void ethr_atomic32_inc(ethr_atomic32_t *);
+void ethr_atomic32_dec(ethr_atomic32_t *);
+ethr_sint32_t ethr_atomic32_add_read(ethr_atomic32_t *, ethr_sint32_t);
+void ethr_atomic32_add(ethr_atomic32_t *, ethr_sint32_t);
+ethr_sint32_t ethr_atomic32_read_band(ethr_atomic32_t *, ethr_sint32_t);
+ethr_sint32_t ethr_atomic32_read_bor(ethr_atomic32_t *, ethr_sint32_t);
+ethr_sint32_t ethr_atomic32_xchg(ethr_atomic32_t *, ethr_sint32_t);
+ethr_sint32_t ethr_atomic32_cmpxchg(ethr_atomic32_t *,
+ ethr_sint32_t,
+ ethr_sint32_t);
+ethr_sint32_t ethr_atomic32_read_acqb(ethr_atomic32_t *);
+ethr_sint32_t ethr_atomic32_inc_read_acqb(ethr_atomic32_t *);
+void ethr_atomic32_set_relb(ethr_atomic32_t *, ethr_sint32_t);
+void ethr_atomic32_dec_relb(ethr_atomic32_t *);
+ethr_sint32_t ethr_atomic32_dec_read_relb(ethr_atomic32_t *);
+ethr_sint32_t ethr_atomic32_cmpxchg_acqb(ethr_atomic32_t *,
+ ethr_sint32_t,
+ ethr_sint32_t);
+ethr_sint32_t ethr_atomic32_cmpxchg_relb(ethr_atomic32_t *,
+ ethr_sint32_t,
+ ethr_sint32_t);
+#endif
+
+int ethr_init_atomics(void);
+
+#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
+
+#ifndef ETHR_HAVE_NATIVE_ATOMICS
+/*
+ * Fallbacks for atomics used in absence of a native implementation.
+ */
+
+#define ETHR_ATOMIC_ADDR_BITS 10
+#define ETHR_ATOMIC_ADDR_SHIFT 6
+
+typedef struct {
+ union {
+ ethr_spinlock_t lck;
+ char buf[ETHR_CACHE_LINE_SIZE];
+ } u;
+} ethr_atomic_protection_t;
+
+extern ethr_atomic_protection_t ethr_atomic_protection__[1 << ETHR_ATOMIC_ADDR_BITS];
+
+#define ETHR_ATOMIC_PTR2LCK__(PTR) \
+(&ethr_atomic_protection__[((((ethr_uint_t) (PTR)) >> ETHR_ATOMIC_ADDR_SHIFT) \
+ & ((1 << ETHR_ATOMIC_ADDR_BITS) - 1))].u.lck)
+
+
+#define ETHR_ATOMIC_OP_FALLBACK_IMPL__(AP, EXPS) \
+do { \
+ ethr_spinlock_t *slp__ = ETHR_ATOMIC_PTR2LCK__((AP)); \
+ ethr_spin_lock(slp__); \
+ { EXPS; } \
+ ethr_spin_unlock(slp__); \
+} while (0)
+
+#endif
+
+/*
+ * --- Pointer size atomics ---------------------------------------------------
+ */
+
+static ETHR_INLINE ethr_sint_t *
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_addr)(ethr_atomic_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t *) ETHR_NATMC_ADDR_FUNC__(var);
+#else
+ return (ethr_sint_t *) var;
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_init)(ethr_atomic_t *var, ethr_sint_t i)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC_FUNC__(init)(var, (ETHR_NAINT_T__) i);
+#else
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var = i);
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_set)(ethr_atomic_t *var, ethr_sint_t i)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC_FUNC__(set)(var, (ETHR_NAINT_T__) i);
+#else
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var = i);
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_read)(ethr_atomic_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(read)(var);
+#else
+ ethr_sint_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var);
+ return res;
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_add)(ethr_atomic_t *var, ethr_sint_t incr)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC_FUNC__(add)(var, (ETHR_NAINT_T__) incr);
+#else
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var += incr);
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_add_read)(ethr_atomic_t *var, ethr_sint_t i)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(add_return)(var, (ETHR_NAINT_T__) i);
+#else
+ ethr_sint_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var += i; res = *var);
+ return res;
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_inc)(ethr_atomic_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC_FUNC__(inc)(var);
+#else
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, ++(*var));
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec)(ethr_atomic_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC_FUNC__(dec)(var);
+#else
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, --(*var));
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_inc_read)(ethr_atomic_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(inc_return)(var);
+#else
+ ethr_sint_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = ++(*var));
+ return res;
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec_read)(ethr_atomic_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(dec_return)(var);
+#else
+ ethr_sint_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = --(*var));
+ return res;
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_read_band)(ethr_atomic_t *var,
+ ethr_sint_t mask)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(and_retold)(var,
+ (ETHR_NAINT_T__) mask);
+#else
+ ethr_sint_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var; *var &= mask);
+ return res;
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_read_bor)(ethr_atomic_t *var,
+ ethr_sint_t mask)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(or_retold)(var,
+ (ETHR_NAINT_T__) mask);
+#else
+ ethr_sint_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var; *var |= mask);
+ return res;
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_xchg)(ethr_atomic_t *var, ethr_sint_t new)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(xchg)(var,
+ (ETHR_NAINT_T__) new);
+#else
+ ethr_sint_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var; *var = new);
+ return res;
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_cmpxchg)(ethr_atomic_t *var,
+ ethr_sint_t new,
+ ethr_sint_t exp)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(cmpxchg)(var,
+ (ETHR_NAINT_T__) new,
+ (ETHR_NAINT_T__) exp);
+#else
+ ethr_sint_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var,
+ {
+ res = *var;
+ if (__builtin_expect(res == exp, 1))
+ *var = new;
+ });
+ return res;
+#endif
+}
+
+/*
+ * Important memory barrier requirements.
+ *
+ * The following atomic operations *must* supply a memory barrier of
+ * at least the type specified by its suffix:
+ * _acqb = acquire barrier
+ * _relb = release barrier
+ */
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_read_acqb)(ethr_atomic_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(read_acqb)(var);
+#else
+ return ETHR_INLINE_FUNC_NAME_(ethr_atomic_read)(var);
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_inc_read_acqb)(ethr_atomic_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(inc_return_acqb)(var);
+#else
+ return ETHR_INLINE_FUNC_NAME_(ethr_atomic_inc_read)(var);
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_set_relb)(ethr_atomic_t *var,
+ ethr_sint_t val)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC_FUNC__(set_relb)(var, (ETHR_NAINT_T__) val);
+#else
+ ETHR_INLINE_FUNC_NAME_(ethr_atomic_set)(var, val);
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec_relb)(ethr_atomic_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC_FUNC__(dec_relb)(var);
+#else
+ ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec)(var);
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec_read_relb)(ethr_atomic_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(dec_return_relb)(var);
+#else
+ return ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec_read)(var);
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_cmpxchg_acqb)(ethr_atomic_t *var,
+ ethr_sint_t new,
+ ethr_sint_t exp)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(cmpxchg_acqb)(var,
+ (ETHR_NAINT_T__) new,
+ (ETHR_NAINT_T__) exp);
+#else
+ return ETHR_INLINE_FUNC_NAME_(ethr_atomic_cmpxchg)(var, new, exp);
+#endif
+}
+
+static ETHR_INLINE ethr_sint_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic_cmpxchg_relb)(ethr_atomic_t *var,
+ ethr_sint_t new,
+ ethr_sint_t exp)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint_t) ETHR_NATMC_FUNC__(cmpxchg_relb)(var,
+ (ETHR_NAINT_T__) new,
+ (ETHR_NAINT_T__) exp);
+#else
+ return ETHR_INLINE_FUNC_NAME_(ethr_atomic_cmpxchg)(var, new, exp);
+#endif
+}
+
+/*
+ * --- 32-bit atomics ---------------------------------------------------------
+ */
+
+static ETHR_INLINE ethr_sint32_t *
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_addr)(ethr_atomic32_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return ethr_native_atomic32_addr(var);
+#else
+ return (ethr_sint32_t *) var;
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_init)(ethr_atomic32_t *var,
+ ethr_sint32_t i)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC32_FUNC__(init)(var, (ETHR_NAINT32_T__) i);
+#else
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var = i);
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_set)(ethr_atomic32_t *var, ethr_sint32_t i)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC32_FUNC__(set)(var, (ETHR_NAINT32_T__) i);
+#else
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var = i);
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_read)(ethr_atomic32_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t) ETHR_NATMC32_FUNC__(read)(var);
+#else
+ ethr_sint32_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var);
+ return res;
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_add)(ethr_atomic32_t *var,
+ ethr_sint32_t incr)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC32_FUNC__(add)(var, (ETHR_NAINT32_T__) incr);
+#else
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var += incr);
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_add_read)(ethr_atomic32_t *var,
+ ethr_sint32_t i)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t)
+ ETHR_NATMC32_FUNC__(add_return)(var, (ETHR_NAINT32_T__) i);
+#else
+ ethr_sint32_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var += i; res = *var);
+ return res;
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_inc)(ethr_atomic32_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC32_FUNC__(inc)(var);
+#else
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, ++(*var));
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_dec)(ethr_atomic32_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC32_FUNC__(dec)(var);
+#else
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, --(*var));
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_inc_read)(ethr_atomic32_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t) ETHR_NATMC32_FUNC__(inc_return)(var);
+#else
+ ethr_sint32_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = ++(*var));
+ return res;
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_dec_read)(ethr_atomic32_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t) ETHR_NATMC32_FUNC__(dec_return)(var);
+#else
+ ethr_sint32_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = --(*var));
+ return res;
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_read_band)(ethr_atomic32_t *var,
+ ethr_sint32_t mask)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t)
+ ETHR_NATMC32_FUNC__(and_retold)(var, (ETHR_NAINT32_T__) mask);
+#else
+ ethr_sint32_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var; *var &= mask);
+ return res;
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_read_bor)(ethr_atomic32_t *var,
+ ethr_sint32_t mask)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return
+ (ethr_sint32_t) ETHR_NATMC32_FUNC__(or_retold)(var,
+ (ETHR_NAINT32_T__) mask);
+#else
+ ethr_sint32_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var; *var |= mask);
+ return res;
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_xchg)(ethr_atomic32_t *var,
+ ethr_sint32_t new)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t) ETHR_NATMC32_FUNC__(xchg)(var,
+ (ETHR_NAINT32_T__) new);
+#else
+ ethr_sint32_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var; *var = new);
+ return res;
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_cmpxchg)(ethr_atomic32_t *var,
+ ethr_sint32_t new,
+ ethr_sint32_t exp)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t) ETHR_NATMC32_FUNC__(cmpxchg)(var,
+ (ETHR_NAINT32_T__) new,
+ (ETHR_NAINT32_T__) exp);
+#else
+ ethr_sint32_t res;
+ ETHR_ATOMIC_OP_FALLBACK_IMPL__(var,
+ {
+ res = *var;
+ if (__builtin_expect(res == exp, 1))
+ *var = new;
+ });
+ return res;
+#endif
+}
+
+/*
+ * Important memory barrier requirements.
+ *
+ * The following atomic operations *must* supply a memory barrier of
+ * at least the type specified by its suffix:
+ * _acqb = acquire barrier
+ * _relb = release barrier
+ */
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_read_acqb)(ethr_atomic32_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t) ETHR_NATMC32_FUNC__(read_acqb)(var);
+#else
+ return ETHR_INLINE_FUNC_NAME_(ethr_atomic32_read)(var);
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_inc_read_acqb)(ethr_atomic32_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t) ETHR_NATMC32_FUNC__(inc_return_acqb)(var);
+#else
+ return ETHR_INLINE_FUNC_NAME_(ethr_atomic32_inc_read)(var);
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_set_relb)(ethr_atomic32_t *var,
+ ethr_sint32_t val)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC32_FUNC__(set_relb)(var, (ETHR_NAINT32_T__) val);
+#else
+ ETHR_INLINE_FUNC_NAME_(ethr_atomic32_set)(var, val);
+#endif
+}
+
+static ETHR_INLINE void
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_dec_relb)(ethr_atomic32_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ ETHR_NATMC32_FUNC__(dec_relb)(var);
+#else
+ ETHR_INLINE_FUNC_NAME_(ethr_atomic32_dec)(var);
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_dec_read_relb)(ethr_atomic32_t *var)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t) ETHR_NATMC32_FUNC__(dec_return_relb)(var);
+#else
+ return ETHR_INLINE_FUNC_NAME_(ethr_atomic32_dec_read)(var);
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_cmpxchg_acqb)(ethr_atomic32_t *var,
+ ethr_sint32_t new,
+ ethr_sint32_t exp)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t)
+ ETHR_NATMC32_FUNC__(cmpxchg_acqb)(var,
+ (ETHR_NAINT32_T__) new,
+ (ETHR_NAINT32_T__) exp);
+#else
+ return ETHR_INLINE_FUNC_NAME_(ethr_atomic32_cmpxchg)(var, new, exp);
+#endif
+}
+
+static ETHR_INLINE ethr_sint32_t
+ETHR_INLINE_FUNC_NAME_(ethr_atomic32_cmpxchg_relb)(ethr_atomic32_t *var,
+ ethr_sint32_t new,
+ ethr_sint32_t exp)
+{
+#ifdef ETHR_HAVE_NATIVE_ATOMICS
+ return (ethr_sint32_t)
+ ETHR_NATMC32_FUNC__(cmpxchg_relb)(var,
+ (ETHR_NAINT32_T__) new,
+ (ETHR_NAINT32_T__) exp);
+#else
+ return ETHR_INLINE_FUNC_NAME_(ethr_atomic32_cmpxchg)(var, new, exp);
+#endif
+}
+
+
+#endif /* ETHR_TRY_INLINE_FUNCS */
+
+#undef ETHR_NAINT_T__
+#undef ETHR_NATMC_FUNC__
+#undef ETHR_NATMC_ADDR_FUNC__
+
+#undef ETHR_NAINT32_T__
+#undef ETHR_NATMC32_FUNC__
+
+#endif
diff --git a/erts/include/internal/ethr_mutex.h b/erts/include/internal/ethr_mutex.h
index 8d9d5e3d08..fadaf1e2a4 100644
--- a/erts/include/internal/ethr_mutex.h
+++ b/erts/include/internal/ethr_mutex.h
@@ -33,6 +33,13 @@
# define ETHR_MTX_HARD_DEBUG
#endif
+#if 0
+# define ETHR_MTX_CHK_EXCL
+#if 1
+# define ETHR_MTX_CHK_NON_EXCL
+#endif
+#endif
+
#ifdef ETHR_MTX_HARD_DEBUG
# ifdef __GNUC__
# warning ETHR_MTX_HARD_DEBUG
@@ -49,6 +56,15 @@
#if defined(ETHR_USE_OWN_RWMTX_IMPL__) || defined(ETHR_USE_OWN_MTX_IMPL__)
+#ifdef ETHR_DEBUG
+# ifndef ETHR_MTX_CHK_EXCL
+# define ETHR_MTX_CHK_EXCL
+# endif
+# ifndef ETHR_MTX_CHK_NON_EXCL
+# define ETHR_MTX_CHK_NON_EXCL
+# endif
+#endif
+
#if 0
# define ETHR_MTX_Q_LOCK_SPINLOCK__
# define ETHR_MTX_QLOCK_TYPE__ ethr_spinlock_t
@@ -62,14 +78,14 @@
# error Need a qlock implementation
#endif
-#define ETHR_RWMTX_W_FLG__ (((long) 1) << 31)
-#define ETHR_RWMTX_W_WAIT_FLG__ (((long) 1) << 30)
-#define ETHR_RWMTX_R_WAIT_FLG__ (((long) 1) << 29)
+#define ETHR_RWMTX_W_FLG__ (((ethr_sint32_t) 1) << 31)
+#define ETHR_RWMTX_W_WAIT_FLG__ (((ethr_sint32_t) 1) << 30)
+#define ETHR_RWMTX_R_WAIT_FLG__ (((ethr_sint32_t) 1) << 29)
/* frequent read kind */
-#define ETHR_RWMTX_R_FLG__ (((long) 1) << 28)
-#define ETHR_RWMTX_R_PEND_UNLCK_MASK__ (ETHR_RWMTX_R_FLG__ - 1)
-#define ETHR_RWMTX_R_MASK__ (ETHR_RWMTX_R_WAIT_FLG__ - 1)
+#define ETHR_RWMTX_R_FLG__ (((ethr_sint32_t) 1) << 28)
+#define ETHR_RWMTX_R_ABRT_UNLCK_FLG__ (((ethr_sint32_t) 1) << 27)
+#define ETHR_RWMTX_R_PEND_UNLCK_MASK__ (ETHR_RWMTX_R_ABRT_UNLCK_FLG__ - 1)
/* normal kind */
#define ETHR_RWMTX_RS_MASK__ (ETHR_RWMTX_R_WAIT_FLG__ - 1)
@@ -79,20 +95,39 @@
#define ETHR_CND_WAIT_FLG__ ETHR_RWMTX_R_WAIT_FLG__
+#ifdef ETHR_DEBUG
+#define ETHR_DBG_CHK_UNUSED_FLG_BITS(V) \
+ ETHR_ASSERT(!((V) & ~(ETHR_RWMTX_W_FLG__ \
+ | ETHR_RWMTX_W_WAIT_FLG__ \
+ | ETHR_RWMTX_R_WAIT_FLG__ \
+ | ETHR_RWMTX_RS_MASK__)))
+#else
+#define ETHR_DBG_CHK_UNUSED_FLG_BITS(V)
+#endif
+
+#define ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(MTX) \
+ ETHR_DBG_CHK_UNUSED_FLG_BITS(ethr_atomic32_read(&(MTX)->mtxb.flgs))
+
struct ethr_mutex_base_ {
#ifdef ETHR_MTX_HARD_DEBUG_FENCE
long pre_fence;
#endif
- ethr_atomic_t flgs;
- ETHR_MTX_QLOCK_TYPE__ qlck;
- ethr_ts_event *q;
+ ethr_atomic32_t flgs;
short aux_scnt;
short main_scnt;
+ ETHR_MTX_QLOCK_TYPE__ qlck;
+ ethr_ts_event *q;
#ifdef ETHR_MTX_HARD_DEBUG_WSQ
int ws;
#endif
+#ifdef ETHR_MTX_CHK_EXCL
+ ethr_atomic32_t exclusive;
+#endif
+#ifdef ETHR_MTX_CHK_NON_EXCL
+ ethr_atomic32_t non_exclusive;
+#endif
#ifdef ETHR_MTX_HARD_DEBUG_LFS
- ethr_atomic_t hdbg_lfs;
+ ethr_atomic32_t hdbg_lfs;
#endif
};
@@ -201,7 +236,7 @@ typedef struct {
typedef union {
struct {
- ethr_atomic_t readers;
+ ethr_atomic32_t readers;
int waiting_readers;
int byte_offset;
ethr_rwmutex_lived lived;
@@ -263,13 +298,13 @@ void ethr_rwmutex_rwunlock(ethr_rwmutex *);
#ifdef ETHR_MTX_HARD_DEBUG_LFS
# define ETHR_MTX_HARD_DEBUG_LFS_INIT(MTXB) \
do { \
- ethr_atomic_init(&(MTXB)->hdbg_lfs, 0); \
+ ethr_atomic32_init(&(MTXB)->hdbg_lfs, 0); \
} while (0)
# define ETHR_MTX_HARD_DEBUG_LFS_RLOCK(MTXB) \
do { \
- long val__; \
+ ethr_sint32_t val__; \
ETHR_COMPILER_BARRIER; \
- val__ = ethr_atomic_inc_read(&(MTXB)->hdbg_lfs); \
+ val__ = ethr_atomic32_inc_read(&(MTXB)->hdbg_lfs); \
ETHR_MTX_HARD_ASSERT(val__ > 0); \
} while (0)
# define ETHR_MTX_HARD_DEBUG_LFS_TRYRLOCK(MTXB, RES) \
@@ -282,15 +317,15 @@ do { \
} while (0)
# define ETHR_MTX_HARD_DEBUG_LFS_RUNLOCK(MTXB) \
do { \
- long val__ = ethr_atomic_dec_read(&(MTXB)->hdbg_lfs); \
+ ethr_sint32_t val__ = ethr_atomic32_dec_read(&(MTXB)->hdbg_lfs); \
ETHR_MTX_HARD_ASSERT(val__ >= 0); \
ETHR_COMPILER_BARRIER; \
} while (0)
# define ETHR_MTX_HARD_DEBUG_LFS_RWLOCK(MTXB) \
do { \
- long val__; \
+ ethr_sint32_t val__; \
ETHR_COMPILER_BARRIER; \
- val__ = ethr_atomic_dec_read(&(MTXB)->hdbg_lfs); \
+ val__ = ethr_atomic32_dec_read(&(MTXB)->hdbg_lfs); \
ETHR_MTX_HARD_ASSERT(val__ == -1); \
} while (0)
# define ETHR_MTX_HARD_DEBUG_LFS_TRYRWLOCK(MTXB, RES) \
@@ -303,7 +338,7 @@ do { \
} while (0)
# define ETHR_MTX_HARD_DEBUG_LFS_RWUNLOCK(MTXB) \
do { \
- long val__ = ethr_atomic_inctest(&(MTXB)->hdbg_lfs); \
+ ethr_sint32_t val__ = ethr_atomic32_inctest(&(MTXB)->hdbg_lfs); \
ETHR_MTX_HARD_ASSERT(val__ == 0); \
ETHR_COMPILER_BARRIER; \
} while (0)
@@ -344,6 +379,116 @@ do { \
#define ETHR_MTX_HARD_DEBUG_FENCE_INIT(X)
#endif
+#ifdef ETHR_MTX_CHK_EXCL
+
+#if !defined(ETHR_DEBUG) && defined(__GNUC__)
+#warning "check exclusive is enabled"
+#endif
+
+# define ETHR_MTX_CHK_EXCL_INIT__(MTXB) \
+ ethr_atomic32_init(&(MTXB)->exclusive, 0)
+
+# define ETHR_MTX_CHK_EXCL_IS_EXCL(MTXB) \
+do { \
+ ETHR_COMPILER_BARRIER; \
+ if (!ethr_atomic32_read(&(MTXB)->exclusive)) \
+ ethr_assert_failed(__FILE__, __LINE__, __func__,\
+ "is exclusive"); \
+ ETHR_COMPILER_BARRIER; \
+} while (0)
+# define ETHR_MTX_CHK_EXCL_IS_NOT_EXCL(MTXB) \
+do { \
+ ETHR_COMPILER_BARRIER; \
+ if (ethr_atomic32_read(&(MTXB)->exclusive)) \
+ ethr_assert_failed(__FILE__, __LINE__, __func__,\
+ "is not exclusive"); \
+ ETHR_COMPILER_BARRIER; \
+} while (0)
+# define ETHR_MTX_CHK_EXCL_SET_EXCL(MTXB) \
+do { \
+ ETHR_MTX_CHK_EXCL_IS_NOT_EXCL((MTXB)); \
+ ethr_atomic32_set(&(MTXB)->exclusive, 1); \
+ ETHR_COMPILER_BARRIER; \
+} while (0)
+# define ETHR_MTX_CHK_EXCL_UNSET_EXCL(MTXB) \
+do { \
+ ETHR_MTX_CHK_EXCL_IS_EXCL((MTXB)); \
+ ethr_atomic32_set(&(MTXB)->exclusive, 0); \
+ ETHR_COMPILER_BARRIER; \
+} while (0)
+
+#ifdef ETHR_MTX_CHK_NON_EXCL
+
+#if !defined(ETHR_DEBUG) && defined(__GNUC__)
+#warning "check non-exclusive is enabled"
+#endif
+
+# define ETHR_MTX_CHK_NON_EXCL_INIT__(MTXB) \
+ ethr_atomic32_init(&(MTXB)->non_exclusive, 0)
+# define ETHR_MTX_CHK_EXCL_IS_NON_EXCL(MTXB) \
+do { \
+ ETHR_COMPILER_BARRIER; \
+ if (!ethr_atomic32_read(&(MTXB)->non_exclusive)) \
+ ethr_assert_failed(__FILE__, __LINE__, __func__,\
+ "is non-exclusive"); \
+ ETHR_COMPILER_BARRIER; \
+} while (0)
+# define ETHR_MTX_CHK_EXCL_IS_NOT_NON_EXCL(MTXB) \
+do { \
+ ETHR_COMPILER_BARRIER; \
+ if (ethr_atomic32_read(&(MTXB)->non_exclusive)) \
+ ethr_assert_failed(__FILE__, __LINE__, __func__,\
+ "is not non-exclusive"); \
+ ETHR_COMPILER_BARRIER; \
+} while (0)
+# define ETHR_MTX_CHK_EXCL_SET_NON_EXCL(MTXB) \
+do { \
+ ETHR_COMPILER_BARRIER; \
+ ethr_atomic32_inc(&(MTXB)->non_exclusive); \
+ ETHR_COMPILER_BARRIER; \
+} while (0)
+# define ETHR_MTX_CHK_EXCL_SET_NON_EXCL_NO(MTXB, NO) \
+do { \
+ ETHR_COMPILER_BARRIER; \
+ ethr_atomic32_add(&(MTXB)->non_exclusive, (NO)); \
+ ETHR_COMPILER_BARRIER; \
+} while (0)
+# define ETHR_MTX_CHK_EXCL_UNSET_NON_EXCL(MTXB) \
+do { \
+ ETHR_COMPILER_BARRIER; \
+ ethr_atomic32_dec(&(MTXB)->non_exclusive); \
+ ETHR_COMPILER_BARRIER; \
+} while (0)
+#else
+# define ETHR_MTX_CHK_NON_EXCL_INIT__(MTXB)
+# define ETHR_MTX_CHK_EXCL_IS_NON_EXCL(MTXB)
+# define ETHR_MTX_CHK_EXCL_IS_NOT_NON_EXCL(MTXB)
+# define ETHR_MTX_CHK_EXCL_SET_NON_EXCL_NO(MTXB, NO)
+# define ETHR_MTX_CHK_EXCL_SET_NON_EXCL(MTXB)
+# define ETHR_MTX_CHK_EXCL_UNSET_NON_EXCL(MTXB)
+#endif
+
+#else
+# define ETHR_MTX_CHK_EXCL_INIT__(MTXB)
+# define ETHR_MTX_CHK_EXCL_IS_EXCL(MTXB)
+# define ETHR_MTX_CHK_EXCL_IS_NOT_EXCL(MTXB)
+# define ETHR_MTX_CHK_EXCL_SET_EXCL(MTXB)
+# define ETHR_MTX_CHK_EXCL_UNSET_EXCL(MTXB)
+# define ETHR_MTX_CHK_NON_EXCL_INIT__(MTXB)
+# define ETHR_MTX_CHK_EXCL_IS_NON_EXCL(MTXB)
+# define ETHR_MTX_CHK_EXCL_IS_NOT_NON_EXCL(MTXB)
+# define ETHR_MTX_CHK_EXCL_SET_NON_EXCL_NO(MTXB, NO)
+# define ETHR_MTX_CHK_EXCL_SET_NON_EXCL(MTXB)
+# define ETHR_MTX_CHK_EXCL_UNSET_NON_EXCL(MTXB)
+#endif
+
+# define ETHR_MTX_CHK_EXCL_INIT(MTXB) \
+do { \
+ ETHR_MTX_CHK_EXCL_INIT__((MTXB)); \
+ ETHR_MTX_CHK_NON_EXCL_INIT__((MTXB)); \
+} while (0)
+
+
#ifdef ETHR_USE_OWN_MTX_IMPL__
#define ETHR_MTX_DEFAULT_MAIN_SPINCOUNT_MAX 2000
@@ -356,21 +501,28 @@ do { \
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_MUTEX_IMPL__)
-void ethr_mutex_lock_wait__(ethr_mutex *, long);
-void ethr_mutex_unlock_wake__(ethr_mutex *, long);
+void ethr_mutex_lock_wait__(ethr_mutex *, ethr_sint32_t);
+void ethr_mutex_unlock_wake__(ethr_mutex *, ethr_sint32_t);
static ETHR_INLINE int
ETHR_INLINE_FUNC_NAME_(ethr_mutex_trylock)(ethr_mutex *mtx)
{
- long act;
+ ethr_sint32_t act;
int res;
ETHR_MTX_HARD_DEBUG_FENCE_CHK(mtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(mtx);
- act = ethr_atomic_cmpxchg_acqb(&mtx->mtxb.flgs, ETHR_RWMTX_W_FLG__, 0);
+ act = ethr_atomic32_cmpxchg_acqb(&mtx->mtxb.flgs, ETHR_RWMTX_W_FLG__, 0);
res = (act == 0) ? 0 : EBUSY;
+#ifdef ETHR_MTX_CHK_EXCL
+ if (res == 0)
+ ETHR_MTX_CHK_EXCL_SET_EXCL(&mtx->mtxb);
+#endif
+
ETHR_MTX_HARD_DEBUG_LFS_TRYRWLOCK(&mtx->mtxb, res);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(mtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(mtx);
ETHR_COMPILER_BARRIER;
return res;
@@ -379,15 +531,19 @@ ETHR_INLINE_FUNC_NAME_(ethr_mutex_trylock)(ethr_mutex *mtx)
static ETHR_INLINE void
ETHR_INLINE_FUNC_NAME_(ethr_mutex_lock)(ethr_mutex *mtx)
{
- long act;
+ ethr_sint32_t act;
ETHR_MTX_HARD_DEBUG_FENCE_CHK(mtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(mtx);
- act = ethr_atomic_cmpxchg_acqb(&mtx->mtxb.flgs, ETHR_RWMTX_W_FLG__, 0);
+ act = ethr_atomic32_cmpxchg_acqb(&mtx->mtxb.flgs, ETHR_RWMTX_W_FLG__, 0);
if (act != 0)
ethr_mutex_lock_wait__(mtx, act);
+ ETHR_MTX_CHK_EXCL_SET_EXCL(&mtx->mtxb);
+
ETHR_MTX_HARD_DEBUG_LFS_RWLOCK(&mtx->mtxb);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(mtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(mtx);
ETHR_COMPILER_BARRIER;
}
@@ -395,16 +551,20 @@ ETHR_INLINE_FUNC_NAME_(ethr_mutex_lock)(ethr_mutex *mtx)
static ETHR_INLINE void
ETHR_INLINE_FUNC_NAME_(ethr_mutex_unlock)(ethr_mutex *mtx)
{
- long act;
+ ethr_sint32_t act;
ETHR_COMPILER_BARRIER;
ETHR_MTX_HARD_DEBUG_FENCE_CHK(mtx);
ETHR_MTX_HARD_DEBUG_LFS_RWUNLOCK(&mtx->mtxb);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(mtx);
+
+ ETHR_MTX_CHK_EXCL_UNSET_EXCL(&mtx->mtxb);
- act = ethr_atomic_cmpxchg_relb(&mtx->mtxb.flgs, 0, ETHR_RWMTX_W_FLG__);
+ act = ethr_atomic32_cmpxchg_relb(&mtx->mtxb.flgs, 0, ETHR_RWMTX_W_FLG__);
if (act != ETHR_RWMTX_W_FLG__)
ethr_mutex_unlock_wake__(mtx, act);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(mtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(mtx);
}
#endif /* ETHR_TRY_INLINE_FUNCS */
diff --git a/erts/include/internal/ethr_optimized_fallbacks.h b/erts/include/internal/ethr_optimized_fallbacks.h
index 2f9f987d0b..8e04692856 100644
--- a/erts/include/internal/ethr_optimized_fallbacks.h
+++ b/erts/include/internal/ethr_optimized_fallbacks.h
@@ -71,36 +71,46 @@ ethr_opt_spin_lock(ethr_opt_spinlock_t *lock)
#define ETHR_HAVE_NATIVE_SPINLOCKS 1
#define ETHR_HAVE_OPTIMIZED_SPINLOCKS 1
-typedef ethr_native_atomic_t ethr_native_spinlock_t;
+#if defined(ETHR_HAVE_NATIVE_ATOMIC32)
+typedef ethr_native_atomic32_t ethr_native_spinlock_t;
+# define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
+#elif defined(ETHR_HAVE_NATIVE_ATOMIC64)
+typedef ethr_native_atomic64_t ethr_native_spinlock_t;
+# define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
+#else
+# error "Missing native atomic implementation"
+#endif
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
static ETHR_INLINE void
ethr_native_spinlock_init(ethr_native_spinlock_t *lock)
{
- ethr_native_atomic_init((ethr_native_atomic_t *) lock, 0);
+ ETHR_NATMC_FUNC__(init)(lock, 0);
}
static ETHR_INLINE void
ethr_native_spin_unlock(ethr_native_spinlock_t *lock)
{
ETHR_COMPILER_BARRIER;
- ETHR_ASSERT(ethr_native_atomic_read((ethr_native_atomic_t *) lock) == 1);
- ethr_native_atomic_set_relb((ethr_native_atomic_t *) lock, 0);
+ ETHR_ASSERT(ETHR_NATMC_FUNC__(read)(lock) == 1);
+ ETHR_NATMC_FUNC__(set_relb)(lock, 0);
}
static ETHR_INLINE void
ethr_native_spin_lock(ethr_native_spinlock_t *lock)
{
- while (ethr_native_atomic_cmpxchg_acqb((ethr_native_atomic_t *) lock,
- (long) 1, (long) 0) != 0) {
- ETHR_SPIN_BODY;
+ while (ETHR_NATMC_FUNC__(cmpxchg_acqb)(lock, 1, 0) != 0) {
+ while (ETHR_NATMC_FUNC__(read)(lock) != 0)
+ ETHR_SPIN_BODY;
}
ETHR_COMPILER_BARRIER;
}
#endif
+#undef ETHR_NATMC_FUNC__
+
#endif
@@ -111,16 +121,26 @@ ethr_native_spin_lock(ethr_native_spinlock_t *lock)
#define ETHR_HAVE_NATIVE_RWSPINLOCKS 1
#define ETHR_HAVE_OPTIMIZED_RWSPINLOCKS 1
-typedef ethr_native_atomic_t ethr_native_rwlock_t;
+#if defined(ETHR_HAVE_NATIVE_ATOMIC32)
+typedef ethr_native_atomic32_t ethr_native_rwlock_t;
+# define ETHR_NAINT_T__ ethr_sint32_t
+# define ETHR_WLOCK_FLAG__ (((ethr_sint32_t) 1) << 30)
+# define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
+#elif defined(ETHR_HAVE_NATIVE_ATOMIC64)
+typedef ethr_native_atomic64_t ethr_native_rwlock_t;
+# define ETHR_NAINT_T__ ethr_sint64_t
+# define ETHR_WLOCK_FLAG__ (((ethr_sint64_t) 1) << 62)
+# define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
+#else
+# error "Missing native atomic implementation"
+#endif
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
-#define ETHR_WLOCK_FLAG__ (((long) 1) << 30)
-
static ETHR_INLINE void
ethr_native_rwlock_init(ethr_native_rwlock_t *lock)
{
- ethr_native_atomic_init((ethr_native_atomic_t *) lock, 0);
+ ETHR_NATMC_FUNC__(init)(lock, 0);
}
static ETHR_INLINE void
@@ -128,22 +148,24 @@ ethr_native_read_unlock(ethr_native_rwlock_t *lock)
{
ETHR_COMPILER_BARRIER;
#ifdef DEBUG
- ETHR_ASSERT(ethr_native_atomic_read((ethr_native_atomic_t *) lock) >= 0);
+ ETHR_ASSERT(ETHR_NATMC_FUNC__(read)(lock) >= 0);
#endif
- ethr_native_atomic_dec_relb((ethr_native_atomic_t *) lock);
+ ETHR_NATMC_FUNC__(dec_relb)(lock);
}
static ETHR_INLINE void
ethr_native_read_lock(ethr_native_rwlock_t *lock)
{
- long act, exp = 0;
+ ETHR_NAINT_T__ act, exp = 0;
while (1) {
- act = ethr_native_atomic_cmpxchg_acqb((ethr_native_atomic_t *) lock,
- exp+1, exp);
+ act = ETHR_NATMC_FUNC__(cmpxchg_acqb)(lock, exp+1, exp);
if (act == exp)
break;
- ETHR_SPIN_BODY;
- exp = (act & ETHR_WLOCK_FLAG__) ? 0 : act;
+ while (act & ETHR_WLOCK_FLAG__) {
+ ETHR_SPIN_BODY;
+ act = ETHR_NATMC_FUNC__(read)(lock);
+ }
+ exp = act;
}
ETHR_COMPILER_BARRIER;
}
@@ -152,18 +174,16 @@ static ETHR_INLINE void
ethr_native_write_unlock(ethr_native_rwlock_t *lock)
{
ETHR_COMPILER_BARRIER;
- ETHR_ASSERT(ethr_native_atomic_read((ethr_native_atomic_t *) lock)
- == ETHR_WLOCK_FLAG__);
- ethr_native_atomic_set_relb((ethr_native_atomic_t *) lock, 0);
+ ETHR_ASSERT(ETHR_NATMC_FUNC__(read)(lock) == ETHR_WLOCK_FLAG__);
+ ETHR_NATMC_FUNC__(set_relb)(lock, 0);
}
static ETHR_INLINE void
ethr_native_write_lock(ethr_native_rwlock_t *lock)
{
- long act, exp = 0;
+ ETHR_NAINT_T__ act, exp = 0;
while (1) {
- act = ethr_native_atomic_cmpxchg_acqb((ethr_native_atomic_t *) lock,
- exp|ETHR_WLOCK_FLAG__, exp);
+ act = ETHR_NATMC_FUNC__(cmpxchg_acqb)(lock, exp|ETHR_WLOCK_FLAG__, exp);
if (act == exp)
break;
ETHR_SPIN_BODY;
@@ -173,13 +193,17 @@ ethr_native_write_lock(ethr_native_rwlock_t *lock)
/* Wait for readers to leave */
while (act != ETHR_WLOCK_FLAG__) {
ETHR_SPIN_BODY;
- act = ethr_native_atomic_read_acqb((ethr_native_atomic_t *) lock);
+ act = ETHR_NATMC_FUNC__(read_acqb)(lock);
}
ETHR_COMPILER_BARRIER;
}
#endif
+#undef ETHR_NAINT_T__
+#undef ETHR_NATMC_FUNC__
+#undef ETHR_WLOCK_FLAG__
+
#endif
#endif
diff --git a/erts/include/internal/ethread.h b/erts/include/internal/ethread.h
index 4a205699bd..4cd95faf6a 100644
--- a/erts/include/internal/ethread.h
+++ b/erts/include/internal/ethread.h
@@ -37,11 +37,6 @@
#undef ETHR_HAVE_OPTIMIZED_SPINLOCK
#undef ETHR_HAVE_OPTIMIZED_RWSPINLOCK
-typedef struct {
- long tv_sec;
- long tv_nsec;
-} ethr_timeval;
-
#if defined(DEBUG)
# define ETHR_DEBUG
#endif
@@ -73,7 +68,7 @@ typedef struct {
#endif
/* Assume 64-byte cache line size */
-#define ETHR_CACHE_LINE_SIZE 64L
+#define ETHR_CACHE_LINE_SIZE ((ethr_uint_t) 64)
#define ETHR_CACHE_LINE_MASK (ETHR_CACHE_LINE_SIZE - 1)
#define ETHR_CACHE_LINE_ALIGN_SIZE(SZ) \
@@ -171,6 +166,22 @@ typedef pthread_key_t ethr_tsd_key;
# undef WIN32_LEAN_AND_MEAN
#endif
+#if defined(_MSC_VER)
+
+#if ETHR_SIZEOF_LONG == 4
+#define ETHR_HAVE_INT32_T 1
+typedef long ethr_sint32_t;
+typedef unsigned long ethr_uint32_t;
+#endif
+
+#if ETHR_SIZEOF___INT64 == 8
+#define ETHR_HAVE_INT64_T 1
+typedef __int64 ethr_sint64_t;
+typedef unsigned __int64 ethr_uint64_t;
+#endif
+
+#endif
+
struct ethr_join_data_;
/* Types */
@@ -198,12 +209,48 @@ typedef DWORD ethr_tsd_key;
#endif
-#ifdef SIZEOF_LONG
-#if SIZEOF_LONG < ETHR_SIZEOF_PTR
-#error size of long currently needs to be at least the same as size of void *
+#ifndef ETHR_HAVE_INT32_T
+#if ETHR_SIZEOF_INT == 4
+#define ETHR_HAVE_INT32_T 1
+typedef int ethr_sint32_t;
+typedef unsigned int ethr_uint32_t;
+#elif ETHR_SIZEOF_LONG == 4
+#define ETHR_HAVE_INT32_T 1
+typedef long ethr_sint32_t;
+typedef unsigned long ethr_uint32_t;
#endif
#endif
+#ifndef ETHR_HAVE_INT64_T
+#if ETHR_SIZEOF_INT == 8
+#define ETHR_HAVE_INT64_T 1
+typedef int ethr_sint64_t;
+typedef unsigned int ethr_uint64_t;
+#elif ETHR_SIZEOF_LONG == 8
+#define ETHR_HAVE_INT64_T 1
+typedef long ethr_sint64_t;
+typedef unsigned long ethr_uint64_t;
+#elif ETHR_SIZEOF_LONG_LONG == 8
+#define ETHR_HAVE_INT64_T 1
+typedef long long ethr_sint64_t;
+typedef unsigned long long ethr_uint64_t;
+#endif
+#endif
+
+#if ETHR_SIZEOF_PTR == 4
+#ifndef ETHR_HAVE_INT32_T
+#error "No 32-bit integer type found"
+#endif
+typedef ethr_sint32_t ethr_sint_t;
+typedef ethr_uint32_t ethr_uint_t;
+#elif ETHR_SIZEOF_PTR == 8
+#ifndef ETHR_HAVE_INT64_T
+#error "No 64-bit integer type found"
+#endif
+typedef ethr_sint64_t ethr_sint_t;
+typedef ethr_uint64_t ethr_uint_t;
+#endif
+
/* __builtin_expect() is needed by both native atomics code
* and the fallback code */
#if !defined(__GNUC__) || (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
@@ -239,6 +286,8 @@ typedef DWORD ethr_tsd_key;
# include "gcc/ethread.h"
# include "libatomic_ops/ethread.h"
# endif
+# elif defined(ETHR_HAVE_LIBATOMIC_OPS)
+# include "libatomic_ops/ethread.h"
# elif defined(ETHR_WIN32_THREADS)
# include "win/ethread.h"
# endif
@@ -384,7 +433,6 @@ typedef struct {
#if !defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
# define ETHR_NEED_SPINLOCK_PROTOTYPES__
# define ETHR_NEED_RWSPINLOCK_PROTOTYPES__
-# define ETHR_NEED_ATOMIC_PROTOTYPES__
#endif
int ethr_init(ethr_init_data *);
@@ -397,7 +445,6 @@ void ethr_thr_exit(void *);
ethr_tid ethr_self(void);
int ethr_equal_tids(ethr_tid, ethr_tid);
-int ethr_time_now(ethr_timeval *);
int ethr_tsd_key_create(ethr_tsd_key *);
int ethr_tsd_key_delete(ethr_tsd_key);
int ethr_tsd_set(ethr_tsd_key, void *);
@@ -500,312 +547,7 @@ ETHR_INLINE_FUNC_NAME_(ethr_spin_lock)(ethr_spinlock_t *lock)
#endif /* ETHR_TRY_INLINE_FUNCS */
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
-/*
- * Map ethread native atomics to ethread API atomics.
- */
-typedef ethr_native_atomic_t ethr_atomic_t;
-#else
-typedef long ethr_atomic_t;
-#endif
-
-#ifdef ETHR_NEED_ATOMIC_PROTOTYPES__
-void ethr_atomic_init(ethr_atomic_t *, long);
-void ethr_atomic_set(ethr_atomic_t *, long);
-long ethr_atomic_read(ethr_atomic_t *);
-long ethr_atomic_inc_read(ethr_atomic_t *);
-long ethr_atomic_dec_read(ethr_atomic_t *);
-void ethr_atomic_inc(ethr_atomic_t *);
-void ethr_atomic_dec(ethr_atomic_t *);
-long ethr_atomic_add_read(ethr_atomic_t *, long);
-void ethr_atomic_add(ethr_atomic_t *, long);
-long ethr_atomic_read_band(ethr_atomic_t *, long);
-long ethr_atomic_read_bor(ethr_atomic_t *, long);
-long ethr_atomic_xchg(ethr_atomic_t *, long);
-long ethr_atomic_cmpxchg(ethr_atomic_t *, long, long);
-long ethr_atomic_read_acqb(ethr_atomic_t *);
-long ethr_atomic_inc_read_acqb(ethr_atomic_t *);
-void ethr_atomic_set_relb(ethr_atomic_t *, long);
-void ethr_atomic_dec_relb(ethr_atomic_t *);
-long ethr_atomic_dec_read_relb(ethr_atomic_t *);
-long ethr_atomic_cmpxchg_acqb(ethr_atomic_t *, long, long);
-long ethr_atomic_cmpxchg_relb(ethr_atomic_t *, long, long);
-#endif
-
-#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
-
-#ifndef ETHR_HAVE_NATIVE_ATOMICS
-/*
- * Fallbacks for atomics used in absence of a native implementation.
- */
-
-#define ETHR_ATOMIC_ADDR_BITS 10
-#define ETHR_ATOMIC_ADDR_SHIFT 6
-
-typedef struct {
- union {
- ethr_spinlock_t lck;
- char buf[ETHR_CACHE_LINE_SIZE];
- } u;
-} ethr_atomic_protection_t;
-
-extern ethr_atomic_protection_t ethr_atomic_protection__[1 << ETHR_ATOMIC_ADDR_BITS];
-
-#define ETHR_ATOMIC_PTR2LCK__(PTR) \
-(&ethr_atomic_protection__[((((unsigned long) (PTR)) >> ETHR_ATOMIC_ADDR_SHIFT) \
- & ((1 << ETHR_ATOMIC_ADDR_BITS) - 1))].u.lck)
-
-
-#define ETHR_ATOMIC_OP_FALLBACK_IMPL__(AP, EXPS) \
-do { \
- ethr_spinlock_t *slp__ = ETHR_ATOMIC_PTR2LCK__((AP)); \
- ethr_spin_lock(slp__); \
- { EXPS; } \
- ethr_spin_unlock(slp__); \
-} while (0)
-
-#endif
-
-static ETHR_INLINE void
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_init)(ethr_atomic_t *var, long i)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- ethr_native_atomic_init(var, i);
-#else
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var = i);
-#endif
-}
-
-static ETHR_INLINE void
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_set)(ethr_atomic_t *var, long i)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- ethr_native_atomic_set(var, i);
-#else
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var = i);
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_read)(ethr_atomic_t *var)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_read(var);
-#else
- long res;
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = (long) *var);
- return res;
-#endif
-}
-
-static ETHR_INLINE void
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_add)(ethr_atomic_t *var, long incr)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- ethr_native_atomic_add(var, incr);
-#else
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var += incr);
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_add_read)(ethr_atomic_t *var, long i)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_add_return(var, i);
-#else
- long res;
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, *var += i; res = *var);
- return res;
-#endif
-}
-
-static ETHR_INLINE void
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_inc)(ethr_atomic_t *var)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- ethr_native_atomic_inc(var);
-#else
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, ++(*var));
-#endif
-}
-
-static ETHR_INLINE void
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec)(ethr_atomic_t *var)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- ethr_native_atomic_dec(var);
-#else
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, --(*var));
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_inc_read)(ethr_atomic_t *var)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_inc_return(var);
-#else
- long res;
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = (long) ++(*var));
- return res;
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec_read)(ethr_atomic_t *var)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_dec_return(var);
-#else
- long res;
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = (long) --(*var));
- return res;
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_read_band)(ethr_atomic_t *var,
- long mask)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_and_retold(var, mask);
-#else
- long res;
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var; *var &= mask);
- return res;
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_read_bor)(ethr_atomic_t *var,
- long mask)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_or_retold(var, mask);
-#else
- long res;
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var; *var |= mask);
- return res;
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_xchg)(ethr_atomic_t *var,
- long new)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_xchg(var, new);
-#else
- long res;
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var, res = *var; *var = new);
- return res;
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_cmpxchg)(ethr_atomic_t *var,
- long new,
- long exp)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_cmpxchg(var, new, exp);
-#else
- long res;
- ETHR_ATOMIC_OP_FALLBACK_IMPL__(var,
- {
- res = *var;
- if (__builtin_expect(res == exp, 1))
- *var = new;
- });
- return res;
-#endif
-}
-
-/*
- * Important memory barrier requirements.
- *
- * The following atomic operations *must* supply a memory barrier of
- * at least the type specified by its suffix:
- * _acqb = acquire barrier
- * _relb = release barrier
- */
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_read_acqb)(ethr_atomic_t *var)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_read_acqb(var);
-#else
- return ETHR_INLINE_FUNC_NAME_(ethr_atomic_read)(var);
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_inc_read_acqb)(ethr_atomic_t *var)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_inc_return_acqb(var);
-#else
- return ETHR_INLINE_FUNC_NAME_(ethr_atomic_inc_read)(var);
-#endif
-}
-
-static ETHR_INLINE void
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_set_relb)(ethr_atomic_t *var, long val)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- ethr_native_atomic_set_relb(var, val);
-#else
- return ETHR_INLINE_FUNC_NAME_(ethr_atomic_set)(var, val);
-#endif
-}
-
-static ETHR_INLINE void
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec_relb)(ethr_atomic_t *var)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- ethr_native_atomic_dec_relb(var);
-#else
- ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec)(var);
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec_read_relb)(ethr_atomic_t *var)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_dec_return_relb(var);
-#else
- return ETHR_INLINE_FUNC_NAME_(ethr_atomic_dec_read)(var);
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_cmpxchg_acqb)(ethr_atomic_t *var,
- long new,
- long exp)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_cmpxchg_acqb(var, new, exp);
-#else
- return ETHR_INLINE_FUNC_NAME_(ethr_atomic_cmpxchg)(var, new, exp);
-#endif
-}
-
-static ETHR_INLINE long
-ETHR_INLINE_FUNC_NAME_(ethr_atomic_cmpxchg_relb)(ethr_atomic_t *var,
- long new,
- long exp)
-{
-#ifdef ETHR_HAVE_NATIVE_ATOMICS
- return ethr_native_atomic_cmpxchg_relb(var, new, exp);
-#else
- return ETHR_INLINE_FUNC_NAME_(ethr_atomic_cmpxchg)(var, new, exp);
-#endif
-}
-
-#endif /* ETHR_TRY_INLINE_FUNCS */
+#include "ethr_atomics.h"
typedef struct ethr_ts_event_ ethr_ts_event; /* Needed by ethr_mutex.h */
@@ -823,7 +565,7 @@ struct ethr_ts_event_ {
ethr_ts_event *prev;
ethr_event event;
void *udata;
- ethr_atomic_t uaflgs;
+ ethr_atomic32_t uaflgs;
unsigned uflgs;
unsigned iflgs; /* for ethr lib only */
short rgix; /* for ethr lib only */
diff --git a/erts/include/internal/ethread_header_config.h.in b/erts/include/internal/ethread_header_config.h.in
index 5debb44756..f394d790d2 100644
--- a/erts/include/internal/ethread_header_config.h.in
+++ b/erts/include/internal/ethread_header_config.h.in
@@ -20,6 +20,21 @@
/* Define to the size of pointers */
#undef ETHR_SIZEOF_PTR
+/* Define to the size of int */
+#undef ETHR_SIZEOF_INT
+
+/* Define to the size of long */
+#undef ETHR_SIZEOF_LONG
+
+/* Define to the size of long long */
+#undef ETHR_SIZEOF_LONG_LONG
+
+/* Define to the size of __int64 */
+#undef ETHR_SIZEOF___INT64
+
+/* Define if bigendian */
+#undef ETHR_BIGENDIAN
+
/* Define if you want to disable native ethread implementations */
#undef ETHR_DISABLE_NATIVE_IMPLS
@@ -100,6 +115,27 @@
/* Define to the size of AO_t if libatomic_ops is used */
#undef ETHR_SIZEOF_AO_T
+/* Define if you have _InterlockedCompareExchange64() */
+#undef ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64
+
+/* Define if you have _InterlockedDecrement64() */
+#undef ETHR_HAVE__INTERLOCKEDDECREMENT64
+
+/* Define if you have _InterlockedIncrement64() */
+#undef ETHR_HAVE__INTERLOCKEDINCREMENT64
+
+/* Define if you have _InterlockedExchangeAdd64() */
+#undef ETHR_HAVE__INTERLOCKEDEXCHANGEADD64
+
+/* Define if you have _InterlockedExchange64() */
+#undef ETHR_HAVE__INTERLOCKEDEXCHANGE64
+
+/* Define if you have _InterlockedAnd64() */
+#undef ETHR_HAVE__INTERLOCKEDAND64
+
+/* Define if you have _InterlockedOr64() */
+#undef ETHR_HAVE__INTERLOCKEDOR64
+
/* 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
index e8e529dd48..16935084b1 100644
--- a/erts/include/internal/gcc/ethr_atomic.h
+++ b/erts/include/internal/gcc/ethr_atomic.h
@@ -22,24 +22,35 @@
* Author: Rickard Green
*/
-#ifndef ETHR_GCC_ATOMIC_H__
-#define ETHR_GCC_ATOMIC_H__
+#undef ETHR_INCLUDE_ATOMIC_IMPL__
+#if !defined(ETHR_GCC_ATOMIC32_H__) && defined(ETHR_ATOMIC_WANT_32BIT_IMPL__)
+#define ETHR_GCC_ATOMIC32_H__
+#define ETHR_INCLUDE_ATOMIC_IMPL__ 4
+#undef ETHR_ATOMIC_WANT_32BIT_IMPL__
+#elif !defined(ETHR_GCC_ATOMIC64_H__) && defined(ETHR_ATOMIC_WANT_64BIT_IMPL__)
+#define ETHR_GCC_ATOMIC64_H__
+#define ETHR_INCLUDE_ATOMIC_IMPL__ 8
+#undef ETHR_ATOMIC_WANT_64BIT_IMPL__
+#endif
+
+#ifdef ETHR_INCLUDE_ATOMIC_IMPL__
-#if !defined(ETHR_HAVE_NATIVE_ATOMICS) && defined(ETHR_HAVE_GCC_ATOMIC_OPS)
-#define ETHR_HAVE_NATIVE_ATOMICS 1
+#ifndef ETHR_GCC_ATOMIC_COMMON__
+#define ETHR_GCC_ATOMIC_COMMON__
-#define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 0
-/* Enable immediate read/write on platforms where we know it is safe */
+#define ETHR_READ_AND_SET_WITHOUT_SYNC_OP__ 0
#if defined(__i386__) || defined(__x86_64__) || defined(__sparc__) \
|| defined(__powerpc__) || defined(__ppc__) || defined(__mips__)
-# undef ETHR_IMMED_ATOMIC_SET_GET_SAFE__
-# define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 1
+# undef ETHR_READ_AND_SET_WITHOUT_SYNC_OP__
+# define ETHR_READ_AND_SET_WITHOUT_SYNC_OP__ 1
#endif
-typedef struct {
- volatile long counter;
-} ethr_native_atomic_t;
-
+#if defined(__x86_64__) || (defined(__i386__) \
+ && !defined(ETHR_PRE_PENTIUM4_COMPAT))
+# define ETHR_READ_ACQB_AND_SET_RELB_COMPILER_BARRIER_ONLY__ 1
+#else
+# define ETHR_READ_ACQB_AND_SET_RELB_COMPILER_BARRIER_ONLY__ 0
+#endif
/*
* According to the documentation this is what we want:
@@ -47,34 +58,73 @@ typedef struct {
* 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 except
- * for gcc 4.2 or above for MIPS, where it's been verified.
+ * don't know from which version. Therefore, we only use
+ * it when it has been verified to work. Otherwise
+ * we use a workaround.
*/
#if defined(__mips__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
+/* __sync_synchronize() has been verified to work here */
#define ETHR_MEMORY_BARRIER __sync_synchronize()
+#define ETHR_READ_DEPEND_MEMORY_BARRIER __sync_synchronize()
+#elif defined(__x86_64__) || (defined(__i386__) \
+ && !defined(ETHR_PRE_PENTIUM4_COMPAT))
+/* Use fence instructions directly instead of workaround */
+#define ETHR_MEMORY_BARRIER __asm__ __volatile__("mfence" : : : "memory")
+#define ETHR_WRITE_MEMORY_BARRIER __asm__ __volatile__("sfence" : : : "memory")
+#define ETHR_READ_MEMORY_BARRIER __asm__ __volatile__("lfence" : : : "memory")
+#define ETHR_READ_DEPEND_MEMORY_BARRIER __asm__ __volatile__("" : : : "memory")
#else
+/* Workaround */
#define ETHR_MEMORY_BARRIER \
do { \
- volatile long x___ = 0; \
- (void) __sync_val_compare_and_swap(&x___, (long) 0, (long) 1); \
+ volatile ethr_sint32_t x___ = 0; \
+ (void) __sync_val_compare_and_swap(&x___, (ethr_sint32_t) 0, (ethr_sint32_t) 1); \
} while (0)
-#endif
#define ETHR_READ_DEPEND_MEMORY_BARRIER ETHR_MEMORY_BARRIER
+#endif
+
+#define ETHR_COMPILER_BARRIER __asm__ __volatile__("" : : : "memory")
-#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
+#endif /* ETHR_GCC_ATOMIC_COMMON__ */
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+#define ETHR_HAVE_NATIVE_ATOMIC32 1
+#define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
+#define ETHR_ATMC_T__ ethr_native_atomic32_t
+#define ETHR_AINT_T__ ethr_sint32_t
+#elif ETHR_INCLUDE_ATOMIC_IMPL__ == 8
+#define ETHR_HAVE_NATIVE_ATOMIC64 1
+#define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
+#define ETHR_ATMC_T__ ethr_native_atomic64_t
+#define ETHR_AINT_T__ ethr_sint64_t
+#else
+#error "Unsupported integer size"
+#endif
+
+typedef struct {
+ volatile ETHR_AINT_T__ counter;
+} ETHR_ATMC_T__;
+
+
+#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
+
+static ETHR_INLINE ETHR_AINT_T__ *
+ETHR_NATMC_FUNC__(addr)(ETHR_ATMC_T__ *var)
+{
+ return (ETHR_AINT_T__ *) &var->counter;
+}
static ETHR_INLINE void
-ethr_native_atomic_set(ethr_native_atomic_t *var, long value)
+ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
{
-#if ETHR_IMMED_ATOMIC_SET_GET_SAFE__
+#if ETHR_READ_AND_SET_WITHOUT_SYNC_OP__
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;
+ ETHR_AINT_T__ act = 0, exp;
do {
exp = act;
act = __sync_val_compare_and_swap(&var->counter, exp, value);
@@ -82,80 +132,86 @@ ethr_native_atomic_set(ethr_native_atomic_t *var, long value)
#endif
}
-#define ethr_native_atomic_init ethr_native_atomic_set
+static ETHR_INLINE void
+ETHR_NATMC_FUNC__(init)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
+{
+ ETHR_NATMC_FUNC__(set)(var, value);
+}
-static ETHR_INLINE long
-ethr_native_atomic_read(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
{
-#if ETHR_IMMED_ATOMIC_SET_GET_SAFE__
+#if ETHR_READ_AND_SET_WITHOUT_SYNC_OP__
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);
+ return __sync_add_and_fetch(&var->counter, (ETHR_AINT_T__) 0);
#endif
}
static ETHR_INLINE void
-ethr_native_atomic_add(ethr_native_atomic_t *var, long incr)
+ETHR_NATMC_FUNC__(add)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ 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)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(add_return)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
{
return __sync_add_and_fetch(&var->counter, incr);
}
static ETHR_INLINE void
-ethr_native_atomic_inc(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(inc)(ETHR_ATMC_T__ *var)
{
- (void) __sync_add_and_fetch(&var->counter, (long) 1);
+ (void) __sync_add_and_fetch(&var->counter, (ETHR_AINT_T__) 1);
}
static ETHR_INLINE void
-ethr_native_atomic_dec(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(dec)(ETHR_ATMC_T__ *var)
{
- (void) __sync_sub_and_fetch(&var->counter, (long) 1);
+ (void) __sync_sub_and_fetch(&var->counter, (ETHR_AINT_T__) 1);
}
-static ETHR_INLINE long
-ethr_native_atomic_inc_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(inc_return)(ETHR_ATMC_T__ *var)
{
- return __sync_add_and_fetch(&var->counter, (long) 1);
+ return __sync_add_and_fetch(&var->counter, (ETHR_AINT_T__) 1);
}
-static ETHR_INLINE long
-ethr_native_atomic_dec_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(dec_return)(ETHR_ATMC_T__ *var)
{
- return __sync_sub_and_fetch(&var->counter, (long) 1);
+ return __sync_sub_and_fetch(&var->counter, (ETHR_AINT_T__) 1);
}
-static ETHR_INLINE long
-ethr_native_atomic_and_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(and_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ 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)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(or_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
- return (long) __sync_fetch_and_or(&var->counter, mask);
+ return (ETHR_AINT_T__) __sync_fetch_and_or(&var->counter, mask);
}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, long new, long old)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ 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)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(xchg)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ new)
{
- long exp, act = 0;
+ ETHR_AINT_T__ exp, act = 0;
do {
exp = act;
act = __sync_val_compare_and_swap(&var->counter, exp, new);
@@ -167,22 +223,68 @@ ethr_native_atomic_xchg(ethr_native_atomic_t *var, long new)
* Atomic ops with at least specified barriers.
*/
-static ETHR_INLINE long
-ethr_native_atomic_read_acqb(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read_acqb)(ETHR_ATMC_T__ *var)
{
- return __sync_add_and_fetch(&var->counter, (long) 0);
+#if ETHR_READ_ACQB_AND_SET_RELB_COMPILER_BARRIER_ONLY__
+ ETHR_AINT_T__ val = var->counter;
+ ETHR_COMPILER_BARRIER;
+ return val;
+#else
+ return __sync_add_and_fetch(&var->counter, (ETHR_AINT_T__) 0);
+#endif
}
-#define ethr_native_atomic_inc_return_acqb ethr_native_atomic_inc_return
-#define ethr_native_atomic_set_relb ethr_native_atomic_xchg
-#define ethr_native_atomic_dec_relb ethr_native_atomic_dec_return
-#define ethr_native_atomic_dec_return_relb ethr_native_atomic_dec_return
+static ETHR_INLINE void
+ETHR_NATMC_FUNC__(set_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
+{
+#if ETHR_READ_ACQB_AND_SET_RELB_COMPILER_BARRIER_ONLY__
+ ETHR_COMPILER_BARRIER;
+ var->counter = i;
+#else
+ (void) ETHR_NATMC_FUNC__(xchg)(var, i);
+#endif
+}
-#define ethr_native_atomic_cmpxchg_acqb ethr_native_atomic_cmpxchg
-#define ethr_native_atomic_cmpxchg_relb ethr_native_atomic_cmpxchg
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(inc_return_acqb)(ETHR_ATMC_T__ *var)
+{
+ return ETHR_NATMC_FUNC__(inc_return)(var);
+}
-#endif
+static ETHR_INLINE void
+ETHR_NATMC_FUNC__(dec_relb)(ETHR_ATMC_T__ *var)
+{
+ ETHR_NATMC_FUNC__(dec)(var);
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(dec_return_relb)(ETHR_ATMC_T__ *var)
+{
+ return ETHR_NATMC_FUNC__(dec_return)(var);
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_acqb)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ old)
+{
+ return ETHR_NATMC_FUNC__(cmpxchg)(var, new, old);
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_relb)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ old)
+{
+ return ETHR_NATMC_FUNC__(cmpxchg)(var, new, old);
+}
#endif
+#undef ETHR_NATMC_FUNC__
+#undef ETHR_ATMC_T__
+#undef ETHR_AINT_T__
+#undef ETHR_AINT_SUFFIX__
+
#endif
diff --git a/erts/include/internal/gcc/ethread.h b/erts/include/internal/gcc/ethread.h
index bb378e31e0..392a1aa2b2 100644
--- a/erts/include/internal/gcc/ethread.h
+++ b/erts/include/internal/gcc/ethread.h
@@ -25,6 +25,16 @@
#ifndef ETHREAD_GCC_H__
#define ETHREAD_GCC_H__
+#if !defined(ETHR_HAVE_NATIVE_ATOMICS) && defined(ETHR_HAVE_GCC_ATOMIC_OPS)
+#define ETHR_HAVE_NATIVE_ATOMICS 1
+
+#define ETHR_ATOMIC_WANT_32BIT_IMPL__
#include "ethr_atomic.h"
+#if ETHR_SIZEOF_PTR == 8
+# define ETHR_ATOMIC_WANT_64BIT_IMPL__
+# include "ethr_atomic.h"
+#endif
+
+#endif
#endif
diff --git a/erts/include/internal/i386/atomic.h b/erts/include/internal/i386/atomic.h
index f28258059f..4e402f261a 100644
--- a/erts/include/internal/i386/atomic.h
+++ b/erts/include/internal/i386/atomic.h
@@ -23,14 +23,24 @@
*
* This code requires a 486 or newer processor.
*/
-#ifndef ETHREAD_I386_ATOMIC_H
-#define ETHREAD_I386_ATOMIC_H
-/* An atomic is an aligned long accessed via locked operations.
- */
-typedef struct {
- volatile long counter;
-} ethr_native_atomic_t;
+#undef ETHR_INCLUDE_ATOMIC_IMPL__
+#if !defined(ETHR_X86_ATOMIC32_H__) && defined(ETHR_ATOMIC_WANT_32BIT_IMPL__)
+#define ETHR_X86_ATOMIC32_H__
+#define ETHR_INCLUDE_ATOMIC_IMPL__ 4
+#undef ETHR_ATOMIC_WANT_32BIT_IMPL__
+#elif !defined(ETHR_X86_ATOMIC64_H__) && defined(ETHR_ATOMIC_WANT_64BIT_IMPL__)
+#define ETHR_X86_ATOMIC64_H__
+#define ETHR_INCLUDE_ATOMIC_IMPL__ 8
+#undef ETHR_ATOMIC_WANT_64BIT_IMPL__
+#endif
+
+#ifdef ETHR_INCLUDE_ATOMIC_IMPL__
+
+#ifndef ETHR_X86_ATOMIC_COMMON__
+#define ETHR_X86_ATOMIC_COMMON__
+
+#define ETHR_ATOMIC_HAVE_INC_DEC_INSTRUCTIONS 1
#if defined(__x86_64__) || !defined(ETHR_PRE_PENTIUM4_COMPAT)
#define ETHR_MEMORY_BARRIER __asm__ __volatile__("mfence" : : : "memory")
@@ -40,123 +50,161 @@ typedef struct {
#else
#define ETHR_MEMORY_BARRIER \
do { \
- volatile long x___ = 0; \
+ volatile ethr_sint32_t x___ = 0; \
__asm__ __volatile__("lock; incl %0" : "=m"(x___) : "m"(x___) : "memory"); \
} while (0)
#endif
-#define ETHR_ATOMIC_HAVE_INC_DEC_INSTRUCTIONS 1
-
-#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
+#endif /* ETHR_X86_ATOMIC_COMMON__ */
-#ifdef __x86_64__
-#define LONG_SUFFIX "q"
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+#define ETHR_HAVE_NATIVE_ATOMIC32 1
+#define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
+#define ETHR_ATMC_T__ ethr_native_atomic32_t
+#define ETHR_AINT_T__ ethr_sint32_t
+#define ETHR_AINT_SUFFIX__ "l"
+#elif ETHR_INCLUDE_ATOMIC_IMPL__ == 8
+#define ETHR_HAVE_NATIVE_ATOMIC64 1
+#define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
+#define ETHR_ATMC_T__ ethr_native_atomic64_t
+#define ETHR_AINT_T__ ethr_sint64_t
+#define ETHR_AINT_SUFFIX__ "q"
#else
-#define LONG_SUFFIX "l"
+#error "Unsupported integer size"
#endif
+/* An atomic is an aligned ETHR_AINT_T__ accessed via locked operations.
+ */
+typedef struct {
+ volatile ETHR_AINT_T__ counter;
+} ETHR_ATMC_T__;
+
+#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
+
+static ETHR_INLINE ETHR_AINT_T__ *
+ETHR_NATMC_FUNC__(addr)(ETHR_ATMC_T__ *var)
+{
+ return (ETHR_AINT_T__ *) &var->counter;
+}
+
static ETHR_INLINE void
-ethr_native_atomic_init(ethr_native_atomic_t *var, long i)
+ETHR_NATMC_FUNC__(init)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
{
var->counter = i;
}
-#define ethr_native_atomic_set(v, i) ethr_native_atomic_init((v), (i))
-static ETHR_INLINE long
-ethr_native_atomic_read(ethr_native_atomic_t *var)
+static ETHR_INLINE void
+ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
+{
+ var->counter = i;
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
{
return var->counter;
}
static ETHR_INLINE void
-ethr_native_atomic_add(ethr_native_atomic_t *var, long incr)
+ETHR_NATMC_FUNC__(add)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
{
__asm__ __volatile__(
- "lock; add" LONG_SUFFIX " %1, %0"
+ "lock; add" ETHR_AINT_SUFFIX__ " %1, %0"
: "=m"(var->counter)
: "ir"(incr), "m"(var->counter));
}
static ETHR_INLINE void
-ethr_native_atomic_inc(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(inc)(ETHR_ATMC_T__ *var)
{
__asm__ __volatile__(
- "lock; inc" LONG_SUFFIX " %0"
+ "lock; inc" ETHR_AINT_SUFFIX__ " %0"
: "=m"(var->counter)
: "m"(var->counter));
}
static ETHR_INLINE void
-ethr_native_atomic_dec(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(dec)(ETHR_ATMC_T__ *var)
{
__asm__ __volatile__(
- "lock; dec" LONG_SUFFIX " %0"
+ "lock; dec" ETHR_AINT_SUFFIX__ " %0"
: "=m"(var->counter)
: "m"(var->counter));
}
-static ETHR_INLINE long
-ethr_native_atomic_add_return(ethr_native_atomic_t *var, long incr)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(add_return)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
{
- long tmp;
+ ETHR_AINT_T__ tmp;
tmp = incr;
__asm__ __volatile__(
- "lock; xadd" LONG_SUFFIX " %0, %1" /* xadd didn't exist prior to the 486 */
+ "lock; xadd" ETHR_AINT_SUFFIX__ " %0, %1" /* xadd didn't exist prior to the 486 */
: "=r"(tmp)
: "m"(var->counter), "0"(tmp));
/* now tmp is the atomic's previous value */
return tmp + incr;
}
-#define ethr_native_atomic_inc_return(var) ethr_native_atomic_add_return((var), 1)
-#define ethr_native_atomic_dec_return(var) ethr_native_atomic_add_return((var), -1)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(inc_return)(ETHR_ATMC_T__ *var)
+{
+ return ETHR_NATMC_FUNC__(add_return)(var, (ETHR_AINT_T__) 1);
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(dec_return)(ETHR_ATMC_T__ *var)
+{
+ return ETHR_NATMC_FUNC__(add_return)(var, (ETHR_AINT_T__) -1);
+}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, long new, long old)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ old)
{
__asm__ __volatile__(
- "lock; cmpxchg" LONG_SUFFIX " %2, %3"
+ "lock; cmpxchg" ETHR_AINT_SUFFIX__ " %2, %3"
: "=a"(old), "=m"(var->counter)
: "r"(new), "m"(var->counter), "0"(old)
: "cc", "memory"); /* full memory clobber to make this a compiler barrier */
return old;
}
-static ETHR_INLINE long
-ethr_native_atomic_and_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(and_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
- long tmp, old;
+ ETHR_AINT_T__ tmp, old;
tmp = var->counter;
do {
old = tmp;
- tmp = ethr_native_atomic_cmpxchg(var, tmp & mask, tmp);
+ tmp = ETHR_NATMC_FUNC__(cmpxchg)(var, tmp & mask, tmp);
} while (__builtin_expect(tmp != old, 0));
/* now tmp is the atomic's previous value */
return tmp;
}
-static ETHR_INLINE long
-ethr_native_atomic_or_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(or_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
- long tmp, old;
+ ETHR_AINT_T__ tmp, old;
tmp = var->counter;
do {
old = tmp;
- tmp = ethr_native_atomic_cmpxchg(var, tmp | mask, tmp);
+ tmp = ETHR_NATMC_FUNC__(cmpxchg)(var, tmp | mask, tmp);
} while (__builtin_expect(tmp != old, 0));
/* now tmp is the atomic's previous value */
return tmp;
}
-static ETHR_INLINE long
-ethr_native_atomic_xchg(ethr_native_atomic_t *var, long val)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(xchg)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ val)
{
- long tmp = val;
+ ETHR_AINT_T__ tmp = val;
__asm__ __volatile__(
- "xchg" LONG_SUFFIX " %0, %1"
+ "xchg" ETHR_AINT_SUFFIX__ " %0, %1"
: "=r"(tmp)
: "m"(var->counter), "0"(tmp));
/* now tmp is the atomic's previous value */
@@ -167,20 +215,73 @@ ethr_native_atomic_xchg(ethr_native_atomic_t *var, long val)
* Atomic ops with at least specified barriers.
*/
-#define ethr_native_atomic_read_acqb ethr_native_atomic_read
-#define ethr_native_atomic_inc_return_acqb ethr_native_atomic_inc_return
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read_acqb)(ETHR_ATMC_T__ *var)
+{
+ ETHR_AINT_T__ val;
#if defined(__x86_64__) || !defined(ETHR_PRE_PENTIUM4_COMPAT)
-#define ethr_native_atomic_set_relb ethr_native_atomic_set
+ val = var->counter;
#else
-#define ethr_native_atomic_set_relb ethr_native_atomic_xchg
+ val = ETHR_NATMC_FUNC__(add_return)(var, 0);
#endif
-#define ethr_native_atomic_dec_relb ethr_native_atomic_dec
-#define ethr_native_atomic_dec_return_relb ethr_native_atomic_dec_return
-#define ethr_native_atomic_cmpxchg_acqb ethr_native_atomic_cmpxchg
-#define ethr_native_atomic_cmpxchg_relb ethr_native_atomic_cmpxchg
+ __asm__ __volatile__("" : : : "memory");
+ return val;
+}
+
+static ETHR_INLINE void
+ETHR_NATMC_FUNC__(set_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
+{
+ __asm__ __volatile__("" : : : "memory");
+#if defined(__x86_64__) || !defined(ETHR_PRE_PENTIUM4_COMPAT)
+ var->counter = i;
+#else
+ (void) ETHR_NATMC_FUNC__(xchg)(var, i);
+#endif
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(inc_return_acqb)(ETHR_ATMC_T__ *var)
+{
+ ETHR_AINT_T__ res = ETHR_NATMC_FUNC__(inc_return)(var);
+ __asm__ __volatile__("" : : : "memory");
+ return res;
+}
-#undef LONG_SUFFIX
+static ETHR_INLINE void
+ETHR_NATMC_FUNC__(dec_relb)(ETHR_ATMC_T__ *var)
+{
+ __asm__ __volatile__("" : : : "memory");
+ ETHR_NATMC_FUNC__(dec)(var);
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(dec_return_relb)(ETHR_ATMC_T__ *var)
+{
+ __asm__ __volatile__("" : : : "memory");
+ return ETHR_NATMC_FUNC__(dec_return)(var);
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_acqb)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ old)
+{
+ return ETHR_NATMC_FUNC__(cmpxchg)(var, new, old);
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_relb)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ old)
+{
+ return ETHR_NATMC_FUNC__(cmpxchg)(var, new, old);
+}
#endif /* ETHR_TRY_INLINE_FUNCS */
-#endif /* ETHREAD_I386_ATOMIC_H */
+#undef ETHR_NATMC_FUNC__
+#undef ETHR_ATMC_T__
+#undef ETHR_AINT_T__
+#undef ETHR_AINT_SUFFIX__
+
+#endif /* ETHR_INCLUDE_ATOMIC_IMPL__ */
diff --git a/erts/include/internal/i386/ethread.h b/erts/include/internal/i386/ethread.h
index ed43e77279..b5a17caefb 100644
--- a/erts/include/internal/i386/ethread.h
+++ b/erts/include/internal/i386/ethread.h
@@ -1,7 +1,7 @@
/*
* %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
@@ -24,7 +24,12 @@
#ifndef ETHREAD_I386_ETHREAD_H
#define ETHREAD_I386_ETHREAD_H
+#define ETHR_ATOMIC_WANT_32BIT_IMPL__
#include "atomic.h"
+#if ETHR_SIZEOF_PTR == 8
+# define ETHR_ATOMIC_WANT_64BIT_IMPL__
+# include "atomic.h"
+#endif
#include "spinlock.h"
#include "rwlock.h"
diff --git a/erts/include/internal/libatomic_ops/ethr_atomic.h b/erts/include/internal/libatomic_ops/ethr_atomic.h
index a6eb43a0bd..d56693dbf8 100644
--- a/erts/include/internal/libatomic_ops/ethr_atomic.h
+++ b/erts/include/internal/libatomic_ops/ethr_atomic.h
@@ -46,17 +46,39 @@
* - AO_store()
* - AO_compare_and_swap()
*
- * The `AO_t' type also have to be at least as large as
- * `void *' and `long' types.
+ * The `AO_t' type also have to be at least as large as the `void *' type.
*/
#if ETHR_SIZEOF_AO_T < ETHR_SIZEOF_PTR
#error The AO_t type is too small
#endif
+#if ETHR_SIZEOF_AO_T == 4
+#define ETHR_HAVE_NATIVE_ATOMIC32 1
+#define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
+#define ETHR_ATMC_T__ ethr_native_atomic32_t
+#define ETHR_AINT_T__ ethr_sint32_t
+#define ETHR_AINT_SUFFIX__ "l"
+#elif ETHR_SIZEOF_AO_T == 8
+#define ETHR_HAVE_NATIVE_ATOMIC64 1
+#define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
+#define ETHR_ATMC_T__ ethr_native_atomic64_t
+#define ETHR_AINT_T__ ethr_sint64_t
+#define ETHR_AINT_SUFFIX__ "q"
+#else
+#error "Unsupported integer size"
+#endif
+
+#if ETHR_SIZEOF_AO_T == 8
+typedef union {
+ volatile AO_t counter;
+ ethr_sint32_t sint32[2];
+} ETHR_ATMC_T__;
+#else
typedef struct {
volatile AO_t counter;
-} ethr_native_atomic_t;
+} ETHR_ATMC_T__;
+#endif
#define ETHR_MEMORY_BARRIER AO_nop_full()
#ifdef AO_HAVE_nop_write
@@ -72,123 +94,151 @@ typedef struct {
#ifdef AO_NO_DD_ORDERING
# define ETHR_READ_DEPEND_MEMORY_BARRIER ETHR_READ_MEMORY_BARRIER
#else
-# define ETHR_READ_DEPEND_MEMORY_BARRIER __asm__ __volatile__("":::"memory")
+# define ETHR_READ_DEPEND_MEMORY_BARRIER AO_compiler_barrier()
+#endif
+
+#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
+
+static ETHR_INLINE ETHR_AINT_T__ *
+ETHR_NATMC_FUNC__(addr)(ETHR_ATMC_T__ *var)
+{
+ return (ETHR_AINT_T__ *) &var->counter;
+}
+
+#if ETHR_SIZEOF_AO_T == 8
+/*
+ * We also need to provide an ethr_native_atomic32_addr(), since
+ * this 64-bit implementation will be used implementing 32-bit
+ * native atomics.
+ */
+
+static ETHR_INLINE ethr_sint32_t *
+ethr_native_atomic32_addr(ETHR_ATMC_T__ *var)
+{
+ ETHR_ASSERT(((void *) &var->sint32[0]) == ((void *) &var->counter));
+#ifdef ETHR_BIGENDIAN
+ return &var->sint32[1];
+#else
+ return &var->sint32[0];
#endif
+}
-#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
+#endif /* ETHR_SIZEOF_AO_T == 8 */
static ETHR_INLINE void
-ethr_native_atomic_set(ethr_native_atomic_t *var, long value)
+ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
{
AO_store(&var->counter, (AO_t) value);
}
static ETHR_INLINE void
-ethr_native_atomic_init(ethr_native_atomic_t *var, long value)
+ETHR_NATMC_FUNC__(init)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
{
- ethr_native_atomic_set(var, value);
+ ETHR_NATMC_FUNC__(set)(var, value);
}
-static ETHR_INLINE long
-ethr_native_atomic_read(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
{
- return (long) AO_load(&var->counter);
+ return (ETHR_AINT_T__) AO_load(&var->counter);
}
-static ETHR_INLINE long
-ethr_native_atomic_add_return(ethr_native_atomic_t *var, long incr)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(add_return)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
{
#ifdef AO_HAVE_fetch_and_add
- return ((long) AO_fetch_and_add(&var->counter, (AO_t) incr)) + incr;
+ return ((ETHR_AINT_T__) AO_fetch_and_add(&var->counter, (AO_t) incr)) + incr;
#else
while (1) {
AO_t exp = AO_load(&var->counter);
AO_t new = exp + (AO_t) incr;
if (AO_compare_and_swap(&var->counter, exp, new))
- return (long) new;
+ return (ETHR_AINT_T__) new;
}
#endif
}
static ETHR_INLINE void
-ethr_native_atomic_add(ethr_native_atomic_t *var, long incr)
+ETHR_NATMC_FUNC__(add)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
{
- (void) ethr_native_atomic_add_return(var, incr);
+ (void) ETHR_NATMC_FUNC__(add_return)(var, incr);
}
-static ETHR_INLINE long
-ethr_native_atomic_inc_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(inc_return)(ETHR_ATMC_T__ *var)
{
#ifdef AO_HAVE_fetch_and_add1
- return ((long) AO_fetch_and_add1(&var->counter)) + 1;
+ return ((ETHR_AINT_T__) AO_fetch_and_add1(&var->counter)) + 1;
#else
- return ethr_native_atomic_add_return(var, 1);
+ return ETHR_NATMC_FUNC__(add_return)(var, 1);
#endif
}
static ETHR_INLINE void
-ethr_native_atomic_inc(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(inc)(ETHR_ATMC_T__ *var)
{
- (void) ethr_native_atomic_inc_return(var);
+ (void) ETHR_NATMC_FUNC__(inc_return)(var);
}
-static ETHR_INLINE long
-ethr_native_atomic_dec_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(dec_return)(ETHR_ATMC_T__ *var)
{
#ifdef AO_HAVE_fetch_and_sub1
- return ((long) AO_fetch_and_sub1(&var->counter)) - 1;
+ return ((ETHR_AINT_T__) AO_fetch_and_sub1(&var->counter)) - 1;
#else
- return ethr_native_atomic_add_return(var, -1);
+ return ETHR_NATMC_FUNC__(add_return)(var, -1);
#endif
}
static ETHR_INLINE void
-ethr_native_atomic_dec(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(dec)(ETHR_ATMC_T__ *var)
{
- (void) ethr_native_atomic_dec_return(var);
+ (void) ETHR_NATMC_FUNC__(dec_return)(var);
}
-static ETHR_INLINE long
-ethr_native_atomic_and_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(and_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
while (1) {
AO_t exp = AO_load(&var->counter);
AO_t new = exp & ((AO_t) mask);
if (AO_compare_and_swap(&var->counter, exp, new))
- return (long) exp;
+ return (ETHR_AINT_T__) exp;
}
}
-static ETHR_INLINE long
-ethr_native_atomic_or_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(or_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
while (1) {
AO_t exp = AO_load(&var->counter);
AO_t new = exp | ((AO_t) mask);
if (AO_compare_and_swap(&var->counter, exp, new))
- return (long) exp;
+ return (ETHR_AINT_T__) exp;
}
}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, long new, long exp)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ exp)
{
- long act;
+ ETHR_AINT_T__ act;
do {
if (AO_compare_and_swap(&var->counter, (AO_t) exp, (AO_t) new))
return exp;
- act = (long) AO_load(&var->counter);
+ act = (ETHR_AINT_T__) AO_load(&var->counter);
} while (act == exp);
return act;
}
-static ETHR_INLINE long
-ethr_native_atomic_xchg(ethr_native_atomic_t *var, long new)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(xchg)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ new)
{
while (1) {
AO_t exp = AO_load(&var->counter);
if (AO_compare_and_swap(&var->counter, exp, (AO_t) new))
- return (long) exp;
+ return (ETHR_AINT_T__) exp;
}
}
@@ -196,97 +246,105 @@ ethr_native_atomic_xchg(ethr_native_atomic_t *var, long new)
* Atomic ops with at least specified barriers.
*/
-static ETHR_INLINE long
-ethr_native_atomic_read_acqb(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read_acqb)(ETHR_ATMC_T__ *var)
{
#ifdef AO_HAVE_load_acquire
- return (long) AO_load_acquire(&var->counter);
+ return (ETHR_AINT_T__) AO_load_acquire(&var->counter);
#else
- long res = ethr_native_atomic_read(var);
+ ETHR_AINT_T__ res = ETHR_NATMC_FUNC__(read)(var);
ETHR_MEMORY_BARRIER;
return res;
#endif
}
-static ETHR_INLINE long
-ethr_native_atomic_inc_return_acqb(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(inc_return_acqb)(ETHR_ATMC_T__ *var)
{
#ifdef AO_HAVE_fetch_and_add1_acquire
- return ((long) AO_fetch_and_add1_acquire(&var->counter)) + 1;
+ return ((ETHR_AINT_T__) AO_fetch_and_add1_acquire(&var->counter)) + 1;
#else
- long res = ethr_native_atomic_add_return(var, 1);
+ ETHR_AINT_T__ res = ETHR_NATMC_FUNC__(add_return)(var, 1);
ETHR_MEMORY_BARRIER;
return res;
#endif
}
static ETHR_INLINE void
-ethr_native_atomic_set_relb(ethr_native_atomic_t *var, long value)
+ETHR_NATMC_FUNC__(set_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
{
#ifdef AO_HAVE_store_release
AO_store_release(&var->counter, (AO_t) value);
#else
ETHR_MEMORY_BARRIER;
- ethr_native_atomic_set(var, value);
+ ETHR_NATMC_FUNC__(set)(var, value);
#endif
}
-static ETHR_INLINE long
-ethr_native_atomic_dec_return_relb(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(dec_return_relb)(ETHR_ATMC_T__ *var)
{
#ifdef AO_HAVE_fetch_and_sub1_release
- return ((long) AO_fetch_and_sub1_release(&var->counter)) - 1;
+ return ((ETHR_AINT_T__) AO_fetch_and_sub1_release(&var->counter)) - 1;
#else
ETHR_MEMORY_BARRIER;
- return ethr_native_atomic_dec_return(var);
+ return ETHR_NATMC_FUNC__(dec_return)(var);
#endif
}
static ETHR_INLINE void
-ethr_native_atomic_dec_relb(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(dec_relb)(ETHR_ATMC_T__ *var)
{
- (void) ethr_native_atomic_dec_return_relb(var);
+ (void) ETHR_NATMC_FUNC__(dec_return_relb)(var);
}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg_acqb(ethr_native_atomic_t *var, long new, long exp)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_acqb)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ exp)
{
#ifdef AO_HAVE_compare_and_swap_acquire
- long act;
+ ETHR_AINT_T__ act;
do {
if (AO_compare_and_swap_acquire(&var->counter, (AO_t) exp, (AO_t) new))
return exp;
- act = (long) AO_load(&var->counter);
+ act = (ETHR_AINT_T__) AO_load(&var->counter);
} while (act == exp);
AO_nop_full();
return act;
#else
- long act = ethr_native_atomic_cmpxchg(var, new, exp);
+ ETHR_AINT_T__ act = ETHR_NATMC_FUNC__(cmpxchg)(var, new, exp);
ETHR_MEMORY_BARRIER;
return act;
#endif
}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg_relb(ethr_native_atomic_t *var, long new, long exp)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_relb)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ exp)
{
#ifdef AO_HAVE_compare_and_swap_release
- long act;
+ ETHR_AINT_T__ act;
do {
if (AO_compare_and_swap_release(&var->counter, (AO_t) exp, (AO_t) new))
return exp;
- act = (long) AO_load(&var->counter);
+ act = (ETHR_AINT_T__) AO_load(&var->counter);
} while (act == exp);
return act;
#else
ETHR_MEMORY_BARRIER;
- return ethr_native_atomic_cmpxchg(var, new, exp);
+ return ETHR_NATMC_FUNC__(cmpxchg)(var, new, exp);
#endif
}
-#endif
+#endif /* ETHR_TRY_INLINE_FUNCS */
-#endif
+#undef ETHR_NATMC_FUNC__
+#undef ETHR_ATMC_T__
+#undef ETHR_AINT_T__
-#endif
+#endif /* !defined(ETHR_HAVE_NATIVE_ATOMICS) && defined(ETHR_HAVE_LIBATOMIC_OPS) */
+
+#endif /* ETHR_LIBATOMIC_OPS_ATOMIC_H__ */
diff --git a/erts/include/internal/ppc32/atomic.h b/erts/include/internal/ppc32/atomic.h
index f21f7c9588..522f433649 100644
--- a/erts/include/internal/ppc32/atomic.h
+++ b/erts/include/internal/ppc32/atomic.h
@@ -28,31 +28,39 @@
#ifndef ETHREAD_PPC_ATOMIC_H
#define ETHREAD_PPC_ATOMIC_H
+#define ETHR_HAVE_NATIVE_ATOMIC32 1
+
typedef struct {
- volatile int counter;
-} ethr_native_atomic_t;
+ volatile ethr_sint32_t counter;
+} ethr_native_atomic32_t;
#define ETHR_MEMORY_BARRIER __asm__ __volatile__("sync" : : : "memory")
-#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
+#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
+
+static ETHR_INLINE ethr_sint32_t *
+ethr_native_atomic32_addr(ethr_native_atomic32_t *var)
+{
+ return (ethr_sint32_t *) &var->counter;
+}
static ETHR_INLINE void
-ethr_native_atomic_init(ethr_native_atomic_t *var, int i)
+ethr_native_atomic32_init(ethr_native_atomic32_t *var, ethr_sint32_t i)
{
var->counter = i;
}
-#define ethr_native_atomic_set(v, i) ethr_native_atomic_init((v), (i))
+#define ethr_native_atomic32_set(v, i) ethr_native_atomic32_init((v), (i))
-static ETHR_INLINE int
-ethr_native_atomic_read(ethr_native_atomic_t *var)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_read(ethr_native_atomic32_t *var)
{
return var->counter;
}
-static ETHR_INLINE int
-ethr_native_atomic_add_return(ethr_native_atomic_t *var, int incr)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_add_return(ethr_native_atomic32_t *var, ethr_sint32_t incr)
{
- int tmp;
+ ethr_sint32_t tmp;
__asm__ __volatile__(
"eieio\n\t"
@@ -69,16 +77,16 @@ ethr_native_atomic_add_return(ethr_native_atomic_t *var, int incr)
}
static ETHR_INLINE void
-ethr_native_atomic_add(ethr_native_atomic_t *var, int incr)
+ethr_native_atomic32_add(ethr_native_atomic32_t *var, ethr_sint32_t incr)
{
/* XXX: could use weaker version here w/o eieio+isync */
- (void)ethr_native_atomic_add_return(var, incr);
+ (void)ethr_native_atomic32_add_return(var, incr);
}
-static ETHR_INLINE int
-ethr_native_atomic_inc_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_inc_return(ethr_native_atomic32_t *var)
{
- int tmp;
+ ethr_sint32_t tmp;
__asm__ __volatile__(
"eieio\n\t"
@@ -95,16 +103,16 @@ ethr_native_atomic_inc_return(ethr_native_atomic_t *var)
}
static ETHR_INLINE void
-ethr_native_atomic_inc(ethr_native_atomic_t *var)
+ethr_native_atomic32_inc(ethr_native_atomic32_t *var)
{
/* XXX: could use weaker version here w/o eieio+isync */
- (void)ethr_native_atomic_inc_return(var);
+ (void)ethr_native_atomic32_inc_return(var);
}
-static ETHR_INLINE int
-ethr_native_atomic_dec_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_dec_return(ethr_native_atomic32_t *var)
{
- int tmp;
+ ethr_sint32_t tmp;
__asm__ __volatile__(
"eieio\n\t"
@@ -121,16 +129,16 @@ ethr_native_atomic_dec_return(ethr_native_atomic_t *var)
}
static ETHR_INLINE void
-ethr_native_atomic_dec(ethr_native_atomic_t *var)
+ethr_native_atomic32_dec(ethr_native_atomic32_t *var)
{
/* XXX: could use weaker version here w/o eieio+isync */
- (void)ethr_native_atomic_dec_return(var);
+ (void)ethr_native_atomic32_dec_return(var);
}
-static ETHR_INLINE int
-ethr_native_atomic_and_retold(ethr_native_atomic_t *var, int mask)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_and_retold(ethr_native_atomic32_t *var, ethr_sint32_t mask)
{
- int old, new;
+ ethr_sint32_t old, new;
__asm__ __volatile__(
"eieio\n\t"
@@ -146,10 +154,10 @@ ethr_native_atomic_and_retold(ethr_native_atomic_t *var, int mask)
return old;
}
-static ETHR_INLINE int
-ethr_native_atomic_or_retold(ethr_native_atomic_t *var, int mask)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_or_retold(ethr_native_atomic32_t *var, ethr_sint32_t mask)
{
- int old, new;
+ ethr_sint32_t old, new;
__asm__ __volatile__(
"eieio\n\t"
@@ -165,10 +173,10 @@ ethr_native_atomic_or_retold(ethr_native_atomic_t *var, int mask)
return old;
}
-static ETHR_INLINE int
-ethr_native_atomic_xchg(ethr_native_atomic_t *var, int val)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_xchg(ethr_native_atomic32_t *var, ethr_sint32_t val)
{
- int tmp;
+ ethr_sint32_t tmp;
__asm__ __volatile__(
"eieio\n\t"
@@ -183,10 +191,12 @@ ethr_native_atomic_xchg(ethr_native_atomic_t *var, int val)
return tmp;
}
-static ETHR_INLINE int
-ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, int new, int expected)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_cmpxchg(ethr_native_atomic32_t *var,
+ ethr_sint32_t new,
+ ethr_sint32_t expected)
{
- int old;
+ ethr_sint32_t old;
__asm__ __volatile__(
"eieio\n\t"
@@ -210,20 +220,20 @@ ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, int new, int expected)
*/
static ETHR_INLINE long
-ethr_native_atomic_read_acqb(ethr_native_atomic_t *var)
+ethr_native_atomic32_read_acqb(ethr_native_atomic32_t *var)
{
- long res = ethr_native_atomic_read(var);
+ long res = ethr_native_atomic32_read(var);
ETHR_MEMORY_BARRIER;
return res;
}
-#define ethr_native_atomic_set_relb ethr_native_atomic_xchg
-#define ethr_native_atomic_inc_return_acqb ethr_native_atomic_inc_return
-#define ethr_native_atomic_dec_relb ethr_native_atomic_dec_return
-#define ethr_native_atomic_dec_return_relb ethr_native_atomic_dec_return
+#define ethr_native_atomic32_set_relb ethr_native_atomic32_xchg
+#define ethr_native_atomic32_inc_return_acqb ethr_native_atomic32_inc_return
+#define ethr_native_atomic32_dec_relb ethr_native_atomic32_dec_return
+#define ethr_native_atomic32_dec_return_relb ethr_native_atomic32_dec_return
-#define ethr_native_atomic_cmpxchg_acqb ethr_native_atomic_cmpxchg
-#define ethr_native_atomic_cmpxchg_relb ethr_native_atomic_cmpxchg
+#define ethr_native_atomic32_cmpxchg_acqb ethr_native_atomic32_cmpxchg
+#define ethr_native_atomic32_cmpxchg_relb ethr_native_atomic32_cmpxchg
#endif /* ETHR_TRY_INLINE_FUNCS */
diff --git a/erts/include/internal/pthread/ethr_event.h b/erts/include/internal/pthread/ethr_event.h
index 104ec287e0..93da8a0429 100644
--- a/erts/include/internal/pthread/ethr_event.h
+++ b/erts/include/internal/pthread/ethr_event.h
@@ -30,31 +30,9 @@
#include <linux/futex.h>
#include <sys/time.h>
-/*
- * Note: Linux futexes operate on 32-bit integers, but
- * ethr_native_atomic_t are 64-bits on 64-bit
- * platforms. This has to be taken into account.
- * Therefore, in each individual value used each
- * byte look the same.
- */
-
-#if ETHR_SIZEOF_PTR == 8
-
-#define ETHR_EVENT_OFF_WAITER__ 0xffffffffffffffffL
-#define ETHR_EVENT_OFF__ 0x7777777777777777L
-#define ETHR_EVENT_ON__ 0L
-
-#elif ETHR_SIZEOF_PTR == 4
-
-#define ETHR_EVENT_OFF_WAITER__ 0xffffffffL
-#define ETHR_EVENT_OFF__ 0x77777777L
-#define ETHR_EVENT_ON__ 0L
-
-#else
-
-#error ehrm...
-
-#endif
+#define ETHR_EVENT_OFF_WAITER__ ((ethr_sint32_t) -1)
+#define ETHR_EVENT_OFF__ ((ethr_sint32_t) 1)
+#define ETHR_EVENT_ON__ ((ethr_sint32_t) 0)
#if defined(FUTEX_WAIT_PRIVATE) && defined(FUTEX_WAKE_PRIVATE)
# define ETHR_FUTEX_WAIT__ FUTEX_WAIT_PRIVATE
@@ -65,11 +43,17 @@
#endif
typedef struct {
- ethr_atomic_t futex;
+ ethr_atomic32_t futex;
} ethr_event;
-#define ETHR_FUTEX__(FTX, OP, VAL) \
- (-1 == syscall(__NR_futex, (void *) (FTX), (OP), (int) (VAL), NULL, NULL, 0)\
+#define ETHR_FUTEX__(FTX, OP, VAL) \
+ (-1 == syscall(__NR_futex, \
+ (void *) ethr_atomic32_addr((FTX)), \
+ (OP), \
+ (int) (VAL), \
+ NULL, \
+ NULL, \
+ 0) \
? errno : 0)
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__)
@@ -77,9 +61,9 @@ typedef struct {
static void ETHR_INLINE
ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e)
{
- long val;
+ ethr_sint32_t val;
ETHR_WRITE_MEMORY_BARRIER;
- val = ethr_atomic_xchg(&e->futex, ETHR_EVENT_ON__);
+ val = ethr_atomic32_xchg(&e->futex, ETHR_EVENT_ON__);
if (val == ETHR_EVENT_OFF_WAITER__) {
int res = ETHR_FUTEX__(&e->futex, ETHR_FUTEX_WAKE__, 1);
if (res != 0)
@@ -90,7 +74,7 @@ ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e)
static void ETHR_INLINE
ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e)
{
- ethr_atomic_set(&e->futex, ETHR_EVENT_OFF__);
+ ethr_atomic32_set(&e->futex, ETHR_EVENT_OFF__);
ETHR_MEMORY_BARRIER;
}
@@ -100,7 +84,7 @@ ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e)
/* --- Posix mutex/cond implementation of events ---------------------------- */
typedef struct {
- ethr_atomic_t state;
+ ethr_atomic32_t state;
pthread_mutex_t mtx;
pthread_cond_t cnd;
} ethr_event;
@@ -114,9 +98,9 @@ typedef struct {
static void ETHR_INLINE
ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e)
{
- long val;
+ ethr_sint32_t val;
ETHR_WRITE_MEMORY_BARRIER;
- val = ethr_atomic_xchg(&e->state, ETHR_EVENT_ON__);
+ val = ethr_atomic32_xchg(&e->state, ETHR_EVENT_ON__);
if (val == ETHR_EVENT_OFF_WAITER__) {
int res = pthread_mutex_lock(&e->mtx);
if (res != 0)
@@ -133,7 +117,7 @@ ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e)
static void ETHR_INLINE
ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e)
{
- ethr_atomic_set(&e->state, ETHR_EVENT_OFF__);
+ ethr_atomic32_set(&e->state, ETHR_EVENT_OFF__);
ETHR_MEMORY_BARRIER;
}
diff --git a/erts/include/internal/sparc32/atomic.h b/erts/include/internal/sparc32/atomic.h
index 2a995d4465..00380dbf07 100644
--- a/erts/include/internal/sparc32/atomic.h
+++ b/erts/include/internal/sparc32/atomic.h
@@ -21,49 +21,86 @@
* Native ethread atomics on SPARC V9.
* Author: Mikael Pettersson.
*/
-#ifndef ETHR_SPARC32_ATOMIC_H
-#define ETHR_SPARC32_ATOMIC_H
-typedef struct {
- volatile long counter;
-} ethr_native_atomic_t;
+#undef ETHR_INCLUDE_ATOMIC_IMPL__
+#if !defined(ETHR_SPARC_V9_ATOMIC32_H__) && defined(ETHR_ATOMIC_WANT_32BIT_IMPL__)
+#define ETHR_SPARC_V9_ATOMIC32_H__
+#define ETHR_INCLUDE_ATOMIC_IMPL__ 4
+#undef ETHR_ATOMIC_WANT_32BIT_IMPL__
+#elif !defined(ETHR_SPARC_V9_ATOMIC64_H__) && defined(ETHR_ATOMIC_WANT_64BIT_IMPL__)
+#define ETHR_SPARC_V9_ATOMIC64_H__
+#define ETHR_INCLUDE_ATOMIC_IMPL__ 8
+#undef ETHR_ATOMIC_WANT_64BIT_IMPL__
+#endif
+
+#ifdef ETHR_INCLUDE_ATOMIC_IMPL__
+
+#ifndef ETHR_SPARC_V9_ATOMIC_COMMON__
+#define ETHR_SPARC_V9_ATOMIC_COMMON__
#define ETHR_MEMORY_BARRIER \
__asm__ __volatile__("membar #LoadLoad|#LoadStore|#StoreLoad|#StoreStore\n" \
: : : "memory")
-#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
+#endif /* ETHR_SPARC_V9_ATOMIC_COMMON__ */
-#if defined(__arch64__)
-#define CASX "casx"
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+#define ETHR_HAVE_NATIVE_ATOMIC32 1
+#define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
+#define ETHR_ATMC_T__ ethr_native_atomic32_t
+#define ETHR_AINT_T__ ethr_sint32_t
+#define ETHR_CAS__ "cas"
+#elif ETHR_INCLUDE_ATOMIC_IMPL__ == 8
+#define ETHR_HAVE_NATIVE_ATOMIC64 1
+#define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
+#define ETHR_ATMC_T__ ethr_native_atomic64_t
+#define ETHR_AINT_T__ ethr_sint64_t
+#define ETHR_CAS__ "casx"
#else
-#define CASX "cas"
+#error "Unsupported integer size"
#endif
+typedef struct {
+ volatile ETHR_AINT_T__ counter;
+} ETHR_ATMC_T__;
+
+#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
+
+static ETHR_INLINE ETHR_AINT_T__ *
+ETHR_NATMC_FUNC__(addr)(ETHR_ATMC_T__ *var)
+{
+ return (ETHR_AINT_T__ *) &var->counter;
+}
+
+static ETHR_INLINE void
+ETHR_NATMC_FUNC__(init)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
+{
+ var->counter = i;
+}
+
static ETHR_INLINE void
-ethr_native_atomic_init(ethr_native_atomic_t *var, long i)
+ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
{
var->counter = i;
}
-#define ethr_native_atomic_set(v, i) ethr_native_atomic_init((v), (i))
-static ETHR_INLINE long
-ethr_native_atomic_read(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
{
return var->counter;
}
-static ETHR_INLINE long
-ethr_native_atomic_add_return(ethr_native_atomic_t *var, long incr)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(add_return)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
{
- long old, tmp;
+ ETHR_AINT_T__ old, tmp;
__asm__ __volatile__("membar #LoadLoad|#StoreLoad\n");
do {
old = var->counter;
tmp = old+incr;
__asm__ __volatile__(
- CASX " [%2], %1, %0"
+ ETHR_CAS__ " [%2], %1, %0"
: "=&r"(tmp)
: "r"(old), "r"(&var->counter), "0"(tmp)
: "memory");
@@ -73,46 +110,46 @@ ethr_native_atomic_add_return(ethr_native_atomic_t *var, long incr)
}
static ETHR_INLINE void
-ethr_native_atomic_add(ethr_native_atomic_t *var, long incr)
+ETHR_NATMC_FUNC__(add)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
{
- (void)ethr_native_atomic_add_return(var, incr);
+ (void)ETHR_NATMC_FUNC__(add_return)(var, incr);
}
-static ETHR_INLINE long
-ethr_native_atomic_inc_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(inc_return)(ETHR_ATMC_T__ *var)
{
- return ethr_native_atomic_add_return(var, 1);
+ return ETHR_NATMC_FUNC__(add_return)(var, 1);
}
static ETHR_INLINE void
-ethr_native_atomic_inc(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(inc)(ETHR_ATMC_T__ *var)
{
- (void)ethr_native_atomic_add_return(var, 1);
+ (void)ETHR_NATMC_FUNC__(add_return)(var, 1);
}
-static ETHR_INLINE long
-ethr_native_atomic_dec_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(dec_return)(ETHR_ATMC_T__ *var)
{
- return ethr_native_atomic_add_return(var, -1);
+ return ETHR_NATMC_FUNC__(add_return)(var, -1);
}
static ETHR_INLINE void
-ethr_native_atomic_dec(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(dec)(ETHR_ATMC_T__ *var)
{
- (void)ethr_native_atomic_add_return(var, -1);
+ (void)ETHR_NATMC_FUNC__(add_return)(var, -1);
}
-static ETHR_INLINE long
-ethr_native_atomic_and_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(and_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
- long old, tmp;
+ ETHR_AINT_T__ old, tmp;
__asm__ __volatile__("membar #LoadLoad|#StoreLoad\n");
do {
old = var->counter;
tmp = old & mask;
__asm__ __volatile__(
- CASX " [%2], %1, %0"
+ ETHR_CAS__ " [%2], %1, %0"
: "=&r"(tmp)
: "r"(old), "r"(&var->counter), "0"(tmp)
: "memory");
@@ -121,17 +158,17 @@ ethr_native_atomic_and_retold(ethr_native_atomic_t *var, long mask)
return old;
}
-static ETHR_INLINE long
-ethr_native_atomic_or_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(or_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
- long old, tmp;
+ ETHR_AINT_T__ old, tmp;
__asm__ __volatile__("membar #LoadLoad|#StoreLoad\n");
do {
old = var->counter;
tmp = old | mask;
__asm__ __volatile__(
- CASX " [%2], %1, %0"
+ ETHR_CAS__ " [%2], %1, %0"
: "=&r"(tmp)
: "r"(old), "r"(&var->counter), "0"(tmp)
: "memory");
@@ -140,17 +177,17 @@ ethr_native_atomic_or_retold(ethr_native_atomic_t *var, long mask)
return old;
}
-static ETHR_INLINE long
-ethr_native_atomic_xchg(ethr_native_atomic_t *var, long val)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(xchg)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ val)
{
- long old, new;
+ ETHR_AINT_T__ old, new;
__asm__ __volatile__("membar #LoadLoad|#StoreLoad");
do {
old = var->counter;
new = val;
__asm__ __volatile__(
- CASX " [%2], %1, %0"
+ ETHR_CAS__ " [%2], %1, %0"
: "=&r"(new)
: "r"(old), "r"(&var->counter), "0"(new)
: "memory");
@@ -159,12 +196,12 @@ ethr_native_atomic_xchg(ethr_native_atomic_t *var, long val)
return old;
}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, long new, long old)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ new, ETHR_AINT_T__ old)
{
__asm__ __volatile__("membar #LoadLoad|#StoreLoad\n");
__asm__ __volatile__(
- CASX " [%2], %1, %0"
+ ETHR_CAS__ " [%2], %1, %0"
: "=&r"(new)
: "r"(old), "r"(&var->counter), "0"(new)
: "memory");
@@ -176,39 +213,65 @@ ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, long new, long old)
* Atomic ops with at least specified barriers.
*/
-static ETHR_INLINE long
-ethr_native_atomic_read_acqb(ethr_native_atomic_t *var)
+/* TODO: relax acquire barriers */
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read_acqb)(ETHR_ATMC_T__ *var)
{
- long res = ethr_native_atomic_read(var);
- __asm__ __volatile__("membar #StoreLoad|#StoreStore");
+ ETHR_AINT_T__ res = ETHR_NATMC_FUNC__(read)(var);
+ __asm__ __volatile__("membar #LoadLoad|#LoadStore|#StoreLoad|#StoreStore" : : : "memory");
return res;
}
static ETHR_INLINE void
-ethr_native_atomic_set_relb(ethr_native_atomic_t *var, long i)
+ETHR_NATMC_FUNC__(set_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
{
- __asm__ __volatile__("membar #LoadStore|#StoreStore");
- ethr_native_atomic_set(var, i);
+ __asm__ __volatile__("membar #LoadStore|#StoreStore" : : : "memory");
+ ETHR_NATMC_FUNC__(set)(var, i);
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(inc_return_acqb)(ETHR_ATMC_T__ *var)
+{
+ ETHR_AINT_T__ res = ETHR_NATMC_FUNC__(inc_return)(var);
+ __asm__ __volatile__("membar #LoadLoad|#LoadStore" : : : "memory");
+ return res;
}
static ETHR_INLINE void
-ethr_native_atomic_dec_relb(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(dec_relb)(ETHR_ATMC_T__ *var)
{
- __asm__ __volatile__("membar #LoadStore|#StoreStore");
- ethr_native_atomic_dec(var);
+ __asm__ __volatile__("membar #LoadStore|#StoreStore" : : : "memory");
+ ETHR_NATMC_FUNC__(dec)(var);
}
-static ETHR_INLINE long
-ethr_native_atomic_dec_return_relb(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(dec_return_relb)(ETHR_ATMC_T__ *var)
{
- __asm__ __volatile__("membar #LoadStore|#StoreStore");
- return ethr_native_atomic_dec_return(var);
+ __asm__ __volatile__("membar #LoadStore|#StoreStore" : : : "memory");
+ return ETHR_NATMC_FUNC__(dec_return)(var);
}
-#define ethr_native_atomic_inc_return_acqb ethr_native_atomic_inc_return
-#define ethr_native_atomic_cmpxchg_acqb ethr_native_atomic_cmpxchg
-#define ethr_native_atomic_cmpxchg_relb ethr_native_atomic_cmpxchg
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_acqb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ new, ETHR_AINT_T__ old)
+{
+ ETHR_AINT_T__ res = ETHR_NATMC_FUNC__(cmpxchg)(var, new, old);
+ __asm__ __volatile__("membar #LoadLoad|#LoadStore" : : : "memory");
+ return res;
+}
+
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ new, ETHR_AINT_T__ old)
+{
+ __asm__ __volatile__("membar #LoadStore|#StoreStore" : : : "memory");
+ return ETHR_NATMC_FUNC__(cmpxchg)(var, new, old);
+}
#endif /* ETHR_TRY_INLINE_FUNCS */
-#endif /* ETHR_SPARC32_ATOMIC_H */
+#undef ETHR_NATMC_FUNC__
+#undef ETHR_ATMC_T__
+#undef ETHR_AINT_T__
+#undef ETHR_CAS__
+
+#endif /* ETHR_INCLUDE_ATOMIC_IMPL__ */
diff --git a/erts/include/internal/sparc32/ethread.h b/erts/include/internal/sparc32/ethread.h
index dca113b4d6..aea9794390 100644
--- a/erts/include/internal/sparc32/ethread.h
+++ b/erts/include/internal/sparc32/ethread.h
@@ -1,7 +1,7 @@
/*
* %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
@@ -24,7 +24,12 @@
#ifndef ETHREAD_SPARC32_ETHREAD_H
#define ETHREAD_SPARC32_ETHREAD_H
+#define ETHR_ATOMIC_WANT_32BIT_IMPL__
#include "atomic.h"
+#if ETHR_SIZEOF_PTR == 8
+# define ETHR_ATOMIC_WANT_64BIT_IMPL__
+# include "atomic.h"
+#endif
#include "spinlock.h"
#include "rwlock.h"
diff --git a/erts/include/internal/tile/atomic.h b/erts/include/internal/tile/atomic.h
index 69569d82d1..48e4c0c6c8 100644
--- a/erts/include/internal/tile/atomic.h
+++ b/erts/include/internal/tile/atomic.h
@@ -24,92 +24,102 @@
#ifndef ETHREAD_TILE_ATOMIC_H
#define ETHREAD_TILE_ATOMIC_H
+#define ETHR_HAVE_NATIVE_ATOMIC32 1
+
#include <atomic.h>
/* An atomic is an aligned int accessed via locked operations.
*/
typedef struct {
- volatile long counter;
-} ethr_native_atomic_t;
+ volatile ethr_sint32_t counter;
+} ethr_native_atomic32_t;
#define ETHR_MEMORY_BARRIER __insn_mf()
-#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
+#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
+
+static ETHR_INLINE ethr_sint32_t *
+ethr_native_atomic32_addr(ethr_native_atomic32_t *var)
+{
+ return (ethr_sint32_t *) &var->counter;
+}
static ETHR_INLINE void
-ethr_native_atomic_init(ethr_native_atomic_t *var, long i)
+ethr_native_atomic32_init(ethr_native_atomic32_t *var, ethr_sint32_t i)
{
var->counter = i;
}
static ETHR_INLINE void
-ethr_native_atomic_set(ethr_native_atomic_t *var, long i)
+ethr_native_atomic32_set(ethr_native_atomic32_t *var, ethr_sint32_t i)
{
atomic_exchange_acq(&var->counter, i);
}
-static ETHR_INLINE long
-ethr_native_atomic_read(ethr_native_atomic_t *var)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_read(ethr_native_atomic32_t *var)
{
return var->counter;
}
static ETHR_INLINE void
-ethr_native_atomic_add(ethr_native_atomic_t *var, long incr)
+ethr_native_atomic32_add(ethr_native_atomic32_t *var, ethr_sint32_t incr)
{
atomic_add(&var->counter, incr);
}
static ETHR_INLINE void
-ethr_native_atomic_inc(ethr_native_atomic_t *var)
+ethr_native_atomic32_inc(ethr_native_atomic32_t *var)
{
atomic_increment(&var->counter);
}
static ETHR_INLINE void
-ethr_native_atomic_dec(ethr_native_atomic_t *var)
+ethr_native_atomic32_dec(ethr_native_atomic32_t *var)
{
atomic_decrement(&var->counter);
}
-static ETHR_INLINE long
-ethr_native_atomic_add_return(ethr_native_atomic_t *var, long incr)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_add_return(ethr_native_atomic32_t *var, ethr_sint32_t incr)
{
return atomic_exchange_and_add(&var->counter, incr) + incr;
}
-static ETHR_INLINE long
-ethr_native_atomic_inc_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_inc_return(ethr_native_atomic32_t *var)
{
- return ethr_native_atomic_add_return(var, 1);
+ return ethr_native_atomic32_add_return(var, 1);
}
-static ETHR_INLINE long
-ethr_native_atomic_dec_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_dec_return(ethr_native_atomic32_t *var)
{
- return ethr_native_atomic_add_return(var, -1);
+ return ethr_native_atomic32_add_return(var, -1);
}
-static ETHR_INLINE long
-ethr_native_atomic_and_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_and_retold(ethr_native_atomic32_t *var, ethr_sint32_t mask)
{
return atomic_and_val(&var->counter, mask);
}
-static ETHR_INLINE long
-ethr_native_atomic_or_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_or_retold(ethr_native_atomic32_t *var, ethr_sint32_t mask)
{
return atomic_or_val(&var->counter, mask);
}
-static ETHR_INLINE long
-ethr_native_atomic_xchg(ethr_native_atomic_t *var, long val)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_xchg(ethr_native_atomic32_t *var, ethr_sint32_t val)
{
return atomic_exchange_acq(&var->counter, val);
}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, long new, long expected)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_cmpxchg(ethr_native_atomic32_t *var,
+ ethr_sint32_t new,
+ ethr_sint32_t expected)
{
return atomic_compare_and_exchange_val_acq(&var->counter, new, expected);
}
@@ -118,54 +128,58 @@ ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, long new, long expected)
* Atomic ops with at least specified barriers.
*/
-static ETHR_INLINE long
-ethr_native_atomic_read_acqb(ethr_native_atomic_t *var)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_read_acqb(ethr_native_atomic32_t *var)
{
- long res = ethr_native_atomic_read(var);
+ ethr_sint32_t res = ethr_native_atomic32_read(var);
ETHR_MEMORY_BARRIER;
return res;
}
-static ETHR_INLINE long
-ethr_native_atomic_inc_return_acqb(ethr_native_atomic_t *var)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_inc_return_acqb(ethr_native_atomic32_t *var)
{
- long res = ethr_native_atomic_inc_return(var);
+ ethr_sint32_t res = ethr_native_atomic32_inc_return(var);
ETHR_MEMORY_BARRIER;
return res;
}
static ETHR_INLINE void
-ethr_native_atomic_set_relb(ethr_native_atomic_t *var, long val)
+ethr_native_atomic32_set_relb(ethr_native_atomic32_t *var, ethr_sint32_t val)
{
ETHR_MEMORY_BARRIER;
- ethr_native_atomic_set(var, val);
+ ethr_native_atomic32_set(var, val);
}
static ETHR_INLINE void
-ethr_native_atomic_dec_relb(ethr_native_atomic_t *var)
+ethr_native_atomic32_dec_relb(ethr_native_atomic32_t *var)
{
ETHR_MEMORY_BARRIER;
- ethr_native_atomic_dec(var);
+ ethr_native_atomic32_dec(var);
}
-static ETHR_INLINE long
-ethr_native_atomic_dec_return_relb(ethr_native_atomic_t *var)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_dec_return_relb(ethr_native_atomic32_t *var)
{
ETHR_MEMORY_BARRIER;
- return ethr_native_atomic_dec_return(var);
+ return ethr_native_atomic32_dec_return(var);
}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg_acqb(ethr_native_atomic_t *var, long new, long exp)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_cmpxchg_acqb(ethr_native_atomic32_t *var,
+ ethr_sint32_t new,
+ ethr_sint32_t exp)
{
- return ethr_native_atomic_cmpxchg(var, new, exp);
+ return ethr_native_atomic32_cmpxchg(var, new, exp);
}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg_relb(ethr_native_atomic_t *var, long new, long exp)
+static ETHR_INLINE ethr_sint32_t
+ethr_native_atomic32_cmpxchg_relb(ethr_native_atomic32_t *var,
+ ethr_sint32_t new,
+ ethr_sint32_t exp)
{
ETHR_MEMORY_BARRIER;
- return ethr_native_atomic_cmpxchg(var, new, exp);
+ return ethr_native_atomic32_cmpxchg(var, new, exp);
}
#endif /* ETHR_TRY_INLINE_FUNCS */
diff --git a/erts/include/internal/win/ethr_atomic.h b/erts/include/internal/win/ethr_atomic.h
index 500459dd6c..60def01a7e 100644
--- a/erts/include/internal/win/ethr_atomic.h
+++ b/erts/include/internal/win/ethr_atomic.h
@@ -22,223 +22,394 @@
* Author: Rickard Green
*/
-#ifndef ETHR_WIN_ATOMIC_H__
-#define ETHR_WIN_ATOMIC_H__
-
-#ifdef _MSC_VER
-# if _MSC_VER < 1300
-# define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 0 /* Dont trust really old compilers */
-# else
-# if defined(_M_IX86)
-# define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 1
-# else /* I.e. IA64 */
-# if _MSC_VER >= 1400
-# define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 1
-# else
-# define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 0
-# endif
-# endif
-# endif
-# if _MSC_VER >= 1400
-# include <intrin.h>
-# undef ETHR_COMPILER_BARRIER
-# define ETHR_COMPILER_BARRIER _ReadWriteBarrier()
-# endif
-#pragma intrinsic(_ReadWriteBarrier)
-#pragma intrinsic(_InterlockedAnd)
-#pragma intrinsic(_InterlockedOr)
+#undef ETHR_INCLUDE_ATOMIC_IMPL__
+#if !defined(ETHR_WIN_ATOMIC32_H__) && defined(ETHR_ATOMIC_WANT_32BIT_IMPL__)
+#define ETHR_WIN_ATOMIC32_H__
+#define ETHR_INCLUDE_ATOMIC_IMPL__ 4
+#undef ETHR_ATOMIC_WANT_32BIT_IMPL__
+#elif !defined(ETHR_WIN_ATOMIC64_H__) && defined(ETHR_ATOMIC_WANT_64BIT_IMPL__)
+#define ETHR_WIN_ATOMIC64_H__
+#ifdef ETHR_HAVE__INTERLOCKEDCOMPAREEXCHANGE64
+/* _InterlockedCompareExchange64() required... */
+#define ETHR_INCLUDE_ATOMIC_IMPL__ 8
+#endif
+#undef ETHR_ATOMIC_WANT_64BIT_IMPL__
+#endif
+
+#ifdef ETHR_INCLUDE_ATOMIC_IMPL__
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+
+#ifndef ETHR_WIN_ATOMIC_COMMON__
+#define ETHR_WIN_ATOMIC_COMMON__
+
+#define ETHR_HAVE_NATIVE_ATOMICS 1
+
+#if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64)
+# define ETHR_READ_AND_SET_WITHOUT_INTERLOCKED_OP__ 1
#else
-# define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 0
+# define ETHR_READ_AND_SET_WITHOUT_INTERLOCKED_OP__ 0
#endif
+#if defined(_M_AMD64) || (defined(_M_IX86) \
+ && !defined(ETHR_PRE_PENTIUM4_COMPAT))
+# define ETHR_READ_ACQB_AND_SET_RELB_COMPILER_BARRIER_ONLY__ 1
+#else
+# define ETHR_READ_ACQB_AND_SET_RELB_COMPILER_BARRIER_ONLY__ 0
+#endif
/*
- * No configure test checking for _Interlocked*_{acq,rel} and
- * Interlocked*{Acquire,Release} have been written yet...
+ * No configure test checking for interlocked acquire/release
+ * versions have been written, yet. It should define
+ * ETHR_HAVE_INTERLOCKED_ACQUIRE_RELEASE_BARRIERS if, and
+ * only if, all used interlocked operations with barriers
+ * exists.
*
* Note, that these are pure optimizations for the itanium
* processor.
*/
-#ifdef ETHR_HAVE_INTERLOCKEDCOMPAREEXCHANGE_ACQ
-#pragma intrinsic(_InterlockedCompareExchange_acq)
+#include <intrin.h>
+#undef ETHR_COMPILER_BARRIER
+#define ETHR_COMPILER_BARRIER _ReadWriteBarrier()
+#pragma intrinsic(_ReadWriteBarrier)
+#pragma intrinsic(_InterlockedCompareExchange)
+
+#if defined(_M_AMD64) || (defined(_M_IX86) \
+ && !defined(ETHR_PRE_PENTIUM4_COMPAT))
+#include <emmintrin.h>
+#include <mmintrin.h>
+#pragma intrinsic(_mm_mfence)
+#define ETHR_MEMORY_BARRIER _mm_mfence()
+#pragma intrinsic(_mm_sfence)
+#define ETHR_WRITE_MEMORY_BARRIER _mm_sfence()
+#pragma intrinsic(_mm_lfence)
+#define ETHR_READ_MEMORY_BARRIER _mm_lfence()
+#define ETHR_READ_DEPEND_MEMORY_BARRIER ETHR_COMPILER_BARRIER
+
+#else
+
+#define ETHR_MEMORY_BARRIER \
+do { \
+ volatile long x___ = 0; \
+ _InterlockedCompareExchange(&x___, (long) 1, (long) 0); \
+} while (0)
+
#endif
-#ifdef ETHR_HAVE_INTERLOCKEDCOMPAREEXCHANGE_REL
+
+#endif /* ETHR_WIN_ATOMIC_COMMON__ */
+
+#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
+
+#define ETHR_HAVE_NATIVE_ATOMIC32 1
+
+/*
+ * All used operations available as 32-bit intrinsics
+ */
+
+#pragma intrinsic(_InterlockedDecrement)
+#pragma intrinsic(_InterlockedIncrement)
+#pragma intrinsic(_InterlockedExchangeAdd)
+#pragma intrinsic(_InterlockedExchange)
+#pragma intrinsic(_InterlockedAnd)
+#pragma intrinsic(_InterlockedOr)
+#ifdef ETHR_HAVE_INTERLOCKED_ACQUIRE_RELEASE_BARRIERS
+#pragma intrinsic(_InterlockedExchangeAdd_acq)
+#pragma intrinsic(_InterlockedIncrement_acq)
+#pragma intrinsic(_InterlockedDecrement_rel)
+#pragma intrinsic(_InterlockedCompareExchange_acq)
#pragma intrinsic(_InterlockedCompareExchange_rel)
#endif
+#define ETHR_ILCKD__(X) _Interlocked ## X
+#ifdef ETHR_HAVE_INTERLOCKED_ACQUIRE_RELEASE_BARRIERS
+#define ETHR_ILCKD_ACQ__(X) _Interlocked ## X ## _acq
+#define ETHR_ILCKD_REL__(X) _Interlocked ## X ## _rel
+#else
+#define ETHR_ILCKD_ACQ__(X) _Interlocked ## X
+#define ETHR_ILCKD_REL__(X) _Interlocked ## X
+#endif
+
+#define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
+#define ETHR_ATMC_T__ ethr_native_atomic32_t
+#define ETHR_AINT_T__ ethr_sint32_t
+
+#elif ETHR_INCLUDE_ATOMIC_IMPL__ == 8
+
+#define ETHR_HAVE_NATIVE_ATOMIC64 1
+
+/*
+ * _InterlockedCompareExchange64() is required. The other may not
+ * be available, but if so, we can generate them.
+ */
+#pragma intrinsic(_InterlockedCompareExchange64)
+
+#if ETHR_READ_AND_SET_WITHOUT_INTERLOCKED_OP__
+#define ETHR_OWN_ILCKD_INIT_VAL__(PTR) *(PTR)
+#else
+#define ETHR_OWN_ILCKD_INIT_VAL__(PTR) (__int64) 0
+#endif
+
+#define ETHR_OWN_ILCKD_BODY_IMPL__(FUNC, PTR, NEW, ACT, EXP, OPS, RET) \
+{ \
+ __int64 NEW, ACT, EXP; \
+ ACT = ETHR_OWN_ILCKD_INIT_VAL__(PTR); \
+ do { \
+ EXP = ACT; \
+ { OPS; } \
+ ACT = _InterlockedCompareExchange64(PTR, NEW, EXP); \
+ } while (ACT != EXP); \
+ return RET; \
+}
+
+#define ETHR_OWN_ILCKD_1_IMPL__(FUNC, NEW, ACT, EXP, OPS, RET) \
+static __forceinline __int64 \
+FUNC(__int64 volatile *ptr) \
+ETHR_OWN_ILCKD_BODY_IMPL__(FUNC, ptr, NEW, ACT, EXP, OPS, RET)
+
+#define ETHR_OWN_ILCKD_2_IMPL__(FUNC, NEW, ACT, EXP, OPS, ARG, RET) \
+static __forceinline __int64 \
+FUNC(__int64 volatile *ptr, __int64 ARG) \
+ETHR_OWN_ILCKD_BODY_IMPL__(FUNC, ptr, NEW, ACT, EXP, OPS, RET)
+
+
+#ifdef ETHR_HAVE__INTERLOCKEDDECREMENT64
+#pragma intrinsic(_InterlockedDecrement64)
+#else
+ETHR_OWN_ILCKD_1_IMPL__(_InterlockedDecrement64, new, act, exp,
+ new = act - 1, new)
+#endif
+#ifdef ETHR_HAVE__INTERLOCKEDINCREMENT64
+#pragma intrinsic(_InterlockedIncrement64)
+#else
+ETHR_OWN_ILCKD_1_IMPL__(_InterlockedIncrement64, new, act, exp,
+ new = act + 1, new)
+#endif
+#ifdef ETHR_HAVE__INTERLOCKEDEXCHANGEADD64
+#pragma intrinsic(_InterlockedExchangeAdd64)
+#else
+ETHR_OWN_ILCKD_2_IMPL__(_InterlockedExchangeAdd64, new, act, exp,
+ new = act + arg, arg, act)
+#endif
+#ifdef ETHR_HAVE__INTERLOCKEDEXCHANGE64
+#pragma intrinsic(_InterlockedExchange64)
+#else
+ETHR_OWN_ILCKD_2_IMPL__(_InterlockedExchange64, new, act, exp,
+ new = arg, arg, act)
+#endif
+#ifdef ETHR_HAVE__INTERLOCKEDAND64
+#pragma intrinsic(_InterlockedAnd64)
+#else
+ETHR_OWN_ILCKD_2_IMPL__(_InterlockedAnd64, new, act, exp,
+ new = act & arg, arg, act)
+#endif
+#ifdef ETHR_HAVE__INTERLOCKEDOR64
+#pragma intrinsic(_InterlockedOr64)
+#else
+ETHR_OWN_ILCKD_2_IMPL__(_InterlockedOr64, new, act, exp,
+ new = act | arg, arg, act)
+#endif
+#ifdef ETHR_HAVE_INTERLOCKED_ACQUIRE_RELEASE_BARRIERS
+#pragma intrinsic(_InterlockedExchangeAdd64_acq)
+#pragma intrinsic(_InterlockedIncrement64_acq)
+#pragma intrinsic(_InterlockedDecrement64_rel)
+#pragma intrinsic(_InterlockedCompareExchange64_acq)
+#pragma intrinsic(_InterlockedCompareExchange64_rel)
+#endif
+
+#define ETHR_ILCKD__(X) _Interlocked ## X ## 64
+#ifdef ETHR_HAVE_INTERLOCKED_ACQUIRE_RELEASE_BARRIERS
+#define ETHR_ILCKD_ACQ__(X) _Interlocked ## X ## 64_acq
+#define ETHR_ILCKD_REL__(X) _Interlocked ## X ## 64_rel
+#else
+#define ETHR_ILCKD_ACQ__(X) _Interlocked ## X ## 64
+#define ETHR_ILCKD_REL__(X) _Interlocked ## X ## 64
+#endif
+
+#define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
+#define ETHR_ATMC_T__ ethr_native_atomic64_t
+#define ETHR_AINT_T__ ethr_sint64_t
+
+#else
+#error "Unsupported integer size"
+#endif
typedef struct {
- volatile LONG value;
-} ethr_native_atomic_t;
+ volatile ETHR_AINT_T__ value;
+} ETHR_ATMC_T__;
-#define ETHR_MEMORY_BARRIER \
-do { \
- volatile LONG x___ = 0; \
- _InterlockedCompareExchange(&x___, (LONG) 1, (LONG) 0); \
-} while (0)
+#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
-#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
+static ETHR_INLINE ETHR_AINT_T__ *
+ETHR_NATMC_FUNC__(addr)(ETHR_ATMC_T__ *var)
+{
+ return (ETHR_AINT_T__ *) &var->value;
+}
static ETHR_INLINE void
-ethr_native_atomic_init(ethr_native_atomic_t *var, long i)
+ETHR_NATMC_FUNC__(init)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
{
- var->value = (LONG) i;
+#if ETHR_READ_AND_SET_WITHOUT_INTERLOCKED_OP__
+ var->value = i;
+#else
+ (void) ETHR_ILCKD__(Exchange)(&var->value, i);
+#endif
}
static ETHR_INLINE void
-ethr_native_atomic_set(ethr_native_atomic_t *var, long i)
+ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
{
-#if ETHR_IMMED_ATOMIC_SET_GET_SAFE__
- var->value = (LONG) i;
+#if ETHR_READ_AND_SET_WITHOUT_INTERLOCKED_OP__
+ var->value = i;
#else
- (void) InterlockedExchange(&var->value, (LONG) i);
+ (void) ETHR_ILCKD__(Exchange)(&var->value, i);
#endif
}
-static ETHR_INLINE long
-ethr_native_atomic_read(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
{
-#if ETHR_IMMED_ATOMIC_SET_GET_SAFE__
+#if ETHR_READ_AND_SET_WITHOUT_INTERLOCKED_OP__
return var->value;
#else
- return InterlockedExchangeAdd(&var->value, (LONG) 0);
+ return ETHR_ILCKD__(ExchangeAdd)(&var->value, (ETHR_AINT_T__) 0);
#endif
}
static ETHR_INLINE void
-ethr_native_atomic_add(ethr_native_atomic_t *var, long incr)
+ETHR_NATMC_FUNC__(add)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
{
- (void) InterlockedExchangeAdd(&var->value, (LONG) incr);
+ (void) ETHR_ILCKD__(ExchangeAdd)(&var->value, incr);
}
-static ETHR_INLINE long
-ethr_native_atomic_add_return(ethr_native_atomic_t *var, long i)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(add_return)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
{
- LONG tmp = InterlockedExchangeAdd(&var->value, (LONG) i);
- return tmp + i;
+ return ETHR_ILCKD__(ExchangeAdd)(&var->value, i) + i;
}
static ETHR_INLINE void
-ethr_native_atomic_inc(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(inc)(ETHR_ATMC_T__ *var)
{
- (void) InterlockedIncrement(&var->value);
+ (void) ETHR_ILCKD__(Increment)(&var->value);
}
static ETHR_INLINE void
-ethr_native_atomic_dec(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(dec)(ETHR_ATMC_T__ *var)
{
- (void) InterlockedDecrement(&var->value);
+ (void) ETHR_ILCKD__(Decrement)(&var->value);
}
-static ETHR_INLINE long
-ethr_native_atomic_inc_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(inc_return)(ETHR_ATMC_T__ *var)
{
- return (long) InterlockedIncrement(&var->value);
+ return ETHR_ILCKD__(Increment)(&var->value);
}
-static ETHR_INLINE long
-ethr_native_atomic_dec_return(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(dec_return)(ETHR_ATMC_T__ *var)
{
- return (long) InterlockedDecrement(&var->value);
+ return ETHR_ILCKD__(Decrement)(&var->value);
}
-static ETHR_INLINE long
-ethr_native_atomic_and_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(and_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
- return (long) _InterlockedAnd(&var->value, mask);
+ return ETHR_ILCKD__(And)(&var->value, mask);
}
-static ETHR_INLINE long
-ethr_native_atomic_or_retold(ethr_native_atomic_t *var, long mask)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(or_retold)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
{
- return (long) _InterlockedOr(&var->value, mask);
+ return ETHR_ILCKD__(Or)(&var->value, mask);
}
-
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, long new, long old)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ old)
{
- return (long) _InterlockedCompareExchange(&var->value, (LONG) new, (LONG) old);
+ return ETHR_ILCKD__(CompareExchange)(&var->value, new, old);
}
-static ETHR_INLINE long
-ethr_native_atomic_xchg(ethr_native_atomic_t *var, long new)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(xchg)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ new)
{
- return (long) InterlockedExchange(&var->value, (LONG) new);
+ return ETHR_ILCKD__(Exchange)(&var->value, new);
}
/*
* Atomic ops with at least specified barriers.
*/
-static ETHR_INLINE long
-ethr_native_atomic_read_acqb(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(read_acqb)(ETHR_ATMC_T__ *var)
{
-#ifdef ETHR_HAVE_INTERLOCKEDEXCHANGEADDACQUIRE
- return (long) InterlockedExchangeAddAcquire(&var->value, (LONG) 0);
+#if ETHR_READ_ACQB_AND_SET_RELB_COMPILER_BARRIER_ONLY__
+ ETHR_AINT_T__ val = var->value;
+ ETHR_COMPILER_BARRIER;
+ return val;
#else
- return (long) InterlockedExchangeAdd(&var->value, (LONG) 0);
+ return ETHR_ILCKD_ACQ__(ExchangeAdd)(&var->value, (ETHR_AINT_T__) 0);
#endif
}
-static ETHR_INLINE long
-ethr_native_atomic_inc_return_acqb(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(inc_return_acqb)(ETHR_ATMC_T__ *var)
{
-#ifdef ETHR_HAVE_INTERLOCKEDINCREMENTACQUIRE
- return (long) InterlockedIncrementAcquire(&var->value);
-#else
- return (long) InterlockedIncrement(&var->value);
-#endif
+ return ETHR_ILCKD_ACQ__(Increment)(&var->value);
}
static ETHR_INLINE void
-ethr_native_atomic_set_relb(ethr_native_atomic_t *var, long i)
+ETHR_NATMC_FUNC__(set_relb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ i)
{
- (void) InterlockedExchange(&var->value, (LONG) i);
+#if ETHR_READ_ACQB_AND_SET_RELB_COMPILER_BARRIER_ONLY__
+ ETHR_COMPILER_BARRIER;
+ var->value = i;
+#else
+ (void) ETHR_ILCKD_REL__(Exchange)(&var->value, i);
+#endif
}
static ETHR_INLINE void
-ethr_native_atomic_dec_relb(ethr_native_atomic_t *var)
+ETHR_NATMC_FUNC__(dec_relb)(ETHR_ATMC_T__ *var)
{
-#ifdef ETHR_HAVE_INTERLOCKEDDECREMENTRELEASE
- (void) InterlockedDecrementRelease(&var->value);
-#else
- (void) InterlockedDecrement(&var->value);
-#endif
+ (void) ETHR_ILCKD_REL__(Decrement)(&var->value);
}
-static ETHR_INLINE long
-ethr_native_atomic_dec_return_relb(ethr_native_atomic_t *var)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(dec_return_relb)(ETHR_ATMC_T__ *var)
{
-#ifdef ETHR_HAVE_INTERLOCKEDDECREMENTRELEASE
- return (long) InterlockedDecrementRelease(&var->value);
-#else
- return (long) InterlockedDecrement(&var->value);
-#endif
+ return ETHR_ILCKD_REL__(Decrement)(&var->value);
}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg_acqb(ethr_native_atomic_t *var, long new, long old)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_acqb)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ old)
{
-#ifdef ETHR_HAVE_INTERLOCKEDCOMPAREEXCHANGE_ACQ
- return (long) _InterlockedCompareExchange_acq(&var->value, (LONG) new, (LONG) old);
-#else
- return (long) _InterlockedCompareExchange(&var->value, (LONG) new, (LONG) old);
-#endif
+ return ETHR_ILCKD_ACQ__(CompareExchange)(&var->value, new, old);
}
-static ETHR_INLINE long
-ethr_native_atomic_cmpxchg_relb(ethr_native_atomic_t *var, long new, long old)
+static ETHR_INLINE ETHR_AINT_T__
+ETHR_NATMC_FUNC__(cmpxchg_relb)(ETHR_ATMC_T__ *var,
+ ETHR_AINT_T__ new,
+ ETHR_AINT_T__ old)
{
-
-#ifdef ETHR_HAVE_INTERLOCKEDCOMPAREEXCHANGE_REL
- return (long) _InterlockedCompareExchange_rel(&var->value, (LONG) new, (LONG) old);
-#else
- return (long) _InterlockedCompareExchange(&var->value, (LONG) new, (LONG) old);
-#endif
+ return ETHR_ILCKD_REL__(CompareExchange)(&var->value, new, old);
}
-#endif
+#endif /* ETHR_TRY_INLINE_FUNCS */
-#endif
+#undef ETHR_ILCKD__
+#undef ETHR_ILCKD_ACQ__
+#undef ETHR_ILCKD_REL__
+#undef ETHR_NATMC_FUNC__
+#undef ETHR_ATMC_T__
+#undef ETHR_AINT_T__
+#undef ETHR_READ_AND_SET_WITHOUT_INTERLOCKED_OP__
+#undef ETHR_READ_ACQB_AND_SET_RELB_COMPILER_BARRIER_ONLY__
+
+#endif /* _MSC_VER */
+
+#endif /* ETHR_INCLUDE_ATOMIC_IMPL__ */
diff --git a/erts/include/internal/win/ethr_event.h b/erts/include/internal/win/ethr_event.h
index af57c20f91..598816b2c6 100644
--- a/erts/include/internal/win/ethr_event.h
+++ b/erts/include/internal/win/ethr_event.h
@@ -21,22 +21,24 @@
* Author: Rickard Green
*/
-#define ETHR_EVENT_OFF_WAITER__ ((LONG) -1)
-#define ETHR_EVENT_OFF__ ((LONG) 1)
-#define ETHR_EVENT_ON__ ((LONG) 0)
+#define ETHR_EVENT_OFF_WAITER__ ((long) -1)
+#define ETHR_EVENT_OFF__ ((long) 1)
+#define ETHR_EVENT_ON__ ((long) 0)
typedef struct {
- volatile LONG state;
+ volatile long state;
HANDLE handle;
} ethr_event;
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__)
+#pragma intrinsic(_InterlockedExchange)
+
static ETHR_INLINE void
ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e)
{
- /* InterlockedExchange() imply a full memory barrier which is important */
- LONG state = InterlockedExchange(&e->state, ETHR_EVENT_ON__);
+ /* _InterlockedExchange() imply a full memory barrier which is important */
+ long state = _InterlockedExchange(&e->state, ETHR_EVENT_ON__);
if (state == ETHR_EVENT_OFF_WAITER__) {
if (!SetEvent(e->handle))
ETHR_FATAL_ERROR__(ethr_win_get_errno__());
@@ -46,7 +48,7 @@ ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e)
static ETHR_INLINE void
ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e)
{
- /* InterlockedExchange() imply a full memory barrier which is important */
+ /* _InterlockedExchange() imply a full memory barrier which is important */
InterlockedExchange(&e->state, ETHR_EVENT_OFF__);
}
diff --git a/erts/include/internal/win/ethread.h b/erts/include/internal/win/ethread.h
index b52710f6a3..c01b17cf14 100644
--- a/erts/include/internal/win/ethread.h
+++ b/erts/include/internal/win/ethread.h
@@ -25,7 +25,11 @@
#ifndef ETHREAD_WIN_H__
#define ETHREAD_WIN_H__
+#define ETHR_ATOMIC_WANT_32BIT_IMPL__
#include "ethr_atomic.h"
-#define ETHR_HAVE_NATIVE_ATOMICS 1
+#if ETHR_SIZEOF_PTR == 8
+# define ETHR_ATOMIC_WANT_64BIT_IMPL__
+# include "ethr_atomic.h"
+#endif
#endif
diff --git a/erts/lib_src/Makefile.in b/erts/lib_src/Makefile.in
index 0d3181cace..757b3b24e2 100644
--- a/erts/lib_src/Makefile.in
+++ b/erts/lib_src/Makefile.in
@@ -283,6 +283,7 @@ endif
ETHR_THR_LIB_BASE_DIR=@ETHR_THR_LIB_BASE_DIR@
ifneq ($(strip $(ETHR_LIB_NAME)),)
ETHREAD_LIB_SRC=common/ethr_aux.c \
+ common/ethr_atomics.c \
common/ethr_mutex.c \
common/ethr_cbf.c \
$(ETHR_THR_LIB_BASE_DIR)/ethread.c \
@@ -381,6 +382,11 @@ $(ERTS_LIB): $(ERTS_LIB_OBJS)
# Object files
#
+ifeq ($(TYPE)-@GCC@,debug-yes)
+$(r_OBJ_DIR)/ethr_aux.o: common/ethr_aux.c
+ $(CC) $(THR_DEFS) $(CFLAGS) -Wno-unused-function $(INCLUDES) -c $< -o $@
+endif
+
$(r_OBJ_DIR)/%.o: common/%.c
$(CC) $(THR_DEFS) $(CFLAGS) $(INCLUDES) -c $< -o $@
@@ -445,6 +451,7 @@ INTERNAL_RELEASE_INCLUDES= \
$(ERTS_INCL_INT)/ethread.h \
$(ERTS_INCL_INT)/ethr_mutex.h \
$(ERTS_INCL_INT)/ethr_optimized_fallbacks.h \
+ $(ERTS_INCL_INT)/ethr_atomics.h \
$(ERTS_INCL_INT)/$(TARGET)/ethread.mk \
$(ERTS_INCL_INT)/$(TARGET)/erts_internal.mk \
$(ERTS_INCL_INT)/$(TARGET)/ethread_header_config.h \
diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c
index 116c9886d8..4c881993a5 100644
--- a/erts/lib_src/common/erl_misc_utils.c
+++ b/erts/lib_src/common/erl_misc_utils.c
@@ -71,6 +71,19 @@
(CPUSET)) != 0 ? -errno : 0)
#define ERTS_MU_SET_THR_AFFINITY__(SETP) \
(sched_setaffinity(0, sizeof(cpu_set_t), (SETP)) != 0 ? -errno : 0)
+#elif defined(HAVE_CPUSET_xETAFFINITY)
+# include <sys/param.h>
+# include <sys/cpuset.h>
+# define ERTS_HAVE_MISC_UTIL_AFFINITY_MASK__
+#define ERTS_MU_GET_PROC_AFFINITY__(CPUINFOP, CPUSET) \
+ (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, \
+ sizeof(cpuset_t), \
+ (CPUSET)) != 0 ? -errno : 0)
+#define ERTS_MU_SET_THR_AFFINITY__(CPUSETP) \
+ (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, \
+ sizeof(cpuset_t), \
+ (CPUSETP)) != 0 ? -errno : 0)
+# define cpu_set_t cpuset_t
#elif defined(__WIN32__)
# define ERTS_HAVE_MISC_UTIL_AFFINITY_MASK__
# define cpu_set_t DWORD
@@ -100,6 +113,11 @@
# define ERTS_SYS_CPU_PATH "/sys/devices/system/cpu"
#endif
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+
static int read_topology(erts_cpu_info_t *cpuinfo);
#if defined(ERTS_HAVE_MISC_UTIL_AFFINITY_MASK__)
@@ -1228,7 +1246,10 @@ read_topology(erts_cpu_info_t *cpuinfo)
nodes++;
}
- core_id = malloc(sizeof(int)*(packages ? packages : 1));
+ if (!packages) {
+ packages = 1;
+ }
+ core_id = malloc(sizeof(int)*packages);
if (!core_id) {
res = -ENOMEM;
goto error;
@@ -1286,11 +1307,13 @@ read_topology(erts_cpu_info_t *cpuinfo)
* Nodes and packages may not be supported; pretend
* that there are one if this is the case...
*/
- if (!nodes)
- cpuinfo->topology[l].node = 0;
- if (!packages)
- cpuinfo->topology[l].processor = 0;
if (slpip[rix].ProcessorMask & (((ULONG_PTR) 1) << l)) {
+ if (!nodes) {
+ cpuinfo->topology[l].node = 0;
+ }
+ if (!packages) {
+ cpuinfo->topology[l].processor = 0;
+ }
if (processor < 0) {
processor = cpuinfo->topology[l].processor;
if (processor < 0) {
@@ -1375,6 +1398,245 @@ read_topology(erts_cpu_info_t *cpuinfo)
return res;
}
+#elif defined(__FreeBSD__)
+
+/**
+ * FreeBSD topology detection is based on kern.sched.topology_spec XML as
+ * exposed by the ULE scheduler and described in SMP(4). It is available in
+ * 8.0 and higher.
+ *
+ * Threads are identified in this XML chunk with a THREAD flag. The function
+ * (simplistically) distinguishes cores and processors by the amount of cache
+ * they share (0 => processor, otherwise => core). Nodes are not identified
+ * (ULE doesn't handle NUMA yet, I believe).
+ */
+
+/**
+ * Recursively parse a topology_spec <group> tag.
+ */
+static
+const char* parse_topology_spec_group(erts_cpu_info_t *cpuinfo, const char* xml, int parentCacheLevel, int* processor_p, int* core_p, int* index_procs_p) {
+ int error = 0;
+ int cacheLevel = parentCacheLevel;
+ const char* next_group_start = strstr(xml + 1, "<group");
+ int is_thread_group = 0;
+ const char* next_cache_level;
+ const char* next_thread_flag;
+ const char* next_group_end;
+ const char* next_children;
+ const char* next_children_end;
+
+ /* parse the cache level */
+ next_cache_level = strstr(xml, "cache-level=\"");
+ if (next_cache_level && (next_group_start == NULL || next_cache_level < next_group_start)) {
+ sscanf(next_cache_level, "cache-level=\"%i\"", &cacheLevel);
+ }
+
+ /* parse the threads flag */
+ next_thread_flag = strstr(xml, "THREAD");
+ if (next_thread_flag && (next_group_start == NULL || next_thread_flag < next_group_start))
+ is_thread_group = 1;
+
+ /* Determine if it's a leaf with the position of the next children tag */
+ next_group_end = strstr(xml, "</group>");
+ next_children = strstr(xml, "<children>");
+ next_children_end = strstr(xml, "</children>");
+ if (next_children == NULL || next_group_end < next_children) {
+ do {
+ const char* next_cpu_start;
+ const char* next_cpu_cdata;
+ const char* next_cpu_end;
+ int cpu_str_size;
+ char* cpu_str;
+ char* cpu_crsr;
+ char* brkb;
+ int thread = 0;
+ int index_procs = *index_procs_p;
+
+ next_cpu_start = strstr(xml, "<cpu");
+ if (!next_cpu_start) {
+ error = 1;
+ break;
+ }
+ next_cpu_cdata = strstr(next_cpu_start, ">") + 1;
+ if (!next_cpu_cdata) {
+ error = 1;
+ break;
+ }
+ next_cpu_end = strstr(next_cpu_cdata, "</cpu>");
+ if (!next_cpu_end) {
+ error = 1;
+ break;
+ }
+ cpu_str_size = next_cpu_end - next_cpu_cdata;
+ cpu_str = (char*) malloc(cpu_str_size + 1);
+ memcpy(cpu_str, (const char*) next_cpu_cdata, cpu_str_size);
+ cpu_str[cpu_str_size] = 0;
+ for (cpu_crsr = strtok_r(cpu_str, " \t,", &brkb); cpu_crsr; cpu_crsr = strtok_r(NULL, " \t,", &brkb)) {
+ int cpu_id;
+ if (index_procs >= cpuinfo->configured) {
+ void* t = realloc(cpuinfo->topology, (sizeof(erts_cpu_topology_t) * (index_procs + 1)));
+ if (t) {
+ cpuinfo->topology = t;
+ } else {
+ error = 1;
+ break;
+ }
+ }
+ cpu_id = atoi(cpu_crsr);
+ cpuinfo->topology[index_procs].node = -1;
+ cpuinfo->topology[index_procs].processor = *processor_p;
+ cpuinfo->topology[index_procs].processor_node = -1;
+ cpuinfo->topology[index_procs].core = *core_p;
+ cpuinfo->topology[index_procs].thread = thread;
+ cpuinfo->topology[index_procs].logical = cpu_id;
+ if (is_thread_group) {
+ thread++;
+ } else {
+ *core_p = (*core_p)++;
+ }
+ index_procs++;
+ }
+ *index_procs_p = index_procs;
+ free(cpu_str);
+ } while (0);
+ xml = next_group_end;
+ } else {
+ while (next_group_start != NULL && next_group_start < next_children_end) {
+ xml = parse_topology_spec_group(cpuinfo, next_group_start, cacheLevel, processor_p, core_p, index_procs_p);
+ if (!xml)
+ break;
+ next_group_start = strstr(xml, "<group");
+ next_children_end = strstr(xml, "</children>");
+ }
+ }
+
+ if (cacheLevel == 0) {
+ *core_p = 0;
+ *processor_p = (*processor_p)++;
+ } else {
+ *core_p = (*core_p)++;
+ }
+
+ if (error)
+ xml = NULL;
+
+ return xml;
+}
+
+/**
+ * Parse the topology_spec. Return the number of CPUs or 0 if parsing failed.
+ */
+static
+int parse_topology_spec(erts_cpu_info_t *cpuinfo, const char* xml) {
+ int res = 1;
+ int index_procs = 0;
+ int core = 0;
+ int processor = 0;
+ xml = strstr(xml, "<groups");
+ if (!xml)
+ return -1;
+
+ xml += 7;
+ xml = strstr(xml, "<group");
+ while (xml) {
+ xml = parse_topology_spec_group(cpuinfo, xml, 0, &processor, &core, &index_procs);
+ if (!xml) {
+ res = 0;
+ break;
+ }
+ xml = strstr(xml, "<group");
+ }
+
+ if (res)
+ res = index_procs;
+
+ return res;
+}
+
+static int
+read_topology(erts_cpu_info_t *cpuinfo)
+{
+ int ix;
+ int res = 0;
+ size_t topology_spec_size = 0;
+ void* topology_spec = NULL;
+
+ errno = 0;
+
+ if (cpuinfo->configured < 1)
+ goto error;
+
+ cpuinfo->topology_size = cpuinfo->configured;
+ cpuinfo->topology = malloc(sizeof(erts_cpu_topology_t)
+ * cpuinfo->configured);
+ if (!cpuinfo->topology) {
+ res = -ENOMEM;
+ goto error;
+ }
+
+ for (ix = 0; ix < cpuinfo->configured; ix++) {
+ cpuinfo->topology[ix].node = -1;
+ cpuinfo->topology[ix].processor = -1;
+ cpuinfo->topology[ix].processor_node = -1;
+ cpuinfo->topology[ix].core = -1;
+ cpuinfo->topology[ix].thread = -1;
+ cpuinfo->topology[ix].logical = -1;
+ }
+
+ if (!sysctlbyname("kern.sched.topology_spec", NULL, &topology_spec_size, NULL, 0)) {
+ topology_spec = malloc(topology_spec_size);
+ if (!topology_spec) {
+ res = -ENOMEM;
+ goto error;
+ }
+
+ if (sysctlbyname("kern.sched.topology_spec", topology_spec, &topology_spec_size, NULL, 0)) {
+ goto error;
+ }
+
+ res = parse_topology_spec(cpuinfo, topology_spec);
+ if (!res || res < cpuinfo->online)
+ res = 0;
+ else {
+ cpuinfo->topology_size = res;
+
+ if (cpuinfo->topology_size != cpuinfo->configured) {
+ void *t = realloc(cpuinfo->topology, (sizeof(erts_cpu_topology_t)
+ * cpuinfo->topology_size));
+ if (t)
+ cpuinfo->topology = t;
+ }
+
+ adjust_processor_nodes(cpuinfo, 1);
+
+ qsort(cpuinfo->topology,
+ cpuinfo->topology_size,
+ sizeof(erts_cpu_topology_t),
+ cpu_cmp);
+ }
+ }
+
+error:
+
+ if (res == 0) {
+ cpuinfo->topology_size = 0;
+ if (cpuinfo->topology) {
+ free(cpuinfo->topology);
+ cpuinfo->topology = NULL;
+ }
+ if (errno)
+ res = -errno;
+ else
+ res = -EINVAL;
+ }
+
+ if (topology_spec)
+ free(topology_spec);
+
+ return res;
+}
+
#else
static int
diff --git a/erts/lib_src/common/ethr_atomics.c b/erts/lib_src/common/ethr_atomics.c
new file mode 100644
index 0000000000..94557d904a
--- /dev/null
+++ b/erts/lib_src/common/ethr_atomics.c
@@ -0,0 +1,402 @@
+/*
+ * %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: The ethread atomic API
+ * Author: Rickard Green
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define ETHR_INLINE_FUNC_NAME_(X) X ## __
+#define ETHR_ATOMIC_IMPL__
+
+#include "ethread.h"
+#include "ethr_internal.h"
+
+#ifndef ETHR_HAVE_NATIVE_ATOMICS
+ethr_atomic_protection_t ethr_atomic_protection__[1 << ETHR_ATOMIC_ADDR_BITS];
+#endif
+
+int
+ethr_init_atomics(void)
+{
+#ifndef ETHR_HAVE_NATIVE_ATOMICS
+ {
+ int i;
+ for (i = 0; i < (1 << ETHR_ATOMIC_ADDR_BITS); i++) {
+ int res = ethr_spinlock_init(&ethr_atomic_protection__[i].u.lck);
+ if (res != 0)
+ return res;
+ }
+ }
+#endif
+ return 0;
+}
+
+/*
+ * --- Pointer size atomics ---------------------------------------------------
+ */
+
+ethr_sint_t *
+ethr_atomic_addr(ethr_atomic_t *var)
+{
+ ETHR_ASSERT(var);
+ return ethr_atomic_addr__(var);
+}
+
+void
+ethr_atomic_init(ethr_atomic_t *var, ethr_sint_t i)
+{
+ ETHR_ASSERT(var);
+ ethr_atomic_init__(var, i);
+}
+
+void
+ethr_atomic_set(ethr_atomic_t *var, ethr_sint_t i)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic_set__(var, i);
+}
+
+ethr_sint_t
+ethr_atomic_read(ethr_atomic_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_read__(var);
+}
+
+ethr_sint_t
+ethr_atomic_add_read(ethr_atomic_t *var, ethr_sint_t incr)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_add_read__(var, incr);
+}
+
+ethr_sint_t
+ethr_atomic_inc_read(ethr_atomic_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_inc_read__(var);
+}
+
+ethr_sint_t
+ethr_atomic_dec_read(ethr_atomic_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_dec_read__(var);
+}
+
+void
+ethr_atomic_add(ethr_atomic_t *var, ethr_sint_t incr)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic_add__(var, incr);
+}
+
+void
+ethr_atomic_inc(ethr_atomic_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic_inc__(var);
+}
+
+void
+ethr_atomic_dec(ethr_atomic_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic_dec__(var);
+}
+
+ethr_sint_t
+ethr_atomic_read_band(ethr_atomic_t *var, ethr_sint_t mask)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_read_band__(var, mask);
+}
+
+ethr_sint_t
+ethr_atomic_read_bor(ethr_atomic_t *var, ethr_sint_t mask)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_read_bor__(var, mask);
+}
+
+ethr_sint_t
+ethr_atomic_xchg(ethr_atomic_t *var, ethr_sint_t new)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_xchg__(var, new);
+}
+
+ethr_sint_t
+ethr_atomic_cmpxchg(ethr_atomic_t *var, ethr_sint_t new, ethr_sint_t expected)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_cmpxchg__(var, new, expected);
+}
+
+ethr_sint_t
+ethr_atomic_read_acqb(ethr_atomic_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_read_acqb__(var);
+}
+
+ethr_sint_t
+ethr_atomic_inc_read_acqb(ethr_atomic_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_inc_read_acqb__(var);
+}
+
+void
+ethr_atomic_set_relb(ethr_atomic_t *var, ethr_sint_t i)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic_set_relb__(var, i);
+}
+
+void
+ethr_atomic_dec_relb(ethr_atomic_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic_dec_relb__(var);
+}
+
+ethr_sint_t
+ethr_atomic_dec_read_relb(ethr_atomic_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_dec_read_relb__(var);
+}
+
+ethr_sint_t
+ethr_atomic_cmpxchg_acqb(ethr_atomic_t *var, ethr_sint_t new, ethr_sint_t exp)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_cmpxchg_acqb__(var, new, exp);
+}
+
+ethr_sint_t
+ethr_atomic_cmpxchg_relb(ethr_atomic_t *var, ethr_sint_t new, ethr_sint_t exp)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic_cmpxchg_relb__(var, new, exp);
+}
+
+
+/*
+ * --- 32-bit atomics ---------------------------------------------------------
+ */
+
+ethr_sint32_t *
+ethr_atomic32_addr(ethr_atomic32_t *var)
+{
+ ETHR_ASSERT(var);
+ return ethr_atomic32_addr__(var);
+}
+
+void
+ethr_atomic32_init(ethr_atomic32_t *var, ethr_sint32_t i)
+{
+ ETHR_ASSERT(var);
+ ethr_atomic32_init__(var, i);
+}
+
+void
+ethr_atomic32_set(ethr_atomic32_t *var, ethr_sint32_t i)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic32_set__(var, i);
+}
+
+ethr_sint32_t
+ethr_atomic32_read(ethr_atomic32_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_read__(var);
+}
+
+
+ethr_sint32_t
+ethr_atomic32_add_read(ethr_atomic32_t *var, ethr_sint32_t incr)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_add_read__(var, incr);
+}
+
+ethr_sint32_t
+ethr_atomic32_inc_read(ethr_atomic32_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_inc_read__(var);
+}
+
+ethr_sint32_t
+ethr_atomic32_dec_read(ethr_atomic32_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_dec_read__(var);
+}
+
+void
+ethr_atomic32_add(ethr_atomic32_t *var, ethr_sint32_t incr)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic32_add__(var, incr);
+}
+
+void
+ethr_atomic32_inc(ethr_atomic32_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic32_inc__(var);
+}
+
+void
+ethr_atomic32_dec(ethr_atomic32_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic32_dec__(var);
+}
+
+ethr_sint32_t
+ethr_atomic32_read_band(ethr_atomic32_t *var, ethr_sint32_t mask)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_read_band__(var, mask);
+}
+
+ethr_sint32_t
+ethr_atomic32_read_bor(ethr_atomic32_t *var, ethr_sint32_t mask)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_read_bor__(var, mask);
+}
+
+ethr_sint32_t
+ethr_atomic32_xchg(ethr_atomic32_t *var, ethr_sint32_t new)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_xchg__(var, new);
+}
+
+ethr_sint32_t
+ethr_atomic32_cmpxchg(ethr_atomic32_t *var,
+ ethr_sint32_t new,
+ ethr_sint32_t expected)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_cmpxchg__(var, new, expected);
+}
+
+ethr_sint32_t
+ethr_atomic32_read_acqb(ethr_atomic32_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_read_acqb__(var);
+}
+
+ethr_sint32_t
+ethr_atomic32_inc_read_acqb(ethr_atomic32_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_inc_read_acqb__(var);
+}
+
+void
+ethr_atomic32_set_relb(ethr_atomic32_t *var, ethr_sint32_t i)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic32_set_relb__(var, i);
+}
+
+void
+ethr_atomic32_dec_relb(ethr_atomic32_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ ethr_atomic32_dec_relb__(var);
+}
+
+ethr_sint32_t
+ethr_atomic32_dec_read_relb(ethr_atomic32_t *var)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_dec_read_relb__(var);
+}
+
+ethr_sint32_t
+ethr_atomic32_cmpxchg_acqb(ethr_atomic32_t *var,
+ ethr_sint32_t new,
+ ethr_sint32_t exp)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_cmpxchg_acqb__(var, new, exp);
+}
+
+ethr_sint32_t
+ethr_atomic32_cmpxchg_relb(ethr_atomic32_t *var,
+ ethr_sint32_t new,
+ ethr_sint32_t exp)
+{
+ ETHR_ASSERT(!ethr_not_inited__);
+ ETHR_ASSERT(var);
+ return ethr_atomic32_cmpxchg_relb__(var, new, exp);
+}
+
diff --git a/erts/lib_src/common/ethr_aux.c b/erts/lib_src/common/ethr_aux.c
index 4db4cffd3a..2c3e25a805 100644
--- a/erts/lib_src/common/ethr_aux.c
+++ b/erts/lib_src/common/ethr_aux.c
@@ -31,7 +31,10 @@
#define ETHR_INLINE_FUNC_NAME_(X) X ## __
#define ETHR_AUX_IMPL__
-
+#define ETHR_ATOMIC_IMPL__ /* Needed in order to pull in
+ native atomic implementations
+ for optimized fallbacks of
+ spinlocks and rwspinlocks */
#include "ethread.h"
#include "ethr_internal.h"
#include <string.h>
@@ -51,10 +54,6 @@ int ethr_not_inited__ = 1;
ethr_memory_allocators ethr_mem__ = ETHR_MEM_ALLOCS_DEF_INITER__;
-#ifndef ETHR_HAVE_OPTIMIZED_ATOMIC_OPS
-ethr_atomic_protection_t ethr_atomic_protection__[1 << ETHR_ATOMIC_ADDR_BITS];
-#endif
-
void *(*ethr_thr_prepare_func__)(void) = NULL;
void (*ethr_thr_parent_func__)(void *) = NULL;
void (*ethr_thr_child_func__)(void *) = NULL;
@@ -138,16 +137,9 @@ ethr_init_common__(ethr_init_data *id)
#endif
ethr_max_stack_size__ = ETHR_B2KW(ethr_max_stack_size__);
-#ifndef ETHR_HAVE_OPTIMIZED_ATOMIC_OPS
- {
- int i;
- for (i = 0; i < (1 << ETHR_ATOMIC_ADDR_BITS); i++) {
- res = ethr_spinlock_init(&ethr_atomic_protection__[i].u.lck);
- if (res != 0)
- return res;
- }
- }
-#endif
+ res = ethr_init_atomics();
+ if (res != 0)
+ return res;
res = ethr_mutex_lib_init(erts_get_cpu_configured(ethr_cpu_info__));
if (res != 0)
@@ -279,14 +271,6 @@ typedef union {
static ethr_spinlock_t ts_ev_alloc_lock;
static ethr_ts_event *free_ts_ev;
-#if SIZEOF_VOID_P == SIZEOF_INT
-typedef unsigned int EthrPtrSzUInt;
-#elif SIZEOF_VOID_P == SIZEOF_LONG
-typedef unsigned long EthrPtrSzUInt;
-#else
-#error No pointer sized integer type
-#endif
-
static ethr_ts_event *ts_event_pool(int size, ethr_ts_event **endpp)
{
int i;
@@ -295,16 +279,16 @@ static ethr_ts_event *ts_event_pool(int size, ethr_ts_event **endpp)
+ ETHR_CACHE_LINE_SIZE);
if (!atsev)
return NULL;
- if ((((EthrPtrSzUInt) atsev) & ETHR_CACHE_LINE_MASK) == 0)
+ if ((((ethr_uint_t) atsev) & ETHR_CACHE_LINE_MASK) == 0)
atsev = ((ethr_aligned_ts_event *)
- ((((EthrPtrSzUInt) atsev) & ~ETHR_CACHE_LINE_MASK)
+ ((((ethr_uint_t) atsev) & ~ETHR_CACHE_LINE_MASK)
+ ETHR_CACHE_LINE_SIZE));
for (i = 1; i < size; i++) {
atsev[i-1].ts_ev.next = &atsev[i].ts_ev;
- ethr_atomic_init(&atsev[i-1].ts_ev.uaflgs, 0);
+ ethr_atomic32_init(&atsev[i-1].ts_ev.uaflgs, 0);
atsev[i-1].ts_ev.iflgs = 0;
}
- ethr_atomic_init(&atsev[size-1].ts_ev.uaflgs, 0);
+ ethr_atomic32_init(&atsev[size-1].ts_ev.uaflgs, 0);
atsev[size-1].ts_ev.iflgs = 0;
atsev[size-1].ts_ev.next = NULL;
if (endpp)
@@ -466,170 +450,6 @@ int ethr_get_main_thr_status(int *on)
return 0;
}
-
-/* Atomics */
-
-void
-ethr_atomic_init(ethr_atomic_t *var, long i)
-{
- ETHR_ASSERT(var);
- ethr_atomic_init__(var, i);
-}
-
-void
-ethr_atomic_set(ethr_atomic_t *var, long i)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- ethr_atomic_set__(var, i);
-}
-
-long
-ethr_atomic_read(ethr_atomic_t *var)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_read__(var);
-}
-
-
-long
-ethr_atomic_add_read(ethr_atomic_t *var, long incr)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_add_read__(var, incr);
-}
-
-long
-ethr_atomic_inc_read(ethr_atomic_t *var)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_inc_read__(var);
-}
-
-long
-ethr_atomic_dec_read(ethr_atomic_t *var)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_dec_read__(var);
-}
-
-void
-ethr_atomic_add(ethr_atomic_t *var, long incr)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- ethr_atomic_add__(var, incr);
-}
-
-void
-ethr_atomic_inc(ethr_atomic_t *var)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- ethr_atomic_inc__(var);
-}
-
-void
-ethr_atomic_dec(ethr_atomic_t *var)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- ethr_atomic_dec__(var);
-}
-
-long
-ethr_atomic_read_band(ethr_atomic_t *var, long mask)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_read_band__(var, mask);
-}
-
-long
-ethr_atomic_read_bor(ethr_atomic_t *var, long mask)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_read_bor__(var, mask);
-}
-
-long
-ethr_atomic_xchg(ethr_atomic_t *var, long new)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_xchg__(var, new);
-}
-
-long
-ethr_atomic_cmpxchg(ethr_atomic_t *var, long new, long expected)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_cmpxchg__(var, new, expected);
-}
-
-long
-ethr_atomic_read_acqb(ethr_atomic_t *var)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_read_acqb__(var);
-}
-
-long
-ethr_atomic_inc_read_acqb(ethr_atomic_t *var)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_inc_read_acqb__(var);
-}
-
-void
-ethr_atomic_set_relb(ethr_atomic_t *var, long i)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- ethr_atomic_set_relb__(var, i);
-}
-
-void
-ethr_atomic_dec_relb(ethr_atomic_t *var)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- ethr_atomic_dec_relb__(var);
-}
-
-long
-ethr_atomic_dec_read_relb(ethr_atomic_t *var)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_dec_read_relb__(var);
-}
-
-long
-ethr_atomic_cmpxchg_acqb(ethr_atomic_t *var, long new, long exp)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_cmpxchg_acqb__(var, new, exp);
-}
-
-long
-ethr_atomic_cmpxchg_relb(ethr_atomic_t *var, long new, long exp)
-{
- ETHR_ASSERT(!ethr_not_inited__);
- ETHR_ASSERT(var);
- return ethr_atomic_cmpxchg_relb__(var, new, exp);
-}
-
-
/* Spinlocks and rwspinlocks */
int
diff --git a/erts/lib_src/common/ethr_mutex.c b/erts/lib_src/common/ethr_mutex.c
index 78323b62a3..2ddef32dfc 100644
--- a/erts/lib_src/common/ethr_mutex.c
+++ b/erts/lib_src/common/ethr_mutex.c
@@ -205,12 +205,17 @@ static void hard_debug_chk_q__(struct ethr_mutex_base_ *, int);
#ifdef ETHR_USE_OWN_RWMTX_IMPL__
static void
+rwmutex_transfer_read_lock(ethr_rwmutex *rwmtx,
+ ethr_sint32_t initial,
+ int q_locked);
+static void
rwmutex_unlock_wake(ethr_rwmutex *rwmtx,
int have_w,
- long initial);
+ ethr_sint32_t initial,
+ int transfer_read_lock);
static int
rwmutex_try_complete_runlock(ethr_rwmutex *rwmtx,
- long initial,
+ ethr_sint32_t initial,
ethr_ts_event *tse,
int start_next_ix,
int check_before_try,
@@ -237,12 +242,12 @@ rwmutex_freqread_rdrs_add(ethr_rwmutex *rwmtx,
int inc)
{
if (type == ETHR_RWMUTEX_TYPE_FREQUENT_READ || ix == 0)
- ethr_atomic_add(&rwmtx->tdata.ra[ix].data.readers, inc);
+ ethr_atomic32_add(&rwmtx->tdata.ra[ix].data.readers, inc);
else {
ETHR_ASSERT(type == ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ);
- ETHR_ASSERT(ethr_atomic_read(&rwmtx->tdata.ra[ix].data.readers) == 0);
+ ETHR_ASSERT(ethr_atomic32_read(&rwmtx->tdata.ra[ix].data.readers) == 0);
ETHR_ASSERT(inc == 1);
- ethr_atomic_set(&rwmtx->tdata.ra[ix].data.readers, (long) 1);
+ ethr_atomic32_set(&rwmtx->tdata.ra[ix].data.readers, (ethr_sint32_t) 1);
}
}
@@ -253,18 +258,20 @@ rwmutex_freqread_rdrs_inc(ethr_rwmutex *rwmtx, ethr_ts_event *tse)
if (rwmtx->type == ETHR_RWMUTEX_TYPE_FREQUENT_READ) {
ix = tse->rgix;
atomic_inc:
- ethr_atomic_inc(&rwmtx->tdata.ra[ix].data.readers);
+ ethr_atomic32_inc(&rwmtx->tdata.ra[ix].data.readers);
}
else {
ix = tse->mtix;
if (ix == 0)
goto atomic_inc;
ETHR_ASSERT(rwmtx->type == ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ);
- ETHR_ASSERT(ethr_atomic_read(&rwmtx->tdata.ra[ix].data.readers) == 0);
- ethr_atomic_set(&rwmtx->tdata.ra[ix].data.readers, (long) 1);
+ ETHR_ASSERT(ethr_atomic32_read(&rwmtx->tdata.ra[ix].data.readers) == 0);
+ ethr_atomic32_set(&rwmtx->tdata.ra[ix].data.readers, (ethr_sint32_t) 1);
}
}
+#if 0 /* Not used */
+
static ETHR_INLINE void
rwmutex_freqread_rdrs_dec(ethr_rwmutex *rwmtx, ethr_ts_event *tse)
{
@@ -272,69 +279,72 @@ rwmutex_freqread_rdrs_dec(ethr_rwmutex *rwmtx, ethr_ts_event *tse)
if (rwmtx->type == ETHR_RWMUTEX_TYPE_FREQUENT_READ) {
ix = tse->rgix;
atomic_dec:
- ethr_atomic_dec(&rwmtx->tdata.ra[ix].data.readers);
+ ethr_atomic32_dec(&rwmtx->tdata.ra[ix].data.readers);
}
else {
ix = tse->mtix;
if (ix == 0)
goto atomic_dec;
ETHR_ASSERT(rwmtx->type == ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ);
- ETHR_ASSERT(ethr_atomic_read(&rwmtx->tdata.ra[ix].data.readers) == 1);
- ethr_atomic_set(&rwmtx->tdata.ra[ix].data.readers, (long) 0);
+ ETHR_ASSERT(ethr_atomic32_read(&rwmtx->tdata.ra[ix].data.readers) == 1);
+ ethr_atomic32_set(&rwmtx->tdata.ra[ix].data.readers, (ethr_sint32_t) 0);
}
}
-static ETHR_INLINE long
+#endif
+
+static ETHR_INLINE ethr_sint32_t
rwmutex_freqread_rdrs_dec_read(ethr_rwmutex *rwmtx, ethr_ts_event *tse)
{
int ix;
if (rwmtx->type == ETHR_RWMUTEX_TYPE_FREQUENT_READ) {
ix = tse->rgix;
atomic_dec_read:
- return ethr_atomic_dec_read(&rwmtx->tdata.ra[ix].data.readers);
+ return ethr_atomic32_dec_read(&rwmtx->tdata.ra[ix].data.readers);
}
else {
ix = tse->mtix;
if (ix == 0)
goto atomic_dec_read;
ETHR_ASSERT(rwmtx->type == ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ);
- ETHR_ASSERT(ethr_atomic_read(&rwmtx->tdata.ra[ix].data.readers) == 1);
- ethr_atomic_set(&rwmtx->tdata.ra[ix].data.readers, (long) 0);
- return (long) 0;
+ ETHR_ASSERT(ethr_atomic32_read(&rwmtx->tdata.ra[ix].data.readers) == 1);
+ ethr_atomic32_set(&rwmtx->tdata.ra[ix].data.readers, (ethr_sint32_t) 0);
+ return (ethr_sint32_t) 0;
}
}
-static ETHR_INLINE long
+static ETHR_INLINE ethr_sint32_t
rwmutex_freqread_rdrs_dec_read_relb(ethr_rwmutex *rwmtx, ethr_ts_event *tse)
{
int ix;
if (rwmtx->type == ETHR_RWMUTEX_TYPE_FREQUENT_READ) {
ix = tse->rgix;
atomic_dec_read:
- return ethr_atomic_dec_read_relb(&rwmtx->tdata.ra[ix].data.readers);
+ return ethr_atomic32_dec_read_relb(&rwmtx->tdata.ra[ix].data.readers);
}
else {
ix = tse->mtix;
if (ix == 0)
goto atomic_dec_read;
ETHR_ASSERT(rwmtx->type == ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ);
- ETHR_ASSERT(ethr_atomic_read(&rwmtx->tdata.ra[ix].data.readers) == 1);
- ethr_atomic_set_relb(&rwmtx->tdata.ra[ix].data.readers, (long) 0);
- return (long) 0;
+ ETHR_ASSERT(ethr_atomic32_read(&rwmtx->tdata.ra[ix].data.readers) == 1);
+ ethr_atomic32_set_relb(&rwmtx->tdata.ra[ix].data.readers,
+ (ethr_sint32_t) 0);
+ return (ethr_sint32_t) 0;
}
}
-static ETHR_INLINE long
+static ETHR_INLINE ethr_sint32_t
rwmutex_freqread_rdrs_read(ethr_rwmutex *rwmtx, int ix)
{
- long res = ethr_atomic_read(&rwmtx->tdata.ra[ix].data.readers);
+ ethr_sint32_t res = ethr_atomic32_read(&rwmtx->tdata.ra[ix].data.readers);
#ifdef ETHR_DEBUG
switch (rwmtx->type) {
case ETHR_RWMUTEX_TYPE_FREQUENT_READ:
ETHR_ASSERT(res >= 0);
break;
case ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ:
- ETHR_ASSERT(res == 0 || res == 1);
+ ETHR_ASSERT(ix == 0 ? res >= 0 : (res == 0 || res == 1));
break;
default:
ETHR_ASSERT(0);
@@ -393,18 +403,19 @@ static void
event_wait(struct ethr_mutex_base_ *mtxb,
ethr_ts_event *tse,
int spincount,
- long type,
+ ethr_sint32_t type,
int is_rwmtx,
int is_freq_read)
{
int locked = 0;
- long act;
+ ethr_sint32_t act;
int need_try_complete_runlock = 0;
+ int transfer_read_lock = 0;
/* Need to enqueue and wait... */
tse->uflgs = type;
- ethr_atomic_set(&tse->uaflgs, type);
+ ethr_atomic32_set(&tse->uaflgs, type);
ETHR_MTX_Q_LOCK(&mtxb->qlck);
locked = 1;
@@ -413,7 +424,7 @@ event_wait(struct ethr_mutex_base_ *mtxb,
hard_debug_chk_q__(mtxb, is_rwmtx);
#endif
- act = ethr_atomic_read(&mtxb->flgs);
+ act = ethr_atomic32_read(&mtxb->flgs);
if (act & type) {
@@ -443,9 +454,9 @@ event_wait(struct ethr_mutex_base_ *mtxb,
/* Set wait bit */
while (1) {
- long new, exp = act;
- int freqread_tryrlock = 0;
+ ethr_sint32_t new, exp = act;
need_try_complete_runlock = 0;
+ transfer_read_lock = 0;
if (type == ETHR_RWMTX_W_WAIT_FLG__) {
if (is_freq_read && act == ETHR_RWMTX_R_FLG__)
@@ -465,19 +476,16 @@ event_wait(struct ethr_mutex_base_ *mtxb,
new = act + 1; /* Try to get it */
}
else {
- if (act & ~ETHR_RWMTX_R_FLG__)
- new = act | ETHR_RWMTX_R_WAIT_FLG__;
- else { /* Try to get it */
- ethr_rwmutex *rwmtx = (ethr_rwmutex *) mtxb;
- rwmutex_freqread_rdrs_inc(rwmtx, tse);
- ETHR_MEMORY_BARRIER;
- new = act | ETHR_RWMTX_R_FLG__;
- freqread_tryrlock = 1;
+ new = act | ETHR_RWMTX_R_WAIT_FLG__;
+ if ((act & (ETHR_RWMTX_W_FLG__
+ | ETHR_RWMTX_W_WAIT_FLG__)) == 0) {
+ /* Transfer read lock to this thread. */
+ transfer_read_lock = 1;
}
}
}
- act = ethr_atomic_cmpxchg_acqb(&mtxb->flgs, new, exp);
+ act = ethr_atomic32_cmpxchg_acqb(&mtxb->flgs, new, exp);
if (exp == act) {
if (new & type) {
act = new;
@@ -488,24 +496,6 @@ event_wait(struct ethr_mutex_base_ *mtxb,
goto done;
}
}
-
- if (freqread_tryrlock) {
- ethr_rwmutex *rwmtx = (ethr_rwmutex *) mtxb;
-
- /* We didn't set ETHR_RWMTX_R_FLG__, however someone
- else might have */
- if (act == ETHR_RWMTX_R_FLG__)
- goto done; /* Got it by help from someone else */
-
- ETHR_ASSERT((act & ETHR_RWMTX_WAIT_FLGS__) == 0);
- /*
- * We know that no waiter flags have been set, i.e.,
- * we cannot get into a situation where we need to wake
- * someone up here. Just restore the readers counter
- * and do it over again...
- */
- rwmutex_freqread_rdrs_dec(rwmtx, tse);
- }
}
/* Enqueue */
@@ -535,26 +525,42 @@ event_wait(struct ethr_mutex_base_ *mtxb,
/* Wait */
locked = 0;
- ETHR_MTX_Q_UNLOCK(&mtxb->qlck);
- if (need_try_complete_runlock) {
+ ETHR_ASSERT(!(transfer_read_lock && need_try_complete_runlock));
+
+ if (transfer_read_lock) {
ETHR_ASSERT(((ethr_rwmutex *) mtxb)->type
!= ETHR_RWMUTEX_TYPE_NORMAL);
/*
- * We were the only one in queue when we enqueued, and it
- * was seemingly read locked. We need to try to complete a
- * runlock otherwise we might be hanging forever. If the
- * runlock could be completed we will be dequeued and
- * woken by ourselves.
+ * We are the only one in the queue and we are not write
+ * locked; rwmutex_transfer_read_lock() will:
+ * - transfer a read lock to us (since we're first in q)
+ * - unlock the Q-lock
*/
- rwmutex_try_complete_runlock((ethr_rwmutex *) mtxb,
- act, tse, 0, 1, 0);
+ rwmutex_transfer_read_lock(((ethr_rwmutex *) mtxb), act, 1);
+ }
+ else {
+ ETHR_MTX_Q_UNLOCK(&mtxb->qlck);
+
+ if (need_try_complete_runlock) {
+ ETHR_ASSERT(((ethr_rwmutex *) mtxb)->type
+ != ETHR_RWMUTEX_TYPE_NORMAL);
+ /*
+ * We were the only one in queue when we enqueued, and it
+ * was seemingly read locked. We need to try to complete a
+ * runlock otherwise we might be hanging forever. If the
+ * runlock could be completed we will be dequeued and
+ * woken by ourselves.
+ */
+ rwmutex_try_complete_runlock((ethr_rwmutex *) mtxb,
+ act, tse, 0, 1, 0);
+ }
}
while (1) {
ethr_event_reset(&tse->event);
- act = ethr_atomic_read_acqb(&tse->uaflgs);
+ act = ethr_atomic32_read_acqb(&tse->uaflgs);
if (!act)
goto done; /* Got it */
@@ -562,7 +568,7 @@ event_wait(struct ethr_mutex_base_ *mtxb,
ethr_event_swait(&tse->event, spincount);
/* swait result: 0 || EINTR */
- act = ethr_atomic_read_acqb(&tse->uaflgs);
+ act = ethr_atomic32_read_acqb(&tse->uaflgs);
if (!act)
goto done; /* Got it */
}
@@ -582,7 +588,7 @@ wake_writer(struct ethr_mutex_base_ *mtxb, int is_rwmtx)
dequeue(&mtxb->q, tse, tse);
ETHR_ASSERT(tse->uflgs == ETHR_RWMTX_W_WAIT_FLG__);
- ETHR_ASSERT(ethr_atomic_read(&tse->uaflgs) == ETHR_RWMTX_W_WAIT_FLG__);
+ ETHR_ASSERT(ethr_atomic32_read(&tse->uaflgs) == ETHR_RWMTX_W_WAIT_FLG__);
#ifdef ETHR_MTX_HARD_DEBUG_WSQ
mtxb->ws--;
#endif
@@ -592,7 +598,7 @@ wake_writer(struct ethr_mutex_base_ *mtxb, int is_rwmtx)
ETHR_MTX_Q_UNLOCK(&mtxb->qlck);
- ethr_atomic_set(&tse->uaflgs, 0);
+ ethr_atomic32_set(&tse->uaflgs, 0);
ethr_event_set(&tse->event);
}
@@ -644,17 +650,15 @@ int check_readers_array(ethr_rwmutex *rwmtx,
static ETHR_INLINE void
write_lock_wait(struct ethr_mutex_base_ *mtxb,
- long initial,
+ ethr_sint32_t initial,
int is_rwmtx,
int is_freq_read)
{
- long act = initial;
+ ethr_sint32_t act = initial;
int scnt, start_scnt;
ethr_ts_event *tse = NULL;
int until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
int res;
- int freq_read_size = -1;
- int freq_read_start_ix = -1;
ETHR_ASSERT(!is_freq_read || is_rwmtx);
@@ -666,44 +670,23 @@ write_lock_wait(struct ethr_mutex_base_ *mtxb,
*/
while (1) {
- long exp;
-
while (act != 0) {
if (is_freq_read && act == ETHR_RWMTX_R_FLG__) {
ethr_rwmutex *rwmtx = (ethr_rwmutex *) mtxb;
+ scnt--;
if (!tse)
tse = ethr_get_ts_event();
- if (freq_read_size < 0) {
- if (rwmtx->type == ETHR_RWMUTEX_TYPE_FREQUENT_READ) {
- freq_read_size = reader_groups_array_size;
- freq_read_start_ix = tse->rgix;
- }
- else {
- freq_read_size = main_threads_array_size;
- freq_read_start_ix = tse->mtix;
- }
- }
- res = check_readers_array(rwmtx,
- freq_read_start_ix,
- freq_read_size);
- scnt--;
- if (res == 0) {
- act = ethr_atomic_read(&mtxb->flgs);
- if (act & ETHR_RWMTX_R_MASK__) {
- res = rwmutex_try_complete_runlock(rwmtx, act,
- tse, 0, 0,
- 1);
- if (res != EBUSY)
- goto done; /* Got it */
- }
- if (scnt <= 0)
- goto chk_spin;
- if (--until_yield == 0) {
- until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
- ETHR_YIELD();
- }
- continue;
+ res = rwmutex_try_complete_runlock(rwmtx, act,
+ tse, 0, 0,
+ 1);
+ if (res != EBUSY)
+ goto done; /* Got it */
+ if (scnt <= 0)
+ goto chk_spin;
+ if (--until_yield == 0) {
+ until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
+ ETHR_YIELD();
}
}
@@ -724,15 +707,13 @@ write_lock_wait(struct ethr_mutex_base_ *mtxb,
until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
ETHR_YIELD();
}
- act = ethr_atomic_read(&mtxb->flgs);
+ act = ethr_atomic32_read(&mtxb->flgs);
scnt--;
}
- exp = act;
-
- act = ethr_atomic_cmpxchg_acqb(&mtxb->flgs,
- ETHR_RWMTX_W_FLG__,
- exp);
+ act = ethr_atomic32_cmpxchg_acqb(&mtxb->flgs,
+ ETHR_RWMTX_W_FLG__,
+ 0);
if (act == 0)
goto done; /* Got it */
}
@@ -753,6 +734,7 @@ mtxb_init(struct ethr_mutex_base_ *mtxb,
#ifdef ETHR_MTX_HARD_DEBUG_WSQ
mtxb->ws = 0;
#endif
+ ETHR_MTX_CHK_EXCL_INIT(mtxb);
if (no_spin) {
mtxb->main_scnt = 0;
mtxb->aux_scnt = 0;
@@ -775,16 +757,16 @@ mtxb_init(struct ethr_mutex_base_ *mtxb,
}
mtxb->q = NULL;
- ethr_atomic_init(&mtxb->flgs, 0);
+ ethr_atomic32_init(&mtxb->flgs, 0);
return ETHR_MTX_QLOCK_INIT(&mtxb->qlck);
}
static int
mtxb_destroy(struct ethr_mutex_base_ *mtxb)
{
- long act;
+ ethr_sint32_t act;
ETHR_MTX_Q_LOCK(&mtxb->qlck);
- act = ethr_atomic_read(&mtxb->flgs);
+ act = ethr_atomic32_read(&mtxb->flgs);
ETHR_MTX_Q_UNLOCK(&mtxb->qlck);
if (act != 0)
return EINVAL;
@@ -850,13 +832,13 @@ ethr_mutex_destroy(ethr_mutex *mtx)
}
void
-ethr_mutex_lock_wait__(ethr_mutex *mtx, long initial)
+ethr_mutex_lock_wait__(ethr_mutex *mtx, ethr_sint32_t initial)
{
write_lock_wait(&mtx->mtxb, initial, 0, 0);
}
void
-ethr_mutex_unlock_wake__(ethr_mutex *mtx, long initial)
+ethr_mutex_unlock_wake__(ethr_mutex *mtx, ethr_sint32_t initial)
{
ethr_ts_event *tse;
@@ -864,7 +846,7 @@ ethr_mutex_unlock_wake__(ethr_mutex *mtx, long initial)
tse = mtx->mtxb.q;
ETHR_ASSERT(tse);
- ETHR_ASSERT(ethr_atomic_read(&mtx->mtxb.flgs)
+ ETHR_ASSERT(ethr_atomic32_read(&mtx->mtxb.flgs)
== (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__));
ETHR_ASSERT(initial & ETHR_RWMTX_W_WAIT_FLG__);
ETHR_MTX_HARD_DEBUG_CHK_Q(mtx);
@@ -874,7 +856,7 @@ ethr_mutex_unlock_wake__(ethr_mutex *mtx, long initial)
* mtxb->flgs; otherwise, we need to clear the write wait bit...
*/
if (tse->next == mtx->mtxb.q)
- ethr_atomic_set(&mtx->mtxb.flgs, ETHR_RWMTX_W_FLG__);
+ ethr_atomic32_set(&mtx->mtxb.flgs, ETHR_RWMTX_W_FLG__);
wake_writer(&mtx->mtxb, 0);
}
@@ -884,7 +866,7 @@ ethr_mutex_unlock_wake__(ethr_mutex *mtx, long initial)
static void
enqueue_mtx(ethr_mutex *mtx, ethr_ts_event *tse_start, ethr_ts_event *tse_end)
{
- long act;
+ ethr_sint32_t act;
/*
* `ethr_cond_signal()' and `ethr_cond_broadcast()' end up here. If `mtx'
@@ -913,7 +895,7 @@ enqueue_mtx(ethr_mutex *mtx, ethr_ts_event *tse_start, ethr_ts_event *tse_end)
}
#endif
- act = ethr_atomic_read(&mtx->mtxb.flgs);
+ act = ethr_atomic32_read(&mtx->mtxb.flgs);
ETHR_ASSERT(act == 0
|| act == ETHR_RWMTX_W_FLG__
|| act == (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__));
@@ -921,10 +903,10 @@ enqueue_mtx(ethr_mutex *mtx, ethr_ts_event *tse_start, ethr_ts_event *tse_end)
/* The normal sane case */
if (!(act & ETHR_RWMTX_W_WAIT_FLG__)) {
ETHR_ASSERT(!mtx->mtxb.q);
- act = ethr_atomic_cmpxchg(&mtx->mtxb.flgs,
- (ETHR_RWMTX_W_FLG__
- | ETHR_RWMTX_W_WAIT_FLG__),
- ETHR_RWMTX_W_FLG__);
+ act = ethr_atomic32_cmpxchg(&mtx->mtxb.flgs,
+ (ETHR_RWMTX_W_FLG__
+ | ETHR_RWMTX_W_WAIT_FLG__),
+ ETHR_RWMTX_W_FLG__);
if (act != ETHR_RWMTX_W_FLG__) {
/*
* Sigh... this wasn't so sane after all since, the mutex was
@@ -956,14 +938,14 @@ enqueue_mtx(ethr_mutex *mtx, ethr_ts_event *tse_start, ethr_ts_event *tse_end)
multi = tse_start != tse_end;
while (1) {
- long new, exp = act;
+ ethr_sint32_t new, exp = act;
if (multi || (act & ETHR_RWMTX_W_FLG__))
new = ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__;
else
new = ETHR_RWMTX_W_FLG__;
- act = ethr_atomic_cmpxchg(&mtx->mtxb.flgs, new, exp);
+ act = ethr_atomic32_cmpxchg(&mtx->mtxb.flgs, new, exp);
if (exp == act) {
ETHR_ASSERT(!mtx->mtxb.q);
if (act & ETHR_RWMTX_W_FLG__) {
@@ -991,7 +973,7 @@ enqueue_mtx(ethr_mutex *mtx, ethr_ts_event *tse_start, ethr_ts_event *tse_end)
ETHR_MTX_HARD_DEBUG_CHK_Q(mtx);
ETHR_MTX_Q_UNLOCK(&mtx->mtxb.qlck);
- ethr_atomic_set(&tse_start->uaflgs, 0);
+ ethr_atomic32_set(&tse_start->uaflgs, 0);
ethr_event_set(&tse_start->event);
}
break;
@@ -1082,9 +1064,9 @@ ethr_cond_signal(ethr_cond *cnd)
ETHR_MTX_HARD_DEBUG_FENCE_CHK(mtx);
ETHR_ASSERT(tse->uflgs == ETHR_RWMTX_W_WAIT_FLG__);
- ETHR_ASSERT(ethr_atomic_read(&tse->uaflgs) == ETHR_CND_WAIT_FLG__);
+ ETHR_ASSERT(ethr_atomic32_read(&tse->uaflgs) == ETHR_CND_WAIT_FLG__);
- ethr_atomic_set(&tse->uaflgs, ETHR_RWMTX_W_WAIT_FLG__);
+ ethr_atomic32_set(&tse->uaflgs, ETHR_RWMTX_W_WAIT_FLG__);
dequeue(&cnd->q, tse, tse);
@@ -1135,10 +1117,11 @@ ethr_cond_broadcast(ethr_cond *cnd)
/* The normal case */
ETHR_ASSERT(tse_tmp->uflgs == ETHR_RWMTX_W_WAIT_FLG__);
- ETHR_ASSERT(ethr_atomic_read(&tse_tmp->uaflgs)
+ ETHR_ASSERT(ethr_atomic32_read(&tse_tmp->uaflgs)
== ETHR_CND_WAIT_FLG__);
- ethr_atomic_set(&tse_tmp->uaflgs, ETHR_RWMTX_W_WAIT_FLG__);
+ ethr_atomic32_set(&tse_tmp->uaflgs,
+ ETHR_RWMTX_W_WAIT_FLG__);
}
else {
/* Should be very unusual */
@@ -1191,7 +1174,7 @@ ethr_cond_wait(ethr_cond *cnd, ethr_mutex *mtx)
tse->udata = (void *) mtx;
tse->uflgs = ETHR_RWMTX_W_WAIT_FLG__; /* Prep for mutex lock op */
- ethr_atomic_set(&tse->uaflgs, ETHR_CND_WAIT_FLG__);
+ ethr_atomic32_set(&tse->uaflgs, ETHR_CND_WAIT_FLG__);
ETHR_MTX_Q_LOCK(&cnd->qlck);
@@ -1204,11 +1187,11 @@ ethr_cond_wait(ethr_cond *cnd, ethr_mutex *mtx)
/* Wait */
woken = 0;
while (1) {
- long act;
+ ethr_sint32_t act;
ethr_event_reset(&tse->event);
- act = ethr_atomic_read_acqb(&tse->uaflgs);
+ act = ethr_atomic32_read_acqb(&tse->uaflgs);
if (!act)
break; /* Mtx locked */
@@ -1224,7 +1207,7 @@ ethr_cond_wait(ethr_cond *cnd, ethr_mutex *mtx)
*/
if (act == ETHR_CND_WAIT_FLG__) {
ETHR_MTX_Q_LOCK(&cnd->qlck);
- act = ethr_atomic_read(&tse->uaflgs);
+ act = ethr_atomic32_read(&tse->uaflgs);
ETHR_ASSERT(act == ETHR_CND_WAIT_FLG__
|| act == ETHR_RWMTX_W_WAIT_FLG__);
/*
@@ -1254,7 +1237,7 @@ ethr_cond_wait(ethr_cond *cnd, ethr_mutex *mtx)
ETHR_MTX_HARD_DEBUG_LFS_RWLOCK(&mtx->mtxb);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(cnd);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(mtx);
-
+ ETHR_MTX_CHK_EXCL_SET_EXCL(&mtx->mtxb);
tse->udata = udata;
ethr_leave_ts_event(tse);
return 0;
@@ -1426,7 +1409,7 @@ wake_readers(ethr_rwmutex *rwmtx, int rs)
rwmtx->rq_end = NULL;
ETHR_ASSERT(!rwmtx->mtxb.q
- || (ethr_atomic_read(&rwmtx->mtxb.q->uaflgs)
+ || (ethr_atomic32_read(&rwmtx->mtxb.q->uaflgs)
== ETHR_RWMTX_W_WAIT_FLG__));
ETHR_RWMTX_HARD_DEBUG_CHK_Q(rwmtx);
@@ -1437,7 +1420,7 @@ wake_readers(ethr_rwmutex *rwmtx, int rs)
#ifdef ETHR_DEBUG
ETHR_ASSERT(tse->uflgs == ETHR_RWMTX_R_WAIT_FLG__);
- ETHR_ASSERT(ethr_atomic_read(&tse->uaflgs)
+ ETHR_ASSERT(ethr_atomic32_read(&tse->uaflgs)
== ETHR_RWMTX_R_WAIT_FLG__);
drs++;
#endif
@@ -1445,7 +1428,7 @@ wake_readers(ethr_rwmutex *rwmtx, int rs)
tse_next = tse->next; /* we aren't allowed to read tse->next
after we have reset uaflgs */
- ethr_atomic_set(&tse->uaflgs, 0);
+ ethr_atomic32_set(&tse->uaflgs, 0);
ethr_event_set(&tse->event);
tse = tse_next;
}
@@ -1488,7 +1471,7 @@ int check_readers_array(ethr_rwmutex *rwmtx,
ETHR_MEMORY_BARRIER;
do {
- long act = rwmutex_freqread_rdrs_read(rwmtx, ix);
+ ethr_sint32_t act = rwmutex_freqread_rdrs_read(rwmtx, ix);
if (act != 0)
return EBUSY;
ix++;
@@ -1499,55 +1482,101 @@ int check_readers_array(ethr_rwmutex *rwmtx,
return 0;
}
-static ETHR_INLINE void
+static void
+rwmutex_freqread_rdrs_dec_chk_wakeup(ethr_rwmutex *rwmtx,
+ ethr_ts_event *tse,
+ ethr_sint32_t initial)
+{
+ ethr_sint32_t act = initial;
+
+ if ((act & (ETHR_RWMTX_W_FLG__|
+ ETHR_RWMTX_R_ABRT_UNLCK_FLG__)) == 0) {
+ if ((act & ETHR_RWMTX_WAIT_FLGS__) == 0) {
+ if (act & ETHR_RWMTX_R_PEND_UNLCK_MASK__) {
+ /*
+ * We *need* to try to complete the runlock.
+ * A writer that just enqueued (not seen by us
+ * in flag field) may depend on someone else
+ * completing the runlock. We just took over
+ * that responsibilty since we modified reader
+ * groups.
+ */
+ rwmutex_try_complete_runlock(rwmtx, act, tse, 1, 0, 0);
+ }
+ }
+ else if ((act & ETHR_RWMTX_WAIT_FLGS__) == ETHR_RWMTX_R_WAIT_FLG__)
+ rwmutex_transfer_read_lock(rwmtx, act, 0);
+ else if ((act & ETHR_RWMTX_WAIT_FLGS__) == ETHR_RWMTX_W_WAIT_FLG__)
+ rwmutex_try_complete_runlock(rwmtx, act, tse, 1, 0, 0);
+ else {
+ /*
+ * Don't know if we got readers or writers
+ * first in queue; need to peek
+ */
+ ETHR_MTX_Q_LOCK(&rwmtx->mtxb.qlck);
+ if (!rwmtx->mtxb.q)
+ ETHR_MTX_Q_UNLOCK(&rwmtx->mtxb.qlck);
+ else if (is_w_waiter(rwmtx->mtxb.q)) {
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
+ ETHR_MTX_Q_UNLOCK(&rwmtx->mtxb.qlck);
+ if ((act & ETHR_RWMTX_W_FLG__) == 0)
+ rwmutex_try_complete_runlock(rwmtx, act, tse, 1, 0, 0);
+ }
+ else {
+ /*
+ * rwmutex_transfer_read_lock() will
+ * unlock Q lock.
+ */
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
+ if (act & ETHR_RWMTX_W_FLG__)
+ ETHR_MTX_Q_UNLOCK(&rwmtx->mtxb.qlck);
+ else
+ rwmutex_transfer_read_lock(rwmtx, act, 1);
+ }
+ }
+ }
+}
+
+static void
rwmutex_freqread_restore_failed_tryrlock(ethr_rwmutex *rwmtx,
ethr_ts_event *tse)
{
- long act;
+ ethr_sint32_t act;
/*
* Restore failed increment
*/
act = rwmutex_freqread_rdrs_dec_read(rwmtx, tse);
- ETHR_WRITE_MEMORY_BARRIER;
+ ETHR_MEMORY_BARRIER;
if (act == 0) {
-
-#ifndef ETHR_WRITE_MEMORY_BARRIER_IS_FULL
- ETHR_READ_MEMORY_BARRIER;
-#endif
-
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
-
- if ((act & ETHR_RWMTX_W_FLG__) == 0
- && act & (ETHR_RWMTX_WAIT_FLGS__|ETHR_RWMTX_R_PEND_UNLCK_MASK__)) {
- /*
- * We either got waiters, or someone else trying
- * to read unlock which we might have to help.
- */
- rwmutex_try_complete_runlock(rwmtx, act, tse, 1, 1, 0);
- }
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
+ rwmutex_freqread_rdrs_dec_chk_wakeup(rwmtx, tse, act);
}
}
static int
rwmutex_try_complete_runlock(ethr_rwmutex *rwmtx,
- long initial,
+ ethr_sint32_t initial,
ethr_ts_event *tse,
int start_next_ix,
int check_before_try,
int try_write_lock)
{
ethr_ts_event *tse_tmp;
- long act = initial;
+ ethr_sint32_t act = initial;
int six, res, length;
+ ETHR_ASSERT((act & ETHR_RWMTX_W_FLG__) == 0);
+
+ if (act & ETHR_RWMTX_R_ABRT_UNLCK_FLG__)
+ return try_write_lock ? EBUSY : 0;
+
tse_tmp = tse;
if (!tse_tmp)
tse_tmp = ethr_get_ts_event();
- if ((act & ETHR_RWMTX_WAIT_FLGS__)
- && (act & ~ETHR_RWMTX_WAIT_FLGS__) == 0)
+ if ((act & ETHR_RWMTX_WAIT_FLGS__) && (act & ~ETHR_RWMTX_WAIT_FLGS__) == 0)
goto check_waiters;
if (rwmtx->type == ETHR_RWMUTEX_TYPE_FREQUENT_READ) {
@@ -1569,24 +1598,33 @@ rwmutex_try_complete_runlock(ethr_rwmutex *rwmtx,
if (check_before_try) {
res = check_readers_array(rwmtx, six, length);
+
+ ETHR_MEMORY_BARRIER;
+
if (res == EBUSY)
return try_write_lock ? EBUSY : 0;
}
+ restart:
+
while (1) {
- long exp = act;
- long new = act+1;
+ ethr_sint32_t exp = act;
+ ethr_sint32_t new = act+1;
+
+ ETHR_ASSERT((act & ETHR_RWMTX_R_ABRT_UNLCK_FLG__) == 0);
ETHR_ASSERT((act & ETHR_RWMTX_R_PEND_UNLCK_MASK__)
< ETHR_RWMTX_R_PEND_UNLCK_MASK__);
- act = ethr_atomic_cmpxchg(&rwmtx->mtxb.flgs, new, exp);
+ act = ethr_atomic32_cmpxchg(&rwmtx->mtxb.flgs, new, exp);
if (exp == act) {
act = new;
break;
}
+
if (!try_write_lock) {
- if (act == ETHR_RWMTX_W_FLG__ || act == 0)
+ if (act == 0 || (act & (ETHR_RWMTX_W_FLG__
+ | ETHR_RWMTX_R_ABRT_UNLCK_FLG__)))
return 0;
if ((act & ETHR_RWMTX_WAIT_FLGS__) == 0) {
if ((act & ETHR_RWMTX_R_FLG__) == 0)
@@ -1601,33 +1639,50 @@ rwmutex_try_complete_runlock(ethr_rwmutex *rwmtx,
else {
if (act == 0)
goto tryrwlock;
- if (act & (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_WAIT_FLGS__))
+ if (act & (ETHR_RWMTX_W_FLG__
+ | ETHR_RWMTX_R_ABRT_UNLCK_FLG__))
return EBUSY;
}
}
res = check_readers_array(rwmtx, six, length);
- if (res == EBUSY) {
- act = ethr_atomic_dec_read(&rwmtx->mtxb.flgs);
- if (act & ETHR_RWMTX_R_MASK__)
- return try_write_lock ? EBUSY : 0;
- }
- else {
- while (1) {
- long exp = act;
- long new = act;
- new &= ~ETHR_RWMTX_R_FLG__;
- new--;
- ETHR_ASSERT(act & ETHR_RWMTX_R_PEND_UNLCK_MASK__);
+ ETHR_MEMORY_BARRIER;
- act = ethr_atomic_cmpxchg(&rwmtx->mtxb.flgs, new, exp);
- if (exp == act) {
- if (new & ETHR_RWMTX_R_PEND_UNLCK_MASK__)
- return try_write_lock ? EBUSY : 0;
- act = new;
- break;
+ ETHR_ASSERT((act & ETHR_RWMTX_W_FLG__) == 0);
+
+ while (1) {
+ int finished_abort = 0;
+ ethr_sint32_t exp = act;
+ ethr_sint32_t new = act;
+
+ new--;
+ if (act & ETHR_RWMTX_R_ABRT_UNLCK_FLG__) {
+ if ((new & ETHR_RWMTX_R_PEND_UNLCK_MASK__) == 0) {
+ new &= ~ETHR_RWMTX_R_ABRT_UNLCK_FLG__;
+ finished_abort = 1;
}
+ ETHR_ASSERT(act & ETHR_RWMTX_R_FLG__);
+ }
+ else if ((act & ETHR_RWMTX_R_FLG__) && res != EBUSY) {
+ new &= ~ETHR_RWMTX_R_FLG__;
+ }
+
+ ETHR_ASSERT(act & ETHR_RWMTX_R_PEND_UNLCK_MASK__);
+
+ act = ethr_atomic32_cmpxchg(&rwmtx->mtxb.flgs, new, exp);
+ if (exp == act) {
+ act = new;
+ if (act & ETHR_RWMTX_W_FLG__)
+ return try_write_lock ? EBUSY : 0;
+ if (finished_abort && (act & ETHR_RWMTX_WAIT_FLGS__))
+ goto restart;
+ if (act & (ETHR_RWMTX_R_FLG__
+ | ETHR_RWMTX_R_ABRT_UNLCK_FLG__
+ | ETHR_RWMTX_R_PEND_UNLCK_MASK__))
+ return try_write_lock ? EBUSY : 0;
+ /* Read unlock completed */
+ break;
}
}
@@ -1637,12 +1692,9 @@ rwmutex_try_complete_runlock(ethr_rwmutex *rwmtx,
* to write lock it).
*/
- if (act & ETHR_RWMTX_W_FLG__)
- return try_write_lock ? EBUSY : 0;
-
if (act & ETHR_RWMTX_WAIT_FLGS__) {
check_waiters:
- rwmutex_unlock_wake(rwmtx, 0, act);
+ rwmutex_unlock_wake(rwmtx, 0, act, 0);
return try_write_lock ? EBUSY : 0;
}
@@ -1652,9 +1704,9 @@ rwmutex_try_complete_runlock(ethr_rwmutex *rwmtx,
tryrwlock:
/* Try to write lock it */
- act = ethr_atomic_cmpxchg_acqb(&rwmtx->mtxb.flgs,
- ETHR_RWMTX_W_FLG__,
- 0);
+ act = ethr_atomic32_cmpxchg_acqb(&rwmtx->mtxb.flgs,
+ ETHR_RWMTX_W_FLG__,
+ 0);
return act == 0 ? 0 : EBUSY;
}
@@ -1663,24 +1715,23 @@ rwmutex_try_complete_runlock(ethr_rwmutex *rwmtx,
static ETHR_INLINE void
rwmutex_incdec_restore_failed_tryrlock(ethr_rwmutex *rwmtx)
{
- long act;
+ ethr_sint32_t act;
/*
* Restore failed increment
*/
- act = ethr_atomic_dec_read(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_dec_read(&rwmtx->mtxb.flgs);
if ((act & ETHR_RWMTX_WAIT_FLGS__)
&& (act & ~ETHR_RWMTX_WAIT_FLGS__) == 0) {
- rwmutex_unlock_wake(rwmtx, 0, act);
+ rwmutex_unlock_wake(rwmtx, 0, act, 0);
}
}
#endif
static void
-rwmutex_normal_rlock_wait(ethr_rwmutex *rwmtx,
- long initial)
+rwmutex_normal_rlock_wait(ethr_rwmutex *rwmtx, ethr_sint32_t initial)
{
- long act = initial, exp;
+ ethr_sint32_t act = initial, exp;
int scnt, start_scnt;
ethr_ts_event *tse = NULL;
int until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
@@ -1696,11 +1747,11 @@ rwmutex_normal_rlock_wait(ethr_rwmutex *rwmtx,
#ifdef ETHR_RLOCK_WITH_INC_DEC
rwmutex_incdec_restore_failed_tryrlock(rwmtx);
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
#endif
while (act & (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__)) {
- if (scnt >= 0) {
+ if (scnt <= 0) {
tse = ethr_get_ts_event();
if (update_spincount(&rwmtx->mtxb, tse, &start_scnt, &scnt)) {
event_wait(&rwmtx->mtxb, tse, scnt,
@@ -1713,17 +1764,17 @@ rwmutex_normal_rlock_wait(ethr_rwmutex *rwmtx,
until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
ETHR_YIELD();
}
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
scnt--;
}
exp = act;
#ifdef ETHR_RLOCK_WITH_INC_DEC
- act = ethr_atomic_inc_read(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_inc_read(&rwmtx->mtxb.flgs);
if ((act & (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__)) == 0)
goto done; /* Got it */
#else
- act = ethr_atomic_cmpxchg_acqb(&rwmtx->mtxb.flgs, exp+1, exp);
+ act = ethr_atomic32_cmpxchg_acqb(&rwmtx->mtxb.flgs, exp+1, exp);
if (act == exp)
goto done; /* Got it */
#endif
@@ -1736,10 +1787,83 @@ rwmutex_normal_rlock_wait(ethr_rwmutex *rwmtx,
static void
rwmutex_freqread_rlock_wait(ethr_rwmutex *rwmtx,
- ethr_ts_event *tse,
- long initial)
+ ethr_ts_event *tse);
+
+static int
+rwmutex_freqread_rlock(ethr_rwmutex *rwmtx, ethr_ts_event *tse, int trylock)
{
- long act = initial;
+ int res = 0;
+ ethr_sint32_t act;
+
+ rwmutex_freqread_rdrs_inc(rwmtx, tse);
+
+ ETHR_MEMORY_BARRIER;
+
+ act = ethr_atomic32_read_acqb(&rwmtx->mtxb.flgs);
+
+ if (act != ETHR_RWMTX_R_FLG__) {
+ int wake_other_readers;
+
+ while (1) {
+ ethr_sint32_t exp, new;
+
+ wake_other_readers = 0;
+
+ if (act == 0)
+ new = act | ETHR_RWMTX_R_FLG__;
+ else if (act == ETHR_RWMTX_R_FLG__)
+ break; /* Got it */
+ else if (act & (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__)) {
+ rwmutex_freqread_restore_failed_tryrlock(rwmtx, tse);
+ if (trylock)
+ res = EBUSY;
+ else
+ rwmutex_freqread_rlock_wait(rwmtx, tse);
+ break;
+ }
+ else if (act & ETHR_RWMTX_R_ABRT_UNLCK_FLG__) {
+ if ((act & ETHR_RWMTX_R_FLG__) == 0)
+ ETHR_FATAL_ERROR__(EFAULT);
+ /*
+ * An aborted runlock, not write locked, and no write
+ * waiters, i.e., we got it...
+ */
+ if (act & ETHR_RWMTX_R_WAIT_FLG__)
+ wake_other_readers = 1;
+ break;
+ }
+ else {
+ new = act | ETHR_RWMTX_R_FLG__;
+ if (act & ETHR_RWMTX_R_PEND_UNLCK_MASK__) {
+ /*
+ * Someone is doing tryrwlock (no writer and no
+ * write waiters); we will try to abort that...
+ */
+ new |= ETHR_RWMTX_R_ABRT_UNLCK_FLG__;
+ }
+
+ if (act & ETHR_RWMTX_R_WAIT_FLG__)
+ wake_other_readers = 1;
+ }
+
+ exp = act;
+ act = ethr_atomic32_cmpxchg_acqb(&rwmtx->mtxb.flgs, new, exp);
+ if (act == exp)
+ break;
+ }
+
+ if (wake_other_readers)
+ rwmutex_transfer_read_lock(rwmtx, act, 0);
+ }
+
+ return res;
+}
+
+static void
+rwmutex_freqread_rlock_wait(ethr_rwmutex *rwmtx,
+ ethr_ts_event *tse)
+{
+ ethr_sint32_t act;
int scnt, start_scnt;
int until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
@@ -1752,12 +1876,10 @@ rwmutex_freqread_rlock_wait(ethr_rwmutex *rwmtx,
while (1) {
- rwmutex_freqread_restore_failed_tryrlock(rwmtx, tse);
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
-
- while (act & ~(ETHR_RWMTX_R_FLG__|ETHR_RWMTX_R_WAIT_FLG__)) {
- if (scnt >= 0) {
+ while (act & (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__)) {
+ if (scnt <= 0) {
if (update_spincount(&rwmtx->mtxb, tse, &start_scnt, &scnt)) {
event_wait(&rwmtx->mtxb, tse, scnt,
ETHR_RWMTX_R_WAIT_FLG__, 1, 1);
@@ -1769,74 +1891,65 @@ rwmutex_freqread_rlock_wait(ethr_rwmutex *rwmtx,
until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
ETHR_YIELD();
}
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
scnt--;
}
- rwmutex_freqread_rdrs_inc(rwmtx, tse);
-
- ETHR_MEMORY_BARRIER;
-
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
-
- if (act == ETHR_RWMTX_R_FLG__)
- return; /* Got it */
-
- while (1) {
- long exp, new;
-
- if (act & ~(ETHR_RWMTX_R_FLG__|ETHR_RWMTX_R_WAIT_FLG__))
- break; /* Busy (need to restore inc) */
-
- if (act & ETHR_RWMTX_R_FLG__)
- return; /* Got it */
-
- exp = act;
- new = act | ETHR_RWMTX_R_FLG__;
- act = ethr_atomic_cmpxchg(&rwmtx->mtxb.flgs, new, exp);
- if (act == exp)
- return; /* Got it */
- }
+ if (rwmutex_freqread_rlock(rwmtx, tse, 1) != EBUSY)
+ break; /* Got it */
}
}
static void
-rwmutex_normal_rwlock_wait(ethr_rwmutex *rwmtx, long initial)
+rwmutex_normal_rwlock_wait(ethr_rwmutex *rwmtx, ethr_sint32_t initial)
{
write_lock_wait(&rwmtx->mtxb, initial, 1, 0);
}
static void
-rwmutex_freqread_rwlock_wait(ethr_rwmutex *rwmtx, long initial)
+rwmutex_freqread_rwlock_wait(ethr_rwmutex *rwmtx, ethr_sint32_t initial)
{
write_lock_wait(&rwmtx->mtxb, initial, 1, 1);
}
static ETHR_INLINE void
-rwlock_wake_set_flags(ethr_rwmutex *rwmtx, long new_initial, int act_initial)
+rwlock_wake_set_flags(ethr_rwmutex *rwmtx,
+ ethr_sint32_t new_initial,
+ ethr_sint32_t act_initial)
{
- long act, act_mask;
+ ethr_sint32_t act, act_mask;
+ int chk_abrt_flg;
+
+ ETHR_MEMORY_BARRIER;
+
if (rwmtx->type != ETHR_RWMUTEX_TYPE_NORMAL) {
/* r pend unlock mask may vary and must be retained */
act_mask = ETHR_RWMTX_R_PEND_UNLCK_MASK__;
+ if (new_initial & ETHR_RWMTX_R_FLG__)
+ chk_abrt_flg = 1;
+ else
+ chk_abrt_flg = 0;
}
else {
#ifdef ETHR_RLOCK_WITH_INC_DEC
/* rs mask may vary and must be retained */
act_mask = ETHR_RWMTX_RS_MASK__;
+ chk_abrt_flg = 0;
#else
/* rs mask always zero */
ETHR_ASSERT((act_initial & ETHR_RWMTX_RS_MASK__) == 0);
- ethr_atomic_set(&rwmtx->mtxb.flgs, new_initial);
+ ethr_atomic32_set(&rwmtx->mtxb.flgs, new_initial);
return;
#endif
}
act = act_initial;
while (1) {
- long exp = act;
- long new = new_initial + (act & act_mask);
- act = ethr_atomic_cmpxchg(&rwmtx->mtxb.flgs, new, exp);
+ ethr_sint32_t exp = act;
+ ethr_sint32_t new = new_initial + (act & act_mask);
+ if (chk_abrt_flg && (act & act_mask))
+ new |= ETHR_RWMTX_R_ABRT_UNLCK_FLG__;
+ act = ethr_atomic32_cmpxchg(&rwmtx->mtxb.flgs, new, exp);
if (act == exp)
break;
exp = act;
@@ -1850,7 +1963,7 @@ dbg_unlock_wake(ethr_rwmutex *rwmtx,
int have_w,
ethr_ts_event *tse)
{
- long exp, act, imask;
+ ethr_sint32_t exp, act, imask;
exp = have_w ? ETHR_RWMTX_W_FLG__ : 0;
@@ -1872,7 +1985,7 @@ dbg_unlock_wake(ethr_rwmutex *rwmtx,
if (rwmtx->rq_end) {
exp |= ETHR_RWMTX_R_WAIT_FLG__;
}
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
ETHR_ASSERT((exp & ~imask) == (act & ~imask));
ETHR_RWMTX_HARD_DEBUG_CHK_Q(rwmtx);
@@ -1883,7 +1996,15 @@ dbg_unlock_wake(ethr_rwmutex *rwmtx,
exp |= ETHR_RWMTX_R_WAIT_FLG__;
if (rwmtx->rq_end->next != rwmtx->mtxb.q)
exp |= ETHR_RWMTX_W_WAIT_FLG__;
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
+ else if (exp == ETHR_RWMTX_R_WAIT_FLG__) {
+ if (!have_w) {
+ if (rwmtx->type != ETHR_RWMUTEX_TYPE_NORMAL)
+ imask |= ETHR_RWMTX_R_FLG__;
+ else
+ imask |= ETHR_RWMTX_RS_MASK__;
+ }
+ }
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
ETHR_ASSERT((exp & ~imask) == (act & ~imask));
ETHR_RWMTX_HARD_DEBUG_CHK_Q(rwmtx);
@@ -1894,41 +2015,85 @@ dbg_unlock_wake(ethr_rwmutex *rwmtx,
#endif
static void
-rwmutex_unlock_wake(ethr_rwmutex *rwmtx, int have_w, long initial)
+rwmutex_transfer_read_lock(ethr_rwmutex *rwmtx,
+ ethr_sint32_t initial,
+ int q_locked)
{
- long new, act = initial;
- ethr_ts_event *tse;
+ ethr_sint32_t act = initial;
- if ((act & ETHR_RWMTX_WAIT_FLGS__) == 0) {
- if (!have_w)
+ if (!q_locked) {
+ ethr_ts_event *tse;
+ ETHR_ASSERT(initial & ETHR_RWMTX_R_WAIT_FLG__);
+ ETHR_ASSERT((initial & ETHR_RWMTX_W_FLG__) == 0);
+ ETHR_MTX_Q_LOCK(&rwmtx->mtxb.qlck);
+
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
+ tse = rwmtx->mtxb.q;
+ if ((act & ETHR_RWMTX_W_FLG__) || !tse || is_w_waiter(tse)) {
+ /* Someone else woke the readers up... */
+ ETHR_MTX_Q_UNLOCK(&rwmtx->mtxb.qlck);
return;
- else {
- while ((act & ETHR_RWMTX_WAIT_FLGS__) == 0) {
- long exp = act;
- new = exp & ~ETHR_RWMTX_W_FLG__;
- act = ethr_atomic_cmpxchg(&rwmtx->mtxb.flgs, new, exp);
- if (act == exp)
- return;
- }
}
}
- ETHR_MTX_Q_LOCK(&rwmtx->mtxb.qlck);
- tse = rwmtx->mtxb.q;
+ rwmutex_unlock_wake(rwmtx, 0, initial, 1);
+}
- if (!have_w) {
- if (!tse) {
+static void
+rwmutex_unlock_wake(ethr_rwmutex *rwmtx, int have_w, ethr_sint32_t initial,
+ int transfer_read_lock)
+{
+ ethr_sint32_t new, act = initial;
+ ethr_ts_event *tse;
+
+ if (transfer_read_lock) {
+ /*
+ * - Q already locked
+ * - Got R waiters first in Q
+ * - Not W locked
+ */
+ tse = rwmtx->mtxb.q;
+
+ ETHR_ASSERT(act & ETHR_RWMTX_R_WAIT_FLG__);
+ ETHR_ASSERT((act & (ETHR_RWMTX_W_FLG__)) == 0);
+ ETHR_ASSERT(tse && !is_w_waiter(tse));
+ }
+ else {
+
+ if ((act & ETHR_RWMTX_WAIT_FLGS__) == 0) {
+ if (!have_w)
+ return;
+ else {
+ while ((act & ETHR_RWMTX_WAIT_FLGS__) == 0) {
+ ethr_sint32_t exp = act;
+ new = exp & ~ETHR_RWMTX_W_FLG__;
+ act = ethr_atomic32_cmpxchg(&rwmtx->mtxb.flgs, new, exp);
+ if (act == exp)
+ return;
+ }
+ }
+ }
+
+ ETHR_MTX_Q_LOCK(&rwmtx->mtxb.qlck);
+ tse = rwmtx->mtxb.q;
+
+ if (!have_w) {
+ if (!tse) {
#ifdef ETHR_DEBUG
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
- ETHR_ASSERT((act & ETHR_RWMTX_WAIT_FLGS__) == 0);
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
+ ETHR_ASSERT((act & ETHR_RWMTX_WAIT_FLGS__) == 0);
#endif
- goto already_served;
- }
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
- if (act & ~ETHR_RWMTX_WAIT_FLGS__) {
- already_served:
- ETHR_MTX_Q_UNLOCK(&rwmtx->mtxb.qlck);
- return;
+ goto already_served;
+ }
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
+ if (act == (ETHR_RWMTX_R_WAIT_FLG__|ETHR_RWMTX_R_FLG__)) {
+ ETHR_ASSERT(tse && !is_w_waiter(tse));
+ }
+ else if (act & ~ETHR_RWMTX_WAIT_FLGS__) {
+ already_served:
+ ETHR_MTX_Q_UNLOCK(&rwmtx->mtxb.qlck);
+ return;
+ }
}
}
@@ -1939,9 +2104,12 @@ rwmutex_unlock_wake(ethr_rwmutex *rwmtx, int have_w, long initial)
if (is_w_waiter(tse)) {
if (!have_w) {
- act = ethr_atomic_read_bor(&rwmtx->mtxb.flgs,
+ act = ethr_atomic32_read_bor(&rwmtx->mtxb.flgs,
ETHR_RWMTX_W_FLG__);
- ETHR_ASSERT((act & ~ETHR_RWMTX_WAIT_FLGS__) == 0);
+ ETHR_ASSERT((act & ~(ETHR_RWMTX_WAIT_FLGS__
+ | (rwmtx->type == ETHR_RWMUTEX_TYPE_NORMAL
+ ? 0
+ : ETHR_RWMTX_R_PEND_UNLCK_MASK__))) == 0);
ETHR_ASSERT(act & ETHR_RWMTX_W_WAIT_FLG__);
act |= ETHR_RWMTX_W_FLG__;
}
@@ -1968,7 +2136,7 @@ rwmutex_unlock_wake(ethr_rwmutex *rwmtx, int have_w, long initial)
if (rwmtx->type == ETHR_RWMUTEX_TYPE_NORMAL) {
rs = rwmtx->tdata.rs;
- new = (long) rs;
+ new = (ethr_sint32_t) rs;
rwmtx->tdata.rs = 0;
}
else {
@@ -1988,6 +2156,7 @@ rwmutex_unlock_wake(ethr_rwmutex *rwmtx, int have_w, long initial)
rwmutex_freqread_rdrs_add(rwmtx, type, ix, wrs);
}
}
+
new = ETHR_RWMTX_R_FLG__;
}
@@ -1995,6 +2164,7 @@ rwmutex_unlock_wake(ethr_rwmutex *rwmtx, int have_w, long initial)
new |= ETHR_RWMTX_W_WAIT_FLG__;
rwlock_wake_set_flags(rwmtx, new, act);
+
wake_readers(rwmtx, rs);
}
}
@@ -2022,16 +2192,16 @@ alloc_readers_array(int length, ethr_rwmutex_lived lived)
if (!mem)
return NULL;
- if ((((unsigned long) mem) & ETHR_CACHE_LINE_MASK) == 0) {
+ if ((((ethr_uint_t) mem) & ETHR_CACHE_LINE_MASK) == 0) {
ra = (ethr_rwmtx_readers_array__ *) mem;
ra->data.byte_offset = 0;
}
else {
ra = ((ethr_rwmtx_readers_array__ *)
- ((((unsigned long) mem) & ~ETHR_CACHE_LINE_MASK)
+ ((((ethr_uint_t) mem) & ~ETHR_CACHE_LINE_MASK)
+ ETHR_CACHE_LINE_SIZE));
- ra->data.byte_offset = (int) ((unsigned long) ra
- - (unsigned long) mem);
+ ra->data.byte_offset = (int) ((ethr_uint_t) ra
+ - (ethr_uint_t) mem);
}
ra->data.lived = lived;
return ra;
@@ -2105,7 +2275,7 @@ ethr_rwmutex_init_opt(ethr_rwmutex *rwmtx, ethr_rwmutex_opt *opt)
rwmtx->tdata.ra = ra;
for (ix = 0; ix < length; ix++) {
- ethr_atomic_init(&rwmtx->tdata.ra[ix].data.readers, 0);
+ ethr_atomic32_init(&rwmtx->tdata.ra[ix].data.readers, 0);
rwmtx->tdata.ra[ix].data.waiting_readers = 0;
}
break;
@@ -2157,8 +2327,9 @@ ethr_rwmutex_destroy(ethr_rwmutex *rwmtx)
return EINVAL;
}
#endif
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
if (rwmtx->type != ETHR_RWMUTEX_TYPE_NORMAL) {
- long act = ethr_atomic_read(&rwmtx->mtxb.flgs);
+ ethr_sint32_t act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
if (act == ETHR_RWMTX_R_FLG__)
rwmutex_try_complete_runlock(rwmtx, act, NULL, 0, 0, 0);
}
@@ -2179,7 +2350,7 @@ int
ethr_rwmutex_tryrlock(ethr_rwmutex *rwmtx)
{
int res = 0;
- long act;
+ ethr_sint32_t act;
ETHR_ASSERT(!ethr_not_inited__);
ETHR_ASSERT(rwmtx);
@@ -2187,25 +2358,27 @@ ethr_rwmutex_tryrlock(ethr_rwmutex *rwmtx)
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
+
switch (rwmtx->type) {
case ETHR_RWMUTEX_TYPE_NORMAL: {
#ifdef ETHR_RLOCK_WITH_INC_DEC
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
if (act & (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__))
res = EBUSY;
else {
- act = ethr_atomic_inc_read_acqb(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_inc_read_acqb(&rwmtx->mtxb.flgs);
if (act & (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__)) {
rwmutex_incdec_restore_failed_tryrlock(rwmtx);
res = EBUSY;
}
}
#else
- long exp = 0;
+ ethr_sint32_t exp = 0;
int tries = 0;
while (1) {
- act = ethr_atomic_cmpxchg_acqb(&rwmtx->mtxb.flgs, exp+1, exp);
+ act = ethr_atomic32_cmpxchg_acqb(&rwmtx->mtxb.flgs, exp+1, exp);
if (act == exp) {
res = 0;
break;
@@ -2225,49 +2398,30 @@ ethr_rwmutex_tryrlock(ethr_rwmutex *rwmtx)
case ETHR_RWMUTEX_TYPE_FREQUENT_READ:
case ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ: {
ethr_ts_event *tse = ethr_get_ts_event();
-
- rwmutex_freqread_rdrs_inc(rwmtx, tse);
-
- ETHR_MEMORY_BARRIER;
-
- act = ethr_atomic_read_acqb(&rwmtx->mtxb.flgs);
-
- if (act != ETHR_RWMTX_R_FLG__) {
- while (1) {
- long exp, new;
-
- if (act & ~(ETHR_RWMTX_R_FLG__|ETHR_RWMTX_R_WAIT_FLG__)) {
- rwmutex_freqread_restore_failed_tryrlock(rwmtx, tse);
- res = EBUSY;
- break;
- }
-
- if (act & ETHR_RWMTX_R_FLG__)
- break;
-
- exp = act;
- new = act | ETHR_RWMTX_R_FLG__;
- act = ethr_atomic_cmpxchg_acqb(&rwmtx->mtxb.flgs, new, exp);
- if (act == exp)
- break;
- }
- }
-
+ res = rwmutex_freqread_rlock(rwmtx, tse, 1);
ethr_leave_ts_event(tse);
break;
}
}
+#ifdef ETHR_MTX_CHK_EXCL
+ if (res == 0) {
+ ETHR_MTX_CHK_EXCL_SET_NON_EXCL(&rwmtx->mtxb);
+ ETHR_MTX_CHK_EXCL_IS_NOT_EXCL(&rwmtx->mtxb);
+ }
+#endif
+
ETHR_MTX_HARD_DEBUG_LFS_TRYRLOCK(&rwmtx->mtxb, res);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
return res;
}
void
ethr_rwmutex_rlock(ethr_rwmutex *rwmtx)
{
- long act;
+ ethr_sint32_t act;
ETHR_ASSERT(!ethr_not_inited__);
ETHR_ASSERT(rwmtx);
@@ -2275,20 +2429,21 @@ ethr_rwmutex_rlock(ethr_rwmutex *rwmtx)
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
+
switch (rwmtx->type) {
case ETHR_RWMUTEX_TYPE_NORMAL: {
#ifdef ETHR_RLOCK_WITH_INC_DEC
- act = ethr_atomic_inc_read_acqb(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_inc_read_acqb(&rwmtx->mtxb.flgs);
if (act & (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__))
rwmutex_normal_rlock_wait(rwmtx, act);
#else
- long exp = 0;
+ ethr_sint32_t exp = 0;
while (1) {
- act = ethr_atomic_cmpxchg_acqb(&rwmtx->mtxb.flgs, exp+1, exp);
- if (act == exp) {
+ act = ethr_atomic32_cmpxchg_acqb(&rwmtx->mtxb.flgs, exp+1, exp);
+ if (act == exp)
break;
- }
if (act & (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_W_WAIT_FLG__)) {
rwmutex_normal_rlock_wait(rwmtx, act);
@@ -2303,38 +2458,15 @@ ethr_rwmutex_rlock(ethr_rwmutex *rwmtx)
case ETHR_RWMUTEX_TYPE_FREQUENT_READ:
case ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ: {
ethr_ts_event *tse = ethr_get_ts_event();
-
- rwmutex_freqread_rdrs_inc(rwmtx, tse);
-
- ETHR_MEMORY_BARRIER;
-
- act = ethr_atomic_read_acqb(&rwmtx->mtxb.flgs);
-
- if (act != ETHR_RWMTX_R_FLG__) {
- while (1) {
- long exp, new;
-
- if (act & ~(ETHR_RWMTX_R_FLG__|ETHR_RWMTX_R_WAIT_FLG__)) {
- rwmutex_freqread_rlock_wait(rwmtx, tse, act);
- break;
- }
-
- if (act & ETHR_RWMTX_R_FLG__)
- break;
-
- exp = act;
- new = act | ETHR_RWMTX_R_FLG__;
- act = ethr_atomic_cmpxchg_acqb(&rwmtx->mtxb.flgs, new, exp);
- if (act == exp)
- break;
- }
- }
-
+ rwmutex_freqread_rlock(rwmtx, tse, 0);
ethr_leave_ts_event(tse);
break;
}
}
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
+ ETHR_MTX_CHK_EXCL_SET_NON_EXCL(&rwmtx->mtxb);
+ ETHR_MTX_CHK_EXCL_IS_NOT_EXCL(&rwmtx->mtxb);
ETHR_MTX_HARD_DEBUG_LFS_RLOCK(&rwmtx->mtxb);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
}
@@ -2342,8 +2474,10 @@ ethr_rwmutex_rlock(ethr_rwmutex *rwmtx)
void
ethr_rwmutex_runlock(ethr_rwmutex *rwmtx)
{
- long act;
+ ethr_sint32_t act;
+ ETHR_MTX_CHK_EXCL_IS_NOT_EXCL(&rwmtx->mtxb);
+ ETHR_MTX_CHK_EXCL_UNSET_NON_EXCL(&rwmtx->mtxb);
ETHR_ASSERT(!ethr_not_inited__);
ETHR_ASSERT(rwmtx);
ETHR_ASSERT(rwmtx->initialized == ETHR_RWMUTEX_INITIALIZED);
@@ -2351,13 +2485,15 @@ ethr_rwmutex_runlock(ethr_rwmutex *rwmtx)
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
ETHR_MTX_HARD_DEBUG_LFS_RUNLOCK(&rwmtx->mtxb);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
+
switch (rwmtx->type) {
case ETHR_RWMUTEX_TYPE_NORMAL:
- act = ethr_atomic_dec_read_relb(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_dec_read_relb(&rwmtx->mtxb.flgs);
if ((act & ETHR_RWMTX_WAIT_FLGS__)
&& (act & ~ETHR_RWMTX_WAIT_FLGS__) == 0) {
ETHR_ASSERT((act & ETHR_RWMTX_W_FLG__) == 0);
- rwmutex_unlock_wake(rwmtx, 0, act);
+ rwmutex_unlock_wake(rwmtx, 0, act, 0);
}
break;
@@ -2369,21 +2505,12 @@ ethr_rwmutex_runlock(ethr_rwmutex *rwmtx)
ETHR_ASSERT(act >= 0);
- ETHR_WRITE_MEMORY_BARRIER;
+ ETHR_MEMORY_BARRIER;
if (act == 0) {
-
-#ifndef ETHR_WRITE_MEMORY_BARRIER_IS_FULL
- ETHR_READ_MEMORY_BARRIER;
-#endif
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
-
- if ((act & ETHR_RWMTX_W_FLG__) == 0
- && (act & (ETHR_RWMTX_WAIT_FLGS__
- | ETHR_RWMTX_R_PEND_UNLCK_MASK__))) {
- rwmutex_try_complete_runlock(rwmtx, act, tse, 1, 0, 0);
- }
-
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
+ if (act != ETHR_RWMTX_R_FLG__)
+ rwmutex_freqread_rdrs_dec_chk_wakeup(rwmtx, tse, act);
}
ethr_leave_ts_event(tse);
@@ -2391,6 +2518,7 @@ ethr_rwmutex_runlock(ethr_rwmutex *rwmtx)
}
}
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
}
@@ -2398,7 +2526,7 @@ int
ethr_rwmutex_tryrwlock(ethr_rwmutex *rwmtx)
{
int res = 0;
- long act;
+ ethr_sint32_t act;
ETHR_ASSERT(!ethr_not_inited__);
ETHR_ASSERT(rwmtx);
@@ -2406,10 +2534,12 @@ ethr_rwmutex_tryrwlock(ethr_rwmutex *rwmtx)
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
+
switch (rwmtx->type) {
case ETHR_RWMUTEX_TYPE_NORMAL:
- act = ethr_atomic_cmpxchg_acqb(&rwmtx->mtxb.flgs,
- ETHR_RWMTX_W_FLG__, 0);
+ act = ethr_atomic32_cmpxchg_acqb(&rwmtx->mtxb.flgs,
+ ETHR_RWMTX_W_FLG__, 0);
if (act != 0)
res = EBUSY;
break;
@@ -2418,29 +2548,36 @@ ethr_rwmutex_tryrwlock(ethr_rwmutex *rwmtx)
case ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ:
res = 0;
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
do {
- if (act & (ETHR_RWMTX_W_FLG__|ETHR_RWMTX_WAIT_FLGS__)) {
- res = EBUSY;
- break;
- }
-
- if (act & ETHR_RWMTX_R_MASK__) {
+ if (act == 0)
+ act = ethr_atomic32_cmpxchg_acqb(&rwmtx->mtxb.flgs,
+ ETHR_RWMTX_W_FLG__, 0);
+ else if (act == ETHR_RWMTX_R_FLG__) {
res = rwmutex_try_complete_runlock(rwmtx, act, NULL,
0, 1, 1);
break;
}
-
- act = ethr_atomic_cmpxchg_acqb(&rwmtx->mtxb.flgs,
- ETHR_RWMTX_W_FLG__, 0);
+ else {
+ res = EBUSY;
+ break;
+ }
} while (act != 0);
break;
}
+#ifdef ETHR_MTX_CHK_EXCL
+ if (res == 0) {
+ ETHR_MTX_CHK_EXCL_SET_EXCL(&rwmtx->mtxb);
+ ETHR_MTX_CHK_EXCL_IS_NOT_NON_EXCL(&rwmtx->mtxb);
+ }
+#endif
+
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
ETHR_MTX_HARD_DEBUG_LFS_TRYRWLOCK(&rwmtx->mtxb, res);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
@@ -2450,17 +2587,19 @@ ethr_rwmutex_tryrwlock(ethr_rwmutex *rwmtx)
void
ethr_rwmutex_rwlock(ethr_rwmutex *rwmtx)
{
- long act;
+ ethr_sint32_t act;
ETHR_ASSERT(!ethr_not_inited__);
ETHR_ASSERT(rwmtx);
ETHR_ASSERT(rwmtx->initialized == ETHR_RWMUTEX_INITIALIZED);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
+
switch (rwmtx->type) {
case ETHR_RWMUTEX_TYPE_NORMAL:
- act = ethr_atomic_cmpxchg_acqb(&rwmtx->mtxb.flgs,
- ETHR_RWMTX_W_FLG__, 0);
+ act = ethr_atomic32_cmpxchg_acqb(&rwmtx->mtxb.flgs,
+ ETHR_RWMTX_W_FLG__, 0);
if (act != 0)
rwmutex_normal_rwlock_wait(rwmtx, act);
break;
@@ -2468,7 +2607,7 @@ ethr_rwmutex_rwlock(ethr_rwmutex *rwmtx)
case ETHR_RWMUTEX_TYPE_FREQUENT_READ:
case ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ:
- act = ethr_atomic_read(&rwmtx->mtxb.flgs);
+ act = ethr_atomic32_read(&rwmtx->mtxb.flgs);
do {
@@ -2477,23 +2616,26 @@ ethr_rwmutex_rwlock(ethr_rwmutex *rwmtx)
break;
}
- act = ethr_atomic_cmpxchg_acqb(&rwmtx->mtxb.flgs,
- ETHR_RWMTX_W_FLG__, 0);
+ act = ethr_atomic32_cmpxchg_acqb(&rwmtx->mtxb.flgs,
+ ETHR_RWMTX_W_FLG__, 0);
} while (act != 0);
break;
}
+ ETHR_MTX_CHK_EXCL_SET_EXCL(&rwmtx->mtxb);
+ ETHR_MTX_CHK_EXCL_IS_NOT_NON_EXCL(&rwmtx->mtxb);
ETHR_MTX_HARD_DEBUG_LFS_RWLOCK(&rwmtx->mtxb);
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
}
void
ethr_rwmutex_rwunlock(ethr_rwmutex *rwmtx)
{
- long act;
+ ethr_sint32_t act;
ETHR_ASSERT(!ethr_not_inited__);
ETHR_ASSERT(rwmtx);
ETHR_ASSERT(rwmtx->initialized == ETHR_RWMUTEX_INITIALIZED);
@@ -2501,24 +2643,30 @@ ethr_rwmutex_rwunlock(ethr_rwmutex *rwmtx)
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
ETHR_MTX_HARD_DEBUG_LFS_RWUNLOCK(&rwmtx->mtxb);
+ ETHR_MTX_CHK_EXCL_IS_NOT_NON_EXCL(&rwmtx->mtxb);
+ ETHR_MTX_CHK_EXCL_UNSET_EXCL(&rwmtx->mtxb);
+
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
+
switch (rwmtx->type) {
case ETHR_RWMUTEX_TYPE_NORMAL:
- act = ethr_atomic_cmpxchg_relb(&rwmtx->mtxb.flgs,
- 0, ETHR_RWMTX_W_FLG__);
+ act = ethr_atomic32_cmpxchg_relb(&rwmtx->mtxb.flgs,
+ 0, ETHR_RWMTX_W_FLG__);
if (act != ETHR_RWMTX_W_FLG__)
- rwmutex_unlock_wake(rwmtx, 1, act);
+ rwmutex_unlock_wake(rwmtx, 1, act, 0);
break;
case ETHR_RWMUTEX_TYPE_FREQUENT_READ:
case ETHR_RWMUTEX_TYPE_EXTREMELY_FREQUENT_READ:
- act = ethr_atomic_cmpxchg_relb(&rwmtx->mtxb.flgs, 0,
- ETHR_RWMTX_W_FLG__);
+ act = ethr_atomic32_cmpxchg_relb(&rwmtx->mtxb.flgs, 0,
+ ETHR_RWMTX_W_FLG__);
if (act != ETHR_RWMTX_W_FLG__)
- rwmutex_unlock_wake(rwmtx, 1, act);
+ rwmutex_unlock_wake(rwmtx, 1, act, 0);
break;
}
ETHR_MTX_HARD_DEBUG_FENCE_CHK(rwmtx);
+ ETHR_MTX_DBG_CHK_UNUSED_FLG_BITS(rwmtx);
}
#else
@@ -2636,7 +2784,7 @@ static void
hard_debug_chk_q__(struct ethr_mutex_base_ *mtxb, int is_rwmtx)
{
int res;
- long flgs = ethr_atomic_read(&mtxb->flgs);
+ ethr_sint32_t flgs = ethr_atomic32_read(&mtxb->flgs);
ETHR_MTX_HARD_ASSERT(res == 0);
@@ -2659,12 +2807,12 @@ hard_debug_chk_q__(struct ethr_mutex_base_ *mtxb, int is_rwmtx)
tse = mtxb->q;
do {
- long type;
+ ethr_sint32_t type;
ETHR_MTX_HARD_ASSERT(tse->next->prev == tse);
ETHR_MTX_HARD_ASSERT(tse->prev->next == tse);
- type = ethr_atomic_read(&tse->uaflgs);
+ type = ethr_atomic32_read(&tse->uaflgs);
ETHR_MTX_HARD_ASSERT(type == tse->uflgs);
switch (type) {
case ETHR_RWMTX_W_WAIT_FLG__:
diff --git a/erts/lib_src/pthread/ethr_event.c b/erts/lib_src/pthread/ethr_event.c
index 6731c0eb46..9434d60d0a 100644
--- a/erts/lib_src/pthread/ethr_event.c
+++ b/erts/lib_src/pthread/ethr_event.c
@@ -24,6 +24,10 @@
#define ETHR_INLINE_FUNC_NAME_(X) X ## __
#define ETHR_EVENT_IMPL__
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "ethread.h"
#if defined(ETHR_LINUX_FUTEX_IMPL__)
@@ -37,7 +41,7 @@
int
ethr_event_init(ethr_event *e)
{
- ethr_atomic_init(&e->futex, ETHR_EVENT_OFF__);
+ ethr_atomic32_init(&e->futex, ETHR_EVENT_OFF__);
return 0;
}
@@ -52,7 +56,7 @@ wait__(ethr_event *e, int spincount)
{
unsigned sc = spincount;
int res;
- long val;
+ ethr_sint32_t val;
int until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
if (spincount < 0)
@@ -60,7 +64,7 @@ wait__(ethr_event *e, int spincount)
while (1) {
while (1) {
- val = ethr_atomic_read(&e->futex);
+ val = ethr_atomic32_read(&e->futex);
if (val == ETHR_EVENT_ON__)
return 0;
if (sc == 0)
@@ -76,16 +80,18 @@ wait__(ethr_event *e, int spincount)
}
if (val != ETHR_EVENT_OFF_WAITER__) {
- val = ethr_atomic_cmpxchg(&e->futex,
- ETHR_EVENT_OFF_WAITER__,
- ETHR_EVENT_OFF__);
+ val = ethr_atomic32_cmpxchg(&e->futex,
+ ETHR_EVENT_OFF_WAITER__,
+ ETHR_EVENT_OFF__);
if (val == ETHR_EVENT_ON__)
return 0;
ETHR_ASSERT(val == ETHR_EVENT_OFF__);
}
- res = ETHR_FUTEX__(&e->futex, ETHR_FUTEX_WAIT__, ETHR_EVENT_OFF_WAITER__);
+ res = ETHR_FUTEX__(&e->futex,
+ ETHR_FUTEX_WAIT__,
+ ETHR_EVENT_OFF_WAITER__);
if (res == EINTR)
break;
if (res != 0 && res != EWOULDBLOCK)
@@ -102,7 +108,7 @@ int
ethr_event_init(ethr_event *e)
{
int res;
- ethr_atomic_init(&e->state, ETHR_EVENT_OFF__);
+ ethr_atomic32_init(&e->state, ETHR_EVENT_OFF__);
res = pthread_mutex_init(&e->mtx, NULL);
if (res != 0)
return res;
@@ -131,7 +137,7 @@ static ETHR_INLINE int
wait__(ethr_event *e, int spincount)
{
int sc = spincount;
- long val;
+ ethr_sint32_t val;
int res, ulres;
int until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS;
@@ -139,7 +145,7 @@ wait__(ethr_event *e, int spincount)
ETHR_FATAL_ERROR__(EINVAL);
while (1) {
- val = ethr_atomic_read(&e->state);
+ val = ethr_atomic32_read(&e->state);
if (val == ETHR_EVENT_ON__)
return 0;
if (sc == 0)
@@ -155,9 +161,9 @@ wait__(ethr_event *e, int spincount)
}
if (val != ETHR_EVENT_OFF_WAITER__) {
- val = ethr_atomic_cmpxchg(&e->state,
- ETHR_EVENT_OFF_WAITER__,
- ETHR_EVENT_OFF__);
+ val = ethr_atomic32_cmpxchg(&e->state,
+ ETHR_EVENT_OFF_WAITER__,
+ ETHR_EVENT_OFF__);
if (val == ETHR_EVENT_ON__)
return 0;
ETHR_ASSERT(val == ETHR_EVENT_OFF__);
@@ -172,7 +178,7 @@ wait__(ethr_event *e, int spincount)
while (1) {
- val = ethr_atomic_read(&e->state);
+ val = ethr_atomic32_read(&e->state);
if (val == ETHR_EVENT_ON__)
break;
diff --git a/erts/lib_src/pthread/ethread.c b/erts/lib_src/pthread/ethread.c
index ea1d9d43f0..f047104103 100644
--- a/erts/lib_src/pthread/ethread.c
+++ b/erts/lib_src/pthread/ethread.c
@@ -72,7 +72,7 @@ static void thr_exit_cleanup(void)
/* Argument passed to thr_wrapper() */
typedef struct {
- ethr_atomic_t result;
+ ethr_atomic32_t result;
ethr_ts_event *tse;
void *(*thr_func)(void *);
void *arg;
@@ -81,14 +81,14 @@ typedef struct {
static void *thr_wrapper(void *vtwd)
{
- long result;
+ ethr_sint32_t result;
void *res;
ethr_thr_wrap_data__ *twd = (ethr_thr_wrap_data__ *) vtwd;
void *(*thr_func)(void *) = twd->thr_func;
void *arg = twd->arg;
ethr_ts_event *tsep = NULL;
- result = (long) ethr_make_ts_event__(&tsep);
+ result = (ethr_sint32_t) ethr_make_ts_event__(&tsep);
if (result == 0) {
tsep->iflgs |= ETHR_TS_EV_ETHREAD;
@@ -99,7 +99,7 @@ static void *thr_wrapper(void *vtwd)
tsep = twd->tse; /* We aren't allowed to follow twd after
result has been set! */
- ethr_atomic_set(&twd->result, result);
+ ethr_atomic32_set(&twd->result, result);
ethr_event_set(&tsep->event);
@@ -191,7 +191,7 @@ ethr_thr_create(ethr_tid *tid, void * (*func)(void *), void *arg,
}
#endif
- ethr_atomic_init(&twd.result, -1);
+ ethr_atomic32_init(&twd.result, (ethr_sint32_t) -1);
twd.tse = ethr_get_ts_event();
twd.thr_func = func;
twd.arg = arg;
@@ -252,10 +252,10 @@ ethr_thr_create(ethr_tid *tid, void * (*func)(void *), void *arg,
/* Wait for child to initialize... */
while (1) {
- long result;
+ ethr_sint32_t result;
ethr_event_reset(&twd.tse->event);
- result = ethr_atomic_read(&twd.result);
+ result = ethr_atomic32_read(&twd.result);
if (result == 0)
break;
@@ -349,32 +349,6 @@ ethr_leave_ts_event(ethr_ts_event *tsep)
}
/*
- * Current time
- */
-
-int
-ethr_time_now(ethr_timeval *time)
-{
- int res;
- struct timeval tv;
-#if ETHR_XCHK
- if (ethr_not_inited__) {
- ETHR_ASSERT(0);
- return EACCES;
- }
- if (!time) {
- ETHR_ASSERT(0);
- return EINVAL;
- }
-#endif
-
- res = gettimeofday(&tv, NULL);
- time->tv_sec = (long) tv.tv_sec;
- time->tv_nsec = ((long) tv.tv_usec)*1000;
- return res;
-}
-
-/*
* Thread specific data
*/
diff --git a/erts/lib_src/win/ethr_event.c b/erts/lib_src/win/ethr_event.c
index ddb4780ff1..68f093f49c 100644
--- a/erts/lib_src/win/ethr_event.c
+++ b/erts/lib_src/win/ethr_event.c
@@ -28,6 +28,9 @@
/* --- Windows implementation of thread events ------------------------------ */
+#pragma intrinsic(_InterlockedExchangeAdd)
+#pragma intrinsic(_InterlockedCompareExchange)
+
int
ethr_event_init(ethr_event *e)
{
@@ -72,10 +75,10 @@ wait(ethr_event *e, int spincount)
while (1) {
long on;
while (1) {
-#if ETHR_IMMED_ATOMIC_SET_GET_SAFE__
+#if ETHR_READ_AND_SET_WITHOUT_INTERLOCKED_OP__
state = e->state;
#else
- state = InterlockedExchangeAdd(&e->state, (LONG) 0);
+ state = _InterlockedExchangeAdd(&e->state, (LONG) 0);
#endif
if (state == ETHR_EVENT_ON__)
return 0;
diff --git a/erts/lib_src/win/ethread.c b/erts/lib_src/win/ethread.c
index 69523edf94..789a360b11 100644
--- a/erts/lib_src/win/ethread.c
+++ b/erts/lib_src/win/ethread.c
@@ -49,7 +49,7 @@
/* Argument passed to thr_wrapper() */
typedef struct {
ethr_tid *tid;
- ethr_atomic_t result;
+ ethr_atomic32_t result;
ethr_ts_event *tse;
void *(*thr_func)(void *);
void *arg;
@@ -93,20 +93,20 @@ static void thr_exit_cleanup(ethr_tid *tid, void *res)
static unsigned __stdcall thr_wrapper(LPVOID vtwd)
{
ethr_tid my_tid;
- long result;
+ ethr_sint32_t result;
void *res;
ethr_thr_wrap_data__ *twd = (ethr_thr_wrap_data__ *) vtwd;
void *(*thr_func)(void *) = twd->thr_func;
void *arg = twd->arg;
ethr_ts_event *tsep = NULL;
- result = (long) ethr_make_ts_event__(&tsep);
+ result = (ethr_sint32_t) ethr_make_ts_event__(&tsep);
if (result == 0) {
tsep->iflgs |= ETHR_TS_EV_ETHREAD;
my_tid = *twd->tid;
if (!TlsSetValue(own_tid_key, (LPVOID) &my_tid)) {
- result = (long) ethr_win_get_errno__();
+ result = (ethr_sint32_t) ethr_win_get_errno__();
ethr_free_ts_event__(tsep);
}
else {
@@ -118,7 +118,7 @@ static unsigned __stdcall thr_wrapper(LPVOID vtwd)
tsep = twd->tse; /* We aren't allowed to follow twd after
result has been set! */
- ethr_atomic_set(&twd->result, result);
+ ethr_atomic32_set(&twd->result, result);
ethr_event_set(&tsep->event);
@@ -128,28 +128,6 @@ static unsigned __stdcall thr_wrapper(LPVOID vtwd)
return 0;
}
-#ifdef __GNUC__
-#define LL_LITERAL(X) X##LL
-#else
-#define LL_LITERAL(X) X##i64
-#endif
-
-#define EPOCH_JULIAN_DIFF LL_LITERAL(11644473600)
-
-static ETHR_INLINE void
-get_curr_time(long *sec, long *nsec)
-{
- SYSTEMTIME t;
- FILETIME ft;
- LONGLONG lft;
-
- GetSystemTime(&t);
- SystemTimeToFileTime(&t, &ft);
- memcpy(&lft, &ft, sizeof(lft));
- *nsec = ((long) (lft % LL_LITERAL(10000000)))*100;
- *sec = (long) ((lft / LL_LITERAL(10000000)) - EPOCH_JULIAN_DIFF);
-}
-
/* internal exports */
int
@@ -320,7 +298,7 @@ ethr_thr_create(ethr_tid *tid, void * (*func)(void *), void *arg,
ETHR_PAGE_ALIGN(ETHR_KW2B(suggested_stack_size));
}
- ethr_atomic_init(&twd.result, -1);
+ ethr_atomic32_init(&twd.result, -1);
twd.tid = tid;
twd.thr_func = func;
@@ -352,11 +330,11 @@ ethr_thr_create(ethr_tid *tid, void * (*func)(void *), void *arg,
/* Wait for child to initialize... */
while (1) {
- long result;
+ ethr_sint32_t result;
int err;
ethr_event_reset(&twd.tse->event);
- result = ethr_atomic_read(&twd.result);
+ result = ethr_atomic32_read(&twd.result);
if (result == 0)
break;
@@ -517,23 +495,6 @@ ethr_equal_tids(ethr_tid tid1, ethr_tid tid2)
return tid1.id == tid2.id && tid1.id != ETHR_INVALID_TID_ID;
}
-int
-ethr_time_now(ethr_timeval *time)
-{
-#if ETHR_XCHK
- if (ethr_not_inited__) {
- ETHR_ASSERT(0);
- return EACCES;
- }
- if (!time) {
- ETHR_ASSERT(0);
- return EINVAL;
- }
-#endif
- get_curr_time(&time->tv_sec, &time->tv_nsec);
- return 0;
-}
-
/*
* Thread specific data
*/
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index 222809e662..bff3f7f9de 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 65c7369b76..5d2f187435 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 f1b54b7fcb..7e492057da 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 abf17bcb0e..c443866671 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 a3f300268f..4a75e43e73 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 a777971b32..30bbfb0943 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 0fe38a1fb2..6681466767 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 7108bf44d0..593bb8dbed 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 935c2de253..d6dc070436 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -427,17 +427,11 @@ delay_trap(Result, Timeout) -> receive after Timeout -> Result end.
%% have to reflect that, which we cannot forsee.
%%
set_cookie(Node, C) when Node =/= nonode@nohost, is_atom(Node) ->
- Res = case C of
- _ when is_atom(C) ->
- auth:set_cookie(Node, C);
- {CI,CO} when is_atom(CI), is_atom(CO) ->
- auth:set_cookie(Node, {CI, CO});
- _ ->
- error
- end,
- case Res of
- error -> exit(badarg);
- Other -> Other
+ case is_atom(C) of
+ true ->
+ auth:set_cookie(Node, C);
+ false ->
+ error(badarg)
end.
-spec get_cookie() -> atom().
diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl
index 3b98b9cddc..24430a3d40 100644
--- a/erts/preloaded/src/init.erl
+++ b/erts/preloaded/src/init.erl
@@ -51,6 +51,9 @@
get_status/0,boot/1,get_arguments/0,get_plain_arguments/0,
get_argument/1,script_id/0]).
+%% for the on_load functionality; not for general use
+-export([run_on_load_handlers/0]).
+
%% internal exports
-export([fetch_loaded/0,ensure_loaded/1,make_permanent/2,
notify_when_started/1,wait_until_started/0,
@@ -69,6 +72,7 @@
script_id = [],
loaded = [],
subscribed = []}).
+-type state() :: #state{}.
-define(ON_LOAD_HANDLER, init__boot__on_load_handler).
@@ -143,10 +147,10 @@ restart() -> init ! {stop,restart}, ok.
-spec reboot() -> 'ok'.
reboot() -> init ! {stop,reboot}, ok.
--spec stop() -> no_return().
+-spec stop() -> 'ok'.
stop() -> init ! {stop,stop}, ok.
--spec stop(non_neg_integer() | string()) -> no_return().
+-spec stop(non_neg_integer() | string()) -> 'ok'.
stop(Status) -> init ! {stop,{stop,Status}}, ok.
-spec boot([binary()]) -> no_return().
@@ -275,7 +279,7 @@ crash(String, List) ->
halt(halt_string(String, List)).
%% Status is {InternalStatus,ProvidedStatus}
--spec boot_loop(pid(), #state{}) -> no_return().
+-spec boot_loop(pid(), state()) -> no_return().
boot_loop(BootPid, State) ->
receive
{BootPid,loaded,ModLoaded} ->
@@ -308,24 +312,6 @@ boot_loop(BootPid, State) ->
{stop,Reason} ->
stop(Reason,State);
{From,fetch_loaded} -> %% Fetch and reset initially loaded modules.
- case whereis(?ON_LOAD_HANDLER) of
- undefined ->
- %% There is no on_load handler process,
- %% probably because init:restart/0 has been
- %% called and it is not the first time we
- %% pass through here.
- ok;
- Pid when is_pid(Pid) ->
- Pid ! run_on_load,
- receive
- {'EXIT',Pid,on_load_done} ->
- ok;
- {'EXIT',Pid,Res} ->
- %% Failure to run an on_load handler.
- %% This is fatal during start-up.
- exit(Res)
- end
- end,
From ! {init,State#state.loaded},
garb_boot_loop(BootPid,State#state{loaded = []});
{From,{ensure_loaded,Module}} ->
@@ -736,6 +722,7 @@ do_boot(Init,Flags,Start) ->
BootList = get_boot(BootFile,Root),
LoadMode = b2a(get_flag('-mode',Flags,false)),
Deb = b2a(get_flag('-init_debug',Flags,false)),
+ catch ?ON_LOAD_HANDLER ! {init_debug_flag,Deb},
BootVars = get_flag_args('-boot_var',Flags),
ParallelLoad =
(Pgm =:= "efile") and (erlang:system_info(thread_pool_size) > 0),
@@ -1335,23 +1322,44 @@ archive_extension() ->
%%% Support for handling of on_load functions.
%%%
+run_on_load_handlers() ->
+ Ref = monitor(process, ?ON_LOAD_HANDLER),
+ catch ?ON_LOAD_HANDLER ! run_on_load,
+ receive
+ {'DOWN',Ref,process,_,noproc} ->
+ %% There is no on_load handler process,
+ %% probably because init:restart/0 has been
+ %% called and it is not the first time we
+ %% pass through here.
+ ok;
+ {'DOWN',Ref,process,_,on_load_done} ->
+ ok;
+ {'DOWN',Ref,process,_,Res} ->
+ %% Failure to run an on_load handler.
+ %% This is fatal during start-up.
+ exit(Res)
+ end.
+
start_on_load_handler_process() ->
register(?ON_LOAD_HANDLER,
- spawn_link(fun on_load_handler_init/0)).
+ spawn(fun on_load_handler_init/0)).
on_load_handler_init() ->
- on_load_loop([]).
+ on_load_loop([], false).
-on_load_loop(Mods) ->
+on_load_loop(Mods, Debug0) ->
receive
+ {init_debug_flag,Debug} ->
+ on_load_loop(Mods, Debug);
{loaded,Mod} ->
- on_load_loop([Mod|Mods]);
+ on_load_loop([Mod|Mods], Debug0);
run_on_load ->
- run_on_load_handlers(Mods),
+ run_on_load_handlers(Mods, Debug0),
exit(on_load_done)
end.
-run_on_load_handlers([M|Ms]) ->
+run_on_load_handlers([M|Ms], Debug) ->
+ debug(Debug, {running_on_load_handler,M}),
Fun = fun() ->
Res = erlang:call_on_load_function(M),
exit(Res)
@@ -1363,9 +1371,12 @@ run_on_load_handlers([M|Ms]) ->
erlang:finish_after_on_load(M, Keep),
case Keep of
false ->
- exit({on_load_function_failed,M});
+ Error = {on_load_function_failed,M},
+ debug(Debug, Error),
+ exit(Error);
true ->
- run_on_load_handlers(Ms)
+ debug(Debug, {on_load_handler_returned_ok,M}),
+ run_on_load_handlers(Ms, Debug)
end
end;
-run_on_load_handlers([]) -> ok.
+run_on_load_handlers([], _) -> ok.
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index 7f24889bb2..10be852e92 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -109,6 +109,8 @@
-define(FILE_RESP_LDATA, 6).
-define(FILE_RESP_N2DATA, 7).
-define(FILE_RESP_EOF, 8).
+-define(FILE_RESP_FNAME, 9).
+-define(FILE_RESP_ALL_DATA, 10).
%% Open modes for the driver's open function.
-define(EFILE_MODE_READ, 1).
@@ -153,7 +155,7 @@
%% Opens a file using the driver port Port. Returns {error, Reason}
%% | {ok, FileDescriptor}
open(Port, File, ModeList) when is_port(Port),
- is_list(File),
+ (is_list(File) orelse is_binary(File)),
is_list(ModeList) ->
case open_mode(ModeList) of
{Mode, _Portopts, _Setopts} ->
@@ -165,10 +167,11 @@ open(_,_,_) ->
{error, badarg}.
%% Opens a file. Returns {error, Reason} | {ok, FileDescriptor}.
-open(File, ModeList) when is_list(File), is_list(ModeList) ->
+open(File, ModeList) when (is_list(File) orelse is_binary(File)),
+ is_list(ModeList) ->
case open_mode(ModeList) of
{Mode, Portopts, Setopts} ->
- open_int({?FD_DRV, Portopts}, File, Mode, Setopts);
+ open_int({?FD_DRV, Portopts},File, Mode, Setopts);
Reason ->
{error, Reason}
end;
@@ -196,7 +199,7 @@ open_int({Driver, Portopts}, File, Mode, Setopts) ->
end;
open_int(Port, File, Mode, Setopts) ->
M = Mode band ?EFILE_MODE_MASK,
- case drv_command(Port, [<<?FILE_OPEN, M:32>>, File, 0]) of
+ case drv_command(Port, [<<?FILE_OPEN, M:32>>, pathname(File)]) of
{ok, Number} ->
open_int_setopts(Port, Number, Setopts);
Error ->
@@ -489,7 +492,7 @@ ipread_s32bu_p32bu(#file_descriptor{module = ?MODULE, data = {_, _}},
%% Returns {ok, Contents} | {error, Reason}
-read_file(File) ->
+read_file(File) when (is_list(File) orelse is_binary(File)) ->
case drv_open(?FD_DRV, [binary]) of
{ok, Port} ->
Result = read_file(Port, File),
@@ -497,11 +500,14 @@ read_file(File) ->
Result;
{error, _} = Error ->
Error
- end.
+ end;
+read_file(_) ->
+ {error, badarg}.
%% Takes a Port opened with open/1.
-read_file(Port, File) when is_port(Port) ->
- Cmd = [?FILE_READ_FILE | File],
+read_file(Port, File) when is_port(Port),
+ (is_list(File) orelse is_binary(File))->
+ Cmd = [?FILE_READ_FILE | pathname(File)],
case drv_command(Port, Cmd) of
{error, enomem} ->
%% It could possibly help to do a
@@ -512,12 +518,14 @@ read_file(Port, File) when is_port(Port) ->
drv_command(Port, Cmd);
Result ->
Result
- end.
+ end;
+read_file(_,_) ->
+ {error, badarg}.
%% Returns {error, Reason} | ok.
-write_file(File, Bin) ->
+write_file(File, Bin) when (is_list(File) orelse is_binary(File)) ->
case open(File, [binary, write]) of
{ok, Handle} ->
Result = write(Handle, Bin),
@@ -525,8 +533,10 @@ write_file(File, Bin) ->
Result;
Error ->
Error
- end.
-
+ end;
+write_file(_, _) ->
+ {error, badarg}.
+
%%%-----------------------------------------------------------------
@@ -539,7 +549,7 @@ write_file(File, Bin) ->
%% Returns {ok, Port}, the Port should be used as first argument in all
%% the following functions. Returns {error, Reason} upon failure.
start() ->
- try erlang:open_port({spawn, atom_to_list(?DRV)}, []) of
+ try erlang:open_port({spawn, atom_to_list(?DRV)}, [binary]) of
Port ->
{ok, Port}
catch
@@ -596,7 +606,7 @@ get_cwd(_, _) ->
{error, badarg}.
get_cwd_int(Drive) ->
- get_cwd_int({?DRV, []}, Drive).
+ get_cwd_int({?DRV, [binary]}, Drive).
get_cwd_int(Port, Drive) ->
drv_command(Port, <<?FILE_PWD, Drive>>).
@@ -606,7 +616,7 @@ get_cwd_int(Port, Drive) ->
%% set_cwd/{1,2}
set_cwd(Dir) ->
- set_cwd_int({?DRV, []}, Dir).
+ set_cwd_int({?DRV, [binary]}, Dir).
set_cwd(Port, Dir) when is_port(Port) ->
set_cwd_int(Port, Dir).
@@ -632,89 +642,88 @@ set_cwd_int(Port, Dir0) ->
end),
%% Dir is now either a string or an EXIT tuple.
%% An EXIT tuple will fail in the following catch.
- drv_command(Port, [?FILE_CHDIR, Dir, 0]).
+ drv_command(Port, [?FILE_CHDIR, pathname(Dir)]).
%% delete/{1,2}
delete(File) ->
- delete_int({?DRV, []}, File).
+ delete_int({?DRV, [binary]}, File).
delete(Port, File) when is_port(Port) ->
delete_int(Port, File).
delete_int(Port, File) ->
- drv_command(Port, [?FILE_DELETE, File, 0]).
+ drv_command(Port, [?FILE_DELETE, pathname(File)]).
%% rename/{2,3}
rename(From, To) ->
- rename_int({?DRV, []}, From, To).
+ rename_int({?DRV, [binary]}, From, To).
rename(Port, From, To) when is_port(Port) ->
rename_int(Port, From, To).
rename_int(Port, From, To) ->
- drv_command(Port, [?FILE_RENAME, From, 0, To, 0]).
+ drv_command(Port, [?FILE_RENAME, pathname(From), pathname(To)]).
%% make_dir/{1,2}
make_dir(Dir) ->
- make_dir_int({?DRV, []}, Dir).
+ make_dir_int({?DRV, [binary]}, Dir).
make_dir(Port, Dir) when is_port(Port) ->
make_dir_int(Port, Dir).
make_dir_int(Port, Dir) ->
- drv_command(Port, [?FILE_MKDIR, Dir, 0]).
+ drv_command(Port, [?FILE_MKDIR, pathname(Dir)]).
%% del_dir/{1,2}
del_dir(Dir) ->
- del_dir_int({?DRV, []}, Dir).
+ del_dir_int({?DRV, [binary]}, Dir).
del_dir(Port, Dir) when is_port(Port) ->
del_dir_int(Port, Dir).
del_dir_int(Port, Dir) ->
- drv_command(Port, [?FILE_RMDIR, Dir, 0]).
+ drv_command(Port, [?FILE_RMDIR, pathname(Dir)]).
%% read_file_info/{1,2}
read_file_info(File) ->
- read_file_info_int({?DRV, []}, File).
+ read_file_info_int({?DRV, [binary]}, File).
read_file_info(Port, File) when is_port(Port) ->
read_file_info_int(Port, File).
read_file_info_int(Port, File) ->
- drv_command(Port, [?FILE_FSTAT, File, 0]).
+ drv_command(Port, [?FILE_FSTAT, pathname(File)]).
%% altname/{1,2}
altname(File) ->
- altname_int({?DRV, []}, File).
+ altname_int({?DRV, [binary]}, File).
altname(Port, File) when is_port(Port) ->
altname_int(Port, File).
altname_int(Port, File) ->
- drv_command(Port, [?FILE_ALTNAME, File, 0]).
-
+ drv_command(Port, [?FILE_ALTNAME, pathname(File)]).
%% write_file_info/{2,3}
write_file_info(File, Info) ->
- write_file_info_int({?DRV, []}, File, Info).
+ write_file_info_int({?DRV, [binary]}, File, Info).
write_file_info(Port, File, Info) when is_port(Port) ->
write_file_info_int(Port, File, Info).
@@ -740,72 +749,72 @@ write_file_info_int(Port,
date_to_bytes(Atime),
date_to_bytes(Mtime),
date_to_bytes(Ctime),
- File, 0]).
+ pathname(File)]).
%% make_link/{2,3}
make_link(Old, New) ->
- make_link_int({?DRV, []}, Old, New).
+ make_link_int({?DRV, [binary]}, Old, New).
make_link(Port, Old, New) when is_port(Port) ->
make_link_int(Port, Old, New).
make_link_int(Port, Old, New) ->
- drv_command(Port, [?FILE_LINK, Old, 0, New, 0]).
+ drv_command(Port, [?FILE_LINK, pathname(Old), pathname(New)]).
%% make_symlink/{2,3}
make_symlink(Old, New) ->
- make_symlink_int({?DRV, []}, Old, New).
+ make_symlink_int({?DRV, [binary]}, Old, New).
make_symlink(Port, Old, New) when is_port(Port) ->
make_symlink_int(Port, Old, New).
make_symlink_int(Port, Old, New) ->
- drv_command(Port, [?FILE_SYMLINK, Old, 0, New, 0]).
+ drv_command(Port, [?FILE_SYMLINK, pathname(Old), pathname(New)]).
%% read_link/{2,3}
read_link(Link) ->
- read_link_int({?DRV, []}, Link).
+ read_link_int({?DRV, [binary]}, Link).
read_link(Port, Link) when is_port(Port) ->
read_link_int(Port, Link).
read_link_int(Port, Link) ->
- drv_command(Port, [?FILE_READLINK, Link, 0]).
+ drv_command(Port, [?FILE_READLINK, pathname(Link)]).
%% read_link_info/{2,3}
read_link_info(Link) ->
- read_link_info_int({?DRV, []}, Link).
+ read_link_info_int({?DRV, [binary]}, Link).
read_link_info(Port, Link) when is_port(Port) ->
read_link_info_int(Port, Link).
read_link_info_int(Port, Link) ->
- drv_command(Port, [?FILE_LSTAT, Link, 0]).
+ drv_command(Port, [?FILE_LSTAT, pathname(Link)]).
%% list_dir/{1,2}
list_dir(Dir) ->
- list_dir_int({?DRV, []}, Dir).
+ list_dir_int({?DRV, [binary]}, Dir).
list_dir(Port, Dir) when is_port(Port) ->
list_dir_int(Port, Dir).
list_dir_int(Port, Dir) ->
- drv_command(Port, [?FILE_READDIR, Dir, 0], []).
+ drv_command(Port, [?FILE_READDIR, pathname(Dir)], []).
@@ -1026,8 +1035,6 @@ lseek_position(_) ->
translate_response(?FILE_RESP_OK, []) ->
ok;
-translate_response(?FILE_RESP_OK, Data) ->
- {ok, Data};
translate_response(?FILE_RESP_ERROR, List) when is_list(List) ->
{error, list_to_atom(List)};
translate_response(?FILE_RESP_NUMBER, List) ->
@@ -1074,6 +1081,16 @@ translate_response(?FILE_RESP_N2DATA = X, L0) when is_list(L0) ->
end;
translate_response(?FILE_RESP_EOF, []) ->
eof;
+translate_response(?FILE_RESP_FNAME, []) ->
+ ok;
+translate_response(?FILE_RESP_FNAME, Data) when is_binary(Data) ->
+ {ok, prim_file:internal_native2name(Data)};
+translate_response(?FILE_RESP_FNAME, Data) ->
+ {ok, Data};
+
+translate_response(?FILE_RESP_ALL_DATA, Data) ->
+ {ok, Data};
+
translate_response(X, Data) ->
{error, {bad_response_from_port, [X | Data]}}.
@@ -1209,3 +1226,9 @@ lists_split([Hd | Tl], N, Rev) ->
reverse(X) -> lists:reverse(X, []).
reverse(L, T) -> lists:reverse(L, T).
+
+% Will add zero termination too
+% The 'EXIT' tuple from a bad argument will eventually generate an error
+% in list_to_binary, which is caught and generates the {error,badarg} return
+pathname(File) ->
+ (catch prim_file:internal_name2native(File)).
diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl
index 91d39c6a73..2e4a2866e6 100644
--- a/erts/preloaded/src/prim_inet.erl
+++ b/erts/preloaded/src/prim_inet.erl
@@ -37,7 +37,7 @@
-export([setopt/3, setopts/2, getopt/2, getopts/2, is_sockopt_val/2]).
-export([chgopt/3, chgopts/2]).
-export([getstat/2, getfd/1, getindex/1, getstatus/1, gettype/1,
- getiflist/1, ifget/3, ifset/3,
+ getifaddrs/1, getiflist/1, ifget/3, ifset/3,
gethostname/1]).
-export([getservbyname/3, getservbyport/3]).
-export([peername/1, setpeername/2]).
@@ -216,9 +216,10 @@ bindx(S, AddFlag, Addrs) ->
sctp ->
%% Really multi-homed "bindx". Stringified args:
%% [AddFlag, (Port, IP)+]:
- Args = ?int8(AddFlag) ++
- lists:concat([?int16(Port)++ip_to_bytes(IP) ||
- {IP, Port} <- Addrs]),
+ Args =
+ [?int8(AddFlag)|
+ [[?int16(Port)|ip_to_bytes(IP)] ||
+ {IP, Port} <- Addrs]],
case ctl_cmd(S, ?SCTP_REQ_BINDX, Args) of
{ok,_} -> {ok, S};
Error -> Error
@@ -623,7 +624,7 @@ chgopt(S, Opt, Value) when is_port(S) ->
chgopts(S, [{Opt,Value}]).
chgopts(S, Opts) when is_port(S), is_list(Opts) ->
- case inet:getopts(S, need_template(Opts)) of
+ case getopts(S, need_template(Opts)) of
{ok,Templates} ->
try merge_options(Opts, Templates) of
NewOpts ->
@@ -636,7 +637,94 @@ chgopts(S, Opts) when is_port(S), is_list(Opts) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-%% IFLIST(insock()) -> {ok,IfNameList} | {error, Reason}
+%% getifaddrs(insock()) -> {ok,IfAddrsList} | {error, Reason}
+%%
+%% IfAddrsList = [{Name,[Opts]}]
+%% Name = string()
+%% Opts = {flags,[Flag]} | {addr,Addr} | {netmask,Addr} | {broadaddr,Addr}
+%% | {dstaddr,Addr} | {hwaddr,HwAddr} | {mtu,integer()}
+%% Flag = up | broadcast | loopback | running | multicast
+%% Addr = ipv4addr() | ipv6addr()
+%% HwAddr = ethernet_addr()
+%%
+%% get interface name and addresses list
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+getifaddrs(S) when is_port(S) ->
+ case ctl_cmd(S, ?INET_REQ_GETIFADDRS, []) of
+ {ok, Data} ->
+ {ok, comp_ifaddrs(build_ifaddrs(Data), ktree_empty())};
+ {error,enotsup} ->
+ case getiflist(S) of
+ {ok, IFs} ->
+ {ok, getifaddrs_ifget(S, IFs)};
+ Err1 -> Err1
+ end;
+ Err2 -> Err2
+ end.
+
+%% Restructure interface properties per interface and remove duplicates
+
+comp_ifaddrs([{If,Opts}|IfOpts], T) ->
+ case ktree_is_defined(If, T) of
+ true ->
+ OptSet = comp_ifaddrs_add(ktree_get(If, T), Opts),
+ comp_ifaddrs(IfOpts, ktree_update(If, OptSet, T));
+ false ->
+ OptSet = comp_ifaddrs_add(ktree_empty(), Opts),
+ comp_ifaddrs(IfOpts, ktree_insert(If, OptSet, T))
+ end;
+comp_ifaddrs([], T) ->
+ [{If,ktree_keys(ktree_get(If, T))} || If <- ktree_keys(T)].
+
+comp_ifaddrs_add(OptSet, [Opt|Opts]) ->
+ case ktree_is_defined(Opt, OptSet) of
+ true
+ when element(1, Opt) =:= flags;
+ element(1, Opt) =:= hwaddr ->
+ comp_ifaddrs_add(OptSet, Opts);
+ _ ->
+ comp_ifaddrs_add(ktree_insert(Opt, undefined, OptSet), Opts)
+ end;
+comp_ifaddrs_add(OptSet, []) -> OptSet.
+
+%% Legacy emulation of getifaddrs
+
+getifaddrs_ifget(_, []) -> [];
+getifaddrs_ifget(S, [IF|IFs]) ->
+ case ifget(S, IF, [flags]) of
+ {ok,[{flags,Flags}]=FlagsVals} ->
+ BroadOpts =
+ case member(broadcast, Flags) of
+ true ->
+ [broadaddr,hwaddr];
+ false ->
+ [hwaddr]
+ end,
+ P2POpts =
+ case member(pointtopoint, Flags) of
+ true ->
+ [dstaddr|BroadOpts];
+ false ->
+ BroadOpts
+ end,
+ getifaddrs_ifget(S, IFs, IF, FlagsVals, [addr,netmask|P2POpts]);
+ _ ->
+ getifaddrs_ifget(S, IFs, IF, [], [addr,netmask,hwaddr])
+ end.
+
+getifaddrs_ifget(S, IFs, IF, FlagsVals, Opts) ->
+ OptVals =
+ case ifget(S, IF, Opts) of
+ {ok,OVs} -> OVs;
+ _ -> []
+ end,
+ [{IF,FlagsVals++OptVals}|getifaddrs_ifget(S, IFs)].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% getiflist(insock()) -> {ok,IfNameList} | {error, Reason}
%%
%% get interface name list
%%
@@ -1325,6 +1413,19 @@ type_value_2({enum,List}, Enum) ->
{value,_} -> true;
false -> false
end;
+type_value_2(sockaddr, Addr) ->
+ case Addr of
+ any -> true;
+ loopback -> true;
+ {A,B,C,D} when ?ip(A,B,C,D) -> true;
+ {A,B,C,D,E,F,G,H} when ?ip6(A,B,C,D,E,F,G,H) -> true;
+ _ -> false
+ end;
+type_value_2(linkaddr, Addr) when is_list(Addr) ->
+ case len(Addr, 32768) of
+ undefined -> false;
+ _ -> true
+ end;
type_value_2({bitenumlist,List}, EnumList) ->
case enum_vals(EnumList, List) of
Ls when is_list(Ls) -> true;
@@ -1413,14 +1514,21 @@ enc_value_2(addr, {any,Port}) ->
[?INET_AF_ANY|?int16(Port)];
enc_value_2(addr, {loopback,Port}) ->
[?INET_AF_LOOPBACK|?int16(Port)];
-enc_value_2(addr, {IP,Port}) ->
- case tuple_size(IP) of
- 4 ->
- [?INET_AF_INET,?int16(Port)|ip4_to_bytes(IP)];
- 8 ->
- [?INET_AF_INET6,?int16(Port)|ip6_to_bytes(IP)]
- end;
-enc_value_2(ether, [X1,X2,X3,X4,X5,X6]) -> [X1,X2,X3,X4,X5,X6];
+enc_value_2(addr, {IP,Port}) when tuple_size(IP) =:= 4 ->
+ [?INET_AF_INET,?int16(Port)|ip4_to_bytes(IP)];
+enc_value_2(addr, {IP,Port}) when tuple_size(IP) =:= 8 ->
+ [?INET_AF_INET6,?int16(Port)|ip6_to_bytes(IP)];
+enc_value_2(ether, [_,_,_,_,_,_]=Xs) -> Xs;
+enc_value_2(sockaddr, any) ->
+ [?INET_AF_ANY];
+enc_value_2(sockaddr, loopback) ->
+ [?INET_AF_LOOPBACK];
+enc_value_2(sockaddr, IP) when tuple_size(IP) =:= 4 ->
+ [?INET_AF_INET|ip4_to_bytes(IP)];
+enc_value_2(sockaddr, IP) when tuple_size(IP) =:= 8 ->
+ [?INET_AF_INET6|ip6_to_bytes(IP)];
+enc_value_2(linkaddr, Linkaddr) ->
+ [?int16(length(Linkaddr)),Linkaddr];
enc_value_2(sctp_assoc_id, Val) -> ?int32(Val);
%% enc_value_2(sctp_assoc_id, Bin) -> [byte_size(Bin),Bin];
enc_value_2({enum,List}, Enum) ->
@@ -1464,7 +1572,11 @@ dec_value(time, [X3,X2,X1,X0|T]) ->
Val -> {Val, T}
end;
dec_value(ip, [A,B,C,D|T]) -> {{A,B,C,D}, T};
-dec_value(ether,[X1,X2,X3,X4,X5,X6|T]) -> {[X1,X2,X3,X4,X5,X6],T};
+%% dec_value(ether, [X1,X2,X3,X4,X5,X6|T]) -> {[X1,X2,X3,X4,X5,X6],T};
+dec_value(sockaddr, [X|T]) ->
+ get_ip(X, T);
+dec_value(linkaddr, [X1,X0|T]) ->
+ split(?i16(X1,X0), T);
dec_value({enum,List}, [X3,X2,X1,X0|T]) ->
Val = ?i32(X3,X2,X1,X0),
case enum_name(Val, List) of
@@ -1480,7 +1592,7 @@ dec_value({bitenumlist,List}, [X3,X2,X1,X0|T]) ->
%% {enum_names(Val, List), T};
dec_value(binary,[L0,L1,L2,L3|List]) ->
Len = ?i32(L0,L1,L2,L3),
- {X,T}=lists:split(Len,List),
+ {X,T}=split(Len,List),
{list_to_binary(X),T};
dec_value(Types, List) when is_tuple(Types) ->
{L,T} = dec_value_tuple(Types, List, 1, []),
@@ -1495,7 +1607,7 @@ dec_value_tuple(Types, List, N, Acc)
{Term,Tail} = dec_value(element(N, Types), List),
dec_value_tuple(Types, Tail, N+1, [Term|Acc]);
dec_value_tuple(_, List, _, Acc) ->
- {lists:reverse(Acc),List}.
+ {rev(Acc),List}.
borlist([V|Vs], Value) ->
borlist(Vs, V bor Value);
@@ -1702,11 +1814,11 @@ merge_fields(_, _, _) -> [].
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-type_ifopt(addr) -> ip;
-type_ifopt(broadaddr) -> ip;
-type_ifopt(dstaddr) -> ip;
+type_ifopt(addr) -> sockaddr;
+type_ifopt(broadaddr) -> sockaddr;
+type_ifopt(dstaddr) -> sockaddr;
type_ifopt(mtu) -> int;
-type_ifopt(netmask) -> ip;
+type_ifopt(netmask) -> sockaddr;
type_ifopt(flags) ->
{bitenumlist,
[{up, ?INET_IFF_UP},
@@ -1718,7 +1830,7 @@ type_ifopt(flags) ->
{no_pointtopoint, ?INET_IFF_NPOINTTOPOINT},
{running, ?INET_IFF_RUNNING},
{multicast, ?INET_IFF_MULTICAST}]};
-type_ifopt(hwaddr) -> ether;
+type_ifopt(hwaddr) -> linkaddr;
type_ifopt(Opt) when is_atom(Opt) -> undefined.
enc_ifopt(addr) -> ?INET_IFOPT_ADDR;
@@ -1903,6 +2015,30 @@ encode_ifname(Name) ->
if N > 255 -> {error, einval};
true -> {ok,[N | Name]}
end.
+
+build_ifaddrs(Cs) ->
+ build_ifaddrs(Cs, []).
+%%
+build_ifaddrs([], []) ->
+ [];
+build_ifaddrs([0|Cs], Acc) ->
+ Name = utf8_to_characters(rev(Acc)),
+ {Opts,Rest} = build_ifaddrs_opts(Cs, []),
+ [{Name,Opts}|build_ifaddrs(Rest)];
+build_ifaddrs([C|Cs], Acc) ->
+ build_ifaddrs(Cs, [C|Acc]).
+
+build_ifaddrs_opts([0|Cs], Acc) ->
+ {rev(Acc),Cs};
+build_ifaddrs_opts([C|Cs]=CCs, Acc) ->
+ case dec_ifopt(C) of
+ undefined ->
+ erlang:error(badarg, [CCs,Acc]);
+ Opt ->
+ Type = type_ifopt(Opt),
+ {Val,Rest} = dec_value(Type, Cs),
+ build_ifaddrs_opts(Rest, [{Opt,Val}|Acc])
+ end.
build_iflist(Cs) ->
build_iflist(Cs, [], []).
@@ -1927,6 +2063,80 @@ rev(L) -> rev(L,[]).
rev([C|L],Acc) -> rev(L,[C|Acc]);
rev([],Acc) -> Acc.
+split(N, L) -> split(N, L, []).
+split(0, L, R) when is_list(L) -> {rev(R),L};
+split(N, [H|T], R) when is_integer(N), N > 0 -> split(N-1, T, [H|R]).
+
+len(L, N) -> len(L, N, 0).
+len([], N, C) when is_integer(N), N >= 0 -> C;
+len(L, 0, _) when is_list(L) -> undefined;
+len([_|L], N, C) when is_integer(N), N >= 0 -> len(L, N-1, C+1).
+
+member(X, [X|_]) -> true;
+member(X, [_|Xs]) -> member(X, Xs);
+member(_, []) -> false.
+
+
+
+%% Lookup tree that keeps key insert order
+
+ktree_empty() -> {[],tree()}.
+ktree_is_defined(Key, {_,T}) -> tree(T, Key, is_defined).
+ktree_get(Key, {_,T}) -> tree(T, Key, get).
+ktree_insert(Key, V, {Keys,T}) -> {[Key|Keys],tree(T, Key, {insert,V})}.
+ktree_update(Key, V, {Keys,T}) -> {Keys,tree(T, Key, {update,V})}.
+ktree_keys({Keys,_}) -> rev(Keys).
+
+%% Simple lookup tree. Hash the key to get statistical balance.
+%% Key is matched equal, not compared equal.
+
+tree() -> nil.
+tree(T, Key, Op) -> tree(T, Key, Op, erlang:phash2(Key)).
+
+tree(nil, _, is_defined, _) -> false;
+tree(nil, K, {insert,V}, _) -> {K,V,nil,nil};
+tree({K,_,_,_}, K, is_defined, _) -> true;
+tree({K,V,_,_}, K, get, _) -> V;
+tree({K,_,L,R}, K, {update,V}, _) -> {K,V,L,R};
+tree({K0,V0,L,R}, K, Op, H) ->
+ H0 = erlang:phash2(K0),
+ if H0 < H; H0 =:= H, K0 < K ->
+ if is_tuple(Op) ->
+ {K0,V0,tree(L, K, Op, H),R};
+ true ->
+ tree(L, K, Op, H)
+ end;
+ true ->
+ if is_tuple(Op) ->
+ {K0,V0,L,tree(R, K, Op, H)};
+ true ->
+ tree(R, K, Op, H)
+ end
+ end.
+
+
+
+utf8_to_characters([]) -> [];
+utf8_to_characters([B|Bs]=Arg) when (B band 16#FF) =:= B ->
+ if 16#F8 =< B ->
+ erlang:error(badarg, [Arg]);
+ 16#F0 =< B ->
+ utf8_to_characters(Bs, B band 16#07, 3);
+ 16#E0 =< B ->
+ utf8_to_characters(Bs, B band 16#0F, 2);
+ 16#C0 =< B ->
+ utf8_to_characters(Bs, B band 16#1F, 1);
+ 16#80 =< B ->
+ erlang:error(badarg, [Arg]);
+ true ->
+ [B|utf8_to_characters(Bs)]
+ end.
+%%
+utf8_to_characters(Bs, U, 0) ->
+ [U|utf8_to_characters(Bs)];
+utf8_to_characters([B|Bs], U, N) when ((B band 16#3F) bor 16#80) =:= B ->
+ utf8_to_characters(Bs, (U bsl 6) bor (B band 16#3F), N-1).
+
ip_to_bytes(IP) when tuple_size(IP) =:= 4 -> ip4_to_bytes(IP);
ip_to_bytes(IP) when tuple_size(IP) =:= 8 -> ip6_to_bytes(IP).
diff --git a/erts/test/autoimport_SUITE.erl b/erts/test/autoimport_SUITE.erl
index 2430dac78d..9724ea3ad5 100644
--- a/erts/test/autoimport_SUITE.erl
+++ b/erts/test/autoimport_SUITE.erl
@@ -20,16 +20,38 @@
-module(autoimport_SUITE).
-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,autoimports/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ autoimports/1]).
-define(TEST_TIMEOUT, ?t:seconds(180)).
-all(suite) -> [autoimports].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [autoimports].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Func, Config) ->
Dog = test_server:timetrap(?TEST_TIMEOUT),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
catch test_server:timetrap_cancel(Dog),
ok.
diff --git a/erts/test/erl_print_SUITE.erl b/erts/test/erl_print_SUITE.erl
index 3bb7d4d016..fe9e811d4d 100644
--- a/erts/test/erl_print_SUITE.erl
+++ b/erts/test/erl_print_SUITE.erl
@@ -32,14 +32,35 @@
-define(DEFAULT_TIMEOUT, ?t:minutes(10)).
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, fin_per_testcase/2]).
--export([erlang_display/1, integer/1, float/1, string/1, character/1, snprintf/1, quote/1]).
+-export([erlang_display/1, integer/1, float/1,
+ string/1, character/1, snprintf/1, quote/1]).
-include_lib("test_server/include/test_server.hrl").
-
-all(doc) -> [];
-all(suite) -> test_cases().
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_cases().
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%
%%
@@ -47,14 +68,9 @@ all(suite) -> test_cases().
%%
%%
-test_cases() ->
- [erlang_display,
- integer,
- float,
- string,
- character,
- snprintf,
- quote].
+test_cases() ->
+ [erlang_display, integer, float, string, character,
+ snprintf, quote].
erlang_display(doc) -> [];
erlang_display(suite) -> [];
diff --git a/erts/test/erlc_SUITE.erl b/erts/test/erlc_SUITE.erl
index 437f020f99..a3a33b568c 100644
--- a/erts/test/erlc_SUITE.erl
+++ b/erts/test/erlc_SUITE.erl
@@ -20,14 +20,33 @@
%% Tests the erlc command by compiling various types of files.
--export([all/1, compile_erl/1, compile_yecc/1, compile_script/1,
- compile_mib/1, good_citizen/1, deep_cwd/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, compile_erl/1,
+ compile_yecc/1, compile_script/1,
+ compile_mib/1, good_citizen/1, deep_cwd/1, arg_overflow/1]).
-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[compile_erl, compile_yecc, compile_script, compile_mib,
- good_citizen, deep_cwd].
+ good_citizen, deep_cwd, arg_overflow].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%% Copy from erlc_SUITE_data/include/erl_test.hrl.
@@ -189,6 +208,18 @@ deep_cwd_1(PrivDir) ->
?line true = filelib:is_file("test.beam"),
ok.
+%% Test that a large number of command line switches does not
+%% overflow the argument buffer
+arg_overflow(Config) when is_list(Config) ->
+ ?line {SrcDir, _OutDir, Cmd} = get_cmd(Config),
+ ?line FileName = filename:join(SrcDir, "erl_test_ok.erl"),
+ ?line Args = lists:flatten([ ["-D", integer_to_list(N), "=1 "] ||
+ N <- lists:seq(1,10000) ]),
+ ?line run(Config, Cmd, FileName, Args,
+ ["Warning: function foo/0 is unused\$",
+ "_OK_"]),
+ ok.
+
erlc() ->
case os:find_executable("erlc") of
false ->
diff --git a/erts/test/erlexec_SUITE.erl b/erts/test/erlexec_SUITE.erl
index 164ce9faaf..e932e5a211 100644
--- a/erts/test/erlexec_SUITE.erl
+++ b/erts/test/erlexec_SUITE.erl
@@ -31,9 +31,11 @@
-define(DEFAULT_TIMEOUT, ?t:minutes(1)).
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
--export([args_file/1, evil_args_file/1, env/1, args_file_env/1, otp_7461/1, otp_7461_remote/1, otp_8209/1]).
+-export([args_file/1, evil_args_file/1, env/1, args_file_env/1, otp_7461/1, otp_7461_remote/1, otp_8209/1, zdbbl_dist_buf_busy_limit/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -43,7 +45,7 @@ init_per_testcase(Case, Config) ->
SavedEnv = save_env(),
[{testcase, Case}, {watchdog, Dog}, {erl_flags_env, SavedEnv} |Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
SavedEnv = ?config(erl_flags_env, Config),
restore_env(SavedEnv),
@@ -51,10 +53,26 @@ fin_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
ok.
-all(doc) -> [];
-all(suite) ->
- [args_file, evil_args_file, env, args_file_env, otp_7461, otp_8209].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+all() ->
+ [args_file, evil_args_file, env, args_file_env,
+ otp_7461, otp_8209, zdbbl_dist_buf_busy_limit].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
otp_8209(doc) ->
["Test that plain first argument does not "
@@ -330,6 +348,25 @@ otp_7461_remote([halt, Pid]) ->
io:format("halt order from ~p to node ~p\n",[Pid,node()]),
halt().
+zdbbl_dist_buf_busy_limit(doc) ->
+ ["Check +zdbbl flag"];
+zdbbl_dist_buf_busy_limit(suite) ->
+ [];
+zdbbl_dist_buf_busy_limit(Config) when is_list(Config) ->
+ LimKB = 1122233,
+ LimB = LimKB*1024,
+ ?line {ok,[[PName]]} = init:get_argument(progname),
+ ?line SNameS = "erlexec_test_02",
+ ?line SName = list_to_atom(SNameS++"@"++
+ hd(tl(string:tokens(atom_to_list(node()),"@")))),
+ ?line Cmd = PName ++ " -sname "++SNameS++" -setcookie "++
+ atom_to_list(erlang:get_cookie()) ++
+ " +zdbbl " ++ integer_to_list(LimKB),
+ ?line open_port({spawn,Cmd},[]),
+ ?line pong = loop_ping(SName,40),
+ ?line LimB = rpc:call(SName,erlang,system_info,[dist_buf_busy_limit]),
+ ?line ok = cleanup_node(SNameS, 10),
+ ok.
%%
diff --git a/erts/test/ethread_SUITE.erl b/erts/test/ethread_SUITE.erl
index 0cc315e9be..9bc3eebb74 100644
--- a/erts/test/ethread_SUITE.erl
+++ b/erts/test/ethread_SUITE.erl
@@ -31,13 +31,14 @@
-define(DEFAULT_TIMEOUT, ?t:minutes(10)).
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, fin_per_testcase/2]).
-export([create_join_thread/1,
equal_tids/1,
mutex/1,
try_lock_mutex/1,
- time_now/1,
cond_wait/1,
broadcast/1,
detached_thread/1,
@@ -50,25 +51,30 @@
-include_lib("test_server/include/test_server.hrl").
-tests() ->
- [create_join_thread,
- equal_tids,
- mutex,
- try_lock_mutex,
- time_now,
- cond_wait,
- broadcast,
- detached_thread,
- max_threads,
- tsd,
- spinlock,
- rwspinlock,
- rwmutex,
- atomic].
-
-all(doc) -> [];
-all(suite) -> tests().
+tests() ->
+ [create_join_thread, equal_tids, mutex, try_lock_mutex,
+ cond_wait, broadcast, detached_thread,
+ max_threads, tsd, spinlock, rwspinlock, rwmutex, atomic].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ tests().
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%
%%
@@ -104,17 +110,6 @@ try_lock_mutex(suite) ->
try_lock_mutex(Config) ->
run_case(Config, "try_lock_mutex", "").
-time_now(doc) ->
- ["Tests ethr_time_now by comparing time values with Erlang."];
-time_now(suite) ->
- [];
-time_now(Config) ->
- run_case(Config, "time_now", "", fun (P) ->
- spawn_link(fun () ->
- watchdog(P)
- end)
- end).
-
wd_dispatch(P) ->
receive
bye ->
@@ -171,7 +166,15 @@ max_threads(doc) ->
max_threads(suite) ->
[];
max_threads(Config) ->
- run_case(Config, "max_threads", "").
+ case {os:type(), os:version()} of
+ {{unix,darwin}, {9, _, _}} ->
+ %% For some reason pthread_create() crashes when more
+ %% threads cannot be created, instead of returning an
+ %% error code on our MacOS X Leopard machine...
+ {skipped, "MacOS X Leopard cannot cope with this test..."};
+ _ ->
+ run_case(Config, "max_threads", "")
+ end.
tsd(doc) ->
["Tests thread specific data."];
diff --git a/erts/test/ethread_SUITE_data/ethread_tests.c b/erts/test/ethread_SUITE_data/ethread_tests.c
index 7fc71d8047..0b59ff5aa6 100644
--- a/erts/test/ethread_SUITE_data/ethread_tests.c
+++ b/erts/test/ethread_SUITE_data/ethread_tests.c
@@ -514,69 +514,6 @@ try_lock_mutex_test(void)
}
/*
- * The time now test.
- *
- * Tests ethr_time_now by comparing time values with Erlang.
- */
-#define TNT_MAX_TIME_DIFF 200000
-#define TNT_MAX_TIME_VALUES 52
-
-static void
-time_now_test(void)
-{
- int scanf_res, time_now_res, i, no_values, max_abs_diff;
- static ethr_timeval tv[TNT_MAX_TIME_VALUES];
- static int ms[TNT_MAX_TIME_VALUES];
-
- i = 0;
- do {
- ASSERT(i < TNT_MAX_TIME_VALUES);
- scanf_res = scanf("%d", &ms[i]);
- time_now_res = ethr_time_now(&tv[i]);
- ASSERT(scanf_res == 1);
- ASSERT(time_now_res == 0);
-#if 0
- print_line("Got %d; %ld:%ld", ms[i], tv[i].tv_sec, tv[i].tv_nsec);
-#endif
- i++;
- } while (ms[i-1] >= 0);
-
- no_values = i-1;
-
- ASSERT(ms[0] == 0);
-
- print_line("TNT_MAX_TIME_DIFF = %d (us)", TNT_MAX_TIME_DIFF);
-
- max_abs_diff = 0;
-
- for (i = 1; i < no_values; i++) {
- long diff;
- long tn_us;
- long e_us;
-
- tn_us = (tv[i].tv_sec - tv[0].tv_sec) * 1000000;
- tn_us += (tv[i].tv_nsec - tv[0].tv_nsec)/1000;
-
- e_us = ms[i]*1000;
-
- diff = e_us - tn_us;
-
- print_line("Erlang time = %ld us; ethr_time_now = %ld us; diff %ld us",
- e_us, tn_us, diff);
-
- if (max_abs_diff < abs((int) diff)) {
- max_abs_diff = abs((int) diff);
- }
-
- ASSERT(e_us - TNT_MAX_TIME_DIFF <= tn_us);
- ASSERT(tn_us <= e_us + TNT_MAX_TIME_DIFF);
- }
-
- print_line("Max absolute diff = %d us", max_abs_diff);
- succeed("Max absolute diff = %d us", max_abs_diff);
-}
-
-/*
* The cond wait test case.
*
* Tests ethr_cond_wait with ethr_cond_signal and ethr_cond_broadcast.
@@ -1538,8 +1475,6 @@ main(int argc, char *argv[])
mutex_test();
else if (strcmp(testcase, "try_lock_mutex") == 0)
try_lock_mutex_test();
- else if (strcmp(testcase, "time_now") == 0)
- time_now_test();
else if (strcmp(testcase, "cond_wait") == 0)
cond_wait_test();
else if (strcmp(testcase, "broadcast") == 0)
diff --git a/erts/test/install_SUITE.erl b/erts/test/install_SUITE.erl
index e14790bc1b..2279ddae00 100644
--- a/erts/test/install_SUITE.erl
+++ b/erts/test/install_SUITE.erl
@@ -29,8 +29,9 @@
%-define(line_trace, 1).
--export([all/1, init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
-export([bin_default/1,
bin_default_dirty/1,
@@ -64,27 +65,32 @@
erlang_bindir = "",
bindir_symlinks = ""}).
-need_symlink_cases() ->
- [bin_unreachable_absolute,
- bin_unreachable_relative,
- bin_same_dir,
- bin_ok_symlink,
- bin_dirname_fail,
+need_symlink_cases() ->
+ [bin_unreachable_absolute, bin_unreachable_relative,
+ bin_same_dir, bin_ok_symlink, bin_dirname_fail,
bin_no_use_dirname_fail].
-dont_need_symlink_cases() ->
- [bin_default,
- bin_default_dirty,
- bin_outside_eprfx,
- bin_outside_eprfx_dirty,
- bin_not_abs,
- bin_unreasonable_path,
- 'bin white space',
+dont_need_symlink_cases() ->
+ [bin_default, bin_default_dirty, bin_outside_eprfx,
+ bin_outside_eprfx_dirty, bin_not_abs,
+ bin_unreasonable_path, 'bin white space',
bin_no_srcfile].
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
dont_need_symlink_cases() ++ need_symlink_cases().
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%
%% The test cases
%%
@@ -585,7 +591,7 @@ init_per_testcase_aux(true, _OsType, Case, Config) ->
{test_dir, make_dirs(?config(priv_dir, Config), atom_to_list(Case))}
| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
diff --git a/erts/test/nt_SUITE.erl b/erts/test/nt_SUITE.erl
index 530fb55270..8b2d8a7147 100644
--- a/erts/test/nt_SUITE.erl
+++ b/erts/test/nt_SUITE.erl
@@ -22,7 +22,9 @@
-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,nt/1,handle_eventlog/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,init_per_testcase/2,
+ end_per_testcase/2,nt/1,handle_eventlog/2,
middleman/1,service_basic/1, service_env/1, user_env/1, synced/1,
service_prio/1,
logout/1, debug/1, restart/1, restart_always/1,stopaction/1,
@@ -31,20 +33,38 @@
-define(TEST_SERVICES, [1,2,3,4,5,6,7,8,9,10,11]).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
case os:type() of
- {win32,nt} ->
- [nt, service_basic, service_env, user_env, synced, service_prio,
- logout, debug,
- restart, restart_always, stopaction];
- _ -> [nt] %%% Just to give a little hint why they are skipped...
+ {win32, nt} ->
+ [nt, service_basic, service_env, user_env, synced,
+ service_prio, logout, debug, restart, restart_always,
+ stopaction];
+ _ -> [nt]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(_Func, Config) ->
Dog = test_server:timetrap(?TEST_TIMEOUT),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
lists:foreach(fun(X) ->
catch remove_service("test_service_" ++
integer_to_list(X)) end,
diff --git a/erts/test/otp_SUITE.erl b/erts/test/otp_SUITE.erl
index 425ad31782..43655c4844 100644
--- a/erts/test/otp_SUITE.erl
+++ b/erts/test/otp_SUITE.erl
@@ -19,7 +19,8 @@
-module(otp_SUITE).
--export([all/1,init_per_suite/1,end_per_suite/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1,end_per_suite/1]).
-export([undefined_functions/1,deprecated_not_in_obsolete/1,
obsolete_but_not_deprecated/1,call_to_deprecated/1,
call_to_size_1/1,strong_components/1]).
@@ -28,10 +29,22 @@
-import(lists, [filter/2,foldl/3,foreach/2]).
-all(suite) ->
- [undefined_functions,deprecated_not_in_obsolete,
- obsolete_but_not_deprecated,call_to_deprecated,
- call_to_size_1,strong_components].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [undefined_functions, deprecated_not_in_obsolete,
+ obsolete_but_not_deprecated, call_to_deprecated,
+ call_to_size_1, strong_components].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_suite(Config) ->
Dog = test_server:timetrap(?t:minutes(10)),
diff --git a/erts/test/run_erl_SUITE.erl b/erts/test/run_erl_SUITE.erl
index efeafbad8c..5288e3e827 100644
--- a/erts/test/run_erl_SUITE.erl
+++ b/erts/test/run_erl_SUITE.erl
@@ -19,7 +19,9 @@
-module(run_erl_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
basic/1,heavy/1,heavier/1,defunct/1]).
-export([ping_me_back/1]).
@@ -29,13 +31,31 @@ init_per_testcase(_Case, Config) ->
Dog = ?t:timetrap(?t:minutes(2)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [basic,heavy,heavier,defunct].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic, heavy, heavier, defunct].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
basic(Config) when is_list(Config) ->
case os:type() of
diff --git a/erts/test/system.spec b/erts/test/system.spec
index 9bfe2dbcf8..e0561ba0b2 100644
--- a/erts/test/system.spec
+++ b/erts/test/system.spec
@@ -1 +1 @@
-{topcase, {dir, "../system_test"}}.
+{suites,"../system_test",all}.
diff --git a/erts/test/z_SUITE.erl b/erts/test/z_SUITE.erl
index 8faddeb0d3..acd07b44c5 100644
--- a/erts/test/z_SUITE.erl
+++ b/erts/test/z_SUITE.erl
@@ -35,26 +35,45 @@
-define(DEFAULT_TIMEOUT, ?t:minutes(5)).
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
-export([search_for_core_files/1, core_files/1]).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
init_per_testcase(Case, Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
[{testcase, Case}, {watchdog, Dog} |Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(doc) -> [];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[core_files].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
core_files(doc) ->
[];
@@ -253,6 +272,8 @@ core_file_search(#core_search_conf{search_dir = Base,
core_cand(Conf, Core, Cores);
"core." ++ _ ->
core_cand(Conf, Core, Cores);
+ Bin when is_binary(Bin) -> %Icky filename; ignore
+ Cores;
BName ->
case lists:suffix(".core", BName) of
true -> core_cand(Conf, Core, Cores);
diff --git a/erts/vsn.mk b/erts/vsn.mk
index a5dd62feb2..8a1590e74c 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -17,8 +17,8 @@
# %CopyrightEnd%
#
-VSN = 5.8.2
-SYSTEM_VSN = R14B01
+VSN = 5.8.3
+SYSTEM_VSN = R14B02
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff --git a/lib/.gitignore b/lib/.gitignore
index 340baf5269..56b1ed2b84 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -531,6 +531,10 @@
/percept/doc/src/percept_profile.xml
/percept/doc/src/percept_ug.xml
+# snmp
+
+snmp/doc/intex.html
+
# syntax_tools
/syntax_tools/doc/src/chapter.xml
diff --git a/lib/Makefile b/lib/Makefile
index f5ffc6f166..00bcf27ee3 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -51,7 +51,7 @@ else
# --------------
#
ERTS_SUB_DIRECTORIES = stdlib sasl kernel compiler
- OTHER_SUB_DIRECTORIES = tools test_server
+ OTHER_SUB_DIRECTORIES = tools test_server common_test runtime_tools
ifdef BUILD_ALL
ifeq ($(findstring win32,$(TARGET)),win32) # BUILD_ALL on win32
OTHER_SUB_DIRECTORIES += \
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml
index 375e859d20..c93adeffe2 100644
--- a/lib/asn1/doc/src/notes.xml
+++ b/lib/asn1/doc/src/notes.xml
@@ -31,6 +31,31 @@
<p>This document describes the changes made to the asn1 application.</p>
+<section><title>Asn1 1.6.15</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The encoding of ExtensionAdditionGroup (for PER and UPER)
+ is corrected.</p>
+ <p>
+ Own Id: OTP-8866 Aux Id: OTP-8797, SEQ-11557 </p>
+ </item>
+ <item>
+ <p>
+ A race condition when several processes in parallel start
+ to do encode/decode using the driver could cause an error
+ log regarding crashing port owner process. This race is
+ now eliminated.</p>
+ <p>
+ Own Id: OTP-8948 Aux Id: seq11733 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Asn1 1.6.14.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/asn1/src/asn1ct.erl b/lib/asn1/src/asn1ct.erl
index 968468cb7f..947578f07d 100644
--- a/lib/asn1/src/asn1ct.erl
+++ b/lib/asn1/src/asn1ct.erl
@@ -39,7 +39,7 @@
add_tobe_refed_func/1,add_generated_refed_func/1,
maybe_rename_function/3,latest_sindex/0,current_sindex/0,
set_current_sindex/1,next_sindex/0,maybe_saved_sindex/2,
- parse_and_save/2,report_verbose/3]).
+ parse_and_save/2,verbose/3,warning/3,error/3]).
-include("asn1_records.hrl").
-include_lib("stdlib/include/erl_compile.hrl").
@@ -103,8 +103,8 @@ compile(File,Options) when is_list(Options) ->
compile1(File,Options) when is_list(Options) ->
- report_verbose("Erlang ASN.1 version ~p compiling ~p ~n",[?vsn,File],Options),
- report_verbose("Compiler Options: ~p~n",[Options],Options),
+ verbose("Erlang ASN.1 version ~p compiling ~p ~n",[?vsn,File],Options),
+ verbose("Compiler Options: ~p~n",[Options],Options),
Ext = filename:extension(File),
Base = filename:basename(File,Ext),
OutFile = outfile(Base,"",Options),
@@ -149,17 +149,17 @@ compile1(File,Options) when is_list(Options) ->
inline(true,Name,Module,Options) ->
RTmodule = get_runtime_mod(Options),
IgorOptions = igorify_options(remove_asn_flags(Options)),
- IgorName = filename:rootname(filename:basename(Name)),
+ IgorName = list_to_atom(filename:rootname(filename:basename(Name))),
% io:format("*****~nName: ~p~nModules: ~p~nIgorOptions: ~p~n*****~n",
% [IgorName,Modules++RTmodule,IgorOptions]),
- report_verbose("Inlining modules: ~p in ~p~n",[[Module]++RTmodule,IgorName],Options),
+ verbose("Inlining modules: ~p in ~p~n",[[Module]++RTmodule,IgorName],Options),
case catch igor:merge(IgorName,[Module]++RTmodule,[{preprocess,true},{stubs,false},{backups,false}]++IgorOptions) of
{'EXIT',{undef,Reason}} -> %% module igor first in R10B
- io:format("Module igor in syntax_tools must be available:~n~p~n",
- [Reason]),
+ error("Module igor in syntax_tools must be available:~n~p~n",
+ [Reason],Options),
{error,'no_compilation'};
{'EXIT',Reason} ->
- io:format("Merge by igor module failed due to ~p~n",[Reason]),
+ error("Merge by igor module failed due to ~p~n",[Reason],Options),
{error,'no_compilation'};
_ ->
%% io:format("compiling output module: ~p~n",[generated_file(Name,IgorOptions)]),
@@ -173,8 +173,8 @@ inline(_,_,_,_) ->
compile_set(SetBase,Files,Options)
when is_list(hd(Files)),is_list(Options) ->
%% case when there are several input files in a list
- report_verbose("Erlang ASN.1 version ~p compiling ~p ~n",[?vsn,Files],Options),
- report_verbose("Compiler Options: ~p~n",[Options],Options),
+ verbose("Erlang ASN.1 version ~p compiling ~p ~n",[?vsn,Files],Options),
+ verbose("Compiler Options: ~p~n",[Options],Options),
OutFile = outfile(SetBase,"",Options),
DbFile = outfile(SetBase,"asn1db",Options),
Includes = [I || {i,I} <- Options],
@@ -728,7 +728,7 @@ parse_set(ScanRes,Options) ->
scan(File,Options) ->
case asn1ct_tok:file(File) of
{error,Reason} ->
- io:format("~p~n",[Reason]),
+ error("~p~n",[Reason],Options),
{false,{error,Reason}};
Tokens ->
case lists:member(ss,Options) of
@@ -753,16 +753,17 @@ parse({true,Tokens},File,Options) ->
if
is_integer(Line) ->
BaseName = filename:basename(File),
- io:format("syntax error at line ~p in module ~s:~n",
- [Line,BaseName]);
+ error("syntax error at line ~p in module ~s:~n",
+ [Line,BaseName],Options);
true ->
- io:format("syntax error in module ~p:~n",[File])
+ error("syntax error in module ~p:~n",
+ [File],Options)
end,
print_error_message(Message),
{false,{error,Message}};
{error,{Line,_Mod,[Message,Token]}} ->
- io:format("syntax error: ~p ~p at line ~p~n",
- [Message,Token,Line]),
+ error("syntax error: ~p ~p at line ~p~n",
+ [Message,Token,Line],Options),
{false,{error,{Line,[Message,Token]}}};
{ok,M} ->
case lists:member(sp,Options) of
@@ -772,7 +773,7 @@ parse({true,Tokens},File,Options) ->
{true,M}
end;
OtherError ->
- io:format("~p~n",[OtherError])
+ error("~p~n",[OtherError],Options)
end;
parse({false,Tokens},_,_) ->
{false,Tokens}.
@@ -802,7 +803,7 @@ check({true,M},File,OutFile,Includes,EncodingRule,DbFile,Options,InputMods) ->
NewM = Module#module{typeorval=NewTypeOrVal},
asn1_db:dbput(NewM#module.name,'MODULE',NewM),
asn1_db:dbsave(DbFile,M#module.name),
- report_verbose("--~p--~n",[{generated,DbFile}],Options),
+ verbose("--~p--~n",[{generated,DbFile}],Options),
{true,{M,NewM,GenTypeOrVal}}
end
end;
@@ -823,11 +824,11 @@ generate({true,{M,_Module,GenTOrV}},OutFile,EncodingRule,Options) ->
% io:format("Options: ~p~n",[Options]),
case catch specialized_decode_prepare(EncodingRule,M,GenTOrV,Options) of
{error, enoent} -> ok;
- {error, Reason} -> io:format("WARNING: Error in configuration"
- "file: ~n~p~n",[Reason]);
- {'EXIT',Reason} -> io:format("WARNING: Internal error when "
- "analyzing configuration"
- "file: ~n~p~n",[Reason]);
+ {error, Reason} -> warning("Error in configuration "
+ "file: ~n~p~n",[Reason],Options);
+ {'EXIT',Reason} -> warning("Internal error when "
+ "analyzing configuration "
+ "file: ~n~p~n",[Reason],Options);
_ -> ok
end,
@@ -835,7 +836,7 @@ generate({true,{M,_Module,GenTOrV}},OutFile,EncodingRule,Options) ->
case (catch asn1ct_gen:pgen(OutFile,EncodingRule,
M#module.name,GenTOrV,Options)) of
{'EXIT',Reason2} ->
- io:format("ERROR: ~p~n",[Reason2]),
+ error("~p~n",[Reason2],Options),
{error,Reason2};
_ ->
ok
@@ -878,7 +879,8 @@ parse_and_save(Module,S) ->
_ -> ok
end;
Err ->
- io:format("Warning: could not do a consistency check of the ~p file: no asn1 source file was found.~n",[lists:concat([Module,".asn1db"])]),
+ warning("could not do a consistency check of the ~p file: no asn1 source file was found.~n",
+ [lists:concat([Module,".asn1db"])],Options),
{error,{asn1,input_file_error,Err}}
end.
parse_and_save1(S,File,Options,Includes) ->
@@ -1183,6 +1185,7 @@ is_inline(Options) ->
_ ->
lists:keymember(inline,1,Options)
end.
+
inline_output(Options,Default) ->
case [X||{inline,X}<-Options] of
[OutputName] ->
@@ -1207,7 +1210,7 @@ compile_py(File,OutFile,Options) ->
compile(File, _OutFile, Options) ->
case catch compile(File, make_erl_options(Options)) of
Exit = {'EXIT',_Reason} ->
- io:format("~p~n~s~n",[Exit,"error"]),
+ error("~p~n~s~n",[Exit,"error"],Options),
error;
{error,_Reason} ->
%% case occurs due to error in asn1ct_parser2,asn1ct_check
@@ -1223,7 +1226,7 @@ compile(File, _OutFile, Options) ->
io:format("~p~n",[ScanRes]),
ok;
Unknown ->
- io:format("~p~n~s~n",[Unknown,"error"]),
+ error("~p~n~s~n",[Unknown,"error"],Options),
error
end.
@@ -1237,7 +1240,7 @@ make_erl_options(Opts) ->
Includes = Opts#options.includes,
Defines = Opts#options.defines,
Outdir = Opts#options.outdir,
-%% Warning = Opts#options.warning,
+ Warning = Opts#options.warning,
Verbose = Opts#options.verbose,
Specific = Opts#options.specific,
Optimize = Opts#options.optimize,
@@ -1249,10 +1252,10 @@ make_erl_options(Opts) ->
true -> [verbose];
false -> []
end ++
-%%% case Warning of
-%%% 0 -> [];
-%%% _ -> [report_warnings]
-%%% end ++
+ case Warning of
+ 0 -> [];
+ _ -> [warnings]
+ end ++
[] ++
case Optimize of
1 -> [optimize];
@@ -1276,7 +1279,7 @@ make_erl_options(Opts) ->
uper_bin -> [uper_bin]
end,
- Options++[report_errors, {cwd, Cwd}, {outdir, Outdir}|
+ Options++[errors, {cwd, Cwd}, {outdir, Outdir}|
lists:map(fun(Dir) -> {i, Dir} end, Includes)]++Specific.
pretty2(Module,AbsFile) ->
@@ -2518,13 +2521,48 @@ type_check(#'Externaltypereference'{}) ->
make_suffix(_) ->
"".
-report_verbose(Format, Args, S) ->
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Report functions.
+%%
+%% Errors messages are controlled with the 'errors' compiler option
+%% Warning messages are controlled with the 'warnings' compiler option
+%% Verbose messages are controlled with the 'verbose' compiler option
+
+error(Format, Args, S) ->
+ case is_error(S) of
+ true ->
+ io:format("Error: " ++ Format, Args);
+ false ->
+ ok
+ end.
+
+warning(Format, Args, S) ->
+ case is_warning(S) of
+ true ->
+ io:format("Warning: " ++ Format, Args);
+ false ->
+ ok
+ end.
+
+verbose(Format, Args, S) ->
case is_verbose(S) of
- true ->
- io:format(Format, Args);
- false ->
- ok
+ true ->
+ io:format(Format, Args);
+ false ->
+ ok
end.
-is_verbose(S) ->
- lists:member(verbose, S).
+is_error(S) when is_record(S, state) ->
+ is_error(S#state.options);
+is_error(O) ->
+ lists:member(errors, O) orelse is_verbose(O).
+
+is_warning(S) when is_record(S, state) ->
+ is_warning(S#state.options);
+is_warning(O) ->
+ lists:member(warnings, O) orelse is_verbose(O).
+
+is_verbose(S) when is_record(S, state) ->
+ is_verbose(S#state.options);
+is_verbose(O) ->
+ lists:member(verbose, O).
diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl
index c6f3b60786..8b1ee6e601 100644
--- a/lib/asn1/src/asn1ct_check.erl
+++ b/lib/asn1/src/asn1ct_check.erl
@@ -2029,8 +2029,9 @@ get_objectset_def2(_S,Set,CField) when is_list(Set) ->
set=Set}};
get_objectset_def2(_S,T = #typedef{typespec=#'ObjectSet'{}},_CField) ->
T;
-get_objectset_def2(_S,T,_CField) ->
- io:format("Warning get_objectset_def2: uncontrolled object set structure:~n~p~n",[T]).
+get_objectset_def2(S,T,_CField) ->
+ asn1ct:warning("get_objectset_def2: uncontrolled object set structure:~n~p~n",
+ [T],S).
type_name(S,#type{def=Def}) ->
CurrMod = S#state.mname,
@@ -2687,7 +2688,7 @@ normalize_value(S,Type,{'DEFAULT',Value},NameList) ->
{'REAL',_,_} ->
normalize_real(Value);
{'ENUMERATED',CType,_} ->
- normalize_enumerated(Value,CType);
+ normalize_enumerated(S,Value,CType);
{'CHOICE',CType,NewNameList} ->
normalize_choice(S,Value,CType,NewNameList);
{'SEQUENCE',CType,NewNameList} ->
@@ -2703,7 +2704,8 @@ normalize_value(S,Type,{'DEFAULT',Value},NameList) ->
{'ASN1_OPEN_TYPE',{typefield,_TF},NL} -> %an open type
normalize_objectclassfieldvalue(S,Value,NL);
Err ->
- io:format("WARNING: could not check default value ~p~nType:~n~p~nNameList:~n~p~n",[Value,Type,Err]),
+ asn1ct:warning("could not check default value ~p~nType:~n~p~nNameList:~n~p~n",
+ [Value,Type,Err],S),
Value
end;
normalize_value(S,Type,Val,NameList) ->
@@ -2788,23 +2790,23 @@ normalize_bitstring(S,Value,Type)->
end,
case catch lists:map(F,RecList) of
{error,Reason} ->
- io:format("WARNING: default value not "
+ asn1ct:warning("default value not "
"compatible with type definition ~p~n",
- [Reason]),
+ [Reason],S),
Value;
NewList ->
NewList
end;
_ ->
- io:format("WARNING: default value not "
+ asn1ct:warning("default value not "
"compatible with type definition ~p~n",
- [RecList]),
+ [RecList],S),
Value
end;
{Name,String} when is_atom(Name) ->
normalize_bitstring(S,String,Type);
Other ->
- io:format("WARNING: illegal default value ~p~n",[Other]),
+ asn1ct:warning("illegal default value ~p~n",[Other],S),
Value
end.
@@ -2843,12 +2845,13 @@ normalize_octetstring(S,Value,CType) ->
%% check if list elements are valid octet values
lists:map(fun([])-> ok;
(H)when H > 255->
- io:format("WARNING: not legal octet value ~p in OCTET STRING, ~p~n",[H,List]);
+ asn1ct:warning("not legal octet value ~p in OCTET STRING, ~p~n",
+ [H,List],S);
(_)-> ok
end, List),
List;
Other ->
- io:format("WARNING: unknown default value ~p~n",[Other]),
+ asn1ct:warning("unknown default value ~p~n",[Other],S),
Value
end.
@@ -2895,23 +2898,23 @@ normalize_objectdescriptor(Value) ->
normalize_real(Value) ->
Value.
-normalize_enumerated(#'Externalvaluereference'{value=V},CType)
+normalize_enumerated(S,#'Externalvaluereference'{value=V},CType)
when is_list(CType) ->
- normalize_enumerated2(V,CType);
-normalize_enumerated(Value,CType) when is_atom(Value),is_list(CType) ->
- normalize_enumerated2(Value,CType);
-normalize_enumerated({Name,EnumV},CType) when is_atom(Name) ->
- normalize_enumerated(EnumV,CType);
-normalize_enumerated(Value,{CType1,CType2}) when is_list(CType1), is_list(CType2)->
- normalize_enumerated(Value,CType1++CType2);
-normalize_enumerated(V,CType) ->
- io:format("WARNING: Enumerated unknown type ~p~n",[CType]),
+ normalize_enumerated2(S,V,CType);
+normalize_enumerated(S,Value,CType) when is_atom(Value),is_list(CType) ->
+ normalize_enumerated2(S,Value,CType);
+normalize_enumerated(S,{Name,EnumV},CType) when is_atom(Name) ->
+ normalize_enumerated(S,EnumV,CType);
+normalize_enumerated(S,Value,{CType1,CType2}) when is_list(CType1), is_list(CType2)->
+ normalize_enumerated(S,Value,CType1++CType2);
+normalize_enumerated(S,V,CType) ->
+ asn1ct:warning("Enumerated unknown type ~p~n",[CType],S),
V.
-normalize_enumerated2(V,Enum) ->
+normalize_enumerated2(S,V,Enum) ->
case lists:keysearch(V,1,Enum) of
{value,{Val,_}} -> Val;
_ ->
- io:format("WARNING: Enumerated value is not correct ~p~n",[V]),
+ asn1ct:warning("Enumerated value is not correct ~p~n",[V],S),
V
end.
@@ -2922,8 +2925,7 @@ normalize_choice(S,{'CHOICE',{C,V}},CType,NameList) when is_atom(C) ->
{C,normalize_value(S,CT,{'DEFAULT',V},
[Name|NameList])};
Other ->
- io:format("WARNING: Wrong format of type/value ~p/~p~n",
- [Other,V]),
+ asn1ct:warning("Wrong format of type/value ~p/~p~n",[Other,V],S),
{C,V}
end;
normalize_choice(S,{'DEFAULT',ValueList},CType,NameList) when is_list(ValueList) ->
@@ -3099,8 +3101,7 @@ normalize_s_of(SorS,S,Value,Type,NameList) when is_list(Value) ->
List when is_list(List) ->
List;
_ ->
- io:format("WARNING: ~p could not handle value ~p~n",
- [SorS,Value]),
+ asn1ct:warning("~p could not handle value ~p~n",[SorS,Value],S),
Value
end;
normalize_s_of(SorS,S,Value,Type,NameList)
@@ -3152,15 +3153,13 @@ get_normalized_value(S,Val,Type,Func,AddArg) ->
V2 = sort_val_if_set(AddArg,V,Type),
call_Func(update_state(S,ExtM),V2,Type,Func,AddArg);
{error,_} ->
- io:format("WARNING: default value not "
- "comparable ~p~n",[Val]),
+ asn1ct:warning("default value not comparable ~p~n",[Val],S),
Val;
{ExtM,NewVal} ->
V2 = sort_val_if_set(AddArg,NewVal,Type),
call_Func(update_state(S,ExtM),V2,Type,Func,AddArg);
_ ->
- io:format("WARNING: default value not "
- "comparable ~p~n",[Val]),
+ asn1ct:warning("default value not comparable ~p~n",[Val],S),
Val
end.
@@ -4109,7 +4108,7 @@ resolve_namednumber(S,#typedef{typespec=Type},Name) ->
case Type#type.def of
{'ENUMERATED',NameList} ->
NamedNumberList=check_enumerated(S,NameList,Type#type.constraint),
- N = normalize_enumerated(Name,NamedNumberList),
+ N = normalize_enumerated(S,Name,NamedNumberList),
{value,{_,V}} = lists:keysearch(N,1,NamedNumberList),
V;
{'INTEGER',NameList} ->
@@ -5710,9 +5709,9 @@ sort_components(der,S=#state{tname=TypeName},Components) ->
end,
case {untagged_choice(S,CompsList),Ext} of
{false,noext} ->
- {true,sort_components1(TypeName,CompsList,[],[],[],[])};
+ {true,sort_components1(S,TypeName,CompsList,[],[],[],[])};
{false,_} ->
- {true,{sort_components1(TypeName,CompsList,[],[],[],[]), []}};
+ {true,{sort_components1(S,TypeName,CompsList,[],[],[],[]), []}};
{true,noext} ->
%% sort in run-time
{dynamic,R1};
@@ -5724,57 +5723,57 @@ sort_components(per,S=#state{tname=TypeName},Components) ->
Root = tag_untagged_choice(S,R1++R2),
case Ext of
noext ->
- {true,sort_components1(TypeName,Root,[],[],[],[])};
+ {true,sort_components1(S,TypeName,Root,[],[],[],[])};
_ ->
- {true,{sort_components1(TypeName,Root,[],[],[],[]),
+ {true,{sort_components1(S,TypeName,Root,[],[],[],[]),
Ext}}
end.
-sort_components1(TypeName,[C=#'ComponentType'{tags=[{'UNIVERSAL',_}|_R]}|Cs],
+sort_components1(S,TypeName,[C=#'ComponentType'{tags=[{'UNIVERSAL',_}|_R]}|Cs],
UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
- sort_components1(TypeName,Cs,[C|UnivAcc],ApplAcc,ContAcc,PrivAcc);
-sort_components1(TypeName,[C=#'ComponentType'{tags=[{'APPLICATION',_}|_R]}|Cs],
+ sort_components1(S,TypeName,Cs,[C|UnivAcc],ApplAcc,ContAcc,PrivAcc);
+sort_components1(S,TypeName,[C=#'ComponentType'{tags=[{'APPLICATION',_}|_R]}|Cs],
UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
- sort_components1(TypeName,Cs,UnivAcc,[C|ApplAcc],ContAcc,PrivAcc);
-sort_components1(TypeName,[C=#'ComponentType'{tags=[{'CONTEXT',_}|_R]}|Cs],
+ sort_components1(S,TypeName,Cs,UnivAcc,[C|ApplAcc],ContAcc,PrivAcc);
+sort_components1(S,TypeName,[C=#'ComponentType'{tags=[{'CONTEXT',_}|_R]}|Cs],
UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
- sort_components1(TypeName,Cs,UnivAcc,ApplAcc,[C|ContAcc],PrivAcc);
-sort_components1(TypeName,[C=#'ComponentType'{tags=[{'PRIVATE',_}|_R]}|Cs],
+ sort_components1(S,TypeName,Cs,UnivAcc,ApplAcc,[C|ContAcc],PrivAcc);
+sort_components1(S,TypeName,[C=#'ComponentType'{tags=[{'PRIVATE',_}|_R]}|Cs],
UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
- sort_components1(TypeName,Cs,UnivAcc,ApplAcc,ContAcc,[C|PrivAcc]);
-sort_components1(TypeName,[],UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
+ sort_components1(S,TypeName,Cs,UnivAcc,ApplAcc,ContAcc,[C|PrivAcc]);
+sort_components1(S,TypeName,[],UnivAcc,ApplAcc,ContAcc,PrivAcc) ->
I = #'ComponentType'.tags,
- ascending_order_check(TypeName,sort_universal_type(UnivAcc)) ++
- ascending_order_check(TypeName,lists:keysort(I,ApplAcc)) ++
- ascending_order_check(TypeName,lists:keysort(I,ContAcc)) ++
- ascending_order_check(TypeName,lists:keysort(I,PrivAcc)).
+ ascending_order_check(S,TypeName,sort_universal_type(UnivAcc)) ++
+ ascending_order_check(S,TypeName,lists:keysort(I,ApplAcc)) ++
+ ascending_order_check(S,TypeName,lists:keysort(I,ContAcc)) ++
+ ascending_order_check(S,TypeName,lists:keysort(I,PrivAcc)).
-ascending_order_check(TypeName,Components) ->
- ascending_order_check1(TypeName,Components),
+ascending_order_check(S,TypeName,Components) ->
+ ascending_order_check1(S,TypeName,Components),
Components.
-ascending_order_check1(TypeName,
+ascending_order_check1(S,TypeName,
[C1 = #'ComponentType'{tags=[{_,T}|_]},
C2 = #'ComponentType'{tags=[{_,T}|_]}|Rest]) ->
- io:format("WARNING: Indistinct tag ~p in SET ~p, components ~p and ~p~n",
- [T,TypeName,C1#'ComponentType'.name,C2#'ComponentType'.name]),
- ascending_order_check1(TypeName,[C2|Rest]);
-ascending_order_check1(TypeName,
+ asn1ct:warning("Indistinct tag ~p in SET ~p, components ~p and ~p~n",
+ [T,TypeName,C1#'ComponentType'.name,C2#'ComponentType'.name],S),
+ ascending_order_check1(S,TypeName,[C2|Rest]);
+ascending_order_check1(S,TypeName,
[C1 = #'ComponentType'{tags=[{'UNIVERSAL',T1}|_]},
C2 = #'ComponentType'{tags=[{'UNIVERSAL',T2}|_]}|Rest]) ->
case (decode_type(T1) == decode_type(T2)) of
true ->
- io:format("WARNING: Indistinct tags ~p and ~p in"
+ asn1ct:warning("Indistinct tags ~p and ~p in"
" SET ~p, components ~p and ~p~n",
[T1,T2,TypeName,C1#'ComponentType'.name,
- C2#'ComponentType'.name]),
- ascending_order_check1(TypeName,[C2|Rest]);
+ C2#'ComponentType'.name],S),
+ ascending_order_check1(S,TypeName,[C2|Rest]);
_ ->
- ascending_order_check1(TypeName,[C2|Rest])
+ ascending_order_check1(S,TypeName,[C2|Rest])
end;
-ascending_order_check1(N,[_|Rest]) ->
- ascending_order_check1(N,Rest);
-ascending_order_check1(_,[]) ->
+ascending_order_check1(S,N,[_|Rest]) ->
+ ascending_order_check1(S,N,Rest);
+ascending_order_check1(_,_,[]) ->
ok.
sort_universal_type(Components) ->
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index df430c4f88..d6f23aca06 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -66,9 +66,9 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) ->
end,
case Typename of
['EXTERNAL'] ->
- emit({{var,asn1ct_name:next(val)},
+ emit({{next,val},
" = asn1rt_check:transform_to_EXTERNAL1990(",
- {var,asn1ct_name:curr(val)},"),",nl}),
+ {curr,val},"),",nl}),
asn1ct_name:new(val);
_ ->
ok
@@ -77,23 +77,40 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) ->
{[],EmptyCL} when EmptyCL == {[],[],[]};EmptyCL == {[],[]};EmptyCL == [] ->
emit(["%%Variable setting just to eliminate ",
"compiler warning for unused vars!",nl,
- "_Val = ",{var,asn1ct_name:curr(val)},",",nl]);
+ "_Val = ",{curr,val},",",nl]);
{[],_} ->
- emit([{var,asn1ct_name:next(val)}," = ?RT_PER:list_to_record("]),
+ emit([{next,val}," = ?RT_PER:list_to_record("]),
emit(["'",asn1ct_gen:list2rname(Typename),"'"]),
- emit([", ",{var,asn1ct_name:curr(val)},"),",nl]);
+ emit([", ",{curr,val},"),",nl]);
_ ->
Fixoptcall = ",Opt} = ?RT_PER:fixoptionals(",
- emit({"{",{var,asn1ct_name:next(val)},Fixoptcall,
+ emit({"{",{next,val},Fixoptcall,
{asis,Optionals},",",length(Optionals),
- ",",{var,asn1ct_name:curr(val)},"),",nl})
+ ",",{curr,val},"),",nl})
end,
asn1ct_name:new(val),
Ext = extensible_enc(CompList),
case Ext of
{ext,_,NumExt} when NumExt > 0 ->
- emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext},
- ", ",{curr,val},"),",nl]);
+ case extgroup_pos_and_length(CompList) of
+ {extgrouppos,ExtGroupPos,ExtGroupLen} ->
+ Elements = make_elements(ExtGroupPos+1,
+ "Val1",lists:seq(1,ExtGroupLen)),
+ emit([
+ {next,val}," = case [X || X <- [",Elements,
+ "],X =/= asn1_NOVALUE] of",nl,
+ "[] -> ",{curr,val},";",nl,
+ "_ -> setelement(",{asis,ExtGroupPos+1},",",
+ {curr,val},",",
+ "{extaddgroup,", Elements,"})",nl,
+ "end,",nl]),
+ asn1ct_name:new(val);
+ _ -> % no extensionAdditionGroup
+ ok
+ end,
+ asn1ct_name:new(tmpval),
+ emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext},",",
+ {curr,val},"),",nl]);
_ -> true
end,
EncObj =
@@ -303,22 +320,20 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) ->
mkvlist(textual_order(to_encoding_order(CompList),asn1ct_name:all(term))),
emit("},")
end,
- emit({{var,asn1ct_name:curr(bytes)},"}"}),
+ emit({{curr,bytes},"}"}),
emit({".",nl,nl}).
textual_order([#'ComponentType'{textual_order=undefined}|_],TermList) ->
TermList;
textual_order(CompList,TermList) when is_list(CompList) ->
- OrderList = [Ix||#'ComponentType'{textual_order=Ix} <- CompList],
+ OrderList = [Ix||#'ComponentType'{textual_order=Ix} <- CompList],
[Term||{_,Term}<-
lists:sort(lists:zip(OrderList,
lists:sublist(TermList,length(OrderList))))];
%% sublist is just because Termlist can sometimes be longer than
%% OrderList, which it really shouldn't
textual_order({Root,Ext},TermList) ->
- textual_order(Root ++ Ext,TermList);
-textual_order({Root1,Ext,Root2},TermList) ->
- textual_order(Root1 ++ Ext ++ Root2, TermList).
+ textual_order(Root ++ Ext,TermList).
to_textual_order({Root,Ext}) ->
{to_textual_order(Root),Ext};
@@ -596,6 +611,27 @@ ext_length([#'ComponentType'{}|T],State=normal,Acc) ->
ext_length([],_,Acc) ->
Acc.
+extgroup_pos_and_length(CompList) when is_list(CompList) ->
+ noextgroup;
+extgroup_pos_and_length({RootList,ExtList}) ->
+ extgrouppos(ExtList,length(RootList)+1);
+extgroup_pos_and_length({Rl1,Ext,_Rl2}) ->
+ extgrouppos(Ext,length(Rl1)+1).
+
+extgrouppos([{'ExtensionAdditionGroup',_Num}|T],Pos) ->
+ extgrouppos(T,Pos,0);
+extgrouppos([_|T],Pos) ->
+ extgrouppos(T,Pos+1);
+extgrouppos([],_) ->
+ noextgroup.
+
+extgrouppos(['ExtensionAdditionGroupEnd'|_T],Pos,Len) ->
+ {extgrouppos,Pos,Len};
+extgrouppos([_|T],Pos,Len) ->
+ extgrouppos(T,Pos,Len+1).
+
+
+
gen_dec_extension_value(_) ->
emit({"{Ext,",{next,bytes},"} = ?RT_PER:getext(",{curr,bytes},")"}),
asn1ct_name:new(bytes).
@@ -743,7 +779,7 @@ gen_enc_components_call1(_Erule,_TopType,[],Pos,_,_,_) ->
Pos.
gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal) ->
- Element = make_element(Pos+1,"Val1",Cname),
+ Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname),
emit({"case ",Element," of",nl}),
% emit({"asn1_DEFAULT -> [];",nl}),
emit({"DFLT when DFLT == asn1_DEFAULT; DFLT == ",{asis,DefaultVal}," -> [];",nl}),
@@ -760,24 +796,23 @@ gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal
gen_enc_component_optional(Erule,TopType,Cname,
Type=#type{def=#'SEQUENCE'{
extaddgroup=Number,
- components=ExtGroupCompList}},
+ components=_ExtGroupCompList}},
Pos,DynamicEnc,Ext) when is_integer(Number) ->
- emit({nl,"begin",nl}),
+ Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname),
+ emit({"case ",Element," of",nl}),
+
+ emit({"asn1_NOVALUE -> [];",nl}),
asn1ct_name:new(tmpval),
- ExtAddGroupTypeName = asn1ct_gen:list2name([Cname|TopType]),
- emit({{curr,tmpval}," = {'",ExtAddGroupTypeName,"', "}),
- ExtNames = [ExtName||#'ComponentType'{name=ExtName}<-ExtGroupCompList],
- Elements = make_elements(Pos+1,"Val1",ExtNames),
- emit({Elements,"},"}),
- InnerType = asn1ct_gen:get_inner(Type#type.def),
+ emit({{curr,tmpval}," ->",nl}),
+ InnerType = asn1ct_gen:get_inner(Type#type.def),
emit({nl,"%% attribute number ",Pos," with type ",
InnerType,nl}),
NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)),
gen_enc_line(Erule,TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext),
emit({nl,"end"});
gen_enc_component_optional(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext) ->
- Element = make_element(Pos+1,"Val1",Cname),
+ Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname),
emit({"case ",Element," of",nl}),
emit({"asn1_NOVALUE -> [];",nl}),
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index 0bb0b65e5d..0844c38353 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -87,7 +87,7 @@ pgen_module(OutFile,Erules,Module,
% gen_vars(asn1_db:mod_to_vars(Module)),
% gen_tag_table(AllTypes),
file:close(Fid),
- asn1ct:report_verbose("--~p--~n",[{generated,ErlFile}],Options).
+ asn1ct:verbose("--~p--~n",[{generated,ErlFile}],Options).
pgen_typeorval(Erules,Module,N2nConvEnums,{Types,Values,_Ptypes,_Classes,Objects,ObjectSets}) ->
@@ -1340,9 +1340,9 @@ pgen_hrl(Erules,Module,TypeOrVal,Options,_Indent) ->
Y ->
Fid = get(gen_file_out),
file:close(Fid),
- asn1ct:report_verbose("--~p--~n",
- [{generated,lists:concat([get(outfile),".hrl"])}],
- Options),
+ asn1ct:verbose("--~p--~n",
+ [{generated,lists:concat([get(outfile),".hrl"])}],
+ Options),
Y
end.
diff --git a/lib/asn1/src/asn1rt_ber_bin.erl b/lib/asn1/src/asn1rt_ber_bin.erl
index ab04d981b0..22f9f2ecfd 100644
--- a/lib/asn1/src/asn1rt_ber_bin.erl
+++ b/lib/asn1/src/asn1rt_ber_bin.erl
@@ -2192,12 +2192,12 @@ decode_tag_and_length(Buffer) ->
%% Check if valid tag
%%
%% check_if_valid_tag(Tag, List_of_valid_tags, OptOrMand) -> name of the tag
-%%===============================================================================
+%%============================================================================
check_if_valid_tag(<<0,0,_/binary>>,_,_) ->
asn1_EOC;
check_if_valid_tag(<<>>, _, OptOrMand) ->
- check_if_valid_tag2(false,[],[],OptOrMand);
+ check_if_valid_tag2_error([], OptOrMand);
check_if_valid_tag(Bytes, ListOfTags, OptOrMand) when is_binary(Bytes) ->
{Tag, _, _} = decode_tag(Bytes),
check_if_valid_tag(Tag, ListOfTags, OptOrMand);
@@ -2217,7 +2217,6 @@ check_if_valid_tag(Tag, ListOfTags, OptOrMand) ->
check_if_valid_tag2(_Class_TagNo, [], Tag, MandOrOpt) ->
check_if_valid_tag2_error(Tag,MandOrOpt);
-
check_if_valid_tag2(Class_TagNo, [{TagName,TagList}|T], Tag, OptOrMand) ->
case check_if_valid_tag_loop(Class_TagNo, TagList) of
true ->
@@ -2226,7 +2225,7 @@ check_if_valid_tag2(Class_TagNo, [{TagName,TagList}|T], Tag, OptOrMand) ->
check_if_valid_tag2(Class_TagNo, T, Tag, OptOrMand)
end.
--spec(check_if_valid_tag2_error/2 :: (term(),atom()) -> no_return()).
+-spec check_if_valid_tag2_error(term(), atom()) -> no_return().
check_if_valid_tag2_error(Tag,mandatory) ->
exit({error,{asn1,{invalid_tag,Tag}}});
diff --git a/lib/asn1/src/asn1rt_driver_handler.erl b/lib/asn1/src/asn1rt_driver_handler.erl
index c95b243ae0..cc2b501e16 100644
--- a/lib/asn1/src/asn1rt_driver_handler.erl
+++ b/lib/asn1/src/asn1rt_driver_handler.erl
@@ -71,7 +71,10 @@ load_driver(Reason) ->
end.
init(FromPid,FromRef) ->
- register(asn1_driver_owner,self()),
+ case catch register(asn1_driver_owner,self()) of
+ true -> true;
+ _Other -> exit(normal)
+ end,
Dir = filename:join([code:priv_dir(asn1),"lib"]),
case catch erl_ddll:load_driver(Dir,asn1_erl_drv) of
ok ->
diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile
index e8f65ec70b..8a23f8e869 100644
--- a/lib/asn1/test/Makefile
+++ b/lib/asn1/test/Makefile
@@ -193,7 +193,7 @@ release_tests_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)/asn1_bin_SUITE_data
$(INSTALL_DIR) $(RELSYSDIR)/asn1_bin_v2_SUITE_data
$(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
- $(INSTALL_DATA) asn1.spec $(INSTALL_PROGS) $(RELSYSDIR)
+ $(INSTALL_DATA) asn1.spec asn1.cover $(INSTALL_PROGS) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
cd asn1_SUITE_data; tar cfh $(RELSYSDIR)/asn1_SUITE_data.tar *
cd $(RELSYSDIR)/asn1_SUITE_data; tar xf $(RELSYSDIR)/asn1_SUITE_data.tar
diff --git a/lib/asn1/test/asn1.cover b/lib/asn1/test/asn1.cover
new file mode 100644
index 0000000000..589a8b7e3d
--- /dev/null
+++ b/lib/asn1/test/asn1.cover
@@ -0,0 +1,2 @@
+{incl_app,asn1,details}.
+
diff --git a/lib/asn1/test/asn1.spec b/lib/asn1/test/asn1.spec
index 6d9ae924fa..ae96de3a58 100644
--- a/lib/asn1/test/asn1.spec
+++ b/lib/asn1/test/asn1.spec
@@ -1,3 +1 @@
-{topcase, {dir, "../asn1_test"}}.
-
-
+{suites,"../asn1_test",all}.
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
new file mode 100644
index 0000000000..e12dede3f7
--- /dev/null
+++ b/lib/asn1/test/asn1_SUITE.erl
@@ -0,0 +1,2489 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%% Purpose : Test suite for the ASN.1 application
+
+-module(asn1_SUITE).
+-define(PER,'per').
+-define(BER,'ber').
+-define(ber_driver(Erule,Func),
+ case Erule of
+ ber_bin_v2 ->
+ Func;
+ _ -> ok
+ end).
+-define(per_optimize(Erule),
+ case Erule of
+ ber_bin_v2 ->[optimize];
+ _ -> []
+ end).
+-define(per_bit_opt(FuncCall),
+ case ?BER of
+ ber_bin_v2 -> FuncCall;
+% _ -> {skip,"only for bit optimized per_bin"}
+ _ -> ok
+ end).
+-define(uper_bin(FuncCall),
+ case ?PER of
+ per -> FuncCall;
+ _ -> ok
+ end).
+
+-compile(export_all).
+%%-export([Function/Arity, ...]).
+
+-include_lib("test_server/include/test_server.hrl").
+
+%% records used by test-case default
+-record('Def1',{ bool0,
+ bool1 = asn1_DEFAULT,
+ bool2 = asn1_DEFAULT,
+ bool3 = asn1_DEFAULT}).
+
+%-record('Def2',{
+%bool10, bool11 = asn1_DEFAULT, bool12 = asn1_DEFAULT, bool13}).
+
+%-record('Def3',{
+%bool30 = asn1_DEFAULT, bool31 = asn1_DEFAULT, bool32 = asn1_DEFAULT, bool33 = asn1_DEFAULT}).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, compile}, parse, default_per, default_ber,
+ default_per_opt, per, {group, ber}, testPrim,
+ testPrimStrings, testPrimExternal, testChoPrim,
+ testChoExtension, testChoExternal, testChoOptional,
+ testChoOptionalImplicitTag, testChoRecursive,
+ testChoTypeRefCho, testChoTypeRefPrim,
+ testChoTypeRefSeq, testChoTypeRefSet, testDef, testOpt,
+ testSeqDefault, testSeqExtension, testSeqExternal,
+ testSeqOptional, testSeqPrim, testSeqTag,
+ testSeqTypeRefCho, testSeqTypeRefPrim,
+ testSeqTypeRefSeq, testSeqTypeRefSet, testSeqOf,
+ testSeqOfIndefinite, testSeqOfCho, testSeqOfExternal,
+ testSetDefault, testSetExtension,
+ testExtensionAdditionGroup, testSetExternal,
+ testSeqOfTag, testSetOptional, testSetPrim, testSetTag,
+ testSetTypeRefCho, testSetTypeRefPrim,
+ testSetTypeRefSeq, testSetTypeRefSet, testSetOf,
+ testSetOfCho, testSetOfExternal, testSetOfTag,
+ testEnumExt, value_test, testSeq2738, constructed,
+ ber_decode_error, h323test, testSeqIndefinite,
+ testSetIndefinite, testChoiceIndefinite,
+ per_GeneralString, per_open_type, testInfObjectClass,
+ testParameterizedInfObj, testMergeCompile, testobj,
+ testDeepTConstr, testConstraints, testInvokeMod,
+ testExport, testImport, testCompactBitString,
+ testMegaco, testParamBasic, testMvrasn6,
+ testContextSwitchingTypes, testTypeValueNotation,
+ testOpenTypeImplicitTag, duplicate_tags, rtUI, testROSE,
+ testINSTANCE_OF, testTCAP, testDER, specialized_decodes,
+ special_decode_performance, test_driver_load,
+ test_ParamTypeInfObj, test_WS_ParamClass,
+ test_Defed_ObjectIdentifier, testSelectionType,
+ testSSLspecs, testNortel, test_undecoded_rest,
+ test_inline, testTcapsystem, testNBAPsystem,
+ test_compile_options, testDoubleEllipses,
+ test_modified_x420, testX420, test_x691, ticket_6143,
+ testExtensionAdditionGroup] ++ common() ++ particular().
+
+groups() ->
+ [{option_tests, [],
+ [test_compile_options, ticket_6143]},
+ {infobj, [],
+ [testInfObjectClass, testParameterizedInfObj,
+ testMergeCompile, testobj, testDeepTConstr]},
+ {performance, [],
+ [testTimer_ber, testTimer_ber_opt_driver, testTimer_per,
+ testTimer_per_opt, testTimer_uper_bin]},
+ {bugs, [],
+ [test_ParamTypeInfObj, test_WS_ParamClass,
+ test_Defed_ObjectIdentifier]},
+ {compile, [],
+ [c_syntax, c_string_per, c_string_ber,
+ c_implicit_before_choice]},
+ {ber, [],
+ [ber_choiceinseq, ber_optional, ber_optional_keyed_list,
+ ber_other]},
+ {app_test, [], [{asn1_app_test, all}]},
+ {appup_test, [], [{asn1_appup_test, all}]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+%all(suite) -> [test_inline,testNBAPsystem,test_compile_options,ticket_6143].
+
+
+init_per_testcase(Func,Config) ->
+ %%?line test_server:format("Func: ~p~n",[Func]),
+ ?line {ok, _} = file:read_file_info(filename:join([?config(priv_dir,Config)])),
+ ?line code:add_patha(?config(priv_dir,Config)),
+ Dog=
+ case Func of
+ testX420 ->
+ test_server:timetrap({minutes,60}); % 60 minutes
+ _ ->
+ test_server:timetrap({minutes,30}) % 60 minutes
+ end,
+%% Dog=test_server:timetrap(1800000), % 30 minutes
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(_Func,Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog).
+
+
+testPrim(suite) -> [];
+testPrim(Config) ->
+ ?line testPrim:compile(Config,?BER,[]),
+ ?line testPrim_cases(?BER),
+ ?line ?ber_driver(?BER,testPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrim_cases(?BER)),
+ ?line testPrim:compile(Config,?PER,[]),
+ ?line testPrim_cases(?PER),
+ ?line ?per_bit_opt(testPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrim_cases(?PER)),
+ ?line ?uper_bin(testPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrim_cases(uper_bin)),
+ ?line testPrim:compile(Config,?PER,[optimize]),
+ ?line testPrim_cases(?PER).
+
+testPrim_cases(Rules) ->
+ ?line testPrim:bool(Rules),
+ ?line testPrim:int(Rules),
+ ?line testPrim:enum(Rules),
+ ?line testPrim:obj_id(Rules),
+ ?line testPrim:rel_oid(Rules),
+ ?line testPrim:null(Rules),
+ ?line testPrim:real(Rules).
+
+
+testCompactBitString(suite) -> [];
+testCompactBitString(Config) ->
+
+ ?line testCompactBitString:compile(Config,?BER,[compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?BER),
+
+ ?line ?ber_driver(?BER,testCompactBitString:compile(Config,?BER,[compact_bit_string,driver])),
+ ?line ?ber_driver(?BER,testCompactBitString:compact_bit_string(?BER)),
+
+ ?line testCompactBitString:compile(Config,?PER,[compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?PER),
+ ?line testCompactBitString:bit_string_unnamed(?PER),
+
+ ?line ?per_bit_opt(testCompactBitString:compile(Config,?PER,
+ [compact_bit_string,optimize])),
+ ?line ?per_bit_opt(testCompactBitString:compact_bit_string(?PER)),
+ ?line ?per_bit_opt(testCompactBitString:bit_string_unnamed(?PER)),
+ ?line ?per_bit_opt(testCompactBitString:ticket_7734(?PER)),
+
+ ?line ?uper_bin(testCompactBitString:compile(Config,uper_bin,
+ [compact_bit_string])),
+ ?line ?uper_bin(testCompactBitString:compact_bit_string(uper_bin)),
+ ?line ?uper_bin(testCompactBitString:bit_string_unnamed(uper_bin)),
+
+ ?line testCompactBitString:compile(Config,?PER,[optimize,compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?PER),
+ ?line testCompactBitString:bit_string_unnamed(?PER),
+
+ ?line testCompactBitString:otp_4869(?PER).
+
+
+testPrimStrings(suite) -> [];
+testPrimStrings(Config) ->
+
+ ?line testPrimStrings:compile(Config,?BER,[]),
+ ?line testPrimStrings_cases(?BER),
+ ?line testPrimStrings:more_strings(?BER), %% these are not implemented in per yet
+ ?line ?ber_driver(?BER,testPrimStrings:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimStrings_cases(?BER)),
+ ?line ?ber_driver(?BER,testPrimStrings:more_strings(?BER)),
+
+ ?line testPrimStrings:compile(Config,?PER,[]),
+ ?line testPrimStrings_cases(?PER),
+
+ ?line ?per_bit_opt(testPrimStrings:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimStrings_cases(?PER)),
+
+ ?line ?uper_bin(testPrimStrings:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimStrings_cases(uper_bin)),
+
+ ?line testPrimStrings:compile(Config,?PER,[optimize]),
+ ?line testPrimStrings_cases(?PER).
+
+testPrimStrings_cases(Rules) ->
+ ?line testPrimStrings:bit_string(Rules),
+ ?line testPrimStrings:bit_string_unnamed(Rules),
+ ?line testPrimStrings:octet_string(Rules),
+ ?line testPrimStrings:numeric_string(Rules),
+ ?line testPrimStrings:other_strings(Rules),
+ ?line testPrimStrings:universal_string(Rules),
+ ?line testPrimStrings:bmp_string(Rules),
+ ?line testPrimStrings:times(Rules),
+ ?line testPrimStrings:utf8_string(Rules).
+
+
+
+testPrimExternal(suite) -> [];
+testPrimExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testPrimExternal:compile(Config,?BER,[]),
+ ?line testPrimExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testPrimExternal:compile(Config,?PER,[]),
+ ?line testPrimExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testPrimExternal:compile(Config,?PER,[optimize]),
+ ?line testPrimExternal_cases(?PER).
+
+testPrimExternal_cases(Rules) ->
+ ?line testPrimExternal:external(Rules).
+
+
+
+
+testChoPrim(suite) -> [];
+testChoPrim(Config) ->
+
+ ?line testChoPrim:compile(Config,?BER,[]),
+ ?line testChoPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoPrim_cases(?BER)),
+
+ ?line testChoPrim:compile(Config,?PER,[]),
+ ?line testChoPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testChoPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoPrim_cases(?PER)),
+
+ ?line ?uper_bin(testChoPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoPrim_cases(uper_bin)),
+
+ ?line testChoPrim:compile(Config,?PER,[optimize]),
+ ?line testChoPrim_cases(?PER).
+
+testChoPrim_cases(Rules) ->
+ ?line testChoPrim:bool(Rules),
+ ?line testChoPrim:int(Rules).
+
+
+
+testChoExtension(suite) -> [];
+testChoExtension(Config) ->
+
+ ?line testChoExtension:compile(Config,?BER,[]),
+ ?line testChoExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExtension_cases(?BER)),
+
+ ?line testChoExtension:compile(Config,?PER,[]),
+ ?line testChoExtension_cases(?PER),
+
+ ?line ?per_bit_opt(testChoExtension:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExtension_cases(?PER)),
+
+ ?line ?uper_bin(testChoExtension:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExtension_cases(uper_bin)),
+
+ ?line testChoExtension:compile(Config,?PER,[optimize]),
+ ?line testChoExtension_cases(?PER).
+
+testChoExtension_cases(Rules) ->
+ ?line testChoExtension:extension(Rules).
+
+
+
+testChoExternal(suite) -> [];
+testChoExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testChoExternal:compile(Config,?BER,[]),
+ ?line testChoExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testChoExternal:compile(Config,?PER,[]),
+ ?line testChoExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testChoExternal:compile(Config,?PER,[optimize]),
+ ?line testChoExternal_cases(?PER).
+
+
+testChoExternal_cases(Rules) ->
+ ?line testChoExternal:external(Rules).
+
+
+
+testChoOptional(suite) -> [];
+testChoOptional(Config) ->
+
+ ?line testChoOptional:compile(Config,?BER,[]),
+ ?line testChoOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoOptional_cases(?BER)),
+
+ ?line testChoOptional:compile(Config,?PER,[]),
+ ?line testChoOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testChoOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoOptional_cases(?PER)),
+
+ ?line ?uper_bin(testChoOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoOptional_cases(uper_bin)),
+
+ ?line testChoOptional:compile(Config,?PER,[optimize]),
+ ?line testChoOptional_cases(?PER).
+
+testChoOptional_cases(Rules) ->
+ ?line testChoOptional:optional(Rules).
+
+testChoOptionalImplicitTag(suite) -> [];
+testChoOptionalImplicitTag(Config) ->
+ %% Only meaningful for ?BER
+ ?line testChoOptionalImplicitTag:compile(Config,?BER),
+ ?line testChoOptionalImplicitTag:optional(?BER).
+
+
+testChoRecursive(suite) -> [];
+testChoRecursive(Config) ->
+
+ ?line testChoRecursive:compile(Config,?BER,[]),
+ ?line testChoRecursive_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoRecursive:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoRecursive_cases(?BER)),
+
+ ?line testChoRecursive:compile(Config,?PER,[]),
+ ?line testChoRecursive_cases(?PER),
+
+ ?line ?per_bit_opt(testChoRecursive:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoRecursive_cases(?PER)),
+
+ ?line ?uper_bin(testChoRecursive:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoRecursive_cases(uper_bin)),
+
+ ?line testChoRecursive:compile(Config,?PER,[optimize]),
+ ?line testChoRecursive_cases(?PER).
+
+testChoRecursive_cases(Rules) ->
+ ?line testChoRecursive:recursive(Rules).
+
+
+
+testChoTypeRefCho(suite) -> [];
+testChoTypeRefCho(Config) ->
+
+ ?line testChoTypeRefCho:compile(Config,?BER,[]),
+ ?line testChoTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefCho_cases(?BER)),
+
+ ?line testChoTypeRefCho:compile(Config,?PER,[]),
+ ?line testChoTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefCho_cases(uper_bin)),
+
+ ?line testChoTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefCho_cases(?PER).
+
+testChoTypeRefCho_cases(Rules) ->
+ ?line testChoTypeRefCho:choice(Rules).
+
+
+
+testChoTypeRefPrim(suite) -> [];
+testChoTypeRefPrim(Config) ->
+
+ ?line testChoTypeRefPrim:compile(Config,?BER,[]),
+ ?line testChoTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefPrim_cases(?BER)),
+
+ ?line testChoTypeRefPrim:compile(Config,?PER,[]),
+ ?line testChoTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefPrim_cases(uper_bin)),
+
+ ?line testChoTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefPrim_cases(?PER).
+
+testChoTypeRefPrim_cases(Rules) ->
+ ?line testChoTypeRefPrim:prim(Rules).
+
+
+
+testChoTypeRefSeq(suite) -> [];
+testChoTypeRefSeq(Config) ->
+
+ ?line testChoTypeRefSeq:compile(Config,?BER,[]),
+ ?line testChoTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefSeq_cases(?BER)),
+
+ ?line testChoTypeRefSeq:compile(Config,?PER,[]),
+ ?line testChoTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefSeq_cases(uper_bin)),
+
+ ?line testChoTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefSeq_cases(?PER).
+
+testChoTypeRefSeq_cases(Rules) ->
+ ?line testChoTypeRefSeq:seq(Rules).
+
+
+
+testChoTypeRefSet(suite) -> [];
+testChoTypeRefSet(Config) ->
+
+ ?line testChoTypeRefSet:compile(Config,?BER,[]),
+ ?line testChoTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefSet_cases(?BER)),
+
+ ?line testChoTypeRefSet:compile(Config,?PER,[]),
+ ?line testChoTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefSet_cases(uper_bin)),
+
+ ?line testChoTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefSet_cases(?PER).
+
+testChoTypeRefSet_cases(Rules) ->
+ ?line testChoTypeRefSet:set(Rules).
+
+
+
+testDef(suite) -> [];
+testDef(Config) ->
+
+ ?line testDef:compile(Config,?BER,[]),
+ ?line testDef_cases(?BER),
+
+ ?line ?ber_driver(?BER,testDef:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDef_cases(?BER)),
+
+ ?line testDef:compile(Config,?PER,[]),
+ ?line testDef_cases(?PER),
+
+ ?line ?per_bit_opt(testDef:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDef_cases(?PER)),
+
+ ?line ?uper_bin(testDef:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDef_cases(uper_bin)),
+
+ ?line testDef:compile(Config,?PER,[optimize]),
+ ?line testDef_cases(?PER).
+
+testDef_cases(Rules) ->
+ ?line testDef:main(Rules).
+
+
+
+testOpt(suite) -> [];
+testOpt(Config) ->
+
+ ?line testOpt:compile(Config,?BER),
+ ?line testOpt_cases(?BER),
+
+ ?line testOpt:compile(Config,?PER),
+ ?line testOpt_cases(?PER).
+
+testOpt_cases(Rules) ->
+ ?line testOpt:main(Rules).
+
+
+testEnumExt(suite) -> [];
+testEnumExt(Config) ->
+
+ ?line testEnumExt:compile(Config,?BER,[]),
+ ?line testEnumExt:main(?BER),
+
+ ?line ?ber_driver(?BER,testEnumExt:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testEnumExt:main(?BER)),
+
+ ?line testEnumExt:compile(Config,?PER,[]),
+ ?line testEnumExt:main(?PER),
+
+ ?line ?per_bit_opt(testEnumExt:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testEnumExt:main(?PER)),
+
+ ?line ?uper_bin(testEnumExt:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testEnumExt:main(uper_bin)),
+
+ ?line testEnumExt:compile(Config,?PER,[optimize]),
+ ?line testEnumExt:main(?PER).
+
+testSeqDefault(doc) -> ["Test of OTP-2523 ENUMERATED with extensionmark."];
+testSeqDefault(suite) -> [];
+testSeqDefault(Config) ->
+
+ ?line testSeqDefault:compile(Config,?BER,[]),
+ ?line testSeqDefault_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqDefault:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqDefault_cases(?BER)),
+
+ ?line testSeqDefault:compile(Config,?PER,[]),
+ ?line testSeqDefault_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqDefault:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqDefault_cases(?PER)),
+
+ ?line ?uper_bin(testSeqDefault:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqDefault_cases(uper_bin)),
+
+ ?line testSeqDefault:compile(Config,?PER,[optimize]),
+ ?line testSeqDefault_cases(?PER).
+
+testSeqDefault_cases(Rules) ->
+ ?line testSeqDefault:main(Rules).
+
+
+
+testSeqExtension(suite) -> [];
+testSeqExtension(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqExtension:compile(Config,?BER,[]),
+ ?line testSeqExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExtension_cases(?BER)).
+
+testSeqExtension_cases(Rules) ->
+ ?line testSeqExtension:main(Rules).
+
+
+
+testSeqExternal(suite) -> [];
+testSeqExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqExternal:compile(Config,?BER,[]),
+ ?line testSeqExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExternal_cases(?BER)).
+
+testSeqExternal_cases(Rules) ->
+ ?line testSeqExternal:main(Rules).
+
+
+testSeqOptional(suite) -> [];
+testSeqOptional(Config) ->
+
+ ?line testSeqOptional:compile(Config,?BER,[]),
+ ?line testSeqOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOptional_cases(?BER)),
+
+ ?line testSeqOptional:compile(Config,?PER,[]),
+ ?line testSeqOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOptional_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOptional_cases(uper_bin)),
+
+ ?line testSeqOptional:compile(Config,?PER,[optimize]),
+ ?line testSeqOptional_cases(?PER).
+
+testSeqOptional_cases(Rules) ->
+ ?line testSeqOptional:main(Rules).
+
+
+
+testSeqPrim(suite) -> [];
+testSeqPrim(Config) ->
+
+ ?line testSeqPrim:compile(Config,?BER,[]),
+ ?line testSeqPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqPrim_cases(?BER)),
+
+ ?line testSeqPrim:compile(Config,?PER,[]),
+ ?line testSeqPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSeqPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqPrim_cases(uper_bin)),
+
+ ?line testSeqPrim:compile(Config,?PER,[optimize]),
+ ?line testSeqPrim_cases(?PER).
+
+testSeqPrim_cases(Rules) ->
+ ?line testSeqPrim:main(Rules).
+
+
+testSeq2738(doc) -> ["Test of OTP-2738 Detect corrupt optional component."];
+testSeq2738(suite) -> [];
+testSeq2738(Config) ->
+
+ ?line testSeq2738:compile(Config,?BER,[]),
+ ?line testSeq2738_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeq2738:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeq2738_cases(?BER)),
+
+ ?line testSeq2738:compile(Config,?PER,[]),
+ ?line testSeq2738_cases(?PER),
+
+ ?line ?per_bit_opt(testSeq2738:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeq2738_cases(?PER)),
+
+ ?line ?uper_bin(testSeq2738:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeq2738_cases(uper_bin)),
+
+ ?line testSeq2738:compile(Config,?PER,[optimize]),
+ ?line testSeq2738_cases(?PER).
+
+testSeq2738_cases(Rules) ->
+ ?line testSeq2738:main(Rules).
+
+
+testSeqTag(suite) -> [];
+testSeqTag(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqTag:compile(Config,?BER,[]),
+ ?line testSeqTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqTag:compile(Config,?PER,[]),
+ ?line testSeqTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqTag:compile(Config,?PER,[optimize]),
+ ?line testSeqTag_cases(?PER).
+
+testSeqTag_cases(Rules) ->
+ ?line testSeqTag:main(Rules).
+
+
+
+
+testSeqTypeRefCho(suite) -> [];
+testSeqTypeRefCho(Config) ->
+
+ ?line testSeqTypeRefCho:compile(Config,?BER,[]),
+ ?line testSeqTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefCho_cases(?BER)),
+
+ ?line testSeqTypeRefCho:compile(Config,?PER,[]),
+ ?line testSeqTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefCho_cases(uper_bin)),
+
+ ?line testSeqTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefCho_cases(?PER).
+
+testSeqTypeRefCho_cases(Rules) ->
+ ?line testSeqTypeRefCho:main(Rules).
+
+
+
+testSeqTypeRefPrim(suite) -> [];
+testSeqTypeRefPrim(Config) ->
+
+ ?line testSeqTypeRefPrim:compile(Config,?BER,[]),
+ ?line testSeqTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefPrim_cases(?BER)),
+
+ ?line testSeqTypeRefPrim:compile(Config,?PER,[]),
+ ?line testSeqTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefPrim_cases(uper_bin)),
+
+ ?line testSeqTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefPrim_cases(?PER).
+
+testSeqTypeRefPrim_cases(Rules) ->
+ ?line testSeqTypeRefPrim:main(Rules).
+
+
+
+testSeqTypeRefSeq(suite) -> [];
+testSeqTypeRefSeq(Config) ->
+
+ ?line testSeqTypeRefSeq:compile(Config,?BER,[]),
+ ?line testSeqTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefSeq_cases(?BER)),
+
+ ?line testSeqTypeRefSeq:compile(Config,?PER,[]),
+ ?line testSeqTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefSeq_cases(uper_bin)),
+
+ ?line testSeqTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefSeq_cases(?PER).
+
+testSeqTypeRefSeq_cases(Rules) ->
+ ?line testSeqTypeRefSeq:main(Rules).
+
+
+
+testSeqTypeRefSet(suite) -> [];
+testSeqTypeRefSet(Config) ->
+
+ ?line testSeqTypeRefSet:compile(Config,?BER,[]),
+ ?line testSeqTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefSet_cases(?BER)),
+
+ ?line testSeqTypeRefSet:compile(Config,?PER,[]),
+ ?line testSeqTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefSet_cases(uper_bin)),
+
+ ?line testSeqTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefSet_cases(?PER).
+
+testSeqTypeRefSet_cases(Rules) ->
+ ?line testSeqTypeRefSet:main(Rules).
+
+
+
+
+testSeqOf(suite) -> [];
+testSeqOf(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOf:compile(Config,?BER,[]),
+ ?line testSeqOf_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOf:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOf_cases(?BER)),
+
+ ?line testSeqOf:compile(Config,?PER,[]),
+ ?line testSeqOf_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOf:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOf_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOf:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOf_cases(uper_bin)),
+
+ ?line testSeqOf:compile(Config,?PER,[optimize]),
+ ?line testSeqOf_cases(?PER).
+
+testSeqOf_cases(Rules) ->
+ ?line testSeqOf:main(Rules).
+
+
+
+
+testSeqOfCho(suite) -> [];
+testSeqOfCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOfCho:compile(Config,?BER,[]),
+ ?line testSeqOfCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOfCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfCho_cases(?BER)),
+
+ ?line testSeqOfCho:compile(Config,?PER,[]),
+ ?line testSeqOfCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOfCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfCho_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOfCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfCho_cases(uper_bin)),
+
+ ?line testSeqOfCho:compile(Config,?PER,[optimize]),
+ ?line testSeqOfCho_cases(?PER).
+
+testSeqOfIndefinite(suite) -> [];
+testSeqOfIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOfIndefinite:compile(Config,?BER,[]),
+ ?line testSeqOfIndefinite:main(),
+
+ ?line ?ber_driver(?BER,testSeqOfIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfIndefinite:main()).
+
+testSeqOfCho_cases(Rules) ->
+ ?line testSeqOfCho:main(Rules).
+
+
+testSeqOfExternal(suite) -> [];
+testSeqOfExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqOfExternal:compile(Config,?BER,[]),
+ ?line testSeqOfExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqOfExternal:compile(Config,?PER,[]),
+ ?line testSeqOfExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfExternal_cases(?PER).
+
+testSeqOfExternal_cases(Rules) ->
+ ?line testSeqOfExternal:main(Rules).
+
+
+
+testSeqOfTag(suite) -> [];
+testSeqOfTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqOfTag:compile(Config,?BER,[]),
+ ?line testSeqOfTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqOfTag:compile(Config,?PER,[]),
+ ?line testSeqOfTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfTag:compile(Config,?PER,[optimize]),
+ ?line testSeqOfTag_cases(?PER).
+
+testSeqOfTag_cases(Rules) ->
+ ?line testSeqOfTag:main(Rules).
+
+
+
+
+testSetDefault(suite) -> [];
+testSetDefault(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetDefault:compile(Config,?BER,[]),
+ ?line testSetDefault_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetDefault:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetDefault_cases(?BER)),
+
+ ?line testSetDefault:compile(Config,?PER,[]),
+ ?line testSetDefault_cases(?PER),
+
+ ?line ?per_bit_opt(testSetDefault:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetDefault_cases(?PER)),
+
+ ?line ?uper_bin(testSetDefault:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetDefault_cases(uper_bin)),
+
+ ?line testSetDefault:compile(Config,?PER,[optimize]),
+ ?line testSetDefault_cases(?PER).
+
+testSetDefault_cases(Rules) ->
+ ?line testSetDefault:main(Rules).
+
+
+testParamBasic(suite) -> [];
+testParamBasic(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testParamBasic:compile(Config,?BER,[]),
+ ?line testParamBasic_cases(?BER),
+
+ ?line ?ber_driver(?BER,testParamBasic:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testParamBasic_cases(?BER)),
+
+ ?line testParamBasic:compile(Config,?PER,[]),
+ ?line testParamBasic_cases(?PER),
+
+ ?line ?per_bit_opt(testParamBasic:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testParamBasic_cases(?PER)),
+
+ ?line ?uper_bin(testParamBasic:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testParamBasic_cases(uper_bin)),
+
+ ?line testParamBasic:compile(Config,?PER,[optimize]),
+ ?line testParamBasic_cases(?PER).
+
+
+testParamBasic_cases(Rules) ->
+ ?line testParamBasic:main(Rules).
+
+testSetExtension(suite) -> [];
+testSetExtension(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetExtension:compile(Config,?BER,[]),
+ ?line testSetExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExtension_cases(?BER)).
+
+testSetExtension_cases(Rules) ->
+ ?line testSetExtension:main(Rules).
+
+
+testSetExternal(suite) -> [];
+testSetExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetExternal:compile(Config,?BER,[]),
+ ?line testSetExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExternal_cases(?BER)).
+
+testSetExternal_cases(Rules) ->
+ ?line testSetExternal:main(Rules).
+
+
+testSetOptional(suite) -> [];
+testSetOptional(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOptional:compile(Config,?BER,[]),
+ ?line testSetOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOptional_cases(?BER)),
+
+ ?line testSetOptional:compile(Config,?PER,[]),
+ ?line testSetOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOptional_cases(?PER)),
+
+ ?line ?uper_bin(testSetOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOptional_cases(uper_bin)),
+
+ ?line testSetOptional:compile(Config,?PER,[optimize]),
+ ?line testSetOptional_cases(?PER).
+
+testSetOptional_cases(Rules) ->
+ ?line ok = testSetOptional:ticket_7533(Rules),
+ ?line ok = testSetOptional:main(Rules).
+
+
+
+
+testSetPrim(suite) -> [];
+testSetPrim(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetPrim:compile(Config,?BER,[]),
+ ?line testSetPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetPrim_cases(?BER)),
+
+ ?line testSetPrim:compile(Config,?PER,[]),
+ ?line testSetPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSetPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSetPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetPrim_cases(uper_bin)),
+
+ ?line testSetPrim:compile(Config,?PER,[optimize]),
+ ?line testSetPrim_cases(?PER).
+
+testSetPrim_cases(Rules) ->
+ ?line testSetPrim:main(Rules).
+
+
+
+testSetTag(suite) -> [];
+testSetTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetTag:compile(Config,?BER,[]),
+ ?line testSetTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetTag:compile(Config,?PER,[]),
+ ?line testSetTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetTag:compile(Config,?PER,[optimize]),
+ ?line testSetTag_cases(?PER).
+
+testSetTag_cases(Rules) ->
+ ?line testSetTag:main(Rules).
+
+
+
+testSetTypeRefCho(suite) -> [];
+testSetTypeRefCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefCho:compile(Config,?BER,[]),
+ ?line testSetTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefCho_cases(?BER)),
+
+ ?line testSetTypeRefCho:compile(Config,?PER,[]),
+ ?line testSetTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefCho_cases(uper_bin)),
+
+ ?line testSetTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefCho_cases(?PER).
+
+testSetTypeRefCho_cases(Rules) ->
+ ?line testSetTypeRefCho:main(Rules).
+
+
+
+testSetTypeRefPrim(suite) -> [];
+testSetTypeRefPrim(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefPrim:compile(Config,?BER,[]),
+ ?line testSetTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefPrim_cases(?BER)),
+
+ ?line testSetTypeRefPrim:compile(Config,?PER,[]),
+ ?line testSetTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefPrim_cases(uper_bin)),
+
+ ?line testSetTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefPrim_cases(?PER).
+
+testSetTypeRefPrim_cases(Rules) ->
+ ?line testSetTypeRefPrim:main(Rules).
+
+
+
+testSetTypeRefSeq(suite) -> [];
+testSetTypeRefSeq(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefSeq:compile(Config,?BER,[]),
+ ?line testSetTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefSeq_cases(?BER)),
+
+ ?line testSetTypeRefSeq:compile(Config,?PER,[]),
+ ?line testSetTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefSeq_cases(uper_bin)),
+
+ ?line testSetTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefSeq_cases(?PER).
+
+testSetTypeRefSeq_cases(Rules) ->
+ ?line testSetTypeRefSeq:main(Rules).
+
+
+
+testSetTypeRefSet(suite) -> [];
+testSetTypeRefSet(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefSet:compile(Config,?BER,[]),
+ ?line testSetTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefSet_cases(?BER)),
+
+ ?line testSetTypeRefSet:compile(Config,?PER,[]),
+ ?line testSetTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefSet_cases(uper_bin)),
+
+ ?line testSetTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefSet_cases(?PER).
+
+testSetTypeRefSet_cases(Rules) ->
+ ?line testSetTypeRefSet:main(Rules).
+
+
+
+testSetOf(suite) -> [];
+testSetOf(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOf:compile(Config,?BER,[]),
+ ?line testSetOf_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOf:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOf_cases(?BER)),
+
+ ?line testSetOf:compile(Config,?PER,[]),
+ ?line testSetOf_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOf:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOf_cases(?PER)),
+
+ ?line ?uper_bin(testSetOf:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOf_cases(uper_bin)),
+
+ ?line testSetOf:compile(Config,?PER,[optimize]),
+ ?line testSetOf_cases(?PER).
+
+testSetOf_cases(Rules) ->
+ ?line testSetOf:main(Rules).
+
+
+
+testSetOfCho(suite) -> [];
+testSetOfCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOfCho:compile(Config,?BER,[]),
+ ?line testSetOfCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOfCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfCho_cases(?BER)),
+
+ ?line testSetOfCho:compile(Config,?PER,[]),
+ ?line testSetOfCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOfCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfCho_cases(?PER)),
+
+ ?line ?uper_bin(testSetOfCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfCho_cases(uper_bin)),
+
+ ?line testSetOfCho:compile(Config,?PER,[optimize]),
+ ?line testSetOfCho_cases(?PER).
+
+testSetOfCho_cases(Rules) ->
+ ?line testSetOfCho:main(Rules).
+
+
+testSetOfExternal(suite) -> [];
+testSetOfExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetOfExternal:compile(Config,?BER,[]),
+ ?line testSetOfExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetOfExternal:compile(Config,?PER,[]),
+ ?line testSetOfExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfExternal_cases(?PER).
+
+testSetOfExternal_cases(Rules) ->
+ ?line testSetOfExternal:main(Rules).
+
+
+
+
+testSetOfTag(suite) -> [];
+testSetOfTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetOfTag:compile(Config,?BER,[]),
+ ?line testSetOfTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetOfTag:compile(Config,?PER,[]),
+ ?line testSetOfTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfTag:compile(Config,?PER,[optimize]),
+ ?line testSetOfTag_cases(?PER).
+
+testSetOfTag_cases(Rules) ->
+ ?line testSetOfTag:main(Rules).
+
+
+c_syntax(suite) -> [];
+c_syntax(Config) ->
+ ?line DataDir% ?line testExternal:compile(Config,?PER),
+% ?line testPrimExternal:compile(Config,?PER),
+% ?line testPrimExternal_cases(?PER).
+ = ?config(data_dir,Config),
+ ?line _TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line {error,_R1} = asn1ct:compile(filename:join(DataDir,"Syntax")),
+ ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"BadTypeEnding")),
+ ?line {error,_R3} = asn1ct:compile(filename:join(DataDir,
+ "BadValueAssignment1")),
+ ?line {error,_R4} = asn1ct:compile(filename:join(DataDir,
+ "BadValueAssignment2")),
+ ?line {error,_R5} = asn1ct:compile(filename:join(DataDir,
+ "BadValueSet")),
+ ?line {error,_R6} = asn1ct:compile(filename:join(DataDir,
+ "ChoiceBadExtension")),
+ ?line {error,_R7} = asn1ct:compile(filename:join(DataDir,
+ "EnumerationBadExtension")),
+ ?line {error,_R8} = asn1ct:compile(filename:join(DataDir,
+ "Example")),
+ ?line {error,_R9} = asn1ct:compile(filename:join(DataDir,
+ "Export1")),
+ ?line {error,_R10} = asn1ct:compile(filename:join(DataDir,
+ "MissingEnd")),
+ ?line {error,_R11} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComma")),
+ ?line {error,_R12} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComponentName")),
+ ?line {error,_R13} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComponentType")),
+ ?line {error,_R14} = asn1ct:compile(filename:join(DataDir,
+ "SeqBadComma")).
+
+
+c_string_per(suite) -> [];
+c_string_per(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?PER,{outdir,TempDir}]).
+
+c_string_ber(suite) -> [];
+c_string_ber(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?BER,{outdir,TempDir}]).
+
+
+c_implicit_before_choice(suite) -> [];
+c_implicit_before_choice(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"CCSNARG3"),[?BER,{outdir,TempDir}]).
+
+parse(suite) -> [];
+parse(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ M1 = test_modules(),
+% M2 = parse_modules(),
+ ?line ok = parse1(M1,DataDir,OutDir).
+
+parse1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[abs,{outdir,OutDir}]),
+ parse1(T,DataDir,OutDir);
+parse1([],_,_) ->
+ ok.
+
+per(suite) -> [];
+per(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = per1(per_modules(),DataDir,OutDir),
+ ?line ?per_bit_opt(per1_bit_opt(per_modules(),DataDir,OutDir)),
+ ?line ok = per1_opt(per_modules(),DataDir,OutDir).
+
+
+per1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1(T,DataDir,OutDir);
+per1([],_,_) ->
+ ok.
+
+per1_bit_opt([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimize,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1_bit_opt(T,DataDir,OutDir);
+per1_bit_opt([],_,_) ->
+ ok.
+
+per1_opt([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimized,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1_opt(T,DataDir,OutDir);
+per1_opt([],_,_) ->
+ ok.
+
+
+ber_choiceinseq(suite) ->[];
+ber_choiceinseq(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"ChoiceInSeq"),[?BER,{outdir,OutDir}]).
+
+ber_optional(suite) ->[];
+ber_optional(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),[?BER,{outdir,OutDir}]),
+ ?line V = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
+ {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
+ {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
+ ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
+ ?line Bytes = lists:flatten(B),
+ ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
+ ?line ok = eq(V,element(2,V2)).
+
+ber_optional_keyed_list(suite) ->[];
+ber_optional_keyed_list(Config) ->
+ case ?BER of
+ ber_bin_v2 -> ok;
+ _ ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),
+ [?BER,keyed_list,{outdir,OutDir}]),
+ ?line Vrecord = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
+ {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
+ {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
+ ?line V = [ {a,[{scriptKey,10}]},
+ {b,[]},
+ {c,[{callingPartysCategory,111}]} ],
+ ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
+ ?line Bytes = lists:flatten(B),
+ ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
+ ?line ok = eq(Vrecord,element(2,V2))
+ end.
+
+
+eq(V,V) ->
+ ok.
+
+
+ber_other(suite) ->[];
+ber_other(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = ber1(ber_modules(),DataDir,OutDir).
+
+
+ber1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?BER,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ ber1(T,DataDir,OutDir);
+ber1([],_,_) ->
+ ok.
+
+default_per(suite) ->[];
+default_per(Config) ->
+ default1(?PER,Config,[]).
+
+default_per_opt(suite) -> [];
+default_per_opt(Config) ->
+ ?per_bit_opt(default1(?PER,Config,[optimize])),
+ default1(?PER,Config,[optimize]).
+
+default_ber(suite) ->[];
+default_ber(Config) ->
+ default1(?BER,Config,[]).
+
+default1(Rule,Config,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Def",[Rule,{outdir,OutDir}]++Options),
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,
+ bool1 = true,
+ bool2 = true,
+ bool3 = true}),
+ ?line {ok,{'Def1',true,true,true,true}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true}),
+ ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,bool2=false}),
+ ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes3)).
+
+
+value_test(suite) ->[];
+value_test(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?BER,{outdir,OutDir}]),
+ ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
+ ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?PER,{outdir,OutDir}]),
+ ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
+ ?line ok = test_bad_values:tests(Config),
+ ok.
+
+
+constructed(suite) ->
+ [];
+constructed(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Constructed",[?BER,{outdir,OutDir}]),
+ ?line {ok,B} = asn1_wrapper:encode('Constructed','S',{'S',false}),
+ ?line [40,3,1,1,0] = lists:flatten(B),
+ ?line {ok,B1} = asn1_wrapper:encode('Constructed','S2',{'S2',false}),
+ ?line [40,5,48,3,1,1,0] = lists:flatten(B1),
+ ?line {ok,B2} = asn1_wrapper:encode('Constructed','I',10),
+ ?line [136,1,10] = lists:flatten(B2),
+ ok.
+
+ber_decode_error(suite) -> [];
+ber_decode_error(Config) ->
+ ?line ok = ber_decode_error:compile(Config,?BER,[]),
+ ?line ok = ber_decode_error:run([]),
+
+ ?line ok = ?ber_driver(?BER,ber_decode_error:compile(Config,?BER,[driver])),
+ ?line ok = ?ber_driver(?BER,ber_decode_error:run([driver])),
+ ok.
+
+h323test(suite) ->
+ [];
+h323test(Config) ->
+ ?line ok = h323test:compile(Config,?PER,[]),
+ ?line ok = h323test:run(?PER),
+ ?line ?per_bit_opt(h323test:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(h323test:run(?PER)),
+ ?line ?uper_bin(h323test:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(h323test:run(uper_bin)),
+ ?line ok = h323test:compile(Config,?PER,[optimize]),
+ ?line ok = h323test:run(?PER),
+ ok.
+
+per_GeneralString(suite) ->
+ [];
+per_GeneralString(Config) ->
+ case erlang:module_loaded('MULTIMEDIA-SYSTEM-CONTROL') of
+ true ->
+ ok;
+ false ->
+ h323test:compile(Config,?PER,[])
+ end,
+ UI = [109,64,1,57],
+ ?line {ok,_V} = asn1_wrapper:decode('MULTIMEDIA-SYSTEM-CONTROL',
+ 'MultimediaSystemControlMessage',UI).
+
+per_open_type(suite) ->
+ [];
+per_open_type(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line ok = asn1ct:compile(DataDir ++ "OpenType",[?PER,{outdir,OutDir}]),
+ Stype = {'Stype',10,true},
+ ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
+ ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes),
+
+ ?line ?per_bit_opt(ok = asn1ct:compile(DataDir ++ "OpenType",
+ [?PER,optimize,{outdir,OutDir}])),
+ ?line ?per_bit_opt({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
+ ?line ?per_bit_opt({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
+
+ ?line ?uper_bin(ok = asn1ct:compile(DataDir ++ "OpenType",
+ [uper_bin,{outdir,OutDir}])),
+ ?line ?uper_bin({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
+ ?line ?uper_bin({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "OpenType",
+ [?PER,optimize,{outdir,OutDir}]),
+ ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
+ ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes).
+
+testConstraints(suite) ->
+ [];
+testConstraints(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testConstraints:compile(Config,?BER,[]),
+ ?line testConstraints:int_constraints(?BER),
+
+ ?line ?ber_driver(?BER,testConstraints:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testConstraints:int_constraints(?BER)),
+
+ ?line testConstraints:compile(Config,?PER,[]),
+ ?line testConstraints:int_constraints(?PER),
+ ?line testConstraints:refed_NNL_name(?PER),
+
+ ?line ?per_bit_opt(testConstraints:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testConstraints:int_constraints(?PER)),
+ ?line ?per_bit_opt(testConstraints:refed_NNL_name(?PER)),
+
+ ?line ?uper_bin(testConstraints:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testConstraints:int_constraints(uper_bin)),
+ ?line ?uper_bin(testConstraints:refed_NNL_name(uper_bin)),
+
+ ?line testConstraints:compile(Config,?PER,[optimize]),
+ ?line testConstraints:int_constraints(?PER),
+ ?line testConstraints:refed_NNL_name(?PER).
+
+testSeqIndefinite(suite) -> [];
+testSeqIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqIndefinite:compile(Config,?BER,[]),
+ ?line testSeqIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testSeqIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqIndefinite:main(?BER)).
+
+testSetIndefinite(suite) -> [];
+testSetIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetIndefinite:compile(Config,?BER,[]),
+ ?line testSetIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testSetIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetIndefinite:main(?BER)).
+
+testChoiceIndefinite(suite) -> [];
+testChoiceIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testChoiceIndefinite:compile(Config,?BER,[]),
+ ?line testChoiceIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testChoiceIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoiceIndefinite:main(?BER)).
+
+testInfObjectClass(suite) ->
+ [];
+testInfObjectClass(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testInfObjectClass:compile(Config,?PER,[]),
+ ?line testInfObjectClass:main(?PER),
+ ?line testInfObj:compile(Config,?PER,[]),
+ ?line testInfObj:main(?PER),
+
+ ?line ?per_bit_opt(testInfObjectClass:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testInfObjectClass:main(?PER)),
+ ?line ?per_bit_opt(testInfObj:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testInfObj:main(?PER)),
+
+ ?line ?uper_bin(testInfObjectClass:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testInfObjectClass:main(uper_bin)),
+ ?line ?uper_bin(testInfObj:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testInfObj:main(uper_bin)),
+
+ ?line testInfObjectClass:compile(Config,?PER,[optimize]),
+ ?line testInfObjectClass:main(?PER),
+ ?line testInfObj:compile(Config,?PER,[optimize]),
+ ?line testInfObj:main(?PER),
+
+ ?line testInfObjectClass:compile(Config,?BER,[]),
+ ?line testInfObjectClass:main(?BER),
+ ?line testInfObj:compile(Config,?BER,[]),
+ ?line testInfObj:main(?BER),
+
+ ?line ?ber_driver(?BER,testInfObjectClass:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testInfObjectClass:main(?BER)),
+ ?line ?ber_driver(?BER,testInfObj:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testInfObj:main(?BER)),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?PER,[]),
+
+ ?line ?per_bit_opt(testInfObj:compile_RANAPfiles(Config,?PER,[optimize])),
+
+ ?line ?uper_bin(testInfObj:compile_RANAPfiles(Config,uper_bin,[])),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?PER,[optimize]),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?BER,[]).
+
+testParameterizedInfObj(suite) ->
+ [];
+testParameterizedInfObj(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testParameterizedInfObj:compile(Config,?PER,[]),
+ ?line testParameterizedInfObj:main(?PER),
+
+ ?line ?per_bit_opt(testParameterizedInfObj:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testParameterizedInfObj:main(?PER)),
+
+ ?line ?uper_bin(testParameterizedInfObj:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testParameterizedInfObj:main(uper_bin)),
+
+ ?line testParameterizedInfObj:compile(Config,?PER,[optimize]),
+ ?line testParameterizedInfObj:main(?PER),
+
+ ?line testParameterizedInfObj:compile(Config,?BER,[]),
+ ?line testParameterizedInfObj:main(?BER),
+
+ ?line ?ber_driver(?BER,testParameterizedInfObj:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testParameterizedInfObj:main(?BER)).
+
+testMergeCompile(suite) ->
+ [];
+testMergeCompile(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testMergeCompile:compile(Config,?PER,[]),
+ ?line testMergeCompile:main(?PER),
+ ?line testMergeCompile:mvrasn(?PER),
+
+ ?line ?per_bit_opt(testMergeCompile:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testMergeCompile:main(?PER)),
+ ?line ?per_bit_opt(testMergeCompile:mvrasn(?PER)),
+
+ ?line ?uper_bin(testMergeCompile:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testMergeCompile:main(uper_bin)),
+ ?line ?uper_bin(testMergeCompile:mvrasn(uper_bin)),
+
+ ?line testMergeCompile:compile(Config,?BER,[]),
+ ?line testMergeCompile:main(?BER),
+ ?line testMergeCompile:mvrasn(?BER),
+
+ ?line ?ber_driver(?BER,testMergeCompile:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testMergeCompile:main(?BER)),
+ ?line ?ber_driver(?BER,testMergeCompile:mvrasn(?BER)).
+
+testobj(suite) ->
+ [];
+testobj(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = testRANAP:compile(Config,?PER,[]),
+ ?line ok = testRANAP:testobj(?PER),
+ ?line ok = testParameterizedInfObj:ranap(?PER),
+
+ ?line ?per_bit_opt(ok = testRANAP:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(ok = testRANAP:testobj(?PER)),
+ ?line ?per_bit_opt(ok = testParameterizedInfObj:ranap(?PER)),
+
+ ?line ?uper_bin(ok = testRANAP:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(ok = testRANAP:testobj(uper_bin)),
+ ?line ?uper_bin(ok = testParameterizedInfObj:ranap(uper_bin)),
+
+ ?line ok = testRANAP:compile(Config,?PER,[optimize]),
+ ?line ok = testRANAP:testobj(?PER),
+ ?line ok = testParameterizedInfObj:ranap(?PER),
+
+ ?line ok = testRANAP:compile(Config,?BER,[]),
+ ?line ok = testRANAP:testobj(?BER),
+ ?line ok = testParameterizedInfObj:ranap(?BER),
+
+ ?line ?ber_driver(?BER,testRANAP:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testRANAP:testobj(?BER)),
+ ?line ?ber_driver(?BER,testParameterizedInfObj:ranap(?BER)).
+
+
+testDeepTConstr(suite) ->
+ [];
+testDeepTConstr(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testDeepTConstr:compile(Config,?PER,[]),
+ ?line testDeepTConstr:main(?PER),
+
+ ?line ?per_bit_opt(testDeepTConstr:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDeepTConstr:main(?PER)),
+
+ ?line ?uper_bin(testDeepTConstr:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDeepTConstr:main(uper_bin)),
+
+ ?line testDeepTConstr:compile(Config,?PER,[optimize]),
+ ?line testDeepTConstr:main(?PER),
+
+ ?line testDeepTConstr:compile(Config,?BER,[]),
+ ?line testDeepTConstr:main(?BER),
+
+ ?line ?ber_driver(?BER,testDeepTConstr:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDeepTConstr:main(?BER)).
+
+testInvokeMod(suite) ->
+ [];
+testInvokeMod(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[{outdir,OutDir}]),
+ ?line {ok,_Result1} = 'PrimStrings':encode('Bs1',[1,0,1,0]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[?PER,{outdir,OutDir}]),
+ ?line {ok,_Result2} = 'PrimStrings':encode('Bs1',[1,0,1,0]).
+
+testExport(suite) ->
+ [];
+testExport(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line {error,{asn1,_Reason}} = asn1ct:compile(filename:join(DataDir,"IllegalExport"),[{outdir,OutDir}]).
+
+testImport(suite) ->
+ [];
+testImport(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line _OutDir = ?config(priv_dir,Config),
+ ?line {error,_} = asn1ct:compile(filename:join(DataDir,"ImportsFrom"),[?BER]),
+ ok.
+
+testMegaco(suite) ->
+ [];
+testMegaco(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ io:format("Config: ~p~n",[Config]),
+ ?line {ok,ModuleName1,ModuleName2} = testMegaco:compile(Config,?BER,[]),
+ ?line ok = testMegaco:main(ModuleName1,Config),
+ ?line ok = testMegaco:main(ModuleName2,Config),
+
+ case ?BER of
+ ber_bin_v2 ->
+ ?line {ok,ModuleName3,ModuleName4} = testMegaco:compile(Config,?BER,[driver]),
+ ?line ok = testMegaco:main(ModuleName3,Config),
+ ?line ok = testMegaco:main(ModuleName4,Config);
+ _-> ok
+ end,
+
+ ?line {ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[]),
+ ?line ok = testMegaco:main(ModuleName5,Config),
+ ?line ok = testMegaco:main(ModuleName6,Config),
+
+ ?line ?per_bit_opt({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(ok = testMegaco:main(ModuleName5,Config)),
+ ?line ?per_bit_opt(ok = testMegaco:main(ModuleName6,Config)),
+
+ ?line ?uper_bin({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(ok = testMegaco:main(ModuleName5,Config)),
+ ?line ?uper_bin(ok = testMegaco:main(ModuleName6,Config)),
+
+ ?line {ok,ModuleName7,ModuleName8} = testMegaco:compile(Config,?PER,[optimize]),
+ ?line ok = testMegaco:main(ModuleName7,Config),
+ ?line ok = testMegaco:main(ModuleName8,Config).
+
+
+testMvrasn6(suite) -> [];
+testMvrasn6(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testMvrasn6:compile(Config,?BER),
+ ?line testMvrasn6:main().
+
+testContextSwitchingTypes(suite) -> [];
+testContextSwitchingTypes(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testContextSwitchingTypes:compile(Config,?BER,[]),
+ ?line testContextSwitchingTypes:test(),
+
+ ?line ?ber_driver(?BER,testContextSwitchingTypes:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testContextSwitchingTypes:test()),
+
+ ?line testContextSwitchingTypes:compile(Config,?PER,[]),
+ ?line testContextSwitchingTypes:test(),
+
+ ?line ?per_bit_opt(testContextSwitchingTypes:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testContextSwitchingTypes:test()),
+
+ ?line ?uper_bin(testContextSwitchingTypes:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testContextSwitchingTypes:test()),
+
+ ?line testContextSwitchingTypes:compile(Config,?PER,[optimize]),
+ ?line testContextSwitchingTypes:test().
+
+testTypeValueNotation(suite) -> [];
+testTypeValueNotation(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ case ?BER of
+ Ber when Ber == ber; Ber == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?BER,[]),
+ ?line testTypeValueNotation:main(?BER,dummy);
+ _ ->
+ ok
+ end,
+
+ ?line ?ber_driver(?BER,testTypeValueNotation:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testTypeValueNotation:main(?BER,optimize)),
+
+ case ?BER of
+ Ber2 when Ber2 == ber; Ber2 == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?PER,[]),
+ ?line testTypeValueNotation:main(?PER,dummy);
+ _ ->
+ ok
+ end,
+
+ ?line ?per_bit_opt(testTypeValueNotation:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testTypeValueNotation:main(?PER,optimize)),
+
+ ?line ?uper_bin(testTypeValueNotation:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testTypeValueNotation:main(uper_bin,optimize)),
+ case ?BER of
+ Ber3 when Ber3 == ber; Ber3 == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?PER,[optimize]),
+ ?line testTypeValueNotation:main(?PER,optimize);
+ _ ->
+ ok
+ end.
+
+testOpenTypeImplicitTag(suite) -> [];
+testOpenTypeImplicitTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?BER,[]),
+ ?line testOpenTypeImplicitTag:main(?BER),
+
+ ?line ?ber_driver(?BER,testOpenTypeImplicitTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testOpenTypeImplicitTag:main(?BER)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?PER,[]),
+ ?line testOpenTypeImplicitTag:main(?PER),
+
+ ?line ?per_bit_opt(testOpenTypeImplicitTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testOpenTypeImplicitTag:main(?PER)),
+
+ ?line ?uper_bin(testOpenTypeImplicitTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testOpenTypeImplicitTag:main(uper_bin)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?PER,[optimize]),
+ ?line testOpenTypeImplicitTag:main(?PER).
+
+duplicate_tags(suite) -> [];
+duplicate_tags(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ {error,{asn1,[{error,{type,_,_,'SeqOpt1Imp',{asn1,{duplicates_of_the_tags,_}}}}]}} =
+ asn1ct:compile(filename:join(DataDir,"SeqOptional2"),[abs]),
+ ok.
+
+rtUI(suite) -> [];
+rtUI(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?BER]),
+ ?line {ok,_} = asn1rt:info('Prim'),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?PER]),
+ ?line {ok,_} = asn1rt:info('Prim'),
+
+ ?line ok = asn1rt:load_driver(),
+ ?line ok = asn1rt:load_driver(),
+ ?line ok = asn1rt:unload_driver().
+
+testROSE(suite) -> [];
+testROSE(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testROSE:compile(Config,?BER,[]),
+
+ ?line testROSE:compile(Config,?PER,[]),
+ ?line ?per_bit_opt(testROSE:compile(Config,?PER,[optimize])),
+ ?line ?uper_bin(testROSE:compile(Config,uper_bin,[])),
+ ?line testROSE:compile(Config,?PER,[optimize]).
+
+testINSTANCE_OF(suite) -> [];
+testINSTANCE_OF(Config) ->
+ ?line testINSTANCE_OF:compile(Config,?BER,[]),
+ ?line testINSTANCE_OF:main(?BER),
+
+ ?line ?ber_driver(?BER,testINSTANCE_OF:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testINSTANCE_OF:main(?BER)),
+
+ ?line testINSTANCE_OF:compile(Config,?PER,[]),
+ ?line testINSTANCE_OF:main(?PER),
+
+ ?line ?per_bit_opt(testINSTANCE_OF:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testINSTANCE_OF:main(?PER)),
+
+ ?line ?uper_bin(testINSTANCE_OF:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testINSTANCE_OF:main(uper_bin)),
+
+ ?line testINSTANCE_OF:compile(Config,?PER,[optimize]),
+ ?line testINSTANCE_OF:main(?PER).
+
+testTCAP(suite) -> [];
+testTCAP(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testTCAP:compile(Config,?BER,[]),
+ ?line testTCAP:test(?BER,Config),
+
+ ?line ?ber_driver(?BER,testTCAP:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testTCAP:test(?BER,Config)),
+
+ ?line ?ber_driver(?BER,testTCAP:compile_asn1config(Config,?BER,[asn1config])),
+ ?line ?ber_driver(?BER,testTCAP:test_asn1config()).
+
+testDER(suite) ->[];
+testDER(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testDER:compile(Config,?BER,[]),
+ ?line testDER:test(),
+
+ ?line ?ber_driver(?BER,testDER:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDER:test()),
+
+ ?line testParamBasic:compile_der(Config,?BER),
+ ?line testParamBasic_cases(der),
+
+
+ ?line testSeqSetDefaultVal:compile(Config,?BER),
+ ?line testSeqSetDefaultVal_cases(?BER).
+
+testSeqSetDefaultVal_cases(?BER) ->
+ ?line testSeqSetDefaultVal:main(?BER).
+
+
+specialized_decodes(suite) -> [];
+specialized_decodes(Config) ->
+ ?line test_partial_incomplete_decode:compile(Config,?BER,[optimize]),
+ ?line test_partial_incomplete_decode:test(?BER,Config),
+ ?line test_selective_decode:test(?BER,Config).
+
+special_decode_performance(suite) ->[];
+special_decode_performance(Config) ->
+ ?line ?ber_driver(?BER,test_special_decode_performance:compile(Config,?BER)),
+ ?line ?ber_driver(?BER,test_special_decode_performance:go(all)).
+
+
+test_driver_load(suite) -> [];
+test_driver_load(Config) ->
+ ?line test_driver_load:compile(Config,?PER),
+ ?line test_driver_load:test(?PER,5).
+
+test_ParamTypeInfObj(suite) -> [];
+test_ParamTypeInfObj(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"IN-CS-1-Datatypes"),[ber_bin]).
+
+test_WS_ParamClass(suite) -> [];
+test_WS_ParamClass(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"InformationFramework"),
+ [ber_bin]).
+
+test_Defed_ObjectIdentifier(suite) -> [];
+test_Defed_ObjectIdentifier(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"UsefulDefinitions"),
+ [ber_bin]).
+
+testSelectionType(suite) -> [];
+testSelectionType(Config) ->
+
+ ?line ok = testSelectionTypes:compile(Config,?BER,[]),
+ ?line {ok,_} = testSelectionTypes:test(),
+
+ ?line ok = testSelectionTypes:compile(Config,?PER,[]),
+ ?line {ok,_} = testSelectionTypes:test().
+
+testSSLspecs(suite) -> [];
+testSSLspecs(Config) ->
+
+ ?line ok = testSSLspecs:compile(Config,?BER,
+ [optimize,compact_bit_string,der]),
+ ?line testSSLspecs:run(?BER),
+
+ case code:which(asn1ct) of
+ cover_compiled ->
+ ok;
+ _ ->
+ ?line ok = testSSLspecs:compile_inline(Config,?BER),
+ ?line ok = testSSLspecs:run_inline(?BER)
+ end.
+
+testNortel(suite) -> [];
+testNortel(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?BER]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?BER,optimize]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?BER,optimize,driver]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?PER]),
+ ?line ?per_bit_opt(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?PER,optimize])),
+ ?line ?uper_bin(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[uper_bin])),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?PER,optimize]).
+test_undecoded_rest(suite) -> [];
+test_undecoded_rest(Config) ->
+
+ ?line ok = test_undecoded_rest:compile(Config,?BER,[]),
+ ?line ok = test_undecoded_rest:test([]),
+
+ ?line ok = test_undecoded_rest:compile(Config,?BER,[undec_rest]),
+ ?line ok = test_undecoded_rest:test(undec_rest),
+
+ ?line ok = test_undecoded_rest:compile(Config,?PER,[]),
+ ?line ok = test_undecoded_rest:test([]),
+
+ ?line ?per_bit_opt(ok = test_undecoded_rest:compile(Config,?PER,[optimize,undec_rest])),
+ ?line ?per_bit_opt(ok = test_undecoded_rest:test(undec_rest)),
+
+ ?line ?uper_bin(ok = test_undecoded_rest:compile(Config,uper_bin,[undec_rest])),
+ ?line ?uper_bin(ok = test_undecoded_rest:test(undec_rest)),
+
+ ?line ok = test_undecoded_rest:compile(Config,?PER,[undec_rest]),
+ ?line ok = test_undecoded_rest:test(undec_rest).
+
+test_inline(suite) -> [];
+test_inline(Config) ->
+ case code:which(asn1ct) of
+ cover_compiled ->
+ {skip,"Not runnable when cover compiled"};
+ _ ->
+ ?line ok=test_inline:compile(Config,?BER,[]),
+ ?line test_inline:main(?BER),
+ ?line test_inline:inline1(Config,?BER,[]),
+ ?line test_inline:performance2()
+ end.
+
+%test_inline_prf(suite) -> [];
+%test_inline_prf(Config) ->
+% ?line test_inline:performance(Config).
+
+testTcapsystem(suite) -> [];
+testTcapsystem(Config) ->
+ ?line ok=testTcapsystem:compile(Config,?BER,[]).
+
+testNBAPsystem(suite) -> [];
+testNBAPsystem(Config) ->
+ ?line ok=testNBAPsystem:compile(Config,?PER,?per_optimize(?BER)),
+ ?line ok=testNBAPsystem:test(?PER,Config).
+
+test_compile_options(suite) -> [];
+test_compile_options(Config) ->
+ case code:which(asn1ct) of
+ cover_compiled ->
+ {skip,"Not runnable when cover compiled"};
+ _ ->
+ ?line ok = test_compile_options:wrong_path(Config),
+ ?line ok = test_compile_options:path(Config),
+ ?line ok = test_compile_options:noobj(Config),
+ ?line ok = test_compile_options:record_name_prefix(Config),
+ ?line ok = test_compile_options:verbose(Config)
+ end.
+testDoubleEllipses(suite) -> [];
+testDoubleEllipses(Config) ->
+ ?line testDoubleEllipses:compile(Config,?BER,[]),
+ ?line testDoubleEllipses:main(?BER),
+ ?line ?ber_driver(?BER,testDoubleEllipses:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDoubleEllipses:main(?BER)),
+ ?line ?per_bit_opt(testDoubleEllipses:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDoubleEllipses:main(?PER)),
+ ?line ?uper_bin(testDoubleEllipses:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDoubleEllipses:main(uper_bin)),
+ ?line testDoubleEllipses:compile(Config,?PER,?per_optimize(?BER)),
+ ?line testDoubleEllipses:main(?PER).
+
+test_modified_x420(suite) -> [];
+test_modified_x420(Config) ->
+ ?line test_modified_x420:compile(Config),
+ ?line test_modified_x420:test_io(Config).
+
+testX420(suite) -> [];
+testX420(Config) ->
+ ?line testX420:compile(?BER,[der],Config),
+ ?line ok = testX420:ticket7759(?BER,Config),
+ ?line testX420:compile(?PER,[],Config).
+
+test_x691(suite) -> [];
+test_x691(Config) ->
+ case ?PER of
+ per ->
+ ?line ok = test_x691:compile(Config,uper_bin,[]),
+ ?line true = test_x691:cases(uper_bin,unaligned),
+ ?line ok = test_x691:compile(Config,?PER,[]),
+ ?line true = test_x691:cases(?PER,aligned),
+%% ?line ok = asn1_test_lib:ticket_7678(Config,[]),
+ ?line ok = asn1_test_lib:ticket_7708(Config,[]),
+ ?line ok = asn1_test_lib:ticket_7763(Config);
+ _ ->
+ ?line ok = test_x691:compile(Config,?PER,?per_optimize(?BER)),
+ ?line true = test_x691:cases(?PER,aligned)
+ end.
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[compact_bit_string]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize,compact_bit_string]).
+
+
+ticket_6143(suite) -> [];
+ticket_6143(Config) ->
+ ?line ok = test_compile_options:ticket_6143(Config).
+
+testExtensionAdditionGroup(suite) -> [];
+testExtensionAdditionGroup(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line PrivDir = ?config(priv_dir,Config),
+ ?line Path = code:get_path(),
+ ?line code:add_patha(PrivDir),
+ DoIt = fun(Erule) ->
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),[Erule,{outdir,PrivDir}]),
+ ?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]),
+ ?line ok = extensionAdditionGroup:run(Erule)
+ end,
+ ?line [DoIt(Rule)|| Rule <- [per_bin,uper_bin,ber_bin]],
+ ?line code:set_path(Path).
+
+
+
+% parse_modules() ->
+% ["ImportsFrom"].
+
+per_modules() ->
+ [X || X <- test_modules()].
+ber_modules() ->
+ [X || X <- test_modules(),
+ X =/= "CommonDataTypes",
+ X =/= "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
+ X =/= "H323-MESSAGES",
+ X =/= "H235-SECURITY-MESSAGES",
+ X =/= "MULTIMEDIA-SYSTEM-CONTROL"].
+test_modules() ->
+ _Modules = [
+ "BitStr",
+ "CommonDataTypes",
+ "Constraints",
+ "ContextSwitchingTypes",
+ "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
+ "Enum",
+ "From",
+ "H235-SECURITY-MESSAGES",
+ "H323-MESSAGES",
+ %%"MULTIMEDIA-SYSTEM-CONTROL", recursive type , problem for asn1ct:value
+ "Import",
+ "Int",
+ "MAP-commonDataTypes",
+% ambigous tags "MAP-insertSubscriberData-def",
+ "Null",
+ "Octetstr",
+ "One",
+ "P-Record",
+ "P",
+% "PDUs",
+ "Person",
+ "PrimStrings",
+ "Real",
+ "XSeq",
+ "XSeqOf",
+ "XSet",
+ "XSetOf",
+ "String",
+ "SwCDR",
+% "Syntax",
+ "Time"
+% ANY "Tst",
+% "Two",
+% errors that should be detected "UndefType"
+] ++
+ [
+ "SeqSetLib", % must be compiled before Seq and Set
+ "Seq",
+ "Set",
+ "SetOf",
+ "SeqOf",
+ "Prim",
+ "Cho",
+ "Def",
+ "Opt",
+ "ELDAPv3",
+ "LDAP"
+ ].
+
+
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+common() ->
+[{group, app_test}, {group, appup_test}, testTimer_ber,
+ testTimer_ber_bin, testTimer_ber_bin_opt,
+ testTimer_ber_bin_opt_driver, testTimer_per,
+ testTimer_per_bin, testTimer_per_bin_opt,
+ testTimer_uper_bin, testComment, testName2Number].
+
+
+
+testTimer_ber(suite) -> [];
+testTimer_ber(Config) ->
+ ?line testTimer:compile(Config,ber,[]),
+ ?line testTimer:go(Config,ber).
+
+testTimer_ber_bin(suite) -> [];
+testTimer_ber_bin(Config) ->
+ ?line testTimer:compile(Config,ber_bin,[]),
+ ?line testTimer:go(Config,ber_bin).
+
+testTimer_ber_bin_opt(suite) -> [];
+testTimer_ber_bin_opt(Config) ->
+ ?line testTimer:compile(Config,ber_bin,[optimize]),
+ ?line testTimer:go(Config,ber_bin).
+
+testTimer_ber_bin_opt_driver(suite) -> [];
+testTimer_ber_bin_opt_driver(Config) ->
+ ?line testTimer:compile(Config,ber_bin,[optimize,driver]),
+ ?line testTimer:go(Config,ber_bin).
+
+testTimer_per(suite) -> [];
+testTimer_per(Config) ->
+ ?line testTimer:compile(Config,per,[]),
+ ?line testTimer:go(Config,per).
+
+testTimer_per_bin(suite) -> [];
+testTimer_per_bin(Config) ->
+ ?line testTimer:compile(Config,per_bin,[]),
+ ?line testTimer:go(Config,per_bin).
+
+testTimer_per_bin_opt(suite) -> [];
+testTimer_per_bin_opt(Config) ->
+ ?line testTimer:compile(Config,per_bin,[optimize]),
+ ?line testTimer:go(Config,per_bin).
+
+
+testTimer_uper_bin(suite) -> [];
+testTimer_uper_bin(Config) ->
+ ?line ok=testTimer:compile(Config,uper_bin,[]),
+ ?line {comment,_} = testTimer:go(Config,uper_bin).
+
+%% Test of multiple-line comment, OTP-8043
+testComment(suite) -> [];
+testComment(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ?line ok = asn1ct:compile(DataDir ++ "Comment",[{outdir,OutDir}]),
+
+ ?line {ok,Enc} = asn1_wrapper:encode('Comment','Seq',{'Seq',12,true}),
+ ?line {ok,{'Seq',12,true}} = asn1_wrapper:decode('Comment','Seq',Enc),
+ ok.
+
+testName2Number(suite) -> [];
+testName2Number(Config) ->
+ DataDir = ?config(data_dir,Config),
+ OutDir = ?config(priv_dir,Config),
+ N2NOptions = [{n2n,Type}|| Type <-
+ ['CauseMisc','CauseProtocol',
+ %% 'CauseNetwork',
+ 'CauseRadioNetwork',
+ 'CauseTransport','CauseNas']],
+ ?line ok = asn1ct:compile(DataDir ++ "S1AP-IEs",[{outdir,OutDir}]++N2NOptions),
+ ?line true = code:add_patha(OutDir),
+
+ ?line 0 = 'S1AP-IEs':name2num_CauseMisc('control-processing-overload'),
+ ?line 'unknown-PLMN' = 'S1AP-IEs':num2name_CauseMisc(5),
+ ok.
+
+
+particular() ->
+ [ticket_7407].
+
+ticket_7407(suite) -> [];
+ticket_7407(Config) ->
+ ?line ok = asn1_test_lib:ticket_7407_compile(Config,[]),
+ ?line ok = asn1_test_lib:ticket_7407_code(true),
+
+ ?line ok = asn1_test_lib:ticket_7407_compile(Config,[no_final_padding]),
+ ?line ok = asn1_test_lib:ticket_7407_code(false).
diff --git a/lib/asn1/test/asn1_SUITE.erl.src b/lib/asn1/test/asn1_SUITE.erl.src
index fad094c988..e1a09adc82 100644
--- a/lib/asn1/test/asn1_SUITE.erl.src
+++ b/lib/asn1/test/asn1_SUITE.erl.src
@@ -2302,9 +2302,12 @@ testExtensionAdditionGroup(Config) ->
?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),Erule ++ [{outdir,PrivDir}]),
?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]),
?line ok = extensionAdditionGroup:run(Erule),
- ?line ok = extensionAdditionGroup:run2(Erule)
+ ?line ok = extensionAdditionGroup:run2(Erule),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"EUTRA-RRC-Definitions"),Erule ++ [{record_name_prefix,"RRC-"},{outdir,PrivDir}]),
+ ?line ok = extensionAdditionGroup:run3(Erule)
end,
- ?line [DoIt(Rule)|| Rule <- [[per_bin],[per_bin,optimize],[uper_bin],[ber_bin],[ber_bin,optimize]]],
+ ?line [DoIt(Rule)|| Rule <- [[per_bin],[per_bin,optimize],[uper_bin]]],
+ %% FIXME problems with automatic tags [ber_bin],[ber_bin,optimize]
?line code:set_path(Path).
diff --git a/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn b/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn
index a451874ef0..3b811dafe6 100644
--- a/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn
+++ b/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn
@@ -1,2640 +1,3155 @@
--- 3GPP TS 36.331 V8.8.0 (2009-12)
--- $Id$
---
-EUTRA-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::=
-
-BEGIN
-
-
-BCCH-BCH-Message ::= SEQUENCE {
- message BCCH-BCH-MessageType
-}
-
-BCCH-BCH-MessageType ::= MasterInformationBlock
-
-
-BCCH-DL-SCH-Message ::= SEQUENCE {
- message BCCH-DL-SCH-MessageType
-}
-
-BCCH-DL-SCH-MessageType ::= CHOICE {
- c1 CHOICE {
- systemInformation SystemInformation,
- systemInformationBlockType1 SystemInformationBlockType1
- },
- messageClassExtension SEQUENCE {}
-}
-
-
-PCCH-Message ::= SEQUENCE {
- message PCCH-MessageType
-}
-
-PCCH-MessageType ::= CHOICE {
- c1 CHOICE {
- paging Paging
- },
- messageClassExtension SEQUENCE {}
-}
-
-
-DL-CCCH-Message ::= SEQUENCE {
- message DL-CCCH-MessageType
-}
-
-DL-CCCH-MessageType ::= CHOICE {
- c1 CHOICE {
- rrcConnectionReestablishment RRCConnectionReestablishment,
- rrcConnectionReestablishmentReject RRCConnectionReestablishmentReject,
- rrcConnectionReject RRCConnectionReject,
- rrcConnectionSetup RRCConnectionSetup
- },
- messageClassExtension SEQUENCE {}
-}
-
-
-DL-DCCH-Message ::= SEQUENCE {
- message DL-DCCH-MessageType
-}
-
-DL-DCCH-MessageType ::= CHOICE {
- c1 CHOICE {
- csfbParametersResponseCDMA2000 CSFBParametersResponseCDMA2000,
- dlInformationTransfer DLInformationTransfer,
- handoverFromEUTRAPreparationRequest HandoverFromEUTRAPreparationRequest,
- mobilityFromEUTRACommand MobilityFromEUTRACommand,
- rrcConnectionReconfiguration RRCConnectionReconfiguration,
- rrcConnectionRelease RRCConnectionRelease,
- securityModeCommand SecurityModeCommand,
- ueCapabilityEnquiry UECapabilityEnquiry,
- counterCheck CounterCheck,
- spare7 NULL,
- spare6 NULL, spare5 NULL, spare4 NULL,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- messageClassExtension SEQUENCE {}
-}
-
-
-UL-CCCH-Message ::= SEQUENCE {
- message UL-CCCH-MessageType
-}
-
-UL-CCCH-MessageType ::= CHOICE {
- c1 CHOICE {
- rrcConnectionReestablishmentRequest RRCConnectionReestablishmentRequest,
- rrcConnectionRequest RRCConnectionRequest
- },
- messageClassExtension SEQUENCE {}
-}
-
-
-UL-DCCH-Message ::= SEQUENCE {
- message UL-DCCH-MessageType
-}
-
-UL-DCCH-MessageType ::= CHOICE {
- c1 CHOICE {
- csfbParametersRequestCDMA2000 CSFBParametersRequestCDMA2000,
- measurementReport MeasurementReport,
- rrcConnectionReconfigurationComplete RRCConnectionReconfigurationComplete,
- rrcConnectionReestablishmentComplete RRCConnectionReestablishmentComplete,
- rrcConnectionSetupComplete RRCConnectionSetupComplete,
- securityModeComplete SecurityModeComplete,
- securityModeFailure SecurityModeFailure,
- ueCapabilityInformation UECapabilityInformation,
- ulHandoverPreparationTransfer ULHandoverPreparationTransfer,
- ulInformationTransfer ULInformationTransfer,
- counterCheckResponse CounterCheckResponse,
- spare5 NULL, spare4 NULL,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- messageClassExtension SEQUENCE {}
-}
-
-
-CounterCheck ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE {
- counterCheck-r8 CounterCheck-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-CounterCheck-r8-IEs ::= SEQUENCE {
- drb-CountMSB-InfoList DRB-CountMSB-InfoList,
- nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
-}
-
-DRB-CountMSB-InfoList::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-CountMSB-Info
-
-DRB-CountMSB-Info ::= SEQUENCE {
- drb-Identity DRB-Identity,
- countMSB-Uplink INTEGER(0..33554431),
- countMSB-Downlink INTEGER(0..33554431)
-}
-
-
-CounterCheckResponse ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- counterCheckResponse-r8 CounterCheckResponse-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-CounterCheckResponse-r8-IEs ::= SEQUENCE {
- drb-CountInfoList DRB-CountInfoList,
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-DRB-CountInfoList ::= SEQUENCE (SIZE (0..maxDRB)) OF DRB-CountInfo
-
-DRB-CountInfo ::= SEQUENCE {
- drb-Identity DRB-Identity,
- count-Uplink INTEGER(0..4294967295),
- count-Downlink INTEGER(0..4294967295)
-}
-
-
-CSFBParametersRequestCDMA2000 ::= SEQUENCE {
- criticalExtensions CHOICE {
- csfbParametersRequestCDMA2000-r8 CSFBParametersRequestCDMA2000-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-CSFBParametersRequestCDMA2000-r8-IEs ::= SEQUENCE {
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-CSFBParametersResponseCDMA2000 ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- csfbParametersResponseCDMA2000-r8 CSFBParametersResponseCDMA2000-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-CSFBParametersResponseCDMA2000-r8-IEs ::= SEQUENCE {
- rand RAND-CDMA2000,
- mobilityParameters MobilityParametersCDMA2000,
- nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
-}
-
-
-DLInformationTransfer ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE {
- dlInformationTransfer-r8 DLInformationTransfer-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-DLInformationTransfer-r8-IEs ::= SEQUENCE {
- dedicatedInfoType CHOICE {
- dedicatedInfoNAS DedicatedInfoNAS,
- dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000,
- dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000
- },
- nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
-}
-
-
-HandoverFromEUTRAPreparationRequest ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE {
- handoverFromEUTRAPreparationRequest-r8
- HandoverFromEUTRAPreparationRequest-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-HandoverFromEUTRAPreparationRequest-r8-IEs ::= SEQUENCE {
- cdma2000-Type CDMA2000-Type,
- rand RAND-CDMA2000 OPTIONAL, -- Cond cdma2000-Type
- mobilityParameters MobilityParametersCDMA2000 OPTIONAL, -- Cond cdma2000-Type
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-
-MasterInformationBlock ::= SEQUENCE {
- dl-Bandwidth ENUMERATED {
- n6, n15, n25, n50, n75, n100},
- phich-Config PHICH-Config,
- systemFrameNumber BIT STRING (SIZE (8)),
- spare BIT STRING (SIZE (10))
-}
-
-
-
-MeasurementReport ::= SEQUENCE {
- criticalExtensions CHOICE {
- c1 CHOICE{
- measurementReport-r8 MeasurementReport-r8-IEs,
- spare7 NULL,
- spare6 NULL, spare5 NULL, spare4 NULL,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-MeasurementReport-r8-IEs ::= SEQUENCE {
- measResults MeasResults,
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-
-MobilityFromEUTRACommand ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE{
- mobilityFromEUTRACommand-r8 MobilityFromEUTRACommand-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-MobilityFromEUTRACommand-r8-IEs ::= SEQUENCE {
- cs-FallbackIndicator BOOLEAN,
- purpose CHOICE{
- handover Handover,
- cellChangeOrder CellChangeOrder
- },
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-Handover ::= SEQUENCE {
- targetRAT-Type ENUMERATED {
- utra, geran, cdma2000-1XRTT, cdma2000-HRPD,
- spare4, spare3, spare2, spare1, ...},
- targetRAT-MessageContainer OCTET STRING,
- nas-SecurityParamFromEUTRA OCTET STRING (SIZE (1)) OPTIONAL, -- Cond UTRAGERAN
- systemInformation SI-OrPSI-GERAN OPTIONAL -- Cond PSHO
-}
-
-CellChangeOrder ::= SEQUENCE {
- t304 ENUMERATED {
- ms100, ms200, ms500, ms1000,
- ms2000, ms4000, ms8000, spare1},
- targetRAT-Type CHOICE {
- geran SEQUENCE {
- physCellId PhysCellIdGERAN,
- carrierFreq CarrierFreqGERAN,
- networkControlOrder BIT STRING (SIZE (2)) OPTIONAL, -- Need OP
- systemInformation SI-OrPSI-GERAN OPTIONAL -- Need OP
- },
- ...
- }
-}
-
-SI-OrPSI-GERAN ::= CHOICE {
- si SystemInfoListGERAN,
- psi SystemInfoListGERAN
-}
-
-SystemInfoListGERAN ::= SEQUENCE (SIZE (1..maxGERAN-SI)) OF
- OCTET STRING (SIZE (1..23))
-
-
-Paging ::= SEQUENCE {
- pagingRecordList PagingRecordList OPTIONAL, -- Need ON
- systemInfoModification ENUMERATED {true} OPTIONAL, -- Need ON
- etws-Indication ENUMERATED {true} OPTIONAL, -- Need ON
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-PagingRecordList ::= SEQUENCE (SIZE (1..maxPageRec)) OF PagingRecord
-
-PagingRecord ::= SEQUENCE {
- ue-Identity PagingUE-Identity,
- cn-Domain ENUMERATED {ps, cs},
- ...
-}
-
-PagingUE-Identity ::= CHOICE {
- s-TMSI S-TMSI,
- imsi IMSI,
- ...
-}
-
-IMSI ::= SEQUENCE (SIZE (6..21)) OF IMSI-Digit
-
-IMSI-Digit::= INTEGER (0..9)
-
-
-RRCConnectionReconfiguration ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE{
- rrcConnectionReconfiguration-r8 RRCConnectionReconfiguration-r8-IEs,
- spare7 NULL,
- spare6 NULL, spare5 NULL, spare4 NULL,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionReconfiguration-r8-IEs ::= SEQUENCE {
- measConfig MeasConfig OPTIONAL, -- Need ON
- mobilityControlInfo MobilityControlInfo OPTIONAL, -- Cond HO
- dedicatedInfoNASList SEQUENCE (SIZE(1..maxDRB)) OF
- DedicatedInfoNAS OPTIONAL, -- Cond nonHO
- radioResourceConfigDedicated RadioResourceConfigDedicated OPTIONAL, -- Cond HO-toEUTRA
- securityConfigHO SecurityConfigHO OPTIONAL, -- Cond HO
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-SecurityConfigHO ::= SEQUENCE {
- handoverType CHOICE {
- intraLTE SEQUENCE {
- securityAlgorithmConfig SecurityAlgorithmConfig OPTIONAL, -- Need OP
- keyChangeIndicator BOOLEAN,
- nextHopChainingCount NextHopChainingCount
- },
- interRAT SEQUENCE {
- securityAlgorithmConfig SecurityAlgorithmConfig,
- nas-SecurityParamToEUTRA OCTET STRING (SIZE(6))
- }
- },
- ...
-}
-
-
-RRCConnectionReconfigurationComplete ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- rrcConnectionReconfigurationComplete-r8
- RRCConnectionReconfigurationComplete-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionReconfigurationComplete-r8-IEs ::= SEQUENCE {
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-
-RRCConnectionReestablishment ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE{
- rrcConnectionReestablishment-r8 RRCConnectionReestablishment-r8-IEs,
- spare7 NULL,
- spare6 NULL, spare5 NULL, spare4 NULL,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionReestablishment-r8-IEs ::= SEQUENCE {
- radioResourceConfigDedicated RadioResourceConfigDedicated,
- nextHopChainingCount NextHopChainingCount,
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-
-RRCConnectionReestablishmentComplete ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- rrcConnectionReestablishmentComplete-r8
- RRCConnectionReestablishmentComplete-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionReestablishmentComplete-r8-IEs ::= SEQUENCE {
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-
-RRCConnectionReestablishmentReject ::= SEQUENCE {
- criticalExtensions CHOICE {
- rrcConnectionReestablishmentReject-r8
- RRCConnectionReestablishmentReject-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionReestablishmentReject-r8-IEs ::= SEQUENCE {
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-
-RRCConnectionReestablishmentRequest ::= SEQUENCE {
- criticalExtensions CHOICE {
- rrcConnectionReestablishmentRequest-r8
- RRCConnectionReestablishmentRequest-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionReestablishmentRequest-r8-IEs ::= SEQUENCE {
- ue-Identity ReestabUE-Identity,
- reestablishmentCause ReestablishmentCause,
- spare BIT STRING (SIZE (2))
-}
-
-ReestabUE-Identity ::= SEQUENCE {
- c-RNTI C-RNTI,
- physCellId PhysCellId,
- shortMAC-I ShortMAC-I
-}
-
-ReestablishmentCause ::= ENUMERATED {
- reconfigurationFailure, handoverFailure,
- otherFailure, spare1}
-
-
-RRCConnectionReject ::= SEQUENCE {
- criticalExtensions CHOICE {
- c1 CHOICE {
- rrcConnectionReject-r8 RRCConnectionReject-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionReject-r8-IEs ::= SEQUENCE {
- waitTime INTEGER (1..16),
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-
-RRCConnectionRelease ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE {
- rrcConnectionRelease-r8 RRCConnectionRelease-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionRelease-r8-IEs ::= SEQUENCE {
- releaseCause ReleaseCause,
- redirectedCarrierInfo RedirectedCarrierInfo OPTIONAL, -- Need ON
- idleModeMobilityControlInfo IdleModeMobilityControlInfo OPTIONAL, -- Need OP
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-ReleaseCause ::= ENUMERATED {loadBalancingTAUrequired,
- other,spare2, spare1 }
-
-RedirectedCarrierInfo ::= CHOICE {
- eutra ARFCN-ValueEUTRA,
- geran CarrierFreqsGERAN,
- utra-FDD ARFCN-ValueUTRA,
- utra-TDD ARFCN-ValueUTRA,
- cdma2000-HRPD CarrierFreqCDMA2000,
- cdma2000-1xRTT CarrierFreqCDMA2000,
- ...
-}
-
-IdleModeMobilityControlInfo ::= SEQUENCE {
- freqPriorityListEUTRA FreqPriorityListEUTRA OPTIONAL, -- Need ON
- freqPriorityListGERAN FreqsPriorityListGERAN OPTIONAL, -- Need ON
- freqPriorityListUTRA-FDD FreqPriorityListUTRA-FDD OPTIONAL, -- Need ON
- freqPriorityListUTRA-TDD FreqPriorityListUTRA-TDD OPTIONAL, -- Need ON
- bandClassPriorityListHRPD BandClassPriorityListHRPD OPTIONAL, -- Need ON
- bandClassPriorityList1XRTT BandClassPriorityList1XRTT OPTIONAL, -- Need ON
- t320 ENUMERATED {
- min5, min10, min20, min30, min60, min120, min180,
- spare1} OPTIONAL, -- Need OR
- ...
-}
-
-FreqPriorityListEUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA
-
-FreqPriorityEUTRA ::= SEQUENCE {
- carrierFreq ARFCN-ValueEUTRA,
- cellReselectionPriority CellReselectionPriority
-}
-
-FreqsPriorityListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF FreqsPriorityGERAN
-
-FreqsPriorityGERAN ::= SEQUENCE {
- carrierFreqs CarrierFreqsGERAN,
- cellReselectionPriority CellReselectionPriority
-}
-
-FreqPriorityListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF FreqPriorityUTRA-FDD
-
-FreqPriorityUTRA-FDD ::= SEQUENCE {
- carrierFreq ARFCN-ValueUTRA,
- cellReselectionPriority CellReselectionPriority
-}
-
-FreqPriorityListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF FreqPriorityUTRA-TDD
-
-FreqPriorityUTRA-TDD ::= SEQUENCE {
- carrierFreq ARFCN-ValueUTRA,
- cellReselectionPriority CellReselectionPriority
-}
-
-BandClassPriorityListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriorityHRPD
-
-BandClassPriorityHRPD ::= SEQUENCE {
- bandClass BandclassCDMA2000,
- cellReselectionPriority CellReselectionPriority
-}
-
-BandClassPriorityList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriority1XRTT
-
-BandClassPriority1XRTT ::= SEQUENCE {
- bandClass BandclassCDMA2000,
- cellReselectionPriority CellReselectionPriority
-}
-
-RRCConnectionRequest ::= SEQUENCE {
- criticalExtensions CHOICE {
- rrcConnectionRequest-r8 RRCConnectionRequest-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionRequest-r8-IEs ::= SEQUENCE {
- ue-Identity InitialUE-Identity,
- establishmentCause EstablishmentCause,
- spare BIT STRING (SIZE (1))
-}
-
-InitialUE-Identity ::= CHOICE {
- s-TMSI S-TMSI,
- randomValue BIT STRING (SIZE (40))
-}
-
-EstablishmentCause ::= ENUMERATED {
- emergency, highPriorityAccess, mt-Access, mo-Signalling,
- mo-Data, spare3, spare2, spare1}
-
-
-RRCConnectionSetup ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE {
- rrcConnectionSetup-r8 RRCConnectionSetup-r8-IEs,
- spare7 NULL,
- spare6 NULL, spare5 NULL, spare4 NULL,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionSetup-r8-IEs ::= SEQUENCE {
- radioResourceConfigDedicated RadioResourceConfigDedicated,
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-
-RRCConnectionSetupComplete ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE{
- rrcConnectionSetupComplete-r8 RRCConnectionSetupComplete-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-RRCConnectionSetupComplete-r8-IEs ::= SEQUENCE {
- selectedPLMN-Identity INTEGER (1..6),
- registeredMME RegisteredMME OPTIONAL,
- dedicatedInfoNAS DedicatedInfoNAS,
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-RegisteredMME ::= SEQUENCE {
- plmn-Identity PLMN-Identity OPTIONAL,
- mmegi BIT STRING (SIZE (16)),
- mmec MMEC
-}
-
-
-SecurityModeCommand ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE{
- securityModeCommand-r8 SecurityModeCommand-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-SecurityModeCommand-r8-IEs ::= SEQUENCE {
- securityConfigSMC SecurityConfigSMC,
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-SecurityConfigSMC ::= SEQUENCE {
- securityAlgorithmConfig SecurityAlgorithmConfig,
- ...
-}
-
-
-SecurityModeComplete ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- securityModeComplete-r8 SecurityModeComplete-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-SecurityModeComplete-r8-IEs ::= SEQUENCE {
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-
-SecurityModeFailure ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- securityModeFailure-r8 SecurityModeFailure-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-SecurityModeFailure-r8-IEs ::= SEQUENCE {
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-
-SystemInformation ::= SEQUENCE {
- criticalExtensions CHOICE {
- systemInformation-r8 SystemInformation-r8-IEs,
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-SystemInformation-r8-IEs ::= SEQUENCE {
- sib-TypeAndInfo SEQUENCE (SIZE (1..maxSIB)) OF CHOICE {
- sib2 SystemInformationBlockType2,
- sib3 SystemInformationBlockType3,
- sib4 SystemInformationBlockType4,
- sib5 SystemInformationBlockType5,
- sib6 SystemInformationBlockType6,
- sib7 SystemInformationBlockType7,
- sib8 SystemInformationBlockType8,
- sib9 SystemInformationBlockType9,
- sib10 SystemInformationBlockType10,
- sib11 SystemInformationBlockType11,
- ...
- },
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-
-SystemInformationBlockType1 ::= SEQUENCE {
- cellAccessRelatedInfo SEQUENCE {
- plmn-IdentityList PLMN-IdentityList,
- trackingAreaCode TrackingAreaCode,
- cellIdentity CellIdentity,
- cellBarred ENUMERATED {barred, notBarred},
- intraFreqReselection ENUMERATED {allowed, notAllowed},
- csg-Indication BOOLEAN,
- csg-Identity BIT STRING (SIZE (27)) OPTIONAL -- Need OR
- },
- cellSelectionInfo SEQUENCE {
- q-RxLevMin Q-RxLevMin,
- q-RxLevMinOffset INTEGER (1..8) OPTIONAL -- Need OP
- },
- p-Max P-Max OPTIONAL, -- Need OP
- freqBandIndicator INTEGER (1..64),
- schedulingInfoList SchedulingInfoList,
- tdd-Config TDD-Config OPTIONAL, -- Cond TDD
- si-WindowLength ENUMERATED {
- ms1, ms2, ms5, ms10, ms15, ms20,
- ms40},
- systemInfoValueTag INTEGER (0..31),
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-PLMN-IdentityList ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo
-
-PLMN-IdentityInfo ::= SEQUENCE {
- plmn-Identity PLMN-Identity,
- cellReservedForOperatorUse ENUMERATED {reserved, notReserved}
-}
-
-SchedulingInfoList ::= SEQUENCE (SIZE (1..maxSI-Message)) OF SchedulingInfo
-
-SchedulingInfo ::= SEQUENCE {
- si-Periodicity ENUMERATED {
- rf8, rf16, rf32, rf64, rf128, rf256, rf512},
- sib-MappingInfo SIB-MappingInfo
-}
-
-SIB-MappingInfo ::= SEQUENCE (SIZE (0..maxSIB-1)) OF SIB-Type
-
-SIB-Type ::= ENUMERATED {
- sibType3, sibType4, sibType5, sibType6,
- sibType7, sibType8, sibType9, sibType10,
- sibType11, spare7, spare6, spare5,
- spare4, spare3, spare2, spare1, ...}
-
-
-UECapabilityEnquiry ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE {
- ueCapabilityEnquiry-r8 UECapabilityEnquiry-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-UECapabilityEnquiry-r8-IEs ::= SEQUENCE {
- ue-CapabilityRequest UE-CapabilityRequest,
- nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
-}
-
-UE-CapabilityRequest ::= SEQUENCE (SIZE (1..maxRAT-Capabilities)) OF RAT-Type
-
-
-UECapabilityInformation ::= SEQUENCE {
- rrc-TransactionIdentifier RRC-TransactionIdentifier,
- criticalExtensions CHOICE {
- c1 CHOICE{
- ueCapabilityInformation-r8 UECapabilityInformation-r8-IEs,
- spare7 NULL,
- spare6 NULL, spare5 NULL, spare4 NULL,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-UECapabilityInformation-r8-IEs ::= SEQUENCE {
- ue-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList,
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-
-ULHandoverPreparationTransfer ::= SEQUENCE {
- criticalExtensions CHOICE {
- c1 CHOICE {
- ulHandoverPreparationTransfer-r8 ULHandoverPreparationTransfer-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE {
- cdma2000-Type CDMA2000-Type,
- meid BIT STRING (SIZE (56)) OPTIONAL,
- dedicatedInfo DedicatedInfoCDMA2000,
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-
-ULInformationTransfer ::= SEQUENCE {
- criticalExtensions CHOICE {
- c1 CHOICE {
- ulInformationTransfer-r8 ULInformationTransfer-r8-IEs,
- spare3 NULL, spare2 NULL, spare1 NULL
- },
- criticalExtensionsFuture SEQUENCE {}
- }
-}
-
-ULInformationTransfer-r8-IEs ::= SEQUENCE {
- dedicatedInfoType CHOICE {
- dedicatedInfoNAS DedicatedInfoNAS,
- dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000,
- dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000
- },
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-
-SystemInformationBlockType2 ::= SEQUENCE {
- ac-BarringInfo SEQUENCE {
- ac-BarringForEmergency BOOLEAN,
- ac-BarringForMO-Signalling AC-BarringConfig OPTIONAL, -- Need OP
- ac-BarringForMO-Data AC-BarringConfig OPTIONAL -- Need OP
- } OPTIONAL, -- Need OP
- radioResourceConfigCommon RadioResourceConfigCommonSIB,
- ue-TimersAndConstants UE-TimersAndConstants,
- freqInfo SEQUENCE {
- ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL, -- Need OP
- ul-Bandwidth ENUMERATED {n6, n15, n25, n50, n75, n100}
- OPTIONAL, -- Need OP
- additionalSpectrumEmission AdditionalSpectrumEmission
- },
- mbsfn-SubframeConfigList MBSFN-SubframeConfigList OPTIONAL, -- Need OR
- timeAlignmentTimerCommon TimeAlignmentTimer,
- ...
-}
-
-AC-BarringConfig ::= SEQUENCE {
- ac-BarringFactor ENUMERATED {
- p00, p05, p10, p15, p20, p25, p30, p40,
- p50, p60, p70, p75, p80, p85, p90, p95},
- ac-BarringTime ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512},
- ac-BarringForSpecialAC BIT STRING (SIZE(5))
-}
-
-MBSFN-SubframeConfigList ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig
-
-MBSFN-SubframeConfig ::= SEQUENCE {
- radioframeAllocationPeriod ENUMERATED {n1, n2, n4, n8, n16, n32},
- radioframeAllocationOffset INTEGER (0..7),
- subframeAllocation CHOICE {
- oneFrame BIT STRING (SIZE(6)),
- fourFrames BIT STRING (SIZE(24))
- }
-}
-
-SystemInformationBlockType3 ::= SEQUENCE {
- cellReselectionInfoCommon SEQUENCE {
- q-Hyst ENUMERATED {
- dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10,
- dB12, dB14, dB16, dB18, dB20, dB22, dB24},
- speedStateReselectionPars SEQUENCE {
- mobilityStateParameters MobilityStateParameters,
- q-HystSF SEQUENCE {
- sf-Medium ENUMERATED {
- dB-6, dB-4, dB-2, dB0},
- sf-High ENUMERATED {
- dB-6, dB-4, dB-2, dB0}
- }
- } OPTIONAL -- Need OP
- },
- cellReselectionServingFreqInfo SEQUENCE {
- s-NonIntraSearch ReselectionThreshold OPTIONAL, -- Need OP
- threshServingLow ReselectionThreshold,
- cellReselectionPriority CellReselectionPriority
- },
- intraFreqCellReselectionInfo SEQUENCE {
- q-RxLevMin Q-RxLevMin,
- p-Max P-Max OPTIONAL, -- Need OP
- s-IntraSearch ReselectionThreshold OPTIONAL, -- Need OP
- allowedMeasBandwidth AllowedMeasBandwidth OPTIONAL, -- Need OP
- presenceAntennaPort1 PresenceAntennaPort1,
- neighCellConfig NeighCellConfig,
- t-ReselectionEUTRA T-Reselection,
- t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL -- Need OP
- },
- ...
-}
-
-
-SystemInformationBlockType4 ::= SEQUENCE {
- intraFreqNeighCellList IntraFreqNeighCellList OPTIONAL, -- Need OR
- intraFreqBlackCellList IntraFreqBlackCellList OPTIONAL, -- Need OR
- csg-PhysCellIdRange PhysCellIdRange OPTIONAL, -- Cond CSG
- ...
-}
-
-IntraFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellIntra)) OF IntraFreqNeighCellInfo
-
-IntraFreqNeighCellInfo ::= SEQUENCE {
- physCellId PhysCellId,
- q-OffsetCell Q-OffsetRange,
- ...
-}
-
-IntraFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange
-
-
-SystemInformationBlockType5 ::= SEQUENCE {
- interFreqCarrierFreqList InterFreqCarrierFreqList,
- ...
-}
-
-InterFreqCarrierFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo
-
-InterFreqCarrierFreqInfo ::= SEQUENCE {
- dl-CarrierFreq ARFCN-ValueEUTRA,
- q-RxLevMin Q-RxLevMin,
- p-Max P-Max OPTIONAL, -- Need OP
- t-ReselectionEUTRA T-Reselection,
- t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP
- threshX-High ReselectionThreshold,
- threshX-Low ReselectionThreshold,
- allowedMeasBandwidth AllowedMeasBandwidth,
- presenceAntennaPort1 PresenceAntennaPort1,
- cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
- neighCellConfig NeighCellConfig,
- q-OffsetFreq Q-OffsetRange DEFAULT dB0,
- interFreqNeighCellList InterFreqNeighCellList OPTIONAL, -- Need OR
- interFreqBlackCellList InterFreqBlackCellList OPTIONAL, -- Need OR
- ...
-}
-
-InterFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellInter)) OF InterFreqNeighCellInfo
-
-InterFreqNeighCellInfo ::= SEQUENCE {
- physCellId PhysCellId,
- q-OffsetCell Q-OffsetRange
-}
-
-InterFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange
-
-
-SystemInformationBlockType6 ::= SEQUENCE {
- carrierFreqListUTRA-FDD CarrierFreqListUTRA-FDD OPTIONAL, -- Need OR
- carrierFreqListUTRA-TDD CarrierFreqListUTRA-TDD OPTIONAL, -- Need OR
- t-ReselectionUTRA T-Reselection,
- t-ReselectionUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP
- ...
-}
-
-CarrierFreqListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF CarrierFreqUTRA-FDD
-
-CarrierFreqUTRA-FDD ::= SEQUENCE {
- carrierFreq ARFCN-ValueUTRA,
- cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
- threshX-High ReselectionThreshold,
- threshX-Low ReselectionThreshold,
- q-RxLevMin INTEGER (-60..-13),
- p-MaxUTRA INTEGER (-50..33),
- q-QualMin INTEGER (-24..0),
- ...
-}
-
-CarrierFreqListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF CarrierFreqUTRA-TDD
-
-CarrierFreqUTRA-TDD ::= SEQUENCE {
- carrierFreq ARFCN-ValueUTRA,
- cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
- threshX-High ReselectionThreshold,
- threshX-Low ReselectionThreshold,
- q-RxLevMin INTEGER (-60..-13),
- p-MaxUTRA INTEGER (-50..33),
- ...
-}
-
-
-SystemInformationBlockType7 ::= SEQUENCE {
- t-ReselectionGERAN T-Reselection,
- t-ReselectionGERAN-SF SpeedStateScaleFactors OPTIONAL, -- Need OR
- carrierFreqsInfoList CarrierFreqsInfoListGERAN OPTIONAL, -- Need OR
- ...
-}
-
-CarrierFreqsInfoListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF CarrierFreqsInfoGERAN
-
-CarrierFreqsInfoGERAN ::= SEQUENCE {
- carrierFreqs CarrierFreqsGERAN,
- commonInfo SEQUENCE {
- cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
- ncc-Permitted BIT STRING (SIZE (8)),
- q-RxLevMin INTEGER (0..45),
- p-MaxGERAN INTEGER (0..39) OPTIONAL, -- Need OP
- threshX-High ReselectionThreshold,
- threshX-Low ReselectionThreshold
- },
- ...
-}
-
-
-SystemInformationBlockType8 ::= SEQUENCE {
- systemTimeInfo SystemTimeInfoCDMA2000 OPTIONAL, -- Need OR
- searchWindowSize INTEGER (0..15) OPTIONAL, -- Need OR
- parametersHRPD SEQUENCE {
- preRegistrationInfoHRPD PreRegistrationInfoHRPD,
- cellReselectionParametersHRPD CellReselectionParametersCDMA2000 OPTIONAL -- Need OR
- } OPTIONAL, -- Need OR
- parameters1XRTT SEQUENCE {
- csfb-RegistrationParam1XRTT CSFB-RegistrationParam1XRTT OPTIONAL, -- Need OP
- longCodeState1XRTT BIT STRING (SIZE (42)) OPTIONAL, -- Need OR
- cellReselectionParameters1XRTT CellReselectionParametersCDMA2000 OPTIONAL -- Need OR
- } OPTIONAL, -- Need OR
- ...
-}
-
-CellReselectionParametersCDMA2000 ::= SEQUENCE {
- bandClassList BandClassListCDMA2000,
- neighCellList NeighCellListCDMA2000,
- t-ReselectionCDMA2000 T-Reselection,
- t-ReselectionCDMA2000-SF SpeedStateScaleFactors OPTIONAL -- Need OP
-}
-NeighCellListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000
-
-NeighCellCDMA2000 ::= SEQUENCE {
- bandClass BandclassCDMA2000,
- neighCellsPerFreqList NeighCellsPerBandclassListCDMA2000
-}
-
-NeighCellsPerBandclassListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000
-
-NeighCellsPerBandclassCDMA2000 ::= SEQUENCE {
- arfcn ARFCN-ValueCDMA2000,
- physCellIdList PhysCellIdListCDMA2000
-}
-
-PhysCellIdListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdCDMA2000
-
-BandClassListCDMA2000 ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassInfoCDMA2000
-
-BandClassInfoCDMA2000 ::= SEQUENCE {
- bandClass BandclassCDMA2000,
- cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
- threshX-High INTEGER (0..63),
- threshX-Low INTEGER (0..63),
- ...
-}
-
-
-SystemInformationBlockType9 ::= SEQUENCE {
- hnb-Name OCTET STRING (SIZE(1..48)) OPTIONAL, -- Need OR
- ...
-}
-
-
-SystemInformationBlockType10 ::= SEQUENCE {
- messageIdentifier BIT STRING (SIZE (16)),
- serialNumber BIT STRING (SIZE (16)),
- warningType OCTET STRING (SIZE (2)),
- warningSecurityInfo OCTET STRING (SIZE (50)) OPTIONAL, -- Need OP
- ...
-}
-
-
-SystemInformationBlockType11 ::= SEQUENCE {
- messageIdentifier BIT STRING (SIZE (16)),
- serialNumber BIT STRING (SIZE (16)),
- warningMessageSegmentType ENUMERATED {notLastSegment, lastSegment},
- warningMessageSegmentNumber INTEGER (0..63),
- warningMessageSegment OCTET STRING,
- dataCodingScheme OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1
- ...
-}
-
-
-AntennaInfoCommon ::= SEQUENCE {
- antennaPortsCount ENUMERATED {an1, an2, an4, spare1}
-}
-
-AntennaInfoDedicated ::= SEQUENCE {
- transmissionMode ENUMERATED {
- tm1, tm2, tm3, tm4, tm5, tm6,
- tm7, spare1},
- codebookSubsetRestriction CHOICE {
- n2TxAntenna-tm3 BIT STRING (SIZE (2)),
- n4TxAntenna-tm3 BIT STRING (SIZE (4)),
- n2TxAntenna-tm4 BIT STRING (SIZE (6)),
- n4TxAntenna-tm4 BIT STRING (SIZE (64)),
- n2TxAntenna-tm5 BIT STRING (SIZE (4)),
- n4TxAntenna-tm5 BIT STRING (SIZE (16)),
- n2TxAntenna-tm6 BIT STRING (SIZE (4)),
- n4TxAntenna-tm6 BIT STRING (SIZE (16))
- } OPTIONAL, -- Cond TM
- ue-TransmitAntennaSelection CHOICE{
- release NULL,
- setup ENUMERATED {closedLoop, openLoop}
- }
-}
-
-
-CQI-ReportConfig ::= SEQUENCE {
- cqi-ReportModeAperiodic ENUMERATED {
- rm12, rm20, rm22, rm30, rm31,
- spare3, spare2, spare1} OPTIONAL, -- Need OR
- nomPDSCH-RS-EPRE-Offset INTEGER (-1..6),
- cqi-ReportPeriodic CQI-ReportPeriodic OPTIONAL -- Need ON
-}
-
-CQI-ReportPeriodic ::= CHOICE {
- release NULL,
- setup SEQUENCE {
- cqi-PUCCH-ResourceIndex INTEGER (0.. 1185),
- cqi-pmi-ConfigIndex INTEGER (0..1023),
- cqi-FormatIndicatorPeriodic CHOICE {
- widebandCQI NULL,
- subbandCQI SEQUENCE {
- k INTEGER (1..4)
- }
- },
- ri-ConfigIndex INTEGER (0..1023) OPTIONAL, -- Need OR
- simultaneousAckNackAndCQI BOOLEAN
- }
-}
-
-
-DRB-Identity ::= INTEGER (1..32)
-
-
-LogicalChannelConfig ::= SEQUENCE {
- ul-SpecificParameters SEQUENCE {
- priority INTEGER (1..16),
- prioritisedBitRate ENUMERATED {
- kBps0, kBps8, kBps16, kBps32, kBps64, kBps128,
- kBps256, infinity, spare8, spare7, spare6,
- spare5, spare4, spare3, spare2, spare1},
- bucketSizeDuration ENUMERATED {
- ms50, ms100, ms150, ms300, ms500, ms1000, spare2,
- spare1},
- logicalChannelGroup INTEGER (0..3) OPTIONAL -- Need OR
- } OPTIONAL, -- Cond UL
- ...
-}
-
-
-MAC-MainConfig ::= SEQUENCE {
- ul-SCH-Config SEQUENCE {
- maxHARQ-Tx ENUMERATED {
- n1, n2, n3, n4, n5, n6, n7, n8,
- n10, n12, n16, n20, n24, n28,
- spare2, spare1} OPTIONAL, -- Need ON
- periodicBSR-Timer ENUMERATED {
- sf5, sf10, sf16, sf20, sf32, sf40, sf64, sf80,
- sf128, sf160, sf320, sf640, sf1280, sf2560,
- infinity, spare1} OPTIONAL, -- Need ON
- retxBSR-Timer ENUMERATED {
- sf320, sf640, sf1280, sf2560, sf5120,
- sf10240, spare2, spare1},
- ttiBundling BOOLEAN
- } OPTIONAL, -- Need ON
- drx-Config DRX-Config OPTIONAL, -- Need ON
- timeAlignmentTimerDedicated TimeAlignmentTimer,
- phr-Config CHOICE {
- release NULL,
- setup SEQUENCE {
- periodicPHR-Timer ENUMERATED {sf10, sf20, sf50, sf100, sf200,
- sf500, sf1000, infinity},
- prohibitPHR-Timer ENUMERATED {sf0, sf10, sf20, sf50, sf100,
- sf200, sf500, sf1000},
- dl-PathlossChange ENUMERATED {dB1, dB3, dB6, infinity}
- }
- } OPTIONAL, -- Need ON
- ...
-}
-
-DRX-Config ::= CHOICE {
- release NULL,
- setup SEQUENCE {
- onDurationTimer ENUMERATED {
- psf1, psf2, psf3, psf4, psf5, psf6,
- psf8, psf10, psf20, psf30, psf40,
- psf50, psf60, psf80, psf100,
- psf200},
- drx-InactivityTimer ENUMERATED {
- psf1, psf2, psf3, psf4, psf5, psf6,
- psf8, psf10, psf20, psf30, psf40,
- psf50, psf60, psf80, psf100,
- psf200, psf300, psf500, psf750,
- psf1280, psf1920, psf2560, spare10,
- spare9, spare8, spare7, spare6,
- spare5, spare4, spare3, spare2,
- spare1},
- drx-RetransmissionTimer ENUMERATED {
- psf1, psf2, psf4, psf6, psf8, psf16,
- psf24, psf33},
- longDRX-CycleStartOffset CHOICE {
- sf10 INTEGER(0..9),
- sf20 INTEGER(0..19),
- sf32 INTEGER(0..31),
- sf40 INTEGER(0..39),
- sf64 INTEGER(0..63),
- sf80 INTEGER(0..79),
- sf128 INTEGER(0..127),
- sf160 INTEGER(0..159),
- sf256 INTEGER(0..255),
- sf320 INTEGER(0..319),
- sf512 INTEGER(0..511),
- sf640 INTEGER(0..639),
- sf1024 INTEGER(0..1023),
- sf1280 INTEGER(0..1279),
- sf2048 INTEGER(0..2047),
- sf2560 INTEGER(0..2559)
- },
- shortDRX SEQUENCE {
- shortDRX-Cycle ENUMERATED {
- sf2, sf5, sf8, sf10, sf16, sf20,
- sf32, sf40, sf64, sf80, sf128, sf160,
- sf256, sf320, sf512, sf640},
- drxShortCycleTimer INTEGER (1..16)
- } OPTIONAL -- Need OR
- }
-}
-
-
-PDCP-Config ::= SEQUENCE {
- discardTimer ENUMERATED {
- ms50, ms100, ms150, ms300, ms500,
- ms750, ms1500, infinity
- } OPTIONAL, -- Cond Setup
- rlc-AM SEQUENCE {
- statusReportRequired BOOLEAN
- } OPTIONAL, -- Cond Rlc-AM
- rlc-UM SEQUENCE {
- pdcp-SN-Size ENUMERATED {len7bits, len12bits}
- } OPTIONAL, -- Cond Rlc-UM
- headerCompression CHOICE {
- notUsed NULL,
- rohc SEQUENCE {
- maxCID INTEGER (1..16383) DEFAULT 15,
- profiles SEQUENCE {
- profile0x0001 BOOLEAN,
- profile0x0002 BOOLEAN,
- profile0x0003 BOOLEAN,
- profile0x0004 BOOLEAN,
- profile0x0006 BOOLEAN,
- profile0x0101 BOOLEAN,
- profile0x0102 BOOLEAN,
- profile0x0103 BOOLEAN,
- profile0x0104 BOOLEAN
- },
- ...
- }
- },
- ...
-}
-
-
-PDSCH-ConfigCommon::= SEQUENCE {
- referenceSignalPower INTEGER (-60..50),
- p-b INTEGER (0..3)
-}
-
-PDSCH-ConfigDedicated::= SEQUENCE {
- p-a ENUMERATED {
- dB-6, dB-4dot77, dB-3, dB-1dot77,
- dB0, dB1, dB2, dB3 }
-}
-
-
-PHICH-Config ::= SEQUENCE {
- phich-Duration ENUMERATED {normal, extended},
- phich-Resource ENUMERATED {oneSixth, half, one, two}
-}
-
-
-PhysicalConfigDedicated ::= SEQUENCE {
- pdsch-ConfigDedicated PDSCH-ConfigDedicated OPTIONAL, -- Need ON
- pucch-ConfigDedicated PUCCH-ConfigDedicated OPTIONAL, -- Need ON
- pusch-ConfigDedicated PUSCH-ConfigDedicated OPTIONAL, -- Need ON
- uplinkPowerControlDedicated UplinkPowerControlDedicated OPTIONAL, -- Need ON
- tpc-PDCCH-ConfigPUCCH TPC-PDCCH-Config OPTIONAL, -- Need ON
- tpc-PDCCH-ConfigPUSCH TPC-PDCCH-Config OPTIONAL, -- Need ON
- cqi-ReportConfig CQI-ReportConfig OPTIONAL, -- Need ON
- soundingRS-UL-ConfigDedicated SoundingRS-UL-ConfigDedicated OPTIONAL, -- Need ON
- antennaInfo CHOICE {
- explicitValue AntennaInfoDedicated,
- defaultValue NULL
- } OPTIONAL, -- Need ON
- schedulingRequestConfig SchedulingRequestConfig OPTIONAL, -- Need ON
- ...
-}
-
-
-P-Max ::= INTEGER (-30..33)
-
-
-PRACH-ConfigSIB ::= SEQUENCE {
- rootSequenceIndex INTEGER (0..837),
- prach-ConfigInfo PRACH-ConfigInfo
-}
-
-PRACH-Config ::= SEQUENCE {
- rootSequenceIndex INTEGER (0..837),
- prach-ConfigInfo PRACH-ConfigInfo OPTIONAL -- Need ON
-}
-
-PRACH-ConfigInfo ::= SEQUENCE {
- prach-ConfigIndex INTEGER (0..63),
- highSpeedFlag BOOLEAN,
- zeroCorrelationZoneConfig INTEGER (0..15),
- prach-FreqOffset INTEGER (0..94)
-}
-
-
-PresenceAntennaPort1 ::= BOOLEAN
-
-
-PUCCH-ConfigCommon ::= SEQUENCE {
- deltaPUCCH-Shift ENUMERATED {ds1, ds2, ds3},
- nRB-CQI INTEGER (0..98),
- nCS-AN INTEGER (0..7),
- n1PUCCH-AN INTEGER (0..2047)
-}
-
-PUCCH-ConfigDedicated ::= SEQUENCE {
- ackNackRepetition CHOICE{
- release NULL,
- setup SEQUENCE {
- repetitionFactor ENUMERATED { n2, n4, n6, spare1},
- n1PUCCH-AN-Rep INTEGER (0..2047)
- }
- },
- tdd-AckNackFeedbackMode ENUMERATED {bundling, multiplexing} OPTIONAL -- Cond TDD
-}
-
-
-PUSCH-ConfigCommon ::= SEQUENCE {
- pusch-ConfigBasic SEQUENCE {
- n-SB INTEGER (1..4),
- hoppingMode ENUMERATED {interSubFrame, intraAndInterSubFrame},
- pusch-HoppingOffset INTEGER (0..98),
- enable64QAM BOOLEAN
- },
- ul-ReferenceSignalsPUSCH UL-ReferenceSignalsPUSCH
-}
-
-PUSCH-ConfigDedicated ::= SEQUENCE {
- betaOffset-ACK-Index INTEGER (0..15),
- betaOffset-RI-Index INTEGER (0..15),
- betaOffset-CQI-Index INTEGER (0..15)
-}
-
-UL-ReferenceSignalsPUSCH ::= SEQUENCE {
- groupHoppingEnabled BOOLEAN,
- groupAssignmentPUSCH INTEGER (0..29),
- sequenceHoppingEnabled BOOLEAN,
- cyclicShift INTEGER (0..7)
-}
-
-
-RACH-ConfigCommon ::= SEQUENCE {
- preambleInfo SEQUENCE {
- numberOfRA-Preambles ENUMERATED {
- n4, n8, n12, n16 ,n20, n24, n28,
- n32, n36, n40, n44, n48, n52, n56,
- n60, n64},
- preamblesGroupAConfig SEQUENCE {
- sizeOfRA-PreamblesGroupA ENUMERATED {
- n4, n8, n12, n16 ,n20, n24, n28,
- n32, n36, n40, n44, n48, n52, n56,
- n60},
- messageSizeGroupA ENUMERATED {b56, b144, b208, b256},
- messagePowerOffsetGroupB ENUMERATED {
- minusinfinity, dB0, dB5, dB8, dB10, dB12,
- dB15, dB18},
- ...
- } OPTIONAL -- Need OP
- },
- powerRampingParameters SEQUENCE {
- powerRampingStep ENUMERATED {dB0, dB2,dB4, dB6},
- preambleInitialReceivedTargetPower ENUMERATED {
- dBm-120, dBm-118, dBm-116, dBm-114, dBm-112,
- dBm-110, dBm-108, dBm-106, dBm-104, dBm-102,
- dBm-100, dBm-98, dBm-96, dBm-94,
- dBm-92, dBm-90}
- },
- ra-SupervisionInfo SEQUENCE {
- preambleTransMax ENUMERATED {
- n3, n4, n5, n6, n7, n8, n10, n20, n50,
- n100, n200},
- ra-ResponseWindowSize ENUMERATED {
- sf2, sf3, sf4, sf5, sf6, sf7,
- sf8, sf10},
- mac-ContentionResolutionTimer ENUMERATED {
- sf8, sf16, sf24, sf32, sf40, sf48,
- sf56, sf64}
- },
- maxHARQ-Msg3Tx INTEGER (1..8),
- ...
-}
-
-
-RACH-ConfigDedicated ::= SEQUENCE {
- ra-PreambleIndex INTEGER (0..63),
- ra-PRACH-MaskIndex INTEGER (0..15)
-}
-
-
-RadioResourceConfigCommonSIB ::= SEQUENCE {
- rach-ConfigCommon RACH-ConfigCommon,
- bcch-Config BCCH-Config,
- pcch-Config PCCH-Config,
- prach-Config PRACH-ConfigSIB,
- pdsch-ConfigCommon PDSCH-ConfigCommon,
- pusch-ConfigCommon PUSCH-ConfigCommon,
- pucch-ConfigCommon PUCCH-ConfigCommon,
- soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon,
- uplinkPowerControlCommon UplinkPowerControlCommon,
- ul-CyclicPrefixLength UL-CyclicPrefixLength,
- ...
-}
-
-RadioResourceConfigCommon ::= SEQUENCE {
- rach-ConfigCommon RACH-ConfigCommon OPTIONAL, -- Need ON
- prach-Config PRACH-Config,
- pdsch-ConfigCommon PDSCH-ConfigCommon OPTIONAL, -- Need ON
- pusch-ConfigCommon PUSCH-ConfigCommon,
- phich-Config PHICH-Config OPTIONAL, -- Need ON
- pucch-ConfigCommon PUCCH-ConfigCommon OPTIONAL, -- Need ON
- soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon OPTIONAL, -- Need ON
- uplinkPowerControlCommon UplinkPowerControlCommon OPTIONAL, -- Need ON
- antennaInfoCommon AntennaInfoCommon OPTIONAL, -- Need ON
- p-Max P-Max OPTIONAL, -- Need OP
- tdd-Config TDD-Config OPTIONAL, -- Cond TDD
- ul-CyclicPrefixLength UL-CyclicPrefixLength,
- ...
-}
-
-BCCH-Config ::= SEQUENCE {
- modificationPeriodCoeff ENUMERATED {n2, n4, n8, n16}
-}
-
-PCCH-Config ::= SEQUENCE {
- defaultPagingCycle ENUMERATED {
- rf32, rf64, rf128, rf256},
- nB ENUMERATED {
- fourT, twoT, oneT, halfT, quarterT, oneEighthT,
- oneSixteenthT, oneThirtySecondT}
-}
-
-UL-CyclicPrefixLength ::= ENUMERATED {len1, len2}
-
-
-RadioResourceConfigDedicated ::= SEQUENCE {
- srb-ToAddModList SRB-ToAddModList OPTIONAL, -- Cond HO-Conn
- drb-ToAddModList DRB-ToAddModList OPTIONAL, -- Cond HO-toEUTRA
- drb-ToReleaseList DRB-ToReleaseList OPTIONAL, -- Need ON
- mac-MainConfig CHOICE {
- explicitValue MAC-MainConfig,
- defaultValue NULL
- } OPTIONAL, -- Cond HO-toEUTRA2
- sps-Config SPS-Config OPTIONAL, -- Need ON
- physicalConfigDedicated PhysicalConfigDedicated OPTIONAL, -- Need ON
- ...
-}
-
-SRB-ToAddModList ::= SEQUENCE (SIZE (1..2)) OF SRB-ToAddMod
-
-SRB-ToAddMod ::= SEQUENCE {
- srb-Identity INTEGER (1..2),
- rlc-Config CHOICE {
- explicitValue RLC-Config,
- defaultValue NULL
- } OPTIONAL, -- Cond Setup
- logicalChannelConfig CHOICE {
- explicitValue LogicalChannelConfig,
- defaultValue NULL
- } OPTIONAL, -- Cond Setup
- ...
-}
-
-DRB-ToAddModList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddMod
-
-DRB-ToAddMod ::= SEQUENCE {
- eps-BearerIdentity INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup
- drb-Identity DRB-Identity,
- pdcp-Config PDCP-Config OPTIONAL, -- Cond PDCP
- rlc-Config RLC-Config OPTIONAL, -- Cond Setup
- logicalChannelIdentity INTEGER (3..10) OPTIONAL, -- Cond DRB-Setup
- logicalChannelConfig LogicalChannelConfig OPTIONAL, -- Cond Setup
- ...
-}
-
-DRB-ToReleaseList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-Identity
-
-
-RLC-Config ::= CHOICE {
- am SEQUENCE {
- ul-AM-RLC UL-AM-RLC,
- dl-AM-RLC DL-AM-RLC
- },
- um-Bi-Directional SEQUENCE {
- ul-UM-RLC UL-UM-RLC,
- dl-UM-RLC DL-UM-RLC
- },
- um-Uni-Directional-UL SEQUENCE {
- ul-UM-RLC UL-UM-RLC
- },
- um-Uni-Directional-DL SEQUENCE {
- dl-UM-RLC DL-UM-RLC
- },
- ...
-}
-
-UL-AM-RLC ::= SEQUENCE {
- t-PollRetransmit T-PollRetransmit,
- pollPDU PollPDU,
- pollByte PollByte,
- maxRetxThreshold ENUMERATED {
- t1, t2, t3, t4, t6, t8, t16, t32}
-}
-
-DL-AM-RLC ::= SEQUENCE {
- t-Reordering T-Reordering,
- t-StatusProhibit T-StatusProhibit
-}
-
-UL-UM-RLC ::= SEQUENCE {
- sn-FieldLength SN-FieldLength
-}
-
-DL-UM-RLC ::= SEQUENCE {
- sn-FieldLength SN-FieldLength,
- t-Reordering T-Reordering
-}
-
-SN-FieldLength ::= ENUMERATED {size5, size10}
-
-T-PollRetransmit ::= ENUMERATED {
- ms5, ms10, ms15, ms20, ms25, ms30, ms35,
- ms40, ms45, ms50, ms55, ms60, ms65, ms70,
- ms75, ms80, ms85, ms90, ms95, ms100, ms105,
- ms110, ms115, ms120, ms125, ms130, ms135,
- ms140, ms145, ms150, ms155, ms160, ms165,
- ms170, ms175, ms180, ms185, ms190, ms195,
- ms200, ms205, ms210, ms215, ms220, ms225,
- ms230, ms235, ms240, ms245, ms250, ms300,
- ms350, ms400, ms450, ms500, spare9, spare8,
- spare7, spare6, spare5, spare4, spare3,
- spare2, spare1}
-
-PollPDU ::= ENUMERATED {
- p4, p8, p16, p32, p64, p128, p256, pInfinity}
-
-PollByte ::= ENUMERATED {
- kB25, kB50, kB75, kB100, kB125, kB250, kB375,
- kB500, kB750, kB1000, kB1250, kB1500, kB2000,
- kB3000, kBinfinity, spare1}
-
-T-Reordering ::= ENUMERATED {
- ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35,
- ms40, ms45, ms50, ms55, ms60, ms65, ms70,
- ms75, ms80, ms85, ms90, ms95, ms100, ms110,
- ms120, ms130, ms140, ms150, ms160, ms170,
- ms180, ms190, ms200, spare1}
-
-T-StatusProhibit ::= ENUMERATED {
- ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35,
- ms40, ms45, ms50, ms55, ms60, ms65, ms70,
- ms75, ms80, ms85, ms90, ms95, ms100, ms105,
- ms110, ms115, ms120, ms125, ms130, ms135,
- ms140, ms145, ms150, ms155, ms160, ms165,
- ms170, ms175, ms180, ms185, ms190, ms195,
- ms200, ms205, ms210, ms215, ms220, ms225,
- ms230, ms235, ms240, ms245, ms250, ms300,
- ms350, ms400, ms450, ms500, spare8, spare7,
- spare6, spare5, spare4, spare3, spare2,
- spare1}
-
-
-SchedulingRequestConfig ::= CHOICE {
- release NULL,
- setup SEQUENCE {
- sr-PUCCH-ResourceIndex INTEGER (0..2047),
- sr-ConfigIndex INTEGER (0..155),
- dsr-TransMax ENUMERATED {
- n4, n8, n16, n32, n64, spare3, spare2, spare1}
- }
-}
-
-
-SoundingRS-UL-ConfigCommon ::= CHOICE {
- release NULL,
- setup SEQUENCE {
- srs-BandwidthConfig ENUMERATED {bw0, bw1, bw2, bw3, bw4, bw5, bw6, bw7},
- srs-SubframeConfig ENUMERATED {
- sc0, sc1, sc2, sc3, sc4, sc5, sc6, sc7,
- sc8, sc9, sc10, sc11, sc12, sc13, sc14, sc15},
- ackNackSRS-SimultaneousTransmission BOOLEAN,
- srs-MaxUpPts ENUMERATED {true} OPTIONAL -- Cond TDD
- }
-}
-
-SoundingRS-UL-ConfigDedicated ::= CHOICE{
- release NULL,
- setup SEQUENCE {
- srs-Bandwidth ENUMERATED {bw0, bw1, bw2, bw3},
- srs-HoppingBandwidth ENUMERATED {hbw0, hbw1, hbw2, hbw3},
- freqDomainPosition INTEGER (0..23),
- duration BOOLEAN,
- srs-ConfigIndex INTEGER (0..1023),
- transmissionComb INTEGER (0..1),
- cyclicShift ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7}
- }
-}
-
-
-
-SPS-Config ::= SEQUENCE {
- semiPersistSchedC-RNTI C-RNTI OPTIONAL, -- Need OR
- sps-ConfigDL SPS-ConfigDL OPTIONAL, -- Need ON
- sps-ConfigUL SPS-ConfigUL OPTIONAL -- Need ON
-}
-
-SPS-ConfigDL ::= CHOICE{
- release NULL,
- setup SEQUENCE {
- semiPersistSchedIntervalDL ENUMERATED {
- sf10, sf20, sf32, sf40, sf64, sf80,
- sf128, sf160, sf320, sf640, spare6,
- spare5, spare4, spare3, spare2,
- spare1},
- numberOfConfSPS-Processes INTEGER (1..8),
- n1-PUCCH-AN-PersistentList N1-PUCCH-AN-PersistentList,
- ...
- }
-}
-
-SPS-ConfigUL ::= CHOICE {
- release NULL,
- setup SEQUENCE {
- semiPersistSchedIntervalUL ENUMERATED {
- sf10, sf20, sf32, sf40, sf64, sf80,
- sf128, sf160, sf320, sf640, spare6,
- spare5, spare4, spare3, spare2,
- spare1},
- implicitReleaseAfter ENUMERATED {e2, e3, e4, e8},
- p0-Persistent SEQUENCE {
- p0-NominalPUSCH-Persistent INTEGER (-126..24),
- p0-UE-PUSCH-Persistent INTEGER (-8..7)
- } OPTIONAL, -- Need OP
- twoIntervalsConfig ENUMERATED {true} OPTIONAL, -- Cond TDD
- ...
- }
-}
-
-N1-PUCCH-AN-PersistentList ::= SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047)
-
-
-TDD-Config ::= SEQUENCE {
- subframeAssignment ENUMERATED {
- sa0, sa1, sa2, sa3, sa4, sa5, sa6},
- specialSubframePatterns ENUMERATED {
- ssp0, ssp1, ssp2, ssp3, ssp4,ssp5, ssp6, ssp7,
- ssp8}
-}
-
-
-TimeAlignmentTimer ::= ENUMERATED {
- sf500, sf750, sf1280, sf1920, sf2560, sf5120,
- sf10240, infinity}
-
-TPC-PDCCH-Config::= CHOICE {
- release NULL,
- setup SEQUENCE {
- tpc-RNTI BIT STRING (SIZE (16)),
- tpc-Index TPC-Index
- }
-}
-
-TPC-Index ::= CHOICE {
- indexOfFormat3 INTEGER (1..15),
- indexOfFormat3A INTEGER (1..31)
-}
-
-
-UplinkPowerControlCommon ::= SEQUENCE {
- p0-NominalPUSCH INTEGER (-126..24),
- alpha ENUMERATED {al0, al04, al05, al06, al07, al08, al09, al1},
- p0-NominalPUCCH INTEGER (-127..-96),
- deltaFList-PUCCH DeltaFList-PUCCH,
- deltaPreambleMsg3 INTEGER (-1..6)
-}
-
-UplinkPowerControlDedicated ::= SEQUENCE {
- p0-UE-PUSCH INTEGER (-8..7),
- deltaMCS-Enabled ENUMERATED {en0, en1},
- accumulationEnabled BOOLEAN,
- p0-UE-PUCCH INTEGER (-8..7),
- pSRS-Offset INTEGER (0..15),
- filterCoefficient FilterCoefficient DEFAULT fc4
-}
-
-DeltaFList-PUCCH ::= SEQUENCE {
- deltaF-PUCCH-Format1 ENUMERATED {deltaF-2, deltaF0, deltaF2},
- deltaF-PUCCH-Format1b ENUMERATED {deltaF1, deltaF3, deltaF5},
- deltaF-PUCCH-Format2 ENUMERATED {deltaF-2, deltaF0, deltaF1, deltaF2},
- deltaF-PUCCH-Format2a ENUMERATED {deltaF-2, deltaF0, deltaF2},
- deltaF-PUCCH-Format2b ENUMERATED {deltaF-2, deltaF0, deltaF2}
-}
-
-
-NextHopChainingCount ::= INTEGER (0..7)
-
-
-SecurityAlgorithmConfig ::= SEQUENCE {
- cipheringAlgorithm ENUMERATED {
- eea0, eea1, eea2, spare5, spare4, spare3,
- spare2, spare1, ...},
- integrityProtAlgorithm ENUMERATED {
- reserved, eia1, eia2, spare5, spare4, spare3,
- spare2, spare1, ...}
-}
-
-
-ShortMAC-I ::= BIT STRING (SIZE (16))
-
-
-AdditionalSpectrumEmission ::= INTEGER (1..32)
-
-
-ARFCN-ValueCDMA2000 ::= INTEGER (0..2047)
-
-
-ARFCN-ValueEUTRA ::= INTEGER (0..maxEARFCN)
-
-
-ARFCN-ValueGERAN ::= INTEGER (0..1023)
-
-
-ARFCN-ValueUTRA ::= INTEGER (0..16383)
-
-
-BandclassCDMA2000 ::= ENUMERATED {
- bc0, bc1, bc2, bc3, bc4, bc5, bc6, bc7, bc8,
- bc9, bc10, bc11, bc12, bc13, bc14, bc15, bc16,
- bc17, spare14, spare13, spare12, spare11, spare10,
- spare9, spare8, spare7, spare6, spare5, spare4,
- spare3, spare2, spare1, ...}
-
-
-BandIndicatorGERAN ::= ENUMERATED {dcs1800, pcs1900}
-
-
-CarrierFreqCDMA2000 ::= SEQUENCE {
- bandClass BandclassCDMA2000,
- arfcn ARFCN-ValueCDMA2000
-}
-
-
-CarrierFreqGERAN ::= SEQUENCE {
- arfcn ARFCN-ValueGERAN,
- bandIndicator BandIndicatorGERAN
-}
-
-
-CarrierFreqsGERAN ::= SEQUENCE {
- startingARFCN ARFCN-ValueGERAN,
- bandIndicator BandIndicatorGERAN,
- followingARFCNs CHOICE {
- explicitListOfARFCNs ExplicitListOfARFCNs,
- equallySpacedARFCNs SEQUENCE {
- arfcn-Spacing INTEGER (1..8),
- numberOfFollowingARFCNs INTEGER (0..31)
- },
- variableBitMapOfARFCNs OCTET STRING (SIZE (1..16))
- }
-}
-
-ExplicitListOfARFCNs ::= SEQUENCE (SIZE (0..31)) OF ARFCN-ValueGERAN
-
-
-CDMA2000-Type ::= ENUMERATED {type1XRTT, typeHRPD}
-
-
-CellIdentity ::= BIT STRING (SIZE (28))
-
-
-CellIndexList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellIndex
-
-CellIndex ::= INTEGER (1..maxCellMeas)
-
-
-CellReselectionPriority ::= INTEGER (0..7)
-
-
-CSFB-RegistrationParam1XRTT ::= SEQUENCE {
- sid BIT STRING (SIZE (15)),
- nid BIT STRING (SIZE (16)),
- multipleSID BOOLEAN,
- multipleNID BOOLEAN,
- homeReg BOOLEAN,
- foreignSIDReg BOOLEAN,
- foreignNIDReg BOOLEAN,
- parameterReg BOOLEAN,
- powerUpReg BOOLEAN,
- registrationPeriod BIT STRING (SIZE (7)),
- registrationZone BIT STRING (SIZE (12)),
- totalZone BIT STRING (SIZE (3)),
- zoneTimer BIT STRING (SIZE (3))
-}
-
-
-CellGlobalIdEUTRA ::= SEQUENCE {
- plmn-Identity PLMN-Identity,
- cellIdentity CellIdentity
-}
-
-
-CellGlobalIdUTRA ::= SEQUENCE {
- plmn-Identity PLMN-Identity,
- cellIdentity BIT STRING (SIZE (28))
-}
-
-
-CellGlobalIdGERAN ::= SEQUENCE {
- plmn-Identity PLMN-Identity,
- locationAreaCode BIT STRING (SIZE (16)),
- cellIdentity BIT STRING (SIZE (16))
-}
-
-
-CellGlobalIdCDMA2000 ::= CHOICE {
- cellGlobalId1XRTT BIT STRING (SIZE (47)),
- cellGlobalIdHRPD BIT STRING (SIZE (128))
-}
-
-
-MobilityControlInfo ::= SEQUENCE {
- targetPhysCellId PhysCellId,
- carrierFreq CarrierFreqEUTRA OPTIONAL, -- Cond HO-toEUTRA
- carrierBandwidth CarrierBandwidthEUTRA OPTIONAL, -- Cond HO-toEUTRA
- additionalSpectrumEmission AdditionalSpectrumEmission OPTIONAL, -- Cond HO-toEUTRA
- t304 ENUMERATED {
- ms50, ms100, ms150, ms200, ms500, ms1000,
- ms2000, spare1},
- newUE-Identity C-RNTI,
- radioResourceConfigCommon RadioResourceConfigCommon,
- rach-ConfigDedicated RACH-ConfigDedicated OPTIONAL, -- Need OP
- ...
-}
-
-CarrierBandwidthEUTRA ::= SEQUENCE {
- dl-Bandwidth ENUMERATED {
- n6, n15, n25, n50, n75, n100, spare10,
- spare9, spare8, spare7, spare6, spare5,
- spare4, spare3, spare2, spare1},
- ul-Bandwidth ENUMERATED {
- n6, n15, n25, n50, n75, n100, spare10,
- spare9, spare8, spare7, spare6, spare5,
- spare4, spare3, spare2, spare1} OPTIONAL -- Need OP
-}
-
-CarrierFreqEUTRA ::= SEQUENCE {
- dl-CarrierFreq ARFCN-ValueEUTRA,
- ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL -- Cond FDD
-}
-
-
-MobilityParametersCDMA2000 ::= OCTET STRING
-
-
-MobilityStateParameters ::= SEQUENCE {
- t-Evaluation ENUMERATED {
- s30, s60, s120, s180, s240, spare3, spare2, spare1},
- t-HystNormal ENUMERATED {
- s30, s60, s120, s180, s240, spare3, spare2, spare1},
- n-CellChangeMedium INTEGER (1..16),
- n-CellChangeHigh INTEGER (1..16)
-}
-
-
-PhysCellId ::= INTEGER (0..503)
-
-
-PhysCellIdRange ::= SEQUENCE {
- start PhysCellId,
- range ENUMERATED {
- n4, n8, n12, n16, n24, n32, n48, n64, n84,
- n96, n128, n168, n252, n504, spare2,
- spare1} OPTIONAL -- Need OP
-}
-
-
-PhysCellIdCDMA2000 ::= INTEGER (0..maxPNOffset)
-
-
-PhysCellIdGERAN ::= SEQUENCE {
- networkColourCode BIT STRING (SIZE (3)),
- baseStationColourCode BIT STRING (SIZE (3))
-}
-
-
-PhysCellIdUTRA-FDD ::= INTEGER (0..511)
-
-
-PhysCellIdUTRA-TDD ::= INTEGER (0..127)
-
-
-PLMN-Identity ::= SEQUENCE {
- mcc MCC OPTIONAL, -- Cond MCC
- mnc MNC
-}
-
-MCC ::= SEQUENCE (SIZE (3)) OF
- MCC-MNC-Digit
-
-MNC ::= SEQUENCE (SIZE (2..3)) OF
- MCC-MNC-Digit
-
-MCC-MNC-Digit ::= INTEGER (0..9)
-
-
-
-PreRegistrationInfoHRPD ::= SEQUENCE {
- preRegistrationAllowed BOOLEAN,
- preRegistrationZoneId PreRegistrationZoneIdHRPD OPTIONAL, -- cond PreRegAllowed
- secondaryPreRegistrationZoneIdList SecondaryPreRegistrationZoneIdListHRPD OPTIONAL -- Need OR
-}
-
-SecondaryPreRegistrationZoneIdListHRPD ::= SEQUENCE (SIZE (1..2)) OF PreRegistrationZoneIdHRPD
-
-PreRegistrationZoneIdHRPD ::= INTEGER (0..255)
-
-
-Q-RxLevMin ::= INTEGER (-70..-22)
-
-
-Q-OffsetRange ::= ENUMERATED {
- dB-24, dB-22, dB-20, dB-18, dB-16, dB-14,
- dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3,
- dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5,
- dB6, dB8, dB10, dB12, dB14, dB16, dB18,
- dB20, dB22, dB24}
-
-
-Q-OffsetRangeInterRAT ::= INTEGER (-15..15)
-
-
-ReselectionThreshold ::= INTEGER (0..31)
-
-
-SpeedStateScaleFactors ::= SEQUENCE {
- sf-Medium ENUMERATED {oDot25, oDot5, oDot75, lDot0},
- sf-High ENUMERATED {oDot25, oDot5, oDot75, lDot0}
-}
-
-SystemTimeInfoCDMA2000 ::= SEQUENCE {
- cdma-EUTRA-Synchronisation BOOLEAN,
- cdma-SystemTime CHOICE {
- synchronousSystemTime BIT STRING (SIZE (39)),
- asynchronousSystemTime BIT STRING (SIZE (49))
- }
-}
-
-
-TrackingAreaCode ::= BIT STRING (SIZE (16))
-
-
-T-Reselection ::= INTEGER (0..7)
-
-
-AllowedMeasBandwidth ::= ENUMERATED {mbw6, mbw15, mbw25, mbw50, mbw75, mbw100}
-
-
-Hysteresis ::= INTEGER (0..30)
-
-
-MeasConfig ::= SEQUENCE {
- -- Measurement objects
- measObjectToRemoveList MeasObjectToRemoveList OPTIONAL, -- Need ON
- measObjectToAddModList MeasObjectToAddModList OPTIONAL, -- Need ON
- -- Reporting configurations
- reportConfigToRemoveList ReportConfigToRemoveList OPTIONAL, -- Need ON
- reportConfigToAddModList ReportConfigToAddModList OPTIONAL, -- Need ON
- -- Measurement identities
- measIdToRemoveList MeasIdToRemoveList OPTIONAL, -- Need ON
- measIdToAddModList MeasIdToAddModList OPTIONAL, -- Need ON
- -- Other parameters
- quantityConfig QuantityConfig OPTIONAL, -- Need ON
- measGapConfig MeasGapConfig OPTIONAL, -- Need ON
- s-Measure RSRP-Range OPTIONAL, -- Need ON
- preRegistrationInfoHRPD PreRegistrationInfoHRPD OPTIONAL, -- Need OP
- speedStatePars CHOICE {
- release NULL,
- setup SEQUENCE {
- mobilityStateParameters MobilityStateParameters,
- timeToTrigger-SF SpeedStateScaleFactors
- }
- } OPTIONAL, -- Need ON
- ...
-}
-
-MeasIdToRemoveList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasId
-
-MeasObjectToRemoveList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectId
-
-ReportConfigToRemoveList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigId
-
-
-MeasGapConfig ::= CHOICE {
- release NULL,
- setup SEQUENCE {
- gapOffset CHOICE {
- gp0 INTEGER (0..39),
- gp1 INTEGER (0..79),
- ...
- }
- }
-}
-
-
-MeasId ::= INTEGER (1..maxMeasId)
-
-
-MeasIdToAddModList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddMod
-
-MeasIdToAddMod ::= SEQUENCE {
- measId MeasId,
- measObjectId MeasObjectId,
- reportConfigId ReportConfigId
-}
-
-
-MeasObjectCDMA2000 ::= SEQUENCE {
- cdma2000-Type CDMA2000-Type,
- carrierFreq CarrierFreqCDMA2000,
- searchWindowSize INTEGER (0..15) OPTIONAL, -- Need ON
- offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
- cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
- cellsToAddModList CellsToAddModListCDMA2000 OPTIONAL, -- Need ON
- cellForWhichToReportCGI PhysCellIdCDMA2000 OPTIONAL, -- Need ON
- ...
-}
-
-CellsToAddModListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModCDMA2000
-
-CellsToAddModCDMA2000 ::= SEQUENCE {
- cellIndex INTEGER (1..maxCellMeas),
- physCellId PhysCellIdCDMA2000
-}
-
-
-MeasObjectEUTRA ::= SEQUENCE {
- carrierFreq ARFCN-ValueEUTRA,
- allowedMeasBandwidth AllowedMeasBandwidth,
- presenceAntennaPort1 PresenceAntennaPort1,
- neighCellConfig NeighCellConfig,
- offsetFreq Q-OffsetRange DEFAULT dB0,
- -- Neighbour cell list
- cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
- cellsToAddModList CellsToAddModList OPTIONAL, -- Need ON
- -- Black list
- blackCellsToRemoveList CellIndexList OPTIONAL, -- Need ON
- blackCellsToAddModList BlackCellsToAddModList OPTIONAL, -- Need ON
- cellForWhichToReportCGI PhysCellId OPTIONAL, -- Need ON
- ...
-}
-
-CellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddMod
-
-CellsToAddMod ::= SEQUENCE {
- cellIndex INTEGER (1..maxCellMeas),
- physCellId PhysCellId,
- cellIndividualOffset Q-OffsetRange
-}
-
-BlackCellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF BlackCellsToAddMod
-
-BlackCellsToAddMod ::= SEQUENCE {
- cellIndex INTEGER (1..maxCellMeas),
- physCellIdRange PhysCellIdRange
-}
-
-
-MeasObjectGERAN ::= SEQUENCE {
- carrierFreqs CarrierFreqsGERAN,
- offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
- ncc-Permitted BIT STRING(SIZE (8)) DEFAULT '11111111'B,
- cellForWhichToReportCGI PhysCellIdGERAN OPTIONAL, -- Need ON
- ...
-}
-
-
-MeasObjectId ::= INTEGER (1..maxObjectId)
-
-
-MeasObjectToAddModList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectToAddMod
-
-MeasObjectToAddMod ::= SEQUENCE {
- measObjectId MeasObjectId,
- measObject CHOICE {
- measObjectEUTRA MeasObjectEUTRA,
- measObjectUTRA MeasObjectUTRA,
- measObjectGERAN MeasObjectGERAN,
- measObjectCDMA2000 MeasObjectCDMA2000,
- ...
- }
-}
-
-
-MeasObjectUTRA ::= SEQUENCE {
- carrierFreq ARFCN-ValueUTRA,
- offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
- cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
- cellsToAddModList CHOICE {
- cellsToAddModListUTRA-FDD CellsToAddModListUTRA-FDD,
- cellsToAddModListUTRA-TDD CellsToAddModListUTRA-TDD
- } OPTIONAL, -- Need ON
- cellForWhichToReportCGI CHOICE {
- utra-FDD PhysCellIdUTRA-FDD,
- utra-TDD PhysCellIdUTRA-TDD
- } OPTIONAL, -- Need ON
- ...
-}
-
-CellsToAddModListUTRA-FDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-FDD
-
-CellsToAddModUTRA-FDD ::= SEQUENCE {
- cellIndex INTEGER (1..maxCellMeas),
- physCellId PhysCellIdUTRA-FDD
-}
-
-CellsToAddModListUTRA-TDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-TDD
-
-CellsToAddModUTRA-TDD ::= SEQUENCE {
- cellIndex INTEGER (1..maxCellMeas),
- physCellId PhysCellIdUTRA-TDD
-}
-
-
-MeasResults ::= SEQUENCE {
- measId MeasId,
- measResultServCell SEQUENCE {
- rsrpResult RSRP-Range,
- rsrqResult RSRQ-Range
- },
- measResultNeighCells CHOICE {
- measResultListEUTRA MeasResultListEUTRA,
- measResultListUTRA MeasResultListUTRA,
- measResultListGERAN MeasResultListGERAN,
- measResultsCDMA2000 MeasResultsCDMA2000,
- ...
- } OPTIONAL,
- ...
-}
-
-MeasResultListEUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultEUTRA
-
-MeasResultEUTRA ::= SEQUENCE {
- physCellId PhysCellId,
- cgi-Info SEQUENCE {
- cellGlobalId CellGlobalIdEUTRA,
- trackingAreaCode TrackingAreaCode,
- plmn-IdentityList PLMN-IdentityList2 OPTIONAL
- } OPTIONAL,
- measResult SEQUENCE {
- rsrpResult RSRP-Range OPTIONAL,
- rsrqResult RSRQ-Range OPTIONAL,
- ...
- }
-}
-
-MeasResultListUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultUTRA
-
-MeasResultUTRA ::= SEQUENCE {
- physCellId CHOICE {
- fdd PhysCellIdUTRA-FDD,
- tdd PhysCellIdUTRA-TDD
- },
- cgi-Info SEQUENCE {
- cellGlobalId CellGlobalIdUTRA,
- locationAreaCode BIT STRING (SIZE (16)) OPTIONAL,
- routingAreaCode BIT STRING (SIZE (8)) OPTIONAL,
- plmn-IdentityList PLMN-IdentityList2 OPTIONAL
- } OPTIONAL,
- measResult SEQUENCE {
- utra-RSCP INTEGER (-5..91) OPTIONAL,
- utra-EcN0 INTEGER (0..49) OPTIONAL,
- ...
- }
-}
-
-MeasResultListGERAN ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultGERAN
-
-MeasResultGERAN ::= SEQUENCE {
- carrierFreq CarrierFreqGERAN,
- physCellId PhysCellIdGERAN,
- cgi-Info SEQUENCE {
- cellGlobalId CellGlobalIdGERAN,
- routingAreaCode BIT STRING (SIZE (8)) OPTIONAL
- } OPTIONAL,
- measResult SEQUENCE {
- rssi INTEGER (0..63),
- ...
- }
-}
-
-MeasResultsCDMA2000 ::= SEQUENCE {
- preRegistrationStatusHRPD BOOLEAN,
- measResultListCDMA2000 MeasResultListCDMA2000
-}
-
-MeasResultListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultCDMA2000
-
-MeasResultCDMA2000 ::= SEQUENCE {
- physCellId PhysCellIdCDMA2000,
- cgi-Info CellGlobalIdCDMA2000 OPTIONAL,
- measResult SEQUENCE {
- pilotPnPhase INTEGER (0..32767) OPTIONAL,
- pilotStrength INTEGER (0..63),
- ...
- }
-}
-
-PLMN-IdentityList2 ::= SEQUENCE (SIZE (1..5)) OF PLMN-Identity
-
-
-QuantityConfig ::= SEQUENCE {
- quantityConfigEUTRA QuantityConfigEUTRA OPTIONAL, -- Need ON
- quantityConfigUTRA QuantityConfigUTRA OPTIONAL, -- Need ON
- quantityConfigGERAN QuantityConfigGERAN OPTIONAL, -- Need ON
- quantityConfigCDMA2000 QuantityConfigCDMA2000 OPTIONAL, -- Need ON
- ...
-}
-
-QuantityConfigEUTRA ::= SEQUENCE {
- filterCoefficientRSRP FilterCoefficient DEFAULT fc4,
- filterCoefficientRSRQ FilterCoefficient DEFAULT fc4
-}
-
-QuantityConfigUTRA ::= SEQUENCE {
- measQuantityUTRA-FDD ENUMERATED {cpich-RSCP, cpich-EcN0},
- measQuantityUTRA-TDD ENUMERATED {pccpch-RSCP},
- filterCoefficient FilterCoefficient DEFAULT fc4
-}
-
-QuantityConfigGERAN ::= SEQUENCE {
- measQuantityGERAN ENUMERATED {rssi},
- filterCoefficient FilterCoefficient DEFAULT fc2
-}
-
-QuantityConfigCDMA2000 ::= SEQUENCE {
- measQuantityCDMA2000 ENUMERATED {pilotStrength, pilotPnPhaseAndPilotStrength}
-}
-
-
-ReportConfigEUTRA ::= SEQUENCE {
- triggerType CHOICE {
- event SEQUENCE {
- eventId CHOICE {
- eventA1 SEQUENCE {
- a1-Threshold ThresholdEUTRA
- },
- eventA2 SEQUENCE {
- a2-Threshold ThresholdEUTRA
- },
- eventA3 SEQUENCE {
- a3-Offset INTEGER (-30..30),
- reportOnLeave BOOLEAN
- },
- eventA4 SEQUENCE {
- a4-Threshold ThresholdEUTRA
- },
- eventA5 SEQUENCE {
- a5-Threshold1 ThresholdEUTRA,
- a5-Threshold2 ThresholdEUTRA
- },
- ...
- },
- hysteresis Hysteresis,
- timeToTrigger TimeToTrigger
- },
- periodical SEQUENCE {
- purpose ENUMERATED {
- reportStrongestCells, reportCGI}
- }
- },
- triggerQuantity ENUMERATED {rsrp, rsrq},
- reportQuantity ENUMERATED {sameAsTriggerQuantity, both},
- maxReportCells INTEGER (1..maxCellReport),
- reportInterval ReportInterval,
- reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity},
- ...
-}
-
-ThresholdEUTRA ::= CHOICE{
- threshold-RSRP RSRP-Range,
- threshold-RSRQ RSRQ-Range
-}
-
-
-ReportConfigId ::= INTEGER (1..maxReportConfigId)
-
-
-ReportConfigInterRAT ::= SEQUENCE {
- triggerType CHOICE {
- event SEQUENCE {
- eventId CHOICE {
- eventB1 SEQUENCE {
- b1-Threshold CHOICE {
- b1-ThresholdUTRA ThresholdUTRA,
- b1-ThresholdGERAN ThresholdGERAN,
- b1-ThresholdCDMA2000 ThresholdCDMA2000
- }
- },
- eventB2 SEQUENCE {
- b2-Threshold1 ThresholdEUTRA,
- b2-Threshold2 CHOICE {
- b2-Threshold2UTRA ThresholdUTRA,
- b2-Threshold2GERAN ThresholdGERAN,
- b2-Threshold2CDMA2000 ThresholdCDMA2000
- }
- },
- ...
- },
- hysteresis Hysteresis,
- timeToTrigger TimeToTrigger
- },
- periodical SEQUENCE {
- purpose ENUMERATED {
- reportStrongestCells,
- reportStrongestCellsForSON,
- reportCGI}
- }
- },
- maxReportCells INTEGER (1..maxCellReport),
- reportInterval ReportInterval,
- reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity},
- ...
-}
-
-ThresholdUTRA ::= CHOICE{
- utra-RSCP INTEGER (-5..91),
- utra-EcN0 INTEGER (0..49)
-}
-
-ThresholdGERAN ::= INTEGER (0..63)
-
-ThresholdCDMA2000 ::= INTEGER (0..63)
-
-
-ReportConfigToAddModList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigToAddMod
-
-ReportConfigToAddMod ::= SEQUENCE {
- reportConfigId ReportConfigId,
- reportConfig CHOICE {
- reportConfigEUTRA ReportConfigEUTRA,
- reportConfigInterRAT ReportConfigInterRAT
- }
-}
-
-
-
-ReportInterval ::= ENUMERATED {
- ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240,
- min1, min6, min12, min30, min60, spare3, spare2, spare1}
-
-
-RSRP-Range ::= INTEGER(0..97)
-
-
-RSRQ-Range ::= INTEGER(0..34)
-
-
-TimeToTrigger ::= ENUMERATED {
- ms0, ms40, ms64, ms80, ms100, ms128, ms160, ms256,
- ms320, ms480, ms512, ms640, ms1024, ms1280, ms2560,
- ms5120}
-
-
-C-RNTI ::= BIT STRING (SIZE (16))
-
-
-DedicatedInfoCDMA2000 ::= OCTET STRING
-
-
-DedicatedInfoNAS ::= OCTET STRING
-
-
-FilterCoefficient ::= ENUMERATED {
- fc0, fc1, fc2, fc3, fc4, fc5,
- fc6, fc7, fc8, fc9, fc11, fc13,
- fc15, fc17, fc19, spare1, ...}
-
-
-MMEC ::= BIT STRING (SIZE (8))
-
-
-NeighCellConfig ::= BIT STRING (SIZE (2))
-
-
-RAND-CDMA2000 ::= BIT STRING (SIZE (32))
-
-
-RAT-Type ::= ENUMERATED {
- eutra, utra, geran-cs, geran-ps, cdma2000-1XRTT,
- spare3, spare2, spare1, ...}
-
-
-RRC-TransactionIdentifier ::= INTEGER (0..3)
-
-
-S-TMSI ::= SEQUENCE {
- mmec MMEC,
- m-TMSI BIT STRING (SIZE (32))
-}
-
-
-UE-CapabilityRAT-ContainerList ::=SEQUENCE (SIZE (0..maxRAT-Capabilities)) OF UE-CapabilityRAT-Container
-
-UE-CapabilityRAT-Container ::= SEQUENCE {
- rat-Type RAT-Type,
- ueCapabilityRAT-Container OCTET STRING
-}
-
-
-UE-EUTRA-Capability ::= SEQUENCE {
- accessStratumRelease AccessStratumRelease,
- ue-Category INTEGER (1..5),
- pdcp-Parameters PDCP-Parameters,
- phyLayerParameters PhyLayerParameters,
- rf-Parameters RF-Parameters,
- measParameters MeasParameters,
- featureGroupIndicators BIT STRING (SIZE (32)) OPTIONAL,
- interRAT-Parameters SEQUENCE {
- utraFDD IRAT-ParametersUTRA-FDD OPTIONAL,
- utraTDD128 IRAT-ParametersUTRA-TDD128 OPTIONAL,
- utraTDD384 IRAT-ParametersUTRA-TDD384 OPTIONAL,
- utraTDD768 IRAT-ParametersUTRA-TDD768 OPTIONAL,
- geran IRAT-ParametersGERAN OPTIONAL,
- cdma2000-HRPD IRAT-ParametersCDMA2000-HRPD OPTIONAL,
- cdma2000-1xRTT IRAT-ParametersCDMA2000-1XRTT OPTIONAL
- },
- nonCriticalExtension SEQUENCE {} OPTIONAL
-}
-
-AccessStratumRelease ::= ENUMERATED {
- rel8, spare7, spare6, spare5, spare4, spare3,
- spare2, spare1, ...}
-
-PDCP-Parameters ::= SEQUENCE {
- supportedROHC-Profiles SEQUENCE {
- profile0x0001 BOOLEAN,
- profile0x0002 BOOLEAN,
- profile0x0003 BOOLEAN,
- profile0x0004 BOOLEAN,
- profile0x0006 BOOLEAN,
- profile0x0101 BOOLEAN,
- profile0x0102 BOOLEAN,
- profile0x0103 BOOLEAN,
- profile0x0104 BOOLEAN
- },
- maxNumberROHC-ContextSessions ENUMERATED {
- cs2, cs4, cs8, cs12, cs16, cs24, cs32,
- cs48, cs64, cs128, cs256, cs512, cs1024,
- cs16384, spare2, spare1} DEFAULT cs16,
- ...
-}
-
-PhyLayerParameters ::= SEQUENCE {
- ue-TxAntennaSelectionSupported BOOLEAN,
- ue-SpecificRefSigsSupported BOOLEAN
-}
-
-RF-Parameters ::= SEQUENCE {
- supportedBandListEUTRA SupportedBandListEUTRA
-}
-
-SupportedBandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA
-
-SupportedBandEUTRA ::= SEQUENCE {
- bandEUTRA INTEGER (1..64),
- halfDuplex BOOLEAN
-}
-
-MeasParameters ::= SEQUENCE {
- bandListEUTRA BandListEUTRA
-}
-
-BandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF BandInfoEUTRA
-
-BandInfoEUTRA ::= SEQUENCE {
- interFreqBandList InterFreqBandList,
- interRAT-BandList InterRAT-BandList OPTIONAL
-}
-
-InterFreqBandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterFreqBandInfo
-
-InterFreqBandInfo ::= SEQUENCE {
- interFreqNeedForGaps BOOLEAN
-}
-
-InterRAT-BandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterRAT-BandInfo
-
-InterRAT-BandInfo ::= SEQUENCE {
- interRAT-NeedForGaps BOOLEAN
-}
-
-IRAT-ParametersUTRA-FDD ::= SEQUENCE {
- supportedBandListUTRA-FDD SupportedBandListUTRA-FDD
-}
-
-SupportedBandListUTRA-FDD ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-FDD
-
-SupportedBandUTRA-FDD ::= ENUMERATED {
- bandI, bandII, bandIII, bandIV, bandV, bandVI,
- bandVII, bandVIII, bandIX, bandX, bandXI,
- bandXII, bandXIII, bandXIV, bandXV, bandXVI, ...}
-
-IRAT-ParametersUTRA-TDD128 ::= SEQUENCE {
- supportedBandListUTRA-TDD128 SupportedBandListUTRA-TDD128
-}
-
-SupportedBandListUTRA-TDD128 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD128
-
-SupportedBandUTRA-TDD128 ::= ENUMERATED {
- a, b, c, d, e, f, g, h, i, j, k, l, m, n,
- o, p, ...}
-
-IRAT-ParametersUTRA-TDD384 ::= SEQUENCE {
- supportedBandListUTRA-TDD384 SupportedBandListUTRA-TDD384
-}
-
-SupportedBandListUTRA-TDD384 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD384
-
-SupportedBandUTRA-TDD384 ::= ENUMERATED {
- a, b, c, d, e, f, g, h, i, j, k, l, m, n,
- o, p, ...}
-
-IRAT-ParametersUTRA-TDD768 ::= SEQUENCE {
- supportedBandListUTRA-TDD768 SupportedBandListUTRA-TDD768
-}
-
-SupportedBandListUTRA-TDD768 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD768
-
-SupportedBandUTRA-TDD768 ::= ENUMERATED {
- a, b, c, d, e, f, g, h, i, j, k, l, m, n,
- o, p, ...}
-
-IRAT-ParametersGERAN ::= SEQUENCE {
- supportedBandListGERAN SupportedBandListGERAN,
- interRAT-PS-HO-ToGERAN BOOLEAN
-}
-
-SupportedBandListGERAN ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandGERAN
-
-SupportedBandGERAN ::= ENUMERATED {
- gsm450, gsm480, gsm710, gsm750, gsm810, gsm850,
- gsm900P, gsm900E, gsm900R, gsm1800, gsm1900,
- spare5, spare4, spare3, spare2, spare1, ...}
-
-IRAT-ParametersCDMA2000-HRPD ::= SEQUENCE {
- supportedBandListHRPD SupportedBandListHRPD,
- tx-ConfigHRPD ENUMERATED {single, dual},
- rx-ConfigHRPD ENUMERATED {single, dual}
-}
-
-SupportedBandListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000
-
-IRAT-ParametersCDMA2000-1XRTT ::= SEQUENCE {
- supportedBandList1XRTT SupportedBandList1XRTT,
- tx-Config1XRTT ENUMERATED {single, dual},
- rx-Config1XRTT ENUMERATED {single, dual}
-}
-
-SupportedBandList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000
-
-
-UE-TimersAndConstants ::= SEQUENCE {
- t300 ENUMERATED {
- ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
- ms2000},
- t301 ENUMERATED {
- ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
- ms2000},
- t310 ENUMERATED {
- ms0, ms50, ms100, ms200, ms500, ms1000, ms2000},
- n310 ENUMERATED {
- n1, n2, n3, n4, n6, n8, n10, n20},
- t311 ENUMERATED {
- ms1000, ms3000, ms5000, ms10000, ms15000,
- ms20000, ms30000},
- n311 ENUMERATED {
- n1, n2, n3, n4, n5, n6, n8, n10},
- ...
-}
-
-
-maxBands INTEGER ::= 64 -- Maximum number of bands listed in EUTRA UE caps
-maxCDMA-BandClass INTEGER ::= 32 -- Maximum value of the CDMA band classes
-maxCellBlack INTEGER ::= 16 -- Maximum number of blacklisted cells
- -- listed in SIB type 4 and 5
-maxCellInter INTEGER ::= 16 -- Maximum number of neighbouring inter-frequency
- -- cells listed in SIB type 5
-maxCellIntra INTEGER ::= 16 -- Maximum number of neighbouring intra-frequency
- -- cells listed in SIB type 4
-maxCellMeas INTEGER ::= 32 -- Maximum number of entries in each of the neighbour
- -- cell lists in a measurement object
-maxCellReport INTEGER ::= 8 -- Maximum number of reported cells
-maxDRB INTEGER ::= 11 -- Maximum number of Data Radio Bearers
-maxEARFCN INTEGER ::= 65535 -- Maximum value of EUTRA carrier fequency
-maxFreq INTEGER ::= 8 -- Maximum number of EUTRA carrier frequencies
-maxGERAN-SI INTEGER ::= 10 -- Maximum number of GERAN SI blocks that can be
- -- provided as part of NACC information
-maxGNFG INTEGER ::= 16 -- Maximum number of GERAN neighbour freq groups
-maxMBSFN-Allocations INTEGER ::= 8 -- Maximum number of MBSFN frame allocations with
- -- different offset
-maxMCS-1 INTEGER ::= 16 -- Maximum number of PUCCH formats (MCS)
-maxMeasId INTEGER ::= 32
-maxObjectId INTEGER ::= 32
-maxPageRec INTEGER ::= 16 --
-maxPNOffset INTEGER ::= 511 -- Maximum number of CDMA2000 PNOffsets
-maxRAT-Capabilities INTEGER ::= 8 -- Maximum number of interworking RATs (incl EUTRA)
-maxReportConfigId INTEGER ::= 32
-maxSIB INTEGER ::= 32 -- Maximum number of SIBs
-maxSIB-1 INTEGER ::= 31
-maxSI-Message INTEGER ::= 32 -- Maximum number of SI messages
-maxUTRA-FDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA FDD carrier frequencies
-maxUTRA-TDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA TDD carrier frequencies
-
-
-END
+-- 3GPP TS 36.331 v9.2.0
+-- http://cdmweb.ericsson.se/TeamCenter/controller/ViewDocs?DocumentName=51%2F15519-10%2FFCP1039669%2F11&Revision=A
+
+EUTRA-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+
+BCCH-BCH-Message ::= SEQUENCE {
+ message BCCH-BCH-MessageType
+}
+
+BCCH-BCH-MessageType ::= MasterInformationBlock
+
+
+BCCH-DL-SCH-Message ::= SEQUENCE {
+ message BCCH-DL-SCH-MessageType
+}
+
+BCCH-DL-SCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ systemInformation SystemInformation,
+ systemInformationBlockType1 SystemInformationBlockType1
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+MCCH-Message ::= SEQUENCE {
+ message MCCH-MessageType
+}
+
+MCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ mbsfnAreaConfiguration-r9 MBSFNAreaConfiguration-r9
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+PCCH-Message ::= SEQUENCE {
+ message PCCH-MessageType
+}
+
+PCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ paging Paging
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+DL-CCCH-Message ::= SEQUENCE {
+ message DL-CCCH-MessageType
+}
+
+DL-CCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ rrcConnectionReestablishment RRCConnectionReestablishment,
+ rrcConnectionReestablishmentReject RRCConnectionReestablishmentReject,
+ rrcConnectionReject RRCConnectionReject,
+ rrcConnectionSetup RRCConnectionSetup
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+DL-DCCH-Message ::= SEQUENCE {
+ message DL-DCCH-MessageType
+}
+
+DL-DCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ csfbParametersResponseCDMA2000 CSFBParametersResponseCDMA2000,
+ dlInformationTransfer DLInformationTransfer,
+ handoverFromEUTRAPreparationRequest HandoverFromEUTRAPreparationRequest,
+ mobilityFromEUTRACommand MobilityFromEUTRACommand,
+ rrcConnectionReconfiguration RRCConnectionReconfiguration,
+ rrcConnectionRelease RRCConnectionRelease,
+ securityModeCommand SecurityModeCommand,
+ ueCapabilityEnquiry UECapabilityEnquiry,
+ counterCheck CounterCheck,
+ ueInformationRequest-r9 UEInformationRequest-r9,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+UL-CCCH-Message ::= SEQUENCE {
+ message UL-CCCH-MessageType
+}
+
+UL-CCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ rrcConnectionReestablishmentRequest RRCConnectionReestablishmentRequest,
+ rrcConnectionRequest RRCConnectionRequest
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+UL-DCCH-Message ::= SEQUENCE {
+ message UL-DCCH-MessageType
+}
+
+UL-DCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ csfbParametersRequestCDMA2000 CSFBParametersRequestCDMA2000,
+ measurementReport MeasurementReport,
+ rrcConnectionReconfigurationComplete RRCConnectionReconfigurationComplete,
+ rrcConnectionReestablishmentComplete RRCConnectionReestablishmentComplete,
+ rrcConnectionSetupComplete RRCConnectionSetupComplete,
+ securityModeComplete SecurityModeComplete,
+ securityModeFailure SecurityModeFailure,
+ ueCapabilityInformation UECapabilityInformation,
+ulHandoverPreparationTransfer ULHandoverPreparationTransfer,
+ ulInformationTransfer ULInformationTransfer,
+ counterCheckResponse CounterCheckResponse,
+ ueInformationResponse-r9 UEInformationResponse-r9,
+ proximityIndication-r9 ProximityIndication-r9,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+CounterCheck ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ counterCheck-r8 CounterCheck-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CounterCheck-r8-IEs ::= SEQUENCE {
+ drb-CountMSB-InfoList DRB-CountMSB-InfoList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+DRB-CountMSB-InfoList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-CountMSB-Info
+
+DRB-CountMSB-Info ::= SEQUENCE {
+ drb-Identity DRB-Identity,
+ countMSB-Uplink INTEGER(0..33554431),
+ countMSB-Downlink INTEGER(0..33554431)
+}
+
+
+CounterCheckResponse ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ counterCheckResponse-r8 CounterCheckResponse-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CounterCheckResponse-r8-IEs ::= SEQUENCE {
+ drb-CountInfoList DRB-CountInfoList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+DRB-CountInfoList ::= SEQUENCE (SIZE (0..maxDRB)) OF DRB-CountInfo
+
+DRB-CountInfo ::= SEQUENCE {
+ drb-Identity DRB-Identity,
+ count-Uplink INTEGER(0..4294967295),
+ count-Downlink INTEGER(0..4294967295)
+}
+
+
+CSFBParametersRequestCDMA2000 ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ csfbParametersRequestCDMA2000-r8 CSFBParametersRequestCDMA2000-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CSFBParametersRequestCDMA2000-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+CSFBParametersResponseCDMA2000 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ csfbParametersResponseCDMA2000-r8 CSFBParametersResponseCDMA2000-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CSFBParametersResponseCDMA2000-r8-IEs ::= SEQUENCE {
+ rand RAND-CDMA2000,
+ mobilityParameters MobilityParametersCDMA2000,
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+
+DLInformationTransfer ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ dlInformationTransfer-r8 DLInformationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+DLInformationTransfer-r8-IEs ::= SEQUENCE {
+ dedicatedInfoType CHOICE {
+ dedicatedInfoNAS DedicatedInfoNAS,
+ dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000,
+ dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+
+HandoverFromEUTRAPreparationRequest ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ handoverFromEUTRAPreparationRequest-r8
+ HandoverFromEUTRAPreparationRequest-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+HandoverFromEUTRAPreparationRequest-r8-IEs ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ rand RAND-CDMA2000 OPTIONAL, -- Cond cdma2000-Type
+ mobilityParameters MobilityParametersCDMA2000 OPTIONAL, -- Cond cdma2000-Type
+ nonCriticalExtension HandoverFromEUTRAPreparationRequest-v890-IEs OPTIONAL
+}
+
+HandoverFromEUTRAPreparationRequest-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension HandoverFromEUTRAPreparationRequest-v920-IEs OPTIONAL
+}
+
+HandoverFromEUTRAPreparationRequest-v920-IEs ::= SEQUENCE {
+ concurrPrepCDMA2000-HRPD-r9 BOOLEAN OPTIONAL, -- Cond PSHO
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+MasterInformationBlock ::= SEQUENCE {
+ dl-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100},
+ phich-Config PHICH-Config,
+ systemFrameNumber BIT STRING (SIZE (8)),
+ spare BIT STRING (SIZE (10))
+}
+
+
+
+MBSFNAreaConfiguration-r9 ::= SEQUENCE {
+ commonSF-Alloc-r9 CommonSF-AllocPatternList-r9,
+ commonSF-AllocPeriod-r9 ENUMERATED {
+ rf4, rf8, rf16, rf32, rf64, rf128, rf256},
+ pmch-InfoList-r9 PMCH-InfoList-r9,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+CommonSF-AllocPatternList-r9 ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig
+
+
+MeasurementReport ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ measurementReport-r8 MeasurementReport-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+MeasurementReport-r8-IEs ::= SEQUENCE {
+ measResults MeasResults,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+MobilityFromEUTRACommand ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ mobilityFromEUTRACommand-r8 MobilityFromEUTRACommand-r8-IEs,
+ mobilityFromEUTRACommand-r9 MobilityFromEUTRACommand-r9-IEs,
+ spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+MobilityFromEUTRACommand-r8-IEs ::= SEQUENCE {
+ cs-FallbackIndicator BOOLEAN,
+ purpose CHOICE{
+ handover Handover,
+ cellChangeOrder CellChangeOrder
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+MobilityFromEUTRACommand-r9-IEs ::= SEQUENCE {
+ cs-FallbackIndicator BOOLEAN,
+ purpose CHOICE{
+ handover Handover,
+ cellChangeOrder CellChangeOrder,
+ e-CSFB-r9 E-CSFB-r9,
+ ...
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+Handover ::= SEQUENCE {
+ targetRAT-Type ENUMERATED {
+ utra, geran, cdma2000-1XRTT, cdma2000-HRPD,
+ spare4, spare3, spare2, spare1, ...},
+ targetRAT-MessageContainer OCTET STRING,
+ nas-SecurityParamFromEUTRA OCTET STRING (SIZE (1)) OPTIONAL, -- Cond UTRAGERAN
+ systemInformation SI-OrPSI-GERAN OPTIONAL -- Cond PSHO
+}
+
+CellChangeOrder ::= SEQUENCE {
+ t304 ENUMERATED {
+ ms100, ms200, ms500, ms1000,
+ ms2000, ms4000, ms8000, spare1},
+ targetRAT-Type CHOICE {
+ geran SEQUENCE {
+ physCellId PhysCellIdGERAN,
+ carrierFreq CarrierFreqGERAN,
+ networkControlOrder BIT STRING (SIZE (2)) OPTIONAL, -- Need OP
+ systemInformation SI-OrPSI-GERAN OPTIONAL -- Need OP
+ },
+ ...
+ }
+}
+
+SI-OrPSI-GERAN ::= CHOICE {
+ si SystemInfoListGERAN,
+ psi SystemInfoListGERAN
+}
+
+E-CSFB-r9 ::= SEQUENCE {
+ messageContCDMA2000-1XRTT-r9 OCTET STRING OPTIONAL, -- Need ON
+ mobilityCDMA2000-HRPD-r9 ENUMERATED {
+ handover, redirection
+ } OPTIONAL, -- Need OP
+ messageContCDMA2000-HRPD-r9 OCTET STRING OPTIONAL, -- Cond concHO
+ redirectCarrierCDMA2000-HRPD-r9 CarrierFreqCDMA2000 OPTIONAL -- Cond concRedir
+}
+
+
+Paging ::= SEQUENCE {
+ pagingRecordList PagingRecordList OPTIONAL, -- Need ON
+ systemInfoModification ENUMERATED {true} OPTIONAL, -- Need ON
+ etws-Indication ENUMERATED {true} OPTIONAL, -- Need ON
+ nonCriticalExtension Paging-v890-IEs OPTIONAL
+}
+
+Paging-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension Paging-v920-IEs OPTIONAL
+}
+
+Paging-v920-IEs ::= SEQUENCE {
+ cmas-Indication-r9 ENUMERATED {true} OPTIONAL, -- Need ON
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+PagingRecordList ::= SEQUENCE (SIZE (1..maxPageRec)) OF PagingRecord
+
+PagingRecord ::= SEQUENCE {
+ ue-Identity PagingUE-Identity,
+ cn-Domain ENUMERATED {ps, cs},
+ ...
+}
+
+PagingUE-Identity ::= CHOICE {
+ s-TMSI S-TMSI,
+ imsi IMSI,
+ ...
+}
+
+IMSI ::= SEQUENCE (SIZE (6..21)) OF IMSI-Digit
+
+IMSI-Digit ::= INTEGER (0..9)
+
+
+ProximityIndication-r9 ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ proximityIndication-r9 ProximityIndication-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ProximityIndication-r9-IEs ::= SEQUENCE {
+ type-r9 ENUMERATED {entering, leaving},
+ carrierFreq-r9 CHOICE {
+ eutra-r9 ARFCN-ValueEUTRA,
+ utra-r9 ARFCN-ValueUTRA,
+ ...
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReconfiguration ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionReconfiguration-r8 RRCConnectionReconfiguration-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReconfiguration-r8-IEs ::= SEQUENCE {
+ measConfig MeasConfig OPTIONAL, -- Need ON
+ mobilityControlInfo MobilityControlInfo OPTIONAL, -- Cond HO
+ dedicatedInfoNASList SEQUENCE (SIZE(1..maxDRB)) OF
+ DedicatedInfoNAS OPTIONAL, -- Cond nonHO
+ radioResourceConfigDedicated RadioResourceConfigDedicated OPTIONAL, -- Cond HO-toEUTRA
+ securityConfigHO SecurityConfigHO OPTIONAL, -- Cond HO
+ nonCriticalExtension RRCConnectionReconfiguration-v890-IEs OPTIONAL
+}
+
+RRCConnectionReconfiguration-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionReconfiguration-v920-IEs OPTIONAL
+}
+
+RRCConnectionReconfiguration-v920-IEs ::= SEQUENCE {
+ otherConfig-r9 OtherConfig-r9 OPTIONAL, -- Need ON
+ fullConfig-r9 ENUMERATED {true} OPTIONAL, -- Cond HO-Reestab
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+SecurityConfigHO ::= SEQUENCE {
+ handoverType CHOICE {
+ intraLTE SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig OPTIONAL, -- Cond fullConfig
+ keyChangeIndicator BOOLEAN,
+ nextHopChainingCount NextHopChainingCount
+ },
+ interRAT SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig,
+ nas-SecurityParamToEUTRA OCTET STRING (SIZE(6))
+ }
+ },
+ ...
+}
+
+
+
+RRCConnectionReconfigurationComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ rrcConnectionReconfigurationComplete-r8
+ RRCConnectionReconfigurationComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReconfigurationComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReestablishment ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionReestablishment-r8 RRCConnectionReestablishment-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishment-r8-IEs ::= SEQUENCE {
+ radioResourceConfigDedicated RadioResourceConfigDedicated,
+ nextHopChainingCount NextHopChainingCount,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionReestablishmentComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentComplete-r8
+ RRCConnectionReestablishmentComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension RRCConnectionReestablishmentComplete-v920-IEs OPTIONAL
+}
+
+RRCConnectionReestablishmentComplete-v920-IEs ::= SEQUENCE {
+ rlf-InfoAvailable-r9 ENUMERATED {true} OPTIONAL,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReestablishmentReject ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentReject-r8
+ RRCConnectionReestablishmentReject-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentReject-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionReestablishmentRequest ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentRequest-r8
+ RRCConnectionReestablishmentRequest-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentRequest-r8-IEs ::= SEQUENCE {
+ ue-Identity ReestabUE-Identity,
+ reestablishmentCause ReestablishmentCause,
+ spare BIT STRING (SIZE (2))
+}
+
+ReestabUE-Identity ::= SEQUENCE {
+ c-RNTI C-RNTI,
+ physCellId PhysCellId,
+ shortMAC-I ShortMAC-I
+}
+
+ReestablishmentCause ::= ENUMERATED {
+ reconfigurationFailure, handoverFailure,
+ otherFailure, spare1}
+
+
+RRCConnectionReject ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionReject-r8 RRCConnectionReject-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReject-r8-IEs ::= SEQUENCE {
+ waitTime INTEGER (1..16),
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionRelease ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionRelease-r8 RRCConnectionRelease-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionRelease-r8-IEs ::= SEQUENCE {
+ releaseCause ReleaseCause,
+ redirectedCarrierInfo RedirectedCarrierInfo OPTIONAL, -- Need ON
+ idleModeMobilityControlInfo IdleModeMobilityControlInfo OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionRelease-v890-IEs OPTIONAL
+}
+
+RRCConnectionRelease-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionRelease-v920-IEs OPTIONAL
+}
+
+RRCConnectionRelease-v920-IEs ::= SEQUENCE {
+ cellInfoList-r9 CHOICE {
+ geran-r9 CellInfoListGERAN-r9,
+ utra-FDD-r9 CellInfoListUTRA-FDD-r9,
+ utra-TDD-r9 CellInfoListUTRA-TDD-r9,
+ ...
+ } OPTIONAL, -- Cond Redirection
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+ReleaseCause ::= ENUMERATED {loadBalancingTAUrequired,
+ other,spare2,spare1}
+
+RedirectedCarrierInfo ::= CHOICE {
+ eutra ARFCN-ValueEUTRA,
+ geran CarrierFreqsGERAN,
+ utra-FDD ARFCN-ValueUTRA,
+ utra-TDD ARFCN-ValueUTRA,
+ cdma2000-HRPD CarrierFreqCDMA2000,
+ cdma2000-1xRTT CarrierFreqCDMA2000,
+ ...
+}
+
+IdleModeMobilityControlInfo ::= SEQUENCE {
+ freqPriorityListEUTRA FreqPriorityListEUTRA OPTIONAL, -- Need ON
+ freqPriorityListGERAN FreqsPriorityListGERAN OPTIONAL, -- Need ON
+ freqPriorityListUTRA-FDD FreqPriorityListUTRA-FDD OPTIONAL, -- Need ON
+ freqPriorityListUTRA-TDD FreqPriorityListUTRA-TDD OPTIONAL, -- Need ON
+ bandClassPriorityListHRPD BandClassPriorityListHRPD OPTIONAL, -- Need ON
+ bandClassPriorityList1XRTT BandClassPriorityList1XRTT OPTIONAL, -- Need ON
+ t320 ENUMERATED {
+ min5, min10, min20, min30, min60, min120, min180,
+ spare1} OPTIONAL, -- Need OR
+ ...
+}
+
+FreqPriorityListEUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA
+
+FreqPriorityEUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqsPriorityListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF FreqsPriorityGERAN
+
+FreqsPriorityGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqPriorityListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF FreqPriorityUTRA-FDD
+
+FreqPriorityUTRA-FDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqPriorityListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF FreqPriorityUTRA-TDD
+
+FreqPriorityUTRA-TDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+BandClassPriorityListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriorityHRPD
+
+BandClassPriorityHRPD ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority
+}
+
+BandClassPriorityList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriority1XRTT
+
+BandClassPriority1XRTT ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority
+}
+
+CellInfoListGERAN-r9 ::= SEQUENCE (SIZE (1..maxCellInfo-GERAN-r9 )) OF CellInfoGERAN-r9
+
+CellInfoGERAN-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdGERAN,
+ carrierFreq-r9 CarrierFreqGERAN,
+ systemInformation-r9 SystemInfoListGERAN
+}
+
+CellInfoListUTRA-FDD-r9 ::= SEQUENCE (SIZE (1..maxUTRA-CellInfo-r9)) OF CellInfoUTRA-FDD-r9
+
+CellInfoUTRA-FDD-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdUTRA-FDD,
+ utra-BCCH-Container-r9 OCTET STRING
+}
+
+CellInfoListUTRA-TDD-r9 ::= SEQUENCE (SIZE (1..maxUTRA-CellInfo-r9)) OF CellInfoUTRA-TDD-r9
+
+CellInfoUTRA-TDD-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdUTRA-TDD,
+ utra-BCCH-Container-r9 OCTET STRING
+}
+
+
+RRCConnectionRequest ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionRequest-r8 RRCConnectionRequest-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionRequest-r8-IEs ::= SEQUENCE {
+ ue-Identity InitialUE-Identity,
+ establishmentCause EstablishmentCause,
+ spare BIT STRING (SIZE (1))
+}
+
+InitialUE-Identity ::= CHOICE {
+ s-TMSI S-TMSI,
+ randomValue BIT STRING (SIZE (40))
+}
+
+EstablishmentCause ::= ENUMERATED {
+ emergency, highPriorityAccess, mt-Access, mo-Signalling,
+ mo-Data, spare3, spare2, spare1}
+
+
+RRCConnectionSetup ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionSetup-r8 RRCConnectionSetup-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionSetup-r8-IEs ::= SEQUENCE {
+ radioResourceConfigDedicated RadioResourceConfigDedicated,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionSetupComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionSetupComplete-r8 RRCConnectionSetupComplete-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionSetupComplete-r8-IEs ::= SEQUENCE {
+ selectedPLMN-Identity INTEGER (1..6),
+ registeredMME RegisteredMME OPTIONAL,
+ dedicatedInfoNAS DedicatedInfoNAS,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+RegisteredMME ::= SEQUENCE {
+ plmn-Identity PLMN-Identity OPTIONAL,
+ mmegi BIT STRING (SIZE (16)),
+ mmec MMEC
+}
+
+
+SecurityModeCommand ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ securityModeCommand-r8 SecurityModeCommand-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeCommand-r8-IEs ::= SEQUENCE {
+ securityConfigSMC SecurityConfigSMC,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+SecurityConfigSMC ::= SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig,
+ ...
+}
+
+
+SecurityModeComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ securityModeComplete-r8 SecurityModeComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SecurityModeFailure ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ securityModeFailure-r8 SecurityModeFailure-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeFailure-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SystemInformation ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ systemInformation-r8 SystemInformation-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+SystemInformation-r8-IEs ::= SEQUENCE {
+ sib-TypeAndInfo SEQUENCE (SIZE (1..maxSIB)) OF CHOICE {
+ sib2 SystemInformationBlockType2,
+ sib3 SystemInformationBlockType3,
+ sib4 SystemInformationBlockType4,
+ sib5 SystemInformationBlockType5,
+ sib6 SystemInformationBlockType6,
+ sib7 SystemInformationBlockType7,
+ sib8 SystemInformationBlockType8,
+ sib9 SystemInformationBlockType9,
+ sib10 SystemInformationBlockType10,
+ sib11 SystemInformationBlockType11,
+ ...,
+ sib12-v920 SystemInformationBlockType12-r9,
+ sib13-v920 SystemInformationBlockType13-r9
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+SystemInformationBlockType1 ::= SEQUENCE {
+ cellAccessRelatedInfo SEQUENCE {
+ plmn-IdentityList PLMN-IdentityList,
+ trackingAreaCode TrackingAreaCode,
+ cellIdentity CellIdentity,
+ cellBarred ENUMERATED {barred, notBarred},
+ intraFreqReselection ENUMERATED {allowed, notAllowed},
+ csg-Indication BOOLEAN,
+ csg-Identity CSG-Identity OPTIONAL -- Need OR
+ },
+ cellSelectionInfo SEQUENCE {
+ q-RxLevMin Q-RxLevMin,
+ q-RxLevMinOffset INTEGER (1..8) OPTIONAL -- Need OP
+ },
+ p-Max P-Max OPTIONAL, -- Need OP
+ freqBandIndicator INTEGER (1..64),
+ schedulingInfoList SchedulingInfoList,
+ tdd-Config TDD-Config OPTIONAL, -- Cond TDD
+ si-WindowLength ENUMERATED {
+ ms1, ms2, ms5, ms10, ms15, ms20,
+ ms40},
+ systemInfoValueTag INTEGER (0..31),
+ nonCriticalExtension SystemInformationBlockType1-v890-IEs OPTIONAL
+}
+
+SystemInformationBlockType1-v890-IEs::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension SystemInformationBlockType1-v920-IEs OPTIONAL
+}
+
+SystemInformationBlockType1-v920-IEs ::= SEQUENCE {
+ ims-EmergencySupport-r9 ENUMERATED {true} OPTIONAL, -- Need OR
+ cellSelectionInfo-v920 CellSelectionInfo-v920 OPTIONAL, -- Need OP
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+PLMN-IdentityList ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo
+
+PLMN-IdentityInfo ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellReservedForOperatorUse ENUMERATED {reserved, notReserved}
+}
+
+SchedulingInfoList ::= SEQUENCE (SIZE (1..maxSI-Message)) OF SchedulingInfo
+
+SchedulingInfo ::= SEQUENCE {
+ si-Periodicity ENUMERATED {
+ rf8, rf16, rf32, rf64, rf128, rf256, rf512},
+ sib-MappingInfo SIB-MappingInfo
+}
+
+SIB-MappingInfo ::= SEQUENCE (SIZE (0..maxSIB-1)) OF SIB-Type
+
+SIB-Type ::= ENUMERATED {
+ sibType3, sibType4, sibType5, sibType6,
+ sibType7, sibType8, sibType9, sibType10,
+ sibType11, sibType12-v920, sibType13-v920, spare5,
+ spare4, spare3, spare2, spare1, ...}
+
+CellSelectionInfo-v920 ::= SEQUENCE {
+ q-QualMin-r9 Q-QualMin-r9,
+ q-QualMinOffset-r9 INTEGER (1..8) OPTIONAL -- Need OP
+}
+
+
+UECapabilityEnquiry ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueCapabilityEnquiry-r8 UECapabilityEnquiry-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UECapabilityEnquiry-r8-IEs ::= SEQUENCE {
+ ue-CapabilityRequest UE-CapabilityRequest,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+UE-CapabilityRequest ::= SEQUENCE (SIZE (1..maxRAT-Capabilities)) OF RAT-Type
+
+
+UECapabilityInformation ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ ueCapabilityInformation-r8 UECapabilityInformation-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UECapabilityInformation-r8-IEs ::= SEQUENCE {
+ ue-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+UEInformationRequest-r9 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueInformationRequest-r9 UEInformationRequest-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UEInformationRequest-r9-IEs ::= SEQUENCE {
+ rach-ReportReq-r9 BOOLEAN,
+ rlf-ReportReq-r9 BOOLEAN,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+UEInformationResponse-r9 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueInformationResponse-r9 UEInformationResponse-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UEInformationResponse-r9-IEs ::= SEQUENCE {
+ rach-Report-r9 SEQUENCE {
+ numberOfPreamblesSent-r9 INTEGER (1..200),
+ contentionDetected-r9 BOOLEAN
+ } OPTIONAL,
+ rlfReport-r9 RLF-Report-r9 OPTIONAL,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+RLF-Report-r9 ::= SEQUENCE {
+ measResultLastServCell SEQUENCE {
+ rsrpResult RSRP-Range,
+ rsrqResult RSRQ-Range OPTIONAL
+ },
+ measResultNeighCells SEQUENCE {
+ measResultListEUTRA MeasResultList2EUTRA OPTIONAL,
+ measResultListUTRA MeasResultList2UTRA OPTIONAL,
+ measResultListGERAN MeasResultListGERAN OPTIONAL,
+ measResultsCDMA2000 MeasResultList2CDMA2000 OPTIONAL
+ } OPTIONAL,
+ ...
+}
+
+MeasResultList2EUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ measResultList MeasResultListEUTRA
+}
+
+MeasResultList2UTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ measResultList MeasResultListUTRA
+}
+
+MeasResultList2CDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF SEQUENCE {
+ carrierFreq CarrierFreqCDMA2000,
+ measResultList MeasResultsCDMA2000
+}
+
+
+ULHandoverPreparationTransfer ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ulHandoverPreparationTransfer-r8 ULHandoverPreparationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ meid BIT STRING (SIZE (56)) OPTIONAL,
+ dedicatedInfo DedicatedInfoCDMA2000,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+ULInformationTransfer ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ulInformationTransfer-r8 ULInformationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ULInformationTransfer-r8-IEs ::= SEQUENCE {
+ dedicatedInfoType CHOICE {
+ dedicatedInfoNAS DedicatedInfoNAS,
+ dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000,
+ dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SystemInformationBlockType2 ::= SEQUENCE {
+ ac-BarringInfo SEQUENCE {
+ ac-BarringForEmergency BOOLEAN,
+ ac-BarringForMO-Signalling AC-BarringConfig OPTIONAL, -- Need OP
+ ac-BarringForMO-Data AC-BarringConfig OPTIONAL -- Need OP
+ } OPTIONAL, -- Need OP
+ radioResourceConfigCommon RadioResourceConfigCommonSIB,
+ ue-TimersAndConstants UE-TimersAndConstants,
+ freqInfo SEQUENCE {
+ ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL, -- Need OP
+ ul-Bandwidth ENUMERATED {n6, n15, n25, n50, n75, n100}
+ OPTIONAL, -- Need OP
+ additionalSpectrumEmission AdditionalSpectrumEmission
+ },
+ mbsfn-SubframeConfigList MBSFN-SubframeConfigList OPTIONAL, -- Need OR
+ timeAlignmentTimerCommon TimeAlignmentTimer,
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ ssac-BarringForMMTEL-Voice-r9 AC-BarringConfig OPTIONAL, -- Need OP
+ ssac-BarringForMMTEL-Video-r9 AC-BarringConfig OPTIONAL -- Need OP
+ ]]
+}
+
+AC-BarringConfig ::= SEQUENCE {
+ ac-BarringFactor ENUMERATED {
+ p00, p05, p10, p15, p20, p25, p30, p40,
+ p50, p60, p70, p75, p80, p85, p90, p95},
+ ac-BarringTime ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512},
+ ac-BarringForSpecialAC BIT STRING (SIZE(5))
+}
+
+MBSFN-SubframeConfigList ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig
+
+
+SystemInformationBlockType3 ::= SEQUENCE {
+ cellReselectionInfoCommon SEQUENCE {
+ q-Hyst ENUMERATED {
+ dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10,
+ dB12, dB14, dB16, dB18, dB20, dB22, dB24},
+ speedStateReselectionPars SEQUENCE {
+ mobilityStateParameters MobilityStateParameters,
+ q-HystSF SEQUENCE {
+ sf-Medium ENUMERATED {
+ dB-6, dB-4, dB-2, dB0},
+ sf-High ENUMERATED {
+ dB-6, dB-4, dB-2, dB0}
+ }
+ } OPTIONAL -- Need OP
+ },
+ cellReselectionServingFreqInfo SEQUENCE {
+ s-NonIntraSearch ReselectionThreshold OPTIONAL, -- Need OP
+ threshServingLow ReselectionThreshold,
+ cellReselectionPriority CellReselectionPriority
+ },
+ intraFreqCellReselectionInfo SEQUENCE {
+ q-RxLevMin Q-RxLevMin,
+ p-Max P-Max OPTIONAL, -- Need OP
+ s-IntraSearch ReselectionThreshold OPTIONAL, -- Need OP
+ allowedMeasBandwidth AllowedMeasBandwidth OPTIONAL, -- Need OP
+ presenceAntennaPort1 PresenceAntennaPort1,
+ neighCellConfig NeighCellConfig,
+ t-ReselectionEUTRA T-Reselection,
+ t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL -- Need OP
+ },
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ s-IntraSearch-v920 SEQUENCE {
+ s-IntraSearchP-r9 ReselectionThreshold,
+ s-IntraSearchQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL, -- Need OP
+ s-NonIntraSearch-v920 SEQUENCE {
+ s-NonIntraSearchP-r9 ReselectionThreshold,
+ s-NonIntraSearchQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL, -- Need OP
+ q-QualMin-r9 Q-QualMin-r9 OPTIONAL, -- Need OP
+ threshServingLowQ-r9 ReselectionThresholdQ-r9 OPTIONAL -- Need OP
+ ]]
+}
+
+
+SystemInformationBlockType4 ::= SEQUENCE {
+ intraFreqNeighCellList IntraFreqNeighCellList OPTIONAL, -- Need OR
+ intraFreqBlackCellList IntraFreqBlackCellList OPTIONAL, -- Need OR
+ csg-PhysCellIdRange PhysCellIdRange OPTIONAL, -- Cond CSG
+ ...
+}
+
+IntraFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellIntra)) OF IntraFreqNeighCellInfo
+
+IntraFreqNeighCellInfo ::= SEQUENCE {
+ physCellId PhysCellId,
+ q-OffsetCell Q-OffsetRange,
+ ...
+}
+
+IntraFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange
+
+
+SystemInformationBlockType5 ::= SEQUENCE {
+ interFreqCarrierFreqList InterFreqCarrierFreqList,
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL -- Need OP
+}
+
+InterFreqCarrierFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo
+
+InterFreqCarrierFreqInfo ::= SEQUENCE {
+ dl-CarrierFreq ARFCN-ValueEUTRA,
+ q-RxLevMin Q-RxLevMin,
+ p-Max P-Max OPTIONAL, -- Need OP
+ t-ReselectionEUTRA T-Reselection,
+ t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ allowedMeasBandwidth AllowedMeasBandwidth,
+ presenceAntennaPort1 PresenceAntennaPort1,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ neighCellConfig NeighCellConfig,
+ q-OffsetFreq Q-OffsetRange DEFAULT dB0,
+ interFreqNeighCellList InterFreqNeighCellList OPTIONAL, -- Need OR
+ interFreqBlackCellList InterFreqBlackCellList OPTIONAL, -- Need OR
+ ...,
+ [[ q-QualMin-r9 Q-QualMin-r9 OPTIONAL, -- Need OP
+ threshX-Q-r9 SEQUENCE {
+ threshX-HighQ-r9 ReselectionThresholdQ-r9,
+ threshX-LowQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL -- Cond RSRQ
+ ]]
+}
+
+InterFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellInter)) OF InterFreqNeighCellInfo
+
+InterFreqNeighCellInfo ::= SEQUENCE {
+ physCellId PhysCellId,
+ q-OffsetCell Q-OffsetRange
+}
+
+InterFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange
+
+
+SystemInformationBlockType6 ::= SEQUENCE {
+ carrierFreqListUTRA-FDD CarrierFreqListUTRA-FDD OPTIONAL, -- Need OR
+ carrierFreqListUTRA-TDD CarrierFreqListUTRA-TDD OPTIONAL, -- Need OR
+ t-ReselectionUTRA T-Reselection,
+ t-ReselectionUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL -- Need OP
+}
+
+CarrierFreqListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF CarrierFreqUTRA-FDD
+
+CarrierFreqUTRA-FDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ q-RxLevMin INTEGER (-60..-13),
+ p-MaxUTRA INTEGER (-50..33),
+ q-QualMin INTEGER (-24..0),
+ ...,
+ [[ threshX-Q-r9 SEQUENCE {
+ threshX-HighQ-r9 ReselectionThresholdQ-r9,
+ threshX-LowQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL -- Cond RSRQ
+ ]]
+}
+
+CarrierFreqListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF CarrierFreqUTRA-TDD
+
+CarrierFreqUTRA-TDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ q-RxLevMin INTEGER (-60..-13),
+ p-MaxUTRA INTEGER (-50..33),
+ ...
+}
+
+
+SystemInformationBlockType7 ::= SEQUENCE {
+ t-ReselectionGERAN T-Reselection,
+ t-ReselectionGERAN-SF SpeedStateScaleFactors OPTIONAL, -- Need OR
+ carrierFreqsInfoList CarrierFreqsInfoListGERAN OPTIONAL, -- Need OR
+ ...
+}
+
+CarrierFreqsInfoListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF CarrierFreqsInfoGERAN
+
+CarrierFreqsInfoGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ commonInfo SEQUENCE {
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ ncc-Permitted BIT STRING (SIZE (8)),
+ q-RxLevMin INTEGER (0..45),
+ p-MaxGERAN INTEGER (0..39) OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold
+ },
+ ...
+}
+
+
+SystemInformationBlockType8 ::= SEQUENCE {
+ systemTimeInfo SystemTimeInfoCDMA2000 OPTIONAL, -- Need OR
+ searchWindowSize INTEGER (0..15) OPTIONAL, -- Need OR
+ parametersHRPD SEQUENCE {
+ preRegistrationInfoHRPD PreRegistrationInfoHRPD,
+ cellReselectionParametersHRPD CellReselectionParametersCDMA2000 OPTIONAL -- Need OR
+ } OPTIONAL, -- Need OR
+ parameters1XRTT SEQUENCE {
+ csfb-RegistrationParam1XRTT CSFB-RegistrationParam1XRTT OPTIONAL, -- Need OP
+ longCodeState1XRTT BIT STRING (SIZE (42)) OPTIONAL, -- Need OR
+ cellReselectionParameters1XRTT CellReselectionParametersCDMA2000 OPTIONAL -- Need OR
+ } OPTIONAL, -- Need OR
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ csfb-SupportForDualRxUEs-r9 BOOLEAN OPTIONAL, -- Need OR
+ cellReselectionParametersHRPD-v920 CellReselectionParametersCDMA2000-v920 OPTIONAL, -- Cond NCL-HRPD
+ cellReselectionParameters1XRTT-v920 CellReselectionParametersCDMA2000-v920 OPTIONAL, -- Cond NCL-1XRTT
+ csfb-RegistrationParam1XRTT-v920 CSFB-RegistrationParam1XRTT-v920 OPTIONAL, -- Cond REG-1XRTT
+ ac-BarringConfig1XRTT-r9 AC-BarringConfig1XRTT-r9 OPTIONAL -- Cond REG-1XRTT
+ ]]
+}
+
+CellReselectionParametersCDMA2000 ::= SEQUENCE {
+ bandClassList BandClassListCDMA2000,
+ neighCellList NeighCellListCDMA2000,
+ t-ReselectionCDMA2000 T-Reselection,
+ t-ReselectionCDMA2000-SF SpeedStateScaleFactors OPTIONAL -- Need OP
+}
+
+CellReselectionParametersCDMA2000-v920 ::= SEQUENCE {
+ neighCellList-v920 NeighCellListCDMA2000-v920
+}
+
+NeighCellListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000
+
+NeighCellCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ neighCellsPerFreqList NeighCellsPerBandclassListCDMA2000
+}
+
+NeighCellsPerBandclassListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000
+
+NeighCellsPerBandclassCDMA2000 ::= SEQUENCE {
+ arfcn ARFCN-ValueCDMA2000,
+ physCellIdList PhysCellIdListCDMA2000
+}
+
+NeighCellListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000-v920
+
+NeighCellCDMA2000-v920 ::= SEQUENCE {
+ neighCellsPerFreqList-v920 NeighCellsPerBandclassListCDMA2000-v920
+}
+
+NeighCellsPerBandclassListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000-v920
+
+NeighCellsPerBandclassCDMA2000-v920 ::= SEQUENCE {
+ physCellIdList-v920 PhysCellIdListCDMA2000-v920
+}
+
+PhysCellIdListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdCDMA2000
+
+PhysCellIdListCDMA2000-v920 ::= SEQUENCE (SIZE (0..24)) OF PhysCellIdCDMA2000
+
+BandClassListCDMA2000 ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassInfoCDMA2000
+
+BandClassInfoCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High INTEGER (0..63),
+ threshX-Low INTEGER (0..63),
+ ...
+}
+
+AC-BarringConfig1XRTT-r9 ::= SEQUENCE {
+ ac-Barring0to9-r9 INTEGER (0..63),
+ ac-Barring10-r9 INTEGER (0..7),
+ ac-Barring11-r9 INTEGER (0..7),
+ ac-Barring12-r9 INTEGER (0..7),
+ ac-Barring13-r9 INTEGER (0..7),
+ ac-Barring14-r9 INTEGER (0..7),
+ ac-Barring15-r9 INTEGER (0..7),
+ ac-BarringMsg-r9 INTEGER (0..7),
+ ac-BarringReg-r9 INTEGER (0..7),
+ ac-BarringEmg-r9 INTEGER (0..7)
+}
+
+
+SystemInformationBlockType9 ::= SEQUENCE {
+ hnb-Name OCTET STRING (SIZE(1..48)) OPTIONAL, -- Need OR
+ ...
+}
+
+
+SystemInformationBlockType10 ::= SEQUENCE {
+ messageIdentifier BIT STRING (SIZE (16)),
+ serialNumber BIT STRING (SIZE (16)),
+ warningType OCTET STRING (SIZE (2)),
+ warningSecurityInfo OCTET STRING (SIZE (50)) OPTIONAL, -- Need OP
+ ...
+}
+
+
+SystemInformationBlockType11 ::= SEQUENCE {
+ messageIdentifier BIT STRING (SIZE (16)),
+ serialNumber BIT STRING (SIZE (16)),
+ warningMessageSegmentType ENUMERATED {notLastSegment, lastSegment},
+ warningMessageSegmentNumber INTEGER (0..63),
+ warningMessageSegment OCTET STRING,
+ dataCodingScheme OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1
+ ...
+}
+
+
+SystemInformationBlockType12-r9 ::= SEQUENCE {
+ messageIdentifier-r9 BIT STRING (SIZE (16)),
+ serialNumber-r9 BIT STRING (SIZE (16)),
+ warningMessageSegmentType-r9 ENUMERATED {notLastSegment, lastSegment},
+ warningMessageSegmentNumber-r9 INTEGER (0..63),
+ warningMessageSegment-r9 OCTET STRING,
+ dataCodingScheme-r9 OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1
+ lateR9NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ ...
+}
+
+
+SystemInformationBlockType13-r9 ::= SEQUENCE {
+ mbsfn-AreaInfoList-r9 MBSFN-AreaInfoList-r9,
+ notificationConfig-r9 MBMS-NotificationConfig-r9,
+ lateR9NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ ...
+}
+
+
+AntennaInfoCommon ::= SEQUENCE {
+ antennaPortsCount ENUMERATED {an1, an2, an4, spare1}
+}
+
+AntennaInfoDedicated ::= SEQUENCE {
+ transmissionMode ENUMERATED {
+ tm1, tm2, tm3, tm4, tm5, tm6,
+ tm7, tm8-v920},
+ codebookSubsetRestriction CHOICE {
+ n2TxAntenna-tm3 BIT STRING (SIZE (2)),
+ n4TxAntenna-tm3 BIT STRING (SIZE (4)),
+ n2TxAntenna-tm4 BIT STRING (SIZE (6)),
+ n4TxAntenna-tm4 BIT STRING (SIZE (64)),
+ n2TxAntenna-tm5 BIT STRING (SIZE (4)),
+ n4TxAntenna-tm5 BIT STRING (SIZE (16)),
+ n2TxAntenna-tm6 BIT STRING (SIZE (4)),
+ n4TxAntenna-tm6 BIT STRING (SIZE (16))
+ } OPTIONAL, -- Cond TM
+ ue-TransmitAntennaSelection CHOICE{
+ release NULL,
+ setup ENUMERATED {closedLoop, openLoop}
+ }
+}
+
+AntennaInfoDedicated-v920 ::= SEQUENCE {
+ codebookSubsetRestriction-v920 CHOICE {
+ n2TxAntenna-tm8-r9 BIT STRING (SIZE (6)),
+ n4TxAntenna-tm8-r9 BIT STRING (SIZE (32))
+ } OPTIONAL -- Cond TM8
+}
+
+
+CQI-ReportConfig ::= SEQUENCE {
+ cqi-ReportModeAperiodic ENUMERATED {
+ rm12, rm20, rm22, rm30, rm31,
+ spare3, spare2, spare1} OPTIONAL, -- Need OR
+ nomPDSCH-RS-EPRE-Offset INTEGER (-1..6),
+ cqi-ReportPeriodic CQI-ReportPeriodic OPTIONAL -- Need ON
+}
+
+CQI-ReportConfig-v920 ::= SEQUENCE {
+ cqi-Mask-r9 ENUMERATED {setup} OPTIONAL, -- Cond cqi-Setup
+ pmi-RI-Report-r9 ENUMERATED {setup} OPTIONAL -- Cond PMIRI
+}
+
+CQI-ReportPeriodic ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ cqi-PUCCH-ResourceIndex INTEGER (0.. 1185),
+ cqi-pmi-ConfigIndex INTEGER (0..1023),
+ cqi-FormatIndicatorPeriodic CHOICE {
+ widebandCQI NULL,
+ subbandCQI SEQUENCE {
+ k INTEGER (1..4)
+ }
+ },
+ ri-ConfigIndex INTEGER (0..1023) OPTIONAL, -- Need OR
+ simultaneousAckNackAndCQI BOOLEAN
+ }
+}
+
+
+DRB-Identity ::= INTEGER (1..32)
+
+
+LogicalChannelConfig ::= SEQUENCE {
+ ul-SpecificParameters SEQUENCE {
+ priority INTEGER (1..16),
+ prioritisedBitRate ENUMERATED {
+ kBps0, kBps8, kBps16, kBps32, kBps64, kBps128,
+ kBps256, infinity, spare8, spare7, spare6,
+ spare5, spare4, spare3, spare2, spare1},
+ bucketSizeDuration ENUMERATED {
+ ms50, ms100, ms150, ms300, ms500, ms1000, spare2,
+ spare1},
+ logicalChannelGroup INTEGER (0..3) OPTIONAL -- Need OR
+ } OPTIONAL, -- Cond UL
+ ...,
+ [[ logicalChannelSR-Mask-r9 ENUMERATED {setup} OPTIONAL -- Cond SRmask
+ ]]
+}
+
+
+MAC-MainConfig ::= SEQUENCE {
+ ul-SCH-Config SEQUENCE {
+ maxHARQ-Tx ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n7, n8,
+ n10, n12, n16, n20, n24, n28,
+ spare2, spare1} OPTIONAL, -- Need ON
+ periodicBSR-Timer ENUMERATED {
+ sf5, sf10, sf16, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, sf1280, sf2560,
+ infinity, spare1} OPTIONAL, -- Need ON
+ retxBSR-Timer ENUMERATED {
+ sf320, sf640, sf1280, sf2560, sf5120,
+ sf10240, spare2, spare1},
+ ttiBundling BOOLEAN
+ } OPTIONAL, -- Need ON
+ drx-Config DRX-Config OPTIONAL, -- Need ON
+ timeAlignmentTimerDedicated TimeAlignmentTimer,
+ phr-Config CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ periodicPHR-Timer ENUMERATED {sf10, sf20, sf50, sf100, sf200,
+ sf500, sf1000, infinity},
+ prohibitPHR-Timer ENUMERATED {sf0, sf10, sf20, sf50, sf100,
+ sf200, sf500, sf1000},
+ dl-PathlossChange ENUMERATED {dB1, dB3, dB6, infinity}
+ }
+ } OPTIONAL, -- Need ON
+ ...,
+ [[ sr-ProhibitTimer-r9 INTEGER (0..7) OPTIONAL -- Need ON
+ ]]
+}
+
+DRX-Config ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ onDurationTimer ENUMERATED {
+ psf1, psf2, psf3, psf4, psf5, psf6,
+ psf8, psf10, psf20, psf30, psf40,
+ psf50, psf60, psf80, psf100,
+ psf200},
+ drx-InactivityTimer ENUMERATED {
+ psf1, psf2, psf3, psf4, psf5, psf6,
+ psf8, psf10, psf20, psf30, psf40,
+ psf50, psf60, psf80, psf100,
+ psf200, psf300, psf500, psf750,
+ psf1280, psf1920, psf2560, spare10,
+ spare9, spare8, spare7, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ drx-RetransmissionTimer ENUMERATED {
+ psf1, psf2, psf4, psf6, psf8, psf16,
+ psf24, psf33},
+ longDRX-CycleStartOffset CHOICE {
+ sf10 INTEGER(0..9),
+ sf20 INTEGER(0..19),
+ sf32 INTEGER(0..31),
+ sf40 INTEGER(0..39),
+ sf64 INTEGER(0..63),
+ sf80 INTEGER(0..79),
+ sf128 INTEGER(0..127),
+ sf160 INTEGER(0..159),
+ sf256 INTEGER(0..255),
+ sf320 INTEGER(0..319),
+ sf512 INTEGER(0..511),
+ sf640 INTEGER(0..639),
+ sf1024 INTEGER(0..1023),
+ sf1280 INTEGER(0..1279),
+ sf2048 INTEGER(0..2047),
+ sf2560 INTEGER(0..2559)
+ },
+ shortDRX SEQUENCE {
+ shortDRX-Cycle ENUMERATED {
+ sf2, sf5, sf8, sf10, sf16, sf20,
+ sf32, sf40, sf64, sf80, sf128, sf160,
+ sf256, sf320, sf512, sf640},
+ drxShortCycleTimer INTEGER (1..16)
+ } OPTIONAL -- Need OR
+ }
+}
+
+
+PDCP-Config ::= SEQUENCE {
+ discardTimer ENUMERATED {
+ ms50, ms100, ms150, ms300, ms500,
+ ms750, ms1500, infinity
+ } OPTIONAL, -- Cond Setup
+ rlc-AM SEQUENCE {
+ statusReportRequired BOOLEAN
+ } OPTIONAL, -- Cond Rlc-AM
+ rlc-UM SEQUENCE {
+ pdcp-SN-Size ENUMERATED {len7bits, len12bits}
+ } OPTIONAL, -- Cond Rlc-UM
+ headerCompression CHOICE {
+ notUsed NULL,
+ rohc SEQUENCE {
+ maxCID INTEGER (1..16383) DEFAULT 15,
+ profiles SEQUENCE {
+ profile0x0001 BOOLEAN,
+ profile0x0002 BOOLEAN,
+ profile0x0003 BOOLEAN,
+ profile0x0004 BOOLEAN,
+ profile0x0006 BOOLEAN,
+ profile0x0101 BOOLEAN,
+ profile0x0102 BOOLEAN,
+ profile0x0103 BOOLEAN,
+ profile0x0104 BOOLEAN
+ },
+ ...
+ }
+ },
+ ...
+}
+
+
+PDSCH-ConfigCommon ::= SEQUENCE {
+ referenceSignalPower INTEGER (-60..50),
+ p-b INTEGER (0..3)
+}
+
+PDSCH-ConfigDedicated::= SEQUENCE {
+ p-a ENUMERATED {
+ dB-6, dB-4dot77, dB-3, dB-1dot77,
+ dB0, dB1, dB2, dB3}
+}
+
+
+PHICH-Config ::= SEQUENCE {
+ phich-Duration ENUMERATED {normal, extended},
+ phich-Resource ENUMERATED {oneSixth, half, one, two}
+}
+
+
+PhysicalConfigDedicated ::= SEQUENCE {
+ pdsch-ConfigDedicated PDSCH-ConfigDedicated OPTIONAL, -- Need ON
+ pucch-ConfigDedicated PUCCH-ConfigDedicated OPTIONAL, -- Need ON
+ pusch-ConfigDedicated PUSCH-ConfigDedicated OPTIONAL, -- Need ON
+ uplinkPowerControlDedicated UplinkPowerControlDedicated OPTIONAL, -- Need ON
+ tpc-PDCCH-ConfigPUCCH TPC-PDCCH-Config OPTIONAL, -- Need ON
+ tpc-PDCCH-ConfigPUSCH TPC-PDCCH-Config OPTIONAL, -- Need ON
+ cqi-ReportConfig CQI-ReportConfig OPTIONAL, -- Need ON
+ soundingRS-UL-ConfigDedicated SoundingRS-UL-ConfigDedicated OPTIONAL, -- Need ON
+ antennaInfo CHOICE {
+ explicitValue AntennaInfoDedicated,
+ defaultValue NULL
+ } OPTIONAL, -- Need ON
+ schedulingRequestConfig SchedulingRequestConfig OPTIONAL, -- Need ON
+ ...,
+ [[ cqi-ReportConfig-v920 CQI-ReportConfig-v920 OPTIONAL, -- Need ON
+ antennaInfo-v920 AntennaInfoDedicated-v920 OPTIONAL -- Need ON
+ ]]
+}
+
+
+P-Max ::= INTEGER (-30..33)
+
+
+PRACH-ConfigSIB ::= SEQUENCE {
+ rootSequenceIndex INTEGER (0..837),
+ prach-ConfigInfo PRACH-ConfigInfo
+}
+
+PRACH-Config ::= SEQUENCE {
+ rootSequenceIndex INTEGER (0..837),
+ prach-ConfigInfo PRACH-ConfigInfo OPTIONAL -- Need ON
+}
+
+PRACH-ConfigInfo ::= SEQUENCE {
+ prach-ConfigIndex INTEGER (0..63),
+ highSpeedFlag BOOLEAN,
+ zeroCorrelationZoneConfig INTEGER (0..15),
+ prach-FreqOffset INTEGER (0..94)
+}
+
+
+PresenceAntennaPort1 ::= BOOLEAN
+
+
+PUCCH-ConfigCommon ::= SEQUENCE {
+ deltaPUCCH-Shift ENUMERATED {ds1, ds2, ds3},
+ nRB-CQI INTEGER (0..98),
+ nCS-AN INTEGER (0..7),
+ n1PUCCH-AN INTEGER (0..2047)
+}
+
+PUCCH-ConfigDedicated ::= SEQUENCE {
+ ackNackRepetition CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ repetitionFactor ENUMERATED {n2, n4, n6, spare1},
+ n1PUCCH-AN-Rep INTEGER (0..2047)
+ }
+ },
+ tdd-AckNackFeedbackMode ENUMERATED {bundling, multiplexing} OPTIONAL -- Cond TDD
+}
+
+
+PUSCH-ConfigCommon ::= SEQUENCE {
+ pusch-ConfigBasic SEQUENCE {
+ n-SB INTEGER (1..4),
+ hoppingMode ENUMERATED {interSubFrame, intraAndInterSubFrame},
+ pusch-HoppingOffset INTEGER (0..98),
+ enable64QAM BOOLEAN
+ },
+ ul-ReferenceSignalsPUSCH UL-ReferenceSignalsPUSCH
+}
+
+PUSCH-ConfigDedicated ::= SEQUENCE {
+ betaOffset-ACK-Index INTEGER (0..15),
+ betaOffset-RI-Index INTEGER (0..15),
+ betaOffset-CQI-Index INTEGER (0..15)
+}
+
+UL-ReferenceSignalsPUSCH ::= SEQUENCE {
+ groupHoppingEnabled BOOLEAN,
+ groupAssignmentPUSCH INTEGER (0..29),
+ sequenceHoppingEnabled BOOLEAN,
+ cyclicShift INTEGER (0..7)
+}
+
+
+RACH-ConfigCommon ::= SEQUENCE {
+ preambleInfo SEQUENCE {
+ numberOfRA-Preambles ENUMERATED {
+ n4, n8, n12, n16 ,n20, n24, n28,
+ n32, n36, n40, n44, n48, n52, n56,
+ n60, n64},
+ preamblesGroupAConfig SEQUENCE {
+ sizeOfRA-PreamblesGroupA ENUMERATED {
+ n4, n8, n12, n16 ,n20, n24, n28,
+ n32, n36, n40, n44, n48, n52, n56,
+ n60},
+ messageSizeGroupA ENUMERATED {b56, b144, b208, b256},
+ messagePowerOffsetGroupB ENUMERATED {
+ minusinfinity, dB0, dB5, dB8, dB10, dB12,
+ dB15, dB18},
+ ...
+ } OPTIONAL -- Need OP
+ },
+ powerRampingParameters SEQUENCE {
+ powerRampingStep ENUMERATED {dB0, dB2,dB4, dB6},
+ preambleInitialReceivedTargetPower ENUMERATED {
+ dBm-120, dBm-118, dBm-116, dBm-114, dBm-112,
+ dBm-110, dBm-108, dBm-106, dBm-104, dBm-102,
+ dBm-100, dBm-98, dBm-96, dBm-94,
+ dBm-92, dBm-90}
+ },
+ ra-SupervisionInfo SEQUENCE {
+ preambleTransMax ENUMERATED {
+ n3, n4, n5, n6, n7, n8, n10, n20, n50,
+ n100, n200},
+ ra-ResponseWindowSize ENUMERATED {
+ sf2, sf3, sf4, sf5, sf6, sf7,
+ sf8, sf10},
+ mac-ContentionResolutionTimer ENUMERATED {
+ sf8, sf16, sf24, sf32, sf40, sf48,
+ sf56, sf64}
+ },
+ maxHARQ-Msg3Tx INTEGER (1..8),
+ ...
+}
+
+
+RACH-ConfigDedicated ::= SEQUENCE {
+ ra-PreambleIndex INTEGER (0..63),
+ ra-PRACH-MaskIndex INTEGER (0..15)
+}
+
+
+RadioResourceConfigCommonSIB ::= SEQUENCE {
+ rach-ConfigCommon RACH-ConfigCommon,
+ bcch-Config BCCH-Config,
+ pcch-Config PCCH-Config,
+ prach-Config PRACH-ConfigSIB,
+ pdsch-ConfigCommon PDSCH-ConfigCommon,
+ pusch-ConfigCommon PUSCH-ConfigCommon,
+ pucch-ConfigCommon PUCCH-ConfigCommon,
+ soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon,
+ uplinkPowerControlCommon UplinkPowerControlCommon,
+ ul-CyclicPrefixLength UL-CyclicPrefixLength,
+ ...
+}
+
+RadioResourceConfigCommon ::= SEQUENCE {
+ rach-ConfigCommon RACH-ConfigCommon OPTIONAL, -- Need ON
+ prach-Config PRACH-Config,
+ pdsch-ConfigCommon PDSCH-ConfigCommon OPTIONAL, -- Need ON
+ pusch-ConfigCommon PUSCH-ConfigCommon,
+ phich-Config PHICH-Config OPTIONAL, -- Need ON
+ pucch-ConfigCommon PUCCH-ConfigCommon OPTIONAL, -- Need ON
+ soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon OPTIONAL, -- Need ON
+ uplinkPowerControlCommon UplinkPowerControlCommon OPTIONAL, -- Need ON
+ antennaInfoCommon AntennaInfoCommon OPTIONAL, -- Need ON
+ p-Max P-Max OPTIONAL, -- Need OP
+ tdd-Config TDD-Config OPTIONAL, -- Cond TDD
+ ul-CyclicPrefixLength UL-CyclicPrefixLength,
+ ...
+}
+
+BCCH-Config ::= SEQUENCE {
+ modificationPeriodCoeff ENUMERATED {n2, n4, n8, n16}
+}
+
+PCCH-Config ::= SEQUENCE {
+ defaultPagingCycle ENUMERATED {
+ rf32, rf64, rf128, rf256},
+ nB ENUMERATED {
+ fourT, twoT, oneT, halfT, quarterT, oneEighthT,
+ oneSixteenthT, oneThirtySecondT}
+}
+
+UL-CyclicPrefixLength ::= ENUMERATED {len1, len2}
+
+
+RadioResourceConfigDedicated ::= SEQUENCE {
+ srb-ToAddModList SRB-ToAddModList OPTIONAL, -- Cond HO-Conn
+ drb-ToAddModList DRB-ToAddModList OPTIONAL, -- Cond HO-toEUTRA
+ drb-ToReleaseList DRB-ToReleaseList OPTIONAL, -- Need ON
+ mac-MainConfig CHOICE {
+ explicitValue MAC-MainConfig,
+ defaultValue NULL
+ } OPTIONAL, -- Cond HO-toEUTRA2
+ sps-Config SPS-Config OPTIONAL, -- Need ON
+ physicalConfigDedicated PhysicalConfigDedicated OPTIONAL, -- Need ON
+ ...,
+ [[ rlf-TimersAndConstants-r9 RLF-TimersAndConstants-r9 OPTIONAL -- Need ON
+ ]]
+}
+
+SRB-ToAddModList ::= SEQUENCE (SIZE (1..2)) OF SRB-ToAddMod
+
+SRB-ToAddMod ::= SEQUENCE {
+ srb-Identity INTEGER (1..2),
+ rlc-Config CHOICE {
+ explicitValue RLC-Config,
+ defaultValue NULL
+ } OPTIONAL, -- Cond Setup
+ logicalChannelConfig CHOICE {
+ explicitValue LogicalChannelConfig,
+ defaultValue NULL
+ } OPTIONAL, -- Cond Setup
+ ...
+}
+
+DRB-ToAddModList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddMod
+
+DRB-ToAddMod ::= SEQUENCE {
+ eps-BearerIdentity INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup
+ drb-Identity DRB-Identity,
+ pdcp-Config PDCP-Config OPTIONAL, -- Cond PDCP
+ rlc-Config RLC-Config OPTIONAL, -- Cond Setup
+ logicalChannelIdentity INTEGER (3..10) OPTIONAL, -- Cond DRB-Setup
+ logicalChannelConfig LogicalChannelConfig OPTIONAL, -- Cond Setup
+ ...
+}
+
+DRB-ToReleaseList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-Identity
+
+
+RLC-Config ::= CHOICE {
+ am SEQUENCE {
+ ul-AM-RLC UL-AM-RLC,
+ dl-AM-RLC DL-AM-RLC
+ },
+ um-Bi-Directional SEQUENCE {
+ ul-UM-RLC UL-UM-RLC,
+ dl-UM-RLC DL-UM-RLC
+ },
+ um-Uni-Directional-UL SEQUENCE {
+ ul-UM-RLC UL-UM-RLC
+ },
+ um-Uni-Directional-DL SEQUENCE {
+ dl-UM-RLC DL-UM-RLC
+ },
+ ...
+}
+
+UL-AM-RLC ::= SEQUENCE {
+ t-PollRetransmit T-PollRetransmit,
+ pollPDU PollPDU,
+ pollByte PollByte,
+ maxRetxThreshold ENUMERATED {
+ t1, t2, t3, t4, t6, t8, t16, t32}
+}
+
+DL-AM-RLC ::= SEQUENCE {
+ t-Reordering T-Reordering,
+ t-StatusProhibit T-StatusProhibit
+}
+
+UL-UM-RLC ::= SEQUENCE {
+ sn-FieldLength SN-FieldLength
+}
+
+DL-UM-RLC ::= SEQUENCE {
+ sn-FieldLength SN-FieldLength,
+ t-Reordering T-Reordering
+}
+
+SN-FieldLength ::= ENUMERATED {size5, size10}
+
+T-PollRetransmit ::= ENUMERATED {
+ ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms105,
+ ms110, ms115, ms120, ms125, ms130, ms135,
+ ms140, ms145, ms150, ms155, ms160, ms165,
+ ms170, ms175, ms180, ms185, ms190, ms195,
+ ms200, ms205, ms210, ms215, ms220, ms225,
+ ms230, ms235, ms240, ms245, ms250, ms300,
+ ms350, ms400, ms450, ms500, spare9, spare8,
+ spare7, spare6, spare5, spare4, spare3,
+ spare2, spare1}
+
+PollPDU ::= ENUMERATED {
+ p4, p8, p16, p32, p64, p128, p256, pInfinity}
+
+PollByte ::= ENUMERATED {
+ kB25, kB50, kB75, kB100, kB125, kB250, kB375,
+ kB500, kB750, kB1000, kB1250, kB1500, kB2000,
+ kB3000, kBinfinity, spare1}
+
+T-Reordering ::= ENUMERATED {
+ ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms110,
+ ms120, ms130, ms140, ms150, ms160, ms170,
+ ms180, ms190, ms200, spare1}
+
+T-StatusProhibit ::= ENUMERATED {
+ ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms105,
+ ms110, ms115, ms120, ms125, ms130, ms135,
+ ms140, ms145, ms150, ms155, ms160, ms165,
+ ms170, ms175, ms180, ms185, ms190, ms195,
+ ms200, ms205, ms210, ms215, ms220, ms225,
+ ms230, ms235, ms240, ms245, ms250, ms300,
+ ms350, ms400, ms450, ms500, spare8, spare7,
+ spare6, spare5, spare4, spare3, spare2,
+ spare1}
+
+
+RLF-TimersAndConstants-r9 ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ t301-r9 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t310-r9 ENUMERATED {
+ ms0, ms50, ms100, ms200, ms500, ms1000, ms2000},
+ n310-r9 ENUMERATED {
+ n1, n2, n3, n4, n6, n8, n10, n20},
+ t311-r9 ENUMERATED {
+ ms1000, ms3000, ms5000, ms10000, ms15000,
+ ms20000, ms30000},
+ n311-r9 ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n8, n10},
+ ...
+ }
+}
+
+
+SchedulingRequestConfig ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ sr-PUCCH-ResourceIndex INTEGER (0..2047),
+ sr-ConfigIndex INTEGER (0..157),
+ dsr-TransMax ENUMERATED {
+ n4, n8, n16, n32, n64, spare3, spare2, spare1}
+ }
+}
+
+
+SoundingRS-UL-ConfigCommon ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ srs-BandwidthConfig ENUMERATED {bw0, bw1, bw2, bw3, bw4, bw5, bw6, bw7},
+ srs-SubframeConfig ENUMERATED {
+ sc0, sc1, sc2, sc3, sc4, sc5, sc6, sc7,
+ sc8, sc9, sc10, sc11, sc12, sc13, sc14, sc15},
+ ackNackSRS-SimultaneousTransmission BOOLEAN,
+ srs-MaxUpPts ENUMERATED {true} OPTIONAL -- Cond TDD
+ }
+}
+
+SoundingRS-UL-ConfigDedicated ::= CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ srs-Bandwidth ENUMERATED {bw0, bw1, bw2, bw3},
+ srs-HoppingBandwidth ENUMERATED {hbw0, hbw1, hbw2, hbw3},
+ freqDomainPosition INTEGER (0..23),
+ duration BOOLEAN,
+ srs-ConfigIndex INTEGER (0..1023),
+ transmissionComb INTEGER (0..1),
+ cyclicShift ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7}
+ }
+}
+
+
+
+SPS-Config ::= SEQUENCE {
+ semiPersistSchedC-RNTI C-RNTI OPTIONAL, -- Need OR
+ sps-ConfigDL SPS-ConfigDL OPTIONAL, -- Need ON
+ sps-ConfigUL SPS-ConfigUL OPTIONAL -- Need ON
+}
+
+SPS-ConfigDL ::= CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ semiPersistSchedIntervalDL ENUMERATED {
+ sf10, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ numberOfConfSPS-Processes INTEGER (1..8),
+ n1-PUCCH-AN-PersistentList N1-PUCCH-AN-PersistentList,
+ ...
+ }
+}
+
+SPS-ConfigUL ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ semiPersistSchedIntervalUL ENUMERATED {
+ sf10, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ implicitReleaseAfter ENUMERATED {e2, e3, e4, e8},
+ p0-Persistent SEQUENCE {
+ p0-NominalPUSCH-Persistent INTEGER (-126..24),
+ p0-UE-PUSCH-Persistent INTEGER (-8..7)
+ } OPTIONAL, -- Need OP
+ twoIntervalsConfig ENUMERATED {true} OPTIONAL, -- Cond TDD
+ ...
+ }
+}
+
+N1-PUCCH-AN-PersistentList ::= SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047)
+
+
+TDD-Config ::= SEQUENCE {
+ subframeAssignment ENUMERATED {
+ sa0, sa1, sa2, sa3, sa4, sa5, sa6},
+ specialSubframePatterns ENUMERATED {
+ ssp0, ssp1, ssp2, ssp3, ssp4,ssp5, ssp6, ssp7,
+ ssp8}
+}
+
+
+TimeAlignmentTimer ::= ENUMERATED {
+ sf500, sf750, sf1280, sf1920, sf2560, sf5120,
+ sf10240, infinity}
+
+TPC-PDCCH-Config ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ tpc-RNTI BIT STRING (SIZE (16)),
+ tpc-Index TPC-Index
+ }
+}
+
+TPC-Index ::= CHOICE {
+ indexOfFormat3 INTEGER (1..15),
+ indexOfFormat3A INTEGER (1..31)
+}
+
+
+UplinkPowerControlCommon ::= SEQUENCE {
+ p0-NominalPUSCH INTEGER (-126..24),
+ alpha ENUMERATED {al0, al04, al05, al06, al07, al08, al09, al1},
+ p0-NominalPUCCH INTEGER (-127..-96),
+ deltaFList-PUCCH DeltaFList-PUCCH,
+ deltaPreambleMsg3 INTEGER (-1..6)
+}
+
+UplinkPowerControlDedicated ::= SEQUENCE {
+ p0-UE-PUSCH INTEGER (-8..7),
+ deltaMCS-Enabled ENUMERATED {en0, en1},
+ accumulationEnabled BOOLEAN,
+ p0-UE-PUCCH INTEGER (-8..7),
+ pSRS-Offset INTEGER (0..15),
+ filterCoefficient FilterCoefficient DEFAULT fc4
+}
+
+DeltaFList-PUCCH ::= SEQUENCE {
+ deltaF-PUCCH-Format1 ENUMERATED {deltaF-2, deltaF0, deltaF2},
+ deltaF-PUCCH-Format1b ENUMERATED {deltaF1, deltaF3, deltaF5},
+ deltaF-PUCCH-Format2 ENUMERATED {deltaF-2, deltaF0, deltaF1, deltaF2},
+ deltaF-PUCCH-Format2a ENUMERATED {deltaF-2, deltaF0, deltaF2},
+ deltaF-PUCCH-Format2b ENUMERATED {deltaF-2, deltaF0, deltaF2}
+}
+
+
+NextHopChainingCount ::= INTEGER (0..7)
+
+
+SecurityAlgorithmConfig ::= SEQUENCE {
+ cipheringAlgorithm ENUMERATED {
+ eea0, eea1, eea2, spare5, spare4, spare3,
+ spare2, spare1, ...},
+ integrityProtAlgorithm ENUMERATED {
+ eia0-v920, eia1, eia2, spare5, spare4, spare3,
+ spare2, spare1, ...}
+}
+
+
+ShortMAC-I ::= BIT STRING (SIZE (16))
+
+
+AdditionalSpectrumEmission ::= INTEGER (1..32)
+
+
+ARFCN-ValueCDMA2000 ::= INTEGER (0..2047)
+
+
+ARFCN-ValueEUTRA ::= INTEGER (0..maxEARFCN)
+
+
+ARFCN-ValueGERAN ::= INTEGER (0..1023)
+
+
+ARFCN-ValueUTRA ::= INTEGER (0..16383)
+
+
+BandclassCDMA2000 ::= ENUMERATED {
+ bc0, bc1, bc2, bc3, bc4, bc5, bc6, bc7, bc8,
+ bc9, bc10, bc11, bc12, bc13, bc14, bc15, bc16,
+ bc17, spare14, spare13, spare12, spare11, spare10,
+ spare9, spare8, spare7, spare6, spare5, spare4,
+ spare3, spare2, spare1, ...}
+
+
+BandIndicatorGERAN ::= ENUMERATED {dcs1800, pcs1900}
+
+
+CarrierFreqCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ arfcn ARFCN-ValueCDMA2000
+}
+
+
+CarrierFreqGERAN ::= SEQUENCE {
+ arfcn ARFCN-ValueGERAN,
+ bandIndicator BandIndicatorGERAN
+}
+
+
+CarrierFreqsGERAN ::= SEQUENCE {
+ startingARFCN ARFCN-ValueGERAN,
+ bandIndicator BandIndicatorGERAN,
+ followingARFCNs CHOICE {
+ explicitListOfARFCNs ExplicitListOfARFCNs,
+ equallySpacedARFCNs SEQUENCE {
+ arfcn-Spacing INTEGER (1..8),
+ numberOfFollowingARFCNs INTEGER (0..31)
+ },
+ variableBitMapOfARFCNs OCTET STRING (SIZE (1..16))
+ }
+}
+
+ExplicitListOfARFCNs ::= SEQUENCE (SIZE (0..31)) OF ARFCN-ValueGERAN
+
+
+CDMA2000-Type ::= ENUMERATED {type1XRTT, typeHRPD}
+
+
+CellIdentity ::= BIT STRING (SIZE (28))
+
+
+CellIndexList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellIndex
+
+CellIndex ::= INTEGER (1..maxCellMeas)
+
+
+CellReselectionPriority ::= INTEGER (0..7)
+
+
+CSFB-RegistrationParam1XRTT ::= SEQUENCE {
+ sid BIT STRING (SIZE (15)),
+ nid BIT STRING (SIZE (16)),
+ multipleSID BOOLEAN,
+ multipleNID BOOLEAN,
+ homeReg BOOLEAN,
+ foreignSIDReg BOOLEAN,
+ foreignNIDReg BOOLEAN,
+ parameterReg BOOLEAN,
+ powerUpReg BOOLEAN,
+ registrationPeriod BIT STRING (SIZE (7)),
+ registrationZone BIT STRING (SIZE (12)),
+ totalZone BIT STRING (SIZE (3)),
+ zoneTimer BIT STRING (SIZE (3))
+}
+
+CSFB-RegistrationParam1XRTT-v920 ::= SEQUENCE {
+ powerDownReg-r9 ENUMERATED {true}
+}
+
+
+CellGlobalIdEUTRA ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellIdentity CellIdentity
+}
+
+
+CellGlobalIdUTRA ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellIdentity BIT STRING (SIZE (28))
+}
+
+
+CellGlobalIdGERAN ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ locationAreaCode BIT STRING (SIZE (16)),
+ cellIdentity BIT STRING (SIZE (16))
+}
+
+
+CellGlobalIdCDMA2000 ::= CHOICE {
+ cellGlobalId1XRTT BIT STRING (SIZE (47)),
+ cellGlobalIdHRPD BIT STRING (SIZE (128))
+}
+
+
+CSG-Identity ::= BIT STRING (SIZE (27))
+
+
+MobilityControlInfo ::= SEQUENCE {
+ targetPhysCellId PhysCellId,
+ carrierFreq CarrierFreqEUTRA OPTIONAL, -- Cond HO-toEUTRA
+ carrierBandwidth CarrierBandwidthEUTRA OPTIONAL, -- Cond HO-toEUTRA
+ additionalSpectrumEmission AdditionalSpectrumEmission OPTIONAL, -- Cond HO-toEUTRA
+ t304 ENUMERATED {
+ ms50, ms100, ms150, ms200, ms500, ms1000,
+ ms2000, spare1},
+ newUE-Identity C-RNTI,
+ radioResourceConfigCommon RadioResourceConfigCommon,
+ rach-ConfigDedicated RACH-ConfigDedicated OPTIONAL, -- Need OP
+ ...
+}
+
+CarrierBandwidthEUTRA ::= SEQUENCE {
+ dl-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100, spare10,
+ spare9, spare8, spare7, spare6, spare5,
+ spare4, spare3, spare2, spare1},
+ ul-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100, spare10,
+ spare9, spare8, spare7, spare6, spare5,
+ spare4, spare3, spare2, spare1} OPTIONAL -- Need OP
+}
+
+CarrierFreqEUTRA ::= SEQUENCE {
+ dl-CarrierFreq ARFCN-ValueEUTRA,
+ ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL -- Cond FDD
+}
+
+
+MobilityParametersCDMA2000 ::= OCTET STRING
+
+
+MobilityStateParameters ::= SEQUENCE {
+ t-Evaluation ENUMERATED {
+ s30, s60, s120, s180, s240, spare3, spare2, spare1},
+ t-HystNormal ENUMERATED {
+ s30, s60, s120, s180, s240, spare3, spare2, spare1},
+ n-CellChangeMedium INTEGER (1..16),
+ n-CellChangeHigh INTEGER (1..16)
+}
+
+
+PhysCellId ::= INTEGER (0..503)
+
+
+PhysCellIdRange ::= SEQUENCE {
+ start PhysCellId,
+ range ENUMERATED {
+ n4, n8, n12, n16, n24, n32, n48, n64, n84,
+ n96, n128, n168, n252, n504, spare2,
+ spare1} OPTIONAL -- Need OP
+}
+
+
+PhysCellIdCDMA2000 ::= INTEGER (0..maxPNOffset)
+
+
+PhysCellIdGERAN ::= SEQUENCE {
+ networkColourCode BIT STRING (SIZE (3)),
+ baseStationColourCode BIT STRING (SIZE (3))
+}
+
+
+PhysCellIdUTRA-FDD ::= INTEGER (0..511)
+
+
+PhysCellIdUTRA-TDD ::= INTEGER (0..127)
+
+
+PLMN-Identity ::= SEQUENCE {
+ mcc MCC OPTIONAL, -- Cond MCC
+ mnc MNC
+}
+
+MCC ::= SEQUENCE (SIZE (3)) OF
+ MCC-MNC-Digit
+
+MNC ::= SEQUENCE (SIZE (2..3)) OF
+ MCC-MNC-Digit
+
+MCC-MNC-Digit ::= INTEGER (0..9)
+
+
+
+PreRegistrationInfoHRPD ::= SEQUENCE {
+ preRegistrationAllowed BOOLEAN,
+ preRegistrationZoneId PreRegistrationZoneIdHRPD OPTIONAL, -- cond PreRegAllowed
+ secondaryPreRegistrationZoneIdList SecondaryPreRegistrationZoneIdListHRPD OPTIONAL -- Need OR
+}
+
+SecondaryPreRegistrationZoneIdListHRPD ::= SEQUENCE (SIZE (1..2)) OF PreRegistrationZoneIdHRPD
+
+PreRegistrationZoneIdHRPD ::= INTEGER (0..255)
+
+
+Q-QualMin-r9 ::= INTEGER (-34..-3)
+
+
+Q-RxLevMin ::= INTEGER (-70..-22)
+
+
+Q-OffsetRange ::= ENUMERATED {
+ dB-24, dB-22, dB-20, dB-18, dB-16, dB-14,
+ dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3,
+ dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5,
+ dB6, dB8, dB10, dB12, dB14, dB16, dB18,
+ dB20, dB22, dB24}
+
+
+Q-OffsetRangeInterRAT ::= INTEGER (-15..15)
+
+
+ReselectionThreshold ::= INTEGER (0..31)
+
+
+ReselectionThresholdQ-r9 ::= INTEGER (0..31)
+
+
+SpeedStateScaleFactors ::= SEQUENCE {
+ sf-Medium ENUMERATED {oDot25, oDot5, oDot75, lDot0},
+ sf-High ENUMERATED {oDot25, oDot5, oDot75, lDot0}
+}
+
+SystemInfoListGERAN ::= SEQUENCE (SIZE (1..maxGERAN-SI)) OF
+ OCTET STRING (SIZE (1..23))
+
+
+SystemTimeInfoCDMA2000 ::= SEQUENCE {
+ cdma-EUTRA-Synchronisation BOOLEAN,
+ cdma-SystemTime CHOICE {
+ synchronousSystemTime BIT STRING (SIZE (39)),
+ asynchronousSystemTime BIT STRING (SIZE (49))
+ }
+}
+
+
+TrackingAreaCode ::= BIT STRING (SIZE (16))
+
+
+T-Reselection ::= INTEGER (0..7)
+
+
+AllowedMeasBandwidth ::= ENUMERATED {mbw6, mbw15, mbw25, mbw50, mbw75, mbw100}
+
+
+Hysteresis ::= INTEGER (0..30)
+
+
+MeasConfig ::= SEQUENCE {
+ -- Measurement objects
+ measObjectToRemoveList MeasObjectToRemoveList OPTIONAL, -- Need ON
+ measObjectToAddModList MeasObjectToAddModList OPTIONAL, -- Need ON
+ -- Reporting configurations
+ reportConfigToRemoveList ReportConfigToRemoveList OPTIONAL, -- Need ON
+ reportConfigToAddModList ReportConfigToAddModList OPTIONAL, -- Need ON
+ -- Measurement identities
+ measIdToRemoveList MeasIdToRemoveList OPTIONAL, -- Need ON
+ measIdToAddModList MeasIdToAddModList OPTIONAL, -- Need ON
+ -- Other parameters
+ quantityConfig QuantityConfig OPTIONAL, -- Need ON
+ measGapConfig MeasGapConfig OPTIONAL, -- Need ON
+ s-Measure RSRP-Range OPTIONAL, -- Need ON
+ preRegistrationInfoHRPD PreRegistrationInfoHRPD OPTIONAL, -- Need OP
+ speedStatePars CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ mobilityStateParameters MobilityStateParameters,
+ timeToTrigger-SF SpeedStateScaleFactors
+ }
+ } OPTIONAL, -- Need ON
+ ...
+}
+
+MeasIdToRemoveList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasId
+
+MeasObjectToRemoveList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectId
+
+ReportConfigToRemoveList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigId
+
+
+MeasGapConfig ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ gapOffset CHOICE {
+ gp0 INTEGER (0..39),
+ gp1 INTEGER (0..79),
+ ...
+ }
+ }
+}
+
+
+MeasId ::= INTEGER (1..maxMeasId)
+
+
+MeasIdToAddModList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddMod
+
+MeasIdToAddMod ::= SEQUENCE {
+ measId MeasId,
+ measObjectId MeasObjectId,
+ reportConfigId ReportConfigId
+}
+
+
+MeasObjectCDMA2000 ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ carrierFreq CarrierFreqCDMA2000,
+ searchWindowSize INTEGER (0..15) OPTIONAL, -- Need ON
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CellsToAddModListCDMA2000 OPTIONAL, -- Need ON
+ cellForWhichToReportCGI PhysCellIdCDMA2000 OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModCDMA2000
+
+CellsToAddModCDMA2000 ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdCDMA2000
+}
+
+
+MeasObjectEUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ allowedMeasBandwidth AllowedMeasBandwidth,
+ presenceAntennaPort1 PresenceAntennaPort1,
+ neighCellConfig NeighCellConfig,
+ offsetFreq Q-OffsetRange DEFAULT dB0,
+ -- Neighbour cell list
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CellsToAddModList OPTIONAL, -- Need ON
+ -- Black list
+ blackCellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ blackCellsToAddModList BlackCellsToAddModList OPTIONAL, -- Need ON
+ cellForWhichToReportCGI PhysCellId OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddMod
+
+CellsToAddMod ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellId,
+ cellIndividualOffset Q-OffsetRange
+}
+
+BlackCellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF BlackCellsToAddMod
+
+BlackCellsToAddMod ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellIdRange PhysCellIdRange
+}
+
+
+MeasObjectGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ ncc-Permitted BIT STRING(SIZE (8)) DEFAULT '11111111'B,
+ cellForWhichToReportCGI PhysCellIdGERAN OPTIONAL, -- Need ON
+ ...
+}
+
+
+MeasObjectId ::= INTEGER (1..maxObjectId)
+
+
+MeasObjectToAddModList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectToAddMod
+
+MeasObjectToAddMod ::= SEQUENCE {
+ measObjectId MeasObjectId,
+ measObject CHOICE {
+ measObjectEUTRA MeasObjectEUTRA,
+ measObjectUTRA MeasObjectUTRA,
+ measObjectGERAN MeasObjectGERAN,
+ measObjectCDMA2000 MeasObjectCDMA2000,
+ ...
+ }
+}
+
+
+MeasObjectUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CHOICE {
+ cellsToAddModListUTRA-FDD CellsToAddModListUTRA-FDD,
+ cellsToAddModListUTRA-TDD CellsToAddModListUTRA-TDD
+ } OPTIONAL, -- Need ON
+ cellForWhichToReportCGI CHOICE {
+ utra-FDD PhysCellIdUTRA-FDD,
+ utra-TDD PhysCellIdUTRA-TDD
+ } OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModListUTRA-FDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-FDD
+
+CellsToAddModUTRA-FDD ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdUTRA-FDD
+}
+
+CellsToAddModListUTRA-TDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-TDD
+
+CellsToAddModUTRA-TDD ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdUTRA-TDD
+}
+
+
+MeasResults ::= SEQUENCE {
+ measId MeasId,
+ measResultServCell SEQUENCE {
+ rsrpResult RSRP-Range,
+ rsrqResult RSRQ-Range
+ },
+ measResultNeighCells CHOICE {
+ measResultListEUTRA MeasResultListEUTRA,
+ measResultListUTRA MeasResultListUTRA,
+ measResultListGERAN MeasResultListGERAN,
+ measResultsCDMA2000 MeasResultsCDMA2000,
+ ...
+ } OPTIONAL,
+ ...,
+ [[ measResultForECID-r9 MeasResultForECID-r9 OPTIONAL
+ ]]
+}
+
+MeasResultListEUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultEUTRA
+
+MeasResultEUTRA ::= SEQUENCE {
+ physCellId PhysCellId,
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdEUTRA,
+ trackingAreaCode TrackingAreaCode,
+ plmn-IdentityList PLMN-IdentityList2 OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ rsrpResult RSRP-Range OPTIONAL,
+ rsrqResult RSRQ-Range OPTIONAL,
+ ...,
+ [[ additionalSI-Info-r9 AdditionalSI-Info-r9 OPTIONAL
+ ]]
+ }
+}
+
+MeasResultListUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultUTRA
+
+MeasResultUTRA ::= SEQUENCE {
+ physCellId CHOICE {
+ fdd PhysCellIdUTRA-FDD,
+ tdd PhysCellIdUTRA-TDD
+ },
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdUTRA,
+ locationAreaCode BIT STRING (SIZE (16)) OPTIONAL,
+ routingAreaCode BIT STRING (SIZE (8)) OPTIONAL,
+ plmn-IdentityList PLMN-IdentityList2 OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ utra-RSCP INTEGER (-5..91) OPTIONAL,
+ utra-EcN0 INTEGER (0..49) OPTIONAL,
+ ...,
+ [[ additionalSI-Info-r9 AdditionalSI-Info-r9 OPTIONAL
+ ]]
+ }
+}
+
+MeasResultListGERAN ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultGERAN
+
+MeasResultGERAN ::= SEQUENCE {
+ carrierFreq CarrierFreqGERAN,
+ physCellId PhysCellIdGERAN,
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdGERAN,
+ routingAreaCode BIT STRING (SIZE (8)) OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ rssi INTEGER (0..63),
+ ...
+ }
+}
+
+MeasResultsCDMA2000 ::= SEQUENCE {
+ preRegistrationStatusHRPD BOOLEAN,
+ measResultListCDMA2000 MeasResultListCDMA2000
+}
+
+MeasResultListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultCDMA2000
+
+MeasResultCDMA2000 ::= SEQUENCE {
+ physCellId PhysCellIdCDMA2000,
+ cgi-Info CellGlobalIdCDMA2000 OPTIONAL,
+ measResult SEQUENCE {
+ pilotPnPhase INTEGER (0..32767) OPTIONAL,
+ pilotStrength INTEGER (0..63),
+ ...
+ }
+}
+
+MeasResultForECID-r9 ::= SEQUENCE {
+ ue-RxTxTimeDiffResult-r9 INTEGER (0..4095),
+ currentSFN-r9 BIT STRING (SIZE (10))
+}
+
+PLMN-IdentityList2 ::= SEQUENCE (SIZE (1..5)) OF PLMN-Identity
+
+AdditionalSI-Info-r9 ::= SEQUENCE {
+ csg-MemberStatus-r9 ENUMERATED {member} OPTIONAL,
+ csg-Identity-r9 CSG-Identity OPTIONAL
+}
+
+
+QuantityConfig ::= SEQUENCE {
+ quantityConfigEUTRA QuantityConfigEUTRA OPTIONAL, -- Need ON
+ quantityConfigUTRA QuantityConfigUTRA OPTIONAL, -- Need ON
+ quantityConfigGERAN QuantityConfigGERAN OPTIONAL, -- Need ON
+ quantityConfigCDMA2000 QuantityConfigCDMA2000 OPTIONAL, -- Need ON
+ ...
+}
+
+QuantityConfigEUTRA ::= SEQUENCE {
+ filterCoefficientRSRP FilterCoefficient DEFAULT fc4,
+ filterCoefficientRSRQ FilterCoefficient DEFAULT fc4
+}
+
+QuantityConfigUTRA ::= SEQUENCE {
+ measQuantityUTRA-FDD ENUMERATED {cpich-RSCP, cpich-EcN0},
+ measQuantityUTRA-TDD ENUMERATED {pccpch-RSCP},
+ filterCoefficient FilterCoefficient DEFAULT fc4
+}
+
+QuantityConfigGERAN ::= SEQUENCE {
+ measQuantityGERAN ENUMERATED {rssi},
+ filterCoefficient FilterCoefficient DEFAULT fc2
+}
+
+QuantityConfigCDMA2000 ::= SEQUENCE {
+ measQuantityCDMA2000 ENUMERATED {pilotStrength, pilotPnPhaseAndPilotStrength}
+}
+
+
+ReportConfigEUTRA ::= SEQUENCE {
+ triggerType CHOICE {
+ event SEQUENCE {
+ eventId CHOICE {
+ eventA1 SEQUENCE {
+ a1-Threshold ThresholdEUTRA
+ },
+ eventA2 SEQUENCE {
+ a2-Threshold ThresholdEUTRA
+ },
+ eventA3 SEQUENCE {
+ a3-Offset INTEGER (-30..30),
+ reportOnLeave BOOLEAN
+ },
+ eventA4 SEQUENCE {
+ a4-Threshold ThresholdEUTRA
+ },
+ eventA5 SEQUENCE {
+ a5-Threshold1 ThresholdEUTRA,
+ a5-Threshold2 ThresholdEUTRA
+ },
+ ...
+ },
+ hysteresis Hysteresis,
+ timeToTrigger TimeToTrigger
+ },
+ periodical SEQUENCE {
+ purpose ENUMERATED {
+ reportStrongestCells, reportCGI}
+ }
+ },
+ triggerQuantity ENUMERATED {rsrp, rsrq},
+ reportQuantity ENUMERATED {sameAsTriggerQuantity, both},
+ maxReportCells INTEGER (1..maxCellReport),
+ reportInterval ReportInterval,
+ reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity},
+ ...,
+ [[ si-RequestForHO-r9 ENUMERATED {setup} OPTIONAL, -- Cond reportCGI
+ ue-RxTxTimeDiffPeriodical-r9 ENUMERATED {setup} OPTIONAL -- Need OR
+ ]]
+}
+
+ThresholdEUTRA ::= CHOICE{
+ threshold-RSRP RSRP-Range,
+ threshold-RSRQ RSRQ-Range
+}
+
+
+ReportConfigId ::= INTEGER (1..maxReportConfigId)
+
+
+ReportConfigInterRAT ::= SEQUENCE {
+ triggerType CHOICE {
+ event SEQUENCE {
+ eventId CHOICE {
+ eventB1 SEQUENCE {
+ b1-Threshold CHOICE {
+ b1-ThresholdUTRA ThresholdUTRA,
+ b1-ThresholdGERAN ThresholdGERAN,
+ b1-ThresholdCDMA2000 ThresholdCDMA2000
+ }
+ },
+ eventB2 SEQUENCE {
+ b2-Threshold1 ThresholdEUTRA,
+ b2-Threshold2 CHOICE {
+ b2-Threshold2UTRA ThresholdUTRA,
+ b2-Threshold2GERAN ThresholdGERAN,
+ b2-Threshold2CDMA2000 ThresholdCDMA2000
+ }
+ },
+ ...
+ },
+ hysteresis Hysteresis,
+ timeToTrigger TimeToTrigger
+ },
+ periodical SEQUENCE {
+ purpose ENUMERATED {
+ reportStrongestCells,
+ reportStrongestCellsForSON,
+ reportCGI}
+ }
+ },
+ maxReportCells INTEGER (1..maxCellReport),
+ reportInterval ReportInterval,
+ reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity},
+ ...,
+ [[ si-RequestForHO-r9 ENUMERATED {setup} OPTIONAL -- Cond reportCGI
+ ]]
+}
+
+ThresholdUTRA ::= CHOICE{
+ utra-RSCP INTEGER (-5..91),
+ utra-EcN0 INTEGER (0..49)
+}
+
+ThresholdGERAN ::= INTEGER (0..63)
+
+ThresholdCDMA2000 ::= INTEGER (0..63)
+
+
+ReportConfigToAddModList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigToAddMod
+
+ReportConfigToAddMod ::= SEQUENCE {
+ reportConfigId ReportConfigId,
+ reportConfig CHOICE {
+ reportConfigEUTRA ReportConfigEUTRA,
+ reportConfigInterRAT ReportConfigInterRAT
+ }
+}
+
+
+
+ReportInterval ::= ENUMERATED {
+ ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240,
+ min1, min6, min12, min30, min60, spare3, spare2, spare1}
+
+
+RSRP-Range ::= INTEGER(0..97)
+
+
+RSRQ-Range ::= INTEGER(0..34)
+
+
+TimeToTrigger ::= ENUMERATED {
+ ms0, ms40, ms64, ms80, ms100, ms128, ms160, ms256,
+ ms320, ms480, ms512, ms640, ms1024, ms1280, ms2560,
+ ms5120}
+
+
+C-RNTI ::= BIT STRING (SIZE (16))
+
+
+DedicatedInfoCDMA2000 ::= OCTET STRING
+
+
+DedicatedInfoNAS ::= OCTET STRING
+
+
+FilterCoefficient ::= ENUMERATED {
+ fc0, fc1, fc2, fc3, fc4, fc5,
+ fc6, fc7, fc8, fc9, fc11, fc13,
+ fc15, fc17, fc19, spare1, ...}
+
+
+MMEC ::= BIT STRING (SIZE (8))
+
+
+NeighCellConfig ::= BIT STRING (SIZE (2))
+
+
+OtherConfig-r9 ::= SEQUENCE {
+ reportProximityConfig-r9 ReportProximityConfig-r9 OPTIONAL, -- Need ON
+ ...
+}
+
+ReportProximityConfig-r9 ::= SEQUENCE {
+ proximityIndicationEUTRA-r9 ENUMERATED {enabled} OPTIONAL, -- Need OR
+ proximityIndicationUTRA-r9 ENUMERATED {enabled} OPTIONAL -- Need OR
+}
+
+
+RAND-CDMA2000 ::= BIT STRING (SIZE (32))
+
+
+RAT-Type ::= ENUMERATED {
+ eutra, utra, geran-cs, geran-ps, cdma2000-1XRTT,
+ spare3, spare2, spare1, ...}
+
+
+RRC-TransactionIdentifier ::= INTEGER (0..3)
+
+
+S-TMSI ::= SEQUENCE {
+ mmec MMEC,
+ m-TMSI BIT STRING (SIZE (32))
+}
+
+
+UE-CapabilityRAT-ContainerList ::=SEQUENCE (SIZE (0..maxRAT-Capabilities)) OF UE-CapabilityRAT-Container
+
+UE-CapabilityRAT-Container ::= SEQUENCE {
+ rat-Type RAT-Type,
+ ueCapabilityRAT-Container OCTET STRING
+}
+
+
+UE-EUTRA-Capability ::= SEQUENCE {
+ accessStratumRelease AccessStratumRelease,
+ ue-Category INTEGER (1..5),
+ pdcp-Parameters PDCP-Parameters,
+ phyLayerParameters PhyLayerParameters,
+ rf-Parameters RF-Parameters,
+ measParameters MeasParameters,
+ featureGroupIndicators BIT STRING (SIZE (32)) OPTIONAL,
+ interRAT-Parameters SEQUENCE {
+ utraFDD IRAT-ParametersUTRA-FDD OPTIONAL,
+ utraTDD128 IRAT-ParametersUTRA-TDD128 OPTIONAL,
+ utraTDD384 IRAT-ParametersUTRA-TDD384 OPTIONAL,
+ utraTDD768 IRAT-ParametersUTRA-TDD768 OPTIONAL,
+ geran IRAT-ParametersGERAN OPTIONAL,
+ cdma2000-HRPD IRAT-ParametersCDMA2000-HRPD OPTIONAL,
+ cdma2000-1xRTT IRAT-ParametersCDMA2000-1XRTT OPTIONAL
+ },
+ nonCriticalExtension UE-EUTRA-Capability-v920-IEs OPTIONAL
+}
+
+UE-EUTRA-Capability-v920-IEs ::= SEQUENCE {
+ phyLayerParameters-v920 PhyLayerParameters-v920,
+ interRAT-ParametersGERAN-v920 IRAT-ParametersGERAN-v920,
+ interRAT-ParametersUTRA-v920 IRAT-ParametersUTRA-v920 OPTIONAL,
+ interRAT-Parameters-v920 IRAT-ParametersCDMA2000-1XRTT-v920 OPTIONAL,
+ deviceType-r9 ENUMERATED {noBenFromBatConsumpOpt} OPTIONAL,
+ csg-ProximityIndicationParameters-r9 CSG-ProximityIndicationParameters-r9,
+ neighCellSI-AcquisitionParameters-r9 NeighCellSI-AcquisitionParameters-r9,
+ son-Parameters-r9 SON-Parameters-r9,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+AccessStratumRelease ::= ENUMERATED {
+ rel8, rel9, spare6, spare5, spare4, spare3,
+ spare2, spare1, ...}
+
+PDCP-Parameters ::= SEQUENCE {
+ supportedROHC-Profiles SEQUENCE {
+ profile0x0001 BOOLEAN,
+ profile0x0002 BOOLEAN,
+ profile0x0003 BOOLEAN,
+ profile0x0004 BOOLEAN,
+ profile0x0006 BOOLEAN,
+ profile0x0101 BOOLEAN,
+ profile0x0102 BOOLEAN,
+ profile0x0103 BOOLEAN,
+ profile0x0104 BOOLEAN
+ },
+ maxNumberROHC-ContextSessions ENUMERATED {
+ cs2, cs4, cs8, cs12, cs16, cs24, cs32,
+ cs48, cs64, cs128, cs256, cs512, cs1024,
+ cs16384, spare2, spare1} DEFAULT cs16,
+ ...
+}
+
+PhyLayerParameters ::= SEQUENCE {
+ ue-TxAntennaSelectionSupported BOOLEAN,
+ ue-SpecificRefSigsSupported BOOLEAN
+}
+
+PhyLayerParameters-v920 ::= SEQUENCE {
+ enhancedDualLayerFDD-Supported-r9 BOOLEAN,
+ enhancedDualLayerTDD-Supported-r9 BOOLEAN
+}
+
+RF-Parameters ::= SEQUENCE {
+ supportedBandListEUTRA SupportedBandListEUTRA
+}
+
+SupportedBandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA
+
+SupportedBandEUTRA ::= SEQUENCE {
+ bandEUTRA INTEGER (1..64),
+ halfDuplex BOOLEAN
+}
+
+MeasParameters ::= SEQUENCE {
+ bandListEUTRA BandListEUTRA
+}
+
+BandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF BandInfoEUTRA
+
+BandInfoEUTRA ::= SEQUENCE {
+ interFreqBandList InterFreqBandList,
+ interRAT-BandList InterRAT-BandList OPTIONAL
+}
+
+InterFreqBandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterFreqBandInfo
+
+InterFreqBandInfo ::= SEQUENCE {
+ interFreqNeedForGaps BOOLEAN
+}
+
+InterRAT-BandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterRAT-BandInfo
+
+InterRAT-BandInfo ::= SEQUENCE {
+ interRAT-NeedForGaps BOOLEAN
+}
+
+IRAT-ParametersUTRA-FDD ::= SEQUENCE {
+ supportedBandListUTRA-FDD SupportedBandListUTRA-FDD
+}
+
+IRAT-ParametersUTRA-v920 ::= SEQUENCE {
+ e-Redirection-r9 ENUMERATED {supported}
+}
+
+SupportedBandListUTRA-FDD ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-FDD
+
+SupportedBandUTRA-FDD ::= ENUMERATED {
+ bandI, bandII, bandIII, bandIV, bandV, bandVI,
+ bandVII, bandVIII, bandIX, bandX, bandXI,
+ bandXII, bandXIII, bandXIV, bandXV, bandXVI, ...}
+
+IRAT-ParametersUTRA-TDD128 ::= SEQUENCE {
+ supportedBandListUTRA-TDD128 SupportedBandListUTRA-TDD128
+}
+
+SupportedBandListUTRA-TDD128 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD128
+
+SupportedBandUTRA-TDD128 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersUTRA-TDD384 ::= SEQUENCE {
+ supportedBandListUTRA-TDD384 SupportedBandListUTRA-TDD384
+}
+
+SupportedBandListUTRA-TDD384 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD384
+
+SupportedBandUTRA-TDD384 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersUTRA-TDD768 ::= SEQUENCE {
+ supportedBandListUTRA-TDD768 SupportedBandListUTRA-TDD768
+}
+
+SupportedBandListUTRA-TDD768 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD768
+
+SupportedBandUTRA-TDD768 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersGERAN ::= SEQUENCE {
+ supportedBandListGERAN SupportedBandListGERAN,
+ interRAT-PS-HO-ToGERAN BOOLEAN
+}
+
+IRAT-ParametersGERAN-v920 ::= SEQUENCE {
+ dtm-r9 ENUMERATED {supported} OPTIONAL,
+ e-RedirectionGERAN-r9 ENUMERATED {supported} OPTIONAL
+}
+
+SupportedBandListGERAN ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandGERAN
+
+SupportedBandGERAN ::= ENUMERATED {
+ gsm450, gsm480, gsm710, gsm750, gsm810, gsm850,
+ gsm900P, gsm900E, gsm900R, gsm1800, gsm1900,
+ spare5, spare4, spare3, spare2, spare1, ...}
+
+IRAT-ParametersCDMA2000-HRPD ::= SEQUENCE {
+ supportedBandListHRPD SupportedBandListHRPD,
+ tx-ConfigHRPD ENUMERATED {single, dual},
+ rx-ConfigHRPD ENUMERATED {single, dual}
+}
+
+SupportedBandListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000
+
+IRAT-ParametersCDMA2000-1XRTT ::= SEQUENCE {
+ supportedBandList1XRTT SupportedBandList1XRTT,
+ tx-Config1XRTT ENUMERATED {single, dual},
+ rx-Config1XRTT ENUMERATED {single, dual}
+}
+
+IRAT-ParametersCDMA2000-1XRTT-v920 ::= SEQUENCE {
+ e-CSFB-r9 ENUMERATED {supported},
+ e-CSFB-ConcPS-Mob-r9 ENUMERATED {notSupported, supported}
+}
+
+SupportedBandList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000
+
+CSG-ProximityIndicationParameters-r9 ::= SEQUENCE {
+ intraFreqProximityIndicationSupported-r9 BOOLEAN,
+ interFreqProximityIndicationSupported-r9 BOOLEAN,
+ utran-ProximityIndicationSupported-r9 BOOLEAN
+}
+
+NeighCellSI-AcquisitionParameters-r9 ::= SEQUENCE {
+ intraFreqSI-AcquisitionForHO-Supported-r9 BOOLEAN,
+ interFreqSI-AcquisitionForHO-Supported-r9 BOOLEAN,
+ utran-SI-AcquisitionForHO-Supported-r9 BOOLEAN
+}
+
+SON-Parameters-r9 ::= SEQUENCE {
+ rach-ReportSupported-r9 BOOLEAN
+}
+
+
+UE-TimersAndConstants ::= SEQUENCE {
+ t300 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t301 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t310 ENUMERATED {
+ ms0, ms50, ms100, ms200, ms500, ms1000, ms2000},
+ n310 ENUMERATED {
+ n1, n2, n3, n4, n6, n8, n10, n20},
+ t311 ENUMERATED {
+ ms1000, ms3000, ms5000, ms10000, ms15000,
+ ms20000, ms30000},
+ n311 ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n8, n10},
+ ...
+}
+
+
+MBMS-NotificationConfig-r9 ::= SEQUENCE {
+ notificationRepetitionCoeff-r9 ENUMERATED {n2, n4},
+ notificationOffset-r9 INTEGER (0..10),
+ notificationSF-Index-r9 INTEGER (1..6)
+}
+
+
+MBSFN-AreaInfoList-r9 ::= SEQUENCE (SIZE(1..maxMBSFN-Area)) OF MBSFN-AreaInfo-r9
+
+MBSFN-AreaInfo-r9 ::= SEQUENCE {
+ mbsfn-AreaId-r9 INTEGER (0..255),
+ non-MBSFNregionLength ENUMERATED {s1, s2},
+ notificationIndicator-r9 INTEGER (0..7),
+ mcch-Config-r9 SEQUENCE {
+ mcch-RepetitionPeriod-r9 ENUMERATED {rf32, rf64, rf128, rf256},
+ mcch-Offset-r9 INTEGER (0..10),
+ mcch-ModificationPeriod-r9 ENUMERATED {rf512, rf1024},
+ sf-AllocInfo-r9 BIT STRING (SIZE(6)),
+ signallingMCS-r9 ENUMERATED {n2, n7, n13, n19}
+ },
+ ...
+}
+
+
+MBSFN-SubframeConfig ::= SEQUENCE {
+ radioframeAllocationPeriod ENUMERATED {n1, n2, n4, n8, n16, n32},
+ radioframeAllocationOffset INTEGER (0..7),
+ subframeAllocation CHOICE {
+ oneFrame BIT STRING (SIZE(6)),
+ fourFrames BIT STRING (SIZE(24))
+ }
+}
+
+PMCH-InfoList-r9 ::= SEQUENCE (SIZE (0..maxPMCH-PerMBSFN)) OF PMCH-Info-r9
+
+PMCH-Info-r9 ::= SEQUENCE {
+ pmch-Config-r9 PMCH-Config-r9,
+ mbms-SessionInfoList-r9 MBMS-SessionInfoList-r9,
+ ...
+}
+
+MBMS-SessionInfoList-r9 ::= SEQUENCE (SIZE (0..maxSessionPerPMCH)) OF MBMS-SessionInfo-r9
+
+MBMS-SessionInfo-r9 ::= SEQUENCE {
+ tmgi-r9 TMGI-r9,
+ sessionId-r9 OCTET STRING (SIZE (1)) OPTIONAL, -- Need OR
+ logicalChannelIdentity-r9 INTEGER (0..maxSessionPerPMCH-1),
+ ...
+}
+
+PMCH-Config-r9 ::= SEQUENCE {
+ sf-AllocEnd-r9 INTEGER (0..1535),
+ dataMCS-r9 INTEGER (0..28),
+ mch-SchedulingPeriod-r9 ENUMERATED {
+ rf8, rf16, rf32, rf64, rf128, rf256, rf512, rf1024},
+ ...
+}
+
+TMGI-r9 ::= SEQUENCE {
+ plmn-Id-r9 CHOICE {
+ plmn-Index-r9 INTEGER (1..6),
+ explicitValue-r9 PLMN-Identity
+ },
+ serviceId-r9 OCTET STRING (SIZE (3))
+}
+
+
+maxBands INTEGER ::= 64 -- Maximum number of bands listed in EUTRA UE caps
+maxCDMA-BandClass INTEGER ::= 32 -- Maximum value of the CDMA band classes
+maxCellBlack INTEGER ::= 16 -- Maximum number of blacklisted cells
+ -- listed in SIB type 4 and 5
+maxCellInter INTEGER ::= 16 -- Maximum number of neighbouring inter-frequency
+ -- cells listed in SIB type 5
+maxCellIntra INTEGER ::= 16 -- Maximum number of neighbouring intra-frequency
+ -- cells listed in SIB type 4
+maxCellMeas INTEGER ::= 32 -- Maximum number of entries in each of the neighbour
+ -- cell lists in a measurement object
+maxCellReport INTEGER ::= 8 -- Maximum number of reported cells
+maxDRB INTEGER ::= 11 -- Maximum number of Data Radio Bearers
+maxEARFCN INTEGER ::= 65535 -- Maximum value of EUTRA carrier fequency
+maxFreq INTEGER ::= 8 -- Maximum number of EUTRA carrier frequencies
+maxCellInfo-GERAN-r9 INTEGER ::= 32 -- Maximum number of GERAN cells for which system in-
+ -- formation can be provided as redirection assistance
+maxGERAN-SI INTEGER ::= 10 -- Maximum number of GERAN SI blocks that can be
+ -- provided as part of NACC information
+maxGNFG INTEGER ::= 16 -- Maximum number of GERAN neighbour freq groups
+maxMBSFN-Allocations INTEGER ::= 8 -- Maximum number of MBSFN frame allocations with
+ -- different offset
+maxMBSFN-Area INTEGER ::= 8
+maxSessionPerPMCH INTEGER ::= 29
+maxSessionPerPMCH-1 INTEGER ::= 28
+maxPMCH-PerMBSFN INTEGER ::= 15
+maxMeasId INTEGER ::= 32
+maxObjectId INTEGER ::= 32
+maxPageRec INTEGER ::= 16 --
+maxPNOffset INTEGER ::= 511 -- Maximum number of CDMA2000 PNOffsets
+maxRAT-Capabilities INTEGER ::= 8 -- Maximum number of interworking RATs (incl EUTRA)
+maxReportConfigId INTEGER ::= 32
+maxSIB INTEGER ::= 32 -- Maximum number of SIBs
+maxSIB-1 INTEGER ::= 31
+maxSI-Message INTEGER ::= 32 -- Maximum number of SI messages
+maxUTRA-FDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA FDD carrier frequencies
+maxUTRA-TDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA TDD carrier frequencies
+maxUTRA-CellInfo-r9 INTEGER ::= 16 -- Maximum number of cells for which system information
+ -- can be provided as redirection assistance
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
index c86c787610..5fcec23756 100644
--- a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
+++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl
@@ -54,3 +54,79 @@ run2(Erule) ->
Val -> ok;
_ -> exit({expected,Val, got, Val2})
end.
+
+run3(Erule) ->
+ Val =
+{'RRC-DL-DCCH-Message',
+ {c1,
+ {rrcConnectionReconfiguration,
+ {'RRC-RRCConnectionReconfiguration',0,
+ {c1,
+ {'rrcConnectionReconfiguration-r8',
+ {'RRC-RRCConnectionReconfiguration-r8-IEs',
+ {'RRC-MeasConfig',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,
+ asn1_NOVALUE,asn1_NOVALUE},
+ asn1_NOVALUE,
+ [[80,66,0,5,10,0,5,0,24,11,7,84,54,33,0,1,1,0,0,0,1,39,5,66,127,0,0,1],
+ []],
+ {'RRC-RadioResourceConfigDedicated',
+ [{'RRC-SRB-ToAddMod',1,
+ {explicitValue,
+ {am,
+ {'RRC-RLC-Config_am',
+ {'RRC-UL-AM-RLC',ms45,pInfinity,kBinfinity,t4},
+ {'RRC-DL-AM-RLC',ms35,ms0}}}},
+ {explicitValue,
+ {'RRC-LogicalChannelConfig',
+ {'RRC-LogicalChannelConfig_ul-SpecificParameters',3,infinity,
+ ms50,0},
+ asn1_NOVALUE}}}],
+ [{'RRC-DRB-ToAddMod',3,3,
+ {'RRC-PDCP-Config',infinity,
+ {'RRC-PDCP-Config_rlc-AM',false},
+ asn1_NOVALUE,
+ {notUsed,'NULL'}},
+ {am,
+ {'RRC-RLC-Config_am',
+ {'RRC-UL-AM-RLC',ms70,p256,kBinfinity,t4},
+ {'RRC-DL-AM-RLC',ms35,ms40}}},
+ 3,
+ {'RRC-LogicalChannelConfig',
+ {'RRC-LogicalChannelConfig_ul-SpecificParameters',5,infinity,ms50,
+ 1},
+ asn1_NOVALUE}},
+ {'RRC-DRB-ToAddMod',4,4,
+ {'RRC-PDCP-Config',infinity,
+ {'RRC-PDCP-Config_rlc-AM',false},
+ asn1_NOVALUE,
+ {notUsed,'NULL'}},
+ {am,
+ {'RRC-RLC-Config_am',
+ {'RRC-UL-AM-RLC',ms70,p256,kBinfinity,t4},
+ {'RRC-DL-AM-RLC',ms35,ms40}}},
+ 4,
+ {'RRC-LogicalChannelConfig',
+ {'RRC-LogicalChannelConfig_ul-SpecificParameters',5,infinity,ms50,
+ 1},
+ asn1_NOVALUE}}],
+ asn1_NOVALUE,
+ {explicitValue,
+ {'RRC-MAC-MainConfig',
+ {'RRC-MAC-MainConfig_ul-SCH-Config',n4,sf10,sf10240,false},
+ asn1_NOVALUE,sf500,
+ {setup,{'RRC-MAC-MainConfig_phr-Config_setup',sf200,sf200,dB3}},
+ asn1_NOVALUE}},
+ asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
+ asn1_NOVALUE,asn1_NOVALUE}}}}}}},
+ io:format("~p:~p~n",[Erule,Val]),
+ {ok,List}= asn1rt:encode('EUTRA-RRC-Definitions','DL-DCCH-Message',Val),
+ Enc = iolist_to_binary(List),
+ io:format("Result from encode:~n~p~n",[Enc]),
+ {ok,Val2} = asn1rt:decode('EUTRA-RRC-Definitions','DL-DCCH-Message',Enc),
+ io:format("Result from decode:~n~p~n",[Val2]),
+ case Val2 of
+ Val -> ok;
+ _ -> exit({expected,Val, got, Val2})
+ end.
+
diff --git a/lib/asn1/test/asn1_app_test.erl b/lib/asn1/test/asn1_app_test.erl
index 23a7e691e7..c3797f08b2 100644
--- a/lib/asn1/test/asn1_app_test.erl
+++ b/lib/asn1/test/asn1_app_test.erl
@@ -26,21 +26,24 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- fields,
- modules,
- exportall,
- app_depend
- ],
- {req, [], {conf, app_init, Cases, app_fin}}.
+all() ->
+ [fields, modules, exportall, app_depend].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-app_init(suite) -> [];
-app_init(doc) -> [];
-app_init(Config) when is_list(Config) ->
+init_per_suite(suite) -> [];
+init_per_suite(doc) -> [];
+init_per_suite(Config) when is_list(Config) ->
case is_app(asn1) of
{ok, AppFile} ->
io:format("AppFile: ~n~p~n", [AppFile]),
@@ -60,9 +63,9 @@ is_app(App) ->
end.
-app_fin(suite) -> [];
-app_fin(doc) -> [];
-app_fin(Config) when is_list(Config) ->
+end_per_suite(suite) -> [];
+end_per_suite(doc) -> [];
+end_per_suite(Config) when is_list(Config) ->
Config.
diff --git a/lib/asn1/test/asn1_appup_test.erl b/lib/asn1/test/asn1_appup_test.erl
index 4a60c814e8..a2c1423eda 100644
--- a/lib/asn1/test/asn1_appup_test.erl
+++ b/lib/asn1/test/asn1_appup_test.erl
@@ -26,18 +26,24 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- appup
- ],
- {req, [], {conf, appup_init, Cases, appup_fin}}.
+all() ->
+ [appup].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-appup_init(suite) -> [];
-appup_init(doc) -> [];
-appup_init(Config) when is_list(Config) ->
+init_per_suite(suite) -> [];
+init_per_suite(doc) -> [];
+init_per_suite(Config) when is_list(Config) ->
AppFile = file_name(asn1, ".app"),
AppupFile = file_name(asn1, ".appup"),
[{app_file, AppFile}, {appup_file, AppupFile}|Config].
@@ -48,9 +54,9 @@ file_name(App, Ext) ->
filename:join([LibDir, "ebin", atom_to_list(App) ++ Ext]).
-appup_fin(suite) -> [];
-appup_fin(doc) -> [];
-appup_fin(Config) when is_list(Config) ->
+end_per_suite(suite) -> [];
+end_per_suite(doc) -> [];
+end_per_suite(Config) when is_list(Config) ->
Config.
diff --git a/lib/asn1/test/asn1_bin_SUITE.erl b/lib/asn1/test/asn1_bin_SUITE.erl
new file mode 100644
index 0000000000..d8c5dd5b27
--- /dev/null
+++ b/lib/asn1/test/asn1_bin_SUITE.erl
@@ -0,0 +1,2382 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%% Purpose : Test suite for the ASN.1 application
+
+-module(asn1_bin_SUITE).
+-define(PER,'per_bin').
+-define(BER,'ber_bin').
+-define(ber_driver(Erule,Func),
+ case Erule of
+ ber_bin_v2 ->
+ Func;
+ _ -> ok
+ end).
+-define(per_optimize(Erule),
+ case Erule of
+ ber_bin_v2 ->[optimize];
+ _ -> []
+ end).
+-define(per_bit_opt(FuncCall),
+ case ?BER of
+ ber_bin_v2 -> FuncCall;
+% _ -> {skip,"only for bit optimized per_bin"}
+ _ -> ok
+ end).
+-define(uper_bin(FuncCall),
+ case ?PER of
+ per -> FuncCall;
+ _ -> ok
+ end).
+
+-compile(export_all).
+%%-export([Function/Arity, ...]).
+
+-include_lib("test_server/include/test_server.hrl").
+
+%% records used by test-case default
+-record('Def1',{bool0, bool1 = asn1_DEFAULT,
+ bool2 = asn1_DEFAULT,
+ bool3 = asn1_DEFAULT}).
+
+%-record('Def2',{
+%bool10, bool11 = asn1_DEFAULT, bool12 = asn1_DEFAULT, bool13}).
+
+%-record('Def3',{
+%bool30 = asn1_DEFAULT, bool31 = asn1_DEFAULT, bool32 = asn1_DEFAULT, bool33 = asn1_DEFAULT}).
+
+
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, compile}, parse, default_per, default_ber,
+ default_per_opt, per, {group, ber}, testPrim,
+ testPrimStrings, testPrimExternal, testChoPrim,
+ testChoExtension, testChoExternal, testChoOptional,
+ testChoOptionalImplicitTag, testChoRecursive,
+ testChoTypeRefCho, testChoTypeRefPrim,
+ testChoTypeRefSeq, testChoTypeRefSet, testDef, testOpt,
+ testSeqDefault, testSeqExtension, testSeqExternal,
+ testSeqOptional, testSeqPrim, testSeqTag,
+ testSeqTypeRefCho, testSeqTypeRefPrim,
+ testSeqTypeRefSeq, testSeqTypeRefSet, testSeqOf,
+ testSeqOfIndefinite, testSeqOfCho, testSeqOfExternal,
+ testSetDefault, testSetExtension,
+ testExtensionAdditionGroup, testSetExternal,
+ testSeqOfTag, testSetOptional, testSetPrim, testSetTag,
+ testSetTypeRefCho, testSetTypeRefPrim,
+ testSetTypeRefSeq, testSetTypeRefSet, testSetOf,
+ testSetOfCho, testSetOfExternal, testSetOfTag,
+ testEnumExt, value_test, testSeq2738, constructed,
+ ber_decode_error, h323test, testSeqIndefinite,
+ testSetIndefinite, testChoiceIndefinite,
+ per_GeneralString, per_open_type, testInfObjectClass,
+ testParameterizedInfObj, testMergeCompile, testobj,
+ testDeepTConstr, testConstraints, testInvokeMod,
+ testExport, testImport, testCompactBitString,
+ testMegaco, testParamBasic, testMvrasn6,
+ testContextSwitchingTypes, testTypeValueNotation,
+ testOpenTypeImplicitTag, duplicate_tags, rtUI, testROSE,
+ testINSTANCE_OF, testTCAP, testDER, specialized_decodes,
+ special_decode_performance, test_driver_load,
+ test_ParamTypeInfObj, test_WS_ParamClass,
+ test_Defed_ObjectIdentifier, testSelectionType,
+ testSSLspecs, testNortel, test_undecoded_rest,
+ test_inline, testTcapsystem, testNBAPsystem,
+ test_compile_options, testDoubleEllipses,
+ test_modified_x420, testX420, test_x691, ticket_6143,
+ testExtensionAdditionGroup] ++ common() ++ particular().
+
+groups() ->
+ [{option_tests, [],
+ [test_compile_options, ticket_6143]},
+ {infobj, [],
+ [testInfObjectClass, testParameterizedInfObj,
+ testMergeCompile, testobj, testDeepTConstr]},
+ {performance, [],
+ [testTimer_ber, testTimer_ber_opt_driver, testTimer_per,
+ testTimer_per_opt, testTimer_uper_bin]},
+ {bugs, [],
+ [test_ParamTypeInfObj, test_WS_ParamClass,
+ test_Defed_ObjectIdentifier]},
+ {compile, [],
+ [c_syntax, c_string_per, c_string_ber,
+ c_implicit_before_choice]},
+ {ber, [],
+ [ber_choiceinseq, ber_optional, ber_optional_keyed_list,
+ ber_other]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+%all(suite) -> [test_inline,testNBAPsystem,test_compile_options,ticket_6143].
+
+init_per_testcase(Func,Config) ->
+ %%?line test_server:format("Func: ~p~n",[Func]),
+ ?line {ok, _} = file:read_file_info(filename:join([?config(priv_dir,Config)])),
+ ?line code:add_patha(?config(priv_dir,Config)),
+ Dog=
+ case Func of
+ testX420 ->
+ test_server:timetrap({minutes,60}); % 60 minutes
+ _ ->
+ test_server:timetrap({minutes,30}) % 60 minutes
+ end,
+%% Dog=test_server:timetrap(1800000), % 30 minutes
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(_Func,Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog).
+
+
+testPrim(suite) -> [];
+testPrim(Config) ->
+ ?line testPrim:compile(Config,?BER,[]),
+ ?line testPrim_cases(?BER),
+ ?line ?ber_driver(?BER,testPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrim_cases(?BER)),
+ ?line testPrim:compile(Config,?PER,[]),
+ ?line testPrim_cases(?PER),
+ ?line ?per_bit_opt(testPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrim_cases(?PER)),
+ ?line ?uper_bin(testPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrim_cases(uper_bin)),
+ ?line testPrim:compile(Config,?PER,[optimize]),
+ ?line testPrim_cases(?PER).
+
+testPrim_cases(Rules) ->
+ ?line testPrim:bool(Rules),
+ ?line testPrim:int(Rules),
+ ?line testPrim:enum(Rules),
+ ?line testPrim:obj_id(Rules),
+ ?line testPrim:rel_oid(Rules),
+ ?line testPrim:null(Rules),
+ ?line testPrim:real(Rules).
+
+
+testCompactBitString(suite) -> [];
+testCompactBitString(Config) ->
+
+ ?line testCompactBitString:compile(Config,?BER,[compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?BER),
+
+ ?line ?ber_driver(?BER,testCompactBitString:compile(Config,?BER,[compact_bit_string,driver])),
+ ?line ?ber_driver(?BER,testCompactBitString:compact_bit_string(?BER)),
+
+ ?line testCompactBitString:compile(Config,?PER,[compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?PER),
+ ?line testCompactBitString:bit_string_unnamed(?PER),
+
+ ?line ?per_bit_opt(testCompactBitString:compile(Config,?PER,
+ [compact_bit_string,optimize])),
+ ?line ?per_bit_opt(testCompactBitString:compact_bit_string(?PER)),
+ ?line ?per_bit_opt(testCompactBitString:bit_string_unnamed(?PER)),
+ ?line ?per_bit_opt(testCompactBitString:ticket_7734(?PER)),
+
+ ?line ?uper_bin(testCompactBitString:compile(Config,uper_bin,
+ [compact_bit_string])),
+ ?line ?uper_bin(testCompactBitString:compact_bit_string(uper_bin)),
+ ?line ?uper_bin(testCompactBitString:bit_string_unnamed(uper_bin)),
+
+ ?line testCompactBitString:compile(Config,?PER,[optimize,compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?PER),
+ ?line testCompactBitString:bit_string_unnamed(?PER),
+
+ ?line testCompactBitString:otp_4869(?PER).
+
+
+testPrimStrings(suite) -> [];
+testPrimStrings(Config) ->
+
+ ?line testPrimStrings:compile(Config,?BER,[]),
+ ?line testPrimStrings_cases(?BER),
+ ?line testPrimStrings:more_strings(?BER), %% these are not implemented in per yet
+ ?line ?ber_driver(?BER,testPrimStrings:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimStrings_cases(?BER)),
+ ?line ?ber_driver(?BER,testPrimStrings:more_strings(?BER)),
+
+ ?line testPrimStrings:compile(Config,?PER,[]),
+ ?line testPrimStrings_cases(?PER),
+
+ ?line ?per_bit_opt(testPrimStrings:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimStrings_cases(?PER)),
+
+ ?line ?uper_bin(testPrimStrings:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimStrings_cases(uper_bin)),
+
+ ?line testPrimStrings:compile(Config,?PER,[optimize]),
+ ?line testPrimStrings_cases(?PER).
+
+testPrimStrings_cases(Rules) ->
+ ?line testPrimStrings:bit_string(Rules),
+ ?line testPrimStrings:bit_string_unnamed(Rules),
+ ?line testPrimStrings:octet_string(Rules),
+ ?line testPrimStrings:numeric_string(Rules),
+ ?line testPrimStrings:other_strings(Rules),
+ ?line testPrimStrings:universal_string(Rules),
+ ?line testPrimStrings:bmp_string(Rules),
+ ?line testPrimStrings:times(Rules),
+ ?line testPrimStrings:utf8_string(Rules).
+
+
+
+testPrimExternal(suite) -> [];
+testPrimExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testPrimExternal:compile(Config,?BER,[]),
+ ?line testPrimExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testPrimExternal:compile(Config,?PER,[]),
+ ?line testPrimExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testPrimExternal:compile(Config,?PER,[optimize]),
+ ?line testPrimExternal_cases(?PER).
+
+testPrimExternal_cases(Rules) ->
+ ?line testPrimExternal:external(Rules).
+
+
+
+
+testChoPrim(suite) -> [];
+testChoPrim(Config) ->
+
+ ?line testChoPrim:compile(Config,?BER,[]),
+ ?line testChoPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoPrim_cases(?BER)),
+
+ ?line testChoPrim:compile(Config,?PER,[]),
+ ?line testChoPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testChoPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoPrim_cases(?PER)),
+
+ ?line ?uper_bin(testChoPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoPrim_cases(uper_bin)),
+
+ ?line testChoPrim:compile(Config,?PER,[optimize]),
+ ?line testChoPrim_cases(?PER).
+
+testChoPrim_cases(Rules) ->
+ ?line testChoPrim:bool(Rules),
+ ?line testChoPrim:int(Rules).
+
+
+
+testChoExtension(suite) -> [];
+testChoExtension(Config) ->
+
+ ?line testChoExtension:compile(Config,?BER,[]),
+ ?line testChoExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExtension_cases(?BER)),
+
+ ?line testChoExtension:compile(Config,?PER,[]),
+ ?line testChoExtension_cases(?PER),
+
+ ?line ?per_bit_opt(testChoExtension:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExtension_cases(?PER)),
+
+ ?line ?uper_bin(testChoExtension:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExtension_cases(uper_bin)),
+
+ ?line testChoExtension:compile(Config,?PER,[optimize]),
+ ?line testChoExtension_cases(?PER).
+
+testChoExtension_cases(Rules) ->
+ ?line testChoExtension:extension(Rules).
+
+
+
+testChoExternal(suite) -> [];
+testChoExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testChoExternal:compile(Config,?BER,[]),
+ ?line testChoExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testChoExternal:compile(Config,?PER,[]),
+ ?line testChoExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testChoExternal:compile(Config,?PER,[optimize]),
+ ?line testChoExternal_cases(?PER).
+
+
+testChoExternal_cases(Rules) ->
+ ?line testChoExternal:external(Rules).
+
+
+
+testChoOptional(suite) -> [];
+testChoOptional(Config) ->
+
+ ?line testChoOptional:compile(Config,?BER,[]),
+ ?line testChoOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoOptional_cases(?BER)),
+
+ ?line testChoOptional:compile(Config,?PER,[]),
+ ?line testChoOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testChoOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoOptional_cases(?PER)),
+
+ ?line ?uper_bin(testChoOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoOptional_cases(uper_bin)),
+
+ ?line testChoOptional:compile(Config,?PER,[optimize]),
+ ?line testChoOptional_cases(?PER).
+
+testChoOptional_cases(Rules) ->
+ ?line testChoOptional:optional(Rules).
+
+testChoOptionalImplicitTag(suite) -> [];
+testChoOptionalImplicitTag(Config) ->
+ %% Only meaningful for ?BER
+ ?line testChoOptionalImplicitTag:compile(Config,?BER),
+ ?line testChoOptionalImplicitTag:optional(?BER).
+
+
+testChoRecursive(suite) -> [];
+testChoRecursive(Config) ->
+
+ ?line testChoRecursive:compile(Config,?BER,[]),
+ ?line testChoRecursive_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoRecursive:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoRecursive_cases(?BER)),
+
+ ?line testChoRecursive:compile(Config,?PER,[]),
+ ?line testChoRecursive_cases(?PER),
+
+ ?line ?per_bit_opt(testChoRecursive:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoRecursive_cases(?PER)),
+
+ ?line ?uper_bin(testChoRecursive:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoRecursive_cases(uper_bin)),
+
+ ?line testChoRecursive:compile(Config,?PER,[optimize]),
+ ?line testChoRecursive_cases(?PER).
+
+testChoRecursive_cases(Rules) ->
+ ?line testChoRecursive:recursive(Rules).
+
+
+
+testChoTypeRefCho(suite) -> [];
+testChoTypeRefCho(Config) ->
+
+ ?line testChoTypeRefCho:compile(Config,?BER,[]),
+ ?line testChoTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefCho_cases(?BER)),
+
+ ?line testChoTypeRefCho:compile(Config,?PER,[]),
+ ?line testChoTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefCho_cases(uper_bin)),
+
+ ?line testChoTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefCho_cases(?PER).
+
+testChoTypeRefCho_cases(Rules) ->
+ ?line testChoTypeRefCho:choice(Rules).
+
+
+
+testChoTypeRefPrim(suite) -> [];
+testChoTypeRefPrim(Config) ->
+
+ ?line testChoTypeRefPrim:compile(Config,?BER,[]),
+ ?line testChoTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefPrim_cases(?BER)),
+
+ ?line testChoTypeRefPrim:compile(Config,?PER,[]),
+ ?line testChoTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefPrim_cases(uper_bin)),
+
+ ?line testChoTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefPrim_cases(?PER).
+
+testChoTypeRefPrim_cases(Rules) ->
+ ?line testChoTypeRefPrim:prim(Rules).
+
+
+
+testChoTypeRefSeq(suite) -> [];
+testChoTypeRefSeq(Config) ->
+
+ ?line testChoTypeRefSeq:compile(Config,?BER,[]),
+ ?line testChoTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefSeq_cases(?BER)),
+
+ ?line testChoTypeRefSeq:compile(Config,?PER,[]),
+ ?line testChoTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefSeq_cases(uper_bin)),
+
+ ?line testChoTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefSeq_cases(?PER).
+
+testChoTypeRefSeq_cases(Rules) ->
+ ?line testChoTypeRefSeq:seq(Rules).
+
+
+
+testChoTypeRefSet(suite) -> [];
+testChoTypeRefSet(Config) ->
+
+ ?line testChoTypeRefSet:compile(Config,?BER,[]),
+ ?line testChoTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefSet_cases(?BER)),
+
+ ?line testChoTypeRefSet:compile(Config,?PER,[]),
+ ?line testChoTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefSet_cases(uper_bin)),
+
+ ?line testChoTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefSet_cases(?PER).
+
+testChoTypeRefSet_cases(Rules) ->
+ ?line testChoTypeRefSet:set(Rules).
+
+
+
+testDef(suite) -> [];
+testDef(Config) ->
+
+ ?line testDef:compile(Config,?BER,[]),
+ ?line testDef_cases(?BER),
+
+ ?line ?ber_driver(?BER,testDef:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDef_cases(?BER)),
+
+ ?line testDef:compile(Config,?PER,[]),
+ ?line testDef_cases(?PER),
+
+ ?line ?per_bit_opt(testDef:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDef_cases(?PER)),
+
+ ?line ?uper_bin(testDef:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDef_cases(uper_bin)),
+
+ ?line testDef:compile(Config,?PER,[optimize]),
+ ?line testDef_cases(?PER).
+
+testDef_cases(Rules) ->
+ ?line testDef:main(Rules).
+
+
+
+testOpt(suite) -> [];
+testOpt(Config) ->
+
+ ?line testOpt:compile(Config,?BER),
+ ?line testOpt_cases(?BER),
+
+ ?line testOpt:compile(Config,?PER),
+ ?line testOpt_cases(?PER).
+
+testOpt_cases(Rules) ->
+ ?line testOpt:main(Rules).
+
+
+testEnumExt(suite) -> [];
+testEnumExt(Config) ->
+
+ ?line testEnumExt:compile(Config,?BER,[]),
+ ?line testEnumExt:main(?BER),
+
+ ?line ?ber_driver(?BER,testEnumExt:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testEnumExt:main(?BER)),
+
+ ?line testEnumExt:compile(Config,?PER,[]),
+ ?line testEnumExt:main(?PER),
+
+ ?line ?per_bit_opt(testEnumExt:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testEnumExt:main(?PER)),
+
+ ?line ?uper_bin(testEnumExt:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testEnumExt:main(uper_bin)),
+
+ ?line testEnumExt:compile(Config,?PER,[optimize]),
+ ?line testEnumExt:main(?PER).
+
+testSeqDefault(doc) -> ["Test of OTP-2523 ENUMERATED with extensionmark."];
+testSeqDefault(suite) -> [];
+testSeqDefault(Config) ->
+
+ ?line testSeqDefault:compile(Config,?BER,[]),
+ ?line testSeqDefault_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqDefault:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqDefault_cases(?BER)),
+
+ ?line testSeqDefault:compile(Config,?PER,[]),
+ ?line testSeqDefault_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqDefault:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqDefault_cases(?PER)),
+
+ ?line ?uper_bin(testSeqDefault:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqDefault_cases(uper_bin)),
+
+ ?line testSeqDefault:compile(Config,?PER,[optimize]),
+ ?line testSeqDefault_cases(?PER).
+
+testSeqDefault_cases(Rules) ->
+ ?line testSeqDefault:main(Rules).
+
+
+
+testSeqExtension(suite) -> [];
+testSeqExtension(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqExtension:compile(Config,?BER,[]),
+ ?line testSeqExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExtension_cases(?BER)).
+
+testSeqExtension_cases(Rules) ->
+ ?line testSeqExtension:main(Rules).
+
+
+
+testSeqExternal(suite) -> [];
+testSeqExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqExternal:compile(Config,?BER,[]),
+ ?line testSeqExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExternal_cases(?BER)).
+
+testSeqExternal_cases(Rules) ->
+ ?line testSeqExternal:main(Rules).
+
+
+testSeqOptional(suite) -> [];
+testSeqOptional(Config) ->
+
+ ?line testSeqOptional:compile(Config,?BER,[]),
+ ?line testSeqOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOptional_cases(?BER)),
+
+ ?line testSeqOptional:compile(Config,?PER,[]),
+ ?line testSeqOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOptional_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOptional_cases(uper_bin)),
+
+ ?line testSeqOptional:compile(Config,?PER,[optimize]),
+ ?line testSeqOptional_cases(?PER).
+
+testSeqOptional_cases(Rules) ->
+ ?line testSeqOptional:main(Rules).
+
+
+
+testSeqPrim(suite) -> [];
+testSeqPrim(Config) ->
+
+ ?line testSeqPrim:compile(Config,?BER,[]),
+ ?line testSeqPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqPrim_cases(?BER)),
+
+ ?line testSeqPrim:compile(Config,?PER,[]),
+ ?line testSeqPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSeqPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqPrim_cases(uper_bin)),
+
+ ?line testSeqPrim:compile(Config,?PER,[optimize]),
+ ?line testSeqPrim_cases(?PER).
+
+testSeqPrim_cases(Rules) ->
+ ?line testSeqPrim:main(Rules).
+
+
+testSeq2738(doc) -> ["Test of OTP-2738 Detect corrupt optional component."];
+testSeq2738(suite) -> [];
+testSeq2738(Config) ->
+
+ ?line testSeq2738:compile(Config,?BER,[]),
+ ?line testSeq2738_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeq2738:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeq2738_cases(?BER)),
+
+ ?line testSeq2738:compile(Config,?PER,[]),
+ ?line testSeq2738_cases(?PER),
+
+ ?line ?per_bit_opt(testSeq2738:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeq2738_cases(?PER)),
+
+ ?line ?uper_bin(testSeq2738:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeq2738_cases(uper_bin)),
+
+ ?line testSeq2738:compile(Config,?PER,[optimize]),
+ ?line testSeq2738_cases(?PER).
+
+testSeq2738_cases(Rules) ->
+ ?line testSeq2738:main(Rules).
+
+
+testSeqTag(suite) -> [];
+testSeqTag(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqTag:compile(Config,?BER,[]),
+ ?line testSeqTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqTag:compile(Config,?PER,[]),
+ ?line testSeqTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqTag:compile(Config,?PER,[optimize]),
+ ?line testSeqTag_cases(?PER).
+
+testSeqTag_cases(Rules) ->
+ ?line testSeqTag:main(Rules).
+
+
+
+
+testSeqTypeRefCho(suite) -> [];
+testSeqTypeRefCho(Config) ->
+
+ ?line testSeqTypeRefCho:compile(Config,?BER,[]),
+ ?line testSeqTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefCho_cases(?BER)),
+
+ ?line testSeqTypeRefCho:compile(Config,?PER,[]),
+ ?line testSeqTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefCho_cases(uper_bin)),
+
+ ?line testSeqTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefCho_cases(?PER).
+
+testSeqTypeRefCho_cases(Rules) ->
+ ?line testSeqTypeRefCho:main(Rules).
+
+
+
+testSeqTypeRefPrim(suite) -> [];
+testSeqTypeRefPrim(Config) ->
+
+ ?line testSeqTypeRefPrim:compile(Config,?BER,[]),
+ ?line testSeqTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefPrim_cases(?BER)),
+
+ ?line testSeqTypeRefPrim:compile(Config,?PER,[]),
+ ?line testSeqTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefPrim_cases(uper_bin)),
+
+ ?line testSeqTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefPrim_cases(?PER).
+
+testSeqTypeRefPrim_cases(Rules) ->
+ ?line testSeqTypeRefPrim:main(Rules).
+
+
+
+testSeqTypeRefSeq(suite) -> [];
+testSeqTypeRefSeq(Config) ->
+
+ ?line testSeqTypeRefSeq:compile(Config,?BER,[]),
+ ?line testSeqTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefSeq_cases(?BER)),
+
+ ?line testSeqTypeRefSeq:compile(Config,?PER,[]),
+ ?line testSeqTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefSeq_cases(uper_bin)),
+
+ ?line testSeqTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefSeq_cases(?PER).
+
+testSeqTypeRefSeq_cases(Rules) ->
+ ?line testSeqTypeRefSeq:main(Rules).
+
+
+
+testSeqTypeRefSet(suite) -> [];
+testSeqTypeRefSet(Config) ->
+
+ ?line testSeqTypeRefSet:compile(Config,?BER,[]),
+ ?line testSeqTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefSet_cases(?BER)),
+
+ ?line testSeqTypeRefSet:compile(Config,?PER,[]),
+ ?line testSeqTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefSet_cases(uper_bin)),
+
+ ?line testSeqTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefSet_cases(?PER).
+
+testSeqTypeRefSet_cases(Rules) ->
+ ?line testSeqTypeRefSet:main(Rules).
+
+
+
+
+testSeqOf(suite) -> [];
+testSeqOf(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOf:compile(Config,?BER,[]),
+ ?line testSeqOf_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOf:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOf_cases(?BER)),
+
+ ?line testSeqOf:compile(Config,?PER,[]),
+ ?line testSeqOf_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOf:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOf_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOf:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOf_cases(uper_bin)),
+
+ ?line testSeqOf:compile(Config,?PER,[optimize]),
+ ?line testSeqOf_cases(?PER).
+
+testSeqOf_cases(Rules) ->
+ ?line testSeqOf:main(Rules).
+
+
+
+
+testSeqOfCho(suite) -> [];
+testSeqOfCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOfCho:compile(Config,?BER,[]),
+ ?line testSeqOfCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOfCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfCho_cases(?BER)),
+
+ ?line testSeqOfCho:compile(Config,?PER,[]),
+ ?line testSeqOfCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOfCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfCho_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOfCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfCho_cases(uper_bin)),
+
+ ?line testSeqOfCho:compile(Config,?PER,[optimize]),
+ ?line testSeqOfCho_cases(?PER).
+
+testSeqOfIndefinite(suite) -> [];
+testSeqOfIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOfIndefinite:compile(Config,?BER,[]),
+ ?line testSeqOfIndefinite:main(),
+
+ ?line ?ber_driver(?BER,testSeqOfIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfIndefinite:main()).
+
+testSeqOfCho_cases(Rules) ->
+ ?line testSeqOfCho:main(Rules).
+
+
+testSeqOfExternal(suite) -> [];
+testSeqOfExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqOfExternal:compile(Config,?BER,[]),
+ ?line testSeqOfExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqOfExternal:compile(Config,?PER,[]),
+ ?line testSeqOfExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfExternal_cases(?PER).
+
+testSeqOfExternal_cases(Rules) ->
+ ?line testSeqOfExternal:main(Rules).
+
+
+
+testSeqOfTag(suite) -> [];
+testSeqOfTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqOfTag:compile(Config,?BER,[]),
+ ?line testSeqOfTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqOfTag:compile(Config,?PER,[]),
+ ?line testSeqOfTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfTag:compile(Config,?PER,[optimize]),
+ ?line testSeqOfTag_cases(?PER).
+
+testSeqOfTag_cases(Rules) ->
+ ?line testSeqOfTag:main(Rules).
+
+
+
+
+testSetDefault(suite) -> [];
+testSetDefault(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetDefault:compile(Config,?BER,[]),
+ ?line testSetDefault_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetDefault:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetDefault_cases(?BER)),
+
+ ?line testSetDefault:compile(Config,?PER,[]),
+ ?line testSetDefault_cases(?PER),
+
+ ?line ?per_bit_opt(testSetDefault:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetDefault_cases(?PER)),
+
+ ?line ?uper_bin(testSetDefault:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetDefault_cases(uper_bin)),
+
+ ?line testSetDefault:compile(Config,?PER,[optimize]),
+ ?line testSetDefault_cases(?PER).
+
+testSetDefault_cases(Rules) ->
+ ?line testSetDefault:main(Rules).
+
+
+testParamBasic(suite) -> [];
+testParamBasic(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testParamBasic:compile(Config,?BER,[]),
+ ?line testParamBasic_cases(?BER),
+
+ ?line ?ber_driver(?BER,testParamBasic:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testParamBasic_cases(?BER)),
+
+ ?line testParamBasic:compile(Config,?PER,[]),
+ ?line testParamBasic_cases(?PER),
+
+ ?line ?per_bit_opt(testParamBasic:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testParamBasic_cases(?PER)),
+
+ ?line ?uper_bin(testParamBasic:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testParamBasic_cases(uper_bin)),
+
+ ?line testParamBasic:compile(Config,?PER,[optimize]),
+ ?line testParamBasic_cases(?PER).
+
+
+testParamBasic_cases(Rules) ->
+ ?line testParamBasic:main(Rules).
+
+testSetExtension(suite) -> [];
+testSetExtension(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetExtension:compile(Config,?BER,[]),
+ ?line testSetExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExtension_cases(?BER)).
+
+testSetExtension_cases(Rules) ->
+ ?line testSetExtension:main(Rules).
+
+
+testSetExternal(suite) -> [];
+testSetExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetExternal:compile(Config,?BER,[]),
+ ?line testSetExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExternal_cases(?BER)).
+
+testSetExternal_cases(Rules) ->
+ ?line testSetExternal:main(Rules).
+
+
+testSetOptional(suite) -> [];
+testSetOptional(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOptional:compile(Config,?BER,[]),
+ ?line testSetOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOptional_cases(?BER)),
+
+ ?line testSetOptional:compile(Config,?PER,[]),
+ ?line testSetOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOptional_cases(?PER)),
+
+ ?line ?uper_bin(testSetOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOptional_cases(uper_bin)),
+
+ ?line testSetOptional:compile(Config,?PER,[optimize]),
+ ?line testSetOptional_cases(?PER).
+
+testSetOptional_cases(Rules) ->
+ ?line ok = testSetOptional:ticket_7533(Rules),
+ ?line ok = testSetOptional:main(Rules).
+
+
+
+
+testSetPrim(suite) -> [];
+testSetPrim(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetPrim:compile(Config,?BER,[]),
+ ?line testSetPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetPrim_cases(?BER)),
+
+ ?line testSetPrim:compile(Config,?PER,[]),
+ ?line testSetPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSetPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSetPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetPrim_cases(uper_bin)),
+
+ ?line testSetPrim:compile(Config,?PER,[optimize]),
+ ?line testSetPrim_cases(?PER).
+
+testSetPrim_cases(Rules) ->
+ ?line testSetPrim:main(Rules).
+
+
+
+testSetTag(suite) -> [];
+testSetTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetTag:compile(Config,?BER,[]),
+ ?line testSetTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetTag:compile(Config,?PER,[]),
+ ?line testSetTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetTag:compile(Config,?PER,[optimize]),
+ ?line testSetTag_cases(?PER).
+
+testSetTag_cases(Rules) ->
+ ?line testSetTag:main(Rules).
+
+
+
+testSetTypeRefCho(suite) -> [];
+testSetTypeRefCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefCho:compile(Config,?BER,[]),
+ ?line testSetTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefCho_cases(?BER)),
+
+ ?line testSetTypeRefCho:compile(Config,?PER,[]),
+ ?line testSetTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefCho_cases(uper_bin)),
+
+ ?line testSetTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefCho_cases(?PER).
+
+testSetTypeRefCho_cases(Rules) ->
+ ?line testSetTypeRefCho:main(Rules).
+
+
+
+testSetTypeRefPrim(suite) -> [];
+testSetTypeRefPrim(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefPrim:compile(Config,?BER,[]),
+ ?line testSetTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefPrim_cases(?BER)),
+
+ ?line testSetTypeRefPrim:compile(Config,?PER,[]),
+ ?line testSetTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefPrim_cases(uper_bin)),
+
+ ?line testSetTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefPrim_cases(?PER).
+
+testSetTypeRefPrim_cases(Rules) ->
+ ?line testSetTypeRefPrim:main(Rules).
+
+
+
+testSetTypeRefSeq(suite) -> [];
+testSetTypeRefSeq(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefSeq:compile(Config,?BER,[]),
+ ?line testSetTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefSeq_cases(?BER)),
+
+ ?line testSetTypeRefSeq:compile(Config,?PER,[]),
+ ?line testSetTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefSeq_cases(uper_bin)),
+
+ ?line testSetTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefSeq_cases(?PER).
+
+testSetTypeRefSeq_cases(Rules) ->
+ ?line testSetTypeRefSeq:main(Rules).
+
+
+
+testSetTypeRefSet(suite) -> [];
+testSetTypeRefSet(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefSet:compile(Config,?BER,[]),
+ ?line testSetTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefSet_cases(?BER)),
+
+ ?line testSetTypeRefSet:compile(Config,?PER,[]),
+ ?line testSetTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefSet_cases(uper_bin)),
+
+ ?line testSetTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefSet_cases(?PER).
+
+testSetTypeRefSet_cases(Rules) ->
+ ?line testSetTypeRefSet:main(Rules).
+
+
+
+testSetOf(suite) -> [];
+testSetOf(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOf:compile(Config,?BER,[]),
+ ?line testSetOf_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOf:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOf_cases(?BER)),
+
+ ?line testSetOf:compile(Config,?PER,[]),
+ ?line testSetOf_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOf:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOf_cases(?PER)),
+
+ ?line ?uper_bin(testSetOf:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOf_cases(uper_bin)),
+
+ ?line testSetOf:compile(Config,?PER,[optimize]),
+ ?line testSetOf_cases(?PER).
+
+testSetOf_cases(Rules) ->
+ ?line testSetOf:main(Rules).
+
+
+
+testSetOfCho(suite) -> [];
+testSetOfCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOfCho:compile(Config,?BER,[]),
+ ?line testSetOfCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOfCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfCho_cases(?BER)),
+
+ ?line testSetOfCho:compile(Config,?PER,[]),
+ ?line testSetOfCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOfCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfCho_cases(?PER)),
+
+ ?line ?uper_bin(testSetOfCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfCho_cases(uper_bin)),
+
+ ?line testSetOfCho:compile(Config,?PER,[optimize]),
+ ?line testSetOfCho_cases(?PER).
+
+testSetOfCho_cases(Rules) ->
+ ?line testSetOfCho:main(Rules).
+
+
+testSetOfExternal(suite) -> [];
+testSetOfExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetOfExternal:compile(Config,?BER,[]),
+ ?line testSetOfExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetOfExternal:compile(Config,?PER,[]),
+ ?line testSetOfExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfExternal_cases(?PER).
+
+testSetOfExternal_cases(Rules) ->
+ ?line testSetOfExternal:main(Rules).
+
+
+
+
+testSetOfTag(suite) -> [];
+testSetOfTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetOfTag:compile(Config,?BER,[]),
+ ?line testSetOfTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetOfTag:compile(Config,?PER,[]),
+ ?line testSetOfTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfTag:compile(Config,?PER,[optimize]),
+ ?line testSetOfTag_cases(?PER).
+
+testSetOfTag_cases(Rules) ->
+ ?line testSetOfTag:main(Rules).
+
+
+c_syntax(suite) -> [];
+c_syntax(Config) ->
+ ?line DataDir% ?line testExternal:compile(Config,?PER),
+% ?line testPrimExternal:compile(Config,?PER),
+% ?line testPrimExternal_cases(?PER).
+ = ?config(data_dir,Config),
+ ?line _TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line {error,_R1} = asn1ct:compile(filename:join(DataDir,"Syntax")),
+ ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"BadTypeEnding")),
+ ?line {error,_R3} = asn1ct:compile(filename:join(DataDir,
+ "BadValueAssignment1")),
+ ?line {error,_R4} = asn1ct:compile(filename:join(DataDir,
+ "BadValueAssignment2")),
+ ?line {error,_R5} = asn1ct:compile(filename:join(DataDir,
+ "BadValueSet")),
+ ?line {error,_R6} = asn1ct:compile(filename:join(DataDir,
+ "ChoiceBadExtension")),
+ ?line {error,_R7} = asn1ct:compile(filename:join(DataDir,
+ "EnumerationBadExtension")),
+ ?line {error,_R8} = asn1ct:compile(filename:join(DataDir,
+ "Example")),
+ ?line {error,_R9} = asn1ct:compile(filename:join(DataDir,
+ "Export1")),
+ ?line {error,_R10} = asn1ct:compile(filename:join(DataDir,
+ "MissingEnd")),
+ ?line {error,_R11} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComma")),
+ ?line {error,_R12} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComponentName")),
+ ?line {error,_R13} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComponentType")),
+ ?line {error,_R14} = asn1ct:compile(filename:join(DataDir,
+ "SeqBadComma")).
+
+
+c_string_per(suite) -> [];
+c_string_per(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?PER,{outdir,TempDir}]).
+
+c_string_ber(suite) -> [];
+c_string_ber(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?BER,{outdir,TempDir}]).
+
+
+c_implicit_before_choice(suite) -> [];
+c_implicit_before_choice(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"CCSNARG3"),[?BER,{outdir,TempDir}]).
+
+parse(suite) -> [];
+parse(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ M1 = test_modules(),
+% M2 = parse_modules(),
+ ?line ok = parse1(M1,DataDir,OutDir).
+
+parse1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[abs,{outdir,OutDir}]),
+ parse1(T,DataDir,OutDir);
+parse1([],_,_) ->
+ ok.
+
+per(suite) -> [];
+per(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = per1(per_modules(),DataDir,OutDir),
+ ?line ?per_bit_opt(per1_bit_opt(per_modules(),DataDir,OutDir)),
+ ?line ok = per1_opt(per_modules(),DataDir,OutDir).
+
+
+per1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1(T,DataDir,OutDir);
+per1([],_,_) ->
+ ok.
+
+per1_bit_opt([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimize,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1_bit_opt(T,DataDir,OutDir);
+per1_bit_opt([],_,_) ->
+ ok.
+
+per1_opt([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimized,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1_opt(T,DataDir,OutDir);
+per1_opt([],_,_) ->
+ ok.
+
+
+ber_choiceinseq(suite) ->[];
+ber_choiceinseq(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"ChoiceInSeq"),[?BER,{outdir,OutDir}]).
+
+ber_optional(suite) ->[];
+ber_optional(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),[?BER,{outdir,OutDir}]),
+ ?line V = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
+ {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
+ {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
+ ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
+ ?line Bytes = lists:flatten(B),
+ ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
+ ?line ok = eq(V,element(2,V2)).
+
+ber_optional_keyed_list(suite) ->[];
+ber_optional_keyed_list(Config) ->
+ case ?BER of
+ ber_bin_v2 -> ok;
+ _ ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),
+ [?BER,keyed_list,{outdir,OutDir}]),
+ ?line Vrecord = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
+ {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
+ {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
+ ?line V = [ {a,[{scriptKey,10}]},
+ {b,[]},
+ {c,[{callingPartysCategory,111}]} ],
+ ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
+ ?line Bytes = lists:flatten(B),
+ ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
+ ?line ok = eq(Vrecord,element(2,V2))
+ end.
+
+
+eq(V,V) ->
+ ok.
+
+
+ber_other(suite) ->[];
+ber_other(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = ber1(ber_modules(),DataDir,OutDir).
+
+
+ber1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?BER,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ ber1(T,DataDir,OutDir);
+ber1([],_,_) ->
+ ok.
+
+default_per(suite) ->[];
+default_per(Config) ->
+ default1(?PER,Config,[]).
+
+default_per_opt(suite) -> [];
+default_per_opt(Config) ->
+ ?per_bit_opt(default1(?PER,Config,[optimize])),
+ default1(?PER,Config,[optimize]).
+
+default_ber(suite) ->[];
+default_ber(Config) ->
+ default1(?BER,Config,[]).
+
+default1(Rule,Config,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Def",[Rule,{outdir,OutDir}]++Options),
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,
+ bool1 = true,
+ bool2 = true,
+ bool3 = true}),
+ ?line {ok,{'Def1',true,true,true,true}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true}),
+ ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,bool2=false}),
+ ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes3)).
+
+
+value_test(suite) ->[];
+value_test(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?BER,{outdir,OutDir}]),
+ ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
+ ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?PER,{outdir,OutDir}]),
+ ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
+ ?line ok = test_bad_values:tests(Config),
+ ok.
+
+
+constructed(suite) ->
+ [];
+constructed(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Constructed",[?BER,{outdir,OutDir}]),
+ ?line {ok,B} = asn1_wrapper:encode('Constructed','S',{'S',false}),
+ ?line [40,3,1,1,0] = lists:flatten(B),
+ ?line {ok,B1} = asn1_wrapper:encode('Constructed','S2',{'S2',false}),
+ ?line [40,5,48,3,1,1,0] = lists:flatten(B1),
+ ?line {ok,B2} = asn1_wrapper:encode('Constructed','I',10),
+ ?line [136,1,10] = lists:flatten(B2),
+ ok.
+
+ber_decode_error(suite) -> [];
+ber_decode_error(Config) ->
+ ?line ok = ber_decode_error:compile(Config,?BER,[]),
+ ?line ok = ber_decode_error:run([]),
+
+ ?line ok = ?ber_driver(?BER,ber_decode_error:compile(Config,?BER,[driver])),
+ ?line ok = ?ber_driver(?BER,ber_decode_error:run([driver])),
+ ok.
+
+h323test(suite) ->
+ [];
+h323test(Config) ->
+ ?line ok = h323test:compile(Config,?PER,[]),
+ ?line ok = h323test:run(?PER),
+ ?line ?per_bit_opt(h323test:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(h323test:run(?PER)),
+ ?line ?uper_bin(h323test:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(h323test:run(uper_bin)),
+ ?line ok = h323test:compile(Config,?PER,[optimize]),
+ ?line ok = h323test:run(?PER),
+ ok.
+
+per_GeneralString(suite) ->
+ [];
+per_GeneralString(Config) ->
+ case erlang:module_loaded('MULTIMEDIA-SYSTEM-CONTROL') of
+ true ->
+ ok;
+ false ->
+ h323test:compile(Config,?PER,[])
+ end,
+ UI = [109,64,1,57],
+ ?line {ok,_V} = asn1_wrapper:decode('MULTIMEDIA-SYSTEM-CONTROL',
+ 'MultimediaSystemControlMessage',UI).
+
+per_open_type(suite) ->
+ [];
+per_open_type(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line ok = asn1ct:compile(DataDir ++ "OpenType",[?PER,{outdir,OutDir}]),
+ Stype = {'Stype',10,true},
+ ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
+ ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes),
+
+ ?line ?per_bit_opt(ok = asn1ct:compile(DataDir ++ "OpenType",
+ [?PER,optimize,{outdir,OutDir}])),
+ ?line ?per_bit_opt({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
+ ?line ?per_bit_opt({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
+
+ ?line ?uper_bin(ok = asn1ct:compile(DataDir ++ "OpenType",
+ [uper_bin,{outdir,OutDir}])),
+ ?line ?uper_bin({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
+ ?line ?uper_bin({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "OpenType",
+ [?PER,optimize,{outdir,OutDir}]),
+ ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
+ ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes).
+
+testConstraints(suite) ->
+ [];
+testConstraints(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testConstraints:compile(Config,?BER,[]),
+ ?line testConstraints:int_constraints(?BER),
+
+ ?line ?ber_driver(?BER,testConstraints:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testConstraints:int_constraints(?BER)),
+
+ ?line testConstraints:compile(Config,?PER,[]),
+ ?line testConstraints:int_constraints(?PER),
+ ?line testConstraints:refed_NNL_name(?PER),
+
+ ?line ?per_bit_opt(testConstraints:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testConstraints:int_constraints(?PER)),
+ ?line ?per_bit_opt(testConstraints:refed_NNL_name(?PER)),
+
+ ?line ?uper_bin(testConstraints:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testConstraints:int_constraints(uper_bin)),
+ ?line ?uper_bin(testConstraints:refed_NNL_name(uper_bin)),
+
+ ?line testConstraints:compile(Config,?PER,[optimize]),
+ ?line testConstraints:int_constraints(?PER),
+ ?line testConstraints:refed_NNL_name(?PER).
+
+testSeqIndefinite(suite) -> [];
+testSeqIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqIndefinite:compile(Config,?BER,[]),
+ ?line testSeqIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testSeqIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqIndefinite:main(?BER)).
+
+testSetIndefinite(suite) -> [];
+testSetIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetIndefinite:compile(Config,?BER,[]),
+ ?line testSetIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testSetIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetIndefinite:main(?BER)).
+
+testChoiceIndefinite(suite) -> [];
+testChoiceIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testChoiceIndefinite:compile(Config,?BER,[]),
+ ?line testChoiceIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testChoiceIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoiceIndefinite:main(?BER)).
+
+testInfObjectClass(suite) ->
+ [];
+testInfObjectClass(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testInfObjectClass:compile(Config,?PER,[]),
+ ?line testInfObjectClass:main(?PER),
+ ?line testInfObj:compile(Config,?PER,[]),
+ ?line testInfObj:main(?PER),
+
+ ?line ?per_bit_opt(testInfObjectClass:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testInfObjectClass:main(?PER)),
+ ?line ?per_bit_opt(testInfObj:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testInfObj:main(?PER)),
+
+ ?line ?uper_bin(testInfObjectClass:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testInfObjectClass:main(uper_bin)),
+ ?line ?uper_bin(testInfObj:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testInfObj:main(uper_bin)),
+
+ ?line testInfObjectClass:compile(Config,?PER,[optimize]),
+ ?line testInfObjectClass:main(?PER),
+ ?line testInfObj:compile(Config,?PER,[optimize]),
+ ?line testInfObj:main(?PER),
+
+ ?line testInfObjectClass:compile(Config,?BER,[]),
+ ?line testInfObjectClass:main(?BER),
+ ?line testInfObj:compile(Config,?BER,[]),
+ ?line testInfObj:main(?BER),
+
+ ?line ?ber_driver(?BER,testInfObjectClass:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testInfObjectClass:main(?BER)),
+ ?line ?ber_driver(?BER,testInfObj:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testInfObj:main(?BER)),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?PER,[]),
+
+ ?line ?per_bit_opt(testInfObj:compile_RANAPfiles(Config,?PER,[optimize])),
+
+ ?line ?uper_bin(testInfObj:compile_RANAPfiles(Config,uper_bin,[])),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?PER,[optimize]),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?BER,[]).
+
+testParameterizedInfObj(suite) ->
+ [];
+testParameterizedInfObj(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testParameterizedInfObj:compile(Config,?PER,[]),
+ ?line testParameterizedInfObj:main(?PER),
+
+ ?line ?per_bit_opt(testParameterizedInfObj:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testParameterizedInfObj:main(?PER)),
+
+ ?line ?uper_bin(testParameterizedInfObj:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testParameterizedInfObj:main(uper_bin)),
+
+ ?line testParameterizedInfObj:compile(Config,?PER,[optimize]),
+ ?line testParameterizedInfObj:main(?PER),
+
+ ?line testParameterizedInfObj:compile(Config,?BER,[]),
+ ?line testParameterizedInfObj:main(?BER),
+
+ ?line ?ber_driver(?BER,testParameterizedInfObj:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testParameterizedInfObj:main(?BER)).
+
+testMergeCompile(suite) ->
+ [];
+testMergeCompile(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testMergeCompile:compile(Config,?PER,[]),
+ ?line testMergeCompile:main(?PER),
+ ?line testMergeCompile:mvrasn(?PER),
+
+ ?line ?per_bit_opt(testMergeCompile:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testMergeCompile:main(?PER)),
+ ?line ?per_bit_opt(testMergeCompile:mvrasn(?PER)),
+
+ ?line ?uper_bin(testMergeCompile:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testMergeCompile:main(uper_bin)),
+ ?line ?uper_bin(testMergeCompile:mvrasn(uper_bin)),
+
+ ?line testMergeCompile:compile(Config,?BER,[]),
+ ?line testMergeCompile:main(?BER),
+ ?line testMergeCompile:mvrasn(?BER),
+
+ ?line ?ber_driver(?BER,testMergeCompile:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testMergeCompile:main(?BER)),
+ ?line ?ber_driver(?BER,testMergeCompile:mvrasn(?BER)).
+
+testobj(suite) ->
+ [];
+testobj(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = testRANAP:compile(Config,?PER,[]),
+ ?line ok = testRANAP:testobj(?PER),
+ ?line ok = testParameterizedInfObj:ranap(?PER),
+
+ ?line ?per_bit_opt(ok = testRANAP:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(ok = testRANAP:testobj(?PER)),
+ ?line ?per_bit_opt(ok = testParameterizedInfObj:ranap(?PER)),
+
+ ?line ?uper_bin(ok = testRANAP:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(ok = testRANAP:testobj(uper_bin)),
+ ?line ?uper_bin(ok = testParameterizedInfObj:ranap(uper_bin)),
+
+ ?line ok = testRANAP:compile(Config,?PER,[optimize]),
+ ?line ok = testRANAP:testobj(?PER),
+ ?line ok = testParameterizedInfObj:ranap(?PER),
+
+ ?line ok = testRANAP:compile(Config,?BER,[]),
+ ?line ok = testRANAP:testobj(?BER),
+ ?line ok = testParameterizedInfObj:ranap(?BER),
+
+ ?line ?ber_driver(?BER,testRANAP:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testRANAP:testobj(?BER)),
+ ?line ?ber_driver(?BER,testParameterizedInfObj:ranap(?BER)).
+
+
+testDeepTConstr(suite) ->
+ [];
+testDeepTConstr(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testDeepTConstr:compile(Config,?PER,[]),
+ ?line testDeepTConstr:main(?PER),
+
+ ?line ?per_bit_opt(testDeepTConstr:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDeepTConstr:main(?PER)),
+
+ ?line ?uper_bin(testDeepTConstr:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDeepTConstr:main(uper_bin)),
+
+ ?line testDeepTConstr:compile(Config,?PER,[optimize]),
+ ?line testDeepTConstr:main(?PER),
+
+ ?line testDeepTConstr:compile(Config,?BER,[]),
+ ?line testDeepTConstr:main(?BER),
+
+ ?line ?ber_driver(?BER,testDeepTConstr:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDeepTConstr:main(?BER)).
+
+testInvokeMod(suite) ->
+ [];
+testInvokeMod(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[{outdir,OutDir}]),
+ ?line {ok,_Result1} = 'PrimStrings':encode('Bs1',[1,0,1,0]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[?PER,{outdir,OutDir}]),
+ ?line {ok,_Result2} = 'PrimStrings':encode('Bs1',[1,0,1,0]).
+
+testExport(suite) ->
+ [];
+testExport(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line {error,{asn1,_Reason}} = asn1ct:compile(filename:join(DataDir,"IllegalExport"),[{outdir,OutDir}]).
+
+testImport(suite) ->
+ [];
+testImport(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line _OutDir = ?config(priv_dir,Config),
+ ?line {error,_} = asn1ct:compile(filename:join(DataDir,"ImportsFrom"),[?BER]),
+ ok.
+
+testMegaco(suite) ->
+ [];
+testMegaco(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ io:format("Config: ~p~n",[Config]),
+ ?line {ok,ModuleName1,ModuleName2} = testMegaco:compile(Config,?BER,[]),
+ ?line ok = testMegaco:main(ModuleName1,Config),
+ ?line ok = testMegaco:main(ModuleName2,Config),
+
+ case ?BER of
+ ber_bin_v2 ->
+ ?line {ok,ModuleName3,ModuleName4} = testMegaco:compile(Config,?BER,[driver]),
+ ?line ok = testMegaco:main(ModuleName3,Config),
+ ?line ok = testMegaco:main(ModuleName4,Config);
+ _-> ok
+ end,
+
+ ?line {ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[]),
+ ?line ok = testMegaco:main(ModuleName5,Config),
+ ?line ok = testMegaco:main(ModuleName6,Config),
+
+ ?line ?per_bit_opt({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(ok = testMegaco:main(ModuleName5,Config)),
+ ?line ?per_bit_opt(ok = testMegaco:main(ModuleName6,Config)),
+
+ ?line ?uper_bin({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(ok = testMegaco:main(ModuleName5,Config)),
+ ?line ?uper_bin(ok = testMegaco:main(ModuleName6,Config)),
+
+ ?line {ok,ModuleName7,ModuleName8} = testMegaco:compile(Config,?PER,[optimize]),
+ ?line ok = testMegaco:main(ModuleName7,Config),
+ ?line ok = testMegaco:main(ModuleName8,Config).
+
+
+testMvrasn6(suite) -> [];
+testMvrasn6(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testMvrasn6:compile(Config,?BER),
+ ?line testMvrasn6:main().
+
+testContextSwitchingTypes(suite) -> [];
+testContextSwitchingTypes(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testContextSwitchingTypes:compile(Config,?BER,[]),
+ ?line testContextSwitchingTypes:test(),
+
+ ?line ?ber_driver(?BER,testContextSwitchingTypes:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testContextSwitchingTypes:test()),
+
+ ?line testContextSwitchingTypes:compile(Config,?PER,[]),
+ ?line testContextSwitchingTypes:test(),
+
+ ?line ?per_bit_opt(testContextSwitchingTypes:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testContextSwitchingTypes:test()),
+
+ ?line ?uper_bin(testContextSwitchingTypes:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testContextSwitchingTypes:test()),
+
+ ?line testContextSwitchingTypes:compile(Config,?PER,[optimize]),
+ ?line testContextSwitchingTypes:test().
+
+testTypeValueNotation(suite) -> [];
+testTypeValueNotation(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ case ?BER of
+ Ber when Ber == ber; Ber == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?BER,[]),
+ ?line testTypeValueNotation:main(?BER,dummy);
+ _ ->
+ ok
+ end,
+
+ ?line ?ber_driver(?BER,testTypeValueNotation:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testTypeValueNotation:main(?BER,optimize)),
+
+ case ?BER of
+ Ber2 when Ber2 == ber; Ber2 == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?PER,[]),
+ ?line testTypeValueNotation:main(?PER,dummy);
+ _ ->
+ ok
+ end,
+
+ ?line ?per_bit_opt(testTypeValueNotation:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testTypeValueNotation:main(?PER,optimize)),
+
+ ?line ?uper_bin(testTypeValueNotation:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testTypeValueNotation:main(uper_bin,optimize)),
+ case ?BER of
+ Ber3 when Ber3 == ber; Ber3 == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?PER,[optimize]),
+ ?line testTypeValueNotation:main(?PER,optimize);
+ _ ->
+ ok
+ end.
+
+testOpenTypeImplicitTag(suite) -> [];
+testOpenTypeImplicitTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?BER,[]),
+ ?line testOpenTypeImplicitTag:main(?BER),
+
+ ?line ?ber_driver(?BER,testOpenTypeImplicitTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testOpenTypeImplicitTag:main(?BER)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?PER,[]),
+ ?line testOpenTypeImplicitTag:main(?PER),
+
+ ?line ?per_bit_opt(testOpenTypeImplicitTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testOpenTypeImplicitTag:main(?PER)),
+
+ ?line ?uper_bin(testOpenTypeImplicitTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testOpenTypeImplicitTag:main(uper_bin)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?PER,[optimize]),
+ ?line testOpenTypeImplicitTag:main(?PER).
+
+duplicate_tags(suite) -> [];
+duplicate_tags(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ {error,{asn1,[{error,{type,_,_,'SeqOpt1Imp',{asn1,{duplicates_of_the_tags,_}}}}]}} =
+ asn1ct:compile(filename:join(DataDir,"SeqOptional2"),[abs]),
+ ok.
+
+rtUI(suite) -> [];
+rtUI(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?BER]),
+ ?line {ok,_} = asn1rt:info('Prim'),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?PER]),
+ ?line {ok,_} = asn1rt:info('Prim'),
+
+ ?line ok = asn1rt:load_driver(),
+ ?line ok = asn1rt:load_driver(),
+ ?line ok = asn1rt:unload_driver().
+
+testROSE(suite) -> [];
+testROSE(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testROSE:compile(Config,?BER,[]),
+
+ ?line testROSE:compile(Config,?PER,[]),
+ ?line ?per_bit_opt(testROSE:compile(Config,?PER,[optimize])),
+ ?line ?uper_bin(testROSE:compile(Config,uper_bin,[])),
+ ?line testROSE:compile(Config,?PER,[optimize]).
+
+testINSTANCE_OF(suite) -> [];
+testINSTANCE_OF(Config) ->
+ ?line testINSTANCE_OF:compile(Config,?BER,[]),
+ ?line testINSTANCE_OF:main(?BER),
+
+ ?line ?ber_driver(?BER,testINSTANCE_OF:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testINSTANCE_OF:main(?BER)),
+
+ ?line testINSTANCE_OF:compile(Config,?PER,[]),
+ ?line testINSTANCE_OF:main(?PER),
+
+ ?line ?per_bit_opt(testINSTANCE_OF:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testINSTANCE_OF:main(?PER)),
+
+ ?line ?uper_bin(testINSTANCE_OF:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testINSTANCE_OF:main(uper_bin)),
+
+ ?line testINSTANCE_OF:compile(Config,?PER,[optimize]),
+ ?line testINSTANCE_OF:main(?PER).
+
+testTCAP(suite) -> [];
+testTCAP(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testTCAP:compile(Config,?BER,[]),
+ ?line testTCAP:test(?BER,Config),
+
+ ?line ?ber_driver(?BER,testTCAP:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testTCAP:test(?BER,Config)),
+
+ ?line ?ber_driver(?BER,testTCAP:compile_asn1config(Config,?BER,[asn1config])),
+ ?line ?ber_driver(?BER,testTCAP:test_asn1config()).
+
+testDER(suite) ->[];
+testDER(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testDER:compile(Config,?BER,[]),
+ ?line testDER:test(),
+
+ ?line ?ber_driver(?BER,testDER:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDER:test()),
+
+ ?line testParamBasic:compile_der(Config,?BER),
+ ?line testParamBasic_cases(der),
+
+
+ ?line testSeqSetDefaultVal:compile(Config,?BER),
+ ?line testSeqSetDefaultVal_cases(?BER).
+
+testSeqSetDefaultVal_cases(?BER) ->
+ ?line testSeqSetDefaultVal:main(?BER).
+
+
+specialized_decodes(suite) -> [];
+specialized_decodes(Config) ->
+ ?line test_partial_incomplete_decode:compile(Config,?BER,[optimize]),
+ ?line test_partial_incomplete_decode:test(?BER,Config),
+ ?line test_selective_decode:test(?BER,Config).
+
+special_decode_performance(suite) ->[];
+special_decode_performance(Config) ->
+ ?line ?ber_driver(?BER,test_special_decode_performance:compile(Config,?BER)),
+ ?line ?ber_driver(?BER,test_special_decode_performance:go(all)).
+
+
+test_driver_load(suite) -> [];
+test_driver_load(Config) ->
+ ?line test_driver_load:compile(Config,?PER),
+ ?line test_driver_load:test(?PER,5).
+
+test_ParamTypeInfObj(suite) -> [];
+test_ParamTypeInfObj(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"IN-CS-1-Datatypes"),[ber_bin]).
+
+test_WS_ParamClass(suite) -> [];
+test_WS_ParamClass(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"InformationFramework"),
+ [ber_bin]).
+
+test_Defed_ObjectIdentifier(suite) -> [];
+test_Defed_ObjectIdentifier(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"UsefulDefinitions"),
+ [ber_bin]).
+
+testSelectionType(suite) -> [];
+testSelectionType(Config) ->
+
+ ?line ok = testSelectionTypes:compile(Config,?BER,[]),
+ ?line {ok,_} = testSelectionTypes:test(),
+
+ ?line ok = testSelectionTypes:compile(Config,?PER,[]),
+ ?line {ok,_} = testSelectionTypes:test().
+
+testSSLspecs(suite) -> [];
+testSSLspecs(Config) ->
+
+ ?line ok = testSSLspecs:compile(Config,?BER,
+ [optimize,compact_bit_string,der]),
+ ?line testSSLspecs:run(?BER),
+
+ case code:which(asn1ct) of
+ cover_compiled ->
+ ok;
+ _ ->
+ ?line ok = testSSLspecs:compile_inline(Config,?BER),
+ ?line ok = testSSLspecs:run_inline(?BER)
+ end.
+
+testNortel(suite) -> [];
+testNortel(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?BER]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?BER,optimize]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?BER,optimize,driver]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?PER]),
+ ?line ?per_bit_opt(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?PER,optimize])),
+ ?line ?uper_bin(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[uper_bin])),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?PER,optimize]).
+test_undecoded_rest(suite) -> [];
+test_undecoded_rest(Config) ->
+
+ ?line ok = test_undecoded_rest:compile(Config,?BER,[]),
+ ?line ok = test_undecoded_rest:test([]),
+
+ ?line ok = test_undecoded_rest:compile(Config,?BER,[undec_rest]),
+ ?line ok = test_undecoded_rest:test(undec_rest),
+
+ ?line ok = test_undecoded_rest:compile(Config,?PER,[]),
+ ?line ok = test_undecoded_rest:test([]),
+
+ ?line ?per_bit_opt(ok = test_undecoded_rest:compile(Config,?PER,[optimize,undec_rest])),
+ ?line ?per_bit_opt(ok = test_undecoded_rest:test(undec_rest)),
+
+ ?line ?uper_bin(ok = test_undecoded_rest:compile(Config,uper_bin,[undec_rest])),
+ ?line ?uper_bin(ok = test_undecoded_rest:test(undec_rest)),
+
+ ?line ok = test_undecoded_rest:compile(Config,?PER,[undec_rest]),
+ ?line ok = test_undecoded_rest:test(undec_rest).
+
+test_inline(suite) -> [];
+test_inline(Config) ->
+ case code:which(asn1ct) of
+ cover_compiled ->
+ {skip,"Not runnable when cover compiled"};
+ _ ->
+ ?line ok=test_inline:compile(Config,?BER,[]),
+ ?line test_inline:main(?BER),
+ ?line test_inline:inline1(Config,?BER,[]),
+ ?line test_inline:performance2()
+ end.
+
+%test_inline_prf(suite) -> [];
+%test_inline_prf(Config) ->
+% ?line test_inline:performance(Config).
+
+testTcapsystem(suite) -> [];
+testTcapsystem(Config) ->
+ ?line ok=testTcapsystem:compile(Config,?BER,[]).
+
+testNBAPsystem(suite) -> [];
+testNBAPsystem(Config) ->
+ ?line ok=testNBAPsystem:compile(Config,?PER,?per_optimize(?BER)),
+ ?line ok=testNBAPsystem:test(?PER,Config).
+
+test_compile_options(suite) -> [];
+test_compile_options(Config) ->
+ case code:which(asn1ct) of
+ cover_compiled ->
+ {skip,"Not runnable when cover compiled"};
+ _ ->
+ ?line ok = test_compile_options:wrong_path(Config),
+ ?line ok = test_compile_options:path(Config),
+ ?line ok = test_compile_options:noobj(Config),
+ ?line ok = test_compile_options:record_name_prefix(Config),
+ ?line ok = test_compile_options:verbose(Config)
+ end.
+testDoubleEllipses(suite) -> [];
+testDoubleEllipses(Config) ->
+ ?line testDoubleEllipses:compile(Config,?BER,[]),
+ ?line testDoubleEllipses:main(?BER),
+ ?line ?ber_driver(?BER,testDoubleEllipses:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDoubleEllipses:main(?BER)),
+ ?line ?per_bit_opt(testDoubleEllipses:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDoubleEllipses:main(?PER)),
+ ?line ?uper_bin(testDoubleEllipses:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDoubleEllipses:main(uper_bin)),
+ ?line testDoubleEllipses:compile(Config,?PER,?per_optimize(?BER)),
+ ?line testDoubleEllipses:main(?PER).
+
+test_modified_x420(suite) -> [];
+test_modified_x420(Config) ->
+ ?line test_modified_x420:compile(Config),
+ ?line test_modified_x420:test_io(Config).
+
+testX420(suite) -> [];
+testX420(Config) ->
+ ?line testX420:compile(?BER,[der],Config),
+ ?line ok = testX420:ticket7759(?BER,Config),
+ ?line testX420:compile(?PER,[],Config).
+
+test_x691(suite) -> [];
+test_x691(Config) ->
+ case ?PER of
+ per ->
+ ?line ok = test_x691:compile(Config,uper_bin,[]),
+ ?line true = test_x691:cases(uper_bin,unaligned),
+ ?line ok = test_x691:compile(Config,?PER,[]),
+ ?line true = test_x691:cases(?PER,aligned),
+%% ?line ok = asn1_test_lib:ticket_7678(Config,[]),
+ ?line ok = asn1_test_lib:ticket_7708(Config,[]),
+ ?line ok = asn1_test_lib:ticket_7763(Config);
+ _ ->
+ ?line ok = test_x691:compile(Config,?PER,?per_optimize(?BER)),
+ ?line true = test_x691:cases(?PER,aligned)
+ end.
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[compact_bit_string]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize,compact_bit_string]).
+
+
+ticket_6143(suite) -> [];
+ticket_6143(Config) ->
+ ?line ok = test_compile_options:ticket_6143(Config).
+
+testExtensionAdditionGroup(suite) -> [];
+testExtensionAdditionGroup(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line PrivDir = ?config(priv_dir,Config),
+ ?line Path = code:get_path(),
+ ?line code:add_patha(PrivDir),
+ DoIt = fun(Erule) ->
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),[Erule,{outdir,PrivDir}]),
+ ?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]),
+ ?line ok = extensionAdditionGroup:run(Erule)
+ end,
+ ?line [DoIt(Rule)|| Rule <- [per_bin,uper_bin,ber_bin]],
+ ?line code:set_path(Path).
+
+
+
+% parse_modules() ->
+% ["ImportsFrom"].
+
+per_modules() ->
+ [X || X <- test_modules()].
+ber_modules() ->
+ [X || X <- test_modules(),
+ X =/= "CommonDataTypes",
+ X =/= "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
+ X =/= "H323-MESSAGES",
+ X =/= "H235-SECURITY-MESSAGES",
+ X =/= "MULTIMEDIA-SYSTEM-CONTROL"].
+test_modules() ->
+ _Modules = [
+ "BitStr",
+ "CommonDataTypes",
+ "Constraints",
+ "ContextSwitchingTypes",
+ "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
+ "Enum",
+ "From",
+ "H235-SECURITY-MESSAGES",
+ "H323-MESSAGES",
+ %%"MULTIMEDIA-SYSTEM-CONTROL", recursive type , problem for asn1ct:value
+ "Import",
+ "Int",
+ "MAP-commonDataTypes",
+% ambigous tags "MAP-insertSubscriberData-def",
+ "Null",
+ "Octetstr",
+ "One",
+ "P-Record",
+ "P",
+% "PDUs",
+ "Person",
+ "PrimStrings",
+ "Real",
+ "XSeq",
+ "XSeqOf",
+ "XSet",
+ "XSetOf",
+ "String",
+ "SwCDR",
+% "Syntax",
+ "Time"
+% ANY "Tst",
+% "Two",
+% errors that should be detected "UndefType"
+] ++
+ [
+ "SeqSetLib", % must be compiled before Seq and Set
+ "Seq",
+ "Set",
+ "SetOf",
+ "SeqOf",
+ "Prim",
+ "Cho",
+ "Def",
+ "Opt",
+ "ELDAPv3",
+ "LDAP"
+ ].
+
+
+common() ->
+[].
+
+particular() ->
+[].
diff --git a/lib/asn1/test/asn1_bin_v2_SUITE.erl b/lib/asn1/test/asn1_bin_v2_SUITE.erl
new file mode 100644
index 0000000000..43d6ba0c6e
--- /dev/null
+++ b/lib/asn1/test/asn1_bin_v2_SUITE.erl
@@ -0,0 +1,2474 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%% Purpose : Test suite for the ASN.1 application
+
+-module(asn1_bin_v2_SUITE).
+-define(PER,'per_bin').
+-define(BER,'ber_bin_v2').
+-define(ber_driver(Erule,Func),
+ case Erule of
+ ber_bin_v2 ->
+ Func;
+ _ -> ok
+ end).
+-define(per_optimize(Erule),
+ case Erule of
+ ber_bin_v2 ->[optimize];
+ _ -> []
+ end).
+-define(per_bit_opt(FuncCall),
+ case ?BER of
+ ber_bin_v2 -> FuncCall;
+% _ -> {skip,"only for bit optimized per_bin"}
+ _ -> ok
+ end).
+-define(uper_bin(FuncCall),
+ case ?PER of
+ per -> FuncCall;
+ _ -> ok
+ end).
+
+-compile(export_all).
+%%-export([Function/Arity, ...]).
+
+-include_lib("test_server/include/test_server.hrl").
+
+%% records used by test-case default
+-record('Def1',{
+bool0, bool1 = asn1_DEFAULT, bool2 = asn1_DEFAULT, bool3 = asn1_DEFAULT}).
+
+%-record('Def2',{
+%bool10, bool11 = asn1_DEFAULT, bool12 = asn1_DEFAULT, bool13}).
+
+%-record('Def3',{
+%bool30 = asn1_DEFAULT, bool31 = asn1_DEFAULT, bool32 = asn1_DEFAULT, bool33 = asn1_DEFAULT}).
+
+
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, compile}, parse, default_per, default_ber,
+ default_per_opt, per, {group, ber}, testPrim,
+ testPrimStrings, testPrimExternal, testChoPrim,
+ testChoExtension, testChoExternal, testChoOptional,
+ testChoOptionalImplicitTag, testChoRecursive,
+ testChoTypeRefCho, testChoTypeRefPrim,
+ testChoTypeRefSeq, testChoTypeRefSet, testDef, testOpt,
+ testSeqDefault, testSeqExtension, testSeqExternal,
+ testSeqOptional, testSeqPrim, testSeqTag,
+ testSeqTypeRefCho, testSeqTypeRefPrim,
+ testSeqTypeRefSeq, testSeqTypeRefSet, testSeqOf,
+ testSeqOfIndefinite, testSeqOfCho, testSeqOfExternal,
+ testSetDefault, testSetExtension,
+ testExtensionAdditionGroup, testSetExternal,
+ testSeqOfTag, testSetOptional, testSetPrim, testSetTag,
+ testSetTypeRefCho, testSetTypeRefPrim,
+ testSetTypeRefSeq, testSetTypeRefSet, testSetOf,
+ testSetOfCho, testSetOfExternal, testSetOfTag,
+ testEnumExt, value_test, testSeq2738, constructed,
+ ber_decode_error, h323test, testSeqIndefinite,
+ testSetIndefinite, testChoiceIndefinite,
+ per_GeneralString, per_open_type, testInfObjectClass,
+ testParameterizedInfObj, testMergeCompile, testobj,
+ testDeepTConstr, testConstraints, testInvokeMod,
+ testExport, testImport, testCompactBitString,
+ testMegaco, testParamBasic, testMvrasn6,
+ testContextSwitchingTypes, testTypeValueNotation,
+ testOpenTypeImplicitTag, duplicate_tags, rtUI, testROSE,
+ testINSTANCE_OF, testTCAP, testDER, specialized_decodes,
+ special_decode_performance, test_driver_load,
+ test_ParamTypeInfObj, test_WS_ParamClass,
+ test_Defed_ObjectIdentifier, testSelectionType,
+ testSSLspecs, testNortel, test_undecoded_rest,
+ test_inline, testTcapsystem, testNBAPsystem,
+ test_compile_options, testDoubleEllipses,
+ test_modified_x420, testX420, test_x691, ticket_6143,
+ testExtensionAdditionGroup] ++ common() ++ particular().
+
+groups() ->
+ [{option_tests, [],
+ [test_compile_options, ticket_6143]},
+ {infobj, [],
+ [testInfObjectClass, testParameterizedInfObj,
+ testMergeCompile, testobj, testDeepTConstr]},
+ {performance, [],
+ [testTimer_ber, testTimer_ber_opt_driver, testTimer_per,
+ testTimer_per_opt, testTimer_uper_bin]},
+ {bugs, [],
+ [test_ParamTypeInfObj, test_WS_ParamClass,
+ test_Defed_ObjectIdentifier]},
+ {compile, [],
+ [c_syntax, c_string_per, c_string_ber,
+ c_implicit_before_choice]},
+ {ber, [],
+ [ber_choiceinseq, ber_optional, ber_optional_keyed_list,
+ ber_other]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+%all(suite) -> [test_inline,testNBAPsystem,test_compile_options,ticket_6143].
+
+init_per_testcase(Func,Config) ->
+ %%?line test_server:format("Func: ~p~n",[Func]),
+ ?line {ok, _} = file:read_file_info(filename:join([?config(priv_dir,Config)])),
+ ?line code:add_patha(?config(priv_dir,Config)),
+ Dog=
+ case Func of
+ testX420 ->
+ test_server:timetrap({minutes,60}); % 60 minutes
+ _ ->
+ test_server:timetrap({minutes,30}) % 60 minutes
+ end,
+ %% Dog=test_server:timetrap(1800000), % 30 minutes
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(_Func,Config) ->
+ Dog=?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog).
+
+
+testPrim(suite) -> [];
+testPrim(Config) ->
+ ?line testPrim:compile(Config,?BER,[]),
+ ?line testPrim_cases(?BER),
+ ?line ?ber_driver(?BER,testPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrim_cases(?BER)),
+ ?line testPrim:compile(Config,?PER,[]),
+ ?line testPrim_cases(?PER),
+ ?line ?per_bit_opt(testPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrim_cases(?PER)),
+ ?line ?uper_bin(testPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrim_cases(uper_bin)),
+ ?line testPrim:compile(Config,?PER,[optimize]),
+ ?line testPrim_cases(?PER).
+
+testPrim_cases(Rules) ->
+ ?line testPrim:bool(Rules),
+ ?line testPrim:int(Rules),
+ ?line testPrim:enum(Rules),
+ ?line testPrim:obj_id(Rules),
+ ?line testPrim:rel_oid(Rules),
+ ?line testPrim:null(Rules),
+ ?line testPrim:real(Rules).
+
+
+testCompactBitString(suite) -> [];
+testCompactBitString(Config) ->
+
+ ?line testCompactBitString:compile(Config,?BER,[compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?BER),
+
+ ?line ?ber_driver(?BER,testCompactBitString:compile(Config,?BER,[compact_bit_string,driver])),
+ ?line ?ber_driver(?BER,testCompactBitString:compact_bit_string(?BER)),
+
+ ?line testCompactBitString:compile(Config,?PER,[compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?PER),
+ ?line testCompactBitString:bit_string_unnamed(?PER),
+
+ ?line ?per_bit_opt(testCompactBitString:compile(Config,?PER,
+ [compact_bit_string,optimize])),
+ ?line ?per_bit_opt(testCompactBitString:compact_bit_string(?PER)),
+ ?line ?per_bit_opt(testCompactBitString:bit_string_unnamed(?PER)),
+ ?line ?per_bit_opt(testCompactBitString:ticket_7734(?PER)),
+
+ ?line ?uper_bin(testCompactBitString:compile(Config,uper_bin,
+ [compact_bit_string])),
+ ?line ?uper_bin(testCompactBitString:compact_bit_string(uper_bin)),
+ ?line ?uper_bin(testCompactBitString:bit_string_unnamed(uper_bin)),
+
+ ?line testCompactBitString:compile(Config,?PER,[optimize,compact_bit_string]),
+ ?line testCompactBitString:compact_bit_string(?PER),
+ ?line testCompactBitString:bit_string_unnamed(?PER),
+
+ ?line testCompactBitString:otp_4869(?PER).
+
+
+testPrimStrings(suite) -> [];
+testPrimStrings(Config) ->
+
+ ?line testPrimStrings:compile(Config,?BER,[]),
+ ?line testPrimStrings_cases(?BER),
+ ?line testPrimStrings:more_strings(?BER), %% these are not implemented in per yet
+ ?line ?ber_driver(?BER,testPrimStrings:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimStrings_cases(?BER)),
+ ?line ?ber_driver(?BER,testPrimStrings:more_strings(?BER)),
+
+ ?line testPrimStrings:compile(Config,?PER,[]),
+ ?line testPrimStrings_cases(?PER),
+
+ ?line ?per_bit_opt(testPrimStrings:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimStrings_cases(?PER)),
+
+ ?line ?uper_bin(testPrimStrings:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimStrings_cases(uper_bin)),
+
+ ?line testPrimStrings:compile(Config,?PER,[optimize]),
+ ?line testPrimStrings_cases(?PER).
+
+testPrimStrings_cases(Rules) ->
+ ?line testPrimStrings:bit_string(Rules),
+ ?line testPrimStrings:bit_string_unnamed(Rules),
+ ?line testPrimStrings:octet_string(Rules),
+ ?line testPrimStrings:numeric_string(Rules),
+ ?line testPrimStrings:other_strings(Rules),
+ ?line testPrimStrings:universal_string(Rules),
+ ?line testPrimStrings:bmp_string(Rules),
+ ?line testPrimStrings:times(Rules),
+ ?line testPrimStrings:utf8_string(Rules).
+
+
+
+testPrimExternal(suite) -> [];
+testPrimExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testPrimExternal:compile(Config,?BER,[]),
+ ?line testPrimExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testPrimExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testPrimExternal:compile(Config,?PER,[]),
+ ?line testPrimExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testPrimExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testPrimExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testPrimExternal:compile(Config,?PER,[optimize]),
+ ?line testPrimExternal_cases(?PER).
+
+testPrimExternal_cases(Rules) ->
+ ?line testPrimExternal:external(Rules).
+
+
+
+
+testChoPrim(suite) -> [];
+testChoPrim(Config) ->
+
+ ?line testChoPrim:compile(Config,?BER,[]),
+ ?line testChoPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoPrim_cases(?BER)),
+
+ ?line testChoPrim:compile(Config,?PER,[]),
+ ?line testChoPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testChoPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoPrim_cases(?PER)),
+
+ ?line ?uper_bin(testChoPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoPrim_cases(uper_bin)),
+
+ ?line testChoPrim:compile(Config,?PER,[optimize]),
+ ?line testChoPrim_cases(?PER).
+
+testChoPrim_cases(Rules) ->
+ ?line testChoPrim:bool(Rules),
+ ?line testChoPrim:int(Rules).
+
+
+
+testChoExtension(suite) -> [];
+testChoExtension(Config) ->
+
+ ?line testChoExtension:compile(Config,?BER,[]),
+ ?line testChoExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExtension_cases(?BER)),
+
+ ?line testChoExtension:compile(Config,?PER,[]),
+ ?line testChoExtension_cases(?PER),
+
+ ?line ?per_bit_opt(testChoExtension:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExtension_cases(?PER)),
+
+ ?line ?uper_bin(testChoExtension:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExtension_cases(uper_bin)),
+
+ ?line testChoExtension:compile(Config,?PER,[optimize]),
+ ?line testChoExtension_cases(?PER).
+
+testChoExtension_cases(Rules) ->
+ ?line testChoExtension:extension(Rules).
+
+
+
+testChoExternal(suite) -> [];
+testChoExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testChoExternal:compile(Config,?BER,[]),
+ ?line testChoExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testChoExternal:compile(Config,?PER,[]),
+ ?line testChoExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testChoExternal:compile(Config,?PER,[optimize]),
+ ?line testChoExternal_cases(?PER).
+
+
+testChoExternal_cases(Rules) ->
+ ?line testChoExternal:external(Rules).
+
+
+
+testChoOptional(suite) -> [];
+testChoOptional(Config) ->
+
+ ?line testChoOptional:compile(Config,?BER,[]),
+ ?line testChoOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoOptional_cases(?BER)),
+
+ ?line testChoOptional:compile(Config,?PER,[]),
+ ?line testChoOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testChoOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoOptional_cases(?PER)),
+
+ ?line ?uper_bin(testChoOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoOptional_cases(uper_bin)),
+
+ ?line testChoOptional:compile(Config,?PER,[optimize]),
+ ?line testChoOptional_cases(?PER).
+
+testChoOptional_cases(Rules) ->
+ ?line testChoOptional:optional(Rules).
+
+testChoOptionalImplicitTag(suite) -> [];
+testChoOptionalImplicitTag(Config) ->
+ %% Only meaningful for ?BER
+ ?line testChoOptionalImplicitTag:compile(Config,?BER),
+ ?line testChoOptionalImplicitTag:optional(?BER).
+
+
+testChoRecursive(suite) -> [];
+testChoRecursive(Config) ->
+
+ ?line testChoRecursive:compile(Config,?BER,[]),
+ ?line testChoRecursive_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoRecursive:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoRecursive_cases(?BER)),
+
+ ?line testChoRecursive:compile(Config,?PER,[]),
+ ?line testChoRecursive_cases(?PER),
+
+ ?line ?per_bit_opt(testChoRecursive:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoRecursive_cases(?PER)),
+
+ ?line ?uper_bin(testChoRecursive:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoRecursive_cases(uper_bin)),
+
+ ?line testChoRecursive:compile(Config,?PER,[optimize]),
+ ?line testChoRecursive_cases(?PER).
+
+testChoRecursive_cases(Rules) ->
+ ?line testChoRecursive:recursive(Rules).
+
+
+
+testChoTypeRefCho(suite) -> [];
+testChoTypeRefCho(Config) ->
+
+ ?line testChoTypeRefCho:compile(Config,?BER,[]),
+ ?line testChoTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefCho_cases(?BER)),
+
+ ?line testChoTypeRefCho:compile(Config,?PER,[]),
+ ?line testChoTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefCho_cases(uper_bin)),
+
+ ?line testChoTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefCho_cases(?PER).
+
+testChoTypeRefCho_cases(Rules) ->
+ ?line testChoTypeRefCho:choice(Rules).
+
+
+
+testChoTypeRefPrim(suite) -> [];
+testChoTypeRefPrim(Config) ->
+
+ ?line testChoTypeRefPrim:compile(Config,?BER,[]),
+ ?line testChoTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefPrim_cases(?BER)),
+
+ ?line testChoTypeRefPrim:compile(Config,?PER,[]),
+ ?line testChoTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefPrim_cases(uper_bin)),
+
+ ?line testChoTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefPrim_cases(?PER).
+
+testChoTypeRefPrim_cases(Rules) ->
+ ?line testChoTypeRefPrim:prim(Rules).
+
+
+
+testChoTypeRefSeq(suite) -> [];
+testChoTypeRefSeq(Config) ->
+
+ ?line testChoTypeRefSeq:compile(Config,?BER,[]),
+ ?line testChoTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefSeq_cases(?BER)),
+
+ ?line testChoTypeRefSeq:compile(Config,?PER,[]),
+ ?line testChoTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefSeq_cases(uper_bin)),
+
+ ?line testChoTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefSeq_cases(?PER).
+
+testChoTypeRefSeq_cases(Rules) ->
+ ?line testChoTypeRefSeq:seq(Rules).
+
+
+
+testChoTypeRefSet(suite) -> [];
+testChoTypeRefSet(Config) ->
+
+ ?line testChoTypeRefSet:compile(Config,?BER,[]),
+ ?line testChoTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testChoTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoTypeRefSet_cases(?BER)),
+
+ ?line testChoTypeRefSet:compile(Config,?PER,[]),
+ ?line testChoTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testChoTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testChoTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testChoTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testChoTypeRefSet_cases(uper_bin)),
+
+ ?line testChoTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testChoTypeRefSet_cases(?PER).
+
+testChoTypeRefSet_cases(Rules) ->
+ ?line testChoTypeRefSet:set(Rules).
+
+
+
+testDef(suite) -> [];
+testDef(Config) ->
+
+ ?line testDef:compile(Config,?BER,[]),
+ ?line testDef_cases(?BER),
+
+ ?line ?ber_driver(?BER,testDef:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDef_cases(?BER)),
+
+ ?line testDef:compile(Config,?PER,[]),
+ ?line testDef_cases(?PER),
+
+ ?line ?per_bit_opt(testDef:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDef_cases(?PER)),
+
+ ?line ?uper_bin(testDef:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDef_cases(uper_bin)),
+
+ ?line testDef:compile(Config,?PER,[optimize]),
+ ?line testDef_cases(?PER).
+
+testDef_cases(Rules) ->
+ ?line testDef:main(Rules).
+
+
+
+testOpt(suite) -> [];
+testOpt(Config) ->
+
+ ?line testOpt:compile(Config,?BER),
+ ?line testOpt_cases(?BER),
+
+ ?line testOpt:compile(Config,?PER),
+ ?line testOpt_cases(?PER).
+
+testOpt_cases(Rules) ->
+ ?line testOpt:main(Rules).
+
+
+testEnumExt(suite) -> [];
+testEnumExt(Config) ->
+
+ ?line testEnumExt:compile(Config,?BER,[]),
+ ?line testEnumExt:main(?BER),
+
+ ?line ?ber_driver(?BER,testEnumExt:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testEnumExt:main(?BER)),
+
+ ?line testEnumExt:compile(Config,?PER,[]),
+ ?line testEnumExt:main(?PER),
+
+ ?line ?per_bit_opt(testEnumExt:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testEnumExt:main(?PER)),
+
+ ?line ?uper_bin(testEnumExt:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testEnumExt:main(uper_bin)),
+
+ ?line testEnumExt:compile(Config,?PER,[optimize]),
+ ?line testEnumExt:main(?PER).
+
+testSeqDefault(doc) -> ["Test of OTP-2523 ENUMERATED with extensionmark."];
+testSeqDefault(suite) -> [];
+testSeqDefault(Config) ->
+
+ ?line testSeqDefault:compile(Config,?BER,[]),
+ ?line testSeqDefault_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqDefault:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqDefault_cases(?BER)),
+
+ ?line testSeqDefault:compile(Config,?PER,[]),
+ ?line testSeqDefault_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqDefault:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqDefault_cases(?PER)),
+
+ ?line ?uper_bin(testSeqDefault:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqDefault_cases(uper_bin)),
+
+ ?line testSeqDefault:compile(Config,?PER,[optimize]),
+ ?line testSeqDefault_cases(?PER).
+
+testSeqDefault_cases(Rules) ->
+ ?line testSeqDefault:main(Rules).
+
+
+
+testSeqExtension(suite) -> [];
+testSeqExtension(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqExtension:compile(Config,?BER,[]),
+ ?line testSeqExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExtension_cases(?BER)).
+
+testSeqExtension_cases(Rules) ->
+ ?line testSeqExtension:main(Rules).
+
+
+
+testSeqExternal(suite) -> [];
+testSeqExternal(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqExternal:compile(Config,?BER,[]),
+ ?line testSeqExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqExternal_cases(?BER)).
+
+testSeqExternal_cases(Rules) ->
+ ?line testSeqExternal:main(Rules).
+
+
+testSeqOptional(suite) -> [];
+testSeqOptional(Config) ->
+
+ ?line testSeqOptional:compile(Config,?BER,[]),
+ ?line testSeqOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOptional_cases(?BER)),
+
+ ?line testSeqOptional:compile(Config,?PER,[]),
+ ?line testSeqOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOptional_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOptional_cases(uper_bin)),
+
+ ?line testSeqOptional:compile(Config,?PER,[optimize]),
+ ?line testSeqOptional_cases(?PER).
+
+testSeqOptional_cases(Rules) ->
+ ?line testSeqOptional:main(Rules).
+
+
+
+testSeqPrim(suite) -> [];
+testSeqPrim(Config) ->
+
+ ?line testSeqPrim:compile(Config,?BER,[]),
+ ?line testSeqPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqPrim_cases(?BER)),
+
+ ?line testSeqPrim:compile(Config,?PER,[]),
+ ?line testSeqPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSeqPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqPrim_cases(uper_bin)),
+
+ ?line testSeqPrim:compile(Config,?PER,[optimize]),
+ ?line testSeqPrim_cases(?PER).
+
+testSeqPrim_cases(Rules) ->
+ ?line testSeqPrim:main(Rules).
+
+
+testSeq2738(doc) -> ["Test of OTP-2738 Detect corrupt optional component."];
+testSeq2738(suite) -> [];
+testSeq2738(Config) ->
+
+ ?line testSeq2738:compile(Config,?BER,[]),
+ ?line testSeq2738_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeq2738:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeq2738_cases(?BER)),
+
+ ?line testSeq2738:compile(Config,?PER,[]),
+ ?line testSeq2738_cases(?PER),
+
+ ?line ?per_bit_opt(testSeq2738:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeq2738_cases(?PER)),
+
+ ?line ?uper_bin(testSeq2738:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeq2738_cases(uper_bin)),
+
+ ?line testSeq2738:compile(Config,?PER,[optimize]),
+ ?line testSeq2738_cases(?PER).
+
+testSeq2738_cases(Rules) ->
+ ?line testSeq2738:main(Rules).
+
+
+testSeqTag(suite) -> [];
+testSeqTag(Config) ->
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqTag:compile(Config,?BER,[]),
+ ?line testSeqTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqTag:compile(Config,?PER,[]),
+ ?line testSeqTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqTag:compile(Config,?PER,[optimize]),
+ ?line testSeqTag_cases(?PER).
+
+testSeqTag_cases(Rules) ->
+ ?line testSeqTag:main(Rules).
+
+
+
+
+testSeqTypeRefCho(suite) -> [];
+testSeqTypeRefCho(Config) ->
+
+ ?line testSeqTypeRefCho:compile(Config,?BER,[]),
+ ?line testSeqTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefCho_cases(?BER)),
+
+ ?line testSeqTypeRefCho:compile(Config,?PER,[]),
+ ?line testSeqTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefCho_cases(uper_bin)),
+
+ ?line testSeqTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefCho_cases(?PER).
+
+testSeqTypeRefCho_cases(Rules) ->
+ ?line testSeqTypeRefCho:main(Rules).
+
+
+
+testSeqTypeRefPrim(suite) -> [];
+testSeqTypeRefPrim(Config) ->
+
+ ?line testSeqTypeRefPrim:compile(Config,?BER,[]),
+ ?line testSeqTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefPrim_cases(?BER)),
+
+ ?line testSeqTypeRefPrim:compile(Config,?PER,[]),
+ ?line testSeqTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefPrim_cases(uper_bin)),
+
+ ?line testSeqTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefPrim_cases(?PER).
+
+testSeqTypeRefPrim_cases(Rules) ->
+ ?line testSeqTypeRefPrim:main(Rules).
+
+
+
+testSeqTypeRefSeq(suite) -> [];
+testSeqTypeRefSeq(Config) ->
+
+ ?line testSeqTypeRefSeq:compile(Config,?BER,[]),
+ ?line testSeqTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefSeq_cases(?BER)),
+
+ ?line testSeqTypeRefSeq:compile(Config,?PER,[]),
+ ?line testSeqTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefSeq_cases(uper_bin)),
+
+ ?line testSeqTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefSeq_cases(?PER).
+
+testSeqTypeRefSeq_cases(Rules) ->
+ ?line testSeqTypeRefSeq:main(Rules).
+
+
+
+testSeqTypeRefSet(suite) -> [];
+testSeqTypeRefSet(Config) ->
+
+ ?line testSeqTypeRefSet:compile(Config,?BER,[]),
+ ?line testSeqTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqTypeRefSet_cases(?BER)),
+
+ ?line testSeqTypeRefSet:compile(Config,?PER,[]),
+ ?line testSeqTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testSeqTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqTypeRefSet_cases(uper_bin)),
+
+ ?line testSeqTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testSeqTypeRefSet_cases(?PER).
+
+testSeqTypeRefSet_cases(Rules) ->
+ ?line testSeqTypeRefSet:main(Rules).
+
+
+
+
+testSeqOf(suite) -> [];
+testSeqOf(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOf:compile(Config,?BER,[]),
+ ?line testSeqOf_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOf:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOf_cases(?BER)),
+
+ ?line testSeqOf:compile(Config,?PER,[]),
+ ?line testSeqOf_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOf:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOf_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOf:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOf_cases(uper_bin)),
+
+ ?line testSeqOf:compile(Config,?PER,[optimize]),
+ ?line testSeqOf_cases(?PER).
+
+testSeqOf_cases(Rules) ->
+ ?line testSeqOf:main(Rules).
+
+
+
+
+testSeqOfCho(suite) -> [];
+testSeqOfCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOfCho:compile(Config,?BER,[]),
+ ?line testSeqOfCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSeqOfCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfCho_cases(?BER)),
+
+ ?line testSeqOfCho:compile(Config,?PER,[]),
+ ?line testSeqOfCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSeqOfCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfCho_cases(?PER)),
+
+ ?line ?uper_bin(testSeqOfCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfCho_cases(uper_bin)),
+
+ ?line testSeqOfCho:compile(Config,?PER,[optimize]),
+ ?line testSeqOfCho_cases(?PER).
+
+testSeqOfIndefinite(suite) -> [];
+testSeqOfIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqOfIndefinite:compile(Config,?BER,[]),
+ ?line testSeqOfIndefinite:main(),
+
+ ?line ?ber_driver(?BER,testSeqOfIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfIndefinite:main()).
+
+testSeqOfCho_cases(Rules) ->
+ ?line testSeqOfCho:main(Rules).
+
+
+testSeqOfExternal(suite) -> [];
+testSeqOfExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqOfExternal:compile(Config,?BER,[]),
+ ?line testSeqOfExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqOfExternal:compile(Config,?PER,[]),
+ ?line testSeqOfExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfExternal_cases(?PER).
+
+testSeqOfExternal_cases(Rules) ->
+ ?line testSeqOfExternal:main(Rules).
+
+
+
+testSeqOfTag(suite) -> [];
+testSeqOfTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSeqOfTag:compile(Config,?BER,[]),
+ ?line testSeqOfTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqOfTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSeqOfTag:compile(Config,?PER,[]),
+ ?line testSeqOfTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSeqOfTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSeqOfTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSeqOfTag:compile(Config,?PER,[optimize]),
+ ?line testSeqOfTag_cases(?PER).
+
+testSeqOfTag_cases(Rules) ->
+ ?line testSeqOfTag:main(Rules).
+
+
+
+
+testSetDefault(suite) -> [];
+testSetDefault(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetDefault:compile(Config,?BER,[]),
+ ?line testSetDefault_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetDefault:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetDefault_cases(?BER)),
+
+ ?line testSetDefault:compile(Config,?PER,[]),
+ ?line testSetDefault_cases(?PER),
+
+ ?line ?per_bit_opt(testSetDefault:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetDefault_cases(?PER)),
+
+ ?line ?uper_bin(testSetDefault:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetDefault_cases(uper_bin)),
+
+ ?line testSetDefault:compile(Config,?PER,[optimize]),
+ ?line testSetDefault_cases(?PER).
+
+testSetDefault_cases(Rules) ->
+ ?line testSetDefault:main(Rules).
+
+
+testParamBasic(suite) -> [];
+testParamBasic(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testParamBasic:compile(Config,?BER,[]),
+ ?line testParamBasic_cases(?BER),
+
+ ?line ?ber_driver(?BER,testParamBasic:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testParamBasic_cases(?BER)),
+
+ ?line testParamBasic:compile(Config,?PER,[]),
+ ?line testParamBasic_cases(?PER),
+
+ ?line ?per_bit_opt(testParamBasic:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testParamBasic_cases(?PER)),
+
+ ?line ?uper_bin(testParamBasic:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testParamBasic_cases(uper_bin)),
+
+ ?line testParamBasic:compile(Config,?PER,[optimize]),
+ ?line testParamBasic_cases(?PER).
+
+
+testParamBasic_cases(Rules) ->
+ ?line testParamBasic:main(Rules).
+
+testSetExtension(suite) -> [];
+testSetExtension(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetExtension:compile(Config,?BER,[]),
+ ?line testSetExtension_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExtension:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExtension_cases(?BER)).
+
+testSetExtension_cases(Rules) ->
+ ?line testSetExtension:main(Rules).
+
+
+testSetExternal(suite) -> [];
+testSetExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetExternal:compile(Config,?BER,[]),
+ ?line testSetExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetExternal_cases(?BER)).
+
+testSetExternal_cases(Rules) ->
+ ?line testSetExternal:main(Rules).
+
+
+testSetOptional(suite) -> [];
+testSetOptional(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOptional:compile(Config,?BER,[]),
+ ?line testSetOptional_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOptional:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOptional_cases(?BER)),
+
+ ?line testSetOptional:compile(Config,?PER,[]),
+ ?line testSetOptional_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOptional:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOptional_cases(?PER)),
+
+ ?line ?uper_bin(testSetOptional:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOptional_cases(uper_bin)),
+
+ ?line testSetOptional:compile(Config,?PER,[optimize]),
+ ?line testSetOptional_cases(?PER).
+
+testSetOptional_cases(Rules) ->
+ ?line ok = testSetOptional:ticket_7533(Rules),
+ ?line ok = testSetOptional:main(Rules).
+
+
+
+
+testSetPrim(suite) -> [];
+testSetPrim(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetPrim:compile(Config,?BER,[]),
+ ?line testSetPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetPrim_cases(?BER)),
+
+ ?line testSetPrim:compile(Config,?PER,[]),
+ ?line testSetPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSetPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSetPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetPrim_cases(uper_bin)),
+
+ ?line testSetPrim:compile(Config,?PER,[optimize]),
+ ?line testSetPrim_cases(?PER).
+
+testSetPrim_cases(Rules) ->
+ ?line testSetPrim:main(Rules).
+
+
+
+testSetTag(suite) -> [];
+testSetTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetTag:compile(Config,?BER,[]),
+ ?line testSetTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetTag:compile(Config,?PER,[]),
+ ?line testSetTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetTag:compile(Config,?PER,[optimize]),
+ ?line testSetTag_cases(?PER).
+
+testSetTag_cases(Rules) ->
+ ?line testSetTag:main(Rules).
+
+
+
+testSetTypeRefCho(suite) -> [];
+testSetTypeRefCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefCho:compile(Config,?BER,[]),
+ ?line testSetTypeRefCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefCho_cases(?BER)),
+
+ ?line testSetTypeRefCho:compile(Config,?PER,[]),
+ ?line testSetTypeRefCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefCho_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefCho_cases(uper_bin)),
+
+ ?line testSetTypeRefCho:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefCho_cases(?PER).
+
+testSetTypeRefCho_cases(Rules) ->
+ ?line testSetTypeRefCho:main(Rules).
+
+
+
+testSetTypeRefPrim(suite) -> [];
+testSetTypeRefPrim(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefPrim:compile(Config,?BER,[]),
+ ?line testSetTypeRefPrim_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefPrim:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefPrim_cases(?BER)),
+
+ ?line testSetTypeRefPrim:compile(Config,?PER,[]),
+ ?line testSetTypeRefPrim_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefPrim:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefPrim_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefPrim:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefPrim_cases(uper_bin)),
+
+ ?line testSetTypeRefPrim:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefPrim_cases(?PER).
+
+testSetTypeRefPrim_cases(Rules) ->
+ ?line testSetTypeRefPrim:main(Rules).
+
+
+
+testSetTypeRefSeq(suite) -> [];
+testSetTypeRefSeq(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefSeq:compile(Config,?BER,[]),
+ ?line testSetTypeRefSeq_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefSeq:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefSeq_cases(?BER)),
+
+ ?line testSetTypeRefSeq:compile(Config,?PER,[]),
+ ?line testSetTypeRefSeq_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefSeq:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefSeq_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefSeq:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefSeq_cases(uper_bin)),
+
+ ?line testSetTypeRefSeq:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefSeq_cases(?PER).
+
+testSetTypeRefSeq_cases(Rules) ->
+ ?line testSetTypeRefSeq:main(Rules).
+
+
+
+testSetTypeRefSet(suite) -> [];
+testSetTypeRefSet(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetTypeRefSet:compile(Config,?BER,[]),
+ ?line testSetTypeRefSet_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetTypeRefSet:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetTypeRefSet_cases(?BER)),
+
+ ?line testSetTypeRefSet:compile(Config,?PER,[]),
+ ?line testSetTypeRefSet_cases(?PER),
+
+ ?line ?per_bit_opt(testSetTypeRefSet:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetTypeRefSet_cases(?PER)),
+
+ ?line ?uper_bin(testSetTypeRefSet:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetTypeRefSet_cases(uper_bin)),
+
+ ?line testSetTypeRefSet:compile(Config,?PER,[optimize]),
+ ?line testSetTypeRefSet_cases(?PER).
+
+testSetTypeRefSet_cases(Rules) ->
+ ?line testSetTypeRefSet:main(Rules).
+
+
+
+testSetOf(suite) -> [];
+testSetOf(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOf:compile(Config,?BER,[]),
+ ?line testSetOf_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOf:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOf_cases(?BER)),
+
+ ?line testSetOf:compile(Config,?PER,[]),
+ ?line testSetOf_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOf:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOf_cases(?PER)),
+
+ ?line ?uper_bin(testSetOf:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOf_cases(uper_bin)),
+
+ ?line testSetOf:compile(Config,?PER,[optimize]),
+ ?line testSetOf_cases(?PER).
+
+testSetOf_cases(Rules) ->
+ ?line testSetOf:main(Rules).
+
+
+
+testSetOfCho(suite) -> [];
+testSetOfCho(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetOfCho:compile(Config,?BER,[]),
+ ?line testSetOfCho_cases(?BER),
+
+ ?line ?ber_driver(?BER,testSetOfCho:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfCho_cases(?BER)),
+
+ ?line testSetOfCho:compile(Config,?PER,[]),
+ ?line testSetOfCho_cases(?PER),
+
+ ?line ?per_bit_opt(testSetOfCho:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfCho_cases(?PER)),
+
+ ?line ?uper_bin(testSetOfCho:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfCho_cases(uper_bin)),
+
+ ?line testSetOfCho:compile(Config,?PER,[optimize]),
+ ?line testSetOfCho_cases(?PER).
+
+testSetOfCho_cases(Rules) ->
+ ?line testSetOfCho:main(Rules).
+
+
+testSetOfExternal(suite) -> [];
+testSetOfExternal(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetOfExternal:compile(Config,?BER,[]),
+ ?line testSetOfExternal_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfExternal_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetOfExternal:compile(Config,?PER,[]),
+ ?line testSetOfExternal_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfExternal_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfExternal_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfExternal_cases(?PER).
+
+testSetOfExternal_cases(Rules) ->
+ ?line testSetOfExternal:main(Rules).
+
+
+
+
+testSetOfTag(suite) -> [];
+testSetOfTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testExternal:compile(Config,?BER,[]),
+ ?line testSetOfTag:compile(Config,?BER,[]),
+ ?line testSetOfTag_cases(?BER),
+
+ ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetOfTag_cases(?BER)),
+
+ ?line testExternal:compile(Config,?PER,[]),
+ ?line testSetOfTag:compile(Config,?PER,[]),
+ ?line testSetOfTag_cases(?PER),
+
+ ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testSetOfTag_cases(?PER)),
+
+ ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testSetOfTag_cases(uper_bin)),
+
+ ?line testExternal:compile(Config,?PER,[optimize]),
+ ?line testSetOfTag:compile(Config,?PER,[optimize]),
+ ?line testSetOfTag_cases(?PER).
+
+testSetOfTag_cases(Rules) ->
+ ?line testSetOfTag:main(Rules).
+
+
+c_syntax(suite) -> [];
+c_syntax(Config) ->
+ ?line DataDir% ?line testExternal:compile(Config,?PER),
+% ?line testPrimExternal:compile(Config,?PER),
+% ?line testPrimExternal_cases(?PER).
+ = ?config(data_dir,Config),
+ ?line _TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line {error,_R1} = asn1ct:compile(filename:join(DataDir,"Syntax")),
+ ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"BadTypeEnding")),
+ ?line {error,_R3} = asn1ct:compile(filename:join(DataDir,
+ "BadValueAssignment1")),
+ ?line {error,_R4} = asn1ct:compile(filename:join(DataDir,
+ "BadValueAssignment2")),
+ ?line {error,_R5} = asn1ct:compile(filename:join(DataDir,
+ "BadValueSet")),
+ ?line {error,_R6} = asn1ct:compile(filename:join(DataDir,
+ "ChoiceBadExtension")),
+ ?line {error,_R7} = asn1ct:compile(filename:join(DataDir,
+ "EnumerationBadExtension")),
+ ?line {error,_R8} = asn1ct:compile(filename:join(DataDir,
+ "Example")),
+ ?line {error,_R9} = asn1ct:compile(filename:join(DataDir,
+ "Export1")),
+ ?line {error,_R10} = asn1ct:compile(filename:join(DataDir,
+ "MissingEnd")),
+ ?line {error,_R11} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComma")),
+ ?line {error,_R12} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComponentName")),
+ ?line {error,_R13} = asn1ct:compile(filename:join(DataDir,
+ "SequenceBadComponentType")),
+ ?line {error,_R14} = asn1ct:compile(filename:join(DataDir,
+ "SeqBadComma")).
+
+
+c_string_per(suite) -> [];
+c_string_per(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?PER,{outdir,TempDir}]).
+
+c_string_ber(suite) -> [];
+c_string_ber(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?BER,{outdir,TempDir}]).
+
+
+c_implicit_before_choice(suite) -> [];
+c_implicit_before_choice(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line TempDir = ?config(priv_dir,Config),
+ ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"CCSNARG3"),[?BER,{outdir,TempDir}]).
+
+parse(suite) -> [];
+parse(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ M1 = test_modules(),
+% M2 = parse_modules(),
+ ?line ok = parse1(M1,DataDir,OutDir).
+
+parse1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[abs,{outdir,OutDir}]),
+ parse1(T,DataDir,OutDir);
+parse1([],_,_) ->
+ ok.
+
+per(suite) -> [];
+per(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = per1(per_modules(),DataDir,OutDir),
+ ?line ?per_bit_opt(per1_bit_opt(per_modules(),DataDir,OutDir)),
+ ?line ok = per1_opt(per_modules(),DataDir,OutDir).
+
+
+per1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1(T,DataDir,OutDir);
+per1([],_,_) ->
+ ok.
+
+per1_bit_opt([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimize,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1_bit_opt(T,DataDir,OutDir);
+per1_bit_opt([],_,_) ->
+ ok.
+
+per1_opt([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimized,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ per1_opt(T,DataDir,OutDir);
+per1_opt([],_,_) ->
+ ok.
+
+
+ber_choiceinseq(suite) ->[];
+ber_choiceinseq(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"ChoiceInSeq"),[?BER,{outdir,OutDir}]).
+
+ber_optional(suite) ->[];
+ber_optional(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),[?BER,{outdir,OutDir}]),
+ ?line V = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
+ {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
+ {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
+ ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
+ ?line Bytes = lists:flatten(B),
+ ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
+ ?line ok = eq(V,element(2,V2)).
+
+ber_optional_keyed_list(suite) ->[];
+ber_optional_keyed_list(Config) ->
+ case ?BER of
+ ber_bin_v2 -> ok;
+ _ ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),
+ [?BER,keyed_list,{outdir,OutDir}]),
+ ?line Vrecord = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
+ {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
+ {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
+ ?line V = [ {a,[{scriptKey,10}]},
+ {b,[]},
+ {c,[{callingPartysCategory,111}]} ],
+ ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
+ ?line Bytes = lists:flatten(B),
+ ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
+ ?line ok = eq(Vrecord,element(2,V2))
+ end.
+
+
+eq(V,V) ->
+ ok.
+
+
+ber_other(suite) ->[];
+ber_other(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = ber1(ber_modules(),DataDir,OutDir).
+
+
+ber1([M|T],DataDir,OutDir) ->
+ ?line ok = asn1ct:compile(DataDir ++ M,[?BER,{outdir,OutDir}]),
+ ?line ok = asn1ct:test(list_to_atom(M)),
+ ber1(T,DataDir,OutDir);
+ber1([],_,_) ->
+ ok.
+
+default_per(suite) ->[];
+default_per(Config) ->
+ default1(?PER,Config,[]).
+
+default_per_opt(suite) -> [];
+default_per_opt(Config) ->
+ ?per_bit_opt(default1(?PER,Config,[optimize])),
+ default1(?PER,Config,[optimize]).
+
+default_ber(suite) ->[];
+default_ber(Config) ->
+ default1(?BER,Config,[]).
+
+default1(Rule,Config,Options) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Def",[Rule,{outdir,OutDir}]++Options),
+ ?line {ok,Bytes1} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,
+ bool1 = true,
+ bool2 = true,
+ bool3 = true}),
+ ?line {ok,{'Def1',true,true,true,true}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes1)),
+
+ ?line {ok,Bytes2} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true}),
+ ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes2)),
+
+ ?line {ok,Bytes3} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,bool2=false}),
+ ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes3)).
+
+
+value_test(suite) ->[];
+value_test(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?BER,{outdir,OutDir}]),
+ ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
+ ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?PER,{outdir,OutDir}]),
+ ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
+ ?line ok = test_bad_values:tests(Config),
+ ok.
+
+
+constructed(suite) ->
+ [];
+constructed(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ ?line ok = asn1ct:compile(DataDir ++ "Constructed",[?BER,{outdir,OutDir}]),
+ ?line {ok,B} = asn1_wrapper:encode('Constructed','S',{'S',false}),
+ ?line [40,3,1,1,0] = lists:flatten(B),
+ ?line {ok,B1} = asn1_wrapper:encode('Constructed','S2',{'S2',false}),
+ ?line [40,5,48,3,1,1,0] = lists:flatten(B1),
+ ?line {ok,B2} = asn1_wrapper:encode('Constructed','I',10),
+ ?line [136,1,10] = lists:flatten(B2),
+ ok.
+
+ber_decode_error(suite) -> [];
+ber_decode_error(Config) ->
+ ?line ok = ber_decode_error:compile(Config,?BER,[]),
+ ?line ok = ber_decode_error:run([]),
+
+ ?line ok = ?ber_driver(?BER,ber_decode_error:compile(Config,?BER,[driver])),
+ ?line ok = ?ber_driver(?BER,ber_decode_error:run([driver])),
+ ok.
+
+h323test(suite) ->
+ [];
+h323test(Config) ->
+ ?line ok = h323test:compile(Config,?PER,[]),
+ ?line ok = h323test:run(?PER),
+ ?line ?per_bit_opt(h323test:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(h323test:run(?PER)),
+ ?line ?uper_bin(h323test:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(h323test:run(uper_bin)),
+ ?line ok = h323test:compile(Config,?PER,[optimize]),
+ ?line ok = h323test:run(?PER),
+ ok.
+
+per_GeneralString(suite) ->
+ [];
+per_GeneralString(Config) ->
+ case erlang:module_loaded('MULTIMEDIA-SYSTEM-CONTROL') of
+ true ->
+ ok;
+ false ->
+ h323test:compile(Config,?PER,[])
+ end,
+ UI = [109,64,1,57],
+ ?line {ok,_V} = asn1_wrapper:decode('MULTIMEDIA-SYSTEM-CONTROL',
+ 'MultimediaSystemControlMessage',UI).
+
+per_open_type(suite) ->
+ [];
+per_open_type(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line ok = asn1ct:compile(DataDir ++ "OpenType",[?PER,{outdir,OutDir}]),
+ Stype = {'Stype',10,true},
+ ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
+ ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes),
+
+ ?line ?per_bit_opt(ok = asn1ct:compile(DataDir ++ "OpenType",
+ [?PER,optimize,{outdir,OutDir}])),
+ ?line ?per_bit_opt({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
+ ?line ?per_bit_opt({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
+
+ ?line ?uper_bin(ok = asn1ct:compile(DataDir ++ "OpenType",
+ [uper_bin,{outdir,OutDir}])),
+ ?line ?uper_bin({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
+ ?line ?uper_bin({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
+
+ ?line ok = asn1ct:compile(DataDir ++ "OpenType",
+ [?PER,optimize,{outdir,OutDir}]),
+ ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
+ ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes).
+
+testConstraints(suite) ->
+ [];
+testConstraints(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testConstraints:compile(Config,?BER,[]),
+ ?line testConstraints:int_constraints(?BER),
+
+ ?line ?ber_driver(?BER,testConstraints:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testConstraints:int_constraints(?BER)),
+
+ ?line testConstraints:compile(Config,?PER,[]),
+ ?line testConstraints:int_constraints(?PER),
+ ?line testConstraints:refed_NNL_name(?PER),
+
+ ?line ?per_bit_opt(testConstraints:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testConstraints:int_constraints(?PER)),
+ ?line ?per_bit_opt(testConstraints:refed_NNL_name(?PER)),
+
+ ?line ?uper_bin(testConstraints:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testConstraints:int_constraints(uper_bin)),
+ ?line ?uper_bin(testConstraints:refed_NNL_name(uper_bin)),
+
+ ?line testConstraints:compile(Config,?PER,[optimize]),
+ ?line testConstraints:int_constraints(?PER),
+ ?line testConstraints:refed_NNL_name(?PER).
+
+testSeqIndefinite(suite) -> [];
+testSeqIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSeqIndefinite:compile(Config,?BER,[]),
+ ?line testSeqIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testSeqIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSeqIndefinite:main(?BER)).
+
+testSetIndefinite(suite) -> [];
+testSetIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testSetIndefinite:compile(Config,?BER,[]),
+ ?line testSetIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testSetIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testSetIndefinite:main(?BER)).
+
+testChoiceIndefinite(suite) -> [];
+testChoiceIndefinite(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testChoiceIndefinite:compile(Config,?BER,[]),
+ ?line testChoiceIndefinite:main(?BER),
+
+ ?line ?ber_driver(?BER,testChoiceIndefinite:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testChoiceIndefinite:main(?BER)).
+
+testInfObjectClass(suite) ->
+ [];
+testInfObjectClass(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testInfObjectClass:compile(Config,?PER,[]),
+ ?line testInfObjectClass:main(?PER),
+ ?line testInfObj:compile(Config,?PER,[]),
+ ?line testInfObj:main(?PER),
+
+ ?line ?per_bit_opt(testInfObjectClass:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testInfObjectClass:main(?PER)),
+ ?line ?per_bit_opt(testInfObj:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testInfObj:main(?PER)),
+
+ ?line ?uper_bin(testInfObjectClass:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testInfObjectClass:main(uper_bin)),
+ ?line ?uper_bin(testInfObj:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testInfObj:main(uper_bin)),
+
+ ?line testInfObjectClass:compile(Config,?PER,[optimize]),
+ ?line testInfObjectClass:main(?PER),
+ ?line testInfObj:compile(Config,?PER,[optimize]),
+ ?line testInfObj:main(?PER),
+
+ ?line testInfObjectClass:compile(Config,?BER,[]),
+ ?line testInfObjectClass:main(?BER),
+ ?line testInfObj:compile(Config,?BER,[]),
+ ?line testInfObj:main(?BER),
+
+ ?line ?ber_driver(?BER,testInfObjectClass:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testInfObjectClass:main(?BER)),
+ ?line ?ber_driver(?BER,testInfObj:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testInfObj:main(?BER)),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?PER,[]),
+
+ ?line ?per_bit_opt(testInfObj:compile_RANAPfiles(Config,?PER,[optimize])),
+
+ ?line ?uper_bin(testInfObj:compile_RANAPfiles(Config,uper_bin,[])),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?PER,[optimize]),
+
+ ?line testInfObj:compile_RANAPfiles(Config,?BER,[]).
+
+testParameterizedInfObj(suite) ->
+ [];
+testParameterizedInfObj(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testParameterizedInfObj:compile(Config,?PER,[]),
+ ?line testParameterizedInfObj:main(?PER),
+
+ ?line ?per_bit_opt(testParameterizedInfObj:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testParameterizedInfObj:main(?PER)),
+
+ ?line ?uper_bin(testParameterizedInfObj:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testParameterizedInfObj:main(uper_bin)),
+
+ ?line testParameterizedInfObj:compile(Config,?PER,[optimize]),
+ ?line testParameterizedInfObj:main(?PER),
+
+ ?line testParameterizedInfObj:compile(Config,?BER,[]),
+ ?line testParameterizedInfObj:main(?BER),
+
+ ?line ?ber_driver(?BER,testParameterizedInfObj:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testParameterizedInfObj:main(?BER)).
+
+testMergeCompile(suite) ->
+ [];
+testMergeCompile(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testMergeCompile:compile(Config,?PER,[]),
+ ?line testMergeCompile:main(?PER),
+ ?line testMergeCompile:mvrasn(?PER),
+
+ ?line ?per_bit_opt(testMergeCompile:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testMergeCompile:main(?PER)),
+ ?line ?per_bit_opt(testMergeCompile:mvrasn(?PER)),
+
+ ?line ?uper_bin(testMergeCompile:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testMergeCompile:main(uper_bin)),
+ ?line ?uper_bin(testMergeCompile:mvrasn(uper_bin)),
+
+ ?line testMergeCompile:compile(Config,?BER,[]),
+ ?line testMergeCompile:main(?BER),
+ ?line testMergeCompile:mvrasn(?BER),
+
+ ?line ?ber_driver(?BER,testMergeCompile:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testMergeCompile:main(?BER)),
+ ?line ?ber_driver(?BER,testMergeCompile:mvrasn(?BER)).
+
+testobj(suite) ->
+ [];
+testobj(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = testRANAP:compile(Config,?PER,[]),
+ ?line ok = testRANAP:testobj(?PER),
+ ?line ok = testParameterizedInfObj:ranap(?PER),
+
+ ?line ?per_bit_opt(ok = testRANAP:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(ok = testRANAP:testobj(?PER)),
+ ?line ?per_bit_opt(ok = testParameterizedInfObj:ranap(?PER)),
+
+ ?line ?uper_bin(ok = testRANAP:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(ok = testRANAP:testobj(uper_bin)),
+ ?line ?uper_bin(ok = testParameterizedInfObj:ranap(uper_bin)),
+
+ ?line ok = testRANAP:compile(Config,?PER,[optimize]),
+ ?line ok = testRANAP:testobj(?PER),
+ ?line ok = testParameterizedInfObj:ranap(?PER),
+
+ ?line ok = testRANAP:compile(Config,?BER,[]),
+ ?line ok = testRANAP:testobj(?BER),
+ ?line ok = testParameterizedInfObj:ranap(?BER),
+
+ ?line ?ber_driver(?BER,testRANAP:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testRANAP:testobj(?BER)),
+ ?line ?ber_driver(?BER,testParameterizedInfObj:ranap(?BER)).
+
+
+testDeepTConstr(suite) ->
+ [];
+testDeepTConstr(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testDeepTConstr:compile(Config,?PER,[]),
+ ?line testDeepTConstr:main(?PER),
+
+ ?line ?per_bit_opt(testDeepTConstr:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDeepTConstr:main(?PER)),
+
+ ?line ?uper_bin(testDeepTConstr:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDeepTConstr:main(uper_bin)),
+
+ ?line testDeepTConstr:compile(Config,?PER,[optimize]),
+ ?line testDeepTConstr:main(?PER),
+
+ ?line testDeepTConstr:compile(Config,?BER,[]),
+ ?line testDeepTConstr:main(?BER),
+
+ ?line ?ber_driver(?BER,testDeepTConstr:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDeepTConstr:main(?BER)).
+
+testInvokeMod(suite) ->
+ [];
+testInvokeMod(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[{outdir,OutDir}]),
+ ?line {ok,_Result1} = 'PrimStrings':encode('Bs1',[1,0,1,0]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[?PER,{outdir,OutDir}]),
+ ?line {ok,_Result2} = 'PrimStrings':encode('Bs1',[1,0,1,0]).
+
+testExport(suite) ->
+ [];
+testExport(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line {error,{asn1,_Reason}} = asn1ct:compile(filename:join(DataDir,"IllegalExport"),[{outdir,OutDir}]).
+
+testImport(suite) ->
+ [];
+testImport(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line _OutDir = ?config(priv_dir,Config),
+ ?line {error,_} = asn1ct:compile(filename:join(DataDir,"ImportsFrom"),[?BER]),
+ ok.
+
+testMegaco(suite) ->
+ [];
+testMegaco(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+ io:format("Config: ~p~n",[Config]),
+ ?line {ok,ModuleName1,ModuleName2} = testMegaco:compile(Config,?BER,[]),
+ ?line ok = testMegaco:main(ModuleName1,Config),
+ ?line ok = testMegaco:main(ModuleName2,Config),
+
+ case ?BER of
+ ber_bin_v2 ->
+ ?line {ok,ModuleName3,ModuleName4} = testMegaco:compile(Config,?BER,[driver]),
+ ?line ok = testMegaco:main(ModuleName3,Config),
+ ?line ok = testMegaco:main(ModuleName4,Config);
+ _-> ok
+ end,
+
+ ?line {ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[]),
+ ?line ok = testMegaco:main(ModuleName5,Config),
+ ?line ok = testMegaco:main(ModuleName6,Config),
+
+ ?line ?per_bit_opt({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(ok = testMegaco:main(ModuleName5,Config)),
+ ?line ?per_bit_opt(ok = testMegaco:main(ModuleName6,Config)),
+
+ ?line ?uper_bin({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(ok = testMegaco:main(ModuleName5,Config)),
+ ?line ?uper_bin(ok = testMegaco:main(ModuleName6,Config)),
+
+ ?line {ok,ModuleName7,ModuleName8} = testMegaco:compile(Config,?PER,[optimize]),
+ ?line ok = testMegaco:main(ModuleName7,Config),
+ ?line ok = testMegaco:main(ModuleName8,Config).
+
+
+testMvrasn6(suite) -> [];
+testMvrasn6(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testMvrasn6:compile(Config,?BER),
+ ?line testMvrasn6:main().
+
+testContextSwitchingTypes(suite) -> [];
+testContextSwitchingTypes(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testContextSwitchingTypes:compile(Config,?BER,[]),
+ ?line testContextSwitchingTypes:test(),
+
+ ?line ?ber_driver(?BER,testContextSwitchingTypes:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testContextSwitchingTypes:test()),
+
+ ?line testContextSwitchingTypes:compile(Config,?PER,[]),
+ ?line testContextSwitchingTypes:test(),
+
+ ?line ?per_bit_opt(testContextSwitchingTypes:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testContextSwitchingTypes:test()),
+
+ ?line ?uper_bin(testContextSwitchingTypes:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testContextSwitchingTypes:test()),
+
+ ?line testContextSwitchingTypes:compile(Config,?PER,[optimize]),
+ ?line testContextSwitchingTypes:test().
+
+testTypeValueNotation(suite) -> [];
+testTypeValueNotation(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ case ?BER of
+ Ber when Ber == ber; Ber == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?BER,[]),
+ ?line testTypeValueNotation:main(?BER,dummy);
+ _ ->
+ ok
+ end,
+
+ ?line ?ber_driver(?BER,testTypeValueNotation:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testTypeValueNotation:main(?BER,optimize)),
+
+ case ?BER of
+ Ber2 when Ber2 == ber; Ber2 == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?PER,[]),
+ ?line testTypeValueNotation:main(?PER,dummy);
+ _ ->
+ ok
+ end,
+
+ ?line ?per_bit_opt(testTypeValueNotation:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testTypeValueNotation:main(?PER,optimize)),
+
+ ?line ?uper_bin(testTypeValueNotation:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testTypeValueNotation:main(uper_bin,optimize)),
+ case ?BER of
+ Ber3 when Ber3 == ber; Ber3 == ber_bin ->
+ ?line testTypeValueNotation:compile(Config,?PER,[optimize]),
+ ?line testTypeValueNotation:main(?PER,optimize);
+ _ ->
+ ok
+ end.
+
+testOpenTypeImplicitTag(suite) -> [];
+testOpenTypeImplicitTag(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?BER,[]),
+ ?line testOpenTypeImplicitTag:main(?BER),
+
+ ?line ?ber_driver(?BER,testOpenTypeImplicitTag:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testOpenTypeImplicitTag:main(?BER)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?PER,[]),
+ ?line testOpenTypeImplicitTag:main(?PER),
+
+ ?line ?per_bit_opt(testOpenTypeImplicitTag:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testOpenTypeImplicitTag:main(?PER)),
+
+ ?line ?uper_bin(testOpenTypeImplicitTag:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testOpenTypeImplicitTag:main(uper_bin)),
+
+ ?line testOpenTypeImplicitTag:compile(Config,?PER,[optimize]),
+ ?line testOpenTypeImplicitTag:main(?PER).
+
+duplicate_tags(suite) -> [];
+duplicate_tags(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ {error,{asn1,[{error,{type,_,_,'SeqOpt1Imp',{asn1,{duplicates_of_the_tags,_}}}}]}} =
+ asn1ct:compile(filename:join(DataDir,"SeqOptional2"),[abs]),
+ ok.
+
+rtUI(suite) -> [];
+rtUI(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?BER]),
+ ?line {ok,_} = asn1rt:info('Prim'),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?PER]),
+ ?line {ok,_} = asn1rt:info('Prim'),
+
+ ?line ok = asn1rt:load_driver(),
+ ?line ok = asn1rt:load_driver(),
+ ?line ok = asn1rt:unload_driver().
+
+testROSE(suite) -> [];
+testROSE(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testROSE:compile(Config,?BER,[]),
+
+ ?line testROSE:compile(Config,?PER,[]),
+ ?line ?per_bit_opt(testROSE:compile(Config,?PER,[optimize])),
+ ?line ?uper_bin(testROSE:compile(Config,uper_bin,[])),
+ ?line testROSE:compile(Config,?PER,[optimize]).
+
+testINSTANCE_OF(suite) -> [];
+testINSTANCE_OF(Config) ->
+ ?line testINSTANCE_OF:compile(Config,?BER,[]),
+ ?line testINSTANCE_OF:main(?BER),
+
+ ?line ?ber_driver(?BER,testINSTANCE_OF:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testINSTANCE_OF:main(?BER)),
+
+ ?line testINSTANCE_OF:compile(Config,?PER,[]),
+ ?line testINSTANCE_OF:main(?PER),
+
+ ?line ?per_bit_opt(testINSTANCE_OF:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testINSTANCE_OF:main(?PER)),
+
+ ?line ?uper_bin(testINSTANCE_OF:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testINSTANCE_OF:main(uper_bin)),
+
+ ?line testINSTANCE_OF:compile(Config,?PER,[optimize]),
+ ?line testINSTANCE_OF:main(?PER).
+
+testTCAP(suite) -> [];
+testTCAP(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testTCAP:compile(Config,?BER,[]),
+ ?line testTCAP:test(?BER,Config),
+
+ ?line ?ber_driver(?BER,testTCAP:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testTCAP:test(?BER,Config)),
+
+ ?line ?ber_driver(?BER,testTCAP:compile_asn1config(Config,?BER,[asn1config])),
+ ?line ?ber_driver(?BER,testTCAP:test_asn1config()).
+
+testDER(suite) ->[];
+testDER(Config) ->
+ ?line true = code:add_patha(?config(priv_dir,Config)),
+
+ ?line testDER:compile(Config,?BER,[]),
+ ?line testDER:test(),
+
+ ?line ?ber_driver(?BER,testDER:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDER:test()),
+
+ ?line testParamBasic:compile_der(Config,?BER),
+ ?line testParamBasic_cases(der),
+
+
+ ?line testSeqSetDefaultVal:compile(Config,?BER),
+ ?line testSeqSetDefaultVal_cases(?BER).
+
+testSeqSetDefaultVal_cases(?BER) ->
+ ?line testSeqSetDefaultVal:main(?BER).
+
+
+specialized_decodes(suite) -> [];
+specialized_decodes(Config) ->
+ ?line test_partial_incomplete_decode:compile(Config,?BER,[optimize]),
+ ?line test_partial_incomplete_decode:test(?BER,Config),
+ ?line test_selective_decode:test(?BER,Config).
+
+special_decode_performance(suite) ->[];
+special_decode_performance(Config) ->
+ ?line ?ber_driver(?BER,test_special_decode_performance:compile(Config,?BER)),
+ ?line ?ber_driver(?BER,test_special_decode_performance:go(all)).
+
+
+test_driver_load(suite) -> [];
+test_driver_load(Config) ->
+ ?line test_driver_load:compile(Config,?PER),
+ ?line test_driver_load:test(?PER,5).
+
+test_ParamTypeInfObj(suite) -> [];
+test_ParamTypeInfObj(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"IN-CS-1-Datatypes"),[ber_bin]).
+
+test_WS_ParamClass(suite) -> [];
+test_WS_ParamClass(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"InformationFramework"),
+ [ber_bin]).
+
+test_Defed_ObjectIdentifier(suite) -> [];
+test_Defed_ObjectIdentifier(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"UsefulDefinitions"),
+ [ber_bin]).
+
+testSelectionType(suite) -> [];
+testSelectionType(Config) ->
+
+ ?line ok = testSelectionTypes:compile(Config,?BER,[]),
+ ?line {ok,_} = testSelectionTypes:test(),
+
+ ?line ok = testSelectionTypes:compile(Config,?PER,[]),
+ ?line {ok,_} = testSelectionTypes:test().
+
+testSSLspecs(suite) -> [];
+testSSLspecs(Config) ->
+
+ ?line ok = testSSLspecs:compile(Config,?BER,
+ [optimize,compact_bit_string,der]),
+ ?line testSSLspecs:run(?BER),
+
+ case code:which(asn1ct) of
+ cover_compiled ->
+ ok;
+ _ ->
+ ?line ok = testSSLspecs:compile_inline(Config,?BER),
+ ?line ok = testSSLspecs:run_inline(?BER)
+ end.
+
+testNortel(suite) -> [];
+testNortel(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?BER]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?BER,optimize]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?BER,optimize,driver]),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?PER]),
+ ?line ?per_bit_opt(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?PER,optimize])),
+ ?line ?uper_bin(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[uper_bin])),
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
+ [?PER,optimize]).
+test_undecoded_rest(suite) -> [];
+test_undecoded_rest(Config) ->
+
+ ?line ok = test_undecoded_rest:compile(Config,?BER,[]),
+ ?line ok = test_undecoded_rest:test([]),
+
+ ?line ok = test_undecoded_rest:compile(Config,?BER,[undec_rest]),
+ ?line ok = test_undecoded_rest:test(undec_rest),
+
+ ?line ok = test_undecoded_rest:compile(Config,?PER,[]),
+ ?line ok = test_undecoded_rest:test([]),
+
+ ?line ?per_bit_opt(ok = test_undecoded_rest:compile(Config,?PER,[optimize,undec_rest])),
+ ?line ?per_bit_opt(ok = test_undecoded_rest:test(undec_rest)),
+
+ ?line ?uper_bin(ok = test_undecoded_rest:compile(Config,uper_bin,[undec_rest])),
+ ?line ?uper_bin(ok = test_undecoded_rest:test(undec_rest)),
+
+ ?line ok = test_undecoded_rest:compile(Config,?PER,[undec_rest]),
+ ?line ok = test_undecoded_rest:test(undec_rest).
+
+test_inline(suite) -> [];
+test_inline(Config) ->
+ case code:which(asn1ct) of
+ cover_compiled ->
+ {skip,"Not runnable when cover compiled"};
+ _ ->
+ ?line ok=test_inline:compile(Config,?BER,[]),
+ ?line test_inline:main(?BER),
+ ?line test_inline:inline1(Config,?BER,[]),
+ ?line test_inline:performance2()
+ end.
+
+%test_inline_prf(suite) -> [];
+%test_inline_prf(Config) ->
+% ?line test_inline:performance(Config).
+
+testTcapsystem(suite) -> [];
+testTcapsystem(Config) ->
+ ?line ok=testTcapsystem:compile(Config,?BER,[]).
+
+testNBAPsystem(suite) -> [];
+testNBAPsystem(Config) ->
+ ?line ok=testNBAPsystem:compile(Config,?PER,?per_optimize(?BER)),
+ ?line ok=testNBAPsystem:test(?PER,Config).
+
+test_compile_options(suite) -> [];
+test_compile_options(Config) ->
+ case code:which(asn1ct) of
+ cover_compiled ->
+ {skip,"Not runnable when cover compiled"};
+ _ ->
+ ?line ok = test_compile_options:wrong_path(Config),
+ ?line ok = test_compile_options:path(Config),
+ ?line ok = test_compile_options:noobj(Config),
+ ?line ok = test_compile_options:record_name_prefix(Config),
+ ?line ok = test_compile_options:verbose(Config)
+ end.
+testDoubleEllipses(suite) -> [];
+testDoubleEllipses(Config) ->
+ ?line testDoubleEllipses:compile(Config,?BER,[]),
+ ?line testDoubleEllipses:main(?BER),
+ ?line ?ber_driver(?BER,testDoubleEllipses:compile(Config,?BER,[driver])),
+ ?line ?ber_driver(?BER,testDoubleEllipses:main(?BER)),
+ ?line ?per_bit_opt(testDoubleEllipses:compile(Config,?PER,[optimize])),
+ ?line ?per_bit_opt(testDoubleEllipses:main(?PER)),
+ ?line ?uper_bin(testDoubleEllipses:compile(Config,uper_bin,[])),
+ ?line ?uper_bin(testDoubleEllipses:main(uper_bin)),
+ ?line testDoubleEllipses:compile(Config,?PER,?per_optimize(?BER)),
+ ?line testDoubleEllipses:main(?PER).
+
+test_modified_x420(suite) -> [];
+test_modified_x420(Config) ->
+ ?line test_modified_x420:compile(Config),
+ ?line test_modified_x420:test_io(Config).
+
+testX420(suite) -> [];
+testX420(Config) ->
+ ?line testX420:compile(?BER,[der],Config),
+ ?line ok = testX420:ticket7759(?BER,Config),
+ ?line testX420:compile(?PER,[],Config).
+
+test_x691(suite) -> [];
+test_x691(Config) ->
+ case ?PER of
+ per ->
+ ?line ok = test_x691:compile(Config,uper_bin,[]),
+ ?line true = test_x691:cases(uper_bin,unaligned),
+ ?line ok = test_x691:compile(Config,?PER,[]),
+ ?line true = test_x691:cases(?PER,aligned),
+%% ?line ok = asn1_test_lib:ticket_7678(Config,[]),
+ ?line ok = asn1_test_lib:ticket_7708(Config,[]),
+ ?line ok = asn1_test_lib:ticket_7763(Config);
+ _ ->
+ ?line ok = test_x691:compile(Config,?PER,?per_optimize(?BER)),
+ ?line true = test_x691:cases(?PER,aligned)
+ end.
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[compact_bit_string]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize]),
+%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize,compact_bit_string]).
+
+
+ticket_6143(suite) -> [];
+ticket_6143(Config) ->
+ ?line ok = test_compile_options:ticket_6143(Config).
+
+testExtensionAdditionGroup(suite) -> [];
+testExtensionAdditionGroup(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line PrivDir = ?config(priv_dir,Config),
+ ?line Path = code:get_path(),
+ ?line code:add_patha(PrivDir),
+ DoIt = fun(Erule) ->
+ ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),[Erule,{outdir,PrivDir}]),
+ ?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]),
+ ?line ok = extensionAdditionGroup:run(Erule)
+ end,
+ ?line [DoIt(Rule)|| Rule <- [per_bin,uper_bin,ber_bin]],
+ ?line code:set_path(Path).
+
+
+
+% parse_modules() ->
+% ["ImportsFrom"].
+
+per_modules() ->
+ [X || X <- test_modules()].
+ber_modules() ->
+ [X || X <- test_modules(),
+ X =/= "CommonDataTypes",
+ X =/= "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
+ X =/= "H323-MESSAGES",
+ X =/= "H235-SECURITY-MESSAGES",
+ X =/= "MULTIMEDIA-SYSTEM-CONTROL"].
+test_modules() ->
+ _Modules = [
+ "BitStr",
+ "CommonDataTypes",
+ "Constraints",
+ "ContextSwitchingTypes",
+ "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
+ "Enum",
+ "From",
+ "H235-SECURITY-MESSAGES",
+ "H323-MESSAGES",
+ %%"MULTIMEDIA-SYSTEM-CONTROL", recursive type , problem for asn1ct:value
+ "Import",
+ "Int",
+ "MAP-commonDataTypes",
+% ambigous tags "MAP-insertSubscriberData-def",
+ "Null",
+ "Octetstr",
+ "One",
+ "P-Record",
+ "P",
+% "PDUs",
+ "Person",
+ "PrimStrings",
+ "Real",
+ "XSeq",
+ "XSeqOf",
+ "XSet",
+ "XSetOf",
+ "String",
+ "SwCDR",
+% "Syntax",
+ "Time"
+% ANY "Tst",
+% "Two",
+% errors that should be detected "UndefType"
+] ++
+ [
+ "SeqSetLib", % must be compiled before Seq and Set
+ "Seq",
+ "Set",
+ "SetOf",
+ "SeqOf",
+ "Prim",
+ "Cho",
+ "Def",
+ "Opt",
+ "ELDAPv3",
+ "LDAP"
+ ].
+
+
+common() ->
+[].
+
+particular() ->
+[smp, ticket7904].
+
+
+smp(suite) -> [];
+smp(Config) ->
+ case erlang:system_info(smp_support) of
+ true ->
+ NumOfProcs = erlang:system_info(schedulers),
+ io:format("smp starting ~p workers\n",[NumOfProcs]),
+
+ ?line Msg = {initiatingMessage, testNBAPsystem:cell_setup_req_msg()},
+ ?line ok = testNBAPsystem:compile(Config,per_bin,[optimize]),
+
+ Parent = self(),
+
+ ?line ok = asn1rt:load_driver(),
+
+ smp2(Parent,NumOfProcs,Msg,2),
+
+ N = 10000,
+
+ ?line {Time1,ok} = timer:tc(?MODULE,smp2,[Parent,NumOfProcs,Msg, N]),
+ ?line {Time1S,ok} = timer:tc(?MODULE,sequential,[NumOfProcs * N,Msg]),
+
+ ?line ok = testNBAPsystem:compile(Config,ber_bin,[optimize,driver]),
+ ?line {Time2,ok} = timer:tc(?MODULE,smp2,[Parent,NumOfProcs,Msg, N]),
+
+ ?line {Time2S,ok} = timer:tc(?MODULE,sequential,[NumOfProcs * N,Msg]),
+
+ {comment,lists:flatten(io_lib:format("Encode/decode time parallell with ~p cores: ~p [microsecs]~nEncode/decode time sequential: ~p [microsecs]",[NumOfProcs,Time1+Time2,Time1S+Time2S]))};
+ false ->
+ {skipped,"No smp support"}
+ end.
+
+smp2(Parent,NumOfProcs,Msg, N) ->
+ Pids = [spawn_link(fun() -> worker(Msg,Parent, N) end)
+ || _ <- lists:seq(1,NumOfProcs)],
+ ?line ok = wait_pids(Pids).
+
+worker(Msg, Parent, N) ->
+ %% io:format("smp worker ~p with ~p worker loops.~n",[self(), N]),
+ worker_loop(N, Msg),
+ Parent ! self().
+
+worker_loop(0, _Msg) ->
+ ok;
+worker_loop(N, Msg) ->
+ ?line {ok,B}=asn1_wrapper:encode('NBAP-PDU-Discriptions',
+ 'NBAP-PDU',
+ Msg),
+ ?line {ok,_Msg}=asn1_wrapper:decode('NBAP-PDU-Discriptions',
+ 'NBAP-PDU',
+ B),
+ worker_loop(N - 1, Msg).
+
+
+wait_pids([]) ->
+ ok;
+wait_pids(Pids) ->
+ receive
+ Pid when is_pid(Pid) ->
+ ?line true = lists:member(Pid,Pids),
+ Others = lists:delete(Pid,Pids),
+ io:format("wait_pid got ~p, still waiting for ~p\n",[Pid,Others]),
+ wait_pids(Others);
+ Err ->
+ io:format("Err: ~p~n",[Err]),
+ ?line exit(Err)
+ end.
+
+sequential(N,Msg) ->
+ %%io:format("sequential encode/decode with N = ~p~n",[N]),
+ worker_loop(N,Msg).
+
+-record('InitiatingMessage',{procedureCode,criticality,value}).
+-record('Iu-ReleaseCommand',{first,second}).
+
+ticket7904(suite) -> [];
+ticket7904(Config) ->
+ ?line DataDir = ?config(data_dir,Config),
+ ?line OutDir = ?config(priv_dir,Config),
+
+ ?line ok = asn1ct:compile(DataDir ++
+ "RANAPextract1",[per_bin,optimize,{outdir,OutDir}]),
+
+ Val1 = #'InitiatingMessage'{procedureCode=1,
+ criticality=ignore,
+ value=#'Iu-ReleaseCommand'{
+ first=13,
+ second=true}},
+
+ ?line {ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1),
+ asn1rt:unload_driver(),
+ ?line {ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1).
diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk
index 0399ff2732..e900a52286 100644
--- a/lib/asn1/vsn.mk
+++ b/lib/asn1/vsn.mk
@@ -1,2 +1,2 @@
#next version number to use is 1.6.15 | 1.7 | 2.0
-ASN1_VSN = 1.6.14.1
+ASN1_VSN = 1.6.15
diff --git a/lib/common_test/doc/src/Makefile b/lib/common_test/doc/src/Makefile
index 6322860088..a914dd0c19 100644
--- a/lib/common_test/doc/src/Makefile
+++ b/lib/common_test/doc/src/Makefile
@@ -51,8 +51,8 @@ CT_MODULES = \
CT_XML_FILES = $(CT_MODULES:=.xml)
XML_APPLICATION_FILES = ref_man.xml
-XML_REF1_FILES = run_test.xml
-XML_REF3_FILES = $(CT_XML_FILES)
+XML_REF1_FILES = ct_run.xml
+XML_REF3_FILES = $(CT_XML_FILES) ct_hooks.xml
XML_REF6_FILES = common_test_app.xml
XML_PART_FILES = part.xml
@@ -71,6 +71,7 @@ XML_CHAPTER_FILES = \
cover_chapter.xml \
ct_master_chapter.xml \
event_handler_chapter.xml \
+ ct_hooks_chapter.xml \
dependencies_chapter.xml \
notes.xml \
notes_history.xml
diff --git a/lib/common_test/doc/src/common_test_app.xml b/lib/common_test/doc/src/common_test_app.xml
index e30eef2488..b4e4b45d62 100644
--- a/lib/common_test/doc/src/common_test_app.xml
+++ b/lib/common_test/doc/src/common_test_app.xml
@@ -131,7 +131,8 @@
<type>
<v> Info = {timetrap,Time} | {require,Required} |
{require,Name,Required} | {userdata,UserData} |
- {silent_connections,Conns} | {stylesheet,CSSFile}</v>
+ {silent_connections,Conns} | {stylesheet,CSSFile} |
+ {ct_hooks, CTHs}</v>
<v> Time = MilliSec | {seconds,integer()} | {minutes,integer()}
| {hours,integer()}</v>
<v> MilliSec = integer()</v>
@@ -143,6 +144,9 @@
<v> UserData = term()</v>
<v> Conns = [atom()]</v>
<v> CSSFile = string()</v>
+ <v> CTHs = [CTHModule | {CTHModule, CTHInitArgs}]</v>
+ <v> CTHModule = atom()</v>
+ <v> CTHInitArgs = term()</v>
</type>
<desc>
@@ -170,6 +174,10 @@
<p>With <c>userdata</c>, it is possible for the user to
specify arbitrary test suite related information which can be
read by calling <c>ct:userdata/2</c>.</p>
+
+ <p>The <c>ct_hooks</c> tag specifies which
+ <seealso marker="ct_hooks_chapter">Common Test Hooks</seealso>
+ are to be run together with this suite.</p>
<p>Other tuples than the ones defined will simply be ignored.</p>
diff --git a/lib/common_test/doc/src/config_file_chapter.xml b/lib/common_test/doc/src/config_file_chapter.xml
index 77b0c0c0b7..59151a73ec 100644
--- a/lib/common_test/doc/src/config_file_chapter.xml
+++ b/lib/common_test/doc/src/config_file_chapter.xml
@@ -248,7 +248,7 @@
<p><c>Callback:check_parameter/1</c></p>
<p>The input argument will be passed from Common Test, as defined in the test
- specification or given as an option to <c>run_test</c>.</p>
+ specification or given as an option to <c>ct_run</c> or <c>ct:run_test</c>.</p>
<p>The return value should be any of the following values indicating if given
configuration parameter is valid:</p>
diff --git a/lib/common_test/doc/src/cover_chapter.xml b/lib/common_test/doc/src/cover_chapter.xml
index 6e4f59ef73..377409ed7b 100644
--- a/lib/common_test/doc/src/cover_chapter.xml
+++ b/lib/common_test/doc/src/cover_chapter.xml
@@ -94,10 +94,10 @@
<p>To activate the code coverage support, you simply specify the
name of the cover specification file as you start Common Test.
- This you do either by using the <c>-cover</c> flag with <c>run_test</c>.
+ This you do either by using the <c>-cover</c> flag with <c>ct_run</c>.
Example:</p>
- <p><c>$ run_test -dir $TESTOBJS/db -cover $TESTOBJS/db/config/db.coverspec</c></p>
+ <p><c>$ ct_run -dir $TESTOBJS/db -cover $TESTOBJS/db/config/db.coverspec</c></p>
<p>You may also pass the cover specification file name in a
call to <c>ct:run_test/1</c>, by adding a <c>{cover,CoverSpec}</c>
diff --git a/lib/common_test/doc/src/ct_hooks.xml b/lib/common_test/doc/src/ct_hooks.xml
new file mode 100644
index 0000000000..0d59ce3b22
--- /dev/null
+++ b/lib/common_test/doc/src/ct_hooks.xml
@@ -0,0 +1,556 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2010</year><year>2010</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Common Test Hooks</title>
+ <prepared>Lukas Larsson</prepared>
+ <responsible>Lukas Larsson</responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>2010-12-02</date>
+ <rev>PA1</rev>
+ <file>ct_hooks.sgml</file>
+ </header>
+ <module>ct_hooks</module>
+ <modulesummary>A callback interface on top of Common Test</modulesummary>
+
+ <description>
+
+ <warning><p>This feature is in alpha release right now. This means that the
+ interface may change in the future and that there may be bugs. We
+ encourage you to use this feature, but be prepared
+ that there might be bugs and that the interface might change
+ inbetween releases.</p></warning>
+
+ <p>The <em>Common Test Hook</em> (henceforth called CTH) framework allows
+ extensions of the default behaviour of Common Test by means of callbacks
+ before and after all test suite calls. It is meant for advanced users of
+ Common Test which want to abstract out behaviour which is common to
+ multiple test suites. </p>
+
+ <p>In brief, Common Test Hooks allows you to:</p>
+
+ <list>
+ <item>Manipulate the runtime config before each suite
+ configuration call</item>
+ <item>Manipulate the return of all suite configuration calls and in
+ extension the result of the test themselves.</item>
+ </list>
+
+ <p>The following sections describe the mandatory and optional CTH
+ functions Common Test will call during test execution. For more details
+ see <seealso marker="ct_hooks_chapter">Common Test Hooks</seealso> in
+ the User's Guide.</p>
+
+ <p>For information about how to add a CTH to your suite see
+ <seealso marker="ct_hooks_chapter#installing">Installing a CTH
+ </seealso> in the User's Guide.</p>
+
+ <note><p>See the
+ <seealso marker="ct_hooks_chapter#example">Example CTH</seealso>
+ in the User's Guide for a minimal example of a CTH. </p></note>
+
+ </description>
+
+ <section>
+ <title>CALLBACK FUNCTIONS</title>
+ <p>The following functions define the callback interface
+ for a Common Test Hook.</p>
+ </section>
+
+ <funcs>
+ <func>
+ <name>Module:init(Id, Opts) -&gt; State</name>
+ <fsummary>Initiates the Common Test Hook</fsummary>
+ <type>
+ <v>Id = reference() | term()</v>
+ <v>Opts = term()</v>
+ <v>State = term()</v>
+ </type>
+
+ <desc>
+ <p> MANDATORY </p>
+
+ <p>Always called before any other callback function.
+ Use this to initiate any common state.
+ It should return a state for this CTH.</p>
+
+ <p><c>Id</c> is the return value of
+ <seealso marker="#Module:id-1">id/1</seealso>, or a <c>reference</c>
+ (created using
+ <seealso marker="erts:erlang#make_ref-0">make_ref/0</seealso>)
+ if <seealso marker="#Module:id-1">id/1</seealso> is not implemented.
+ </p>
+
+ <p>For details about when init is called see
+ <seealso marker="ct_hooks_chapter#scope">scope</seealso>
+ in the User's Guide.</p>
+
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:pre_init_per_suite(SuiteName, Config, CTHState) -&gt;
+ Result</name>
+ <fsummary>Called before init_per_suite</fsummary>
+ <type>
+ <v>SuiteName = atom()</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {Return, NewCTHState}</v>
+ <v>Return = NewConfig | SkipOrFail</v>
+ <v>SkipOrFail = {fail, Reason} | {skip, Reason}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:init_per_suite-1">
+ init_per_suite</seealso> if it exists.
+ It typically contains initialization/logging which needs to be done
+ before init_per_suite is called.
+ If <c>{skip,Reason}</c> or <c>{fail,Reason}</c> is returned,
+ init_per_suite and all test cases of the suite will be skipped and
+ Reason printed in the overview log of the suite.</p>
+
+ <p><c>SuiteName</c> is the name of the suite to be run.</p>
+
+ <p><c>Config</c> is the original config list of the test suite.</p>
+
+ <p><c>CTHState</c> is the current internal state of the CTH.</p>
+
+ <p><c>Return</c> is the result of the init_per_suite function.
+ If it is <c>{skip,Reason}</c> or <c>{fail,Reason}</c>
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_suite
+ </seealso> will never be called, instead the initiation is considered
+ to be skipped/failed respectively. If a <c>NewConfig</c> list
+ is returned, <seealso marker="common_test#Module:init_per_suite-1">
+ init_per_suite</seealso> will be called with that <c>NewConfig</c> list.
+ See <seealso marker="ct_hooks_chapter#pre">
+ Pre Hooks</seealso> in the User's Guide for more details.</p>
+
+
+ <p>Note that this function is only called if the CTH has been added
+ before init_per_suite is run, see
+ <seealso marker="ct_hooks_chapter#scope">CTH Scoping</seealso>
+ in the User's Guide for details.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:post_init_per_suite(SuiteName, Config, Return, CTHState) -&gt;
+ Result</name>
+ <fsummary>Called after init_per_suite</fsummary>
+ <type>
+ <v>SuiteName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail, Reason} | {skip, Reason} | term()</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:init_per_suite-1">
+ init_per_suite</seealso> if it exists. It typically contains extra
+ checks to make sure that all the correct dependencies have
+ been started correctly.</p>
+
+ <p><c>Return</c> is what
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_suite
+ </seealso> returned, i.e. {fail,Reason}, {skip,Reason}, a <c>Config</c>
+ list or a term describing how
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_suite
+ </seealso> failed.</p>
+
+ <p><c>NewReturn</c> is the possibly modified return value of
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_suite
+ </seealso>. It is here possible to recover from a failure in
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_suite
+ </seealso> by returning the <c>ConfigList</c> with the <c>tc_status</c>
+ element removed. See <seealso marker="ct_hooks_chapter#post">
+ Post Hooks</seealso> in the User's Guide for more details.</p>
+
+ <p><c>CTHState</c> is the current internal state of the CTH.</p>
+
+ <p>Note that this function is only called if the CTH has been added
+ before or in init_per_suite, see
+ <seealso marker="ct_hooks_chapter#scope">CTH Scoping</seealso>
+ in the User's Guide for details.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:pre_init_per_group(GroupName, Config, CTHState) -&gt;
+ Result</name>
+ <fsummary>Called before init_per_group</fsummary>
+ <type>
+ <v>GroupName = atom()</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:init_per_group-2">
+ init_per_group</seealso> if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:pre_init_per_suite-3">
+ pre_init_per_suite</seealso>, but for the
+ <seealso marker="common_test#Module:init_per_group-2">
+ init_per_group</seealso> instead.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:post_init_per_group(GroupName, Config, Return, CTHState) -&gt;
+ Result</name>
+ <fsummary>Called after init_per_group</fsummary>
+ <type>
+ <v>GroupName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:init_per_group-2">
+ init_per_group</seealso> if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:post_init_per_suite-4">
+ post_init_per_suite</seealso>, but for the
+ <seealso marker="common_test#Module:init_per_group-2">
+ init_per_group</seealso> instead.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:pre_init_per_testcase(TestcaseName, Config, CTHState) -&gt;
+ Result</name>
+ <fsummary>Called before init_per_testcase</fsummary>
+ <type>
+ <v>TestcaseName = atom()</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:init_per_testcase-2">
+ init_per_testcase</seealso> if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:pre_init_per_suite-3">
+ pre_init_per_suite</seealso>, but for the
+ <seealso marker="common_test#Module:init_per_testcase-2">
+ init_per_testcase</seealso> function instead.</p>
+
+ <p>Note that it is not possible to add CTH's here right now,
+ that feature might be added later,
+ but it would right now break backwards compatability.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:post_end_per_testcase(TestcaseName, Config, Return, CTHState)
+ -&gt; Result</name>
+ <fsummary>Called after end_per_testcase</fsummary>
+ <type>
+ <v>TestcaseName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:end_per_testcase-2">
+ end_per_testcase</seealso> if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:post_init_per_suite-4">
+ post_init_per_suite</seealso>, but for the
+ <seealso marker="common_test#Module:end_per_testcase-2">
+ end_per_testcase</seealso> function instead.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:pre_end_per_group(GroupName, Config, CTHState) -&gt;
+ Result</name>
+ <fsummary>Called before end_per_group</fsummary>
+ <type>
+ <v>GroupName = atom()</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:end_per_group-2">
+ end_per_group</seealso> if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:pre_init_per_suite-3">
+ pre_init_per_suite</seealso>, but for the
+ <seealso marker="common_test#Module:end_per_group-2">
+ end_per_group</seealso> function instead.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:post_end_per_group(GroupName, Config, Return, CTHState) -&gt;
+ Result</name>
+ <fsummary>Called after end_per_group</fsummary>
+ <type>
+ <v>GroupName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:end_per_group-2">
+ end_per_group</seealso> if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:post_init_per_suite-4">
+ post_init_per_suite</seealso>, but for the
+ <seealso marker="common_test#Module:end_per_group-2">
+ end_per_group</seealso> function instead.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:pre_end_per_suite(SuiteName, Config, CTHState) -&gt;
+ Result</name>
+ <fsummary>Called before end_per_suite</fsummary>
+ <type>
+ <v>SuiteName = atom()</v>
+ <v>Config = NewConfig = [{Key,Value}]</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewConfig | SkipOrFail, NewCTHState}</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called before
+ <seealso marker="common_test#Module:end_per_suite-1">
+ end_per_suite</seealso> if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:pre_init_per_suite-3">
+ pre_init_per_suite</seealso>, but for the
+ <seealso marker="common_test#Module:end_per_suite-2">
+ end_per_suite</seealso> function instead.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:post_end_per_suite(SuiteName, Config, Return, CTHState) -&gt;
+ Result</name>
+ <fsummary>Called after end_per_suite</fsummary>
+ <type>
+ <v>SuiteName = atom()</v>
+ <v>Config = [{Key,Value}]</v>
+ <v>Return = NewReturn = Config | SkipOrFail | term()</v>
+ <v>SkipOrFail = {fail,Reason} | {skip, Reason}</v>
+ <v>CTHState = NewCTHState = term()</v>
+ <v>Result = {NewReturn, NewCTHState}</v>
+ <v>Key = atom()</v>
+ <v>Value = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called after
+ <seealso marker="common_test#Module:end_per_suite-1">
+ end_per_suite</seealso> if it exists. It behaves the same way as
+ <seealso marker="ct_hooks#Module:post_init_per_suite-4">
+ post_init_per_suite</seealso>, but for the
+ <seealso marker="common_test#Module:end_per_suite-2">
+ end_per_suite</seealso> function instead.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:on_tc_fail(TestcaseName, Reason, CTHState) -&gt;
+ NewCTHState</name>
+ <fsummary>Called after the CTH scope ends</fsummary>
+ <type>
+ <v>TestcaseName = init_per_suite | end_per_suite |
+ init_per_group | end_per_group | atom()</v>
+ <v>Reason = term()</v>
+ <v>CTHState = NewCTHState = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called whenever a testcase fails.
+ It is called after the post function has been called for
+ the testcase which failed. i.e.
+ if init_per_suite fails this function is called after
+ <seealso marker="#Module:post_init_per_suite-4">
+ post_init_per_suite</seealso>, and if a testcase fails it is called
+ after <seealso marker="#Module:post_end_per_testcase-4">
+ post_end_per_testcase</seealso>.</p>
+
+ <p>The data which comes with the Reason follows the same format as the
+ <seealso marker="event_handler_chapter#failreason">FailReason
+ </seealso> in the <seealso marker="event_handler_chapter#tc_done">tc_done</seealso> event.
+ See <seealso marker="event_handler_chapter#events">Event Handling
+ </seealso> in the User's Guide for details.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:on_tc_skip(TestcaseName, Reason, CTHState) -&gt;
+ NewCTHState</name>
+ <fsummary>Called after the CTH scope ends</fsummary>
+ <type>
+ <v>TestcaseName = end_per_suite | init_per_group |
+ end_per_group | atom()</v>
+ <v>Reason = {tc_auto_skip | tc_user_skip, term()}</v>
+ <v>CTHState = NewCTHState = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called whenever a testcase is skipped.
+ It is called after the post function has been called for the
+ testcase which was skipped.
+ i.e. if init_per_group is skipped this function is called after
+ <seealso marker="#Module:post_init_per_suite-4">post_init_per_group
+ </seealso>, and if a testcase is skipped it is called after
+ <seealso marker="#Module:post_end_per_testcase-4">post_end_per_testcase
+ </seealso>.</p>
+
+ <p>The data which comes with the Reason follows the same format as
+ <seealso marker="event_handler_chapter#tc_auto_skip">tc_auto_skip
+ </seealso> and <seealso marker="event_handler_chapter#tc_user_skip">
+ tc_user_skip</seealso> events.
+ See <seealso marker="event_handler_chapter#events">Event Handling
+ </seealso> in the User's Guide for details.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:terminate(CTHState)</name>
+ <fsummary>Called after the CTH scope ends</fsummary>
+ <type>
+ <v>CTHState = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>This function is called at the end of a CTH's
+ <seealso marker="ct_hooks_chapter#scope">scope</seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>Module:id(Opts) -&gt; Id</name>
+ <fsummary>Called before the init function of a CTH</fsummary>
+ <type>
+ <v>Opts = term()</v>
+ <v>Id = term()</v>
+ </type>
+
+ <desc>
+ <p> OPTIONAL </p>
+
+ <p>The <c>Id</c> is used to uniquely identify a CTH instance,
+ if two CTH's return the same <c>Id</c> the second CTH is ignored
+ and subsequent calls to the CTH will only be made to the first
+ instance. For more information see
+ <seealso marker="ct_hooks_chapter#installing">Installing a CTH
+ </seealso> in the User's Guide.
+ </p>
+
+ <p>This function should NOT have any side effects as it might
+ be called multiple times by Common Test.</p>
+
+ <p>If not implemented the CTH will act as if this function returned a
+ call to <c>make_ref/0</c>.</p>
+ </desc>
+ </func>
+
+ </funcs>
+
+</erlref>
+
+
diff --git a/lib/common_test/doc/src/ct_hooks_chapter.xml b/lib/common_test/doc/src/ct_hooks_chapter.xml
new file mode 100644
index 0000000000..fc5ab48e1b
--- /dev/null
+++ b/lib/common_test/doc/src/ct_hooks_chapter.xml
@@ -0,0 +1,401 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2011</year><year>2011</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Common Test Hooks</title>
+ <prepared>Lukas Larsson</prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>ct_hooks_chapter.xml</file>
+ </header>
+
+ <marker id="general"></marker>
+ <section>
+ <title>General</title>
+ <warning><p>This feature is in alpha release right now. This means that the
+ interface may change in the future and that there may be bugs. We
+ encourage you to use this feature, but be prepared
+ that there might be bugs and that the interface might change
+ inbetween releases.</p></warning>
+ <p>
+ The <em>Common Test Hook</em> (henceforth called CTH) framework allows
+ extensions of the default behaviour of Common Test by means of hooks
+ before and after all test suite calls. CTHs allow advanced Common Test
+ users to abstract out behaviour which is common to multiple test suites
+ without littering all test suites with library calls. Some example
+ usages are: logging, starting and monitoring external systems,
+ building C files needed by the tests and much more!</p>
+
+ <p>In brief, Common Test Hooks allows you to:</p>
+
+ <list>
+ <item>Manipulate the runtime config before each suite
+ configuration call</item>
+ <item>Manipulate the return of all suite configuration calls and in
+ extension the result of the test themselves.</item>
+ </list>
+
+ <p>The following sections describe how to use CTHs, when they are run
+ and how to manipulate your test results in a CTH</p>
+
+ <warning><p>When executing within a CTH all timetraps are shutoff. So
+ if your CTH never returns, the entire test run will be stalled!</p>
+ </warning>
+
+ </section>
+
+ <marker id="installing"></marker>
+ <section>
+ <title>Installing a CTH</title>
+ <p>There are multiple ways to install a CTH in your test run. You can do it
+ for all tests in a run, for specific test suites and for specific groups
+ within a test suite. If you want a CTH to be present in all test suites
+ within your test run there are three different ways to accomplish that.
+ </p>
+
+ <list>
+ <item>Add <c>-ct_hooks</c> as an argument to
+ <seealso marker="run_test_chapter#ct_run">ct_run</seealso>.
+ To add multiple CTHs using this method append them to each other
+ using the keyword <c>and</c>, i.e.
+ <c>ct_run -ct_hooks cth1 [{debug,true}] and cth2 ...</c>.</item>
+ <item>Add the <c>ct_hooks</c> tag to your
+ <seealso marker="run_test_chapter#test_specifications">
+ Test Specification</seealso></item>
+ <item>Add the <c>ct_hooks</c> tag to your call to
+ <seealso marker="ct#run_test-1">ct:run_test/1</seealso></item>
+ </list>
+
+ <p>You can also add CTHs within a test suite. This is done by returning
+ <c>{ct_hooks,[CTH]}</c> in the config list from
+ <seealso marker="common_test#Module:suite-0">suite/0</seealso>,
+ <seealso marker="common_test#Module:init_per_suite-1">
+ init_per_suite/1</seealso> or
+ <seealso marker="common_test#Module:init_per_group-2">
+ init_per_group/2</seealso>. <c>CTH</c> in this case can be either
+ only the module name of the CTH or a tuple with the module name and the
+ initial arguments to the CTH. Eg:
+ <c>{ct_hooks,[my_cth_module]}</c> or
+ <c>{ct_hooks,[{my_cth_module,[{debug,true}]}]}</c></p>
+
+ <section>
+ <title>Overriding CTHs</title>
+ <p>By default each installation of a CTH will cause a new instance of it
+ to be activated. This can cause problems if you want to be able to
+ override CTHs in test specifications while still having them in the
+ suite info function. The
+ <seealso marker="ct_hooks#Module:id-1">id/1</seealso>
+ callback exists to address this problem. By returning the same
+ <c>id</c> in both places, Common Test knows that this CTH
+ has already been installed and will not try to install it again.</p>
+ </section>
+
+ </section>
+
+ <marker id="scope"/>
+ <section>
+ <title>CTH Scope</title>
+ <p>Once the CTH is installed into a certain test run it will be there until
+ its scope is expired. The scope of a CTH depends on when it is
+ installed.
+ The <seealso marker="ct_hooks#Module:init-2">init/2</seealso> is
+ called at the beginning of the scope and the
+ <seealso marker="ct_hooks#Module:terminate-1">terminate/1
+ </seealso> function is called when the scope ends.</p>
+ <table>
+ <row>
+ <cell><em>CTH Installed in</em></cell>
+ <cell><em>CTH scope begins before</em></cell>
+ <cell><em>CTH scope ends after</em></cell>
+ </row>
+ <row>
+ <cell><seealso marker="run_test_chapter#ct_run">ct_run</seealso></cell>
+ <cell>the first test suite is to be run.</cell>
+ <cell>the last test suite has been run.</cell>
+ </row>
+ <row>
+ <cell><seealso marker="ct#run_test-1">ct:run_test</seealso></cell>
+ <cell>the first test suite is to be run.</cell>
+ <cell>the last test suite has been run.</cell>
+ </row>
+ <row>
+ <cell><seealso marker="run_test_chapter#test_specifications">
+ Test Specification</seealso></cell>
+ <cell>the first test suite is to be run.</cell>
+ <cell>the last test suite has been run.</cell>
+ </row>
+ <row>
+ <cell><seealso marker="common_test#Module:suite-0">suite/0
+ </seealso></cell>
+ <cell><seealso marker="ct_hooks#Module:pre_init_per_suite-3">
+ pre_init_per_suite/3</seealso> is called.</cell>
+ <cell><seealso marker="ct_hooks#Module:post_end_per_suite-4">
+ post_end_per_suite/4</seealso> has been called for that test suite.</cell>
+ </row>
+ <row>
+ <cell><seealso marker="common_test#Module:init_per_suite-1">
+ init_per_suite/1</seealso></cell>
+ <cell><seealso marker="ct_hooks#Module:post_init_per_suite-4">
+ post_init_per_suite/4</seealso> is called.</cell>
+ <cell><seealso marker="ct_hooks#Module:post_end_per_suite-4">
+ post_end_per_suite/4</seealso> has been called for that test suite.</cell>
+ </row>
+ <row>
+ <cell><seealso marker="common_test#Module:init_per_group-2">
+ init_per_group/2</seealso></cell>
+ <cell><seealso marker="ct_hooks#Module:post_init_per_group-4">
+ post_init_per_group/4</seealso> is called.</cell>
+ <cell><seealso marker="ct_hooks#Module:post_end_per_suite-4">
+ post_end_per_group/4</seealso> has been called for that group.</cell>
+ </row>
+ <tcaption>Scope of a CTH</tcaption>
+ </table>
+
+ <section>
+ <title>CTH Processes and Tables</title>
+ <p>CTHs are run with the same process scoping as normal test suites
+ i.e. a different process will execute the init_per_suite hooks then the
+ init_per_group or per_testcase hooks. So if you want to spawn a
+ process in the CTH you cannot link with the CTH process as it will exit
+ after the post hook ends. Also if you for some reason need an ETS
+ table with your CTH, you will have to spawn a process which handles
+ it.</p>
+ </section>
+
+ </section>
+
+ <marker id="manipulating"/>
+ <section>
+ <title>Manipulating tests</title>
+ <p>It is through CTHs possible to manipulate the results of tests and
+ configuration functions. The main purpose of doing this with CTHs is to
+ allow common patterns to be abstracted out from test test suites and applied to
+ multiple test suites without duplicating any code. All of the callback
+ functions for a CTH follow a common interface, this interface is
+ described below.</p>
+
+ <p>It is only possible to hook into test function which exists in the test
+ suite. So in order for a CTH to hook in before
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_suite</seealso>,
+ the <seealso marker="common_test#Module:init_per_suite-1">init_per_suite</seealso>
+ function must exist in the test suite.</p>
+
+ <marker id="pre"/>
+ <section>
+ <title>Pre Hooks</title>
+ <p>
+ It is possible in a CTH to hook in behaviour before
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_suite</seealso>,
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_group</seealso>,
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_testcase</seealso>,
+ <seealso marker="common_test#Module:init_per_suite-1">end_per_group</seealso> and
+ <seealso marker="common_test#Module:init_per_suite-1">end_per_suite</seealso>.
+ This is done in the CTH functions called pre_&lt;name of function&gt;.
+ All of these functions take the same three arguments: <c>Name</c>,
+ <c>Config</c> and <c>CTHState</c>. The return value of the CTH function
+ is always a combination of an result for the suite/group/test and an
+ updated <c>CTHState</c>. If you want the test suite to continue on
+ executing you should return the config list which you want the test to
+ use as the result. If you for some reason want to skip/fail the test,
+ return a tuple with <c>skip</c> or <c>fail</c> and a reason as the
+ result. Example:
+ </p>
+ <code>pre_init_per_suite(SuiteName, Config, CTHState) -&gt;
+ case db:connect() of
+ {error,_Reason} -&gt;
+ {{fail, "Could not connect to DB"}, CTHState};
+ {ok, Handle} -&gt;
+ {[{db_handle, Handle} | Config], CTHState#state{ handle = Handle }}
+ end.</code>
+
+ </section>
+
+ <marker id="post"/>
+ <section>
+ <title>Post Hooks</title>
+ <p>It is also possible in a CTH to hook in behaviour after
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_suite</seealso>,
+ <seealso marker="common_test#Module:init_per_suite-1">init_per_group</seealso>,
+ <seealso marker="common_test#Module:init_per_suite-1">end_per_testcase</seealso>,
+ <seealso marker="common_test#Module:init_per_suite-1">end_per_group</seealso> and
+ <seealso marker="common_test#Module:init_per_suite-1">end_per_suite</seealso>.
+ This is done in the CTH functions called post_&lt;name of function&gt;.
+ All of these function take the same four arguments: <c>Name</c>,
+ <c>Config</c>, <c>Return</c> and <c>CTHState</c>. <c>Config</c> in this
+ case is the same <c>Config</c> as the testcase is called with.
+ <c>Return</c> is the value returned by the testcase. If the testcase
+ failed by crashing, <c>Return</c> will be
+ <c>{'EXIT',{{Error,Reason},Stacktrace}}</c>.</p>
+
+ <p>The return value of the CTH function is always a combination of an
+ result for the suite/group/test and an updated <c>CTHState</c>. If
+ you want the callback to not affect the outcome of the test you should
+ return the <c>Return</c> data as it is given to the CTH. You can also
+ modify the result of the test. By returning the <c>Config</c> list
+ with the <c>tc_status</c> element removed you can recover from a test
+ failure. As in all the pre hooks, it is also possible to fail/skip
+ the test case in the post hook. Example: </p>
+
+ <code>post_end_per_testcase(_TC, Config, {'EXIT',{_,_}}, CTHState) -&gt;
+ case db:check_consistency() of
+ true ->
+ %% DB is good, pass the test.
+ {proplists:delete(tc_status, Config), CTHState};
+ false ->
+ %% DB is not good, mark as skipped instead of failing
+ {{skip, "DB is inconsisten!"}, CTHState}
+ end;
+post_end_per_testcase(_TC, Config, Return, CTHState) -&gt;
+ %% Do nothing if tc does not crash.
+ {Return, CTHState}.</code>
+
+ <note>Recovering from a testcase failure using CTHs should only be done as
+ a last resort. If used wrongly it could become very difficult to
+ determine which tests pass or fail in a test run</note>
+
+ </section>
+
+ <marker id="skip_n_fail"/>
+ <section>
+ <title>Skip and Fail hooks</title>
+ <p>
+ After any post hook has been executed for all installed CTHs,
+ <seealso marker="ct_hooks#Module:on_tc_fail-3">on_tc_fail</seealso>
+ or <seealso marker="ct_hooks#Module:on_tc_fail-3">on_tc_skip</seealso>
+ might be called if the testcase failed or was skipped
+ respectively. You cannot affect the outcome of the tests any further at
+ this point.
+ </p>
+ </section>
+
+ </section>
+
+ <marker id="example"/>
+ <section>
+ <title>Example CTH</title>
+ <p>The CTH below will log information about a test run into a format
+ parseable by <seealso marker="kernel:file#consult-1">file:consult/1</seealso>.
+ </p>
+ <code>%%% @doc Common Test Example Common Test Hook module.
+-module(example_cth).
+
+%% Callbacks
+-export([id/1]).
+-export([init/2]).
+
+-export([pre_init_per_suite/3]).
+-export([post_init_per_suite/4]).
+-export([pre_end_per_suite/3]).
+-export([post_end_per_suite/4]).
+
+-export([pre_init_per_group/3]).
+-export([post_init_per_group/4]).
+-export([pre_end_per_group/3]).
+-export([post_end_per_group/4]).
+
+-export([pre_init_per_testcase/3]).
+-export([post_end_per_testcase/4]).
+
+-export([on_tc_fail/3]).
+-export([on_tc_skip/3]).
+
+-export([terminate/1]).
+
+-record(state, { file_handle, total, suite_total, ts, tcs, data }).
+
+%% @doc Return a unique id for this CTH.
+id(Opts) ->
+ proplists:get_value(filename, Opts, "/tmp/file.log").
+
+%% @doc Always called before any other callback function. Use this to initiate
+%% any common state.
+init(Id, Opts) ->
+ {ok,D} = file:open(Id,[write]),
+ #state{ file_handle = D, total = 0, data = [] }.
+
+%% @doc Called before init_per_suite is called.
+pre_init_per_suite(Suite,Config,State) ->
+ {Config, State#state{ suite_total = 0, tcs = [] }}.
+
+%% @doc Called after init_per_suite.
+post_init_per_suite(Suite,Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called before end_per_suite.
+pre_end_per_suite(Suite,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after end_per_suite.
+post_end_per_suite(Suite,Config,Return,State) ->
+ Data = {suites, Suite, State#state.suite_total, lists:reverse(State#state.tcs)},
+ {Return, State#state{ data = [Data | State#state.data] ,
+ total = State#state.total + State#state.suite_total } }.
+
+%% @doc Called before each init_per_group.
+pre_init_per_group(Group,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after each init_per_group.
+post_init_per_group(Group,Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called after each end_per_group.
+pre_end_per_group(Group,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after each end_per_group.
+post_end_per_group(Group,Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called before each test case.
+pre_init_per_testcase(TC,Config,State) ->
+ {Config, State#state{ ts = now(), total = State#state.suite_total + 1 } }.
+
+%% @doc Called after each test case.
+post_end_per_testcase(TC,Config,Return,State) ->
+ TCInfo = {testcase, TC, Return, timer:now_diff(now(), State#state.ts)},
+ {Return, State#state{ ts = undefined, tcs = [TCInfo | State#state.tcs] } }.
+
+%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group,
+%% post_end_per_group and post_end_per_testcase if the suite, group or test case failed.
+on_tc_fail(TC, Reason, State) ->
+ State.
+
+%% @doc Called when a test case is skipped by either user action
+%% or due to an init function failing.
+on_tc_skip(TC, Reason, State) ->
+ State.
+
+%% @doc Called when the scope of the CTH is done
+terminate(State) ->
+ io:format(State#state.file_handle, "~p.~n",
+ [{test_run, State#state.total, State#state.data}]),
+ file:close(State#state.file_handle),
+ ok.</code>
+ </section>
+
+</chapter>
+
+
+
+
diff --git a/lib/common_test/doc/src/ct_master_chapter.xml b/lib/common_test/doc/src/ct_master_chapter.xml
index 01f8e61d36..f4f0ecad62 100644
--- a/lib/common_test/doc/src/ct_master_chapter.xml
+++ b/lib/common_test/doc/src/ct_master_chapter.xml
@@ -188,7 +188,7 @@
<seealso marker="run_test_chapter#test_specifications">Running Test Suites</seealso>
chapter). The result is that any test specified to run on a node with the same
name as the Common Test node in question (typically <c>ct@somehost</c> if started
- with the <c>run_test</c> program), will be performed. Tests without explicit
+ with the <c>ct_run</c> program), will be performed. Tests without explicit
node association will always be performed too of course!</p>
<note><p>It is recommended that absolute paths are used for log directories,
diff --git a/lib/common_test/doc/src/run_test.xml b/lib/common_test/doc/src/ct_run.xml
index 2f0a94afba..1ab563d74f 100644
--- a/lib/common_test/doc/src/run_test.xml
+++ b/lib/common_test/doc/src/ct_run.xml
@@ -21,7 +21,7 @@
</legalnotice>
- <title>The run_test program</title>
+ <title>The ct_run program</title>
<prepared>Peter Andersson</prepared>
<responsible>Peter Andersson</responsible>
<docno></docno>
@@ -29,18 +29,18 @@
<checked></checked>
<date>2010-04-01</date>
<rev>PA2</rev>
- <file>run_test.xml</file>
+ <file>ct_run.xml</file>
</header>
- <com>run_test</com>
+ <com>ct_run</com>
<comsummary>Program used for starting Common Test from the
OS command line.
</comsummary>
<description>
- <p>The <c>run_test</c> program is automatically installed with Erlang/OTP
+ <p>The <c>ct_run</c> program is automatically installed with Erlang/OTP
and Common Test (please see the Installation chapter in the Common
Test User's Guide for more information). The program accepts a number
- of different start flags. Some flags trigger <c>run_test</c>
+ of different start flags. Some flags trigger <c>ct_run</c>
to start the Common Test application and pass on data to it. Some
flags start an Erlang node prepared for running Common Test in a
particular mode.</p>
@@ -50,20 +50,20 @@
shell (or an Erlang program). Please see the <c>ct</c> man page for
details.</p>
- <p><c>run_test</c> also accepts Erlang emulator flags. These are used
- when <c>run_test</c> calls <c>erl</c> to start the Erlang node
+ <p><c>ct_run</c> also accepts Erlang emulator flags. These are used
+ when <c>ct_run</c> calls <c>erl</c> to start the Erlang node
(making it possible to e.g. add directories to the code server path,
change the cookie on the node, start additional applications, etc).</p>
<p>With the optional flag:</p>
<pre>-erl_args</pre>
- <p>it's possible to divide the options on the <c>run_test</c> command line into
+ <p>it's possible to divide the options on the <c>ct_run</c> command line into
two groups, one that Common Test should process (those preceding <c>-erl_args</c>),
and one it should completely ignore and pass on directly to the emulator
(those following <c>-erl_args</c>). Options preceding <c>-erl_args</c> that Common Test
doesn't recognize, also get passed on to the emulator untouched.
By means of <c>-erl_args</c> the user may specify flags with the same name, but
- with different destinations, on the <c>run_test</c> command line.</p>
+ with different destinations, on the <c>ct_run</c> command line.</p>
<p>If <c>-pa</c> or <c>-pz</c> flags are specified in the Common Test group of options
(preceding <c>-erl_args</c>), relative directories will be converted to
absolute and re-inserted into the code path by Common Test (to avoid
@@ -72,17 +72,17 @@
following <c>-erl_args</c> on the command line. These directories are added
to the code path normally (i.e. on specified form)</p>
- <p>If <c>run_test</c> is called with option:</p>
+ <p>If <c>ct_run</c> is called with option:</p>
<pre>-help</pre>
<p>it prints all valid start flags to stdout.</p>
</description>
- <marker id="run_test"></marker>
+ <marker id="ct_run"></marker>
<section>
<title>Run tests from command line</title>
<pre>
- run_test [-dir TestDir1 TestDir2 .. TestDirN] |
+ ct_run [-dir TestDir1 TestDir2 .. TestDirN] |
[-suite Suite1 Suite2 .. SuiteN
[[-group Group1 Group2 .. GroupN] [-case Case1 Case2 .. CaseN]]]
[-step [config | keep_inactive]]
@@ -110,7 +110,7 @@
<section>
<title>Run tests using test specification</title>
<pre>
- run_test -spec TestSpec1 TestSpec2 .. TestSpecN
+ ct_run -spec TestSpec1 TestSpec2 .. TestSpecN
[-config ConfigFile1 ConfigFile2 .. ConfigFileN]
[-userconfig CallbackModule1 ConfigString1 and CallbackModule2
ConfigString2 and .. and CallbackModuleN ConfigStringN]
@@ -136,7 +136,7 @@
<section>
<title>Run tests in web based GUI</title>
<pre>
- run_test -vts [-browser Browser]
+ ct_run -vts [-browser Browser]
[-dir TestDir1 TestDir2 .. TestDirN] |
[-suite Suite [[-group Group] [-case Case]]]
[-config ConfigFile1 ConfigFile2 .. ConfigFileN]
@@ -152,12 +152,12 @@
<section>
<title>Refresh the HTML index files</title>
<pre>
- run_test -refresh_logs [-logdir LogDir] [-basic_html]</pre>
+ ct_run -refresh_logs [-logdir LogDir] [-basic_html]</pre>
</section>
<section>
<title>Run CT in interactive mode</title>
<pre>
- run_test -shell
+ ct_run -shell
[-config ConfigFile1 ConfigFile2 ... ConfigFileN]
[-userconfig CallbackModule1 ConfigString1 and CallbackModule2
ConfigString2 and .. and CallbackModuleN ConfigStringN]
@@ -166,7 +166,7 @@
<section>
<title>Start a Common Test Master node</title>
<pre>
- run_test -ctmaster</pre>
+ ct_run -ctmaster</pre>
</section>
<section>
diff --git a/lib/common_test/doc/src/ct_slave.xml b/lib/common_test/doc/src/ct_slave.xml
deleted file mode 100644
index ceebf51f1a..0000000000
--- a/lib/common_test/doc/src/ct_slave.xml
+++ /dev/null
@@ -1,139 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE erlref SYSTEM "erlref.dtd">
-<erlref>
-<header>
-<title>ct_slave</title>
-<prepared></prepared>
-<responsible></responsible>
-<docno>1</docno>
-<approved></approved>
-<checked></checked>
-<date></date>
-<rev>A</rev>
-<file>ct_slave.xml</file></header>
-<module>ct_slave</module>
-<modulesummary>Common Test Framework functions for starting and stopping nodes for
-Large Scale Testing.</modulesummary>
-<description>
-<p>Common Test Framework functions for starting and stopping nodes for
-Large Scale Testing.</p>
-
- <p>This module exports functions which are used by the Common Test Master
- to start and stop "slave" nodes. It is the default callback module for the
- <c>{init, node_start}</c> term of the Test Specification.</p></description>
-<funcs>
-<func>
-<name>start(Node) -&gt; Result</name>
-<fsummary>Starts an Erlang node with name Node on the local host.</fsummary>
-<type>
-<v>Node = atom()</v><v>Result = {ok, NodeName} | {error, already_started, NodeName} | {error, started_not_connected, NodeName} | {error, boot_timeout, NodeName} | {error, init_timeout, NodeName} | {error, startup_timeout, NodeName} | {error, not_alive, NodeName}</v><v>NodeName = atom()</v></type>
-<desc><marker id="start-1"/>
-
-<p>Starts an Erlang node with name <c>Node</c> on the local host.</p>
-<p><em>See also:</em> <seealso marker="#start-3">start/3</seealso>.</p>
-</desc></func>
-<func>
-<name>start(Host, Node) -&gt; Result</name>
-<fsummary>Starts an Erlang node with name Node on host
- Host with the default options.</fsummary>
-<type>
-<v>Node = atom()</v><v>Host = atom()</v><v>Result = {ok, NodeName} | {error, already_started, NodeName} | {error, started_not_connected, NodeName} | {error, boot_timeout, NodeName} | {error, init_timeout, NodeName} | {error, startup_timeout, NodeName} | {error, not_alive, NodeName}</v><v>NodeName = atom()</v></type>
-<desc><marker id="start-2"/>
-
-<p>Starts an Erlang node with name <c>Node</c> on host
- <c>Host</c> with the default options.</p>
-<p><em>See also:</em> <seealso marker="#start-3">start/3</seealso>.</p>
-</desc></func>
-<func>
-<name>start(Host, Node, Options::Opts) -&gt; Result</name>
-<fsummary>Starts an Erlang node with name Node on host
- Host as specified by the combination of options in
- Opts.</fsummary>
-<type>
-<v>Node = atom()</v><v>Host = atom()</v><v>Opts = [OptTuples]</v><v>OptTuples = {username, Username} | {password, Password} | {boot_timeout, BootTimeout} | {init_timeout, InitTimeout} | {startup_timeout, StartupTimeout} | {startup_functions, StartupFunctions} | {monitor_master, Monitor} | {kill_if_fail, KillIfFail} | {erl_flags, ErlangFlags}</v><v>Username = string()</v><v>Password = string()</v><v>BootTimeout = integer()</v><v>InitTimeout = integer()</v><v>StartupTimeout = integer()</v><v>StartupFunctions = [StartupFunctionSpec]</v><v>StartupFunctionSpec = {Module, Function, Arguments}</v><v>Module = atom()</v><v>Function = atom()</v><v>Arguments = [term]</v><v>Monitor = bool()</v><v>KillIfFail = bool()</v><v>ErlangFlags = string()</v><v>Result = {ok, NodeName} | {error, already_started, NodeName} | {error, started_not_connected, NodeName} | {error, boot_timeout, NodeName} | {error, init_timeout, NodeName} | {error, startup_timeout, NodeName} | {error, not_alive, NodeName}</v><v>NodeName = atom()</v></type>
-<desc><marker id="start-3"/>
-
-<p>Starts an Erlang node with name <c>Node</c> on host
- <c>Host</c> as specified by the combination of options in
- <c>Opts</c>.</p>
-
- <p>Options <c>Username</c> and <c>Password</c> will be used
- to log in onto the remote host <c>Host</c>.
- Username, if omitted, defaults to the current user name,
- and password is empty by default.</p>
-
- <p>A list of functions specified in the <c>Startup</c> option will be
- executed after startup of the node. Note that all used modules should be
- present in the code path on the <c>Host</c>.</p>
-
- <p>The timeouts are applied as follows:
- <list>
- <item>
- <c>BootTimeout</c> - time to start the Erlang node, in seconds.
- Defaults to 3 seconds. If node does not become pingable within this time,
- the result <c>{error, boot_timeout, NodeName}</c> is returned;
- </item>
- <item>
- <c>InitTimeout</c> - time to wait for the node until it calls the
- internal callback function informing master about successfull startup.
- Defaults to one second.
- In case of timed out message the result
- <c>{error, init_timeout, NodeName}</c> is returned;
- </item>
- <item>
- <c>StartupTimeout</c> - time to wait intil the node finishes to run
- the <c>StartupFunctions</c>. Defaults to one second.
- If this timeout occurs, the result
- <c>{error, startup_timeout, NodeName}</c> is returned.
- </item>
- </list></p>
-
- <p>Option <c>monitor_master</c> specifies, if the slave node should be
- stopped in case of master node stop. Defaults to false.</p>
-
- <p>Option <c>kill_if_fail</c> specifies, if the slave node should be
- killed in case of a timeout during initialization or startup.
- Defaults to true. Note that node also may be still alive it the boot
- timeout occurred, but it will not be killed in this case.</p>
-
- <p>Option <c>erlang_flags</c> specifies, which flags will be added
- to the parameters of the <c>erl</c> executable.</p>
-
- <p>Special return values are:
- <list>
- <item><c>{error, already_started, NodeName}</c> - if the node with
- the given name is already started on a given host;</item>
- <item><c>{error, started_not_connected, NodeName}</c> - if node is
- started, but not connected to the master node.</item>
- <item><c>{error, not_alive, NodeName}</c> - if node on which the
- <c>ct_slave:start/3</c> is called, is not alive. Note that
- <c>NodeName</c> is the name of current node in this case.</item>
- </list></p>
-
-</desc></func>
-<func>
-<name>stop(Node) -&gt; Result</name>
-<fsummary>Stops the running Erlang node with name Node on
- the localhost.</fsummary>
-<type>
-<v>Node = atom()</v><v>Result = {ok, NodeName} | {error, not_started, NodeName} | {error, not_connected, NodeName} | {error, stop_timeout, NodeName}</v><v>NodeName = atom()</v></type>
-<desc><marker id="stop-1"/>
-
-<p>Stops the running Erlang node with name <c>Node</c> on
- the localhost.</p>
-</desc></func>
-<func>
-<name>stop(Host, Node) -&gt; Result</name>
-<fsummary>Stops the running Erlang node with name Node on
- host Host.</fsummary>
-<type>
-<v>Host = atom()</v><v>Node = atom()</v><v>Result = {ok, NodeName} | {error, not_started, NodeName} | {error, not_connected, NodeName} | {error, stop_timeout, NodeName}</v><v>NodeName = atom()</v></type>
-<desc><marker id="stop-2"/>
-
-<p>Stops the running Erlang node with name <c>Node</c> on
- host <c>Host</c>.</p>
-</desc></func></funcs>
-
-<authors>
-<aname> </aname>
-<email> </email></authors></erlref> \ No newline at end of file
diff --git a/lib/common_test/doc/src/event_handler_chapter.xml b/lib/common_test/doc/src/event_handler_chapter.xml
index 7f5144b760..a01feb59d1 100644
--- a/lib/common_test/doc/src/event_handler_chapter.xml
+++ b/lib/common_test/doc/src/event_handler_chapter.xml
@@ -61,14 +61,15 @@
itself.</p>
</section>
<section>
+ <marker id="usage"></marker>
<title>Usage</title>
<p>Event handlers may be installed by means of an <c>event_handler</c>
- start flag (<c>run_test</c>) or option (<c>ct:run_test/1</c>), where the
+ start flag (<c>ct_run</c>) or option (<c>ct:run_test/1</c>), where the
argument specifies the names of one or more event handler modules.
Example:</p>
- <p><c>$ run_test -suite test/my_SUITE -event_handler handlers/my_evh1
+ <p><c>$ ct_run -suite test/my_SUITE -event_handler handlers/my_evh1
handlers/my_evh2 -pa $PWD/handlers</c></p>
- <p>Use the <c><![CDATA[run_test -event_handler_init]]></c> option instead of
+ <p>Use the <c><![CDATA[ct_run -event_handler_init]]></c> option instead of
<c><![CDATA[-event_handler]]></c> to pass start arguments to the event handler
init function.</p>
<p>All event handler modules must have gen_event behaviour. Note also that
@@ -120,6 +121,7 @@
node the event has originated from (only relevant for CT Master event handlers).
<c>data</c> is specific for the particular event.</p>
+ <marker id="events"></marker>
<p><em>General events:</em></p>
<list>
@@ -172,6 +174,7 @@
are also given.
</p></item>
+ <marker id="tc_done"/>
<item><c>#event{name = tc_done, data = {Suite,FuncOrGroup,Result}}</c>
<p><c>Suite = atom()</c>, name of the suite.</p>
<p><c>FuncOrGroup = Func | {Conf,GroupName,GroupProperties}</c></p>
@@ -181,12 +184,14 @@
(unknown if init- or end function times out).</p>
<p><c>GroupProperties = list()</c>, list of execution properties for the group.</p>
<p><c>Result = ok | {skipped,SkipReason} | {failed,FailReason}</c>, the result.</p>
+ <marker id="skipreason"/>
<p><c>SkipReason = {require_failed,RequireInfo} |
{require_failed_in_suite0,RequireInfo} |
{failed,{Suite,init_per_testcase,FailInfo}} |
UserTerm</c>,
the reason why the case has been skipped.</p>
- <p><c>FailReason = {error,FailInfo} |
+ <marker id="failreason"/>
+ <p><c>FailReason = {error,FailInfo} |
{error,{RunTimeError,StackTrace}} |
{timetrap_timeout,integer()} |
{failed,{Suite,end_per_testcase,FailInfo}}</c>, reason for failure.</p>
@@ -209,6 +214,7 @@
<c>end_per_testcase</c> for the case failed.
</p></item>
+ <marker id="tc_auto_skip"></marker>
<item><c>#event{name = tc_auto_skip, data = {Suite,Func,Reason}}</c>
<p><c>Suite = atom()</c>, the name of the suite.</p>
<p><c>Func = atom()</c>, the name of the test case or configuration function.</p>
@@ -234,7 +240,8 @@
skipped because of <c>init_per_testcase</c> failing, since that information is carried with
the <c>tc_done</c> event.
</p></item>
-
+
+ <marker id="tc_user_skip"></marker>
<item><c>#event{name = tc_user_skip, data = {Suite,TestCase,Comment}}</c>
<p><c>Suite = atom()</c>, name of the suite.</p>
<p><c>TestCase = atom()</c>, name of the test case.</p>
diff --git a/lib/common_test/doc/src/install_chapter.xml b/lib/common_test/doc/src/install_chapter.xml
index 828588a673..89c497962d 100644
--- a/lib/common_test/doc/src/install_chapter.xml
+++ b/lib/common_test/doc/src/install_chapter.xml
@@ -34,8 +34,8 @@
<title>General information</title>
<p>The two main interfaces for running tests with Common Test
- are an executable program named run_test and an
- erlang module named <c>ct</c>. The run_test program
+ are an executable program named ct_run and an
+ erlang module named <c>ct</c>. The ct_run program
is compiled for the underlying operating system (e.g. Unix/Linux
or Windows) during the build of the Erlang/OTP system, and is
installed automatically with other executable programs in
@@ -43,22 +43,22 @@
The <c>ct</c> interface functions can be called from the Erlang shell,
or from any Erlang function, on any supported platform.</p>
- <p>A legacy Bourne shell script - also named run_test - exists,
+ <p>A legacy Bourne shell script - named run_test - exists,
which may be manually generated and installed. This script may be used
- instead of the run_test program mentioned above, e.g. if the user
+ instead of the ct_run program mentioned above, e.g. if the user
wishes to modify or customize the Common Test start flags in a simpler
- way than making changes to the run_test C program.</p>
+ way than making changes to the ct_run C program.</p>
<p>The Common Test application is installed with the Erlang/OTP
system and no additional installation step is required to start using
- Common Test by means of the run_test executable program, and/or the interface
+ Common Test by means of the ct_run executable program, and/or the interface
functions in the <c>ct</c> module. If you wish to use the legacy Bourne
- shell script version of run_test, however, this script needs to be
+ shell script version run_test, however, this script needs to be
generated first, according to the instructions below.</p>
<p><note>Before reading on, please note that since Common Test version
1.5, the run_test shell script is no longer required for starting
- tests with Common Test from the OS command line. The run_test
+ tests with Common Test from the OS command line. The ct_run
program (descibed above) is the new recommended command line interface
for Common Test. The shell script exists mainly for legacy reasons and
may not be updated in future releases of Common Test. It may even be removed.
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index af9dbfa9ec..2fd5dcf4f1 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -32,6 +32,57 @@
<file>notes.xml</file>
</header>
+<section><title>Common_Test 1.5.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Updated ct:get_status documentation to describe
+ no_tests_running return value.</p>
+ <p>
+ Own Id: OTP-8895 Aux Id: seq11701 </p>
+ </item>
+ <item>
+ <p>
+ Fixed race condition test failures in the test suites
+ testing common test's parallel groups feature.</p>
+ <p>
+ Own Id: OTP-8921</p>
+ </item>
+ <item>
+ <p>
+ The include directive of testspecs now work when used on
+ a remote node.</p>
+ <p>
+ Own Id: OTP-8935 Aux Id: seq11731 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ ct:parse_table can now handle multiline sql rows</p>
+ <p>
+ Own Id: OTP-8907 Aux Id: seq11702 </p>
+ </item>
+ <item>
+ <p>
+ The run_test executable has been renamed to the less
+ generic ct_run to better work with other applications.
+ run_test will remain until R16B at which point it will be
+ removed.</p>
+ <p>
+ Own Id: OTP-8936</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Common_Test 1.5.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/common_test/doc/src/part.xml b/lib/common_test/doc/src/part.xml
index 53a4cb1bbf..41371b60be 100644
--- a/lib/common_test/doc/src/part.xml
+++ b/lib/common_test/doc/src/part.xml
@@ -75,6 +75,7 @@
<xi:include href="ct_master_chapter.xml"/>
<xi:include href="event_handler_chapter.xml"/>
<xi:include href="dependencies_chapter.xml"/>
+ <xi:include href="ct_hooks_chapter.xml"/>
<xi:include href="why_test_chapter.xml"/>
</part>
diff --git a/lib/common_test/doc/src/ref_man.xml b/lib/common_test/doc/src/ref_man.xml
index 8be234d979..631e3871c2 100644
--- a/lib/common_test/doc/src/ref_man.xml
+++ b/lib/common_test/doc/src/ref_man.xml
@@ -63,7 +63,7 @@
Server application.</p>
</description>
<xi:include href="common_test_app.xml"/>
- <xi:include href="run_test.xml"/>
+ <xi:include href="ct_run.xml"/>
<!-- If you make modifications in the module list below,
you also need to update CT_MODULES in Makefile. -->
<xi:include href="ct.xml"/>
@@ -76,6 +76,7 @@
<xi:include href="ct_telnet.xml"/>
<xi:include href="unix_telnet.xml"/>
<xi:include href="ct_slave.xml"/>
+ <xi:include href="ct_hooks.xml"/>
</application>
diff --git a/lib/common_test/doc/src/run_test_chapter.xml b/lib/common_test/doc/src/run_test_chapter.xml
index 1efff25f5b..f052adf25e 100644
--- a/lib/common_test/doc/src/run_test_chapter.xml
+++ b/lib/common_test/doc/src/run_test_chapter.xml
@@ -71,7 +71,7 @@
<p>If test suites or help modules include header files stored in other
locations than the test directory, you may specify these include directories
- by means of the <c><![CDATA[-include]]></c> flag with <c><![CDATA[run_test]]></c>,
+ by means of the <c><![CDATA[-include]]></c> flag with <c><![CDATA[ct_run]]></c>,
or the <c><![CDATA[include]]></c> option with <c><![CDATA[ct:run_test/1]]></c>.
In addition to this, an include path may be specified with an OS
environment variable; <c><![CDATA[CT_INCLUDE_PATH]]></c>. Example (bash):</p>
@@ -93,7 +93,7 @@
there instead.</p>
<p>It is possible to disable the automatic compilation feature by using the
- <c><![CDATA[-no_auto_compile]]></c> flag with <c><![CDATA[run_test]]></c>, or
+ <c><![CDATA[-no_auto_compile]]></c> flag with <c><![CDATA[ct_run]]></c>, or
the <c><![CDATA[{auto_compile,false}]]></c> option with
<c><![CDATA[ct:run_test/1]]></c>. With automatic compilation
disabled, the user is responsible for compiling the test suite modules
@@ -105,29 +105,30 @@
RPC from a remote node.</p>
</section>
+ <marker id="ct_run"></marker>
<section>
<title>Running tests from the OS command line</title>
- <p>The <c>run_test</c> program can be used for running tests from
+ <p>The <c>ct_run</c> program can be used for running tests from
the OS command line, e.g.
</p>
<list>
- <item><c><![CDATA[run_test -config <configfilenames> -dir <dirs>]]></c></item>
- <item><c><![CDATA[run_test -config <configfilenames> -suite <suiteswithfullpath>]]></c>
+ <item><c><![CDATA[ct_run -config <configfilenames> -dir <dirs>]]></c></item>
+ <item><c><![CDATA[ct_run -config <configfilenames> -suite <suiteswithfullpath>]]></c>
</item>
- <item><c><![CDATA[run_test -userconfig <callbackmodulename> <configfilenames> -suite <suiteswithfullpath>]]></c>
+ <item><c><![CDATA[ct_run -userconfig <callbackmodulename> <configfilenames> -suite <suiteswithfullpath>]]></c>
</item>
- <item><c><![CDATA[run_test -config <configfilenames> -suite <suitewithfullpath>
+ <item><c><![CDATA[ct_run -config <configfilenames> -suite <suitewithfullpath>
-group <groupnames> -case <casenames>]]></c></item>
</list>
<p>Examples:</p>
- <p><c>$ run_test -config $CFGS/sys1.cfg $CFGS/sys2.cfg -dir $SYS1_TEST $SYS2_TEST</c></p>
- <p><c>$ run_test -userconfig ct_config_xml $CFGS/sys1.xml $CFGS/sys2.xml -dir $SYS1_TEST $SYS2_TEST</c></p>
- <p><c>$ run_test -suite $SYS1_TEST/setup_SUITE $SYS2_TEST/config_SUITE</c></p>
- <p><c>$ run_test -suite $SYS1_TEST/setup_SUITE -case start stop</c></p>
- <p><c>$ run_test -suite $SYS1_TEST/setup_SUITE -group installation -case start stop</c></p>
+ <p><c>$ ct_run -config $CFGS/sys1.cfg $CFGS/sys2.cfg -dir $SYS1_TEST $SYS2_TEST</c></p>
+ <p><c>$ ct_run -userconfig ct_config_xml $CFGS/sys1.xml $CFGS/sys2.xml -dir $SYS1_TEST $SYS2_TEST</c></p>
+ <p><c>$ ct_run -suite $SYS1_TEST/setup_SUITE $SYS2_TEST/config_SUITE</c></p>
+ <p><c>$ ct_run -suite $SYS1_TEST/setup_SUITE -case start stop</c></p>
+ <p><c>$ ct_run -suite $SYS1_TEST/setup_SUITE -group installation -case start stop</c></p>
- <p>Other flags that may be used with <c>run_test</c>:</p>
+ <p>Other flags that may be used with <c>ct_run</c>:</p>
<list>
<item><c><![CDATA[-logdir <dir>]]></c>, specifies where the HTML log files are to be written.</item>
<item><c><![CDATA[-label <name_of_test_run>]]></c>, associates the test run with a name that gets printed
@@ -147,6 +148,8 @@
<seealso marker="event_handler_chapter#event_handling">event handlers</seealso>.</item>
<item><c><![CDATA[-event_handler_init <event_handlers>]]></c>, to install
<seealso marker="event_handler_chapter#event_handling">event handlers</seealso> including start arguments.</item>
+ <item><c><![CDATA[-ct_hooks <ct_hooks>]]></c>, to install
+ <seealso marker="ct_hooks_chapter#installing">Common Test Hooks</seealso> including start arguments.</item>
<item><c><![CDATA[-include]]></c>, specifies include directories (see above).</item>
<item><c><![CDATA[-no_auto_compile]]></c>, disables the automatic test suite compilation feature (see above).</item>
<item><c><![CDATA[-multiply_timetraps <n>]]></c>, extends <seealso marker="write_test_chapter#timetraps">timetrap
@@ -167,20 +170,20 @@
<note><p>Directories passed to Common Test may have either relative or absolute paths.</p></note>
<note><p>Arbitrary start flags to the Erlang Runtime System may also be passed as
- parameters to <c>run_test</c>. It is, for example, useful to be able to
+ parameters to <c>ct_run</c>. It is, for example, useful to be able to
pass directories that should be added to the Erlang code server search path
with the <c>-pa</c> or <c>-pz</c> flag. If you have common help- or library
modules for test suites (separately compiled), stored in other directories
than the test suite directories, these help/lib directories are preferrably
added to the code path this way. Example:</p>
- <p><c>$ run_test -dir ./chat_server -logdir ./chat_server/testlogs -pa $PWD/chat_server/ebin</c></p>
+ <p><c>$ ct_run -dir ./chat_server -logdir ./chat_server/testlogs -pa $PWD/chat_server/ebin</c></p>
<p>Note how in this example, the absolute path of the <c>chat_server/ebin</c>
directory is passed to the code server. This is essential since relative
paths are stored by the code server as relative, and Common Test changes
the current working directory of the Erlang Runtime System during the test run!</p>
</note>
- <p>For more information about the <c>run_test</c> program, see the
+ <p>For more information about the <c>ct_run</c> program, see the
<seealso marker="install_chapter#general">Installation</seealso> chapter.
</p>
</section>
@@ -188,7 +191,7 @@
<section>
<title>Running tests from the Web based GUI</title>
- <p>The web based GUI, VTS, is started with the <c>run_test</c>
+ <p>The web based GUI, VTS, is started with the <c>ct_run</c>
program. From the GUI you can load config files, and select
directories, suites and cases to run. You can also state the
config files, directories, suites and cases on the command line
@@ -196,22 +199,22 @@
</p>
<list>
- <item><c>run_test -vts</c></item>
- <item><c><![CDATA[run_test -vts -config <configfilename>]]></c></item>
- <item><c><![CDATA[run_test -vts -config <configfilename> -suite <suitewithfullpath>
+ <item><c>ct_run -vts</c></item>
+ <item><c><![CDATA[ct_run -vts -config <configfilename>]]></c></item>
+ <item><c><![CDATA[ct_run -vts -config <configfilename> -suite <suitewithfullpath>
-case <casename>]]></c></item>
</list>
<p>From the GUI you can run tests and view the result and the logs.
</p>
- <p>Note that <c>run_test -vts</c> will try to open the Common Test start
+ <p>Note that <c>ct_run -vts</c> will try to open the Common Test start
page in an existing web browser window or start the browser if it is
not running. Which browser should be started may be specified with
the browser start command option:</p>
- <p><c><![CDATA[run_test -vts -browser <browser_start_cmd>]]></c></p>
+ <p><c><![CDATA[ct_run -vts -browser <browser_start_cmd>]]></c></p>
<p>Example:</p>
- <p><c><![CDATA[$ run_test -vts -browser 'firefox&']]></c></p>
+ <p><c><![CDATA[$ ct_run -vts -browser 'firefox&']]></c></p>
<p>Note that the browser must run as a separate OS process or VTS will hang!</p>
<p>If no specific browser start command is specified, Firefox will
be the default browser on Unix platforms and Internet Explorer on Windows.
@@ -227,10 +230,10 @@
<p>Common Test provides an Erlang API for running tests. The main (and most
flexible) function for specifying and executing tests is called
<c>ct:run_test/1</c>. This function takes the same start parameters as
- the <c>run_test</c> program described above, only the flags are instead
+ the <c>ct_run</c> program described above, only the flags are instead
given as options in a list of key-value tuples. E.g. a test specified
- with <c>run_test</c> like:</p>
- <p><c>$ run_test -suite ./my_SUITE -logdir ./results</c></p>
+ with <c>ct_run</c> like:</p>
+ <p><c>$ ct_run -suite ./my_SUITE -logdir ./results</c></p>
<p>is with <c>ct:run_test/1</c> specified as:</p>
<p><c>1> ct:run_test([{suite,"./my_SUITE"},{logdir,"./results"}]).</c></p>
<p>For detailed documentation, please see the <c>ct</c> manual page.</p>
@@ -253,17 +256,17 @@
manually and call <c>ct:install/1</c> to install any configuration
data you might need (use <c>[]</c> as argument otherwise), then
call <c>ct:start_interactive/0</c> to start Common Test. If you use
- the <c>run_test</c> program, you may start the Erlang shell and Common Test
+ the <c>ct_run</c> program, you may start the Erlang shell and Common Test
in the same go by using the <c>-shell</c> and, optionally, the <c>-config</c>
and/or <c>-userconfig</c> flag. Examples:
</p>
<list>
- <item><c>run_test -shell</c></item>
- <item><c><![CDATA[run_test -shell -config cfg/db.cfg]]></c></item>
- <item><c><![CDATA[run_test -shell -userconfig db_login testuser x523qZ]]></c></item>
+ <item><c>ct_run -shell</c></item>
+ <item><c><![CDATA[ct_run -shell -config cfg/db.cfg]]></c></item>
+ <item><c><![CDATA[ct_run -shell -userconfig db_login testuser x523qZ]]></c></item>
</list>
- <p>If no config file is given with the <c>run_test</c> command,
+ <p>If no config file is given with the <c>ct_run</c> command,
a warning will be displayed. If Common Test has been run from the same
directory earlier, the same config file(s) will be used
again. If Common Test has not been run from this directory before, no
@@ -293,7 +296,7 @@
<c>ctlog.html</c> in the <c><![CDATA[ct_run.<timestamp>]]></c>
directory. A link to this file will be available in the file
named <c>last_interactive.html</c> in the directory from which
- you executed <c>run_test</c>. Currently, specifying a different
+ you executed <c>ct_run</c>. Currently, specifying a different
root directory for the logs than the current working directory,
is not supported.</p>
@@ -309,7 +312,7 @@
<section>
<title>Step by step execution of test cases with the Erlang Debugger</title>
- <p>By means of <c>run_test -step [opts]</c>, or by passing the
+ <p>By means of <c>ct_run -step [opts]</c>, or by passing the
<c>{step,Opts}</c> option to <c>ct:run_test/1</c>, it is possible
to get the Erlang Debugger started automatically and use its
graphical interface to investigate the state of the current test
@@ -333,8 +336,8 @@
with <c>dir</c>.</p>
</section>
+ <marker id="test_specifications"></marker>
<section>
- <marker id="test_specifications"></marker>
<title>Using test specifications</title>
<p>The most flexible way to specify what to test, is to use a so
@@ -345,12 +348,12 @@
for <c>ct</c>). There are two general types of terms:
configuration terms and test specification terms.</p>
<p>With configuration terms it is possible to e.g. label the test
- run (similar to <c>run_test -label</c>), evaluate arbitrary expressions
+ run (similar to <c>ct_run -label</c>), evaluate arbitrary expressions
before starting a test, import configuration
data (similar to
- <c>run_test -config/-userconfig</c>), specify HTML log directories (similar
+ <c>ct_run -config/-userconfig</c>), specify HTML log directories (similar
to
- <c>run_test -logdir</c>), give aliases to test nodes and test
+ <c>ct_run -logdir</c>), give aliases to test nodes and test
directories (to make a specification easier to read and
maintain), enable code coverage analysis (see
the <seealso marker="cover_chapter#cover">Code Coverage
@@ -359,21 +362,23 @@
Event Handling</seealso> chapter). There is also a term for
specifying include directories that should be passed on to the
compiler when automatic compilation is performed (similar
- to <c>run_test -include</c>, see above).</p>
+ to <c>ct_run -include</c>, see above).</p>
<p>With test specification terms it is possible to state exactly
which tests should run and in which order. A test term specifies
either one or more suites, one or more test case groups, or one
or more test cases in a group or suite.</p>
<p>An arbitrary number of test terms may be declared in sequence.
- Common Test will compile the terms into one or more tests to be
- performed in one resulting test run. Note that a term that
+ Common Test will by default compile the terms into one or more tests
+ to be performed in one resulting test run. Note that a term that
specifies a set of test cases will "swallow" one that only
specifies a subset of these cases. E.g. the result of merging
one term that specifies that all cases in suite S should be
executed, with another term specifying only test case X and Y in
S, is a test of all cases in S. However, if a term specifying
test case X and Y in S is merged with a term specifying case Z
- in S, the result is a test of X, Y and Z in S.</p>
+ in S, the result is a test of X, Y and Z in S. To disable this
+ behaviour, it is possible in test specification to set the
+ <c>merge_tests</c> term to <c>false</c>.</p>
<p>A test term can also specify one or more test suites, groups,
or test cases to be skipped. Skipped suites, groups and cases
are not executed and show up in the HTML test log files as
@@ -432,6 +437,8 @@
{userconfig, NodeRefs, {CallbackModule, ConfigStrings}}.
{alias, DirAlias, Dir}.
+
+ {merge_tests, Bool}.
{logdir, LogDir}.
{logdir, NodeRefs, LogDir}.
@@ -440,6 +447,9 @@
{event_handler, NodeRefs, EventHandlers}.
{event_handler, EventHandlers, InitArgs}.
{event_handler, NodeRefs, EventHandlers, InitArgs}.
+
+ {ct_hooks, CTHModules}.
+ {ct_hooks, NodeRefs, CTHModules}.
</pre>
<p>Test terms:</p>
<pre>
@@ -478,6 +488,9 @@
LogDir = string()
EventHandlers = atom() | [atom()]
InitArgs = [term()]
+ CTHModules = [CTHModule | {CTHModule, CTHInitArgs}]
+ CTHModule = atom()
+ CTHInitArgs = term()
DirRef = DirAlias | Dir
Suites = atom() | [atom()] | all
Suite = atom()
@@ -535,7 +548,7 @@
<p>It is possible for the user to provide a test specification that
includes (for Common Test) unrecognizable terms. If this is desired,
the <c>-allow_user_terms</c> flag should be used when starting tests with
- <c>run_test</c>. This forces Common Test to ignore unrecognizable terms.
+ <c>ct_run</c>. This forces Common Test to ignore unrecognizable terms.
Note that in this mode, Common Test is not able to check the specification
for errors as efficiently as if the scanner runs in default mode.
If <c>ct:run_test/1</c> is used for starting the tests, the relaxed scanner
@@ -661,11 +674,11 @@
</pre>
<p>To install the CSS file (Common Test inlines the definition in the
- HTML code), the name may be provided when executing <c>run_test</c>.
+ HTML code), the name may be provided when executing <c>ct_run</c>.
Example:</p>
<pre>
- $ run_test -dir $TEST/prog -stylesheet $TEST/styles/test_categories.css
+ $ ct_run -dir $TEST/prog -stylesheet $TEST/styles/test_categories.css
</pre>
<p>Categories in a CSS file installed with the <c>-stylesheet</c> flag
@@ -738,7 +751,7 @@
means of time, it is also possible to specify what action Common Test should
take upon timeout. Either Common Test performs all tests in the current run before stopping,
or it stops as soon as the current test job is finished. Repetition can be activated by
- means of <c>run_test</c> start flags, or tuples in the <c>ct:run:test/1</c>
+ means of <c>ct_run</c> start flags, or tuples in the <c>ct:run:test/1</c>
option list argument. The flags (options in parenthesis) are:</p>
<list>
<item><c>-repeat N ({repeat,N})</c>, where <c>N</c> is a positive integer.</item>
@@ -774,7 +787,7 @@
<p>Example 1:</p>
<pre>
- $ run_test -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -force_stop</pre>
+ $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -force_stop</pre>
<p>Here the suites in test directory to1, followed by the suites in to2, will be executed
in one test run. A timeout event will occur after 10 minutes. As long as there is time
left, Common Test will repeat the test run (i.e. starting over with the to1 test).
@@ -787,7 +800,7 @@
$ date
Fri Sep 28 15:00:00 MEST 2007
- $ run_test -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -until 160000</pre>
+ $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -until 160000</pre>
<p>Here the same test run as in the example above will be executed (and possibly repeated).
In this example, however, the timeout will occur after 1 hour and when that happens,
Common Test will finish the entire test run before stopping (i.e. the to1 and to2 test
@@ -795,7 +808,7 @@
<p>Example 3:</p>
<pre>
- $ run_test -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -repeat 5</pre>
+ $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -repeat 5</pre>
<p>Here the test run, including both the to1 and the to2 test, will be repeated 5 times.</p>
<note><p>This feature should not be confused with the <c>repeat</c> property of a test
@@ -814,7 +827,7 @@
of the <c>-silent_connections</c> flag:</p>
<pre>
- run_test -silent_connections [conn_types]
+ ct_run -silent_connections [conn_types]
</pre>
<p>where <c>conn_types</c> specifies <c>telnet, ftp, rpc</c> and/or <c>snmp</c>.</p>
@@ -822,11 +835,11 @@
<p>Example:</p>
<pre>
- run_test ... -silent_connections telnet ftp</pre>
+ ct_run ... -silent_connections telnet ftp</pre>
<p>switches off logging for telnet and ftp connections.</p>
<pre>
- run_test ... -silent_connections</pre>
+ ct_run ... -silent_connections</pre>
<p>switches off logging for all connection types.</p>
diff --git a/lib/common_test/doc/src/test_structure_chapter.xml b/lib/common_test/doc/src/test_structure_chapter.xml
index cd38ae0c7c..b9ca59135d 100644
--- a/lib/common_test/doc/src/test_structure_chapter.xml
+++ b/lib/common_test/doc/src/test_structure_chapter.xml
@@ -144,7 +144,7 @@
be used when the test suite needs to write to files.
</item>
- <tag><em>run_test</em></tag>
+ <tag><em>ct_run</em></tag>
<item>
The name of an executable program that may be
used as an interface for specifying and running
diff --git a/lib/common_test/doc/src/write_test_chapter.xml b/lib/common_test/doc/src/write_test_chapter.xml
index 5afec6de6a..76493d3616 100644
--- a/lib/common_test/doc/src/write_test_chapter.xml
+++ b/lib/common_test/doc/src/write_test_chapter.xml
@@ -115,6 +115,7 @@
</p>
</section>
+ <marker id="per_testcase"/>
<section>
<title>Init and end per test case</title>
diff --git a/lib/common_test/priv/Makefile.in b/lib/common_test/priv/Makefile.in
index 6372bbc8d5..a6ac0f1a02 100644
--- a/lib/common_test/priv/Makefile.in
+++ b/lib/common_test/priv/Makefile.in
@@ -56,8 +56,8 @@ ifneq ($(findstring win32,$(TARGET)),win32)
#
# Files
#
-FILES =
-SCRIPTS =
+FILES = vts.tool
+SCRIPTS =
IMAGES = tile1.jpg
#
diff --git a/lib/common_test/src/Makefile b/lib/common_test/src/Makefile
index 027667e6b0..378a7ba08c 100644
--- a/lib/common_test/src/Makefile
+++ b/lib/common_test/src/Makefile
@@ -67,7 +67,9 @@ MODULES= \
ct_config \
ct_config_plain \
ct_config_xml \
- ct_slave
+ ct_slave \
+ ct_hooks\
+ ct_hooks_lock
TARGET_MODULES= $(MODULES:%=$(EBIN)/%)
diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl
index 8ae175f10d..b0a92dcc15 100644
--- a/lib/common_test/src/ct.erl
+++ b/lib/common_test/src/ct.erl
@@ -97,7 +97,7 @@
%%% <code>install([{config,["config_node.ctc","config_user.ctc"]}])</code>.</p>
%%%
%%% <p>Note that this function is automatically run by the
-%%% <code>run_test</code> program.</p>
+%%% <code>ct_run</code> program.</p>
install(Opts) ->
ct_run:install(Opts).
@@ -148,7 +148,8 @@ run(TestDirs) ->
%%% {auto_compile,Bool} | {multiply_timetraps,M} | {scale_timetraps,Bool} |
%%% {repeat,N} | {duration,DurTime} | {until,StopTime} |
%%% {force_stop,Bool} | {decrypt,DecryptKeyOrFile} |
-%%% {refresh_logs,LogDir} | {basic_html,Bool}
+%%% {refresh_logs,LogDir} | {basic_html,Bool} |
+%%% {ct_hooks, CTHs}
%%% TestDirs = [string()] | string()
%%% Suites = [string()] | string()
%%% Cases = [atom()] | atom()
@@ -176,13 +177,16 @@ run(TestDirs) ->
%%% DecryptKeyOrFile = {key,DecryptKey} | {file,DecryptFile}
%%% DecryptKey = string()
%%% DecryptFile = string()
+%%% CTHs = [CTHModule | {CTHModule, CTHInitArgs}]
+%%% CTHModule = atom()
+%%% CTHInitArgs = term()
%%% Result = [TestResult] | {error,Reason}
%%% @doc Run tests as specified by the combination of options in <code>Opts</code>.
%%% The options are the same as those used with the
-%%% <seealso marker="run_test#run_test"><code>run_test</code></seealso> program.
+%%% <seealso marker="ct_run#ct_run"><code>ct_run</code></seealso> program.
%%% Note that here a <code>TestDir</code> can be used to point out the path to
%%% a <code>Suite</code>. Note also that the option <code>testcase</code>
-%%% corresponds to the <code>-case</code> option in the <code>run_test</code>
+%%% corresponds to the <code>-case</code> option in the <code>ct_run</code>
%%% program. Configuration files specified in <code>Opts</code> will be
%%% installed automatically at startup.
run_test(Opts) ->
@@ -225,7 +229,7 @@ step(TestDir,Suite,Case,Opts) ->
%%%
%%% <p>From this mode all test case support functions can be executed
%%% directly from the erlang shell. The interactive mode can also be
-%%% started from the OS command line with <code>run_test -shell
+%%% started from the OS command line with <code>ct_run -shell
%%% [-config File...]</code>.</p>
%%%
%%% <p>If any functions using "required config data" (e.g. telnet or
@@ -694,7 +698,7 @@ userdata(TestDir, Suite, Case) ->
%%%-----------------------------------------------------------------
-%%% @spec get_status() -> TestStatus | {error,Reason}
+%%% @spec get_status() -> TestStatus | {error,Reason} | no_tests_running
%%% TestStatus = [StatusElem]
%%% StatusElem = {current,{Suite,TestCase}} | {successful,Successful} |
%%% {failed,Failed} | {skipped,Skipped} | {total,Total}
diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl
index f2ca023cff..b61eda7152 100644
--- a/lib/common_test/src/ct_framework.erl
+++ b/lib/common_test/src/ct_framework.erl
@@ -24,7 +24,7 @@
-module(ct_framework).
--export([init_tc/3, end_tc/3, get_suite/2, report/2, warn/1]).
+-export([init_tc/3, end_tc/4, get_suite/2, report/2, warn/1]).
-export([error_notification/4]).
-export([overview_html_header/1]).
@@ -207,7 +207,7 @@ init_tc2(Mod,Func,SuiteInfo,MergeResult,Config,DoInit) ->
{skip,{require_failed_in_suite0,Reason}};
{error,Reason} ->
{auto_skip,{require_failed,Reason}};
- FinalConfig ->
+ {ok, FinalConfig} ->
case MergeResult of
{error,Reason} ->
%% suite0 configure finished now, report that
@@ -216,13 +216,25 @@ init_tc2(Mod,Func,SuiteInfo,MergeResult,Config,DoInit) ->
_ ->
case get('$test_server_framework_test') of
undefined ->
- FinalConfig;
+ ct_suite_init(Mod, FuncSpec, FinalConfig);
Fun ->
- Fun(init_tc, FinalConfig)
+ case Fun(init_tc, FinalConfig) of
+ NewConfig when is_list(NewConfig) ->
+ {ok,NewConfig};
+ Else ->
+ Else
+ end
end
end
end.
-
+
+ct_suite_init(Mod, Func, [Config]) when is_list(Config) ->
+ case ct_hooks:init_tc( Mod, Func, Config) of
+ NewConfig when is_list(NewConfig) ->
+ {ok, [NewConfig]};
+ Else ->
+ Else
+ end.
add_defaults(Mod,Func,FuncInfo,DoInit) ->
case (catch Mod:suite()) of
@@ -239,7 +251,9 @@ add_defaults(Mod,Func,FuncInfo,DoInit) ->
(_) -> false
end, SuiteInfo) of
true ->
- SuiteInfo1 = merge_with_suite_defaults(Mod,SuiteInfo),
+ SuiteInfoNoCTH =
+ lists:keydelete(ct_hooks,1,SuiteInfo),
+ SuiteInfo1 = merge_with_suite_defaults(Mod,SuiteInfoNoCTH),
case add_defaults1(Mod,Func,FuncInfo,SuiteInfo1,DoInit) of
Error = {error,_} -> {SuiteInfo1,Error};
MergedInfo -> {SuiteInfo1,MergedInfo}
@@ -362,6 +376,8 @@ configure([{timetrap,off}|Rest],Info,SuiteInfo,Scope,Config) ->
configure([{timetrap,Time}|Rest],Info,SuiteInfo,Scope,Config) ->
Dog = test_server:timetrap(Time),
configure(Rest,Info,SuiteInfo,Scope,[{watchdog,Dog}|Config]);
+configure([{ct_hooks, Hook} | Rest], Info, SuiteInfo, Scope, Config) ->
+ configure(Rest, Info, SuiteInfo, Scope, [{ct_hooks, Hook} | Config]);
configure([_|Rest],Info,SuiteInfo,Scope,Config) ->
configure(Rest,Info,SuiteInfo,Scope,Config);
configure([],_,_,_,Config) ->
@@ -418,14 +434,14 @@ try_set_default(Name,Key,Info,Where) ->
%%%
%%% @doc Test server framework callback, called by the test_server
%%% when a test case is finished.
-end_tc(?MODULE,error_in_suite,_) -> % bad start!
+end_tc(?MODULE,error_in_suite,_, _) -> % bad start!
ok;
-end_tc(Mod,Func,{TCPid,Result,[Args]}) when is_pid(TCPid) ->
- end_tc(Mod,Func,TCPid,Result,Args);
-end_tc(Mod,Func,{Result,[Args]}) ->
- end_tc(Mod,Func,self(),Result,Args).
+end_tc(Mod,Func,{TCPid,Result,[Args]}, Return) when is_pid(TCPid) ->
+ end_tc(Mod,Func,TCPid,Result,Args,Return);
+end_tc(Mod,Func,{Result,[Args]}, Return) ->
+ end_tc(Mod,Func,self(),Result,Args,Return).
-end_tc(Mod,Func,TCPid,Result,Args) ->
+end_tc(Mod,Func,TCPid,Result,Args,Return) ->
case lists:keysearch(watchdog,1,Args) of
{value,{watchdog,Dog}} -> test_server:timetrap_cancel(Dog);
false -> ok
@@ -448,8 +464,10 @@ end_tc(Mod,Func,TCPid,Result,Args) ->
{_,GroupName,_Props} = Group ->
case lists:keysearch(save_config,1,Args) of
{value,{save_config,SaveConfig}} ->
- ct_util:save_suite_data(last_saved_config,
- {Mod,{group,GroupName}},SaveConfig),
+ ct_util:save_suite_data(
+ last_saved_config,
+ {Mod,{group,GroupName}},
+ SaveConfig),
Group;
false ->
Group
@@ -466,12 +484,33 @@ end_tc(Mod,Func,TCPid,Result,Args) ->
end,
ct_util:reset_silent_connections(),
- %% send sync notification so that event handlers may print
- %% in the log file before it gets closed
- ct_event:sync_notify(#event{name=tc_done,
- node=node(),
- data={Mod,FuncSpec,tag(Result)}}),
- case Result of
+ case get('$test_server_framework_test') of
+ undefined ->
+ {FinalResult,FinalNotify} =
+ case ct_hooks:end_tc(
+ Mod, FuncSpec, Args, Result, Return) of
+ '$ct_no_change' ->
+ {FinalResult = ok,Result};
+ FinalResult ->
+ {FinalResult,FinalResult}
+ end,
+ % send sync notification so that event handlers may print
+ % in the log file before it gets closed
+ ct_event:sync_notify(#event{name=tc_done,
+ node=node(),
+ data={Mod,FuncSpec,
+ tag_cth(FinalNotify)}});
+ Fun ->
+ % send sync notification so that event handlers may print
+ % in the log file before it gets closed
+ ct_event:sync_notify(#event{name=tc_done,
+ node=node(),
+ data={Mod,FuncSpec,tag(Result)}}),
+ FinalResult = Fun(end_tc, Return)
+ end,
+
+
+ case FinalResult of
{skip,{sequence_failed,_,_}} ->
%% ct_logs:init_tc is never called for a skipped test case
%% in a failing sequence, so neither should end_tc
@@ -490,12 +529,7 @@ end_tc(Mod,Func,TCPid,Result,Args) ->
_ ->
ok
end,
- case get('$test_server_framework_test') of
- undefined ->
- ok;
- Fun ->
- Fun(end_tc, ok)
- end.
+ FinalResult.
%% {error,Reason} | {skip,Reason} | {timetrap_timeout,TVal} |
%% {testcase_aborted,Reason} | testcase_aborted_or_killed |
@@ -511,6 +545,21 @@ tag(E = testcase_aborted_or_killed) ->
tag(Other) ->
Other.
+tag_cth({STag,Reason}) when STag == skip; STag == skipped ->
+ {skipped,Reason};
+tag_cth({fail, Reason}) ->
+ {failed, {error,Reason}};
+tag_cth(E = {ETag,_}) when ETag == error; ETag == 'EXIT';
+ ETag == timetrap_timeout;
+ ETag == testcase_aborted ->
+ {failed,E};
+tag_cth(E = testcase_aborted_or_killed) ->
+ {failed,E};
+tag_cth(List) when is_list(List) ->
+ ok;
+tag_cth(Other) ->
+ Other.
+
%%%-----------------------------------------------------------------
%%% @spec error_notification(Mod,Func,Args,Error) -> ok
%%% Mod = atom()
@@ -694,12 +743,12 @@ get_suite(Mod, Group={conf,Props,_Init,TCs,_End}) ->
%% init/end functions for top groups will be executed
case catch proplists:get_value(name, element(2, hd(ConfTests))) of
Name -> % top group
- ConfTests;
+ delete_subs(ConfTests, ConfTests);
_ ->
[]
end;
false ->
- ConfTests
+ delete_subs(ConfTests, ConfTests)
end
end;
_ ->
@@ -716,9 +765,25 @@ get_suite(Mod, Name) ->
find_groups(Mod, Name, TCs, GroupDefs) ->
Found = find(Mod, Name, TCs, GroupDefs, [], GroupDefs, false),
Trimmed = trim(Found),
- delete_subs(Trimmed, Trimmed).
-
-find(Mod, all, _TCs, [{Name,Props,Tests} | Gs], Known, Defs, _) ->
+ %% I cannot find a reason to why this function is called,
+ %% It deletes any group which is referenced in any other
+ %% group. i.e.
+ %% groups() ->
+ %% [{test, [], [testcase1]},
+ %% {testcases, [], [{group, test}]}].
+ %% Would be changed to
+ %% groups() ->
+ %% [{testcases, [], [testcase1]}].
+ %% instead of what I believe is correct:
+ %% groups() ->
+ %% [{test, [], [testcase1]},
+ %% {testcases, [], [testcase1]}].
+ %% Have to double check with peppe
+ delete_subs(Trimmed, Trimmed),
+ Trimmed.
+
+find(Mod, all, _TCs, [{Name,Props,Tests} | Gs], Known, Defs, _)
+ when is_atom(Name), is_list(Props), is_list(Tests) ->
cyclic_test(Mod, Name, Known),
[make_conf(Mod, Name, Props,
find(Mod, all, all, Tests, [Name | Known], Defs, true)) |
@@ -740,8 +805,8 @@ find(Mod, Name, TCs, [{Name,Props,Tests} | _Gs], Known, Defs, false)
find(Mod, Name, TCs, [{Name1,Props,Tests} | Gs], Known, Defs, false)
when is_atom(Name1), is_list(Props), is_list(Tests) ->
cyclic_test(Mod, Name1, Known),
- [make_conf(Mod, Name1, Props,
- find(Mod, Name, TCs, Tests, [Name1 | Known], Defs, false)) |
+ [make_conf(Mod,Name1,Props,
+ find(Mod, Name, TCs, Tests, [Name1 | Known], Defs, false)) |
find(Mod, Name, TCs, Gs, [], Defs, false)];
find(Mod, Name, _TCs, [{Name,_Props,_Tests} | _Gs], _Known, _Defs, true)
@@ -757,17 +822,31 @@ find(Mod, Name, all, [{Name1,Props,Tests} | Gs], Known, Defs, true)
find(Mod, Name, all, Tests, [Name1 | Known], Defs, true)) |
find(Mod, Name, all, Gs, [], Defs, true)];
-find(Mod, Name, TCs, [{group,Name1} | Gs], Known, Defs, Found) when is_atom(Name1) ->
+find(Mod, Name, TCs, [{group,Name1} | Gs], Known, Defs, Found)
+ when is_atom(Name1) ->
find(Mod, Name, TCs, [expand(Mod, Name1, Defs) | Gs], Known, Defs, Found);
+%% Undocumented remote group feature, use with caution
+find(Mod, Name, TCs, [{group, ExtMod, ExtGrp} | Gs], Known, Defs, true)
+ when is_atom(ExtMod), is_atom(ExtGrp) ->
+ ExternalDefs = ExtMod:groups(),
+ ExternalTCs = find(ExtMod, ExtGrp, TCs, [{group, ExtGrp}],
+ [], ExternalDefs, false),
+ ExternalTCs ++ find(Mod, Name, TCs, Gs, Known, Defs, true);
+
find(Mod, Name, TCs, [{Name1,Tests} | Gs], Known, Defs, Found)
when is_atom(Name1), is_list(Tests) ->
find(Mod, Name, TCs, [{Name1,[],Tests} | Gs], Known, Defs, Found);
-find(Mod, Name, TCs, [TC | Gs], Known, Defs, false) when is_atom(TC) ->
+find(Mod, Name, TCs, [_TC | Gs], Known, Defs, false) ->
find(Mod, Name, TCs, Gs, Known, Defs, false);
find(Mod, Name, TCs, [TC | Gs], Known, Defs, true) when is_atom(TC) ->
+ [{Mod, TC} | find(Mod, Name, TCs, Gs, Known, Defs, true)];
+
+find(Mod, Name, TCs, [{ExternalTC, Case} = TC | Gs], Known, Defs, true)
+ when is_atom(ExternalTC),
+ is_atom(Case) ->
[TC | find(Mod, Name, TCs, Gs, Known, Defs, true)];
find(Mod, _Name, _TCs, [BadTerm | _Gs], Known, _Defs, _Found) ->
@@ -787,7 +866,7 @@ find(_Mod, _Name, _TCs, [], _Known, _Defs, false) ->
find(_Mod, _Name, _TCs, [], _Known, _Defs, _Found) ->
[].
-delete_subs([Conf | Confs], All) ->
+delete_subs([{conf, _,_,_,_} = Conf | Confs], All) ->
All1 = delete_conf(Conf, All),
case is_sub(Conf, All1) of
true ->
@@ -795,7 +874,8 @@ delete_subs([Conf | Confs], All) ->
false ->
delete_subs(Confs, All)
end;
-
+delete_subs([_Else | Confs], All) ->
+ delete_subs(Confs, All);
delete_subs([], All) ->
All.
@@ -887,7 +967,9 @@ make_all_conf(Mod) ->
[] ->
{error,{invalid_group_spec,Mod}};
ConfTests ->
- [{conf,Props,Init,all,End} || {conf,Props,Init,_,End} <- ConfTests]
+ [{conf,Props,Init,all,End} ||
+ {conf,Props,Init,_,End}
+ <- delete_subs(ConfTests, ConfTests)]
end
end.
@@ -933,31 +1015,11 @@ get_all(Mod, ConfTests) ->
[{?MODULE,error_in_suite,[[{error,What}]]}];
SeqsAndTCs ->
%% expand group references in all() using ConfTests
- Expand =
- fun({group,Name}) ->
- FindConf =
- fun({conf,Props,_,_,_}) ->
- case proplists:get_value(name, Props) of
- Name -> true;
- _ -> false
- end
- end,
- case lists:filter(FindConf, ConfTests) of
- [ConfTest|_] ->
- ConfTest;
- [] ->
- E = "Invalid reference to group "++
- atom_to_list(Name)++" in "++
- atom_to_list(Mod)++":all/0",
- throw({error,list_to_atom(E)})
- end;
- (SeqOrTC) -> SeqOrTC
- end,
- case catch lists:map(Expand, SeqsAndTCs) of
+ case catch expand_groups(SeqsAndTCs, ConfTests, Mod) of
{error,_} = Error ->
[{?MODULE,error_in_suite,[[Error]]}];
Tests ->
- Tests
+ delete_subs(Tests, Tests)
end
end;
Skip = {skip,_Reason} ->
@@ -968,6 +1030,30 @@ get_all(Mod, ConfTests) ->
[{?MODULE,error_in_suite,[[{error,Reason}]]}]
end.
+expand_groups([H | T], ConfTests, Mod) ->
+ [expand_groups(H, ConfTests, Mod) | expand_groups(T, ConfTests, Mod)];
+expand_groups([], _ConfTests, _Mod) ->
+ [];
+expand_groups({group,Name}, ConfTests, Mod) ->
+ FindConf =
+ fun({conf,Props,_,_,_}) ->
+ case proplists:get_value(name, Props) of
+ Name -> true;
+ _ -> false
+ end
+ end,
+ case lists:filter(FindConf, ConfTests) of
+ [ConfTest|_] ->
+ expand_groups(ConfTest, ConfTests, Mod);
+ [] ->
+ E = "Invalid reference to group "++
+ atom_to_list(Name)++" in "++
+ atom_to_list(Mod)++":all/0",
+ throw({error,list_to_atom(E)})
+ end;
+expand_groups(SeqOrTC, _ConfTests, _Mod) ->
+ SeqOrTC.
+
%%!============================================================
%%! The support for sequences by means of using sequences/0
@@ -1137,6 +1223,18 @@ report(What,Data) ->
ok;
tc_done ->
{_Suite,Case,Result} = Data,
+ case Result of
+ {failed, _} ->
+ ct_hooks:on_tc_fail(What, Data);
+ {skipped,{failed,{_,init_per_testcase,_}}} ->
+ ct_hooks:on_tc_skip(tc_auto_skip, Data);
+ {skipped,{require_failed,_}} ->
+ ct_hooks:on_tc_skip(tc_auto_skip, Data);
+ {skipped,_} ->
+ ct_hooks:on_tc_skip(tc_user_skip, Data);
+ _Else ->
+ ok
+ end,
case {Case,Result} of
{init_per_suite,_} ->
ok;
@@ -1154,8 +1252,8 @@ report(What,Data) ->
add_to_stats(auto_skipped);
{_,{skipped,_}} ->
add_to_stats(user_skipped);
- {_,{FailOrSkip,_Reason}} ->
- add_to_stats(FailOrSkip)
+ {_,{SkipOrFail,_Reason}} ->
+ add_to_stats(SkipOrFail)
end;
tc_user_skip ->
%% test case specified as skipped in testspec
@@ -1163,6 +1261,7 @@ report(What,Data) ->
ct_event:sync_notify(#event{name=tc_user_skip,
node=node(),
data=Data}),
+ ct_hooks:on_tc_skip(What, Data),
add_to_stats(user_skipped);
tc_auto_skip ->
%% test case skipped because of error in init_per_suite
@@ -1175,6 +1274,7 @@ report(What,Data) ->
ct_event:sync_notify(#event{name=tc_auto_skip,
node=node(),
data=Data}),
+ ct_hooks:on_tc_skip(What, Data),
if Case /= end_per_suite, Case /= end_per_group ->
add_to_stats(auto_skipped);
true ->
diff --git a/lib/common_test/src/ct_hooks.erl b/lib/common_test/src/ct_hooks.erl
new file mode 100644
index 0000000000..77b7566d9e
--- /dev/null
+++ b/lib/common_test/src/ct_hooks.erl
@@ -0,0 +1,305 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%% @doc Common Test Framework test execution control module.
+%%%
+%%% <p>This module is a proxy for calling and handling common test hooks.</p>
+
+-module(ct_hooks).
+
+%% API Exports
+-export([init/1]).
+-export([init_tc/3]).
+-export([end_tc/5]).
+-export([terminate/1]).
+-export([on_tc_skip/2]).
+-export([on_tc_fail/2]).
+
+-type proplist() :: [{atom(),term()}].
+
+%% If you change this, remember to update ct_util:look -> stop clause as well.
+-define(config_name, ct_hooks).
+
+%% -------------------------------------------------------------------------
+%% API Functions
+%% -------------------------------------------------------------------------
+
+%% @doc Called before any suites are started
+-spec init(State :: term()) -> ok |
+ {error, Reason :: term()}.
+init(Opts) ->
+ call([{Hook, call_id, undefined} || Hook <- get_new_hooks(Opts)],
+ ok, init, []).
+
+
+%% @doc Called after all suites are done.
+-spec terminate(Hooks :: term()) ->
+ ok.
+terminate(Hooks) ->
+ call([{HookId, fun call_terminate/3} || {HookId,_,_} <- Hooks],
+ ct_hooks_terminate_dummy, terminate, Hooks),
+ ok.
+
+%% @doc Called as each test case is started. This includes all configuration
+%% tests.
+-spec init_tc(Mod :: atom(), Func :: atom(), Args :: list()) ->
+ NewConfig :: proplist() |
+ {skip, Reason :: term()} |
+ {auto_skip, Reason :: term()} |
+ {fail, Reason :: term()}.
+init_tc(ct_framework, _Func, Args) ->
+ Args;
+init_tc(Mod, init_per_suite, Config) ->
+ Info = case catch proplists:get_value(ct_hooks, Mod:suite()) of
+ List when is_list(List) ->
+ [{ct_hooks,List}];
+ _Else ->
+ []
+ end,
+ call(fun call_generic/3, Config ++ Info, [pre_init_per_suite, Mod]);
+init_tc(Mod, end_per_suite, Config) ->
+ call(fun call_generic/3, Config, [pre_end_per_suite, Mod]);
+init_tc(Mod, {init_per_group, GroupName, Opts}, Config) ->
+ maybe_start_locker(Mod, GroupName, Opts),
+ call(fun call_generic/3, Config, [pre_init_per_group, GroupName]);
+init_tc(_Mod, {end_per_group, GroupName, _}, Config) ->
+ call(fun call_generic/3, Config, [pre_end_per_group, GroupName]);
+init_tc(_Mod, TC, Config) ->
+ call(fun call_generic/3, Config, [pre_init_per_testcase, TC]).
+
+%% @doc Called as each test case is completed. This includes all configuration
+%% tests.
+-spec end_tc(Mod :: atom(),
+ Func :: atom(),
+ Args :: list(),
+ Result :: term(),
+ Resturn :: term()) ->
+ NewConfig :: proplist() |
+ {skip, Reason :: term()} |
+ {auto_skip, Reason :: term()} |
+ {fail, Reason :: term()} |
+ ok | '$ct_no_change'.
+end_tc(ct_framework, _Func, _Args, Result, _Return) ->
+ Result;
+
+end_tc(Mod, init_per_suite, Config, _Result, Return) ->
+ call(fun call_generic/3, Return, [post_init_per_suite, Mod, Config],
+ '$ct_no_change');
+
+end_tc(Mod, end_per_suite, Config, Result, _Return) ->
+ call(fun call_generic/3, Result, [post_end_per_suite, Mod, Config],
+ '$ct_no_change');
+
+end_tc(_Mod, {init_per_group, GroupName, _}, Config, _Result, Return) ->
+ call(fun call_generic/3, Return, [post_init_per_group, GroupName, Config],
+ '$ct_no_change');
+
+end_tc(Mod, {end_per_group, GroupName, Opts}, Config, Result, _Return) ->
+ Res = call(fun call_generic/3, Result,
+ [post_end_per_group, GroupName, Config], '$ct_no_change'),
+ maybe_stop_locker(Mod, GroupName,Opts),
+ Res;
+
+end_tc(_Mod, TC, Config, Result, _Return) ->
+ call(fun call_generic/3, Result, [post_end_per_testcase, TC, Config],
+ '$ct_no_change').
+
+on_tc_skip(How, {_Suite, Case, Reason}) ->
+ call(fun call_cleanup/3, {How, Reason}, [on_tc_skip, Case]).
+
+on_tc_fail(_How, {_Suite, Case, Reason}) ->
+ call(fun call_cleanup/3, Reason, [on_tc_fail, Case]).
+
+%% -------------------------------------------------------------------------
+%% Internal Functions
+%% -------------------------------------------------------------------------
+call_id(Mod, Config, Meta) when is_atom(Mod) ->
+ call_id({Mod, []}, Config, Meta);
+call_id({Mod, Opts}, Config, Scope) ->
+ Id = catch_apply(Mod,id,[Opts], make_ref()),
+ {Config, {Id, scope(Scope), {Mod, {Id,Opts}}}}.
+
+call_init({Mod,{Id,Opts}},Config,_Meta) ->
+ NewState = Mod:init(Id, Opts),
+ {Config, {Mod, NewState}}.
+
+call_terminate({Mod, State}, _, _) ->
+ catch_apply(Mod,terminate,[State], ok),
+ {[],{Mod,State}}.
+
+call_cleanup({Mod, State}, Reason, [Function | Args]) ->
+ NewState = catch_apply(Mod,Function, Args ++ [Reason, State],
+ State),
+ {Reason, {Mod, NewState}}.
+
+call_generic({Mod, State}, Value, [Function | Args]) ->
+ {NewValue, NewState} = catch_apply(Mod, Function, Args ++ [Value, State],
+ {Value,State}),
+ {NewValue, {Mod, NewState}}.
+
+%% Generic call function
+call(Fun, Config, Meta) ->
+ maybe_lock(),
+ Hooks = get_hooks(),
+ Res = call([{HookId,Fun} || {HookId,_, _} <- Hooks] ++
+ get_new_hooks(Config, Fun),
+ remove(?config_name,Config), Meta, Hooks),
+ maybe_unlock(),
+ Res.
+
+call(Fun, Config, Meta, NoChangeRet) when is_function(Fun) ->
+ case call(Fun,Config,Meta) of
+ Config -> NoChangeRet;
+ NewReturn -> NewReturn
+ end;
+
+call([{Hook, call_id, NextFun} | Rest], Config, Meta, Hooks) ->
+ try
+ {Config, {NewId, _, _} = NewHook} = call_id(Hook, Config, Meta),
+ {NewHooks, NewRest} =
+ case lists:keyfind(NewId, 1, Hooks) of
+ false when NextFun =:= undefined ->
+ {Hooks ++ [NewHook],
+ [{NewId, fun call_init/3} | Rest]};
+ ExistingHook when is_tuple(ExistingHook) ->
+ {Hooks, Rest};
+ _ ->
+ {Hooks ++ [NewHook],
+ [{NewId, fun call_init/3},{NewId,NextFun} | Rest]}
+ end,
+ call(NewRest, Config, Meta, NewHooks)
+ catch Error:Reason ->
+ Trace = erlang:get_stacktrace(),
+ ct_logs:log("Suite Hook","Failed to start a CTH: ~p:~p",
+ [Error,{Reason,Trace}]),
+ call([], {fail,"Failed to start CTH"
+ ", see the CT Log for details"}, Meta, Hooks)
+ end;
+call([{HookId, Fun} | Rest], Config, Meta, Hooks) ->
+ try
+ {_,Scope,ModState} = lists:keyfind(HookId, 1, Hooks),
+ {NewConf, NewHookInfo} = Fun(ModState, Config, Meta),
+ NewCalls = get_new_hooks(NewConf, Fun),
+ NewHooks = lists:keyreplace(HookId, 1, Hooks, {HookId, Scope, NewHookInfo}),
+ call(NewCalls ++ Rest, remove(?config_name, NewConf), Meta,
+ terminate_if_scope_ends(HookId, Meta, NewHooks))
+ catch throw:{error_in_cth_call,Reason} ->
+ call(Rest, {fail, Reason}, Meta,
+ terminate_if_scope_ends(HookId, Meta, Hooks))
+ end;
+call([], Config, _Meta, Hooks) ->
+ save_suite_data_async(Hooks),
+ Config.
+
+remove(Key,List) when is_list(List) ->
+ [Conf || Conf <- List, is_tuple(Conf) =:= false
+ orelse element(1, Conf) =/= Key];
+remove(_, Else) ->
+ Else.
+
+%% Translate scopes, i.e. init_per_group,group1 -> end_per_group,group1 etc
+scope([pre_init_per_testcase, TC|_]) ->
+ [post_end_per_testcase, TC];
+scope([pre_init_per_group, GroupName|_]) ->
+ [post_end_per_group, GroupName];
+scope([post_init_per_group, GroupName|_]) ->
+ [post_end_per_group, GroupName];
+scope([pre_init_per_suite, SuiteName|_]) ->
+ [post_end_per_suite, SuiteName];
+scope([post_init_per_suite, SuiteName|_]) ->
+ [post_end_per_suite, SuiteName];
+scope(init) ->
+ none.
+
+terminate_if_scope_ends(HookId, [Function,Tag|T], Hooks) when T =/= [] ->
+ terminate_if_scope_ends(HookId,[Function,Tag],Hooks);
+terminate_if_scope_ends(HookId, Function, Hooks) ->
+ case lists:keyfind(HookId, 1, Hooks) of
+ {HookId, Function, _ModState} = Hook ->
+ terminate([Hook]),
+ lists:keydelete(HookId, 1, Hooks);
+ _ ->
+ Hooks
+ end.
+
+%% Fetch hook functions
+get_new_hooks(Config, Fun) ->
+ lists:foldl(fun(NewHook, Acc) ->
+ [{NewHook, call_id, Fun} | Acc]
+ end, [], get_new_hooks(Config)).
+
+get_new_hooks(Config) when is_list(Config) ->
+ lists:flatmap(fun({?config_name, HookConfigs}) ->
+ HookConfigs;
+ (_) ->
+ []
+ end, Config);
+get_new_hooks(_Config) ->
+ [].
+
+save_suite_data_async(Hooks) ->
+ ct_util:save_suite_data_async(?config_name, Hooks).
+
+get_hooks() ->
+ ct_util:read_suite_data(?config_name).
+
+catch_apply(M,F,A, Default) ->
+ try
+ apply(M,F,A)
+ catch error:Reason ->
+ case erlang:get_stacktrace() of
+ %% Return the default if it was the CTH module which did not have the function.
+ [{M,F,A}|_] when Reason == undef ->
+ Default;
+ Trace ->
+ ct_logs:log("Suite Hook","Call to CTH failed: ~p:~p",
+ [error,{Reason,Trace}]),
+ throw({error_in_cth_call,
+ lists:flatten(
+ io_lib:format("~p:~p/~p CTH call failed",
+ [M,F,length(A)]))})
+ end
+ end.
+
+
+%% We need to lock around the state for parallel groups only. This is because
+%% we will get several processes reading and writing the state for a single
+%% cth at the same time.
+maybe_start_locker(Mod,GroupName,Opts) ->
+ case lists:member(parallel,Opts) of
+ true ->
+ {ok, _Pid} = ct_hooks_lock:start({Mod,GroupName});
+ false ->
+ ok
+ end.
+
+maybe_stop_locker(Mod,GroupName,Opts) ->
+ case lists:member(parallel,Opts) of
+ true ->
+ stopped = ct_hooks_lock:stop({Mod,GroupName});
+ false ->
+ ok
+ end.
+
+
+maybe_lock() ->
+ locked = ct_hooks_lock:request().
+
+maybe_unlock() ->
+ unlocked = ct_hooks_lock:release().
diff --git a/lib/common_test/src/ct_hooks_lock.erl b/lib/common_test/src/ct_hooks_lock.erl
new file mode 100644
index 0000000000..98794201bb
--- /dev/null
+++ b/lib/common_test/src/ct_hooks_lock.erl
@@ -0,0 +1,132 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%% @doc Common Test Framework test execution control module.
+%%%
+%%% <p>This module is a proxy for calling and handling locks in
+%%% common test hooks.</p>
+
+-module(ct_hooks_lock).
+
+-behaviour(gen_server).
+
+%% API
+-export([start/1, stop/1, request/0, release/0]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+-define(SERVER, ?MODULE).
+
+-record(state, { id, locked = false, requests = [] }).
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+
+%% @doc Starts the server
+start(Id) ->
+ case gen_server:start({local, ?SERVER}, ?MODULE, Id, []) of
+ {error,{already_started, Pid}} ->
+ {ok,Pid};
+ Else ->
+ Else
+ end.
+
+stop(Id) ->
+ try
+ gen_server:call(?SERVER, {stop,Id})
+ catch exit:{noproc,_} ->
+ stopped
+ end.
+
+request() ->
+ try
+ gen_server:call(?SERVER,{request,self()},infinity)
+ catch exit:{noproc,_} ->
+ locked
+ end.
+
+release() ->
+ try
+ gen_server:call(?SERVER,{release,self()})
+ catch exit:{noproc,_} ->
+ unlocked
+ end.
+
+%%%===================================================================
+%%% gen_server callbacks
+%%%===================================================================
+
+%% @doc Initiates the server
+init(Id) ->
+ {ok, #state{ id = Id }}.
+
+%% @doc Handling call messages
+handle_call({stop,Id}, _From, #state{ id = Id, requests = Reqs } = State) ->
+ [gen_server:reply(Req, locker_stopped) || {Req,_ReqId} <- Reqs],
+ {stop, normal, stopped, State};
+handle_call({stop,_Id}, _From, State) ->
+ {reply, stopped, State};
+handle_call({request, Pid}, _From, #state{ locked = false,
+ requests = [] } = State) ->
+ Ref = monitor(process, Pid),
+ {reply, locked, State#state{ locked = {true, Pid, Ref}} };
+handle_call({request, Pid}, From, #state{ requests = Reqs } = State) ->
+ {noreply, State#state{ requests = Reqs ++ [{From,Pid}] }};
+handle_call({release, Pid}, _From, #state{ locked = {true, Pid, Ref},
+ requests = []} = State) ->
+ demonitor(Ref,[flush]),
+ {reply, unlocked, State#state{ locked = false }};
+handle_call({release, Pid}, _From,
+ #state{ locked = {true, Pid, Ref},
+ requests = [{NextFrom,NextPid}|Rest]} = State) ->
+ demonitor(Ref,[flush]),
+ gen_server:reply(NextFrom,locked),
+ NextRef = monitor(process, NextPid),
+ {reply,unlocked,State#state{ locked = {true, NextPid, NextRef},
+ requests = Rest } };
+handle_call({release, _Pid}, _From, State) ->
+ {reply, not_locked, State}.
+
+%% @doc Handling cast messages
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+%% @doc Handling all non call/cast messages
+handle_info({'DOWN',Ref,process,Pid,_},
+ #state{ locked = {true, Pid, Ref},
+ requests = [{NextFrom,NextPid}|Rest] } = State) ->
+ gen_server:reply(NextFrom, locked),
+ NextRef = monitor(process, NextPid),
+ {noreply,State#state{ locked = {true, NextPid, NextRef},
+ requests = Rest } }.
+
+%% @doc This function is called by a gen_server when it is about to terminate.
+terminate(_Reason, _State) ->
+ ok.
+
+%% @doc Convert process state when code is changed
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%% -------------------------------------------------------------------------
+%% Internal Functions
+%% -------------------------------------------------------------------------
diff --git a/lib/common_test/src/ct_master.erl b/lib/common_test/src/ct_master.erl
index 42e4cf08f4..2ea2ba106a 100644
--- a/lib/common_test/src/ct_master.erl
+++ b/lib/common_test/src/ct_master.erl
@@ -101,12 +101,14 @@ run([TS|TestSpecs],AllowUserTerms,InclNodes,ExclNodes) when is_list(TS),
TSRec=#testspec{logdir=AllLogDirs,
config=StdCfgFiles,
userconfig=UserCfgFiles,
+ include=AllIncludes,
init=AllInitOpts,
event_handler=AllEvHs} ->
AllCfgFiles = {StdCfgFiles, UserCfgFiles},
RunSkipPerNode = ct_testspec:prepare_tests(TSRec),
RunSkipPerNode2 = exclude_nodes(ExclNodes,RunSkipPerNode),
- run_all(RunSkipPerNode2,AllLogDirs,AllCfgFiles,AllEvHs,[],[],AllInitOpts,TS1)
+ run_all(RunSkipPerNode2,AllLogDirs,AllCfgFiles,AllEvHs,
+ AllIncludes,[],[],AllInitOpts,TS1)
end,
[{TS,Result} | run(TestSpecs,AllowUserTerms,InclNodes,ExclNodes)];
run([],_,_,_) ->
@@ -163,11 +165,13 @@ run_on_node([TS|TestSpecs],AllowUserTerms,Node) when is_list(TS),is_atom(Node) -
TSRec=#testspec{logdir=AllLogDirs,
config=StdCfgFiles,
init=AllInitOpts,
+ include=AllIncludes,
userconfig=UserCfgFiles,
event_handler=AllEvHs} ->
AllCfgFiles = {StdCfgFiles, UserCfgFiles},
{Run,Skip} = ct_testspec:prepare_tests(TSRec,Node),
- run_all([{Node,Run,Skip}],AllLogDirs,AllCfgFiles,AllEvHs,[],[],AllInitOpts,TS1)
+ run_all([{Node,Run,Skip}],AllLogDirs,AllCfgFiles,AllEvHs,
+ AllIncludes, [],[],AllInitOpts,TS1)
end,
[{TS,Result} | run_on_node(TestSpecs,AllowUserTerms,Node)];
run_on_node([],_,_) ->
@@ -189,7 +193,7 @@ run_on_node(TestSpecs,Node) ->
run_all([{Node,Run,Skip}|Rest],AllLogDirs,
{AllStdCfgFiles, AllUserCfgFiles}=AllCfgFiles,
- AllEvHs,NodeOpts,LogDirs,InitOptions,Specs) ->
+ AllEvHs,AllIncludes,NodeOpts,LogDirs,InitOptions,Specs) ->
LogDir =
lists:foldl(fun({N,Dir},_Found) when N == Node ->
Dir;
@@ -211,6 +215,14 @@ run_all([{Node,Run,Skip}|Rest],AllLogDirs,
({_N,_F},Fs) -> Fs;
(F,Fs) -> [{userconfig, F}|Fs]
end,[],AllUserCfgFiles),
+
+ Includes = lists:foldr(fun({N,I},Acc) when N =:= Node ->
+ [I|Acc];
+ ({_,_},Acc) ->
+ Acc;
+ (I,Acc) ->
+ [I | Acc]
+ end, [], AllIncludes),
EvHs =
lists:foldr(fun({N,H,A},Hs) when N == Node -> [{H,A}|Hs];
({_N,_H,_A},Hs) -> Hs;
@@ -219,10 +231,13 @@ run_all([{Node,Run,Skip}|Rest],AllLogDirs,
NO = {Node,[{prepared_tests,{Run,Skip},Specs},
{logdir,LogDir},
+ {include, Includes},
{config,StdCfgFiles},
{event_handler,EvHs}] ++ UserCfgFiles},
- run_all(Rest,AllLogDirs,AllCfgFiles,AllEvHs,[NO|NodeOpts],[LogDir|LogDirs],InitOptions,Specs);
-run_all([],AllLogDirs,_,AllEvHs,NodeOpts,LogDirs,InitOptions,Specs) ->
+ run_all(Rest,AllLogDirs,AllCfgFiles,AllEvHs,AllIncludes,
+ [NO|NodeOpts],[LogDir|LogDirs],InitOptions,Specs);
+run_all([],AllLogDirs,_,AllEvHs,_AllIncludes,
+ NodeOpts,LogDirs,InitOptions,Specs) ->
Handlers = [{H,A} || {Master,H,A} <- AllEvHs, Master == master],
MasterLogDir = case lists:keysearch(master,1,AllLogDirs) of
{value,{_,Dir}} -> Dir;
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index 586b3893f1..f50a46a241 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -54,6 +54,7 @@
logdir,
config = [],
event_handlers = [],
+ ct_hooks = [],
include = [],
silent_connections,
stylesheet,
@@ -65,12 +66,12 @@
%%%-----------------------------------------------------------------
%%% @spec script_start() -> void()
%%%
-%%% @doc Start tests via the run_test program or script.
+%%% @doc Start tests via the ct_run program or script.
%%%
-%%% <p>Example:<br/><code>./run_test -config config.ctc -dir
+%%% <p>Example:<br/><code>./ct_run -config config.ctc -dir
%%% $TEST_DIR</code></p>
%%%
-%%% <p>Example:<br/><code>./run_test -config config.ctc -suite
+%%% <p>Example:<br/><code>./ct_run -config config.ctc -suite
%%% $SUITE_PATH/$SUITE_NAME [-case $CASE_NAME]</code></p>
%%%
script_start() ->
@@ -80,7 +81,7 @@ script_start() ->
(_) -> true end, Init),
%% convert relative dirs added with pa or pz (pre erl_args on
- %% the run_test command line) to absolute so that app modules
+ %% the ct_run command line) to absolute so that app modules
%% can be found even after CT changes CWD to logdir
rel_to_abs(CtArgs),
@@ -171,6 +172,7 @@ script_start1(Parent, Args) ->
([]) -> true
end, false, Args),
EvHandlers = event_handler_args2opts(Args),
+ CTHooks = ct_hooks_args2opts(Args),
%% check flags and set corresponding application env variables
@@ -234,6 +236,7 @@ script_start1(Parent, Args) ->
StartOpts = #opts{label = Label, vts = Vts, shell = Shell, cover = Cover,
logdir = LogDir, event_handlers = EvHandlers,
+ ct_hooks = CTHooks,
include = IncludeDirs,
silent_connections = SilentConns,
stylesheet = Stylesheet,
@@ -305,6 +308,10 @@ script_start2(StartOpts = #opts{vts = undefined,
SpecStartOpts#opts.scale_timetraps),
AllEvHs = merge_vals([StartOpts#opts.event_handlers,
SpecStartOpts#opts.event_handlers]),
+ AllCTHooks = merge_vals(
+ [StartOpts#opts.ct_hooks,
+ SpecStartOpts#opts.ct_hooks]),
+
AllInclude = merge_vals([StartOpts#opts.include,
SpecStartOpts#opts.include]),
application:set_env(common_test, include, AllInclude),
@@ -315,6 +322,7 @@ script_start2(StartOpts = #opts{vts = undefined,
logdir = LogDir,
config = SpecStartOpts#opts.config,
event_handlers = AllEvHs,
+ ct_hooks = AllCTHooks,
include = AllInclude,
multiply_timetraps = MultTT,
scale_timetraps = ScaleTT}}
@@ -332,7 +340,8 @@ script_start2(StartOpts = #opts{vts = undefined,
{error,no_testspec_specified};
{undefined,_} -> % no testspec used
case check_and_install_configfiles(InitConfig, TheLogDir,
- Opts#opts.event_handlers) of
+ Opts#opts.event_handlers,
+ Opts#opts.ct_hooks) of
ok -> % go on read tests from start flags
script_start3(Opts#opts{config=InitConfig,
logdir=TheLogDir}, Args);
@@ -343,7 +352,8 @@ script_start2(StartOpts = #opts{vts = undefined,
%% merge config from start flags with config from testspec
AllConfig = merge_vals([InitConfig, Opts#opts.config]),
case check_and_install_configfiles(AllConfig, TheLogDir,
- Opts#opts.event_handlers) of
+ Opts#opts.event_handlers,
+ Opts#opts.ct_hooks) of
ok -> % read tests from spec
{Run,Skip} = ct_testspec:prepare_tests(Terms, node()),
do_run(Run, Skip, Opts#opts{config=AllConfig,
@@ -358,7 +368,8 @@ script_start2(StartOpts, Args) ->
InitConfig = ct_config:prepare_config_list(Args),
LogDir = which(logdir, StartOpts#opts.logdir),
case check_and_install_configfiles(InitConfig, LogDir,
- StartOpts#opts.event_handlers) of
+ StartOpts#opts.event_handlers,
+ StartOpts#opts.ct_hooks) of
ok -> % go on read tests from start flags
script_start3(StartOpts#opts{config=InitConfig,
logdir=LogDir}, Args);
@@ -366,11 +377,12 @@ script_start2(StartOpts, Args) ->
Error
end.
-check_and_install_configfiles(Configs, LogDir, EvHandlers) ->
+check_and_install_configfiles(Configs, LogDir, EvHandlers, CTHooks) ->
case ct_config:check_config_files(Configs) of
false ->
install([{config,Configs},
- {event_handler,EvHandlers}], LogDir);
+ {event_handler,EvHandlers},
+ {ct_hooks,CTHooks}], LogDir);
{value,{error,{nofile,File}}} ->
{error,{cant_read_config_file,File}};
{value,{error,{wrong_config,Message}}}->
@@ -438,11 +450,13 @@ script_start4(#opts{vts = true, config = Config, event_handlers = EvHandlers,
script_start4(#opts{label = Label, shell = true, config = Config,
event_handlers = EvHandlers,
+ ct_hooks = CTHooks,
logdir = LogDir, testspecs = Specs}, _Args) ->
%% label - used by ct_logs
application:set_env(common_test, test_label, Label),
- InstallOpts = [{config,Config},{event_handler,EvHandlers}],
+ InstallOpts = [{config,Config},{event_handler,EvHandlers},
+ {ct_hooks, CTHooks}],
if Config == [] ->
ok;
true ->
@@ -482,11 +496,11 @@ script_start4(Opts = #opts{tests = Tests}, Args) ->
%%%-----------------------------------------------------------------
%%% @spec script_usage() -> ok
-%%% @doc Print usage information for <code>run_test</code>.
+%%% @doc Print usage information for <code>ct_run</code>.
script_usage() ->
io:format("\n\nUsage:\n\n"),
io:format("Run tests in web based GUI:\n\n"
- "\trun_test -vts [-browser Browser]"
+ "\tct_run -vts [-browser Browser]"
"\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
"\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]"
"\n\t[-dir TestDir1 TestDir2 .. TestDirN] |"
@@ -497,7 +511,7 @@ script_usage() ->
"\n\t[-scale_timetraps]"
"\n\t[-basic_html]\n\n"),
io:format("Run tests from command line:\n\n"
- "\trun_test [-dir TestDir1 TestDir2 .. TestDirN] |"
+ "\tct_run [-dir TestDir1 TestDir2 .. TestDirN] |"
"\n\t[-suite Suite1 Suite2 .. SuiteN [-case Case1 Case2 .. CaseN]]"
"\n\t[-step [config | keep_inactive]]"
"\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
@@ -508,6 +522,7 @@ script_usage() ->
"\n\t[-stylesheet CSSFile]"
"\n\t[-cover CoverCfgFile]"
"\n\t[-event_handler EvHandler1 EvHandler2 .. EvHandlerN]"
+ "\n\t[-ct_hooks CTHook1 CTHook2 .. CTHookN]"
"\n\t[-include InclDir1 InclDir2 .. InclDirN]"
"\n\t[-no_auto_compile]"
"\n\t[-multiply_timetraps N]"
@@ -517,7 +532,7 @@ script_usage() ->
"\n\t[-duration HHMMSS [-force_stop]] |"
"\n\t[-until [YYMoMoDD]HHMMSS [-force_stop]]\n\n"),
io:format("Run tests using test specification:\n\n"
- "\trun_test -spec TestSpec1 TestSpec2 .. TestSpecN"
+ "\tct_run -spec TestSpec1 TestSpec2 .. TestSpecN"
"\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
"\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]"
"\n\t[-logdir LogDir]"
@@ -526,6 +541,7 @@ script_usage() ->
"\n\t[-stylesheet CSSFile]"
"\n\t[-cover CoverCfgFile]"
"\n\t[-event_handler EvHandler1 EvHandler2 .. EvHandlerN]"
+ "\n\t[-ct_hooks CTHook1 CTHook2 .. CTHookN]"
"\n\t[-include InclDir1 InclDir2 .. InclDirN]"
"\n\t[-no_auto_compile]"
"\n\t[-multiply_timetraps N]"
@@ -535,11 +551,11 @@ script_usage() ->
"\n\t[-duration HHMMSS [-force_stop]] |"
"\n\t[-until [YYMoMoDD]HHMMSS [-force_stop]]\n\n"),
io:format("Refresh the HTML index files:\n\n"
- "\trun_test -refresh_logs [LogDir]"
+ "\tct_run -refresh_logs [LogDir]"
"[-logdir LogDir] "
"[-basic_html]\n\n"),
io:format("Run CT in interactive mode:\n\n"
- "\trun_test -shell"
+ "\tct_run -shell"
"\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]"
"\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]\n\n").
@@ -664,6 +680,9 @@ run_test1(StartOpts) ->
end, Hs))
end,
+ %% CT Hooks
+ CTHooks = get_start_opt(ct_hooks, value, [], StartOpts),
+
%% silent connections
SilentConns = get_start_opt(silent_connections,
fun(all) -> [];
@@ -733,7 +752,9 @@ run_test1(StartOpts) ->
Opts = #opts{label = Label,
cover = Cover, step = Step, logdir = LogDir, config = CfgFiles,
- event_handlers = EvHandlers, include = Include,
+ event_handlers = EvHandlers,
+ ct_hooks = CTHooks,
+ include = Include,
silent_connections = SilentConns,
stylesheet = Stylesheet,
multiply_timetraps = MultiplyTT,
@@ -784,11 +805,16 @@ run_spec_file(Relaxed,
SpecOpts#opts.event_handlers]),
AllInclude = merge_vals([Opts#opts.include,
SpecOpts#opts.include]),
+
+ AllCTHooks = merge_vals([Opts#opts.ct_hooks,
+ SpecOpts#opts.ct_hooks]),
+
application:set_env(common_test, include, AllInclude),
case check_and_install_configfiles(AllConfig,
which(logdir,LogDir),
- AllEvHs) of
+ AllEvHs,
+ AllCTHooks) of
ok ->
Opts1 = Opts#opts{label = Label,
cover = Cover,
@@ -798,7 +824,8 @@ run_spec_file(Relaxed,
include = AllInclude,
testspecs = AbsSpecs,
multiply_timetraps = MultTT,
- scale_timetraps = ScaleTT},
+ scale_timetraps = ScaleTT,
+ ct_hooks = AllCTHooks},
{Run,Skip} = ct_testspec:prepare_tests(TS, node()),
reformat_result(catch do_run(Run, Skip, Opts1, StartOpts));
{error,GCFReason} ->
@@ -808,10 +835,12 @@ run_spec_file(Relaxed,
run_prepared(Run, Skip, Opts = #opts{logdir = LogDir,
config = CfgFiles,
- event_handlers = EvHandlers},
+ event_handlers = EvHandlers,
+ ct_hooks = CTHooks},
StartOpts) ->
LogDir1 = which(logdir, LogDir),
- case check_and_install_configfiles(CfgFiles, LogDir1, EvHandlers) of
+ case check_and_install_configfiles(CfgFiles, LogDir1,
+ EvHandlers, CTHooks) of
ok ->
reformat_result(catch do_run(Run, Skip, Opts#opts{logdir = LogDir1},
StartOpts));
@@ -842,7 +871,8 @@ check_config_file(Callback, File)->
run_dir(Opts = #opts{logdir = LogDir,
config = CfgFiles,
- event_handlers = EvHandlers}, StartOpts) ->
+ event_handlers = EvHandlers,
+ ct_hooks = CTHook }, StartOpts) ->
LogDir1 = which(logdir, LogDir),
Opts1 = Opts#opts{logdir = LogDir1},
AbsCfgFiles =
@@ -863,7 +893,9 @@ run_dir(Opts = #opts{logdir = LogDir,
check_config_file(Callback, File)
end, FileList)}
end, CfgFiles),
- case install([{config,AbsCfgFiles},{event_handler,EvHandlers}], LogDir1) of
+ case install([{config,AbsCfgFiles},
+ {event_handler,EvHandlers},
+ {ct_hooks, CTHook}], LogDir1) of
ok -> ok;
{error,IReason} -> exit(IReason)
end,
@@ -968,7 +1000,8 @@ run_testspec1(TestSpec) ->
application:set_env(common_test, include, AllInclude),
LogDir1 = which(logdir,Opts#opts.logdir),
case check_and_install_configfiles(Opts#opts.config, LogDir1,
- Opts#opts.event_handlers) of
+ Opts#opts.event_handlers,
+ Opts#opts.ct_hooks) of
ok ->
Opts1 = Opts#opts{testspecs = [],
logdir = LogDir1,
@@ -986,6 +1019,7 @@ get_data_for_node(#testspec{label = Labels,
config = Cfgs,
userconfig = UsrCfgs,
event_handler = EvHs,
+ ct_hooks = CTHooks,
include = Incl,
multiply_timetraps = MTs,
scale_timetraps = STs}, Node) ->
@@ -1000,12 +1034,14 @@ get_data_for_node(#testspec{label = Labels,
ConfigFiles = [{?ct_config_txt,F} || {N,F} <- Cfgs, N==Node] ++
[CBF || {N,CBF} <- UsrCfgs, N==Node],
EvHandlers = [{H,A} || {N,H,A} <- EvHs, N==Node],
+ FiltCTHooks = [Hook || {N,Hook} <- CTHooks, N==Node],
Include = [I || {N,I} <- Incl, N==Node],
#opts{label = Label,
logdir = LogDir,
cover = Cover,
config = ConfigFiles,
event_handlers = EvHandlers,
+ ct_hooks = FiltCTHooks,
include = Include,
multiply_timetraps = MT,
scale_timetraps = ST}.
@@ -1036,15 +1072,7 @@ refresh_logs(LogDir) ->
which(logdir, undefined) ->
".";
which(logdir, Dir) ->
- Dir;
-which(multiply_timetraps, undefined) ->
- 1;
-which(multiply_timetraps, MT) ->
- MT;
-which(scale_timetraps, undefined) ->
- false;
-which(scale_timetraps, ST) ->
- ST.
+ Dir.
choose_val(undefined, V1) ->
V1;
@@ -2032,12 +2060,37 @@ get_start_opt(Key, IfExists, IfNotExists, Args) ->
Val;
{value,{Key,_Val}} ->
IfExists;
- _ when is_function(IfNotExists) ->
- IfNotExists();
_ ->
IfNotExists
end.
+ct_hooks_args2opts(Args) ->
+ ct_hooks_args2opts(
+ proplists:get_value(ct_hooks, Args, []),[]).
+
+ct_hooks_args2opts([CTH,Arg,"and"| Rest],Acc) ->
+ ct_hooks_args2opts(Rest,[{list_to_atom(CTH),
+ parse_cth_args(Arg)}|Acc]);
+ct_hooks_args2opts([CTH], Acc) ->
+ ct_hooks_args2opts([CTH,"and"],Acc);
+ct_hooks_args2opts([CTH, "and" | Rest], Acc) ->
+ ct_hooks_args2opts(Rest,[list_to_atom(CTH)|Acc]);
+ct_hooks_args2opts([CTH, Args], Acc) ->
+ ct_hooks_args2opts([CTH, Args, "and"],Acc);
+ct_hooks_args2opts([],Acc) ->
+ lists:reverse(Acc).
+
+parse_cth_args(String) ->
+ try
+ true = io_lib:printable_list(String),
+ {ok,Toks,_} = erl_scan:string(String++"."),
+ {ok, Args} = erl_parse:parse_term(Toks),
+ Args
+ catch _:_ ->
+ String
+ end.
+
+
event_handler_args2opts(Args) ->
case proplists:get_value(event_handler, Args) of
undefined ->
@@ -2103,7 +2156,7 @@ get_pa_pz([], PA, PZ) ->
{PA,PZ}.
%% This function translates ct:run_test/1 start options
-%% to run_test start arguments (on the init arguments format) -
+%% to ct_run start arguments (on the init arguments format) -
%% this is useful mainly for testing the ct_run start functions.
opts2args(EnvStartOpts) ->
lists:flatmap(fun({config,CfgFiles}) ->
@@ -2165,6 +2218,22 @@ opts2args(EnvStartOpts) ->
end, EHs),
[_LastAnd|StrsR] = lists:reverse(lists:flatten(Strs)),
[{event_handler_init,lists:reverse(StrsR)}];
+ ({ct_hooks,[]}) ->
+ [];
+ ({ct_hooks,CTHs}) when is_list(CTHs) ->
+ io:format(user,"ct_hooks: ~p",[CTHs]),
+ Strs = lists:flatmap(
+ fun({CTH,Arg}) ->
+ [atom_to_list(CTH),
+ lists:flatten(
+ io_lib:format("~p",[Arg])),
+ "and"];
+ (CTH) when is_atom(CTH) ->
+ [atom_to_list(CTH),"and"]
+ end,CTHs),
+ [_LastAnd|StrsR] = lists:reverse(Strs),
+ io:format(user,"return: ~p",[lists:reverse(StrsR)]),
+ [{ct_hooks,lists:reverse(StrsR)}];
({Opt,As=[A|_]}) when is_atom(A) ->
[{Opt,[atom_to_list(Atom) || Atom <- As]}];
({Opt,Strs=[S|_]}) when is_list(S) ->
@@ -2263,12 +2332,19 @@ do_trace(Terms) ->
dbg:tracer(),
dbg:p(self(), [sos,call]),
lists:foreach(fun({m,M}) ->
- case dbg:tpl(M,[{'_',[],[{return_trace}]}]) of
+ case dbg:tpl(M,x) of
+ {error,What} -> exit({error,{tracing_failed,What}});
+ _ -> ok
+ end;
+ ({me,M}) ->
+ case dbg:tp(M,[{'_',[],[{exception_trace},
+ {message,{caller}}]}]) of
{error,What} -> exit({error,{tracing_failed,What}});
_ -> ok
end;
({f,M,F}) ->
- case dbg:tpl(M,F,[{'_',[],[{return_trace}]}]) of
+ case dbg:tpl(M,F,[{'_',[],[{exception_trace},
+ {message,{caller}}]}]) of
{error,What} -> exit({error,{tracing_failed,What}});
_ -> ok
end;
diff --git a/lib/common_test/src/ct_testspec.erl b/lib/common_test/src/ct_testspec.erl
index f5069427a2..2c7cd3577c 100644
--- a/lib/common_test/src/ct_testspec.erl
+++ b/lib/common_test/src/ct_testspec.erl
@@ -68,7 +68,8 @@ prepare_tests(TestSpec) when is_record(TestSpec,testspec) ->
%% Create initial list of {Node,{Run,Skip}} tuples
NodeList = lists:map(fun(N) -> {N,{[],[]}} end, list_nodes(TestSpec)),
%% Get all Run tests sorted per node basis.
- NodeList1 = run_per_node(Run,NodeList),
+ NodeList1 = run_per_node(Run,NodeList,
+ TestSpec#testspec.merge_tests),
%% Get all Skip entries sorted per node basis.
NodeList2 = skip_per_node(Skip,NodeList1),
%% Change representation.
@@ -89,11 +90,17 @@ prepare_tests(TestSpec) when is_record(TestSpec,testspec) ->
%% run_per_node/2 takes the Run list as input and returns a list
%% of {Node,RunPerNode,[]} tuples where the tests have been sorted
%% on a per node basis.
-run_per_node([{{Node,Dir},Test}|Ts],Result) ->
+run_per_node([{{Node,Dir},Test}|Ts],Result, MergeTests) ->
{value,{Node,{Run,Skip}}} = lists:keysearch(Node,1,Result),
- Run1 = merge_tests(Dir,Test,Run),
- run_per_node(Ts,insert_in_order({Node,{Run1,Skip}},Result));
-run_per_node([],Result) ->
+ Run1 = case MergeTests of
+ false ->
+ append({Dir, Test}, Run);
+ true ->
+ merge_tests(Dir,Test,Run)
+ end,
+ run_per_node(Ts,insert_in_order({Node,{Run1,Skip}},Result),
+ MergeTests);
+run_per_node([],Result,_) ->
Result.
merge_tests(Dir,Test={all,_},TestDirs) ->
@@ -281,6 +288,8 @@ collect_tests(Terms,TestSpec,Relaxed) ->
{Terms2, TestSpec3} = filter_init_terms(Terms, [], TestSpec2),
add_tests(Terms2,TestSpec3).
+get_global([{merge_tests, Bool} | Ts], Spec) ->
+ get_global(Ts,Spec#testspec{ merge_tests = Bool });
get_global([{alias,Ref,Dir}|Ts],Spec=#testspec{alias=Refs}) ->
get_global(Ts,Spec#testspec{alias=[{Ref,get_absdir(Dir,Spec)}|Refs]});
get_global([{node,Ref,Node}|Ts],Spec=#testspec{nodes=Refs}) ->
@@ -394,8 +403,6 @@ filter_init_terms([Term|Ts], NewTerms, Spec)->
filter_init_terms([], NewTerms, Spec)->
{lists:reverse(NewTerms), Spec}.
-add_option([], _, List, _)->
- List;
add_option({Key, Value}, Node, List, WarnIfExists) when is_list(Value)->
OldOptions = case lists:keyfind(Node, 1, List) of
{Node, Options}->
@@ -625,6 +632,20 @@ add_tests([{event_handler,Node,H,Args}|Ts],Spec) when is_atom(H) ->
Node1 = ref2node(Node,Spec#testspec.nodes),
add_tests(Ts,Spec#testspec{event_handler=[{Node1,H,Args}|EvHs]});
+%% --- ct_hooks --
+add_tests([{ct_hooks, all_nodes, Hooks} | Ts], Spec) ->
+ Tests = [{ct_hooks,N,Hooks} || N <- list_nodes(Spec)],
+ add_tests(Tests ++ Ts, Spec);
+add_tests([{ct_hooks, Node, [Hook|Hooks]}|Ts], Spec) ->
+ SuiteCbs = Spec#testspec.ct_hooks,
+ Node1 = ref2node(Node,Spec#testspec.nodes),
+ add_tests([{ct_hooks, Node, Hooks} | Ts],
+ Spec#testspec{ct_hooks = [{Node1,Hook} | SuiteCbs]});
+add_tests([{ct_hooks, _Node, []}|Ts], Spec) ->
+ add_tests(Ts, Spec);
+add_tests([{ct_hooks, Hooks}|Ts], Spec) ->
+ add_tests([{ct_hooks, all_nodes, Hooks}|Ts], Spec);
+
%% --- include ---
add_tests([{include,all_nodes,InclDirs}|Ts],Spec) ->
Tests = lists:map(fun(N) -> {include,N,InclDirs} end, list_nodes(Spec)),
@@ -656,7 +677,7 @@ add_tests([{suites,Node,Dir,Ss}|Ts],Spec) ->
Tests = Spec#testspec.tests,
Tests1 = insert_suites(ref2node(Node,Spec#testspec.nodes),
ref2dir(Dir,Spec#testspec.alias),
- Ss,Tests),
+ Ss,Tests, Spec#testspec.merge_tests),
add_tests(Ts,Spec#testspec{tests=Tests1});
%% --- groups ---
@@ -682,13 +703,15 @@ add_tests([{groups,Node,Dir,Suite,Gs}|Ts],Spec) ->
Tests = Spec#testspec.tests,
Tests1 = insert_groups(ref2node(Node,Spec#testspec.nodes),
ref2dir(Dir,Spec#testspec.alias),
- Suite,Gs,all,Tests),
+ Suite,Gs,all,Tests,
+ Spec#testspec.merge_tests),
add_tests(Ts,Spec#testspec{tests=Tests1});
add_tests([{groups,Node,Dir,Suite,Gs,{cases,TCs}}|Ts],Spec) ->
Tests = Spec#testspec.tests,
Tests1 = insert_groups(ref2node(Node,Spec#testspec.nodes),
ref2dir(Dir,Spec#testspec.alias),
- Suite,Gs,TCs,Tests),
+ Suite,Gs,TCs,Tests,
+ Spec#testspec.merge_tests),
add_tests(Ts,Spec#testspec{tests=Tests1});
%% --- cases ---
@@ -703,7 +726,7 @@ add_tests([{cases,Node,Dir,Suite,Cs}|Ts],Spec) ->
Tests = Spec#testspec.tests,
Tests1 = insert_cases(ref2node(Node,Spec#testspec.nodes),
ref2dir(Dir,Spec#testspec.alias),
- Suite,Cs,Tests),
+ Suite,Cs,Tests, Spec#testspec.merge_tests),
add_tests(Ts,Spec#testspec{tests=Tests1});
%% --- skip_suites ---
@@ -718,7 +741,8 @@ add_tests([{skip_suites,Node,Dir,Ss,Cmt}|Ts],Spec) ->
Tests = Spec#testspec.tests,
Tests1 = skip_suites(ref2node(Node,Spec#testspec.nodes),
ref2dir(Dir,Spec#testspec.alias),
- Ss,Cmt,Tests),
+ Ss,Cmt,Tests,
+ Spec#testspec.merge_tests),
add_tests(Ts,Spec#testspec{tests=Tests1});
%% --- skip_groups ---
@@ -740,13 +764,15 @@ add_tests([{skip_groups,Node,Dir,Suite,Gs,Cmt}|Ts],Spec) ->
Tests = Spec#testspec.tests,
Tests1 = skip_groups(ref2node(Node,Spec#testspec.nodes),
ref2dir(Dir,Spec#testspec.alias),
- Suite,Gs,all,Cmt,Tests),
+ Suite,Gs,all,Cmt,Tests,
+ Spec#testspec.merge_tests),
add_tests(Ts,Spec#testspec{tests=Tests1});
add_tests([{skip_groups,Node,Dir,Suite,Gs,{cases,TCs},Cmt}|Ts],Spec) ->
Tests = Spec#testspec.tests,
Tests1 = skip_groups(ref2node(Node,Spec#testspec.nodes),
ref2dir(Dir,Spec#testspec.alias),
- Suite,Gs,TCs,Cmt,Tests),
+ Suite,Gs,TCs,Cmt,Tests,
+ Spec#testspec.merge_tests),
add_tests(Ts,Spec#testspec{tests=Tests1});
%% --- skip_cases ---
@@ -761,7 +787,7 @@ add_tests([{skip_cases,Node,Dir,Suite,Cs,Cmt}|Ts],Spec) ->
Tests = Spec#testspec.tests,
Tests1 = skip_cases(ref2node(Node,Spec#testspec.nodes),
ref2dir(Dir,Spec#testspec.alias),
- Suite,Cs,Cmt,Tests),
+ Suite,Cs,Cmt,Tests,Spec#testspec.merge_tests),
add_tests(Ts,Spec#testspec{tests=Tests1});
%% --- handled/errors ---
@@ -771,6 +797,9 @@ add_tests([{alias,_,_}|Ts],Spec) -> % handled
add_tests([{node,_,_}|Ts],Spec) -> % handled
add_tests(Ts,Spec);
+add_tests([{merge_tests, _} | Ts], Spec) -> % handled
+ add_tests(Ts,Spec);
+
%% check if it's a CT term that has bad format or if the user seems to
%% have added something of his/her own, which we'll let pass if relaxed
%% mode is enabled.
@@ -823,17 +852,22 @@ separate([],_,_,_) ->
%% {Suite2,[{GrOrCase21,{skip,Cmt}},GrOrCase22,...]},...]}
%% GrOrCase = {GroupName,[Case1,Case2,...]} | Case
-insert_suites(Node,Dir,[S|Ss],Tests) ->
- Tests1 = insert_cases(Node,Dir,S,all,Tests),
- insert_suites(Node,Dir,Ss,Tests1);
-insert_suites(_Node,_Dir,[],Tests) ->
+insert_suites(Node,Dir,[S|Ss],Tests, MergeTests) ->
+ Tests1 = insert_cases(Node,Dir,S,all,Tests,MergeTests),
+ insert_suites(Node,Dir,Ss,Tests1,MergeTests);
+insert_suites(_Node,_Dir,[],Tests,_MergeTests) ->
Tests;
-insert_suites(Node,Dir,S,Tests) ->
- insert_suites(Node,Dir,[S],Tests).
+insert_suites(Node,Dir,S,Tests,MergeTests) ->
+ insert_suites(Node,Dir,[S],Tests,MergeTests).
-insert_groups(Node,Dir,Suite,Group,Cases,Tests) when is_atom(Group) ->
- insert_groups(Node,Dir,Suite,[Group],Cases,Tests);
-insert_groups(Node,Dir,Suite,Groups,Cases,Tests) when
+insert_groups(Node,Dir,Suite,Group,Cases,Tests,MergeTests)
+ when is_atom(Group) ->
+ insert_groups(Node,Dir,Suite,[Group],Cases,Tests,MergeTests);
+insert_groups(Node,Dir,Suite,Groups,Cases,Tests,false) when
+ ((Cases == all) or is_list(Cases)) and is_list(Groups) ->
+ Groups1 = [{Gr,Cases} || Gr <- Groups],
+ append({{Node,Dir},[{Suite,Groups1}]},Tests);
+insert_groups(Node,Dir,Suite,Groups,Cases,Tests,true) when
((Cases == all) or is_list(Cases)) and is_list(Groups) ->
case lists:keysearch({Node,Dir},1,Tests) of
{value,{{Node,Dir},[{all,_}]}} ->
@@ -847,9 +881,10 @@ insert_groups(Node,Dir,Suite,Groups,Cases,Tests) when
Groups1 = [{Gr,Cases} || Gr <- Groups],
insert_in_order({{Node,Dir},[{Suite,Groups1}]},Tests)
end;
-insert_groups(Node,Dir,Suite,Groups,Case,Tests) when is_atom(Case) ->
+insert_groups(Node,Dir,Suite,Groups,Case,Tests, MergeTests)
+ when is_atom(Case) ->
Cases = if Case == all -> all; true -> [Case] end,
- insert_groups(Node,Dir,Suite,Groups,Cases,Tests).
+ insert_groups(Node,Dir,Suite,Groups,Cases,Tests, MergeTests).
insert_groups1(_Suite,_Groups,all) ->
all;
@@ -879,7 +914,9 @@ insert_groups2([Group={GrName,Cases}|Groups],GrAndCases) ->
insert_groups2([],GrAndCases) ->
GrAndCases.
-insert_cases(Node,Dir,Suite,Cases,Tests) when is_list(Cases) ->
+insert_cases(Node,Dir,Suite,Cases,Tests,false) when is_list(Cases) ->
+ append({{Node,Dir},[{Suite,Cases}]},Tests);
+insert_cases(Node,Dir,Suite,Cases,Tests,true) when is_list(Cases) ->
case lists:keysearch({Node,Dir},1,Tests) of
{value,{{Node,Dir},[{all,_}]}} ->
Tests;
@@ -889,8 +926,8 @@ insert_cases(Node,Dir,Suite,Cases,Tests) when is_list(Cases) ->
false ->
insert_in_order({{Node,Dir},[{Suite,Cases}]},Tests)
end;
-insert_cases(Node,Dir,Suite,Case,Tests) when is_atom(Case) ->
- insert_cases(Node,Dir,Suite,[Case],Tests).
+insert_cases(Node,Dir,Suite,Case,Tests,MergeTests) when is_atom(Case) ->
+ insert_cases(Node,Dir,Suite,[Case],Tests,MergeTests).
insert_cases1(_Suite,_Cases,all) ->
all;
@@ -905,22 +942,28 @@ insert_cases1(Suite,Cases,Suites0) ->
insert_in_order({Suite,Cases},Suites0)
end.
-skip_suites(Node,Dir,[S|Ss],Cmt,Tests) ->
- Tests1 = skip_cases(Node,Dir,S,all,Cmt,Tests),
- skip_suites(Node,Dir,Ss,Cmt,Tests1);
-skip_suites(_Node,_Dir,[],_Cmt,Tests) ->
+skip_suites(Node,Dir,[S|Ss],Cmt,Tests,MergeTests) ->
+ Tests1 = skip_cases(Node,Dir,S,all,Cmt,Tests,MergeTests),
+ skip_suites(Node,Dir,Ss,Cmt,Tests1,MergeTests);
+skip_suites(_Node,_Dir,[],_Cmt,Tests,_MergeTests) ->
Tests;
-skip_suites(Node,Dir,S,Cmt,Tests) ->
- skip_suites(Node,Dir,[S],Cmt,Tests).
-
-skip_groups(Node,Dir,Suite,Group,all,Cmt,Tests) when is_atom(Group) ->
- skip_groups(Node,Dir,Suite,[Group],all,Cmt,Tests);
-skip_groups(Node,Dir,Suite,Group,Cases,Cmt,Tests) when is_atom(Group) ->
- skip_groups(Node,Dir,Suite,[Group],Cases,Cmt,Tests);
-skip_groups(Node,Dir,Suite,Groups,Case,Cmt,Tests) when is_atom(Case),
- Case =/= all ->
- skip_groups(Node,Dir,Suite,Groups,[Case],Cmt,Tests);
-skip_groups(Node,Dir,Suite,Groups,Cases,Cmt,Tests) when
+skip_suites(Node,Dir,S,Cmt,Tests,MergeTests) ->
+ skip_suites(Node,Dir,[S],Cmt,Tests,MergeTests).
+
+skip_groups(Node,Dir,Suite,Group,all,Cmt,Tests,MergeTests)
+ when is_atom(Group) ->
+ skip_groups(Node,Dir,Suite,[Group],all,Cmt,Tests,MergeTests);
+skip_groups(Node,Dir,Suite,Group,Cases,Cmt,Tests,MergeTests)
+ when is_atom(Group) ->
+ skip_groups(Node,Dir,Suite,[Group],Cases,Cmt,Tests,MergeTests);
+skip_groups(Node,Dir,Suite,Groups,Case,Cmt,Tests,MergeTests)
+ when is_atom(Case),Case =/= all ->
+ skip_groups(Node,Dir,Suite,Groups,[Case],Cmt,Tests,MergeTests);
+skip_groups(Node,Dir,Suite,Groups,Cases,Cmt,Tests,false) when
+ ((Cases == all) or is_list(Cases)) and is_list(Groups) ->
+ Suites1 = skip_groups1(Suite,[{Gr,Cases} || Gr <- Groups],Cmt,[]),
+ append({{Node,Dir},Suites1},Tests);
+skip_groups(Node,Dir,Suite,Groups,Cases,Cmt,Tests,true) when
((Cases == all) or is_list(Cases)) and is_list(Groups) ->
Suites =
case lists:keysearch({Node,Dir},1,Tests) of
@@ -931,9 +974,10 @@ skip_groups(Node,Dir,Suite,Groups,Cases,Cmt,Tests) when
end,
Suites1 = skip_groups1(Suite,[{Gr,Cases} || Gr <- Groups],Cmt,Suites),
insert_in_order({{Node,Dir},Suites1},Tests);
-skip_groups(Node,Dir,Suite,Groups,Case,Cmt,Tests) when is_atom(Case) ->
+skip_groups(Node,Dir,Suite,Groups,Case,Cmt,Tests,MergeTests)
+ when is_atom(Case) ->
Cases = if Case == all -> all; true -> [Case] end,
- skip_groups(Node,Dir,Suite,Groups,Cases,Cmt,Tests).
+ skip_groups(Node,Dir,Suite,Groups,Cases,Cmt,Tests,MergeTests).
skip_groups1(Suite,Groups,Cmt,Suites0) ->
SkipGroups = lists:map(fun(Group) ->
@@ -947,7 +991,10 @@ skip_groups1(Suite,Groups,Cmt,Suites0) ->
insert_in_order({Suite,SkipGroups},Suites0)
end.
-skip_cases(Node,Dir,Suite,Cases,Cmt,Tests) when is_list(Cases) ->
+skip_cases(Node,Dir,Suite,Cases,Cmt,Tests,false) when is_list(Cases) ->
+ Suites1 = skip_cases1(Suite,Cases,Cmt,[]),
+ append({{Node,Dir},Suites1},Tests);
+skip_cases(Node,Dir,Suite,Cases,Cmt,Tests,true) when is_list(Cases) ->
Suites =
case lists:keysearch({Node,Dir},1,Tests) of
{value,{{Node,Dir},Suites0}} ->
@@ -957,8 +1004,8 @@ skip_cases(Node,Dir,Suite,Cases,Cmt,Tests) when is_list(Cases) ->
end,
Suites1 = skip_cases1(Suite,Cases,Cmt,Suites),
insert_in_order({{Node,Dir},Suites1},Tests);
-skip_cases(Node,Dir,Suite,Case,Cmt,Tests) when is_atom(Case) ->
- skip_cases(Node,Dir,Suite,[Case],Cmt,Tests).
+skip_cases(Node,Dir,Suite,Case,Cmt,Tests,MergeTests) when is_atom(Case) ->
+ skip_cases(Node,Dir,Suite,[Case],Cmt,Tests,MergeTests).
skip_cases1(Suite,Cases,Cmt,Suites0) ->
SkipCases = lists:map(fun(C) ->
@@ -972,6 +1019,9 @@ skip_cases1(Suite,Cases,Cmt,Suites0) ->
insert_in_order({Suite,SkipCases},Suites0)
end.
+append(Elem, List) ->
+ List ++ [Elem].
+
insert_in_order([E|Es],List) ->
List1 = insert_elem(E,List,[]),
insert_in_order(Es,List1);
@@ -1044,6 +1094,7 @@ valid_terms() ->
{userconfig,2},
{userconfig,3},
{alias,3},
+ {merge_tests,1},
{logdir,2},
{logdir,3},
{label,2},
@@ -1051,6 +1102,8 @@ valid_terms() ->
{event_handler,2},
{event_handler,3},
{event_handler,4},
+ {ct_hooks,2},
+ {ct_hooks,3},
{multiply_timetraps,2},
{multiply_timetraps,3},
{scale_timetraps,2},
diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl
index 0a434666fa..0476e1599f 100644
--- a/lib/common_test/src/ct_util.erl
+++ b/lib/common_test/src/ct_util.erl
@@ -32,7 +32,9 @@
-export([close_connections/0]).
--export([save_suite_data/3, save_suite_data/2, read_suite_data/1,
+-export([save_suite_data/3, save_suite_data/2,
+ save_suite_data_async/3, save_suite_data_async/2,
+ read_suite_data/1,
delete_suite_data/0, delete_suite_data/1, match_delete_suite_data/1,
delete_testdata/0, delete_testdata/1, set_testdata/1, get_testdata/1,
update_testdata/2]).
@@ -159,6 +161,17 @@ do_start(Parent,Mode,LogDir) ->
ok
end,
{StartTime,TestLogDir} = ct_logs:init(Mode),
+
+ %% Initiate ct_hooks
+ case catch ct_hooks:init(Opts) of
+ ok ->
+ ok;
+ {_,CTHReason} ->
+ ct_logs:tc_print('Suite Callback',CTHReason,[]),
+ Parent ! {self(), CTHReason},
+ self() ! {{stop,normal},{self(),make_ref()}}
+ end,
+
ct_event:notify(#event{name=test_start,
node=node(),
data={StartTime,
@@ -182,12 +195,19 @@ read_opts() ->
{error,{bad_installation,Error}}
end.
+
save_suite_data(Key, Value) ->
call({save_suite_data, {Key, undefined, Value}}).
save_suite_data(Key, Name, Value) ->
call({save_suite_data, {Key, Name, Value}}).
+save_suite_data_async(Key, Value) ->
+ save_suite_data_async(Key, undefined, Value).
+
+save_suite_data_async(Key, Name, Value) ->
+ cast({save_suite_data, {Key, Name, Value}}).
+
read_suite_data(Key) ->
call({read_suite_data, Key}).
@@ -268,6 +288,9 @@ loop(Mode,TestData,StartDir) ->
TestData1 = lists:keydelete(Key,1,TestData),
return(From,ok),
loop(Mode,[New|TestData1],StartDir);
+ {{get_testdata, all}, From} ->
+ return(From, TestData),
+ loop(From, TestData, StartDir);
{{get_testdata,Key},From} ->
case lists:keysearch(Key,1,TestData) of
{value,{Key,Val}} ->
@@ -299,6 +322,10 @@ loop(Mode,TestData,StartDir) ->
ct_event:sync_notify(#event{name=test_done,
node=node(),
data=Time}),
+ Callbacks = ets:lookup_element(?suite_table,
+ ct_hooks,
+ #suite_data.value),
+ ct_hooks:terminate(Callbacks),
close_connections(ets:tab2list(?conn_table)),
ets:delete(?conn_table),
ets:delete(?board_table),
@@ -308,6 +335,9 @@ loop(Mode,TestData,StartDir) ->
ct_config:stop(),
file:set_cwd(StartDir),
return(From,ok);
+ {Ref, _Msg} when is_reference(Ref) ->
+ %% This clause is used when doing cast operations.
+ loop(Mode,TestData,StartDir);
{get_mode,From} ->
return(From,Mode),
loop(Mode,TestData,StartDir);
@@ -556,10 +586,37 @@ listenv(Telnet) ->
%%% @hidden
%%% @equiv ct:parse_table/1
parse_table(Data) ->
- [Heading|Lines]=
- [remove_space(string:tokens(L, "|"),[]) || L <- Data, hd(L)==$|],
+ {Heading, Rest} = get_headings(Data),
+ Lines = parse_row(Rest,[],size(Heading)),
{Heading,Lines}.
+get_headings(["|" ++ Headings | Rest]) ->
+ {remove_space(string:tokens(Headings, "|"),[]), Rest};
+get_headings([_ | Rest]) ->
+ get_headings(Rest);
+get_headings([]) ->
+ {{},[]}.
+
+parse_row(["|" ++ _ = Row | T], Rows, NumCols) when NumCols > 1 ->
+ case string:tokens(Row, "|") of
+ Values when length(Values) =:= NumCols ->
+ parse_row(T,[remove_space(Values,[])|Rows], NumCols);
+ Values when length(Values) < NumCols ->
+ parse_row([Row ++"\n"++ hd(T) | tl(T)], Rows, NumCols)
+ end;
+parse_row(["|" ++ _ = Row | T], Rows, 1 = NumCols) ->
+ case string:rchr(Row, $|) of
+ 1 ->
+ parse_row([Row ++"\n"++hd(T) | tl(T)], Rows, NumCols);
+ _Else ->
+ parse_row(T, [remove_space(string:tokens(Row,"|"),[])|Rows],
+ NumCols)
+ end;
+parse_row([_Skip | T], Rows, NumCols) ->
+ parse_row(T, Rows, NumCols);
+parse_row([], Rows, _NumCols) ->
+ lists:reverse(Rows).
+
remove_space([Str|Rest],Acc) ->
remove_space(Rest,[string:strip(string:strip(Str),both,$')|Acc]);
remove_space([],Acc) ->
@@ -686,6 +743,9 @@ call(Msg) ->
return({To,Ref},Result) ->
To ! {Ref, Result}.
+cast(Msg) ->
+ ct_util_server ! {Msg, {ct_util_server, make_ref()}}.
+
seconds(T) ->
test_server:seconds(T).
diff --git a/lib/common_test/src/ct_util.hrl b/lib/common_test/src/ct_util.hrl
index ee973f6220..f0255c533c 100644
--- a/lib/common_test/src/ct_util.hrl
+++ b/lib/common_test/src/ct_util.hrl
@@ -36,11 +36,13 @@
config=[],
userconfig=[],
event_handler=[],
+ ct_hooks=[],
include=[],
multiply_timetraps=[],
scale_timetraps=[],
alias=[],
- tests=[]}).
+ tests=[],
+ merge_tests = true }).
-record(cover, {app=none,
level=details,
diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile
index f2fe3390cf..be4b4c32b8 100644
--- a/lib/common_test/test/Makefile
+++ b/lib/common_test/test/Makefile
@@ -40,7 +40,8 @@ MODULES= \
ct_test_server_if_1_SUITE \
ct_config_SUITE \
ct_master_SUITE \
- ct_misc_1_SUITE
+ ct_misc_1_SUITE \
+ ct_hooks_SUITE
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/common_test/test/common_test.spec b/lib/common_test/test/common_test.spec
index 7619a75b31..8755b08117 100644
--- a/lib/common_test/test/common_test.spec
+++ b/lib/common_test/test/common_test.spec
@@ -1 +1 @@
-{topcase, {dir, "../common_test"}}.
+{suites,"../common_test_test",all}. \ No newline at end of file
diff --git a/lib/common_test/test/ct_config_SUITE.erl b/lib/common_test/test/ct_config_SUITE.erl
index fc15abc5bc..2ddc7d6422 100644
--- a/lib/common_test/test/ct_config_SUITE.erl
+++ b/lib/common_test/test/ct_config_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
@@ -64,19 +64,22 @@ end_per_testcase(install_config = TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- [""];
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [require, install_config, userconfig_static,
+ userconfig_dynamic, testspec_legacy, testspec_static,
+ testspec_dynamic].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [
- require,
- install_config,
- userconfig_static,
- userconfig_dynamic,
- testspec_legacy,
- testspec_static,
- testspec_dynamic
- ].
%%--------------------------------------------------------------------
%% TEST CASES
@@ -199,74 +202,74 @@ events_to_check(Test, N) ->
expected_events(Test) ++ events_to_check(Test, N-1).
expected_events(config_static_SUITE)->
-[
- {?eh,start_logging,{'DEF','RUNDIR'}},
- {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
- {?eh,start_info,{1,1,8}},
- {?eh,tc_start,{config_static_SUITE,init_per_suite}},
- {?eh,tc_done,{config_static_SUITE,init_per_suite,ok}},
- {?eh,tc_start,{config_static_SUITE,test_get_config_simple}},
- {?eh,tc_done,{config_static_SUITE,test_get_config_simple,ok}},
- {?eh,test_stats,{1,0,{0,0}}},
- {?eh,tc_start,{config_static_SUITE,test_get_config_nested}},
- {?eh,tc_done,{config_static_SUITE,test_get_config_nested,ok}},
- {?eh,test_stats,{2,0,{0,0}}},
- {?eh,tc_start,{config_static_SUITE,test_default_suitewide}},
- {?eh,tc_done,{config_static_SUITE,test_default_suitewide,ok}},
- {?eh,test_stats,{3,0,{0,0}}},
- {?eh,tc_start,{config_static_SUITE,test_config_name_already_in_use1}},
- {?eh,tc_done,
- {config_static_SUITE,test_config_name_already_in_use1,{skipped,{config_name_already_in_use,[x1]}}}},
- {?eh,test_stats,{3,0,{1,0}}},
- {?eh,tc_start,{config_static_SUITE,test_default_tclocal}},
- {?eh,tc_done,{config_static_SUITE,test_default_tclocal,ok}},
- {?eh,test_stats,{4,0,{1,0}}},
- {?eh,tc_start,{config_static_SUITE,test_config_name_already_in_use2}},
- {?eh,tc_done,
- {config_static_SUITE,test_config_name_already_in_use2,
- {skipped,{config_name_already_in_use,[x1,alias]}}}},
- {?eh,test_stats,{4,0,{2,0}}},
- {?eh,tc_start,{config_static_SUITE,test_alias_tclocal}},
- {?eh,tc_done,{config_static_SUITE,test_alias_tclocal,ok}},
- {?eh,test_stats,{5,0,{2,0}}},
- {?eh,tc_start,{config_static_SUITE,test_get_config_undefined}},
- {?eh,tc_done,{config_static_SUITE,test_get_config_undefined,ok}},
- {?eh,test_stats,{6,0,{2,0}}},
- {?eh,tc_start,{config_static_SUITE,end_per_suite}},
- {?eh,tc_done,{config_static_SUITE,end_per_suite,ok}},
- {?eh,test_done,{'DEF','STOP_TIME'}},
- {?eh,stop_logging,[]}
-];
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,8}},
+ {?eh,tc_start,{config_static_SUITE,init_per_suite}},
+ {?eh,tc_done,{config_static_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{config_static_SUITE,test_get_config_simple}},
+ {?eh,tc_done,{config_static_SUITE,test_get_config_simple,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{config_static_SUITE,test_get_config_nested}},
+ {?eh,tc_done,{config_static_SUITE,test_get_config_nested,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{config_static_SUITE,test_default_suitewide}},
+ {?eh,tc_done,{config_static_SUITE,test_default_suitewide,ok}},
+ {?eh,test_stats,{3,0,{0,0}}},
+ {?eh,tc_start,{config_static_SUITE,test_config_name_already_in_use1}},
+ {?eh,tc_done,
+ {config_static_SUITE,test_config_name_already_in_use1,{skipped,{config_name_already_in_use,[x1]}}}},
+ {?eh,test_stats,{3,0,{1,0}}},
+ {?eh,tc_start,{config_static_SUITE,test_default_tclocal}},
+ {?eh,tc_done,{config_static_SUITE,test_default_tclocal,ok}},
+ {?eh,test_stats,{4,0,{1,0}}},
+ {?eh,tc_start,{config_static_SUITE,test_config_name_already_in_use2}},
+ {?eh,tc_done,
+ {config_static_SUITE,test_config_name_already_in_use2,
+ {skipped,{config_name_already_in_use,[x1,alias]}}}},
+ {?eh,test_stats,{4,0,{2,0}}},
+ {?eh,tc_start,{config_static_SUITE,test_alias_tclocal}},
+ {?eh,tc_done,{config_static_SUITE,test_alias_tclocal,ok}},
+ {?eh,test_stats,{5,0,{2,0}}},
+ {?eh,tc_start,{config_static_SUITE,test_get_config_undefined}},
+ {?eh,tc_done,{config_static_SUITE,test_get_config_undefined,ok}},
+ {?eh,test_stats,{6,0,{2,0}}},
+ {?eh,tc_start,{config_static_SUITE,end_per_suite}},
+ {?eh,tc_done,{config_static_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
expected_events(config_dynamic_SUITE)->
-[
- {?eh,start_logging,{'DEF','RUNDIR'}},
- {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
- {?eh,start_info,{1,1,5}},
- {?eh,tc_start,{config_dynamic_SUITE,init_per_suite}},
- {?eh,tc_done,{config_dynamic_SUITE,init_per_suite,ok}},
- {?eh,tc_start,{config_dynamic_SUITE,test_get_known_variable}},
- {?eh,tc_done,
- {config_dynamic_SUITE,test_get_known_variable,ok}},
- {?eh,test_stats,{1,0,{0,0}}},
- {?eh,tc_start,{config_dynamic_SUITE,test_localtime_update}},
- {?eh,tc_done,{config_dynamic_SUITE,test_localtime_update,ok}},
- {?eh,test_stats,{2,0,{0,0}}},
- {?eh,tc_start,{config_dynamic_SUITE,test_server_pid}},
- {?eh,tc_done,{config_dynamic_SUITE,test_server_pid,ok}},
- {?eh,test_stats,{3,0,{0,0}}},
- {?eh,tc_start,
- {config_dynamic_SUITE,test_disappearable_variable}},
- {?eh,tc_done,
- {config_dynamic_SUITE,test_disappearable_variable,ok}},
- {?eh,test_stats,{4,0,{0,0}}},
- {?eh,tc_start,
- {config_dynamic_SUITE,test_disappearable_variable_alias}},
- {?eh,tc_done,
- {config_dynamic_SUITE,test_disappearable_variable_alias,ok}},
- {?eh,test_stats,{5,0,{0,0}}},
- {?eh,tc_start,{config_dynamic_SUITE,end_per_suite}},
- {?eh,tc_done,{config_dynamic_SUITE,end_per_suite,ok}},
- {?eh,test_done,{'DEF','STOP_TIME'}},
- {?eh,stop_logging,[]}
-].
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,start_info,{1,1,5}},
+ {?eh,tc_start,{config_dynamic_SUITE,init_per_suite}},
+ {?eh,tc_done,{config_dynamic_SUITE,init_per_suite,ok}},
+ {?eh,tc_start,{config_dynamic_SUITE,test_get_known_variable}},
+ {?eh,tc_done,
+ {config_dynamic_SUITE,test_get_known_variable,ok}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{config_dynamic_SUITE,test_localtime_update}},
+ {?eh,tc_done,{config_dynamic_SUITE,test_localtime_update,ok}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,{config_dynamic_SUITE,test_server_pid}},
+ {?eh,tc_done,{config_dynamic_SUITE,test_server_pid,ok}},
+ {?eh,test_stats,{3,0,{0,0}}},
+ {?eh,tc_start,
+ {config_dynamic_SUITE,test_disappearable_variable}},
+ {?eh,tc_done,
+ {config_dynamic_SUITE,test_disappearable_variable,ok}},
+ {?eh,test_stats,{4,0,{0,0}}},
+ {?eh,tc_start,
+ {config_dynamic_SUITE,test_disappearable_variable_alias}},
+ {?eh,tc_done,
+ {config_dynamic_SUITE,test_disappearable_variable_alias,ok}},
+ {?eh,test_stats,{5,0,{0,0}}},
+ {?eh,tc_start,{config_dynamic_SUITE,end_per_suite}},
+ {?eh,tc_done,{config_dynamic_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ].
diff --git a/lib/common_test/test/ct_error_SUITE.erl b/lib/common_test/test/ct_error_SUITE.erl
index 2fa031b884..17faf5ee3f 100644
--- a/lib/common_test/test/ct_error_SUITE.erl
+++ b/lib/common_test/test/ct_error_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
@@ -56,19 +56,22 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- [""];
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [cfg_error, lib_error, no_compile, timetrap_end_conf,
+ timetrap_normal, timetrap_extended].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-all(suite) ->
- [
- cfg_error,
- lib_error,
- no_compile,
- timetrap_end_conf,
- timetrap_normal,
- timetrap_extended
- ].
-
%%--------------------------------------------------------------------
%% TEST CASES
@@ -122,7 +125,7 @@ lib_error(Config) when is_list(Config) ->
TestEvents = events_to_check(lib_error),
ok = ct_test_support:verify_events(TestEvents, Events, Config).
-
+
%%%-----------------------------------------------------------------
%%%
@@ -140,7 +143,7 @@ no_compile(Config) when is_list(Config) ->
TestEvents = events_to_check(no_compile),
ok = ct_test_support:verify_events(TestEvents, Events, Config).
-
+
%%%-----------------------------------------------------------------
%%%
timetrap_end_conf(Config) when is_list(Config) ->
@@ -214,8 +217,8 @@ setup(Test, Config) ->
reformat(Events, EH) ->
ct_test_support:reformat(Events, EH).
-%reformat(Events, _EH) ->
-% Events.
+ %reformat(Events, _EH) ->
+ % Events.
%%%-----------------------------------------------------------------
%%% TEST EVENTS
@@ -248,7 +251,7 @@ test_events(cfg_error) ->
{?eh,test_stats,{0,0,{0,2}}},
{?eh,tc_auto_skip,
{cfg_error_1_SUITE,end_per_suite,{failed,{cfg_error_1_SUITE,init_per_suite,
- {'EXIT',init_per_suite_fails}}}}},
+ {'EXIT',init_per_suite_fails}}}}},
{?eh,tc_start,{cfg_error_2_SUITE,init_per_suite}},
{?eh,tc_done,
@@ -378,12 +381,12 @@ test_events(cfg_error) ->
{?eh,tc_auto_skip,
{cfg_error_8_SUITE,tc1,
{failed,{cfg_error_8_SUITE,init_per_group,
- {'EXIT',{init_per_group_fails,g1}}}}}},
+ {'EXIT',{init_per_group_fails,g1}}}}}},
{?eh,test_stats,{4,0,{0,11}}},
{?eh,tc_auto_skip,
{cfg_error_8_SUITE,end_per_group,
{failed,{cfg_error_8_SUITE,init_per_group,
- {'EXIT',{init_per_group_fails,g1}}}}}}],
+ {'EXIT',{init_per_group_fails,g1}}}}}}],
[{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g2,[]}}},
{?eh,tc_done,{cfg_error_8_SUITE,
@@ -396,7 +399,7 @@ test_events(cfg_error) ->
{?eh,tc_auto_skip,{cfg_error_8_SUITE,end_per_group,
{failed,{cfg_error_8_SUITE,init_per_group,
{timetrap_timeout,2000}}}}}],
-
+
[{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g3,[]}}},
{?eh,tc_done,
{cfg_error_8_SUITE,{init_per_group,g3,[]},
@@ -436,7 +439,7 @@ test_events(cfg_error) ->
{?eh,test_stats,{5,0,{0,13}}},
{?eh,tc_start,{cfg_error_8_SUITE,{end_per_group,g4,[]}}},
{?eh,tc_done,{cfg_error_8_SUITE,{end_per_group,g4,[]},ok}}],
-
+
[{?eh,tc_start,{cfg_error_8_SUITE,{init_per_group,g5,[]}}},
{?eh,tc_done,{cfg_error_8_SUITE,{init_per_group,g5,[]},ok}},
{?eh,tc_start,{cfg_error_8_SUITE,tc1}},
diff --git a/lib/common_test/test/ct_event_handler_SUITE.erl b/lib/common_test/test/ct_event_handler_SUITE.erl
index 00a4c4ded3..b27770881d 100644
--- a/lib/common_test/test/ct_event_handler_SUITE.erl
+++ b/lib/common_test/test/ct_event_handler_SUITE.erl
@@ -28,7 +28,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
%-include_lib("common_test/include/ct_event.hrl").
@@ -56,12 +56,21 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- [];
+suite() -> [{ct_hooks,[ts_install_cth]}].
-all(suite) ->
+all() ->
[start_stop, results].
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%--------------------------------------------------------------------
%% TEST CASES
diff --git a/lib/common_test/test/ct_groups_test_1_SUITE.erl b/lib/common_test/test/ct_groups_test_1_SUITE.erl
index 64d61fc104..3712bc0e33 100644
--- a/lib/common_test/test/ct_groups_test_1_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_1_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
@@ -56,12 +56,21 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- ["Run smoke tests of Common Test."];
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [groups_suite_1, groups_suite_2, groups_suites_1,
+ groups_dir_1, groups_dirs_1].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [groups_suite_1, groups_suite_2,
- groups_suites_1, groups_dir_1, groups_dirs_1].
%%--------------------------------------------------------------------
%% TEST CASES
diff --git a/lib/common_test/test/ct_groups_test_2_SUITE.erl b/lib/common_test/test/ct_groups_test_2_SUITE.erl
index c4371501b3..32e8d0c6d7 100644
--- a/lib/common_test/test/ct_groups_test_2_SUITE.erl
+++ b/lib/common_test/test/ct_groups_test_2_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
@@ -56,12 +56,21 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- ["Run smoke tests of Common Test."];
+suite() -> [{ct_hooks,[ts_install_cth]}].
-all(suite) ->
+all() ->
[missing_conf, repeat_1].
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%--------------------------------------------------------------------
%% TEST CASES
%%--------------------------------------------------------------------
diff --git a/lib/common_test/test/ct_hooks_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE.erl
new file mode 100644
index 0000000000..1e187aa205
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE.erl
@@ -0,0 +1,1021 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File: ct_error_SUITE
+%%%
+%%% Description:
+%%% Test various errors in Common Test suites.
+%%%
+%%% The suites used for the test are located in the data directory.
+%%%-------------------------------------------------------------------
+-module(ct_hooks_SUITE).
+
+-compile(export_all).
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-define(eh, ct_test_support_eh).
+
+%%--------------------------------------------------------------------
+%% TEST SERVER CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Description: Since Common Test starts another Test Server
+%% instance, the tests need to be performed on a separate node (or
+%% there will be clashes with logging processes etc).
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ DataDir = ?config(data_dir, Config),
+ TestDir = filename:join(DataDir,"cth/tests/"),
+ CTHs = filelib:wildcard(filename:join(TestDir,"*_cth.erl")),
+ io:format("CTHs: ~p",[CTHs]),
+ [io:format("Compiling ~p: ~p",
+ [FileName,compile:file(FileName,[{outdir,TestDir},debug_info])]) ||
+ FileName <- CTHs],
+ ct_test_support:init_per_suite([{path_dirs,[TestDir]} | Config]).
+
+end_per_suite(Config) ->
+ ct_test_support:end_per_suite(Config).
+
+init_per_testcase(TestCase, Config) ->
+ ct_test_support:init_per_testcase(TestCase, Config).
+
+end_per_testcase(TestCase, Config) ->
+ ct_test_support:end_per_testcase(TestCase, Config).
+
+
+suite() ->
+ [{timetrap,{seconds,20}}].
+
+all() ->
+ all(suite).
+
+all(suite) ->
+ lists:reverse(
+ [
+ one_cth, two_cth, faulty_cth_no_init, faulty_cth_id_no_init,
+ faulty_cth_exit_in_init, faulty_cth_exit_in_id,
+ faulty_cth_exit_in_init_scope_suite, minimal_cth,
+ minimal_and_maximal_cth, faulty_cth_undef,
+ scope_per_suite_cth, scope_per_group_cth, scope_suite_cth,
+ scope_per_suite_state_cth, scope_per_group_state_cth,
+ scope_suite_state_cth,
+ fail_pre_suite_cth, fail_post_suite_cth, skip_pre_suite_cth,
+ skip_post_suite_cth, recover_post_suite_cth, update_config_cth,
+ state_update_cth, options_cth, same_id_cth,
+ fail_n_skip_with_minimal_cth
+ ]
+ )
+ .
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+
+%%%-----------------------------------------------------------------
+%%%
+one_cth(Config) when is_list(Config) ->
+ do_test(one_empty_cth, "ct_cth_empty_SUITE.erl",[empty_cth], Config).
+
+two_cth(Config) when is_list(Config) ->
+ do_test(two_empty_cth, "ct_cth_empty_SUITE.erl",[empty_cth,empty_cth],
+ Config).
+
+faulty_cth_no_init(Config) when is_list(Config) ->
+ do_test(faulty_cth_no_init, "ct_cth_empty_SUITE.erl",[askjhdkljashdkaj],
+ Config,{error,"Failed to start CTH, see the "
+ "CT Log for details"}).
+
+faulty_cth_id_no_init(Config) when is_list(Config) ->
+ do_test(faulty_cth_id_no_init, "ct_cth_empty_SUITE.erl",[id_no_init_cth],
+ Config,{error,"Failed to start CTH, see the "
+ "CT Log for details"}).
+
+minimal_cth(Config) when is_list(Config) ->
+ do_test(minimal_cth, "ct_cth_empty_SUITE.erl",[minimal_cth],Config).
+
+minimal_and_maximal_cth(Config) when is_list(Config) ->
+ do_test(minimal_and_maximal_cth, "ct_cth_empty_SUITE.erl",
+ [minimal_cth, empty_cth],Config).
+
+faulty_cth_undef(Config) when is_list(Config) ->
+ do_test(faulty_cth_undef, "ct_cth_empty_SUITE.erl",
+ [undef_cth],Config).
+
+faulty_cth_exit_in_init_scope_suite(Config) when is_list(Config) ->
+ do_test(faulty_cth_exit_in_init_scope_suite,
+ "ct_exit_in_init_scope_suite_cth_SUITE.erl",
+ [],Config).
+
+faulty_cth_exit_in_init(Config) when is_list(Config) ->
+ do_test(faulty_cth_exit_in_init, "ct_cth_empty_SUITE.erl",
+ [crash_init_cth], Config,
+ {error,"Failed to start CTH, see the "
+ "CT Log for details"}).
+
+faulty_cth_exit_in_id(Config) when is_list(Config) ->
+ do_test(faulty_cth_exit_in_id, "ct_cth_empty_SUITE.erl",
+ [crash_id_cth], Config,
+ {error,"Failed to start CTH, see the "
+ "CT Log for details"}).
+
+scope_per_suite_cth(Config) when is_list(Config) ->
+ do_test(scope_per_suite_cth, "ct_scope_per_suite_cth_SUITE.erl",
+ [],Config).
+
+scope_suite_cth(Config) when is_list(Config) ->
+ do_test(scope_suite_cth, "ct_scope_suite_cth_SUITE.erl",
+ [],Config).
+
+scope_per_group_cth(Config) when is_list(Config) ->
+ do_test(scope_per_group_cth, "ct_scope_per_group_cth_SUITE.erl",
+ [],Config).
+
+scope_per_suite_state_cth(Config) when is_list(Config) ->
+ do_test(scope_per_suite_state_cth, "ct_scope_per_suite_state_cth_SUITE.erl",
+ [],Config).
+
+scope_suite_state_cth(Config) when is_list(Config) ->
+ do_test(scope_suite_state_cth, "ct_scope_suite_state_cth_SUITE.erl",
+ [],Config).
+
+scope_per_group_state_cth(Config) when is_list(Config) ->
+ do_test(scope_per_group_state_cth, "ct_scope_per_group_state_cth_SUITE.erl",
+ [],Config).
+
+fail_pre_suite_cth(Config) when is_list(Config) ->
+ do_test(fail_pre_suite_cth, "ct_cth_empty_SUITE.erl",
+ [fail_pre_suite_cth],Config).
+
+fail_post_suite_cth(Config) when is_list(Config) ->
+ do_test(fail_post_suite_cth, "ct_cth_empty_SUITE.erl",
+ [fail_post_suite_cth],Config).
+
+skip_pre_suite_cth(Config) when is_list(Config) ->
+ do_test(skip_pre_suite_cth, "ct_cth_empty_SUITE.erl",
+ [skip_pre_suite_cth],Config).
+
+skip_post_suite_cth(Config) when is_list(Config) ->
+ do_test(skip_post_suite_cth, "ct_cth_empty_SUITE.erl",
+ [skip_post_suite_cth],Config).
+
+recover_post_suite_cth(Config) when is_list(Config) ->
+ do_test(recover_post_suite_cth, "ct_cth_fail_per_suite_SUITE.erl",
+ [recover_post_suite_cth],Config).
+
+update_config_cth(Config) when is_list(Config) ->
+ do_test(update_config_cth, "ct_update_config_SUITE.erl",
+ [update_config_cth],Config).
+
+state_update_cth(Config) when is_list(Config) ->
+ do_test(state_update_cth, "ct_cth_fail_one_skip_one_SUITE.erl",
+ [state_update_cth,state_update_cth],Config).
+
+options_cth(Config) when is_list(Config) ->
+ do_test(options_cth, "ct_cth_empty_SUITE.erl",
+ [{empty_cth,[test]}],Config).
+
+same_id_cth(Config) when is_list(Config) ->
+ do_test(same_id_cth, "ct_cth_empty_SUITE.erl",
+ [same_id_cth,same_id_cth],Config).
+
+fail_n_skip_with_minimal_cth(Config) when is_list(Config) ->
+ do_test(fail_n_skip_with_minimal_cth, "ct_cth_fail_one_skip_one_SUITE.erl",
+ [minimal_terminate_cth],Config).
+
+%%%-----------------------------------------------------------------
+%%% HELP FUNCTIONS
+%%%-----------------------------------------------------------------
+
+do_test(Tag, SWC, CTHs, Config) ->
+ do_test(Tag, SWC, CTHs, Config, ok).
+do_test(Tag, SWC, CTHs, Config, {error,_} = Res) ->
+ do_test(Tag, SWC, CTHs, Config, Res, 1);
+do_test(Tag, SWC, CTHs, Config, Res) ->
+ do_test(Tag, SWC, CTHs, Config, Res, 2).
+
+do_test(Tag, SuiteWildCard, CTHs, Config, Res, EC) ->
+
+ DataDir = ?config(data_dir, Config),
+ Suites = filelib:wildcard(
+ filename:join([DataDir,"cth/tests",SuiteWildCard])),
+ {Opts,ERPid} = setup([{suite,Suites},
+ {ct_hooks,CTHs},{label,Tag}], Config),
+ Res = ct_test_support:run(Opts, Config),
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(Tag,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+
+ TestEvents = events_to_check(Tag, EC),
+ ok = ct_test_support:verify_events(TestEvents, Events, Config).
+
+setup(Test, Config) ->
+ Opts0 = ct_test_support:get_opts(Config),
+ Level = ?config(trace_level, Config),
+ EvHArgs = [{cbm,ct_test_support},{trace_level,Level}],
+ Opts = Opts0 ++ [{event_handler,{?eh,EvHArgs}}|Test],
+ ERPid = ct_test_support:start_event_receiver(Config),
+ {Opts,ERPid}.
+
+reformat(Events, EH) ->
+ ct_test_support:reformat(Events, EH).
+%reformat(Events, _EH) ->
+% Events.
+
+%%%-----------------------------------------------------------------
+%%% TEST EVENTS
+%%%-----------------------------------------------------------------
+events_to_check(Test) ->
+ %% 2 tests (ct:run_test + script_start) is default
+ events_to_check(Test, 2).
+
+events_to_check(_, 0) ->
+ [];
+events_to_check(Test, N) ->
+ test_events(Test) ++ events_to_check(Test, N-1).
+
+test_events(one_empty_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{empty_cth,id,[[]]}},
+ {?eh,cth,{empty_cth,init,[{'_','_','_'},[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,
+ [ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,[test_case,'$proplist','_',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,
+ [ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(two_empty_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',id,[[]]}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,cth,{'_',id,[[]]}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
+ {?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}},
+ {?eh,cth,{'_',post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{'_',terminate,[[]]}},
+ {?eh,cth,{'_',terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(faulty_cth_no_init) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(faulty_cth_id_no_init) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',id,[[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {negative,{?eh,tc_start,'_'},
+ {?eh,test_done,{'DEF','STOP_TIME'}}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(minimal_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {negative,{?eh,cth,{'_',id,['_',[]]}},
+ {?eh,cth,{'_',init,['_',[]]}}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(minimal_and_maximal_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {negative,{?eh,cth,{'_',id,['_',[]]}},
+ {?eh,cth,{'_',init,['_',[]]}}},
+ {?eh,cth,{'_',id,[[]]}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
+ {?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{'_',terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(faulty_cth_undef) ->
+ FailReasonStr = "undef_cth:pre_init_per_suite/3 CTH call failed",
+ FailReason = {ct_cth_empty_SUITE,init_per_suite,
+ {failed,FailReasonStr}},
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,
+ {failed, {error,FailReasonStr}}}},
+ {?eh,cth,{'_',on_tc_fail,'_'}},
+
+ {?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,
+ {failed, FailReason}}},
+ {?eh,cth,{'_',on_tc_skip,'_'}},
+
+ {?eh,tc_auto_skip,{ct_cth_empty_SUITE,end_per_suite,
+ {failed, FailReason}}},
+ {?eh,cth,{'_',on_tc_skip,'_'}},
+
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(faulty_cth_exit_in_init_scope_suite) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{'_',init_per_suite}},
+ {?eh,cth,{empty_cth,init,['_',[]]}},
+ {?eh,tc_done,
+ {ct_exit_in_init_scope_suite_cth_SUITE,init_per_suite,
+ {failed,
+ {error,
+ "Failed to start CTH, see the CT Log for details"}}}},
+ {?eh,tc_auto_skip,
+ {ct_exit_in_init_scope_suite_cth_SUITE,test_case,
+ {failed,
+ {ct_exit_in_init_scope_suite_cth_SUITE,init_per_suite,
+ {failed,
+ "Failed to start CTH, see the CT Log for details"}}}}},
+ {?eh,tc_auto_skip,
+ {ct_exit_in_init_scope_suite_cth_SUITE,end_per_suite,
+ {failed,
+ {ct_exit_in_init_scope_suite_cth_SUITE,init_per_suite,
+ {failed,
+ "Failed to start CTH, see the CT Log for details"}}}}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(faulty_cth_exit_in_init) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{empty_cth,init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}];
+
+test_events(faulty_cth_exit_in_id) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{empty_cth,id,[[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {negative, {?eh,tc_start,'_'},
+ {?eh,test_done,{'DEF','STOP_TIME'}}},
+ {?eh,stop_logging,[]}];
+
+test_events(scope_per_suite_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_scope_per_suite_cth_SUITE,init_per_suite}},
+ {?eh,cth,{'_',id,[[]]}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_scope_per_suite_cth_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_scope_per_suite_cth_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_scope_per_suite_cth_SUITE,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_scope_per_suite_cth_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_scope_per_suite_cth_SUITE,end_per_suite}},
+ {?eh,cth,{'_',pre_end_per_suite,
+ [ct_scope_per_suite_cth_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_suite,[ct_scope_per_suite_cth_SUITE,'$proplist','_',[]]}},
+ {?eh,cth,{'_',terminate,[[]]}},
+ {?eh,tc_done,{ct_scope_per_suite_cth_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(scope_suite_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_scope_suite_cth_SUITE,init_per_suite}},
+ {?eh,cth,{'_',id,[[]]}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,cth,{'_',pre_init_per_suite,[ct_scope_suite_cth_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_scope_suite_cth_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_scope_suite_cth_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_scope_suite_cth_SUITE,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_scope_suite_cth_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_scope_suite_cth_SUITE,end_per_suite}},
+ {?eh,cth,{'_',pre_end_per_suite,[ct_scope_suite_cth_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_suite,[ct_scope_suite_cth_SUITE,'$proplist','_',[]]}},
+ {?eh,cth,{'_',terminate,[[]]}},
+ {?eh,tc_done,{ct_scope_suite_cth_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(scope_per_group_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_scope_per_group_cth_SUITE,init_per_suite}},
+ {?eh,tc_done,{ct_scope_per_group_cth_SUITE,init_per_suite,ok}},
+
+ [{?eh,tc_start,{ct_scope_per_group_cth_SUITE,{init_per_group,group1,[]}}},
+ {?eh,cth,{'_',id,[[]]}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,cth,{'_',post_init_per_group,[group1,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_scope_per_group_cth_SUITE,{init_per_group,group1,[]},ok}},
+
+ {?eh,tc_start,{ct_scope_per_group_cth_SUITE,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_scope_per_group_cth_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_scope_per_group_cth_SUITE,{end_per_group,group1,[]}}},
+ {?eh,cth,{'_',pre_end_per_group,[group1,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_group,[group1,'$proplist','_',[]]}},
+ {?eh,cth,{'_',terminate,[[]]}},
+ {?eh,tc_done,{ct_scope_per_group_cth_SUITE,{end_per_group,group1,[]},ok}}],
+
+ {?eh,tc_start,{ct_scope_per_group_cth_SUITE,end_per_suite}},
+ {?eh,tc_done,{ct_scope_per_group_cth_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(scope_per_suite_state_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_scope_per_suite_state_cth_SUITE,init_per_suite}},
+ {?eh,cth,{'_',id,[[test]]}},
+ {?eh,cth,{'_',init,['_',[test]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_scope_per_suite_state_cth_SUITE,'$proplist','$proplist',[test]]}},
+ {?eh,tc_done,{ct_scope_per_suite_state_cth_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_scope_per_suite_state_cth_SUITE,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[test]]}},
+ {?eh,tc_done,{ct_scope_per_suite_state_cth_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_scope_per_suite_state_cth_SUITE,end_per_suite}},
+ {?eh,cth,{'_',pre_end_per_suite,
+ [ct_scope_per_suite_state_cth_SUITE,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_end_per_suite,[ct_scope_per_suite_state_cth_SUITE,'$proplist','_',[test]]}},
+ {?eh,cth,{'_',terminate,[[test]]}},
+ {?eh,tc_done,{ct_scope_per_suite_state_cth_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(scope_suite_state_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_scope_suite_state_cth_SUITE,init_per_suite}},
+ {?eh,cth,{'_',id,[[test]]}},
+ {?eh,cth,{'_',init,['_',[test]]}},
+ {?eh,cth,{'_',pre_init_per_suite,[ct_scope_suite_state_cth_SUITE,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_scope_suite_state_cth_SUITE,'$proplist','$proplist',[test]]}},
+ {?eh,tc_done,{ct_scope_suite_state_cth_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_scope_suite_state_cth_SUITE,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[test]]}},
+ {?eh,tc_done,{ct_scope_suite_state_cth_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_scope_suite_state_cth_SUITE,end_per_suite}},
+ {?eh,cth,{'_',pre_end_per_suite,[ct_scope_suite_state_cth_SUITE,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_end_per_suite,[ct_scope_suite_state_cth_SUITE,'$proplist','_',[test]]}},
+ {?eh,cth,{'_',terminate,[[test]]}},
+ {?eh,tc_done,{ct_scope_suite_state_cth_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(scope_per_group_state_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,init_per_suite}},
+ {?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,init_per_suite,ok}},
+
+ [{?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,{init_per_group,group1,[]}}},
+ {?eh,cth,{'_',id,[[test]]}},
+ {?eh,cth,{'_',init,['_',[test]]}},
+ {?eh,cth,{'_',post_init_per_group,[group1,'$proplist','$proplist',[test]]}},
+ {?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,{init_per_group,group1,[]},ok}},
+
+ {?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[test]]}},
+ {?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,{end_per_group,group1,[]}}},
+ {?eh,cth,{'_',pre_end_per_group,[group1,'$proplist',[test]]}},
+ {?eh,cth,{'_',post_end_per_group,[group1,'$proplist','_',[test]]}},
+ {?eh,cth,{'_',terminate,[[test]]}},
+ {?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,{end_per_group,group1,[]},ok}}],
+
+ {?eh,tc_start,{ct_scope_per_group_state_cth_SUITE,end_per_suite}},
+ {?eh,tc_done,{ct_scope_per_group_state_cth_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(fail_pre_suite_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist',
+ {fail,"Test failure"},[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,
+ {failed, {error,"Test failure"}}}},
+ {?eh,cth,{'_',on_tc_fail,
+ [init_per_suite,{failed,"Test failure"},[]]}},
+
+
+ {?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,
+ {failed,{ct_cth_empty_SUITE,init_per_suite,
+ {failed,"Test failure"}}}}},
+ {?eh,cth,{'_',on_tc_skip,
+ [test_case, {tc_auto_skip,
+ {failed, {ct_cth_empty_SUITE, init_per_suite,
+ {failed, "Test failure"}}}},[]]}},
+
+
+ {?eh,tc_auto_skip, {ct_cth_empty_SUITE, end_per_suite,
+ {failed, {ct_cth_empty_SUITE, init_per_suite,
+ {failed, "Test failure"}}}}},
+ {?eh,cth,{'_',on_tc_skip,
+ [end_per_suite, {tc_auto_skip,
+ {failed, {ct_cth_empty_SUITE, init_per_suite,
+ {failed, "Test failure"}}}},[]]}},
+
+
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth, {'_',terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(fail_post_suite_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,
+ {failed,{error,"Test failure"}}}},
+ {?eh,cth,{'_',on_tc_fail,[init_per_suite, {failed,"Test failure"}, []]}},
+
+ {?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,
+ {failed,{ct_cth_empty_SUITE,init_per_suite,
+ {failed,"Test failure"}}}}},
+ {?eh,cth,{'_',on_tc_skip,[test_case,{tc_auto_skip,'_'},[]]}},
+
+ {?eh,tc_auto_skip, {ct_cth_empty_SUITE, end_per_suite,
+ {failed, {ct_cth_empty_SUITE, init_per_suite,
+ {failed, "Test failure"}}}}},
+ {?eh,cth,{'_',on_tc_skip,[end_per_suite,{tc_auto_skip,'_'},[]]}},
+
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth, {'_',terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(skip_pre_suite_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist',{skip,"Test skip"},[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,{skipped,"Test skip"}}},
+ {?eh,cth,{'_',on_tc_skip,
+ [init_per_suite,{tc_user_skip,{skipped,"Test skip"}},[]]}},
+
+ {?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,"Test skip"}},
+ {?eh,cth,{'_',on_tc_skip,[test_case,{tc_auto_skip,"Test skip"},[]]}},
+
+ {?eh,tc_auto_skip, {ct_cth_empty_SUITE, end_per_suite,"Test skip"}},
+ {?eh,cth,{'_',on_tc_skip,[end_per_suite,{tc_auto_skip,"Test skip"},[]]}},
+
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth, {'_',terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(skip_post_suite_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_suite,[ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,{skipped,"Test skip"}}},
+ {?eh,cth,{'_',on_tc_skip,
+ [init_per_suite,{tc_user_skip,{skipped,"Test skip"}},[]]}},
+
+ {?eh,tc_auto_skip,{ct_cth_empty_SUITE,test_case,"Test skip"}},
+ {?eh,cth,{'_',on_tc_skip,[test_case,{tc_auto_skip,"Test skip"},[]]}},
+
+ {?eh,tc_auto_skip, {ct_cth_empty_SUITE, end_per_suite,"Test skip"}},
+ {?eh,cth,{'_',on_tc_skip,[end_per_suite,{tc_auto_skip,"Test skip"},[]]}},
+
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{'_',terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(recover_post_suite_cth) ->
+ Suite = ct_cth_fail_per_suite_SUITE,
+ [
+ {?eh,start_logging,'_'},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{Suite,init_per_suite}},
+ {?eh,cth,{'_',pre_init_per_suite,[Suite,'$proplist','$proplist']}},
+ {?eh,cth,{'_',post_init_per_suite,[Suite,contains([tc_status]),
+ {'EXIT',{'_','_'}},[]]}},
+ {?eh,tc_done,{Suite,init_per_suite,ok}},
+
+ {?eh,tc_start,{Suite,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,
+ [test_case, not_contains([tc_status]),[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,
+ [test_case, contains([tc_status]),'_',[]]}},
+ {?eh,tc_done,{Suite,test_case,ok}},
+
+ {?eh,tc_start,{Suite,end_per_suite}},
+ {?eh,cth,{'_',pre_end_per_suite,
+ [Suite,not_contains([tc_status]),[]]}},
+ {?eh,cth,{'_',post_end_per_suite,
+ [Suite,not_contains([tc_status]),'_',[]]}},
+ {?eh,tc_done,{Suite,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{'_',terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(update_config_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+
+ {?eh,tc_start,{ct_update_config_SUITE,init_per_suite}},
+ {?eh,cth,{'_',pre_init_per_suite,
+ [ct_update_config_SUITE,contains([]),[]]}},
+ {?eh,cth,{'_',post_init_per_suite,
+ [ct_update_config_SUITE,
+ '$proplist',
+ contains(
+ [init_per_suite,
+ pre_init_per_suite]),
+ []]}},
+ {?eh,tc_done,{ct_update_config_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_update_config_SUITE, {init_per_group,group1,[]}}},
+ {?eh,cth,{'_',pre_init_per_group,
+ [group1,contains(
+ [post_init_per_suite,
+ init_per_suite,
+ pre_init_per_suite]),
+ []]}},
+ {?eh,cth,{'_',post_init_per_group,
+ [group1,
+ contains(
+ [post_init_per_suite,
+ init_per_suite,
+ pre_init_per_suite]),
+ contains(
+ [init_per_group,
+ pre_init_per_group,
+ post_init_per_suite,
+ init_per_suite,
+ pre_init_per_suite]),
+ []]}},
+ {?eh,tc_done,{ct_update_config_SUITE,{init_per_group,group1,[]},ok}},
+
+ {?eh,tc_start,{ct_update_config_SUITE,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,
+ [test_case,contains(
+ [post_init_per_group,
+ init_per_group,
+ pre_init_per_group,
+ post_init_per_suite,
+ init_per_suite,
+ pre_init_per_suite]),
+ []]}},
+ {?eh,cth,{'_',post_end_per_testcase,
+ [test_case,contains(
+ [init_per_testcase,
+ pre_init_per_testcase,
+ post_init_per_group,
+ init_per_group,
+ pre_init_per_group,
+ post_init_per_suite,
+ init_per_suite,
+ pre_init_per_suite]),
+ ok,[]]}},
+ {?eh,tc_done,{ct_update_config_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_update_config_SUITE, {end_per_group,group1,[]}}},
+ {?eh,cth,{'_',pre_end_per_group,
+ [group1,contains(
+ [post_init_per_group,
+ init_per_group,
+ pre_init_per_group,
+ post_init_per_suite,
+ init_per_suite,
+ pre_init_per_suite]),
+ []]}},
+ {?eh,cth,{'_',post_end_per_group,
+ [group1,
+ contains(
+ [pre_end_per_group,
+ post_init_per_group,
+ init_per_group,
+ pre_init_per_group,
+ post_init_per_suite,
+ init_per_suite,
+ pre_init_per_suite]),
+ ok,[]]}},
+ {?eh,tc_done,{ct_update_config_SUITE,{end_per_group,group1,[]},ok}},
+
+ {?eh,tc_start,{ct_update_config_SUITE,end_per_suite}},
+ {?eh,cth,{'_',pre_end_per_suite,
+ [ct_update_config_SUITE,contains(
+ [post_init_per_suite,
+ init_per_suite,
+ pre_init_per_suite]),
+ []]}},
+ {?eh,cth,{'_',post_end_per_suite,
+ [ct_update_config_SUITE,contains(
+ [pre_end_per_suite,
+ post_init_per_suite,
+ init_per_suite,
+ pre_init_per_suite]),
+ '_',[]]}},
+ {?eh,tc_done,{ct_update_config_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{'_',terminate,[contains(
+ [post_end_per_suite,
+ pre_end_per_suite,
+ post_init_per_suite,
+ init_per_suite,
+ pre_init_per_suite])]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(state_update_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{'_',init_per_suite}},
+
+ {?eh,tc_done,{'_',end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{'_',terminate,[contains(
+ [post_end_per_suite,pre_end_per_suite,
+ post_end_per_group,pre_end_per_group,
+ {not_in_order,
+ [post_end_per_testcase,pre_init_per_testcase,
+ on_tc_skip,post_end_per_testcase,
+ pre_init_per_testcase,on_tc_fail,
+ post_end_per_testcase,pre_init_per_testcase]
+ },
+ post_init_per_group,pre_init_per_group,
+ post_init_per_suite,pre_init_per_suite,
+ init])]}},
+ {?eh,cth,{'_',terminate,[contains(
+ [post_end_per_suite,pre_end_per_suite,
+ post_end_per_group,pre_end_per_group,
+ {not_in_order,
+ [post_end_per_testcase,pre_init_per_testcase,
+ on_tc_skip,post_end_per_testcase,
+ pre_init_per_testcase,on_tc_fail,
+ post_end_per_testcase,pre_init_per_testcase]
+ },
+ post_init_per_group,pre_init_per_group,
+ post_init_per_suite,pre_init_per_suite,
+ init]
+ )]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(options_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{empty_cth,init,['_',[test]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,cth,{empty_cth,pre_init_per_suite,
+ [ct_cth_empty_SUITE,'$proplist',[test]]}},
+ {?eh,cth,{empty_cth,post_init_per_suite,
+ [ct_cth_empty_SUITE,'$proplist','$proplist',[test]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
+ {?eh,cth,{empty_cth,pre_init_per_testcase,[test_case,'$proplist',[test]]}},
+ {?eh,cth,{empty_cth,post_end_per_testcase,[test_case,'$proplist','_',[test]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
+ {?eh,cth,{empty_cth,pre_end_per_suite,
+ [ct_cth_empty_SUITE,'$proplist',[test]]}},
+ {?eh,cth,{empty_cth,post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[test]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{empty_cth,terminate,[[test]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(same_id_cth) ->
+ [
+ {?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',id,[[]]}},
+ {?eh,cth,{'_',init,[same_id_cth,[]]}},
+ {?eh,cth,{'_',id,[[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{ct_cth_empty_SUITE,init_per_suite}},
+ {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {negative,
+ {?eh,cth,{'_',pre_init_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_init_per_suite,
+ [ct_cth_empty_SUITE,'$proplist','$proplist',[]]}}},
+ {negative,
+ {?eh,cth,{'_',post_init_per_suite,
+ [ct_cth_empty_SUITE,'$proplist','$proplist',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,init_per_suite,ok}}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,test_case}},
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {negative,
+ {?eh,cth,{'_',pre_init_per_testcase,[test_case,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}}},
+ {negative,
+ {?eh,cth,{'_',post_end_per_testcase,[test_case,'$proplist',ok,[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,test_case,ok}}},
+
+ {?eh,tc_start,{ct_cth_empty_SUITE,end_per_suite}},
+ {?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {negative,
+ {?eh,cth,{'_',pre_end_per_suite,[ct_cth_empty_SUITE,'$proplist',[]]}},
+ {?eh,cth,{'_',post_end_per_suite,[ct_cth_empty_SUITE,'$proplist','_',[]]}}},
+ {negative,
+ {?eh,cth,{'_',post_end_per_suite,
+ [ct_cth_empty_SUITE,'$proplist','_',[]]}},
+ {?eh,tc_done,{ct_cth_empty_SUITE,end_per_suite,ok}}},
+ {?eh,test_done,{'DEF','STOP_TIME'}},
+ {?eh,cth,{'_',terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(fail_n_skip_with_minimal_cth) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,cth,{'_',init,['_',[]]}},
+ {?eh,test_start,{'DEF',{'START_TIME','LOGDIR'}}},
+ {?eh,tc_start,{'_',init_per_suite}},
+
+ {?eh,tc_done,{'_',end_per_suite,ok}},
+ {?eh,cth,{'_',terminate,[[]]}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(ok) ->
+ ok.
+
+
+%% test events help functions
+contains(List) ->
+ fun(Proplist) when is_list(Proplist) ->
+ contains(List,Proplist)
+ end.
+
+contains([{not_in_order,List}|T],Rest) ->
+ contains_parallel(List,Rest),
+ contains(T,Rest);
+contains([{Ele,Pos}|T] = L,[H|T2]) ->
+ case element(Pos,H) of
+ Ele ->
+ contains(T,T2);
+ _ ->
+ contains(L,T2)
+ end;
+contains([Ele|T],[{Ele,_}|T2])->
+ contains(T,T2);
+contains([Ele|T],[Ele|T2])->
+ contains(T,T2);
+contains(List,[_|T]) ->
+ contains(List,T);
+contains([],_) ->
+ match.
+
+contains_parallel([Key | T], Elems) ->
+ contains([Key],Elems),
+ contains_parallel(T,Elems);
+contains_parallel([],_Elems) ->
+ match.
+
+not_contains(List) ->
+ fun(Proplist) when is_list(Proplist) ->
+ [] = [Ele || {Ele,_} <- Proplist,
+ Test <- List,
+ Test =:= Ele]
+ end.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_id_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_id_cth.erl
new file mode 100644
index 0000000000..02c36e378c
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_id_cth.erl
@@ -0,0 +1,34 @@
+%%
+%% %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(crash_id_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-export([id/1]).
+
+id(Opts) ->
+ empty_cth:id(Opts),
+ exit(diediedie).
+
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_init_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_init_cth.erl
new file mode 100644
index 0000000000..6ed23565f6
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/crash_init_cth.erl
@@ -0,0 +1,34 @@
+%%
+%% %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(crash_init_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-export([init/2]).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts),
+ exit(diediedie).
+
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_empty_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_empty_SUITE.erl
new file mode 100644
index 0000000000..499069b382
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_empty_SUITE.erl
@@ -0,0 +1,47 @@
+%%
+%% %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(ct_cth_empty_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl
new file mode 100644
index 0000000000..017812c719
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_one_skip_one_SUITE.erl
@@ -0,0 +1,64 @@
+%%
+%% %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(ct_cth_fail_one_skip_one_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_Group,Config) ->
+ Config.
+
+end_per_group(_Group,_Config) ->
+ ok.
+
+init_per_testcase(test_case2, Config) ->
+ {skip,"skip it"};
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+groups() ->
+ [{group1,[parallel],[{group2,[parallel],[test_case1,test_case2,test_case3]}]}].
+
+all() ->
+ [{group,group1}].
+
+%% Test cases starts here.
+test_case1(Config) ->
+ ok = nok.
+
+test_case2(Config) ->
+ ok.
+
+test_case3(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_per_suite_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_per_suite_SUITE.erl
new file mode 100644
index 0000000000..136a15ec96
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_cth_fail_per_suite_SUITE.erl
@@ -0,0 +1,47 @@
+%%
+%% %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(ct_cth_fail_per_suite_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ ok = nok.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_exit_in_init_scope_suite_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_exit_in_init_scope_suite_cth_SUITE.erl
new file mode 100644
index 0000000000..42be0a659e
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_exit_in_init_scope_suite_cth_SUITE.erl
@@ -0,0 +1,50 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ct_exit_in_init_scope_suite_cth_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+%% Test server callback functions
+suite() ->
+ [{ct_hooks,[crash_init_cth]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_cth_SUITE.erl
new file mode 100644
index 0000000000..628bca774c
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_cth_SUITE.erl
@@ -0,0 +1,56 @@
+%%
+%% %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(ct_scope_per_group_cth_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+init_per_group(GroupName, Config) ->
+ [{ct_hooks,[empty_cth]}|Config].
+
+end_per_group(GroupName, Config) ->
+ ok.
+
+all() ->
+ [{group,group1}].
+
+groups() ->
+ [{group1,[],[test_case]}].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_state_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_state_cth_SUITE.erl
new file mode 100644
index 0000000000..14ea52bf8c
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_group_state_cth_SUITE.erl
@@ -0,0 +1,56 @@
+%%
+%% %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(ct_scope_per_group_state_cth_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ [{ct_hooks,[{empty_cth,[test]}]}|Config].
+
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+all() ->
+ [{group,group1}].
+
+groups() ->
+ [{group1,[],[test_case]}].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_cth_SUITE.erl
new file mode 100644
index 0000000000..5c1658be44
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_cth_SUITE.erl
@@ -0,0 +1,47 @@
+%%
+%% %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(ct_scope_per_suite_cth_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ [{ct_hooks,[empty_cth]}|Config].
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_state_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_state_cth_SUITE.erl
new file mode 100644
index 0000000000..96d00e3b28
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_suite_state_cth_SUITE.erl
@@ -0,0 +1,47 @@
+%%
+%% %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(ct_scope_per_suite_state_cth_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ [{ct_hooks,[{empty_cth,[test]}]}|Config].
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl
new file mode 100644
index 0000000000..fa632444c5
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_per_tc_cth_SUITE.erl
@@ -0,0 +1,110 @@
+%%
+%% %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(ct_scope_per_tc_cth_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% @doc
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% 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.
+%%
+%% @spec init_per_suite(Config) -> Config
+%% @end
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Cleanup after the whole suite
+%%
+%% @spec end_per_suite(Config) -> _
+%% @end
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @doc
+%% 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.
+%%
+%% 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.
+%% Initiation before each test case
+%%
+%% @spec init_per_testcase(TestCase, Config) -> Config
+%% @end
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ [{ct_hooks,[empty_cth]}|Config].
+
+%%--------------------------------------------------------------------
+%% @doc
+%% 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.
+%%
+%% Cleanup after each test case
+%%
+%% @spec end_per_testcase(TestCase, Config) -> _
+%% @end
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%%
+%% Returns a list of all test cases in this test suite
+%%
+%% @spec all() -> TestCases
+%% @end
+%%--------------------------------------------------------------------
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_cth_SUITE.erl
new file mode 100644
index 0000000000..988a0969ca
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_cth_SUITE.erl
@@ -0,0 +1,50 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ct_scope_suite_cth_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+suite() ->
+ [{ct_hooks,[empty_cth]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_state_cth_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_state_cth_SUITE.erl
new file mode 100644
index 0000000000..18b68fbcdc
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_scope_suite_state_cth_SUITE.erl
@@ -0,0 +1,50 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ct_scope_suite_state_cth_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+suite() ->
+ [{ct_hooks,[{empty_cth,[test]}]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+all() ->
+ [test_case].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_update_config_SUITE.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_update_config_SUITE.erl
new file mode 100644
index 0000000000..57fea347f6
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/ct_update_config_SUITE.erl
@@ -0,0 +1,56 @@
+%%
+%% %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(ct_update_config_SUITE).
+
+-suite_defaults([{timetrap, {minutes, 10}}]).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("ct.hrl").
+
+%% Test server callback functions
+init_per_suite(Config) ->
+ [{init_per_suite,now()}|Config].
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_TestCase, Config) ->
+ [{init_per_testcase,now()}|Config].
+
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+init_per_group(GroupName, Config) ->
+ [{init_per_group,now()}|Config].
+
+end_per_group(GroupName, Config) ->
+ ok.
+
+all() ->
+ [{group,group1}].
+
+groups() ->
+ [{group1,[],[test_case]}].
+
+%% Test cases starts here.
+test_case(Config) when is_list(Config) ->
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl
new file mode 100644
index 0000000000..5d07cd3dea
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/empty_cth.erl
@@ -0,0 +1,278 @@
+%%
+%% %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%
+%%
+
+%%% @doc Common Test Example Suite Callback module.
+%%%
+%%% <p>This module gives an example of a common test CTH (Common Test Hook).
+%%% There are many ways to add a CTH to a test run, you can do it either in
+%%% the command line using -ct_hook, in a test spec using
+%%% {ct_hook,M} or in the suite it self by returning ct_hook
+%%% from either suite/0, init_per_suite/1, init_per_group/2 and
+%%% init_per_testcase/2. The scope of the CTH is determined by where is it
+%%% started. If it is started in the command line or test spec then it will
+%%% be stopped at the end of all tests. If it is started in init_per_suite,
+%%% it will be stopped after end_per_suite and so on. See terminate
+%%% documentation for a table describing the scoping machanics.
+%%%
+%%% All of callbacks except init/1 in a CTH are optional.</p>
+
+-module(empty_cth).
+
+%% CT Hooks
+-export([id/1]).
+-export([init/2]).
+
+-export([pre_init_per_suite/3]).
+-export([post_init_per_suite/4]).
+-export([pre_end_per_suite/3]).
+-export([post_end_per_suite/4]).
+
+-export([pre_init_per_group/3]).
+-export([post_init_per_group/4]).
+-export([pre_end_per_group/3]).
+-export([post_end_per_group/4]).
+
+-export([pre_init_per_testcase/3]).
+-export([post_end_per_testcase/4]).
+
+-export([on_tc_fail/3]).
+-export([on_tc_skip/3]).
+
+-export([terminate/1]).
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+-type proplist() :: list({atom(),term()}).
+-type config() :: proplist().
+-type reason() :: term().
+-type skip_or_fail() :: {skip, reason()} |
+ {auto_skip, reason()} |
+ {fail, reason()} |
+ {'EXIT',reason()}.
+
+-record(state, { id = ?MODULE :: term()}).
+
+%% @doc Always called before any other callback function. Use this to initiate
+%% any common state. It should return an state for this CTH.
+-spec init(Id :: term(), Opts :: proplist()) ->
+ State :: #state{}.
+init(Id, Opts) ->
+ gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, init, [Id, Opts]}}),
+ Opts.
+
+%% @doc The ID is used to uniquly identify an CTH instance, if two CTH's
+%% return the same ID the seconds CTH is ignored. This function should NOT
+%% have any side effects as it might be called multiple times by common test.
+-spec id(Opts :: proplist()) ->
+ Id :: term().
+id(Opts) ->
+ gen_event:notify(?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, id, [Opts]}}),
+ now().
+
+%% @doc Called before init_per_suite is called. Note that this callback is
+%% only called if the CTH is added before init_per_suite is run (eg. in a test
+%% specification, suite/0 function etc).
+%% You can change the config in the this function.
+-spec pre_init_per_suite(Suite :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_per_suite(Suite,Config,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, pre_init_per_suite,
+ [Suite,Config,State]}}),
+ {Config, State}.
+
+%% @doc Called after init_per_suite.
+%% you can change the return value in this function.
+-spec post_init_per_suite(Suite :: atom(),
+ Config :: config(),
+ Return :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+post_init_per_suite(Suite,Config,Return,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, post_init_per_suite,
+ [Suite,Config,Return,State]}}),
+ {Return, State}.
+
+%% @doc Called before end_per_suite. The config/state can be changed here,
+%% though it will only affect the *end_per_suite function.
+-spec pre_end_per_suite(Suite :: atom(),
+ Config :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+pre_end_per_suite(Suite,Config,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, pre_end_per_suite,
+ [Suite,Config,State]}}),
+ {Config, State}.
+
+%% @doc Called after end_per_suite. Note that the config cannot be
+%% changed here, only the status of the suite.
+-spec post_end_per_suite(Suite :: atom(),
+ Config :: config(),
+ Return :: term(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_per_suite(Suite,Config,Return,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, post_end_per_suite,
+ [Suite,Config,Return,State]}}),
+ {Return, State}.
+
+%% @doc Called before each init_per_group.
+%% You can change the config in this function.
+-spec pre_init_per_group(Group :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_per_group(Group,Config,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, pre_init_per_group,
+ [Group,Config,State]}}),
+ {Config, State}.
+
+%% @doc Called after each init_per_group.
+%% You can change the return value in this function.
+-spec post_init_per_group(Group :: atom(),
+ Config :: config(),
+ Return :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+post_init_per_group(Group,Config,Return,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, post_init_per_group,
+ [Group,Config,Return,State]}}),
+ {Return, State}.
+
+%% @doc Called after each end_per_group. The config/state can be changed here,
+%% though it will only affect the *end_per_group functions.
+-spec pre_end_per_group(Group :: atom(),
+ Config :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+pre_end_per_group(Group,Config,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, pre_end_per_group,
+ [Group,Config,State]}}),
+ {Config, State}.
+
+%% @doc Called after each end_per_group. Note that the config cannot be
+%% changed here, only the status of the group.
+-spec post_end_per_group(Group :: atom(),
+ Config :: config(),
+ Return :: term(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_per_group(Group,Config,Return,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, post_end_per_group,
+ [Group,Config,Return,State]}}),
+ {Return, State}.
+
+%% @doc Called before each test case.
+%% You can change the config in this function.
+-spec pre_init_per_testcase(TC :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_per_testcase(TC,Config,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, pre_init_per_testcase,
+ [TC,Config,State]}}),
+ {Config, State}.
+
+%% @doc Called after each test case. Note that the config cannot be
+%% changed here, only the status of the test case.
+-spec post_end_per_testcase(TC :: atom(),
+ Config :: config(),
+ Return :: term(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_per_testcase(TC,Config,Return,State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, post_end_per_testcase,
+ [TC,Config,Return,State]}}),
+ {Return, State}.
+
+%% @doc Called after post_init_per_suite, post_end_per_suite, post_init_per_group,
+%% post_end_per_group and post_end_per_tc if the suite, group or test case failed.
+%% This function should be used for extra cleanup which might be needed.
+%% It is not possible to modify the config or the status of the test run.
+-spec on_tc_fail(TC :: init_per_suite | end_per_suite |
+ init_per_group | end_per_group | atom(),
+ Reason :: term(), State :: #state{}) ->
+ NewState :: #state{}.
+on_tc_fail(TC, Reason, State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, on_tc_fail,
+ [TC,Reason,State]}}),
+ State.
+
+%% @doc Called when a test case is skipped by either user action
+%% or due to an init function failing. Test case can be
+%% end_per_suite, init_per_group, end_per_group and the actual test cases.
+-spec on_tc_skip(TC :: end_per_suite |
+ init_per_group | end_per_group | atom(),
+ {tc_auto_skip, {failed, {Mod :: atom(), Function :: atom(), Reason :: term()}}} |
+ {tc_user_skip, {skipped, Reason :: term()}},
+ State :: #state{}) ->
+ NewState :: #state{}.
+on_tc_skip(TC, Reason, State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, on_tc_skip,
+ [TC,Reason,State]}}),
+ State.
+
+%% @doc Called when the scope of the CTH is done, this depends on
+%% when the CTH was specified. This translation table describes when this
+%% function is called.
+%%
+%% | Started in | terminate called |
+%% |---------------------|-------------------------|
+%% | command_line | after all tests are run |
+%% | test spec | after all tests are run |
+%% | suite/0 | after SUITE is done |
+%% | init_per_suite/1 | after SUITE is done |
+%% | init_per_group/2 | after group is done |
+%% |-----------------------------------------------|
+%%
+-spec terminate(State :: #state{}) ->
+ term().
+terminate(State) ->
+ gen_event:notify(
+ ?CT_EVMGR_REF, #event{ name = cth, node = node(),
+ data = {?MODULE, terminate, [State]}}),
+ ok.
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl
new file mode 100644
index 0000000000..b4c26259a6
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_post_suite_cth.erl
@@ -0,0 +1,72 @@
+%%
+%% %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(fail_post_suite_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State),
+ {{fail, "Test failure"}, State}.
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl
new file mode 100644
index 0000000000..acf80a1b2e
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/fail_pre_suite_cth.erl
@@ -0,0 +1,72 @@
+%%
+%% %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(fail_pre_suite_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State),
+ {{fail, "Test failure"}, State}.
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/id_no_init_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/id_no_init_cth.erl
new file mode 100644
index 0000000000..58ed400e1c
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/id_no_init_cth.erl
@@ -0,0 +1,32 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+
+-module(id_no_init_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-export([id/1]).
+
+id(Opts) ->
+ empty_cth:id(Opts).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_cth.erl
new file mode 100644
index 0000000000..a18f4bf2f3
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_cth.erl
@@ -0,0 +1,33 @@
+%%
+%% %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(minimal_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-export([init/2]).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl
new file mode 100644
index 0000000000..79cd55f68e
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/minimal_terminate_cth.erl
@@ -0,0 +1,38 @@
+%%
+%% %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(minimal_terminate_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-export([init/2]).
+-export([terminate/1]).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+terminate(State) ->
+ empty_cth:terminate(State).
+
+
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl
new file mode 100644
index 0000000000..01a932bd59
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/recover_post_suite_cth.erl
@@ -0,0 +1,74 @@
+%%
+%% %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(recover_post_suite_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,{'EXIT',Reason} = Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State),
+ {lists:keydelete(tc_status,1,Config),State};
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl
new file mode 100644
index 0000000000..acfb93fe26
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/same_id_cth.erl
@@ -0,0 +1,75 @@
+%%
+%% %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(same_id_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+id(Opts) ->
+ empty_cth:id(Opts),
+ ?MODULE.
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl
new file mode 100644
index 0000000000..6d4605b33b
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_post_suite_cth.erl
@@ -0,0 +1,72 @@
+%%
+%% %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(skip_post_suite_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State),
+ {{skip, "Test skip"}, State}.
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl
new file mode 100644
index 0000000000..49efd0d0cd
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/skip_pre_suite_cth.erl
@@ -0,0 +1,73 @@
+%%
+%% %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(skip_pre_suite_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State),
+ {{skip, "Test skip"}, State}.
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl
new file mode 100644
index 0000000000..53d75e6ce3
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/state_update_cth.erl
@@ -0,0 +1,83 @@
+%%
+%% %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(state_update_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ State = empty_cth:init(Id, Opts),
+ [init|State].
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State),
+ {Config, [pre_init_per_suite|State]}.
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State),
+ {Config, [post_init_per_suite|State]}.
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State),
+ {Config, [pre_end_per_suite|State]}.
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State),
+ {Return, [post_end_per_suite|State]}.
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State),
+ {Config, [pre_init_per_group|State]}.
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State),
+ {Return, [post_init_per_group|State]}.
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State),
+ {Config, [pre_end_per_group|State]}.
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State),
+ {Return, [post_end_per_group|State]}.
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State),
+ {Config, [pre_init_per_testcase|State]}.
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State),
+ {Return, [post_end_per_testcase|State]}.
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State),
+ [on_tc_fail|State].
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State),
+ [on_tc_skip|State].
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl
new file mode 100644
index 0000000000..4c44ef025b
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/undef_cth.erl
@@ -0,0 +1,71 @@
+%%
+%% %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(undef_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(_Suite, _Config, _State) ->
+ lists:flaten([1,2,[3,4]]).
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State).
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State).
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State).
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State).
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State).
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State).
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State).
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State).
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State).
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl
new file mode 100644
index 0000000000..788ef2cec2
--- /dev/null
+++ b/lib/common_test/test/ct_hooks_SUITE_data/cth/tests/update_config_cth.erl
@@ -0,0 +1,82 @@
+%%
+%% %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(update_config_cth).
+
+
+-include_lib("common_test/src/ct_util.hrl").
+-include_lib("common_test/include/ct_event.hrl").
+
+
+%% CT Hooks
+-compile(export_all).
+
+init(Id, Opts) ->
+ empty_cth:init(Id, Opts).
+
+pre_init_per_suite(Suite, Config, State) ->
+ empty_cth:pre_init_per_suite(Suite,Config,State),
+ {[{pre_init_per_suite,now()}|Config],State}.
+
+post_init_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_init_per_suite(Suite,Config,Return,State),
+ {[{post_init_per_suite,now()}|Return],State}.
+
+pre_end_per_suite(Suite,Config,State) ->
+ empty_cth:pre_end_per_suite(Suite,Config,State),
+ {[{pre_end_per_suite,now()}|Config],State}.
+
+post_end_per_suite(Suite,Config,Return,State) ->
+ empty_cth:post_end_per_suite(Suite,Config,Return,State),
+ NewConfig = [{post_end_per_suite,now()}|Config],
+ {NewConfig,NewConfig}.
+
+pre_init_per_group(Group,Config,State) ->
+ empty_cth:pre_init_per_group(Group,Config,State),
+ {[{pre_init_per_group,now()}|Config],State}.
+
+post_init_per_group(Group,Config,Return,State) ->
+ empty_cth:post_init_per_group(Group,Config,Return,State),
+ {[{post_init_per_group,now()}|Return],State}.
+
+pre_end_per_group(Group,Config,State) ->
+ empty_cth:pre_end_per_group(Group,Config,State),
+ {[{pre_end_per_group,now()}|Config],State}.
+
+post_end_per_group(Group,Config,Return,State) ->
+ empty_cth:post_end_per_group(Group,Config,Return,State),
+ {[{post_end_per_group,now()}|Config],State}.
+
+pre_init_per_testcase(TC,Config,State) ->
+ empty_cth:pre_init_per_testcase(TC,Config,State),
+ {[{pre_init_per_testcase,now()}|Config],State}.
+
+post_end_per_testcase(TC,Config,Return,State) ->
+ empty_cth:post_end_per_testcase(TC,Config,Return,State),
+ {[{post_end_per_testcase,now()}|Config],State}.
+
+on_tc_fail(TC, Reason, State) ->
+ empty_cth:on_tc_fail(TC,Reason,State).
+
+on_tc_skip(TC, Reason, State) ->
+ empty_cth:on_tc_skip(TC,Reason,State).
+
+terminate(State) ->
+ empty_cth:terminate(State).
diff --git a/lib/common_test/test/ct_master_SUITE.erl b/lib/common_test/test/ct_master_SUITE.erl
index e0e1f93db2..e208397296 100644
--- a/lib/common_test/test/ct_master_SUITE.erl
+++ b/lib/common_test/test/ct_master_SUITE.erl
@@ -28,11 +28,18 @@
-module(ct_master_SUITE).
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
+-define(TEMP_DIR, case os:type() of
+ {win32,_} ->
+ "c:/Temp";
+ _ ->
+ "/tmp"
+ end).
+
%%--------------------------------------------------------------------
%% TEST SERVER CALLBACK FUNCTIONS
%%--------------------------------------------------------------------
@@ -43,39 +50,84 @@
%% there will be clashes with logging processes etc).
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- Config1 = ct_test_support:init_per_suite(Config),
- Config1.
+ ct_test_support:init_per_suite(Config).
end_per_suite(Config) ->
ct_test_support:end_per_suite(Config).
init_per_testcase(TestCase, Config) ->
- ct_test_support:init_per_testcase(TestCase, [{master, true}|Config]).
+ NodeCount = 5,
+ NodeNames = [list_to_atom("t_"++integer_to_list(N)) ||
+ N <- lists:seq(1, NodeCount)],
+ ct_test_support:init_per_testcase(
+ TestCase,[{node_names,NodeNames},
+ {master, true}|Config]).
end_per_testcase(TestCase, Config) ->
+ case os:type() of
+ {win32,_} ->
+ %% If this is a windows run the logs are saved to /tmp and
+ %% then moved to private_dir as a tar because otherwise
+ %% the file names become too long! :(
+ Files = filelib:wildcard(filename:join(?TEMP_DIR,"slave.*")),
+ erl_tar:create(
+ filename:join(
+ proplists:get_value(priv_dir,Config),"slaves.tar.gz"),
+ Files,[compressed]),
+ os:cmd("rm -rf "++filename:join(?TEMP_DIR,"slave.*"));
+ _ ->
+ ok
+ end,
+
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- [""];
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [ct_master_test].
-all(suite) ->
- [
- ct_master_test
- ].
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%--------------------------------------------------------------------
%% TEST CASES
%%--------------------------------------------------------------------
ct_master_test(Config) when is_list(Config)->
- NodeCount = 5,
+ NodeNames = proplists:get_value(node_names, Config),
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
- NodeNames = [list_to_atom("testnode_"++integer_to_list(N)) ||
- N <- lists:seq(1, NodeCount)],
+
FileName = filename:join(PrivDir, "ct_master_spec.spec"),
Suites = [master_SUITE],
TSFile = make_spec(DataDir, FileName, NodeNames, Suites, Config),
+ ERPid = ct_test_support:start_event_receiver(Config),
+ spawn(ct@ancalagon,
+ fun() ->
+ dbg:tracer(),dbg:p(all,c),
+ dbg:tpl(erlang, spawn_link, 4,x),
+ receive ok -> ok end
+ end),
+
[{TSFile, ok}] = run_test(ct_master_test, FileName, Config),
+
+ Events = ct_test_support:get_events(ERPid, Config),
+
+ ct_test_support:log_events(groups_suite_1,
+ reformat(Events, ?eh),
+ ?config(priv_dir, Config)),
+ find_events(NodeNames, [{tc_start,{master_SUITE,init_per_suite}},
+ {tc_start,{master_SUITE,first_testcase}},
+ {tc_start,{master_SUITE,second_testcase}},
+ {tc_start,{master_SUITE,third_testcase}},
+ {tc_start,{master_SUITE,end_per_suite}}],
+ Events),
+
ok.
%%%-----------------------------------------------------------------
@@ -112,13 +164,25 @@ make_spec(DataDir, FileName, NodeNames, Suites, Config)->
PrivDir = ?config(priv_dir, Config),
LD = lists:map(fun(NodeName)->
- {logdir, NodeName, get_log_dir(PrivDir, NodeName)}
+ {logdir, NodeName, get_log_dir(os:type(),PrivDir, NodeName)}
end,
NodeNames) ++ [{logdir, master, PrivDir}],
-
- ct_test_support:write_testspec(N++C++S++LD++NS, FileName).
-
-get_log_dir(PrivDir, NodeName)->
+ EvHArgs = [{cbm,ct_test_support},{trace_level,?config(trace_level,Config)}],
+ EH = [{event_handler,master,[?eh],EvHArgs}],
+
+ Include = [{include,filename:join([DataDir,"master/include"])}],
+
+ ct_test_support:write_testspec(N++Include++EH++C++S++LD++NS, FileName).
+
+get_log_dir({win32,_},PrivDir, NodeName)->
+ case filelib:is_dir(?TEMP_DIR) of
+ false ->
+ file:make_dir(?TEMP_DIR);
+ _ ->
+ ok
+ end,
+ get_log_dir(tmp, ?TEMP_DIR,NodeName);
+get_log_dir(_,PrivDir,NodeName) ->
LogDir = filename:join(PrivDir, io_lib:format("slave.~p", [NodeName])),
file:make_dir(LogDir),
LogDir.
@@ -126,11 +190,34 @@ get_log_dir(PrivDir, NodeName)->
run_test(_Name, FileName, Config)->
[{FileName, ok}] = ct_test_support:run(ct_master, run, [FileName], Config).
-reformat_events(Events, EH) ->
+reformat(Events, EH) ->
ct_test_support:reformat(Events, EH).
%%%-----------------------------------------------------------------
%%% TEST EVENTS
%%%-----------------------------------------------------------------
+find_events([], _CheckEvents, _) ->
+ ok;
+find_events([NodeName|NodeNames],CheckEvents,AllEvents) ->
+ find_events(NodeNames, CheckEvents,
+ remove_events(add_host(NodeName),CheckEvents, AllEvents, [])).
+
+remove_events(Node,[{Name,Data} | RestChecks],
+ [{?eh,#event{ name = Name, node = Node, data = Data }}|RestEvs],
+ Acc) ->
+ remove_events(Node, RestChecks, RestEvs, Acc);
+remove_events(Node, Checks, [Event|RestEvs], Acc) ->
+ remove_events(Node, Checks, RestEvs, [Event | Acc]);
+remove_events(_Node, [], [], Acc) ->
+ lists:reverse(Acc);
+remove_events(Node, Events, [], Acc) ->
+ test_server:format("Could not find events: ~p in ~p for node ~p",
+ [Events, lists:reverse(Acc), Node]),
+ exit(event_not_found).
+
+add_host(NodeName) ->
+ {ok, HostName} = inet:gethostname(),
+ list_to_atom(atom_to_list(NodeName)++"@"++HostName).
+
expected_events(_)->
-[].
+ [].
diff --git a/lib/common_test/test/ct_master_SUITE_data/master/include/test.hrl b/lib/common_test/test/ct_master_SUITE_data/master/include/test.hrl
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/common_test/test/ct_master_SUITE_data/master/include/test.hrl
diff --git a/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl b/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl
index e37ec3659c..032d69ad9f 100644
--- a/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl
+++ b/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl
@@ -28,6 +28,7 @@
-compile(export_all).
-include_lib("common_test/include/ct.hrl").
+-include("test.hrl").
suite() ->
[].
diff --git a/lib/common_test/test/ct_misc_1_SUITE.erl b/lib/common_test/test/ct_misc_1_SUITE.erl
index eb6c6aa101..f5904ca180 100644
--- a/lib/common_test/test/ct_misc_1_SUITE.erl
+++ b/lib/common_test/test/ct_misc_1_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("test_server/include/test_server_line.hrl").
-include_lib("common_test/include/ct_event.hrl").
@@ -57,13 +57,23 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- [""];
+suite() -> [{ct_hooks,[ts_install_cth]}].
-all(suite) ->
- [
- beam_me_up
- ].
+all() ->
+ [beam_me_up, {group,parse_table}].
+
+groups() ->
+ [{parse_table,[parallel],
+ [parse_table_empty, parse_table_single,
+ parse_table_multiline_row,
+ parse_table_one_column_multiline,
+ parse_table_one_column_simple]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%--------------------------------------------------------------------
%% TEST CASES
@@ -106,6 +116,59 @@ beam_me_up(Config) when is_list(Config) ->
TestEvents = events_to_check(beam_me_up, 1),
ok = ct_test_support:verify_events(TestEvents, Events, Config).
+parse_table_empty(Config) when is_list(Config) ->
+
+ String = ["+----+-------+---------+---------+----------+------+--------+",
+ "| id | col11 | col2222 | col3333 | col4 | col5 | col6666 |",
+ "+----+-------+---------+---------+----------+------+--------+",
+ "+----+-------+---------+---------+----------+------+--------+",
+ "Query Done: 0 records selected"],
+
+ {{"id","col11","col2222","col3333","col4","col5","col6666"},[]} =
+ ct:parse_table(String).
+
+
+parse_table_single(Config) when is_list(Config) ->
+
+ String = ["+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+",
+ "| id | col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8 |",
+"+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+",
+ "| 0 | 0 | -1407231560 | -256 | -1407231489 | 1500 | 1 | 1 | 1 |",
+ "+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+"
+ "Query Done: 1 record selected"],
+
+ {{"id","col1","col2","col3","col4","col5","col6","col7","col8"},
+ [{"0","0","-1407231560","-256","-1407231489", "1500","1","1","1"}]} =
+ ct:parse_table(String).
+
+parse_table_multiline_row(Config) when is_list(Config) ->
+
+ String = ["+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+",
+ "| id | col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8 |",
+"+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+",
+ "| 0 | 0 | Free test string",
+ " on more lines",
+ "than one",
+ "| -256 | -1407231489 | 1500 | 1 | 1 | 1 |",
+ "+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+"
+ "Query Done: 1 record selected"],
+
+ {{"id","col1","col2","col3","col4","col5","col6","col7","col8"},
+ [{"0","0","Free test string\n on more lines\nthan one\n",
+ "-256","-1407231489", "1500","1","1","1"}]} =
+ ct:parse_table(String).
+
+parse_table_one_column_simple(Config) when is_list(Config) ->
+
+ String = ["|test|","|test value|"],
+
+ {{"test"},[{"test value"}]} = ct:parse_table(String).
+
+parse_table_one_column_multiline(Config) when is_list(Config) ->
+ String = ["|test|","|test","value|"],
+
+ {{"test"},[{"test\nvalue"}]} = ct:parse_table(String).
+
%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
%%%-----------------------------------------------------------------
diff --git a/lib/common_test/test/ct_repeat_1_SUITE.erl b/lib/common_test/test/ct_repeat_1_SUITE.erl
index 1b4cafc9d3..40ef3e42fb 100644
--- a/lib/common_test/test/ct_repeat_1_SUITE.erl
+++ b/lib/common_test/test/ct_repeat_1_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
@@ -56,24 +56,26 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- [];
+suite() -> [{ct_hooks,[ts_install_cth]}].
-all(suite) ->
- [repeat_cs,
- repeat_cs_and_grs,
- repeat_seq,
- repeat_cs_until_any_ok,
- repeat_gr_until_any_ok,
- repeat_cs_until_any_fail,
- repeat_gr_until_any_fail,
- repeat_cs_until_all_ok,
- repeat_gr_until_all_ok,
- repeat_cs_until_all_fail,
- repeat_gr_until_all_fail,
+all() ->
+ [repeat_cs, repeat_cs_and_grs, repeat_seq,
+ repeat_cs_until_any_ok, repeat_gr_until_any_ok,
+ repeat_cs_until_any_fail, repeat_gr_until_any_fail,
+ repeat_cs_until_all_ok, repeat_gr_until_all_ok,
+ repeat_cs_until_all_fail, repeat_gr_until_all_fail,
repeat_seq_until_any_fail,
- repeat_shuffled_seq_until_any_fail
- ].
+ repeat_shuffled_seq_until_any_fail].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%--------------------------------------------------------------------
%% TEST CASES
diff --git a/lib/common_test/test/ct_sequence_1_SUITE.erl b/lib/common_test/test/ct_sequence_1_SUITE.erl
index 0cf40f106a..0876a6f8b8 100644
--- a/lib/common_test/test/ct_sequence_1_SUITE.erl
+++ b/lib/common_test/test/ct_sequence_1_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
@@ -56,13 +56,24 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(suite) ->
- [subgroup_return_fail,
- subgroup_init_fail,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [subgroup_return_fail, subgroup_init_fail,
subgroup_after_failed_case,
case_after_subgroup_return_fail,
case_after_subgroup_fail_init].
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%--------------------------------------------------------------------
%% TEST CASES
%%--------------------------------------------------------------------
diff --git a/lib/common_test/test/ct_skip_SUITE.erl b/lib/common_test/test/ct_skip_SUITE.erl
index 2e02061dec..2b64062e4d 100644
--- a/lib/common_test/test/ct_skip_SUITE.erl
+++ b/lib/common_test/test/ct_skip_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
@@ -56,14 +56,20 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- [""];
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [auto_skip, user_skip].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [
- auto_skip,
- user_skip
- ].
%%--------------------------------------------------------------------
diff --git a/lib/common_test/test/ct_smoke_test_SUITE.erl b/lib/common_test/test/ct_smoke_test_SUITE.erl
index 05a2c20695..096171f951 100644
--- a/lib/common_test/test/ct_smoke_test_SUITE.erl
+++ b/lib/common_test/test/ct_smoke_test_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
@@ -112,14 +112,22 @@ end_per_testcase(TestCase, Config) ->
%% Description: Returns a description of the test suite (doc) and a
%% list of all test cases in the suite (suite).
%%--------------------------------------------------------------------
-all(doc) ->
- ["Run smoke tests of Common Test."];
+suite() -> [{ct_hooks,[ts_install_cth]}].
-all(suite) ->
- [dir1, dir2, dir1_2,
- suite11, suite21, suite11_21,
+all() ->
+ [dir1, dir2, dir1_2, suite11, suite21, suite11_21,
tc111, tc211, tc111_112].
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%--------------------------------------------------------------------
%% TEST CASES
diff --git a/lib/common_test/test/ct_test_server_if_1_SUITE.erl b/lib/common_test/test/ct_test_server_if_1_SUITE.erl
index eb85409073..44c30d7a38 100644
--- a/lib/common_test/test/ct_test_server_if_1_SUITE.erl
+++ b/lib/common_test/test/ct_test_server_if_1_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
@@ -56,13 +56,20 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- [""];
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [ts_if_1].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [
- ts_if_1
- ].
%%--------------------------------------------------------------------
diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl
index 7bfb9ffb49..b4f1a0e71f 100644
--- a/lib/common_test/test/ct_test_support.erl
+++ b/lib/common_test/test/ct_test_support.erl
@@ -43,6 +43,14 @@ init_per_suite(Config) ->
init_per_suite(Config, 50).
init_per_suite(Config, Level) ->
+ case os:type() of
+ {win32, _} ->
+ %% Extend timeout for windows as starting node
+ %% can take a long time there
+ test_server:timetrap( 120000 * test_server:timetrap_scale_factor());
+ _ ->
+ ok
+ end,
case delete_old_logs(os:type(), Config) of
{'EXIT',DelLogsReason} ->
test_server:format(0, "Failed to delete old log directories: ~p~n",
@@ -50,7 +58,13 @@ init_per_suite(Config, Level) ->
_ ->
ok
end,
+
+ start_slave(Config, Level).
+
+start_slave(Config,Level) ->
[_,Host] = string:tokens(atom_to_list(node()), "@"),
+
+ test_server:format(0, "Trying to start ~s~n", ["ct@"++Host]),
case slave:start(Host, ct, []) of
{error,Reason} ->
test_server:fail(Reason);
@@ -126,9 +140,16 @@ init_per_testcase(_TestCase, Config) ->
end_per_testcase(_TestCase, Config) ->
CTNode = ?config(ct_node, Config),
- wait_for_ct_stop(CTNode),
- ok.
-
+ case wait_for_ct_stop(CTNode) of
+ %% Common test was not stopped to we restart node.
+ false ->
+ cover:stop(CTNode),
+ slave:stop(CTNode),
+ start_slave(Config,proplists:get_value(trace_level,Config)),
+ {fail, "Could not stop common_test"};
+ true ->
+ ok
+ end.
%%%-----------------------------------------------------------------
%%%
@@ -219,11 +240,11 @@ wait_for_ct_stop(CTNode) ->
wait_for_ct_stop(0, CTNode) ->
test_server:format(0, "Giving up! Stopping ~p.", [CTNode]),
- ok;
+ false;
wait_for_ct_stop(Retries, CTNode) ->
case rpc:call(CTNode, erlang, whereis, [ct_util_server]) of
undefined ->
- ok;
+ true;
Pid ->
test_server:format(0, "Waiting for CT (~p) to finish (~p)...",
[Pid,Retries]),
@@ -351,13 +372,33 @@ locate({parallel,TEvs}, Node, Evs, Config) ->
case Evs of
[{TEH,#event{name=tc_start,
node=Node,
- data={M,{init_per_group,GroupName,Props}}}},
- {TEH,#event{name=tc_done,
- node=Node,
- data={M,{init_per_group,GroupName,Props},R}}} | Es] ->
+ data={M,{init_per_group,
+ GroupName,Props}}}}|Es] ->
+ %% Use dropwhile here as a tc_done from a
+ %% previous testcase might sneak in here
+ EvsG = lists:dropwhile(
+ fun({EH,#event{name=tc_done,
+ node=EvNode,
+ data={EvM,{init_per_group,
+ EvGroupName,
+ EvProps},EvR}}})
+ when TEH == EH, EvNode == Node, EvM == M,
+ EvGroupName == GroupName,
+ EvProps == Props,
+ EvR == R ->
+ false;
+ ({EH,#event{name=stop_logging,
+ node=EvNode,data=_}})
+ when EH == TEH, EvNode == Node ->
+ exit({group_init_done_not_found,
+ GroupName,Props});
+ (_) ->
+ true
+ end, Es),
+
test_server:format("Found ~p!", [InitStart]),
test_server:format("Found ~p!", [InitDone]),
- {TEs,Es};
+ {TEs,EvsG};
_ ->
nomatch
end;
@@ -846,22 +887,49 @@ locate({TEH,tc_done,{undefined,undefined,{testcase_aborted,
nomatch
end;
-%% matches any event of type Name
-locate({TEH,Name,Data}, Node, [Ev|Evs], Config) when Data == '_' ->
- case Ev of
- {TEH,#event{name=Name, node=Node}} ->
- {Config,Evs};
+%% Negative matching: Given two events, the first should not be present before
+%% the other is matched.
+locate({negative,NotMatch, Match} = Neg, Node, Evs, Config) ->
+ case locate(NotMatch, Node, Evs, Config) of
+ nomatch ->
+ locate(Match, Node, Evs, Config);
_ ->
- nomatch
+ exit({found_negative_event,Neg})
end;
-locate({TEH,Name,Data}, Node, [Ev|Evs], Config) ->
- case Ev of
- {TEH,#event{name=Name, node=Node, data=Data}} ->
- {Config,Evs};
- _ ->
+%% matches any event of type Name
+locate({TEH,Name,Data}, Node, [{TEH,#event{name=Name,
+ data = EvData,
+ node = Node}}|Evs],
+ Config) ->
+ try match_data(Data, EvData) of
+ match ->
+ {Config,Evs}
+ catch _:_ ->
nomatch
- end.
+ end;
+
+locate({_TEH,_Name,_Data}, _Node, [_|_Evs], _Config) ->
+ nomatch.
+
+match_data(D,D) ->
+ match;
+match_data('_',_) ->
+ match;
+match_data(Fun,Data) when is_function(Fun) ->
+ Fun(Data);
+match_data('$proplist',Proplist) ->
+ match_data(
+ fun(List) ->
+ lists:foreach(fun({_,_}) -> ok end,List)
+ end,Proplist);
+match_data([H1|MatchT],[H2|ValT]) ->
+ match_data(H1,H2),
+ match_data(MatchT,ValT);
+match_data(Tuple1,Tuple2) when is_tuple(Tuple1),is_tuple(Tuple2) ->
+ match_data(tuple_to_list(Tuple1),tuple_to_list(Tuple2));
+match_data([],[]) ->
+ match.
log_events(TC, Events, PrivDir) ->
LogFile = filename:join(PrivDir, atom_to_list(TC)++".events"),
diff --git a/lib/common_test/test/ct_testspec_1_SUITE.erl b/lib/common_test/test/ct_testspec_1_SUITE.erl
index dc399bfb4c..e080e074bf 100644
--- a/lib/common_test/test/ct_testspec_1_SUITE.erl
+++ b/lib/common_test/test/ct_testspec_1_SUITE.erl
@@ -29,7 +29,7 @@
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("common_test/include/ct_event.hrl").
-define(eh, ct_test_support_eh).
@@ -56,24 +56,41 @@ init_per_testcase(TestCase, Config) ->
end_per_testcase(TestCase, Config) ->
ct_test_support:end_per_testcase(TestCase, Config).
-all(doc) ->
- ["Run smoke tests of Common Test."];
-
-all(suite) ->
- [all_suites, skip_all_suites,
- suite, skip_suite,
- all_testcases, skip_all_testcases,
- testcase, skip_testcase,
- all_groups, skip_all_groups,
- group, skip_group,
- group_all_testcases, skip_group_all_testcases,
- group_testcase, skip_group_testcase,
- topgroup,
- subgroup, skip_subgroup,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [all_suites, skip_all_suites, suite, skip_suite,
+ all_testcases, skip_all_testcases, testcase,
+ skip_testcase, all_groups, skip_all_groups, group,
+ skip_group, group_all_testcases,
+ skip_group_all_testcases, group_testcase,
+ skip_group_testcase, topgroup, subgroup, skip_subgroup,
subgroup_all_testcases, skip_subgroup_all_testcases,
subgroup_testcase, skip_subgroup_testcase,
- sub_skipped_by_top,
- testcase_in_multiple_groups].
+ sub_skipped_by_top, testcase_in_multiple_groups,
+ order_of_tests_in_multiple_dirs_no_merge_tests,
+ order_of_tests_in_multiple_suites_no_merge_tests,
+ order_of_suites_in_multiple_dirs_no_merge_tests,
+ order_of_groups_in_multiple_dirs_no_merge_tests,
+ order_of_groups_in_multiple_suites_no_merge_tests,
+ order_of_tests_in_multiple_dirs,
+ order_of_tests_in_multiple_suites,
+ order_of_suites_in_multiple_dirs,
+ order_of_groups_in_multiple_dirs,
+ order_of_groups_in_multiple_suites,
+ order_of_tests_in_multiple_suites_with_skip_no_merge_tests,
+ order_of_tests_in_multiple_suites_with_skip,
+ all_plus_one_tc_no_merge_tests,
+ all_plus_one_tc].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%--------------------------------------------------------------------
%% TEST CASES
@@ -366,6 +383,223 @@ testcase_in_multiple_groups(Config) when is_list(Config) ->
setup_and_execute(testcase_in_multiple_groups, TestSpec, Config).
%%%-----------------------------------------------------------------
+%%%
+
+order_of_tests_in_multiple_dirs_no_merge_tests(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestDir2 = filename:join(DataDir, "groups_2"),
+ TestSpec = [{merge_tests, false},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1a]},
+ {cases,TestDir2,groups_22_SUITE,[testcase_1]},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1b]}],
+
+ setup_and_execute(order_of_tests_in_multiple_dirs_no_merge_tests,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_tests_in_multiple_suites_no_merge_tests(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestSpec = [{merge_tests, false},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1a]},
+ {cases,TestDir1,groups_11_SUITE,[testcase_1]},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1b]}],
+
+ setup_and_execute(order_of_tests_in_multiple_suites_no_merge_tests,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_suites_in_multiple_dirs_no_merge_tests(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestDir2 = filename:join(DataDir, "groups_2"),
+ TestSpec = [{merge_tests, false},
+ {suites,TestDir1,groups_12_SUITE},
+ {suites,TestDir2,groups_22_SUITE},
+ {suites,TestDir1,groups_11_SUITE}],
+
+ setup_and_execute(order_of_suites_in_multiple_dirs_no_merge_tests,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_groups_in_multiple_dirs_no_merge_tests(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestDir2 = filename:join(DataDir, "groups_2"),
+ TestSpec = [{merge_tests, false},
+ {groups,TestDir1,groups_12_SUITE,test_group_1a},
+ {groups,TestDir2,groups_22_SUITE,test_group_1a},
+ {groups,TestDir1,groups_12_SUITE,test_group_1b}],
+
+ setup_and_execute(order_of_groups_in_multiple_dirs_no_merge_tests,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_groups_in_multiple_suites_no_merge_tests(Config)
+ when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestSpec = [{merge_tests, false},
+ {groups,TestDir1,groups_12_SUITE,test_group_1a},
+ {groups,TestDir1,groups_11_SUITE,test_group_1a},
+ {groups,TestDir1,groups_12_SUITE,test_group_1b}],
+
+ setup_and_execute(order_of_groups_in_multiple_suites_no_merge_tests,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_tests_in_multiple_suites_with_skip_no_merge_tests(Config)
+ when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestSpec = [{merge_tests, false},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1a]},
+ {cases,TestDir1,groups_11_SUITE,[testcase_1]},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1b]},
+ {cases,TestDir1,groups_11_SUITE,[testcase_2]},
+ {skip_cases,TestDir1,groups_12_SUITE,[testcase_1b],"Skip it"}],
+
+ setup_and_execute(
+ order_of_tests_in_multiple_suites_with_skip_no_merge_tests,
+ TestSpec, Config).
+
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_tests_in_multiple_dirs(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestDir2 = filename:join(DataDir, "groups_2"),
+ TestSpec = [{cases,TestDir1,groups_12_SUITE,[testcase_1a]},
+ {cases,TestDir2,groups_22_SUITE,[testcase_1]},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1b]}],
+
+ setup_and_execute(order_of_tests_in_multiple_dirs,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_tests_in_multiple_suites(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestSpec = [{cases,TestDir1,groups_12_SUITE,[testcase_1a]},
+ {cases,TestDir1,groups_11_SUITE,[testcase_1]},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1b]}],
+
+ setup_and_execute(order_of_tests_in_multiple_suites,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_suites_in_multiple_dirs(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestDir2 = filename:join(DataDir, "groups_2"),
+ TestSpec = [{suites,TestDir1,groups_12_SUITE},
+ {suites,TestDir2,groups_22_SUITE},
+ {suites,TestDir1,groups_11_SUITE}],
+
+ setup_and_execute(order_of_suites_in_multiple_dirs,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_groups_in_multiple_dirs(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestDir2 = filename:join(DataDir, "groups_2"),
+ TestSpec = [{groups,TestDir1,groups_12_SUITE,test_group_1a},
+ {groups,TestDir2,groups_22_SUITE,test_group_1a},
+ {groups,TestDir1,groups_12_SUITE,test_group_1b}],
+
+ setup_and_execute(order_of_groups_in_multiple_dirs,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_groups_in_multiple_suites(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestSpec = [{groups,TestDir1,groups_12_SUITE,test_group_1a},
+ {groups,TestDir1,groups_11_SUITE,test_group_1a},
+ {groups,TestDir1,groups_12_SUITE,test_group_1b}],
+
+ setup_and_execute(order_of_groups_in_multiple_suites,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+order_of_tests_in_multiple_suites_with_skip(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestSpec = [{cases,TestDir1,groups_12_SUITE,[testcase_1a]},
+ {cases,TestDir1,groups_11_SUITE,[testcase_1]},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1b]},
+ {cases,TestDir1,groups_11_SUITE,[testcase_2]},
+ {skip_cases,TestDir1,groups_12_SUITE,[testcase_1b],"Skip it!"}],
+
+ setup_and_execute(order_of_tests_in_multiple_suites_with_skip,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+all_plus_one_tc_no_merge_tests(Config) when is_list(Config) ->
+
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestSpec = [{merge_tests,false},
+ {suites,TestDir1,groups_12_SUITE},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1a]}],
+
+ setup_and_execute(all_plus_one_tc_no_merge_tests,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
+%%%
+
+all_plus_one_tc(Config) when is_list(Config) ->
+
+ DataDir = ?config(data_dir, Config),
+
+ TestDir1 = filename:join(DataDir, "groups_1"),
+ TestSpec = [{suites,TestDir1,groups_12_SUITE},
+ {cases,TestDir1,groups_12_SUITE,[testcase_1a]}],
+
+ setup_and_execute(all_plus_one_tc,
+ TestSpec, Config).
+
+%%%-----------------------------------------------------------------
%%% HELP FUNCTIONS
%%%-----------------------------------------------------------------
@@ -428,6 +662,719 @@ events_to_check(_, 0) ->
events_to_check(Test, N) ->
test_events(Test) ++ events_to_check(Test, N-1).
+test_events(all_suites) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{simple_1_SUITE,init_per_suite}},
+ {?eh,tc_done,{simple_1_SUITE,end_per_suite,'_'}},
+ {?eh,tc_start,{simple_2_SUITE,init_per_suite}},
+ {?eh,test_stats,{4,0,{0,0}}},
+ {?eh,tc_done,{simple_2_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_all_suites) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_user_skip,{simple_1_SUITE,all,"SKIPPED!"}},
+ {?eh,tc_user_skip,{simple_2_SUITE,all,"SKIPPED!"}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(suite) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{simple_1_SUITE,init_per_suite}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_done,{simple_1_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_suite) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_user_skip,{simple_1_SUITE,all,"SKIPPED!"}},
+ {?eh,tc_done,{simple_2_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(all_testcases) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{simple_1_SUITE,init_per_suite}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_done,{simple_1_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_all_testcases) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_user_skip,{simple_1_SUITE,all,"SKIPPED!"}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(testcase) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{simple_1_SUITE,init_per_suite}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {negative,{?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_done,{simple_1_SUITE,end_per_suite,'_'}}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_testcase) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{simple_1_SUITE,init_per_suite}},
+ {?eh,tc_user_skip,{simple_1_SUITE,tc1,"SKIPPED!"}},
+ {?eh,tc_start,{simple_1_SUITE,tc2}},
+ {?eh,tc_start,{simple_1_SUITE,end_per_suite}},
+
+ {?eh,tc_start,{simple_2_SUITE,init_per_suite}},
+ {?eh,tc_user_skip,{simple_2_SUITE,tc2,"SKIPPED!"}},
+ {?eh,tc_start,{simple_2_SUITE,tc1}},
+ {?eh,test_stats,{2,0,{2,0}}},
+ {?eh,tc_start,{simple_2_SUITE,end_per_suite}},
+
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(all_groups) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,test_stats,{12,0,{0,0}}},
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_all_groups) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_user_skip, {groups_11_SUITE,{group,test_group_1a},"SKIPPED!"}},
+ {?eh,test_stats,{0,0,{1,0}}},
+ {?eh,tc_user_skip, {groups_11_SUITE,{group,test_group_1b},"SKIPPED!"}},
+ {?eh,test_stats,{0,0,{2,0}}},
+ {?eh,tc_user_skip, {groups_11_SUITE,{group,test_group_2},"SKIPPED!"}},
+ {?eh,test_stats,{0,0,{3,0}}},
+ {?eh,tc_user_skip, {groups_11_SUITE,{group,test_group_4},"SKIPPED!"}},
+ {?eh,test_stats,{0,0,{4,0}}},
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(group) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1a,[]}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1a,[]},'_'}},
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_group) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+
+ {?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1a,[]}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1a,[]},'_'}},
+
+ {?eh,tc_user_skip, {groups_11_SUITE,{group,test_group_1b},"SKIPPED!"}},
+ {?eh,test_stats,{2,0,{1,0}}},
+ {negative,{?eh,tc_user_skip,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(group_all_testcases) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1a,[]}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1a,[]},'_'}},
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_group_all_testcases) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_user_skip, {groups_11_SUITE,{group,test_group_1a},"SKIPPED!"}},
+ {?eh,tc_user_skip, {groups_11_SUITE,{group,test_group_1b},"SKIPPED!"}},
+ {?eh,test_stats,{0,0,{2,0}}},
+ {?eh,tc_start,{groups_11_SUITE,end_per_suite}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(group_testcase) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1a,[]}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {negative,{?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1a,[]},'_'}}},
+
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_group_testcase) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+
+ {?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1a,[]}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1a}},
+ {?eh,tc_user_skip,{groups_11_SUITE,testcase_1b,"SKIPPED!"}},
+ {?eh,test_stats,{1,0,{1,0}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1a,[]},'_'}},
+
+ {?eh,tc_start,{groups_11_SUITE,{init_per_group,test_group_1b,[]}}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1b}},
+ {?eh,tc_user_skip,{groups_11_SUITE,testcase_1a,"SKIPPED!"}},
+ {?eh,test_stats,{2,0,{2,0}}},
+ {?eh,tc_done,{groups_11_SUITE,{end_per_group,test_group_1b,[]},'_'}},
+
+ {negative,{?eh,tc_user_skip,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(topgroup) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}},
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]}}}
+ ],
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_3,[]}}}
+ ],
+ {?eh,test_stats,{6,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_2,[parallel]},ok}}]},
+
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_4,[]}}},
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}},
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,'_'}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_7,'_'}}}],
+ {shuffle,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_8,
+ [{shuffle,'_'},sequence]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_8,
+ [{shuffle,'_'},sequence]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_8,
+ [shuffle,sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_8,
+ [shuffle,sequence]},ok}}
+ ]},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_6,[parallel]},ok}}
+ ]},
+ {?eh,test_stats,{12,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_5,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_4,[]}}}],
+
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(subgroup) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}},
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]}}}
+ ],
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_3,[]}}}
+ ],
+ {?eh,test_stats,{4,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_2,[parallel]},ok}}]},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_subgroup) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_4,[]}}},
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}},
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,'_'}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_7,'_'}}}],
+ {?eh,tc_user_skip,
+ {groups_12_SUITE,{group,test_group_8},"SKIPPED!"}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_6,[parallel]},ok}}
+ ]},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_5,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_4,[]}}}],
+
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(subgroup_all_testcases) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_4,[]}}},
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}},
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,'_'}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_7,'_'}}}],
+ {shuffle,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_8,
+ [{shuffle,'_'},sequence]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_8,
+ [{shuffle,'_'},sequence]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_8,
+ [shuffle,sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_8,
+ [shuffle,sequence]},ok}}
+ ]},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_6,[parallel]},ok}}
+ ]},
+ {?eh,test_stats,{6,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_5,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_4,[]}}}],
+
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}},
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]}}}
+ ],
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,test_stats,{10,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_3,[]}}}
+ ],
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_2,[parallel]},ok}}]},
+
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_subgroup_all_testcases) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_4,[]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_4,[]},ok}},
+ {?eh,tc_user_skip,{groups_12_SUITE,{group,test_group_5},"SKIPPED!"}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_4,[]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_4,[]},ok}}
+ ],
+
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(subgroup_testcase) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_4,[]}}},
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}},
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,'_'}}},
+ {?eh,test_stats,{1,0,{0,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_7,'_'}}}],
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_6,[parallel]},ok}}
+ ]},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_5,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_4,[]}}}],
+
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_2,[parallel]},ok}},
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_3,[{repeat,2}]}}},
+ {?eh,test_stats,{2,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_3,[{repeat,2}]}}}
+ ],
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_3,[]}}},
+ {?eh,test_stats,{3,0,{0,0}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_3,[]}}}
+ ],
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_2,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_2,[parallel]},ok}}]},
+
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(skip_subgroup_testcase) ->
+ [
+
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_4,[]}}},
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_5,[parallel]},ok}},
+ {parallel,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_6,[parallel]},ok}},
+ [{?eh,tc_start,{groups_12_SUITE,{init_per_group,test_group_7,'_'}}},
+ {?eh,tc_user_skip, {groups_12_SUITE,testcase_7a,"SKIPPED!"}},
+ {?eh,test_stats,{1,0,{1,0}}},
+ {?eh,tc_user_skip, {groups_12_SUITE,testcase_7b,"SKIPPED!"}},
+ {?eh,test_stats,{1,0,{2,0}}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_7,'_'}}}],
+ {shuffle,
+ [{?eh,tc_start,
+ {groups_12_SUITE,{init_per_group,test_group_8,
+ [{shuffle,'_'},sequence]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{init_per_group,test_group_8,
+ [{shuffle,'_'},sequence]},ok}},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_8,
+ [shuffle,sequence]}}},
+ {?eh,tc_done,{groups_12_SUITE,{end_per_group,test_group_8,
+ [shuffle,sequence]},ok}}
+ ]},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_6,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_6,[parallel]},ok}}
+ ]},
+ {?eh,test_stats,{4,0,{2,0}}},
+ {?eh,tc_start,
+ {groups_12_SUITE,{end_per_group,test_group_5,[parallel]}}},
+ {?eh,tc_done,
+ {groups_12_SUITE,{end_per_group,test_group_5,[parallel]},ok}}]},
+ {?eh,tc_start,{groups_12_SUITE,{end_per_group,test_group_4,[]}}}],
+
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+
+ ];
+
+test_events(sub_skipped_by_top) ->
+ [
+ {?eh,start_logging,'_'},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+
+ {?eh,tc_user_skip,{groups_12_SUITE,{group,test_group_4},"SKIPPED!"}},
+
+ {negative,
+ {?eh,tc_user_skip,{groups_12_SUITE,{group,test_group_4},"SKIPPED!"}},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}}},
+
+ {negative,{?eh,tc_start,'_'},{?eh,stop_logging,'_'}}
+ ];
+
+test_events(testcase_in_multiple_groups) ->
+ [];
+
+test_events(order_of_tests_in_multiple_dirs_no_merge_tests) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done, {groups_12_SUITE,testcase_1a,
+ {failed,{error,{test_case_failed,no_group_data}}}}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_1,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done, {groups_12_SUITE,testcase_1b,
+ {failed,{error,{test_case_failed,no_group_data}}}}},
+ {?eh,stop_logging,[]}
+ ];
+test_events(order_of_tests_in_multiple_suites_no_merge_tests) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,'_'}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1,ok}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1b,'_'}},
+ {?eh,stop_logging,[]}
+ ];
+test_events(order_of_suites_in_multiple_dirs_no_merge_tests) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,init_per_suite,'_'}},
+ {?eh,tc_start,{groups_12_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {?eh,tc_start,{groups_22_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_22_SUITE,init_per_suite,'_'}},
+ {?eh,tc_start,{groups_22_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_22_SUITE,end_per_suite,'_'}},
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,init_per_suite,'_'}},
+ {?eh,tc_start,{groups_11_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,'_'}},
+ {?eh,stop_logging,[]}];
+test_events(order_of_groups_in_multiple_dirs_no_merge_tests) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+
+ {?eh,tc_start, {groups_12_SUITE,{init_per_group,test_group_1a,'_'}}},
+ {?eh,tc_done, {groups_12_SUITE,{end_per_group,test_group_1a,'_'},'_'}},
+
+ {?eh,tc_start, {groups_22_SUITE,{init_per_group,test_group_1a,'_'}}},
+ {?eh,tc_done, {groups_22_SUITE,{end_per_group,test_group_1a,'_'},'_'}},
+
+ {?eh,tc_start, {groups_12_SUITE,{init_per_group,test_group_1b,'_'}}},
+ {?eh,tc_done, {groups_12_SUITE,{end_per_group,test_group_1b,'_'},'_'}},
+
+ {?eh,stop_logging,[]}];
+test_events(order_of_groups_in_multiple_suites_no_merge_tests) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+
+ {?eh,tc_start, {groups_12_SUITE,{init_per_group,test_group_1a,'_'}}},
+ {?eh,tc_done, {groups_12_SUITE,{end_per_group,test_group_1a,'_'},'_'}},
+
+ {?eh,tc_start, {groups_11_SUITE,{init_per_group,test_group_1a,'_'}}},
+ {?eh,tc_done, {groups_11_SUITE,{end_per_group,test_group_1a,'_'},'_'}},
+
+ {?eh,tc_start, {groups_12_SUITE,{init_per_group,test_group_1b,'_'}}},
+ {?eh,tc_done, {groups_12_SUITE,{end_per_group,test_group_1b,'_'},'_'}},
+
+ {?eh,stop_logging,[]}];
+test_events(order_of_tests_in_multiple_suites_with_skip_no_merge_tests) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,'_'}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1,ok}},
+ {?eh,tc_user_skip,{groups_12_SUITE,testcase_1b,'_'}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2,ok}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(order_of_tests_in_multiple_dirs) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,
+ {groups_12_SUITE,testcase_1a,
+ {failed,{error,{test_case_failed,no_group_data}}}}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,
+ {groups_12_SUITE,testcase_1b,
+ {failed,{error,{test_case_failed,no_group_data}}}}},
+ {?eh,tc_start,{groups_22_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_22_SUITE,testcase_1,ok}},
+ {?eh,stop_logging,[]}
+ ];
+test_events(order_of_tests_in_multiple_suites) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,'_'}},
+
+ {?eh,tc_start,{groups_12_SUITE,testcase_1b}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1b,'_'}},
+
+ {?eh,tc_start,{groups_11_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1,ok}},
+ {?eh,stop_logging,[]}
+ ];
+test_events(order_of_suites_in_multiple_dirs) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,init_per_suite,'_'}},
+ {?eh,tc_start,{groups_12_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+
+ {?eh,tc_start,{groups_11_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,init_per_suite,'_'}},
+ {?eh,tc_start,{groups_11_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_11_SUITE,end_per_suite,'_'}},
+
+ {?eh,tc_start,{groups_22_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_22_SUITE,init_per_suite,'_'}},
+ {?eh,tc_start,{groups_22_SUITE,end_per_suite}},
+ {?eh,tc_done,{groups_22_SUITE,end_per_suite,'_'}},
+ {?eh,stop_logging,[]}];
+test_events(order_of_groups_in_multiple_dirs) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+
+ {?eh,tc_start, {groups_12_SUITE,{init_per_group,test_group_1a,'_'}}},
+ {?eh,tc_done, {groups_12_SUITE,{end_per_group,test_group_1a,'_'},'_'}},
+
+ {?eh,tc_start, {groups_12_SUITE,{init_per_group,test_group_1b,'_'}}},
+ {?eh,tc_done, {groups_12_SUITE,{end_per_group,test_group_1b,'_'},'_'}},
+
+ {?eh,tc_start, {groups_22_SUITE,{init_per_group,test_group_1a,'_'}}},
+ {?eh,tc_done, {groups_22_SUITE,{end_per_group,test_group_1a,'_'},'_'}},
+
+ {?eh,stop_logging,[]}];
+test_events(order_of_groups_in_multiple_suites) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+
+ {?eh,tc_start, {groups_12_SUITE,{init_per_group,test_group_1a,'_'}}},
+ {?eh,tc_done, {groups_12_SUITE,{end_per_group,test_group_1a,'_'},'_'}},
+
+ {?eh,tc_start, {groups_12_SUITE,{init_per_group,test_group_1b,'_'}}},
+ {?eh,tc_done, {groups_12_SUITE,{end_per_group,test_group_1b,'_'},'_'}},
+
+ {?eh,tc_start, {groups_11_SUITE,{init_per_group,test_group_1a,'_'}}},
+ {?eh,tc_done, {groups_11_SUITE,{end_per_group,test_group_1a,'_'},'_'}},
+
+ {?eh,stop_logging,[]}];
+
+test_events(order_of_tests_in_multiple_suites_with_skip) ->
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_start,{groups_12_SUITE,testcase_1a}},
+ {?eh,tc_done,{groups_12_SUITE,testcase_1a,'_'}},
+ {?eh,tc_user_skip,{groups_12_SUITE,testcase_1b,'_'}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_1}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_1,ok}},
+ {?eh,tc_start,{groups_11_SUITE,testcase_2}},
+ {?eh,tc_done,{groups_11_SUITE,testcase_2,ok}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(all_plus_one_tc_no_merge_tests) ->
+
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {?eh,stop_logging,[]}
+ ];
+
+test_events(all_plus_one_tc) ->
+
+ [{?eh,start_logging,{'DEF','RUNDIR'}},
+ {?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+ {?eh,tc_done,{groups_12_SUITE,end_per_suite,'_'}},
+ {negative,{?eh,tc_start,{groups_12_SUITE,init_per_suite}},
+ {?eh,stop_logging,[]}}
+ ];
+
test_events(_) ->
[
].
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index 413ef21df3..1a820848b5 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1,3 +1,3 @@
-COMMON_TEST_VSN = 1.5.1
+COMMON_TEST_VSN = 1.5.2
diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml
index e1f24b602d..f2af932aef 100644
--- a/lib/compiler/doc/src/compile.xml
+++ b/lib/compiler/doc/src/compile.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2010</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -164,6 +164,70 @@
for details.</p>
</item>
+ <tag><c>makedep</c></tag>
+ <item>
+ <p>Produce a Makefile rule to track headers dependencies.
+ No object file is produced.
+ </p>
+ <p>By default, this rule is written to
+ <c><![CDATA[<File>.Pbeam]]></c>. However, if the option
+ <c>binary</c> is set, nothing is written and the rule is
+ returned in <c>Binary</c>.
+ </p>
+ <p>For instance, if one has the following module:
+ </p>
+ <code>
+-module(module).
+
+-include_lib("eunit/include/eunit.hrl").
+-include("header.hrl").
+ </code>
+ <p>Here is the Makefile rule generated by this option:
+ </p>
+ <code>
+module.beam: module.erl \
+ /usr/local/lib/erlang/lib/eunit/include/eunit.hrl \
+ header.hrl
+ </code>
+ </item>
+
+ <tag><c>{makedep_output, Output}</c></tag>
+ <item>
+ <p>Write generated rule(s) to <c>Output</c> instead of the
+ default <c><![CDATA[<File>.Pbeam]]></c>. <c>Output</c>
+ can be a filename or an <c>io_device()</c>. To write to
+ stdout, use <c>standard_io</c>. However if <c>binary</c>
+ is set, nothing is written to <c>Output</c> and the
+ result is returned to the caller with
+ <c>{ok, ModuleName, Binary}</c>.
+ </p>
+ </item>
+
+ <tag><c>{makedep_target, Target}</c></tag>
+ <item>
+ <p>Change the name of the rule emitted to <c>Target</c>.
+ </p>
+ </item>
+
+ <tag><c>makedep_quote_target</c></tag>
+ <item>
+ <p>Characters in <c>Target</c> special to make(1) are quoted.
+ </p>
+ </item>
+
+ <tag><c>makedep_add_missing</c></tag>
+ <item>
+ <p>Consider missing headers as generated files and add them to the
+ dependencies.
+ </p>
+ </item>
+
+ <tag><c>makedep_phony</c></tag>
+ <item>
+ <p>Add a phony target for each dependency.
+ </p>
+ </item>
+
<tag><c>'P'</c></tag>
<item>
<p>Produces a listing of the parsed code after preprocessing
@@ -310,9 +374,9 @@
(there will not even be a warning if there is a mismatch).</p>
</item>
- <tag><c>{no_auto_import,[F/A, ...]}</c></tag>
+ <tag><c>{no_auto_import,[{F,A}, ...]}</c></tag>
<item>
- <p>Makes the function <c>F/A</c> no longer beeing
+ <p>Makes the function <c>F/A</c> no longer being
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
@@ -323,8 +387,12 @@
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>
+ <c>{ no_auto_import,[{F,A}, ...]}</c></p>
</note>
+ <p>If this option is written in the source code, as a
+ <c>-compile</c> directive, the syntax <c>F/A</c> can be used instead
+ of <c>{F,A}</c>. Example:</p>
+ <code>-compile({no_auto_import,[error/1]}).</code>
</item>
</taglist>
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index 00ea0da55c..9d89b17afb 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -31,6 +31,56 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 4.7.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Two compiler bugs (that would cause the compiler to
+ terminate) reported by Christopher Williams have been
+ fixed.</p>
+ <p>
+ Own Id: OTP-8949</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The compiler would translate binary comprehensions
+ containing tail segments in a way that would would
+ confuse Dialyzer. For instance:</p>
+ <p><c>[42 || &lt;&lt;_:8/integer, _/bits&gt;&gt; &lt;=
+ Bits]</c></p>
+ <p>
+ would produce a Dialyzer warning.</p>
+ <p>
+ Own Id: OTP-8864</p>
+ </item>
+ <item>
+ <p>
+ Code such as <c>foo(A) -&gt; &lt;&lt;A:0&gt;&gt;</c>
+ would crash the compiler.</p>
+ <p>
+ Own Id: OTP-8865</p>
+ </item>
+ <item>
+ <p>
+ The compiler could fail with an internal error when
+ variables were exported from a receive block but the
+ return value of the receive block were not used. (Thanks
+ to Jim Engquist for reporting this error.)</p>
+ <p>
+ Own Id: OTP-8888</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Compiler 4.7.1</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index 0f6d2f6193..9da9253f5b 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -118,7 +118,9 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
ifeq ($(NATIVE_LIBS_ENABLED),yes)
ERL_COMPILE_FLAGS += +native
endif
-ERL_COMPILE_FLAGS += +inline +warn_unused_import -I../../stdlib/include -I$(EGEN) -W
+ERL_COMPILE_FLAGS += +inline +warn_unused_import \
+ +warnings_as_errors \
+ -I../../stdlib/include -I$(EGEN) -W
# ----------------------------------------------------
# Targets
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl
index 9c6f835ab0..c45874597a 100644
--- a/lib/compiler/src/beam_block.erl
+++ b/lib/compiler/src/beam_block.erl
@@ -36,12 +36,13 @@ function({function,Name,Arity,CLabel,Is0}, Lc0) ->
%% Collect basic blocks and optimize them.
Is2 = blockify(Is1),
- Is3 = beam_utils:live_opt(Is2),
- Is4 = opt_blocks(Is3),
- Is5 = beam_utils:delete_live_annos(Is4),
+ Is3 = move_allocates(Is2),
+ Is4 = beam_utils:live_opt(Is3),
+ Is5 = opt_blocks(Is4),
+ Is6 = beam_utils:delete_live_annos(Is5),
%% Optimize bit syntax.
- {Is,Lc} = bsm_opt(Is5, Lc0),
+ {Is,Lc} = bsm_opt(Is6, Lc0),
%% Done.
{{function,Name,Arity,CLabel,Is},Lc}
@@ -156,11 +157,7 @@ opt_blocks([I|Is]) ->
opt_blocks([]) -> [].
opt_block(Is0) ->
- %% We explicitly move any allocate instruction upwards before optimising
- %% moves, to avoid any potential problems with the calculation of live
- %% registers.
- Is1 = move_allocates(Is0),
- Is = find_fixpoint(fun opt/1, Is1),
+ Is = find_fixpoint(fun opt/1, Is0),
opt_alloc(Is).
find_fixpoint(OptFun, Is0) ->
@@ -170,11 +167,21 @@ find_fixpoint(OptFun, Is0) ->
end.
%% move_allocates(Is0) -> Is
-%% Move allocates upwards in the instruction stream, in the hope of
-%% getting more possibilities for optimizing away moves later.
-
-move_allocates(Is) ->
- move_allocates_1(reverse(Is), []).
+%% Move allocate instructions upwards in the instruction stream, in the
+%% hope of getting more possibilities for optimizing away moves later.
+%%
+%% NOTE: Moving allocation instructions is only safe because it is done
+%% immediately after code generation so that we KNOW that if {x,X} is
+%% initialized, all x registers with lower numbers are also initialized.
+%% That assumption may not be true after other optimizations, such as
+%% the beam_utils:live_opt/1 optimization.
+
+move_allocates([{block,Bl0}|Is]) ->
+ Bl = move_allocates_1(reverse(Bl0), []),
+ [{block,Bl}|move_allocates(Is)];
+move_allocates([I|Is]) ->
+ [I|move_allocates(Is)];
+move_allocates([]) -> [].
move_allocates_1([{set,[],[],{alloc,_,_}=Alloc}|Is0], Acc0) ->
{Is,Acc} = move_allocates_2(Alloc, Is0, Acc0),
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 761d4ffec0..45cdf8a659 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -407,16 +407,23 @@ check_liveness(R, [{bif,Op,{f,Fail},Ss,D}|Is], St0) ->
Other ->
Other
end;
-check_liveness(R, [{gc_bif,Op,{f,Fail},_,Ss,D}|Is], St0) ->
- case check_liveness_fail(R, Op, Ss, Fail, St0) of
- {killed,St} = Killed ->
- case member(R, Ss) of
- true -> {used,St};
- false when R =:= D -> Killed;
- false -> check_liveness(R, Is, St)
- end;
- Other ->
- Other
+check_liveness(R, [{gc_bif,Op,{f,Fail},Live,Ss,D}|Is], St0) ->
+ case R of
+ {x,X} when X >= Live ->
+ {killed,St0};
+ {x,_} ->
+ {used,St0};
+ _ ->
+ case check_liveness_fail(R, Op, Ss, Fail, St0) of
+ {killed,St}=Killed ->
+ case member(R, Ss) of
+ true -> {used,St};
+ false when R =:= D -> Killed;
+ false -> check_liveness(R, Is, St)
+ end;
+ Other ->
+ Other
+ end
end;
check_liveness(R, [{bs_add,{f,0},Ss,D}|Is], St) ->
case member(R, Ss) of
@@ -482,10 +489,13 @@ check_liveness(R, [{bs_context_to_binary,S}|Is], St) ->
S -> {used,St};
_ -> check_liveness(R, Is, St)
end;
-check_liveness(R, [{loop_rec,{f,_},{x,0}}|Is], St) ->
+check_liveness(R, [{loop_rec,{f,_},{x,0}}|_], St) ->
case R of
- {x,_} -> {killed,St};
- _ -> check_liveness(R, Is, St)
+ {x,_} ->
+ {killed,St};
+ _ ->
+ %% y register. Rarely happens. Be very conversative.
+ {unknown,St}
end;
check_liveness(R, [{loop_rec_end,{f,Fail}}|_], St) ->
check_liveness_at(R, Fail, St);
diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl
index d1fd9d40e2..4b74d60e9f 100644
--- a/lib/compiler/src/cerl.erl
+++ b/lib/compiler/src/cerl.erl
@@ -973,7 +973,7 @@ atom_name(Node) ->
%% TODO: replace the use of the unofficial 'write_string/2'.
--spec atom_lit(cerl()) -> string().
+-spec atom_lit(cerl()) -> nonempty_string().
atom_lit(Node) ->
io_lib:write_string(atom_name(Node), $'). %' stupid Emacs.
@@ -1079,7 +1079,7 @@ char_val(Node) ->
%%
%% @see c_char/1
--spec char_lit(c_literal()) -> string().
+-spec char_lit(c_literal()) -> nonempty_string().
char_lit(Node) ->
io_lib:write_char(char_val(Node)).
@@ -1178,7 +1178,7 @@ string_val(Node) ->
%%
%% @see c_string/1
--spec string_lit(c_literal()) -> string().
+-spec string_lit(c_literal()) -> nonempty_string().
string_lit(Node) ->
io_lib:write_string(string_val(Node)).
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 26da3ecad2..ce8a5bf864 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -112,9 +112,10 @@ noenv_forms(Forms, Opt) when is_atom(Opt) ->
-spec noenv_output_generated([option()]) -> boolean().
noenv_output_generated(Opts) ->
+ {_,Passes} = passes(file, expand_opts(Opts)),
any(fun ({save_binary,_F}) -> true;
(_Other) -> false
- end, passes(file, expand_opts(Opts))).
+ end, Passes).
%%
%% Local functions
@@ -205,6 +206,9 @@ format_error(write_error) ->
format_error({rename,From,To,Error}) ->
io_lib:format("failed to rename ~s to ~s: ~s",
[From,To,file:format_error(Error)]);
+format_error({delete,File,Error}) ->
+ io_lib:format("failed to delete file ~s: ~s",
+ [File,file:format_error(Error)]);
format_error({delete_temp,File,Error}) ->
io_lib:format("failed to delete temporary file ~s: ~s",
[File,file:format_error(Error)]);
@@ -240,26 +244,12 @@ internal(Master, Input, Opts) ->
end}.
internal({forms,Forms}, Opts) ->
- Ps = passes(forms, Opts),
+ {_,Ps} = passes(forms, Opts),
internal_comp(Ps, "", "", #compile{code=Forms,options=Opts});
internal({file,File}, Opts) ->
- Ps = passes(file, Opts),
+ {Ext,Ps} = passes(file, Opts),
Compile = #compile{options=Opts},
- case member(from_core, Opts) of
- true -> internal_comp(Ps, File, ".core", Compile);
- false ->
- case member(from_beam, Opts) of
- true ->
- internal_comp(Ps, File, ".beam", Compile);
- false ->
- case member(from_asm, Opts) orelse member(asm, Opts) of
- true ->
- internal_comp(Ps, File, ".S", Compile);
- false ->
- internal_comp(Ps, File, ".erl", Compile)
- end
- end
- end.
+ internal_comp(Ps, File, Ext, Compile).
internal_comp(Passes, File, Suffix, St0) ->
Dir = filename:dirname(File),
@@ -367,42 +357,52 @@ mpf(Ms) ->
[{File,[M || {F,M} <- Ms, F =:= File]} ||
File <- lists:usort([F || {F,_} <- Ms])].
-%% passes(forms|file, [Option]) -> [{Name,PassFun}]
-%% Figure out which passes that need to be run.
-
-passes(forms, Opts) ->
- case member(from_core, Opts) of
- true ->
- select_passes(core_passes(), Opts);
- false ->
- select_passes(standard_passes(), Opts)
+%% passes(forms|file, [Option]) -> {Extension,[{Name,PassFun}]}
+%% Figure out the extension of the input file and which passes
+%% that need to be run.
+
+passes(Type, Opts) ->
+ {Ext,Passes0} = passes_1(Opts),
+ Passes1 = case Type of
+ file -> Passes0;
+ forms -> tl(Passes0)
+ end,
+ Passes = select_passes(Passes1, Opts),
+
+ %% If the last pass saves the resulting binary to a file,
+ %% insert a first pass to remove the file (unless the
+ %% source file is a BEAM file).
+ {Ext,case last(Passes) of
+ {save_binary,_Fun} ->
+ case Passes of
+ [{read_beam_file,_}|_] ->
+ %% The BEAM is both input and output.
+ %% Don't remove it.
+ Passes;
+ _ ->
+ [?pass(remove_file)|Passes]
+ end;
+ _ ->
+ Passes
+ end}.
+
+passes_1([Opt|Opts]) ->
+ case pass(Opt) of
+ {_,_}=Res -> Res;
+ none -> passes_1(Opts)
end;
-passes(file, Opts) ->
- case member(from_beam, Opts) of
- true ->
- Ps = [?pass(read_beam_file)|binary_passes()],
- select_passes(Ps, Opts);
- false ->
- Ps = case member(from_asm, Opts) orelse member(asm, Opts) of
- true ->
- [?pass(beam_consult_asm)|asm_passes()];
- false ->
- case member(from_core, Opts) of
- true ->
- [?pass(parse_core)|core_passes()];
- false ->
- [?pass(parse_module)|standard_passes()]
- end
- end,
- Fs = select_passes(Ps, Opts),
-
- %% If the last pass saves the resulting binary to a file,
- %% insert a first pass to remove the file.
- case last(Fs) of
- {save_binary,_Fun} -> [?pass(remove_file)|Fs];
- _Other -> Fs
- end
- end.
+passes_1([]) ->
+ {".erl",[?pass(parse_module)|standard_passes()]}.
+
+pass(from_core) ->
+ {".core",[?pass(parse_core)|core_passes()]};
+pass(from_asm) ->
+ {".S",[?pass(beam_consult_asm)|asm_passes()]};
+pass(asm) ->
+ pass(from_asm);
+pass(from_beam) ->
+ {".beam",[?pass(read_beam_file)|binary_passes()]};
+pass(_) -> none.
%% select_passes([Command], Opts) -> [{Name,Function}]
%% Interpret the lists of commands to return a pure list of passes.
@@ -435,6 +435,8 @@ passes(file, Opts) ->
%% file will be Ext. (Ext should not contain
%% a period.) No more passes will be run.
%%
+%% done End compilation at this point.
+%%
%% {done,Ext} End compilation at this point. Produce a listing
%% as with {listing,Ext}, unless 'binary' is
%% specified, in which case the current
@@ -468,6 +470,8 @@ select_passes([{src_listing,Ext}|_], _Opts) ->
[{listing,fun (St) -> src_listing(Ext, St) end}];
select_passes([{listing,Ext}|_], _Opts) ->
[{listing,fun (St) -> listing(Ext, St) end}];
+select_passes([done|_], _Opts) ->
+ [];
select_passes([{done,Ext}|_], Opts) ->
select_passes([{unless,binary,{listing,Ext}}], Opts);
select_passes([{iff,Flag,Pass}|Ps], Opts) ->
@@ -550,6 +554,13 @@ select_list_passes_1([], _, Acc) ->
standard_passes() ->
[?pass(transform_module),
+
+ {iff,makedep,[
+ ?pass(makedep),
+ {unless,binary,?pass(makedep_output)}
+ ]},
+ {iff,makedep,done},
+
{iff,'dpp',{listing,"pp"}},
?pass(lint_module),
{iff,'P',{src_listing,"P"}},
@@ -901,6 +912,184 @@ core_lint_module(St) ->
errors=St#compile.errors ++ Es}}
end.
+makedep(#compile{code=Code,options=Opts}=St) ->
+ Ifile = St#compile.ifile,
+ Ofile = St#compile.ofile,
+
+ %% Get the target of the Makefile rule.
+ Target0 =
+ case proplists:get_value(makedep_target, Opts) of
+ undefined ->
+ %% The target is derived from the output filename: possibly
+ %% remove the current working directory to obtain a relative
+ %% path.
+ shorten_filename(Ofile);
+ T ->
+ %% The caller specified one.
+ T
+ end,
+
+ %% Quote the target is the called asked for this.
+ Target1 = case proplists:get_value(makedep_quote_target, Opts) of
+ true ->
+ %% For now, only "$" is replaced by "$$".
+ Fun = fun
+ ($$) -> "$$";
+ (C) -> C
+ end,
+ map(Fun, Target0);
+ _ ->
+ Target0
+ end,
+ Target = Target1 ++ ":",
+
+ %% List the dependencies (includes) for this target.
+ {MainRule,PhonyRules} = makedep_add_headers(
+ Ifile, % The input file name.
+ Code, % The parsed source.
+ [], % The list of dependencies already added.
+ length(Target), % The current line length.
+ Target, % The target.
+ "", % Phony targets.
+ Opts),
+
+ %% Prepare the content of the Makefile. For instance:
+ %% hello.erl: hello.hrl common.hrl
+ %%
+ %% Or if phony targets are enabled:
+ %% hello.erl: hello.hrl common.hrl
+ %%
+ %% hello.hrl:
+ %%
+ %% common.hrl:
+ Makefile = case proplists:get_value(makedep_phony, Opts) of
+ true -> MainRule ++ PhonyRules;
+ _ -> MainRule
+ end,
+ {ok,St#compile{code=iolist_to_binary([Makefile,"\n"])}}.
+
+makedep_add_headers(Ifile, [{attribute,_,file,{File,_}}|Rest],
+ Included, LineLen, MainTarget, Phony, Opts) ->
+ %% The header "File" exists, add it to the dependencies.
+ {Included1,LineLen1,MainTarget1,Phony1} =
+ makedep_add_header(Ifile, Included, LineLen, MainTarget, Phony, File),
+ makedep_add_headers(Ifile, Rest, Included1, LineLen1,
+ MainTarget1, Phony1, Opts);
+makedep_add_headers(Ifile, [{error,{_,epp,{include,file,File}}}|Rest],
+ Included, LineLen, MainTarget, Phony, Opts) ->
+ %% The header "File" doesn't exist, do we add it to the dependencies?
+ case proplists:get_value(makedep_add_missing, Opts) of
+ true ->
+ {Included1,LineLen1,MainTarget1,Phony1} =
+ makedep_add_header(Ifile, Included, LineLen, MainTarget,
+ Phony, File),
+ makedep_add_headers(Ifile, Rest, Included1, LineLen1,
+ MainTarget1, Phony1, Opts);
+ _ ->
+ makedep_add_headers(Ifile, Rest, Included, LineLen,
+ MainTarget, Phony, Opts)
+ end;
+makedep_add_headers(Ifile, [_|Rest], Included, LineLen,
+ MainTarget, Phony, Opts) ->
+ makedep_add_headers(Ifile, Rest, Included,
+ LineLen, MainTarget, Phony, Opts);
+makedep_add_headers(_Ifile, [], _Included, _LineLen,
+ MainTarget, Phony, _Opts) ->
+ {MainTarget,Phony}.
+
+makedep_add_header(Ifile, Included, LineLen, MainTarget, Phony, File) ->
+ case member(File, Included) of
+ true ->
+ %% This file was already listed in the dependencies, skip it.
+ {Included,LineLen,MainTarget,Phony};
+ false ->
+ Included1 = [File|Included],
+
+ %% Remove "./" in front of the dependency filename.
+ File1 = case File of
+ "./" ++ File0 -> File0;
+ _ -> File
+ end,
+
+ %% Prepare the phony target name.
+ Phony1 = case File of
+ Ifile -> Phony;
+ _ -> Phony ++ "\n\n" ++ File1 ++ ":"
+ end,
+
+ %% Add the file to the dependencies. Lines longer than 76 columns
+ %% are splitted.
+ if
+ LineLen + 1 + length(File1) > 76 ->
+ LineLen1 = 2 + length(File1),
+ MainTarget1 = MainTarget ++ " \\\n " ++ File1,
+ {Included1,LineLen1,MainTarget1,Phony1};
+ true ->
+ LineLen1 = LineLen + 1 + length(File1),
+ MainTarget1 = MainTarget ++ " " ++ File1,
+ {Included1,LineLen1,MainTarget1,Phony1}
+ end
+ end.
+
+makedep_output(#compile{code=Code,options=Opts,ofile=Ofile}=St) ->
+ %% Write this Makefile (Code) to the selected output.
+ %% If no output is specified, the default is to write to a file named after
+ %% the output file.
+ Output0 = case proplists:get_value(makedep_output, Opts) of
+ undefined ->
+ %% Prepare the default filename.
+ outfile(filename:basename(Ofile, ".beam"), "Pbeam", Opts);
+ O ->
+ O
+ end,
+
+ %% If the caller specified an io_device(), there's nothing to do. If he
+ %% specified a filename, we must create it. Furthermore, this created file
+ %% must be closed before returning.
+ Ret = case Output0 of
+ _ when is_list(Output0) ->
+ case file:delete(Output0) of
+ Ret2 when Ret2 =:= ok; Ret2 =:= {error,enoent} ->
+ case file:open(Output0, [write]) of
+ {ok,IODev} ->
+ {ok,IODev,true};
+ {error,Reason2} ->
+ {error,open,Reason2}
+ end;
+ {error,Reason1} ->
+ {error,delete,Reason1}
+ end;
+ _ ->
+ {ok,Output0,false}
+ end,
+
+ case Ret of
+ {ok,Output1,CloseOutput} ->
+ try
+ %% Write the Makefile.
+ io:fwrite(Output1, "~s", [Code]),
+ %% Close the file if relevant.
+ if
+ CloseOutput -> file:close(Output1);
+ true -> ok
+ end,
+ {ok,St}
+ catch
+ exit:_ ->
+ %% Couldn't write to output Makefile.
+ Err = {St#compile.ifile,[{none,?MODULE,write_error}]},
+ {error,St#compile{errors=St#compile.errors++[Err]}}
+ end;
+ {error,open,Reason} ->
+ %% Couldn't open output Makefile.
+ Err = {St#compile.ifile,[{none,?MODULE,{open,Reason}}]},
+ {error,St#compile{errors=St#compile.errors++[Err]}};
+ {error,delete,Reason} ->
+ %% Couldn't open output Makefile.
+ Err = {St#compile.ifile,[{none,?MODULE,{delete,Output0,Reason}}]},
+ {error,St#compile{errors=St#compile.errors++[Err]}}
+ end.
+
%% expand_module(State) -> State'
%% Do the common preprocessing of the input forms.
diff --git a/lib/compiler/src/core_lint.erl b/lib/compiler/src/core_lint.erl
index b633f568c9..b513a8965c 100644
--- a/lib/compiler/src/core_lint.erl
+++ b/lib/compiler/src/core_lint.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -65,7 +65,8 @@
| {'return_mismatch', fa()} | {'undefined_function', fa()}
| {'duplicate_var', cerl:var_name(), fa()}
| {'unbound_var', cerl:var_name(), fa()}
- | {'undefined_function', fa(), fa()}.
+ | {'undefined_function', fa(), fa()}
+ | {'tail_segment_not_at_end', fa()}.
-type error() :: {module(), err_desc()}.
-type warning() :: {module(), term()}.
@@ -116,7 +117,9 @@ format_error({duplicate_var,N,{F,A}}) ->
format_error({unbound_var,N,{F,A}}) ->
io_lib:format("unbound variable ~s in ~w/~w", [N,F,A]);
format_error({undefined_function,{F1,A1},{F2,A2}}) ->
- io_lib:format("undefined function ~w/~w in ~w/~w", [F1,A1,F2,A2]).
+ io_lib:format("undefined function ~w/~w in ~w/~w", [F1,A1,F2,A2]);
+format_error({tail_segment_not_at_end,{F,A}}) ->
+ io_lib:format("binary tail segment not at end in ~w/~w", [F,A]).
-type ret() :: {'ok', [{module(), [warning(),...]}]}
| {'error', [{module(), [error(),...]}],
@@ -450,7 +453,8 @@ pattern(#c_cons{hd=H,tl=T}, Def, Ps, St) ->
pattern_list([H,T], Def, Ps, St);
pattern(#c_tuple{es=Es}, Def, Ps, St) ->
pattern_list(Es, Def, Ps, St);
-pattern(#c_binary{segments=Ss}, Def, Ps, St) ->
+pattern(#c_binary{segments=Ss}, Def, Ps, St0) ->
+ St = pat_bin_tail_check(Ss, St0),
pat_bin(Ss, Def, Ps, St);
pattern(#c_alias{var=V,pat=P}, Def, Ps, St0) ->
{Vvs,St1} = variable(V, Ps, St0),
@@ -482,6 +486,19 @@ pat_segment(#c_bitstr{val=V,size=S,type=T}, Def0, Ps0, St0) ->
pat_segment(_, Def, Ps, St) ->
{Ps,Def,add_error({not_bs_pattern,St#lint.func}, St)}.
+%% pat_bin_tail_check([Elem], State) -> State.
+%% There must be at most one tail segment (a size-less segment of
+%% type binary) and it must occur at the end.
+
+pat_bin_tail_check([#c_bitstr{size=#c_literal{val=all}}], St) ->
+ %% Size-less field is OK at the end of the list of segments.
+ St;
+pat_bin_tail_check([#c_bitstr{size=#c_literal{val=all}}|_], St) ->
+ add_error({tail_segment_not_at_end,St#lint.func}, St);
+pat_bin_tail_check([_|Ss], St) ->
+ pat_bin_tail_check(Ss, St);
+pat_bin_tail_check([], St) -> St.
+
%% pat_bit_expr(SizePat, Type, Defined, State) -> State.
%% Check the Size pattern, this is an input! Because of optimizations,
%% we must allow any kind of constant and literal here.
diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl
index 948937c438..f24a46c5a9 100644
--- a/lib/compiler/src/v3_codegen.erl
+++ b/lib/compiler/src/v3_codegen.erl
@@ -235,7 +235,7 @@ match_cg(M, Rs, Le, Vdb, Bef, St0) ->
I = Le#l.i,
{Sis,Int0} = adjust_stack(Bef, I, I+1, Vdb),
{B,St1} = new_label(St0),
- {Mis,Int1,St2} = match_cg(M, St0#cg.ultimate_failure,
+ {Mis,Int1,St2} = match_cg(M, St1#cg.ultimate_failure,
Int0, St1#cg{break=B}),
%% Put return values in registers.
Reg = load_vars(Rs, Int1#sr.reg),
@@ -1523,7 +1523,9 @@ cg_binary_size_1([], Bits, Acc) ->
[{1,_}|_] ->
{bs_init_bits,cg_binary_bytes_to_bits(Sizes, [])};
[{8,_}|_] ->
- {bs_init2,[E || {8,E} <- Sizes]}
+ {bs_init2,[E || {8,E} <- Sizes]};
+ [] ->
+ {bs_init_bits,[]}
end.
cg_binary_size_2({integer,N}, U, _, Next, Bits, Acc) ->
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index f6bb45787c..2da24b2908 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -892,25 +892,22 @@ lc_tq(Line, E, [{generate,Lg,P,G}|Qs0], Mc, St0) ->
lc_tq(Line, E, [{b_generate,Lg,P,G}|Qs0], Mc, St0) ->
{Gs,Qs1} = splitwith(fun is_guard_test/1, Qs0),
{Name,St1} = new_fun_name("blc", St0),
- {Tname,St2} = new_var_name(St1),
- LA = lineno_anno(Line, St2),
+ LA = lineno_anno(Line, St1),
LAnno = #a{anno=LA},
- HeadBinPattern = pattern(P,St2),
- #c_binary{segments=Ps} = HeadBinPattern,
- {EPs,St3} = emasculate_segments(Ps,St2),
- Tail = #c_var{anno=LA,name=Tname},
- TailSegment = #c_bitstr{val=Tail,size=#c_literal{val=all},
- unit=#c_literal{val=1},
- type=#c_literal{val=binary},
- flags=#c_literal{val=[big,unsigned]}},
- Pattern = HeadBinPattern#c_binary{segments=Ps ++ [TailSegment]},
- EPattern = HeadBinPattern#c_binary{segments=EPs ++ [TailSegment]},
+ HeadBinPattern = pattern(P, St1),
+ #c_binary{segments=Ps0} = HeadBinPattern,
+ {Ps,Tail,St2} = append_tail_segment(Ps0, St1),
+ {EPs,St3} = emasculate_segments(Ps, St2),
+ Pattern = HeadBinPattern#c_binary{segments=Ps},
+ EPattern = HeadBinPattern#c_binary{segments=EPs},
{Arg,St4} = new_var(St3),
{Guardc,St5} = lc_guard_tests(Gs, St4), %These are always flat!
+ Tname = Tail#c_var.name,
{Nc,[],St6} = expr({call,Lg,{atom,Lg,Name},[{var,Lg,Tname}]}, St5),
{Bc,Bps,St7} = lc_tq(Line, E, Qs1, Nc, St6),
{Gc,Gps,St10} = safe(G, St7), %Will be a function argument!
Fc = function_clause([Arg], LA, {Name,1}),
+ {TailSegList,_,St} = append_tail_segment([], St10),
Cs = [#iclause{anno=#a{anno=[compiler_generated|LA]},
pats=[Pattern],
guard=Guardc,
@@ -922,14 +919,14 @@ lc_tq(Line, E, [{b_generate,Lg,P,G}|Qs0], Mc, St0) ->
op=#c_var{anno=LA,name={Name,1}},
args=[Tail]}]},
#iclause{anno=LAnno,
- pats=[#c_binary{anno=LA, segments=[TailSegment]}],guard=[],
+ pats=[#c_binary{anno=LA,segments=TailSegList}],guard=[],
body=[Mc]}],
Fun = #ifun{anno=LAnno,id=[],vars=[Arg],clauses=Cs,fc=Fc},
{#iletrec{anno=LAnno,defs=[{{Name,1},Fun}],
body=Gps ++ [#iapply{anno=LAnno,
op=#c_var{anno=LA,name={Name,1}},
args=[Gc]}]},
- [],St10};
+ [],St};
lc_tq(Line, E, [Fil0|Qs0], Mc, St0) ->
%% Special case sequences guard tests.
LA = lineno_anno(Line, St0),
@@ -1037,26 +1034,24 @@ bc_tq1(Line, E, [{b_generate,Lg,P,G}|Qs0], AccExpr, St0) ->
{Gs,Qs1} = splitwith(fun is_guard_test/1, Qs0),
{Name,St1} = new_fun_name("lbc", St0),
LA = lineno_anno(Line, St1),
- {[Tail,AccVar],St2} = new_vars(LA, 2, St1),
+ {AccVar,St2} = new_var(LA, St1),
LAnno = #a{anno=LA},
HeadBinPattern = pattern(P, St2),
- #c_binary{segments=Ps} = HeadBinPattern,
- {EPs,St3} = emasculate_segments(Ps, St2),
- TailSegment = #c_bitstr{val=Tail,size=#c_literal{val=all},
- unit=#c_literal{val=1},
- type=#c_literal{val=binary},
- flags=#c_literal{val=[big,unsigned]}},
- Pattern = HeadBinPattern#c_binary{segments=Ps ++ [TailSegment]},
- EPattern = HeadBinPattern#c_binary{segments=EPs ++ [TailSegment]},
- {Arg,St4} = new_var(St3),
+ #c_binary{segments=Ps0} = HeadBinPattern,
+ {Ps,Tail,St3} = append_tail_segment(Ps0, St2),
+ {EPs,St4} = emasculate_segments(Ps, St3),
+ Pattern = HeadBinPattern#c_binary{segments=Ps},
+ EPattern = HeadBinPattern#c_binary{segments=EPs},
+ {Arg,St5} = new_var(St4),
NewMore = {call,Lg,{atom,Lg,Name},[{var,Lg,Tail#c_var.name},
{var,Lg,AccVar#c_var.name}]},
- {Guardc,St5} = lc_guard_tests(Gs, St4), %These are always flat!
- {Bc,Bps,St6} = bc_tq1(Line, E, Qs1, AccVar, St5),
- {Nc,Nps,St7} = expr(NewMore, St6),
- {Gc,Gps,St8} = safe(G, St7), %Will be a function argument!
+ {Guardc,St6} = lc_guard_tests(Gs, St5), %These are always flat!
+ {Bc,Bps,St7} = bc_tq1(Line, E, Qs1, AccVar, St6),
+ {Nc,Nps,St8} = expr(NewMore, St7),
+ {Gc,Gps,St9} = safe(G, St8), %Will be a function argument!
Fc = function_clause([Arg,AccVar], LA, {Name,2}),
Body = Bps ++ Nps ++ [#iset{var=AccVar,arg=Bc},Nc],
+ {TailSegList,_,St} = append_tail_segment([], St9),
Cs = [#iclause{anno=LAnno,
pats=[Pattern,AccVar],
guard=Guardc,
@@ -1066,7 +1061,7 @@ bc_tq1(Line, E, [{b_generate,Lg,P,G}|Qs0], AccExpr, St0) ->
guard=[],
body=Nps ++ [Nc]},
#iclause{anno=LAnno,
- pats=[#c_binary{anno=LA,segments=[TailSegment]},AccVar],
+ pats=[#c_binary{anno=LA,segments=TailSegList},AccVar],
guard=[],
body=[AccVar]}],
Fun = #ifun{anno=LAnno,id=[],vars=[Arg,AccVar],clauses=Cs,fc=Fc},
@@ -1074,7 +1069,7 @@ bc_tq1(Line, E, [{b_generate,Lg,P,G}|Qs0], AccExpr, St0) ->
body=Gps ++ [#iapply{anno=LAnno,
op=#c_var{anno=LA,name={Name,2}},
args=[Gc,AccExpr]}]},
- [],St8};
+ [],St};
bc_tq1(Line, E, [Fil0|Qs0], AccVar, St0) ->
%% Special case sequences guard tests.
LA = lineno_anno(Line, St0),
@@ -1120,6 +1115,29 @@ bc_tq1(_, {bin,Bl,Elements}, [], AccVar, St0) ->
%%Anno = Anno0#a{anno=[compiler_generated|A]},
{set_anno(E, Anno),Pre,St}.
+append_tail_segment(Segs, St) ->
+ app_tail_seg(Segs, St, []).
+
+app_tail_seg([#c_bitstr{val=Var0,size=#c_literal{val=all}}=Seg0]=L,
+ St0, Acc) ->
+ case Var0 of
+ #c_var{name='_'} ->
+ {Var,St} = new_var(St0),
+ Seg = Seg0#c_bitstr{val=Var},
+ {reverse(Acc, [Seg]),Var,St};
+ #c_var{} ->
+ {reverse(Acc, L),Var0,St0}
+ end;
+app_tail_seg([H|T], St, Acc) ->
+ app_tail_seg(T, St, [H|Acc]);
+app_tail_seg([], St0, Acc) ->
+ {Var,St} = new_var(St0),
+ Tail = #c_bitstr{val=Var,size=#c_literal{val=all},
+ unit=#c_literal{val=1},
+ type=#c_literal{val=binary},
+ flags=#c_literal{val=[unsigned,big]}},
+ {reverse(Acc, [Tail]),Var,St}.
+
emasculate_segments(Segs, St) ->
emasculate_segments(Segs, St, []).
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index fbe4d8617e..3b33a08cf7 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -147,6 +147,7 @@ attributes([]) -> [].
include_attribute(type) -> false;
include_attribute(spec) -> false;
include_attribute(opaque) -> false;
+include_attribute(export_type) -> false;
include_attribute(_) -> true.
function({#c_var{name={F,Arity}=FA},Body}, St0) ->
diff --git a/lib/compiler/src/v3_kernel_pp.erl b/lib/compiler/src/v3_kernel_pp.erl
index a300dd283f..e363a5387a 100644
--- a/lib/compiler/src/v3_kernel_pp.erl
+++ b/lib/compiler/src/v3_kernel_pp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,10 +20,12 @@
-module(v3_kernel_pp).
--include("v3_kernel.hrl").
-
-export([format/1]).
+%%-define(INCLUDE_ANNOTATIONS, 1).
+
+-include("v3_kernel.hrl").
+
%% These are "internal" structures in sys_kernel which are here for
%% debugging purposes.
-record(iset, {anno=[],vars,arg,body}).
@@ -50,28 +52,33 @@ format(Node) -> format(Node, #ctxt{}).
format(Node, Ctxt) ->
case canno(Node) of
-%% [] ->
-%% format_1(Node, Ctxt);
-%% [L,{file,_}] when is_integer(L) ->
-%% format_1(Node, Ctxt);
-%% #k{a=Anno}=K when Anno =/= [] ->
-%% format(setelement(2, Node, K#k{a=[]}), Ctxt);
-%% List ->
-%% format_anno(List, Ctxt, fun (Ctxt1) ->
-%% format_1(Node, Ctxt1)
-%% end);
- _ ->
- format_1(Node, Ctxt)
+ [] ->
+ format_1(Node, Ctxt);
+ [L,{file,_}] when is_integer(L) ->
+ format_1(Node, Ctxt);
+ #k{a=Anno}=K when Anno =/= [] ->
+ format(setelement(2, Node, K#k{a=[]}), Ctxt);
+ List ->
+ format_anno(List, Ctxt, fun (Ctxt1) ->
+ format_1(Node, Ctxt1)
+ end)
end.
-%% format_anno(Anno, Ctxt0, ObjFun) ->
-%% Ctxt1 = ctxt_bump_indent(Ctxt0, 1),
-%% ["( ",
-%% ObjFun(Ctxt0),
-%% nl_indent(Ctxt1),
-%% "-| ",io_lib:write(Anno),
-%% " )"].
-
+
+-ifndef(INCLUDE_ANNOTATIONS).
+%% Don't include annotations (for readability).
+format_anno(_Anno, Ctxt, ObjFun) ->
+ ObjFun(Ctxt).
+-else.
+%% Include annotations (for debugging of annotations).
+format_anno(Anno, Ctxt0, ObjFun) ->
+ Ctxt1 = ctxt_bump_indent(Ctxt0, 1),
+ ["( ",
+ ObjFun(Ctxt0),
+ nl_indent(Ctxt1),
+ "-| ",io_lib:write(Anno),
+ " )"].
+-endif.
%% format_1(Kexpr, Context) -> string().
@@ -107,6 +114,8 @@ format_1(#k_bin_int{size=Sz,unit=U,flags=Fs,val=Val,next=Next}, Ctxt) ->
[format_bin_seg_1(S, Ctxt),
format_bin_seg(Next, ctxt_bump_indent(Ctxt, 2))];
format_1(#k_bin_end{}, _Ctxt) -> "#<>#";
+format_1(#k_literal{val=Term}, _Ctxt) ->
+ io_lib:format("~p", [Term]);
format_1(#k_local{name=N,arity=A}, Ctxt) ->
"local " ++ format_fa_pair({N,A}, Ctxt);
format_1(#k_remote{mod=M,name=N,arity=A}, _Ctxt) ->
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index 2d08e71e09..934bf39393 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -153,7 +153,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) compiler.dynspec compiler.cover \
+ $(INSTALL_DATA) compiler.spec compiler.cover \
$(EMAKEFILE) $(ERL_FILES) $(CORE_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) \
$(INLINE_ERL_FILES) $(RELSYSDIR)
diff --git a/lib/compiler/test/andor_SUITE.erl b/lib/compiler/test/andor_SUITE.erl
index 84cfd16e60..2438fad6ca 100644
--- a/lib/compiler/test/andor_SUITE.erl
+++ b/lib/compiler/test/andor_SUITE.erl
@@ -18,16 +18,35 @@
%%
-module(andor_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
t_case/1,t_and_or/1,t_andalso/1,t_orelse/1,inside/1,overlap/1,
combined/1,in_case/1,before_and_inside_if/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(andor_SUITE),
+ [t_case, t_and_or, t_andalso, t_orelse, inside, overlap,
+ combined, in_case, before_and_inside_if].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [t_case,t_and_or,t_andalso,t_orelse,inside,overlap,combined,in_case,
- before_and_inside_if].
t_case(Config) when is_list(Config) ->
%% We test boolean cases almost but not quite like cases
diff --git a/lib/compiler/test/apply_SUITE.erl b/lib/compiler/test/apply_SUITE.erl
index f23dd6c2db..f309042911 100644
--- a/lib/compiler/test/apply_SUITE.erl
+++ b/lib/compiler/test/apply_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -18,15 +18,34 @@
%%
-module(apply_SUITE).
--export([all/1,mfa/1,fun_apply/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,mfa/1,fun_apply/1]).
-export([foo/0,bar/1,baz/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(apply_SUITE),
+ [mfa, fun_apply].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [mfa,fun_apply].
-define(APPLY0(M, F), (fun(Res) -> Res = M:F() end)(apply(M, F, []))).
-define(APPLY1(M, F, A1), (fun(Res) -> Res = M:F(A1) end)(apply(M, F, [A1]))).
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index 74b5d7c7eb..7fca737a20 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -18,7 +18,9 @@
%%
-module(beam_validator_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
beam_files/1,compiler_bug/1,stupid_but_valid/1,
xrange/1,yrange/1,stack/1,call_last/1,merge_undefined/1,
uninit/1,unsafe_catch/1,
@@ -30,34 +32,49 @@
state_after_fault_in_catch/1,no_exception_in_catch/1,
undef_label/1,illegal_instruction/1,failing_gc_guard_bif/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = test_server:timetrap(?t:minutes(10)),
[{watchdog,Dog}|Config].
-fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [beam_files,compiler_bug,stupid_but_valid,
- xrange,yrange,stack,call_last,merge_undefined,
- uninit,unsafe_catch,
- dead_code,mult_labels,
- overwrite_catchtag,overwrite_trytag,accessing_tags,bad_catch_try,
- cons_guard,
- freg_range,freg_uninit,freg_state,
- bin_match,bin_aligned,
- bad_dsetel,state_after_fault_in_catch,no_exception_in_catch,
- undef_label,illegal_instruction,failing_gc_guard_bif].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(beam_validator_SUITE),
+ [beam_files, compiler_bug, stupid_but_valid, xrange,
+ yrange, stack, call_last, merge_undefined, uninit,
+ unsafe_catch, dead_code, mult_labels,
+ overwrite_catchtag, overwrite_trytag, accessing_tags,
+ bad_catch_try, cons_guard, freg_range, freg_uninit,
+ freg_state, bin_match, bin_aligned, bad_dsetel,
+ state_after_fault_in_catch, no_exception_in_catch,
+ undef_label, illegal_instruction, failing_gc_guard_bif].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
beam_files(Config) when is_list(Config) ->
- ?line {ok,Cwd} = file:get_cwd(),
- ?line Parent = filename:dirname(Cwd),
- ?line Wc = filename:join([Parent,"*","*.beam"]),
+ ?line DataDir = proplists:get_value(data_dir, Config),
+ ?line Wc = filename:join([DataDir,"..","..","*","*.beam"]),
%% Must have at least two files here, or there will be
%% a grammatical error in the output of the io:format/2 call below. ;-)
?line [_,_|_] = Fs = filelib:wildcard(Wc),
diff --git a/lib/compiler/test/bs_bincomp_SUITE.erl b/lib/compiler/test/bs_bincomp_SUITE.erl
index a64a5d590b..28801bd7d0 100644
--- a/lib/compiler/test/bs_bincomp_SUITE.erl
+++ b/lib/compiler/test/bs_bincomp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,19 +21,36 @@
-module(bs_bincomp_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
byte_aligned/1,bit_aligned/1,extended_byte_aligned/1,
extended_bit_aligned/1,mixed/1,filters/1,trim_coverage/1,
- nomatch/1,sizes/1]).
+ nomatch/1,sizes/1,tail/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- test_lib:recompile(?MODULE),
- [byte_aligned,bit_aligned,extended_byte_aligned,
- extended_bit_aligned,mixed,filters,trim_coverage,
- nomatch,sizes].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+all() ->
+ test_lib:recompile(bs_bincomp_SUITE),
+ [byte_aligned, bit_aligned, extended_byte_aligned,
+ extended_bit_aligned, mixed, filters, trim_coverage,
+ nomatch, sizes, tail].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
byte_aligned(Config) when is_list(Config) ->
cs_init(),
@@ -270,6 +287,38 @@ sizes(Config) when is_list(Config) ->
?line cs_end(),
ok.
+tail(Config) when is_list(Config) ->
+ ?line [] = tail_1(<<0:7>>),
+ ?line [0] = tail_1(<<0>>),
+ ?line [0] = tail_1(<<0:12>>),
+ ?line [0,0] = tail_1(<<0:20>>),
+
+ ?line [] = tail_2(<<0:7>>),
+ ?line [42] = tail_2(<<0>>),
+ ?line [] = tail_2(<<0:12>>),
+ ?line [42,42] = tail_2(<<0,1>>),
+
+ ?line <<>> = tail_3(<<0:7>>),
+ ?line <<42>> = tail_3(<<0>>),
+ ?line <<42>> = tail_3(<<0:12>>),
+ ?line <<42,42>> = tail_3(<<0:20>>),
+
+ ?line [] = tail_4(<<0:15>>),
+ ?line [7] = tail_4(<<7,8>>),
+ ?line [9] = tail_4(<<9,17:12>>),
+ ok.
+
+tail_1(Bits) ->
+ [X || <<X:8/integer, _/bits>> <= Bits].
+
+tail_2(Bits) ->
+ [42 || <<_:8/integer, _/bytes>> <= Bits].
+
+tail_3(Bits) ->
+ << <<42>> || <<_:8/integer, _/bits>> <= Bits >>.
+
+tail_4(Bits) ->
+ [X || <<X:8/integer, Tail/bits>> <= Bits, bit_size(Tail) >= 8].
cs_init() ->
diff --git a/lib/compiler/test/bs_bit_binaries_SUITE.erl b/lib/compiler/test/bs_bit_binaries_SUITE.erl
index 6337460b13..052289e00c 100644
--- a/lib/compiler/test/bs_bit_binaries_SUITE.erl
+++ b/lib/compiler/test/bs_bit_binaries_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-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
@@ -21,19 +21,39 @@
-module(bs_bit_binaries_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
misc/1,horrid_match/1,test_bitstr/1,test_bit_size/1,asymmetric_tests/1,
big_asymmetric_tests/1,binary_to_and_from_list/1,
big_binary_to_and_from_list/1,send_and_receive/1,
send_and_receive_alot/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(bs_bit_binaries_SUITE),
+ [misc, horrid_match, test_bitstr, test_bit_size,
+ asymmetric_tests, big_asymmetric_tests,
+ binary_to_and_from_list, big_binary_to_and_from_list,
+ send_and_receive, send_and_receive_alot].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [misc,horrid_match,test_bitstr,test_bit_size,asymmetric_tests,
- big_asymmetric_tests,binary_to_and_from_list,big_binary_to_and_from_list,
- send_and_receive,send_and_receive_alot].
misc(Config) when is_list(Config) ->
?line <<1:100>> = <<1:100>>,
diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl
index 1862a28bbe..c430b12b70 100644
--- a/lib/compiler/test/bs_construct_SUITE.erl
+++ b/lib/compiler/test/bs_construct_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,23 +23,44 @@
-module(bs_construct_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
two/1,test1/1,fail/1,float_bin/1,in_guard/1,in_catch/1,
nasty_literals/1,coerce_to_float/1,side_effect/1,
opt/1,otp_7556/1,float_arith/1,otp_8054/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(bs_construct_SUITE),
+ [two, test1, fail, float_bin, in_guard, in_catch,
+ nasty_literals, side_effect, opt, otp_7556, float_arith,
+ otp_8054].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [two,test1,fail,float_bin,in_guard,in_catch,nasty_literals,
- side_effect,opt,otp_7556,float_arith,otp_8054].
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
@@ -66,6 +87,8 @@ id(I) -> I.
l(I_13, I_big1, I_16, Bin) ->
[
+ ?T(<<I_13:0>>,
+ []),
?T(<<-43>>,
[256-43]),
?T(<<4:4,7:4>>,
@@ -208,7 +231,7 @@ one_test({C_bin, E_bin, Str, Result}) ->
ok;
%% For situations where the final bits may not matter, like
%% for floats:
- N when integer(N) ->
+ N when is_integer(N) ->
io:format("Info: compiled and interpreted differ in the"
" last bytes:~n ~p, ~p.~n",
[bitstring_to_list(C_bin), bitstring_to_list(E_bin)]),
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index caaa587006..d674f273f0 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -20,7 +20,9 @@
-module(bs_match_SUITE).
-compile(nowarn_shadow_vars).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
fun_shadow/1,int_float/1,otp_5269/1,null_fields/1,wiger/1,
bin_tail/1,save_restore/1,shadowed_size_var/1,
partitioned_bs_match/1,function_clause/1,
@@ -35,24 +37,45 @@
-export([coverage_id/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- test_lib:recompile(?MODULE),
- [fun_shadow,int_float,otp_5269,null_fields,wiger,bin_tail,save_restore,
- shadowed_size_var,partitioned_bs_match,function_clause,unit,
- shared_sub_bins,bin_and_float,dec_subidentifiers,skip_optional_tag,
- 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,cover_beam_bool].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(bs_match_SUITE),
+ [fun_shadow, int_float, otp_5269, null_fields, wiger,
+ bin_tail, save_restore, shadowed_size_var,
+ partitioned_bs_match, function_clause, unit,
+ shared_sub_bins, bin_and_float, dec_subidentifiers,
+ skip_optional_tag, 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,
+ cover_beam_bool].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
diff --git a/lib/compiler/test/bs_utf_SUITE.erl b/lib/compiler/test/bs_utf_SUITE.erl
index 4281874a24..af57688347 100644
--- a/lib/compiler/test/bs_utf_SUITE.erl
+++ b/lib/compiler/test/bs_utf_SUITE.erl
@@ -19,18 +19,37 @@
-module(bs_utf_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
utf8_roundtrip/1,unused_utf_char/1,utf16_roundtrip/1,
utf32_roundtrip/1,guard/1,extreme_tripping/1,
literals/1,coverage/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(bs_utf_SUITE),
+ [utf8_roundtrip, unused_utf_char, utf16_roundtrip,
+ utf32_roundtrip, guard, extreme_tripping, literals,
+ coverage].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [utf8_roundtrip,unused_utf_char,utf16_roundtrip,
- utf32_roundtrip,guard,extreme_tripping,
- literals,coverage].
utf8_roundtrip(Config) when is_list(Config) ->
?line [utf8_roundtrip_1(P) || P <- utf_data()],
diff --git a/lib/compiler/test/compilation_SUITE.erl b/lib/compiler/test/compilation_SUITE.erl
index 9c06740816..ba225b66d0 100644
--- a/lib/compiler/test/compilation_SUITE.erl
+++ b/lib/compiler/test/compilation_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,34 +20,46 @@
-module(compilation_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-compile(export_all).
-all(suite) ->
- test_lib:recompile(?MODULE),
- [self_compile_old_inliner,self_compile,
- compiler_1,compiler_3,compiler_5,
- beam_compiler_1, beam_compiler_2, beam_compiler_3,
- beam_compiler_4, beam_compiler_5, beam_compiler_6,
- beam_compiler_7, beam_compiler_8, beam_compiler_9,
- beam_compiler_10, beam_compiler_11, beam_compiler_12,
- nested_tuples_in_case_expr,
- otp_2330, guards, vsn,
- otp_2380, otp_2141, otp_2173, otp_4790,
- const_list_256,
- bin_syntax_1, bin_syntax_2, bin_syntax_3,
- bin_syntax_4, bin_syntax_5, bin_syntax_6,
- live_var, convopts,
- bad_functional_value,
- catch_in_catch, redundant_case, long_string,
- otp_5076, complex_guard, otp_5092, otp_5151,
- otp_5235,otp_5244,
- trycatch_4, opt_crash,
- otp_5404,otp_5436,otp_5481,otp_5553,otp_5632,
- otp_5714,otp_5872,otp_6121,otp_6121a,otp_6121b,
- otp_7202,otp_7345,on_load,string_table
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(compilation_SUITE),
+ [self_compile_old_inliner, self_compile, compiler_1,
+ compiler_3, compiler_5, beam_compiler_1,
+ beam_compiler_2, beam_compiler_3, beam_compiler_4,
+ beam_compiler_5, beam_compiler_6, beam_compiler_7,
+ beam_compiler_8, beam_compiler_9, beam_compiler_10,
+ beam_compiler_11, beam_compiler_12,
+ nested_tuples_in_case_expr, otp_2330, guards,
+ {group, vsn}, otp_2380, otp_2141, otp_2173, otp_4790,
+ const_list_256, bin_syntax_1, bin_syntax_2,
+ bin_syntax_3, bin_syntax_4, bin_syntax_5, bin_syntax_6,
+ live_var, convopts, bad_functional_value,
+ catch_in_catch, redundant_case, long_string, otp_5076,
+ complex_guard, otp_5092, otp_5151, otp_5235, otp_5244,
+ trycatch_4, opt_crash, otp_5404, otp_5436, otp_5481,
+ otp_5553, otp_5632, otp_5714, otp_5872, otp_6121,
+ otp_6121a, otp_6121b, otp_7202, otp_7345, on_load,
+ string_table,otp_8949_a,otp_8949_a].
+
+groups() ->
+ [{vsn, [], [vsn_1, vsn_2, vsn_3]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-define(comp(N),
N(Config) when is_list(Config) -> try_it(N, Config)).
@@ -151,7 +163,7 @@ split({int, N}, <<N:16,B:N/binary,T/binary>>) ->
beam_compiler_7(doc) ->
"Code snippet submitted from Ulf Wiger which fails in R3 Beam.";
beam_compiler_7(suite) -> [];
-beam_compiler_7(Config) when list(Config) ->
+beam_compiler_7(Config) when is_list(Config) ->
?line done = empty(2, false).
empty(N, Toggle) when N > 0 ->
@@ -311,12 +323,11 @@ from(H, [H | T]) -> T;
from(H, [_ | T]) -> from(H, T);
from(_, []) -> [].
-vsn(suite) -> [vsn_1, vsn_2, vsn_3].
vsn_1(doc) ->
"Test generation of 'vsn' attribute";
vsn_1(suite) -> [];
-vsn_1(Conf) when list(Conf) ->
+vsn_1(Conf) when is_list(Conf) ->
?line M = vsn_1,
?line compile_load(M, ?config(data_dir, Conf), Conf),
@@ -340,7 +351,7 @@ vsn_1(Conf) when list(Conf) ->
vsn_2(doc) ->
"Test overriding of generation of 'vsn' attribute";
vsn_2(suite) -> [];
-vsn_2(Conf) when list(Conf) ->
+vsn_2(Conf) when is_list(Conf) ->
?line M = vsn_2,
?line compile_load(M, ?config(data_dir, Conf), Conf),
@@ -356,7 +367,7 @@ vsn_2(Conf) when list(Conf) ->
vsn_3(doc) ->
"Test that different code yields different generated 'vsn'";
vsn_3(suite) -> [];
-vsn_3(Conf) when list(Conf) ->
+vsn_3(Conf) when is_list(Conf) ->
?line M = vsn_3,
?line compile_load(M, ?config(data_dir, Conf), Conf),
@@ -606,5 +617,45 @@ string_table(Config) when is_list(Config) ->
?line {"StrT", <<"stringabletringtable">>} = StringTableChunk,
ok.
+otp_8949_a(Config) when is_list(Config) ->
+ value = otp_8949_a(),
+ ok.
+
+-record(cs, {exs,keys = [],flags = 1}).
+-record(exs, {children = []}).
+
+otp_8949_a() ->
+ case id([#cs{}]) of
+ [#cs{}=Cs] ->
+ SomeVar = id(value),
+ if
+ Cs#cs.flags band 1 =/= 0 ->
+ id(SomeVar);
+ (((Cs#cs.exs)#exs.children /= [])
+ and
+ (Cs#cs.flags band (1 bsl 0 bor (1 bsl 22)) == 0));
+ Cs#cs.flags band (1 bsl 22) =/= 0 ->
+ ok
+ end
+ end.
+
+otp_8949_b(Config) when is_list(Config) ->
+ self() ! something,
+ ?line value = otp_8949_b([], false),
+ ?line {'EXIT',_} = (catch otp_8949_b([], true)),
+ ok.
+
+%% Would cause an endless loop in beam_utils.
+otp_8949_b(A, B) ->
+ Var = id(value),
+ if
+ A == [], B == false ->
+ ok
+ end,
+ receive
+ something ->
+ id(Var)
+ end.
+
id(I) -> I.
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index e1cc5dafb5..037c078fd0 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,33 +20,50 @@
%% Tests compile:file/1 and compile:file/2 with various options.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
app_test/1,
file_1/1, module_mismatch/1, big_file/1, outdir/1,
- binary/1, cond_and_ifdef/1, listings/1, listings_big/1,
+ binary/1, makedep/1, cond_and_ifdef/1, listings/1, listings_big/1,
other_output/1, package_forms/1, encrypted_abstr/1,
- bad_record_use/1, bad_record_use1/1, bad_record_use2/1, strict_record/1,
+ bad_record_use1/1, bad_record_use2/1, strict_record/1,
missing_testheap/1, cover/1, env/1, core/1, asm/1]).
-export([init/3]).
+suite() -> [{ct_hooks,[ts_install_cth]}].
%% To cover the stripping of 'type' and 'spec' in beam_asm.
-type all_return_type() :: [atom()].
--spec all('suite' | [_]) -> all_return_type().
-
-all(suite) ->
- test_lib:recompile(?MODULE),
- [app_test,
- file_1, module_mismatch, big_file, outdir, binary,
- cond_and_ifdef, listings, listings_big,
- other_output, package_forms,
- encrypted_abstr,
- bad_record_use, strict_record,
+-spec all() -> all_return_type().
+
+all() ->
+ test_lib:recompile(compile_SUITE),
+ [app_test, file_1, module_mismatch, big_file, outdir,
+ binary, makedep, cond_and_ifdef, listings, listings_big,
+ other_output, package_forms, encrypted_abstr,
+ {group, bad_record_use}, strict_record,
missing_testheap, cover, env, core, asm].
+groups() ->
+ [{bad_record_use, [],
+ [bad_record_use1, bad_record_use2]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%% Test that the Application file has no `basic' errors.";
app_test(Config) when is_list(Config) ->
@@ -132,6 +149,76 @@ binary(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
+%% Tests that the dependencies-Makefile-related options work.
+
+makedep(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(60)),
+ ?line {Simple,Target} = files(Config, "makedep"),
+ ?line DataDir = ?config(data_dir, Config),
+ ?line SimpleRootname = filename:rootname(Simple),
+ ?line IncludeDir = filename:join(filename:dirname(Simple), "include"),
+ ?line IncludeOptions = [
+ {d,need_foo},
+ {d,foo_value,42},
+ {d,include_generated},
+ {i,IncludeDir}
+ ],
+ %% Basic rule.
+ ?line BasicMf1Name = SimpleRootname ++ "-basic1.mk",
+ ?line {ok,BasicMf1} = file:read_file(BasicMf1Name),
+ ?line {ok,_,Mf1} = compile:file(Simple, [binary,makedep]),
+ ?line BasicMf1 = makedep_canonicalize_result(Mf1, DataDir),
+ %% Basic rule with one existing header.
+ ?line BasicMf2Name = SimpleRootname ++ "-basic2.mk",
+ ?line {ok,BasicMf2} = file:read_file(BasicMf2Name),
+ ?line {ok,_,Mf2} = compile:file(Simple, [binary,makedep|IncludeOptions]),
+ ?line BasicMf2 = makedep_canonicalize_result(Mf2, DataDir),
+ %% Rule with one existing header and one missing header.
+ ?line MissingMfName = SimpleRootname ++ "-missing.mk",
+ ?line {ok,MissingMf} = file:read_file(MissingMfName),
+ ?line {ok,_,Mf3} = compile:file(Simple,
+ [binary,makedep,makedep_add_missing|IncludeOptions]),
+ ?line MissingMf = makedep_canonicalize_result(Mf3, DataDir),
+ %% Rule with modified target.
+ ?line TargetMf1Name = SimpleRootname ++ "-target1.mk",
+ ?line {ok,TargetMf1} = file:read_file(TargetMf1Name),
+ ?line {ok,_,Mf4} = compile:file(Simple,
+ [binary,makedep,{makedep_target,"$target"}|IncludeOptions]),
+ ?line TargetMf1 = makedep_modify_target(
+ makedep_canonicalize_result(Mf4, DataDir), "$$target"),
+ %% Rule with quoted modified target.
+ ?line TargetMf2Name = SimpleRootname ++ "-target2.mk",
+ ?line {ok,TargetMf2} = file:read_file(TargetMf2Name),
+ ?line {ok,_,Mf5} = compile:file(Simple,
+ [binary,makedep,{makedep_target,"$target"},makedep_quote_target|
+ IncludeOptions]),
+ ?line TargetMf2 = makedep_modify_target(
+ makedep_canonicalize_result(Mf5, DataDir), "$$target"),
+ %% Basic rule written to some file.
+ ?line {ok,_} = compile:file(Simple,
+ [makedep,{makedep_output,Target}|IncludeOptions]),
+ ?line {ok,Mf6} = file:read_file(Target),
+ ?line BasicMf2 = makedep_canonicalize_result(Mf6, DataDir),
+
+ ?line ok = file:delete(Target),
+ ?line ok = file:del_dir(filename:dirname(Target)),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+makedep_canonicalize_result(Mf, DataDir) ->
+ Mf0 = binary_to_list(Mf),
+ %% Replace the Datadir by "$(srcdir)".
+ Mf1 = re:replace(Mf0, DataDir, "$(srcdir)/",
+ [global,multiline,{return,list}]),
+ %% Long lines are splitted, put back everything on one line.
+ Mf2 = re:replace(Mf1, "\\\\\n ", "", [global,multiline,{return,list}]),
+ list_to_binary(Mf2).
+
+makedep_modify_target(Mf, Target) ->
+ Mf0 = binary_to_list(Mf),
+ Mf1 = re:replace(Mf0, Target, "$target", [{return,list}]),
+ list_to_binary(Mf1).
+
%% Tests that conditional compilation, defining values, including files work.
cond_and_ifdef(Config) when is_list(Config) ->
@@ -465,7 +552,6 @@ exists(Name) ->
{error, _} -> false
end.
-bad_record_use(suite) -> [bad_record_use1, bad_record_use2].
%% Tests that the compiler does not accept
%% bad use of records.
diff --git a/lib/compiler/test/compile_SUITE_data/simple-basic1.mk b/lib/compiler/test/compile_SUITE_data/simple-basic1.mk
new file mode 100644
index 0000000000..4073fa82d0
--- /dev/null
+++ b/lib/compiler/test/compile_SUITE_data/simple-basic1.mk
@@ -0,0 +1 @@
+simple.beam: $(srcdir)/simple.erl
diff --git a/lib/compiler/test/compile_SUITE_data/simple-basic2.mk b/lib/compiler/test/compile_SUITE_data/simple-basic2.mk
new file mode 100644
index 0000000000..761d1d9582
--- /dev/null
+++ b/lib/compiler/test/compile_SUITE_data/simple-basic2.mk
@@ -0,0 +1 @@
+simple.beam: $(srcdir)/simple.erl $(srcdir)/include/simple.hrl
diff --git a/lib/compiler/test/compile_SUITE_data/simple-missing.mk b/lib/compiler/test/compile_SUITE_data/simple-missing.mk
new file mode 100644
index 0000000000..b13d44ec36
--- /dev/null
+++ b/lib/compiler/test/compile_SUITE_data/simple-missing.mk
@@ -0,0 +1 @@
+simple.beam: $(srcdir)/simple.erl $(srcdir)/include/simple.hrl generated.hrl
diff --git a/lib/compiler/test/compile_SUITE_data/simple-target1.mk b/lib/compiler/test/compile_SUITE_data/simple-target1.mk
new file mode 100644
index 0000000000..dd9fa0d6e5
--- /dev/null
+++ b/lib/compiler/test/compile_SUITE_data/simple-target1.mk
@@ -0,0 +1 @@
+$target: $(srcdir)/simple.erl $(srcdir)/include/simple.hrl
diff --git a/lib/compiler/test/compile_SUITE_data/simple-target2.mk b/lib/compiler/test/compile_SUITE_data/simple-target2.mk
new file mode 100644
index 0000000000..a5fc6f461d
--- /dev/null
+++ b/lib/compiler/test/compile_SUITE_data/simple-target2.mk
@@ -0,0 +1 @@
+$$target: $(srcdir)/simple.erl $(srcdir)/include/simple.hrl
diff --git a/lib/compiler/test/compile_SUITE_data/simple.erl b/lib/compiler/test/compile_SUITE_data/simple.erl
index 2021056388..0c1c70a778 100644
--- a/lib/compiler/test/compile_SUITE_data/simple.erl
+++ b/lib/compiler/test/compile_SUITE_data/simple.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -37,3 +37,7 @@ foo() ->
{?included_value, ?foo_value}.
-endif.
+
+-ifdef(include_generated).
+-include("generated.hrl").
+-endif.
diff --git a/lib/compiler/test/compiler.cover b/lib/compiler/test/compiler.cover
index 69d284ea6c..9fc4c7dd43 100644
--- a/lib/compiler/test/compiler.cover
+++ b/lib/compiler/test/compiler.cover
@@ -1,3 +1,5 @@
+{incl_app,compiler,details}.
+
%% -*- erlang -*-
-{exclude,[sys_pre_attributes,core_scan,core_parse]}.
+{excl_mods,[sys_pre_attributes,core_scan,core_parse]}.
diff --git a/lib/compiler/test/compiler.dynspec b/lib/compiler/test/compiler.dynspec
deleted file mode 100644
index 7e452cef6c..0000000000
--- a/lib/compiler/test/compiler.dynspec
+++ /dev/null
@@ -1,10 +0,0 @@
-%% -*- erlang -*-
-%% You can test this file using this command.
-%% file:script("compiler.dynspec", [{'Os',"Unix"}]).
-
-case Os of
- "VxWorks" ->
- [{skip,{compile_SUITE,listings,"VxWorks filesystem too slow"}}];
- _ ->
- []
-end.
diff --git a/lib/compiler/test/compiler.spec b/lib/compiler/test/compiler.spec
new file mode 100644
index 0000000000..f2546c3ced
--- /dev/null
+++ b/lib/compiler/test/compiler.spec
@@ -0,0 +1,2 @@
+%% -*- erlang -*-
+{suites,"../compiler_test",all}.
diff --git a/lib/compiler/test/core_SUITE.erl b/lib/compiler/test/core_SUITE.erl
index 54cf799057..c5969b5580 100644
--- a/lib/compiler/test/core_SUITE.erl
+++ b/lib/compiler/test/core_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,10 +18,12 @@
%%
-module(core_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
dehydrated_itracer/1,nested_tries/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(comp(N),
N(Config) when is_list(Config) -> try_it(N, Config)).
@@ -30,14 +32,32 @@ init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = test_server:timetrap(?t:minutes(5)),
[{watchdog,Dog}|Config].
-fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [dehydrated_itracer,nested_tries].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(core_SUITE),
+ [dehydrated_itracer, nested_tries].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
?comp(dehydrated_itracer).
?comp(nested_tries).
diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl
index 5f2c905d4a..c13e4d2162 100644
--- a/lib/compiler/test/core_fold_SUITE.erl
+++ b/lib/compiler/test/core_fold_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-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
@@ -18,18 +18,37 @@
%%
-module(core_fold_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
t_element/1,setelement/1,t_length/1,append/1,t_apply/1,bifs/1,
eq/1,nested_call_in_case/1,coverage/1]).
-export([foo/0,foo/1,foo/2,foo/3]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(core_fold_SUITE),
+ [t_element, setelement, t_length, append, t_apply, bifs,
+ eq, nested_call_in_case, coverage].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [t_element,setelement,t_length,append,t_apply,bifs,
- eq,nested_call_in_case,coverage].
t_element(Config) when is_list(Config) ->
X = make_ref(),
diff --git a/lib/compiler/test/error_SUITE.erl b/lib/compiler/test/error_SUITE.erl
index ec58a0761e..2bb3fea438 100644
--- a/lib/compiler/test/error_SUITE.erl
+++ b/lib/compiler/test/error_SUITE.erl
@@ -18,14 +18,32 @@
%%
-module(error_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
head_mismatch_line/1,warnings_as_errors/1, bif_clashes/1]).
-all(suite) ->
- test_lib:recompile(?MODULE),
- [head_mismatch_line,warnings_as_errors,bif_clashes].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(error_SUITE),
+ [head_mismatch_line, warnings_as_errors, bif_clashes].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
bif_clashes(Config) when is_list(Config) ->
diff --git a/lib/compiler/test/float_SUITE.erl b/lib/compiler/test/float_SUITE.erl
index b48b1daa32..cad144ea63 100644
--- a/lib/compiler/test/float_SUITE.erl
+++ b/lib/compiler/test/float_SUITE.erl
@@ -17,13 +17,34 @@
%% %CopyrightEnd%
%%
-module(float_SUITE).
--export([all/1,pending/1,bif_calls/1,math_functions/1,mixed_float_and_int/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ pending/1,bif_calls/1,math_functions/1,mixed_float_and_int/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(float_SUITE),
+ [pending, bif_calls, math_functions,
+ mixed_float_and_int].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [pending,bif_calls,math_functions,mixed_float_and_int].
%% Thanks to Tobias Lindahl <[email protected]>
%% Shows the effect of pending exceptions on the x86.
diff --git a/lib/compiler/test/fun_SUITE.erl b/lib/compiler/test/fun_SUITE.erl
index fb2667245a..dbf2416f3c 100644
--- a/lib/compiler/test/fun_SUITE.erl
+++ b/lib/compiler/test/fun_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -18,14 +18,33 @@
%%
-module(fun_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
test1/1,overwritten_fun/1,otp_7202/1,bif_fun/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(fun_SUITE),
+ [test1, overwritten_fun, otp_7202, bif_fun].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [test1,overwritten_fun,otp_7202,bif_fun].
%%% The help functions below are copied from emulator:bs_construct_SUITE.
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 8f23bd2e5a..482564a32b 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,9 +18,10 @@
%%
-module(guard_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
misc/1,const_cond/1,basic_not/1,complex_not/1,nested_nots/1,
semicolon/1,complex_semicolon/1,comma/1,
or_guard/1,more_or_guards/1,
@@ -33,17 +34,33 @@
basic_andalso_orelse/1,traverse_dcd/1,
check_qlc_hrl/1,andalso_semi/1,t_tuple_size/1,binary_part/1]).
-all(suite) ->
- test_lib:recompile(?MODULE),
- [misc,const_cond,basic_not,complex_not,nested_nots,
- semicolon,complex_semicolon,
- comma,or_guard,more_or_guards,
- complex_or_guards,and_guard,
- xor_guard,more_xor_guards,
- build_in_guard,old_guard_tests,gbif,
- t_is_boolean,is_function_2,tricky,rel_ops,literal_type_tests,
- basic_andalso_orelse,traverse_dcd,check_qlc_hrl,andalso_semi,
- t_tuple_size,binary_part].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(guard_SUITE),
+ [misc, const_cond, basic_not, complex_not, nested_nots,
+ semicolon, complex_semicolon, comma, or_guard,
+ more_or_guards, complex_or_guards, and_guard, xor_guard,
+ more_xor_guards, build_in_guard, old_guard_tests, gbif,
+ t_is_boolean, is_function_2, tricky, rel_ops,
+ literal_type_tests, basic_andalso_orelse, traverse_dcd,
+ check_qlc_hrl, andalso_semi, t_tuple_size, binary_part].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
misc(Config) when is_list(Config) ->
?line 42 = case id(42) of
@@ -94,8 +111,8 @@ const_cond(Config) when is_list(Config) ->
const_cond(T, Sz) ->
case T of
_X when false -> never;
- _X when tuple(T), eq == eq, tuple_size(T) == Sz -> ok;
- _X when tuple(T), eq == leq, tuple_size(T) =< Sz -> ok;
+ _X when is_tuple(T), eq == eq, tuple_size(T) == Sz -> ok;
+ _X when is_tuple(T), eq == leq, tuple_size(T) =< Sz -> ok;
_X -> error
end.
@@ -1137,7 +1154,7 @@ make_test([{T,L}|Ts]) ->
make_test([]) -> [].
test(T, L) ->
- S0 = io_lib:format("begin io:format(\"~~p~~n\", [{~p,~p}]), if ~w(~w) -> true; true -> false end end. ", [T,L,T,L]),
+ S0 = io_lib:format("begin io:format(\"~~p~n\", [{~p,~p}]), if ~w(~w) -> true; true -> false end end. ", [T,L,T,L]),
S = lists:flatten(S0),
{ok,Toks,_Line} = erl_scan:string(S),
{ok,E} = erl_parse:parse_exprs(Toks),
@@ -1145,7 +1162,7 @@ test(T, L) ->
{match,0,{atom,0,Val},hd(E)}.
test(T, L1, L2) ->
- S0 = io_lib:format("begin io:format(\"~~p~~n\", [{~p,~p,~p}]), if ~w(~w, ~w) -> true; true -> false end end. ", [T,L1,L2,T,L1,L2]),
+ S0 = io_lib:format("begin io:format(\"~~p~n\", [{~p,~p,~p}]), if ~w(~w, ~w) -> true; true -> false end end. ", [T,L1,L2,T,L1,L2]),
S = lists:flatten(S0),
{ok,Toks,_Line} = erl_scan:string(S),
{ok,E} = erl_parse:parse_exprs(Toks),
diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl
index 396fb450b7..7b9600c2f6 100644
--- a/lib/compiler/test/inline_SUITE.erl
+++ b/lib/compiler/test/inline_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
-module(inline_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-compile(export_all).
-compile({inline,[badarg/2]}).
@@ -28,10 +28,29 @@
%% Needed by test case `lists'.
-compile(inline_list_funcs).
-all(suite) ->
- test_lib:recompile(?MODULE),
- [attribute,bsdecode,bsdes,barnes2,decode1,smith,itracer,pseudoknot,lists,
- really_inlined,otp_7223,coverage].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(inline_SUITE),
+ [attribute, bsdecode, bsdes, barnes2, decode1, smith,
+ itracer, pseudoknot, lists, really_inlined, otp_7223,
+ coverage].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
attribute(Config) when is_list(Config) ->
Name = "attribute",
@@ -49,7 +68,7 @@ attribute(Config) when is_list(Config) ->
ok.
-define(comp(Name),
- Name(Config) when list(Config) ->
+ Name(Config) when is_list(Config) ->
try_inline(Name, Config)).
?comp(bsdecode).
diff --git a/lib/compiler/test/lc_SUITE.erl b/lib/compiler/test/lc_SUITE.erl
index 40bf67e1fa..bcdcf2fd9f 100644
--- a/lib/compiler/test/lc_SUITE.erl
+++ b/lib/compiler/test/lc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,21 +19,41 @@
-module(lc_SUITE).
-author('[email protected]').
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
basic/1,deeply_nested/1,no_generator/1,
empty_generator/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(lc_SUITE),
+ [basic, deeply_nested, no_generator, empty_generator].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [basic,deeply_nested,no_generator,empty_generator].
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
@@ -160,7 +180,7 @@ empty_generator(Config) when is_list(Config) ->
id(I) -> I.
fc(Args, {'EXIT',{function_clause,[{?MODULE,_,Args}|_]}}) -> ok;
-fc(Args, {'EXIT',{function_clause,[{?MODULE,Name,Arity}|_]}})
+fc(Args, {'EXIT',{function_clause,[{?MODULE,_,Arity}|_]}})
when length(Args) =:= Arity ->
true = test_server:is_native(?MODULE);
fc(Args, {'EXIT',{{case_clause,ActualArgs},_}})
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl
index fd51b777ac..b9b9fdd158 100644
--- a/lib/compiler/test/match_SUITE.erl
+++ b/lib/compiler/test/match_SUITE.erl
@@ -18,17 +18,36 @@
%%
-module(match_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
pmatch/1,mixed/1,aliases/1,match_in_call/1,
untuplify/1,shortcut_boolean/1,letify_guard/1,
selectify/1,underscore/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(match_SUITE),
+ [pmatch, mixed, aliases, match_in_call, untuplify,
+ shortcut_boolean, letify_guard, selectify, underscore].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [pmatch,mixed,aliases,match_in_call,untuplify,shortcut_boolean,
- letify_guard,selectify,underscore].
pmatch(Config) when is_list(Config) ->
?line ok = doit(1),
diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl
index 450a4e279d..bf8d6c7b7c 100644
--- a/lib/compiler/test/misc_SUITE.erl
+++ b/lib/compiler/test/misc_SUITE.erl
@@ -18,11 +18,13 @@
%%
-module(misc_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
tobias/1,empty_string/1,md5/1,silly_coverage/1,
confused_literals/1,integer_encoding/1,override_bif/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% For the override_bif testcase.
%% NB, no other testcases in this testsuite can use these without erlang:prefix!
@@ -45,17 +47,34 @@ init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = test_server:timetrap(?t:minutes(10)),
[{watchdog,Dog}|Config].
-fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
--spec all(any()) -> misc_SUITE_test_cases().
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+-spec all() -> misc_SUITE_test_cases().
+all() ->
+ test_lib:recompile(misc_SUITE),
+ [tobias, empty_string, md5, silly_coverage,
+ confused_literals, integer_encoding, override_bif].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [tobias,empty_string,md5,silly_coverage,confused_literals,
- integer_encoding, override_bif].
%%
diff --git a/lib/compiler/test/num_bif_SUITE.erl b/lib/compiler/test/num_bif_SUITE.erl
index 912f7366dd..29610aec6e 100644
--- a/lib/compiler/test/num_bif_SUITE.erl
+++ b/lib/compiler/test/num_bif_SUITE.erl
@@ -18,7 +18,7 @@
%%
-module(num_bif_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Tests optimization of the BIFs:
%% abs/1
@@ -30,17 +30,37 @@
%% round/1
%% trunc/1
--export([all/1, t_abs/1, t_float/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, t_abs/1, t_float/1,
t_float_to_list/1, t_integer_to_list/1,
t_list_to_integer/1,
- t_list_to_float/1, t_list_to_float_safe/1, t_list_to_float_risky/1,
+ t_list_to_float_safe/1, t_list_to_float_risky/1,
t_round/1, t_trunc/1]).
-all(suite) ->
- test_lib:recompile(?MODULE),
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(num_bif_SUITE),
[t_abs, t_float, t_float_to_list, t_integer_to_list,
- t_list_to_float, t_list_to_integer,
- t_round, t_trunc].
+ {group, t_list_to_float}, t_list_to_integer, t_round,
+ t_trunc].
+
+groups() ->
+ [{t_list_to_float, [],
+ [t_list_to_float_safe, t_list_to_float_risky]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
t_abs(Config) when is_list(Config) ->
%% Floats.
@@ -142,7 +162,6 @@ t_integer_to_list(Config) when is_list(Config) ->
%% Tests list_to_float/1.
-t_list_to_float(suite) -> [t_list_to_float_safe, t_list_to_float_risky].
t_list_to_float_safe(Config) when is_list(Config) ->
?line 0.0 = list_to_float("0.0"),
diff --git a/lib/compiler/test/parteval_SUITE.erl b/lib/compiler/test/parteval_SUITE.erl
index 3ef84571b9..b8faaf5f87 100644
--- a/lib/compiler/test/parteval_SUITE.erl
+++ b/lib/compiler/test/parteval_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,11 +18,31 @@
%%
-module(parteval_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1, pe2/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, pe2/1]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [pe2].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [pe2].
%% (This is more general than needed, since we once compiled the same
%% source code with and without a certain option.)
diff --git a/lib/compiler/test/pmod_SUITE.erl b/lib/compiler/test/pmod_SUITE.erl
index 13503ce905..f9fcae6ba8 100644
--- a/lib/compiler/test/pmod_SUITE.erl
+++ b/lib/compiler/test/pmod_SUITE.erl
@@ -18,20 +18,40 @@
%%
-module(pmod_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
basic/1, otp_8447/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- test_lib:recompile(?MODULE),
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(pmod_SUITE),
[basic, otp_8447].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
+end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index fca3f0387b..bf6f289656 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_SUITE.erl
@@ -20,23 +20,42 @@
-module(receive_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
- recv/1,coverage/1,otp_7980/1,ref_opt/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ export/1,recv/1,coverage/1,otp_7980/1,ref_opt/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(_Case, Config) ->
?line Dog = test_server:timetrap(test_server:minutes(2)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [recv,coverage,otp_7980,ref_opt].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(receive_SUITE),
+ [recv, coverage, otp_7980, ref_opt, export].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-record(state, {ena = true}).
@@ -205,4 +224,25 @@ collect_recv_opt_instrs(Code) ->
end] || {function,_,_,_,Is} <- Code],
lists:append(L).
+export(Config) when is_list(Config) ->
+ Ref = make_ref(),
+ ?line self() ! {result,Ref,42},
+ ?line 42 = export_1(Ref),
+ ?line {error,timeout} = export_1(Ref),
+ ok.
+
+export_1(Reference) ->
+ id(Reference),
+ receive
+ {result,Reference,Result} ->
+ Result
+ after 1 ->
+ Result = {error,timeout}
+ end,
+ %% Result ({x,1}) is used, but not the return value ({x,0})
+ %% of the receive. Used to be incorrectly optimized
+ %% by beam_block.
+ id({build,self()}),
+ Result.
+
id(I) -> I.
diff --git a/lib/compiler/test/record_SUITE.erl b/lib/compiler/test/record_SUITE.erl
index f26ff769c7..6f85adbb77 100644
--- a/lib/compiler/test/record_SUITE.erl
+++ b/lib/compiler/test/record_SUITE.erl
@@ -20,9 +20,11 @@
-module(record_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
errors/1,record_test_2/1,record_test_3/1,record_access_in_guards/1,
guard_opt/1,eval_once/1,foobar/1,missing_test_heap/1, nested_access/1]).
@@ -30,15 +32,34 @@ init_per_testcase(_Case, Config) ->
?line Dog = test_server:timetrap(test_server:minutes(2)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [errors,record_test_2,record_test_3,record_access_in_guards,
- guard_opt,eval_once,foobar,missing_test_heap,nested_access].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(record_SUITE),
+ [errors, record_test_2, record_test_3,
+ record_access_in_guards, guard_opt, eval_once, foobar,
+ missing_test_heap, nested_access].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-record(foo, {a,b,c,d}).
-record(bar, {a,b,c,d}).
diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl
index d8799952a9..53d8c04169 100644
--- a/lib/compiler/test/test_lib.erl
+++ b/lib/compiler/test/test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -41,7 +41,7 @@ smoke_disasm(Mod) when is_atom(Mod) ->
smoke_disasm(code:which(Mod));
smoke_disasm(File) when is_list(File) ->
Res = beam_disasm:file(File),
- {beam_file,Mod} = {element(1, Res),element(2, Res)}.
+ {beam_file,_Mod} = {element(1, Res),element(2, Res)}.
%% Retrieve the "interesting" compiler options (options for optimization
%% and compatibility) for the given module.
@@ -62,16 +62,16 @@ opt_opts(Mod) ->
(_) -> false
end, Opts).
-%% Some test suites gets cloned (e.g. to "record_SUITE" to "record_no_opt_SUITE"),
-%% but the data directory is not cloned. This function retrieves the path to
-%% the original data directory.
+%% Some test suites gets cloned (e.g. to "record_SUITE" to
+%% "record_no_opt_SUITE"), but the data directory is not cloned.
+%% This function retrieves the path to the original data directory.
get_data_dir(Config) ->
Data0 = ?config(data_dir, Config),
- {ok,Data1,_} = regexp:sub(Data0, "_no_opt_SUITE", "_SUITE"),
- {ok,Data2,_} = regexp:sub(Data1, "_post_opt_SUITE", "_SUITE"),
- {ok,Data,_} = regexp:sub(Data2, "_inline_SUITE", "_SUITE"),
- Data.
+ Opts = [{return,list}],
+ Data1 = re:replace(Data0, "_no_opt_SUITE", "_SUITE", Opts),
+ Data = re:replace(Data1, "_post_opt_SUITE", "_SUITE", Opts),
+ re:replace(Data, "_inline_SUITE", "_SUITE", Opts).
%% p_run(fun(Data) -> ok|error, List) -> ok
%% Will fail the test case if there were any errors.
diff --git a/lib/compiler/test/trycatch_SUITE.erl b/lib/compiler/test/trycatch_SUITE.erl
index c2f6dc24be..db438e28f8 100644
--- a/lib/compiler/test/trycatch_SUITE.erl
+++ b/lib/compiler/test/trycatch_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,21 +18,40 @@
%%
-module(trycatch_SUITE).
--export([all/1,basic/1,lean_throw/1,try_of/1,try_after/1,%after_bind/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,basic/1,lean_throw/1,
+ try_of/1,try_after/1,%after_bind/1,
catch_oops/1,after_oops/1,eclectic/1,rethrow/1,
nested_of/1,nested_catch/1,nested_after/1,
nested_horrid/1,last_call_optimization/1,bool/1,
plain_catch_coverage/1,andalso_orelse/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(trycatch_SUITE),
+ [basic, lean_throw, try_of, try_after, catch_oops,
+ after_oops, eclectic, rethrow, nested_of, nested_catch,
+ nested_after, nested_horrid, last_call_optimization,
+ bool, plain_catch_coverage, andalso_orelse].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [basic,lean_throw,try_of,try_after,%after_bind,
- catch_oops,after_oops,eclectic,rethrow,
- nested_of,nested_catch,nested_after,
- nested_horrid,last_call_optimization,
- bool,plain_catch_coverage,andalso_orelse].
basic(Conf) when is_list(Conf) ->
diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl
index 5ed8836c70..75e2b17de4 100644
--- a/lib/compiler/test/warnings_SUITE.erl
+++ b/lib/compiler/test/warnings_SUITE.erl
@@ -26,12 +26,14 @@
-define(privdir, "warnings_SUITE_priv").
-define(t, test_server).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(datadir, ?config(data_dir, Conf)).
-define(privdir, ?config(priv_dir, Conf)).
-endif.
--export([all/1,init_per_testcase/2,fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2]).
-export([pattern/1,pattern2/1,pattern3/1,pattern4/1,
guard/1,bad_arith/1,bool_cases/1,bad_apply/1,
@@ -44,16 +46,34 @@ init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- test_lib:recompile(?MODULE),
- [pattern,pattern2,pattern3,pattern4,
- guard,bad_arith,bool_cases,bad_apply,files,effect,
- bin_opt_info,bin_construction].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(warnings_SUITE),
+ [pattern, pattern2, pattern3, pattern4, guard,
+ bad_arith, bool_cases, bad_apply, files, effect,
+ bin_opt_info, bin_construction].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
pattern(Config) when is_list(Config) ->
%% Test warnings generated by v3_core.
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index 4658eccd19..d180ecd4e2 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 4.7.1
+COMPILER_VSN = 4.7.2
diff --git a/lib/cosEvent/doc/src/notes.xml b/lib/cosEvent/doc/src/notes.xml
index b6c4531901..1a5c8afa17 100644
--- a/lib/cosEvent/doc/src/notes.xml
+++ b/lib/cosEvent/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2010</year>
+ <year>1999</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -33,42 +33,48 @@
</header>
<section>
- <title>cosEvent 2.1.9</title>
+ <title>cosEvent 2.1.10</title>
<section>
<title>Improvements and New Features</title>
<list type="bulleted">
<item>
<p>
- Test suites published.</p>
+ Eliminated Dialyzer warnings when using exit or throw.</p>
<p>
- Own Id: OTP-8543 Aux Id:</p>
+ Own Id: OTP-9050 Aux Id:</p>
</item>
</list>
</section>
</section>
<section>
- <title>cosEvent 2.1.8</title>
+ <title>cosEvent 2.1.9</title>
<section>
<title>Improvements and New Features</title>
<list type="bulleted">
<item>
<p>
- Removed the usage of the codeinclude tag in the documentation.</p>
+ Test suites published.</p>
<p>
- Own Id: OTP-8409 Aux Id:</p>
+ Own Id: OTP-8543 Aux Id:</p>
</item>
</list>
</section>
+ </section>
+
+ <section>
+ <title>cosEvent 2.1.8</title>
<section>
- <title>Fixed Bugs and Malfunctions</title>
+ <title>Improvements and New Features</title>
<list type="bulleted">
<item>
- <p>The documentation EIX file was not generated.</p>
- <p>Own id: OTP-8355 Aux Id:</p>
+ <p>
+ Removed the usage of the codeinclude tag in the documentation.</p>
+ <p>
+ Own Id: OTP-8409 Aux Id:</p>
</item>
</list>
</section>
diff --git a/lib/cosEvent/src/cosEventApp.erl b/lib/cosEvent/src/cosEventApp.erl
index 084490f845..143c241448 100644
--- a/lib/cosEvent/src/cosEventApp.erl
+++ b/lib/cosEvent/src/cosEventApp.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -66,26 +66,31 @@
%% Effect : Install necessary data in the IFR DB
%%------------------------------------------------------------
install() ->
- install_loop(?IDL_MODULES, []).
+ case install_loop(?IDL_MODULES, []) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ exit(Reason)
+ end.
install_loop([], _) ->
ok;
install_loop([H|T], Accum) ->
case catch H:'oe_register'() of
{'EXIT',{unregistered,App}} ->
- ?write_ErrorMsg("Unable to register '~p'; application ~p not registered.
-Trying to unregister ~p~n", [H,App,Accum]),
+ ?write_ErrorMsg("Unable to register '~p'; application ~p not registered.\n"
+ "Trying to unregister ~p~n", [H,App,Accum]),
uninstall_loop(Accum, {exit, register});
{'EXCEPTION',_} ->
- ?write_ErrorMsg("Unable to register '~p'; propably already registered.
-You are adviced to confirm this.
-Trying to unregister ~p~n", [H,Accum]),
+ ?write_ErrorMsg("Unable to register '~p'; propably already registered.\n"
+ "You are adviced to confirm this.\n"
+ "Trying to unregister ~p~n", [H,Accum]),
uninstall_loop(Accum, {exit, register});
ok ->
install_loop(T, [H|Accum]);
_ ->
- ?write_ErrorMsg("Unable to register '~p'; reason unknown.
-Trying to unregister ~p~n", [H,Accum]),
+ ?write_ErrorMsg("Unable to register '~p'; reason unknown.\n"
+ "Trying to unregister ~p~n", [H,Accum]),
uninstall_loop(Accum, {exit, register})
end.
@@ -96,27 +101,32 @@ Trying to unregister ~p~n", [H,Accum]),
%% Effect : Remove data related to cosEvent from the IFR DB
%%------------------------------------------------------------
uninstall() ->
- uninstall_loop(lists:reverse(?IDL_MODULES), ok).
+ case uninstall_loop(lists:reverse(?IDL_MODULES), ok) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ exit(Reason)
+ end.
uninstall_loop([],ok) ->
ok;
uninstall_loop([],{exit, register}) ->
- exit({?MODULE, "oe_register failed"});
+ {error, {?MODULE, "oe_register failed"}};
uninstall_loop([],{exit, unregister}) ->
- exit({?MODULE, "oe_unregister failed"});
+ {error, {?MODULE, "oe_unregister failed"}};
uninstall_loop([],{exit, both}) ->
- exit({?MODULE, "oe_register and, for some of those already registered, oe_unregister failed"});
+ {error, {?MODULE, "oe_register and, for some of those already registered, oe_unregister failed"}};
uninstall_loop([H|T], Status) ->
case catch H:'oe_unregister'() of
ok ->
uninstall_loop(T, Status);
_ when Status == ok ->
- ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.
-You are adviced to confirm this.~n",[H]),
+ ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.\n"
+ "You are adviced to confirm this.\n",[H]),
uninstall_loop(T, {exit, unregister});
_ ->
- ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.
-You are adviced to confirm this.~n",[H]),
+ ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.\n"
+ "You are adviced to confirm this.\n",[H]),
uninstall_loop(T, {exit, both})
end.
diff --git a/lib/cosEvent/test/Makefile b/lib/cosEvent/test/Makefile
index 3d95075ee1..d37d3e4e3c 100644
--- a/lib/cosEvent/test/Makefile
+++ b/lib/cosEvent/test/Makefile
@@ -34,6 +34,7 @@ RELSYSDIR = $(RELEASE_PATH)/cosEvent_test
# Target Specs
# ----------------------------------------------------
TEST_SPEC_FILE = cosEvent.spec
+COVER_FILE = cosEvent.cover
IDL_FILES = \
@@ -146,7 +147,7 @@ release_docs_spec:
release_tests_spec: tests
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
- $(ERL_FILES) $(RELSYSDIR)
+ $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
$(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
$(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
diff --git a/lib/cosEvent/test/cosEvent.cover b/lib/cosEvent/test/cosEvent.cover
new file mode 100644
index 0000000000..df12ea3ca9
--- /dev/null
+++ b/lib/cosEvent/test/cosEvent.cover
@@ -0,0 +1,2 @@
+{incl_app,cosEvent,details}.
+
diff --git a/lib/cosEvent/test/cosEvent.spec b/lib/cosEvent/test/cosEvent.spec
index 910f7a7c28..f793693779 100644
--- a/lib/cosEvent/test/cosEvent.spec
+++ b/lib/cosEvent/test/cosEvent.spec
@@ -1,19 +1 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-{topcase, {dir, "../cosEvent_test"}}.
+{suites,"../cosEvent_test",all}.
diff --git a/lib/cosEvent/test/event_channel_SUITE.erl b/lib/cosEvent/test/event_channel_SUITE.erl
index 2b0cf1fe30..6c7194e8c7 100644
--- a/lib/cosEvent/test/event_channel_SUITE.erl
+++ b/lib/cosEvent/test/event_channel_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,7 +22,7 @@
-module(event_channel_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -53,21 +53,33 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, event_objects_api/1, events_api/1, events_sync_api/1,
- cases/0, init_all/1, finish_all/1,
- init_per_testcase/2, fin_per_testcase/2, app_test/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ event_objects_api/1, events_api/1, events_sync_api/1,
+ cases/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2, app_test/1]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for the cosEvent interfaces", ""];
-all(suite) -> {req,
- [mnesia, orber],
- {conf, init_all, cases(), finish_all}}.
-
-cases() ->
- [events_api, events_sync_api, event_objects_api, app_test].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [events_api, events_sync_api, event_objects_api,
+ app_test].
%%-----------------------------------------------------------------
%% Init and cleanup functions.
@@ -78,12 +90,12 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
Path = code:which(?MODULE),
code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
mnesia:delete_schema([node()]),
@@ -96,7 +108,7 @@ init_all(Config) when is_list(Config) ->
oe_event_test_server:oe_register(),
Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
oe_event_test_server:oe_unregister(),
cosEventApp:stop(),
cosEventApp:uninstall(),
diff --git a/lib/cosEvent/test/event_test_PullC_impl.erl b/lib/cosEvent/test/event_test_PullC_impl.erl
index 186d1cbd51..4b81572cad 100644
--- a/lib/cosEvent/test/event_test_PullC_impl.erl
+++ b/lib/cosEvent/test/event_test_PullC_impl.erl
@@ -2,7 +2,7 @@
%%
%% %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
diff --git a/lib/cosEvent/test/event_test_PullS_impl.erl b/lib/cosEvent/test/event_test_PullS_impl.erl
index b7fa0c34f0..81685980fb 100644
--- a/lib/cosEvent/test/event_test_PullS_impl.erl
+++ b/lib/cosEvent/test/event_test_PullS_impl.erl
@@ -2,7 +2,7 @@
%%
%% %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
diff --git a/lib/cosEvent/test/event_test_PushC_impl.erl b/lib/cosEvent/test/event_test_PushC_impl.erl
index 6eadf74a31..c2be1d4c08 100644
--- a/lib/cosEvent/test/event_test_PushC_impl.erl
+++ b/lib/cosEvent/test/event_test_PushC_impl.erl
@@ -2,7 +2,7 @@
%%
%% %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
diff --git a/lib/cosEvent/test/event_test_PushS_impl.erl b/lib/cosEvent/test/event_test_PushS_impl.erl
index da82e97211..35cfc66e6b 100644
--- a/lib/cosEvent/test/event_test_PushS_impl.erl
+++ b/lib/cosEvent/test/event_test_PushS_impl.erl
@@ -2,7 +2,7 @@
%%
%% %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
diff --git a/lib/cosEvent/test/generated_SUITE.erl b/lib/cosEvent/test/generated_SUITE.erl
index 2d75b18451..b3c8f91267 100644
--- a/lib/cosEvent/test/generated_SUITE.erl
+++ b/lib/cosEvent/test/generated_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
-module(generated_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -71,12 +71,12 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -84,19 +84,42 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["This suite is for testing IC generated files"];
-all(suite) ->
- ['CosEventChannelAdmin_AlreadyConnected', 'CosEventChannelAdmin_TypeError',
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ ['CosEventChannelAdmin_AlreadyConnected',
+ 'CosEventChannelAdmin_TypeError',
'CosEventComm_Disconnected',
- 'CosEventChannelAdmin_ConsumerAdmin', 'CosEventChannelAdmin_EventChannel',
- 'CosEventChannelAdmin_ProxyPullConsumer', 'CosEventChannelAdmin_ProxyPullSupplier',
- 'CosEventChannelAdmin_ProxyPushConsumer', 'CosEventChannelAdmin_ProxyPushSupplier',
- 'CosEventChannelAdmin_SupplierAdmin', oe_CosEventComm_CAdmin,
- oe_CosEventComm_Channel, oe_CosEventComm_Event, oe_CosEventComm_PullerS,
- oe_CosEventComm_PusherS, 'CosEventComm_PullConsumer',
- 'CosEventComm_PullSupplier', 'CosEventComm_PushConsumer',
+ 'CosEventChannelAdmin_ConsumerAdmin',
+ 'CosEventChannelAdmin_EventChannel',
+ 'CosEventChannelAdmin_ProxyPullConsumer',
+ 'CosEventChannelAdmin_ProxyPullSupplier',
+ 'CosEventChannelAdmin_ProxyPushConsumer',
+ 'CosEventChannelAdmin_ProxyPushSupplier',
+ 'CosEventChannelAdmin_SupplierAdmin',
+ oe_CosEventComm_CAdmin, oe_CosEventComm_Channel,
+ oe_CosEventComm_Event, oe_CosEventComm_PullerS,
+ oe_CosEventComm_PusherS, 'CosEventComm_PullConsumer',
+ 'CosEventComm_PullSupplier',
+ 'CosEventComm_PushConsumer',
'CosEventComm_PushSupplier'].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -105,7 +128,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/cosEvent/vsn.mk b/lib/cosEvent/vsn.mk
index 9c00a17100..38999db5fa 100644
--- a/lib/cosEvent/vsn.mk
+++ b/lib/cosEvent/vsn.mk
@@ -1 +1,3 @@
-COSEVENT_VSN = 2.1.9
+
+COSEVENT_VSN = 2.1.10
+
diff --git a/lib/cosEventDomain/doc/src/notes.xml b/lib/cosEventDomain/doc/src/notes.xml
index deb1985c86..522dcea829 100644
--- a/lib/cosEventDomain/doc/src/notes.xml
+++ b/lib/cosEventDomain/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2010</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,7 +32,24 @@
</header>
<section>
+ <title>cosEventDomain 1.1.10</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Eliminated Dialyzer warnings when using exit or throw.</p>
+ <p>
+ Own Id: OTP-9050 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosEventDomain 1.1.9</title>
+
<section>
<title>Improvements and New Features</title>
<list type="bulleted">
@@ -44,7 +61,6 @@
</item>
</list>
</section>
-
</section>
<section>
diff --git a/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomain_impl.erl b/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomain_impl.erl
index 0b73100540..f5dd6d5c14 100644
--- a/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomain_impl.erl
+++ b/lib/cosEventDomain/src/CosEventDomainAdmin_EventDomain_impl.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -778,12 +778,17 @@ get_qos(_OE_This, #state{cyclic = Cyclic, diamonds = Diamonds} = State) ->
%%----------------------------------------------------------------------
set_qos(_OE_This, State, NewQoS) ->
QoS = cosEventDomainApp:get_qos(NewQoS),
- set_qos_helper(QoS, State, []).
+ case set_qos_helper(QoS, State, []) of
+ {ok, NewState} ->
+ {reply, ok, NewState};
+ {error, Errors} ->
+ corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Errors})
+ end.
set_qos_helper([], State, []) ->
- {reply, ok, State};
+ {ok, State}; %{reply, ok, State};
set_qos_helper([], _, Errors) ->
- corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Errors});
+ {error, Errors};
set_qos_helper([{?DiamondDetection, Diamonds}|T], #state{diamonds = Diamonds} = State,
Errors) ->
set_qos_helper(T, State, Errors);
@@ -828,12 +833,17 @@ set_qos_helper([{?CycleDetection, _}|T], #state{cyclic = Cyclic} = State, Errors
%%----------------------------------------------------------------------
validate_qos(_OE_This, State, WantedQoS) ->
QoS = cosEventDomainApp:get_qos(WantedQoS),
- {reply, {ok, validate_qos_helper(QoS, State, [], [])}, State}.
+ case validate_qos_helper(QoS, State, [], []) of
+ {ok, Properties} ->
+ {reply, {ok, Properties}, State};
+ {error, Errors} ->
+ corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Errors})
+ end.
validate_qos_helper([], _, Properties, []) ->
- Properties;
+ {ok, Properties};
validate_qos_helper([], _, _, Errors) ->
- corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Errors});
+ {error, Errors};
validate_qos_helper([{?DiamondDetection, ?ForbidDiamonds}|T], State, Properties,
Errors) ->
case get_diamonds_helper(State, false) of
diff --git a/lib/cosEventDomain/src/cosEventDomainApp.erl b/lib/cosEventDomain/src/cosEventDomainApp.erl
index d57f51443c..734e4deccb 100644
--- a/lib/cosEventDomain/src/cosEventDomainApp.erl
+++ b/lib/cosEventDomain/src/cosEventDomainApp.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -270,12 +270,17 @@ create_id() ->
get_qos([]) ->
[];
get_qos(Properties) ->
- get_qos(Properties, [], []).
+ case get_qos(Properties, [], []) of
+ {ok, Supported} ->
+ Supported;
+ {error, Unsupported} ->
+ corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupported})
+ end.
get_qos([], Supported, []) ->
- Supported;
+ {ok, Supported};
get_qos([], _, Unsupported) ->
- corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupported});
+ {error, Unsupported};
get_qos([#'CosNotification_Property'{name = ?CycleDetection,
value= #any{value = ?AuthorizeCycles}}|T],
Supported, Unsupported) ->
diff --git a/lib/cosEventDomain/test/Makefile b/lib/cosEventDomain/test/Makefile
index 9893b05b8c..5b53690c6b 100644
--- a/lib/cosEventDomain/test/Makefile
+++ b/lib/cosEventDomain/test/Makefile
@@ -34,6 +34,7 @@ RELSYSDIR = $(RELEASE_PATH)/cosEventDomain_test
# Target Specs
# ----------------------------------------------------
TEST_SPEC_FILE = cosEventDomain.spec
+COVER_FILE = cosEventDomain.cover
MODULES = \
@@ -99,6 +100,6 @@ release_docs_spec:
release_tests_spec: tests
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(TEST_SPEC_FILE) \
- $(ERL_FILES) $(RELSYSDIR)
+ $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
diff --git a/lib/cosEventDomain/test/cosEventDomain.cover b/lib/cosEventDomain/test/cosEventDomain.cover
new file mode 100644
index 0000000000..f87f6d97bf
--- /dev/null
+++ b/lib/cosEventDomain/test/cosEventDomain.cover
@@ -0,0 +1,2 @@
+{incl_app,cosEventDomain,details}.
+
diff --git a/lib/cosEventDomain/test/cosEventDomain.spec b/lib/cosEventDomain/test/cosEventDomain.spec
index 0d3e307071..bcee74c5f1 100644
--- a/lib/cosEventDomain/test/cosEventDomain.spec
+++ b/lib/cosEventDomain/test/cosEventDomain.spec
@@ -1,19 +1 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-{topcase, {dir, "../cosEventDomain_test"}}.
+{suites,"../cosEventDomain_test",all}.
diff --git a/lib/cosEventDomain/test/event_domain_SUITE.erl b/lib/cosEventDomain/test/event_domain_SUITE.erl
index ddf0af3489..2793f94639 100644
--- a/lib/cosEventDomain/test/event_domain_SUITE.erl
+++ b/lib/cosEventDomain/test/event_domain_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %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
@@ -22,7 +22,7 @@
-module(event_domain_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("cosNotification/include/CosNotifyChannelAdmin.hrl").
-include_lib("cosNotification/include/CosNotification.hrl").
@@ -56,20 +56,31 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, event_domain_api/1, event_domain_factory_api/1,
- cases/0, init_all/1, finish_all/1,
- init_per_testcase/2, fin_per_testcase/2, app_test/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ event_domain_api/1, event_domain_factory_api/1,
+ cases/0, init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2, app_test/1]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for the cosEventDomain interfaces", ""];
-all(suite) -> {req,
- [mnesia, orber, cosNotification],
- {conf, init_all, cases(), finish_all}}.
-
-cases() ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
[event_domain_api, event_domain_factory_api, app_test].
%%-----------------------------------------------------------------
@@ -81,12 +92,12 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
mnesia:delete_schema([node()]),
mnesia:create_schema([node()]),
ok = corba:orb_init([{flags, 16#02},
@@ -102,7 +113,7 @@ init_all(Config) when is_list(Config) ->
cosEventDomainApp:start(),
Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
cosEventDomainApp:stop(),
cosEventDomainApp:uninstall(),
cosNotificationApp:stop(),
diff --git a/lib/cosEventDomain/test/generated_SUITE.erl b/lib/cosEventDomain/test/generated_SUITE.erl
index 6c6996ca79..575568a7b9 100644
--- a/lib/cosEventDomain/test/generated_SUITE.erl
+++ b/lib/cosEventDomain/test/generated_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
-module(generated_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -71,12 +71,11 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -84,17 +83,41 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["This suite is for testing IC generated files"];
-all(suite) ->
- ['CosEventDomainAdmin', 'CosEventDomainAdmin_DiamondSeq',
- 'CosEventDomainAdmin_AlreadyExists', 'CosEventDomainAdmin_DomainIDSeq',
- 'CosEventDomainAdmin_Connection', 'CosEventDomainAdmin_ConnectionIDSeq',
- 'CosEventDomainAdmin_ConnectionNotFound', 'CosEventDomainAdmin_CycleCreationForbidden',
- 'CosEventDomainAdmin_CycleSeq', 'CosEventDomainAdmin_DiamondCreationForbidden',
- 'CosEventDomainAdmin_DomainNotFound', 'CosEventDomainAdmin_MemberIDSeq',
- 'CosEventDomainAdmin_RouteSeq', 'CosEventDomainAdmin_EventDomainFactory',
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ ['CosEventDomainAdmin',
+ 'CosEventDomainAdmin_DiamondSeq',
+ 'CosEventDomainAdmin_AlreadyExists',
+ 'CosEventDomainAdmin_DomainIDSeq',
+ 'CosEventDomainAdmin_Connection',
+ 'CosEventDomainAdmin_ConnectionIDSeq',
+ 'CosEventDomainAdmin_ConnectionNotFound',
+ 'CosEventDomainAdmin_CycleCreationForbidden',
+ 'CosEventDomainAdmin_CycleSeq',
+ 'CosEventDomainAdmin_DiamondCreationForbidden',
+ 'CosEventDomainAdmin_DomainNotFound',
+ 'CosEventDomainAdmin_MemberIDSeq',
+ 'CosEventDomainAdmin_RouteSeq',
+ 'CosEventDomainAdmin_EventDomainFactory',
'CosEventDomainAdmin_EventDomain'].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -103,7 +126,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/cosEventDomain/vsn.mk b/lib/cosEventDomain/vsn.mk
index bd21133fe5..f4a77ab7a8 100644
--- a/lib/cosEventDomain/vsn.mk
+++ b/lib/cosEventDomain/vsn.mk
@@ -1 +1,3 @@
-COSEVENTDOMAIN_VSN = 1.1.9
+
+COSEVENTDOMAIN_VSN = 1.1.10
+
diff --git a/lib/cosFileTransfer/test/Makefile b/lib/cosFileTransfer/test/Makefile
new file mode 100644
index 0000000000..cb181bdb66
--- /dev/null
+++ b/lib/cosFileTransfer/test/Makefile
@@ -0,0 +1,133 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(COSFILETRANSFER_VSN)
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/cosFileTransfer_test
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+TEST_SPEC_FILE = cosFileTransfer.spec
+COVER_FILE = cosFileTransfer.cover
+
+
+IDL_FILES =
+
+IDLOUTDIR = idl_output
+
+MODULES = \
+ fileTransfer_SUITE \
+
+GEN_MODULES = \
+
+GEN_HRL_FILES = \
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES =
+
+GEN_FILES = \
+ $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \
+ $(GEN_MODULES:%=$(IDLOUTDIR)/%.erl)
+
+GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR))
+
+SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR))
+
+TARGET_FILES = \
+ $(GEN_TARGET_FILES) \
+ $(SUITE_TARGET_FILES)
+
+
+# ----------------------------------------------------
+# PROGRAMS
+# ----------------------------------------------------
+LOCAL_CLASSPATH = $(ERL_TOP)lib/cosFileTransfer/priv:$(ERL_TOP)lib/cosFileTransfer/test
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosFileTransfer/ebin \
+ -pa $(ERL_TOP)/lib/cosFileTransfer/src \
+ -pa $(ERL_TOP)/lib/cosFileTransfer/include \
+ -pa $(ERL_TOP)/lib/cosProperty/ebin \
+ -pa $(ERL_TOP)/lib/cosProperty/include \
+ -pa $(ERL_TOP)/lib/orber/ebin \
+ -pa $(ERL_TOP)/lib/ic/ebin
+
+ERL_COMPILE_FLAGS += \
+ $(ERL_IDL_FLAGS) \
+ -pa $(ERL_TOP)/lib/orber/include \
+ -pa $(ERL_TOP)/lib/cosProperty/include \
+ -pa $(ERL_TOP)/internal_tools/test_server/ebin \
+ -pa $(ERL_TOP)/lib/cosFileTransfer/ebin \
+ -pa $(ERL_TOP)/lib/cosFileTransfer/include \
+ -pa $(ERL_TOP)/lib/cosFileTransfer/test/idl_output \
+ -I$(ERL_TOP)/lib/orber/include \
+ -I$(ERL_TOP)/lib/cosProperty/include \
+ -I$(ERL_TOP)/lib/cosFileTransfer/src \
+ -I$(ERL_TOP)/lib/cosFileTransfer/include \
+ -I$(ERL_TOP)/lib/cosFileTransfer \
+ -I$(ERL_TOP)/lib/cosFileTransfer/test/$(IDLOUTDIR) \
+ -I$(ERL_TOP)/lib/test_server/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+
+tests debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f idl_output/*
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+docs:
+
+# ----------------------------------------------------
+# Special Targets
+# ----------------------------------------------------
+
+# ----------------------------------------------------
+# Release Targets
+# ----------------------------------------------------
+# We don't copy generated intermediate erlang and hrl files
+
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_docs_spec:
+
+release_tests_spec: tests
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
+ $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
diff --git a/lib/cosFileTransfer/test/cosFileTransfer.cover b/lib/cosFileTransfer/test/cosFileTransfer.cover
new file mode 100644
index 0000000000..063dd66990
--- /dev/null
+++ b/lib/cosFileTransfer/test/cosFileTransfer.cover
@@ -0,0 +1,2 @@
+{incl_app,cosFileTransfer,details}.
+
diff --git a/lib/cosFileTransfer/test/cosFileTransfer.spec b/lib/cosFileTransfer/test/cosFileTransfer.spec
new file mode 100644
index 0000000000..290b27d048
--- /dev/null
+++ b/lib/cosFileTransfer/test/cosFileTransfer.spec
@@ -0,0 +1 @@
+{suites,"../cosFileTransfer_test", all}.
diff --git a/lib/cosFileTransfer/test/fileTransfer_SUITE.erl b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl
new file mode 100644
index 0000000000..1e27139ed1
--- /dev/null
+++ b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl
@@ -0,0 +1,972 @@
+%%-----------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+%%----------------------------------------------------------------------
+%% File : fileTransfer_SUITE.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module(fileTransfer_SUITE).
+
+%%--------------- INCLUDES -----------------------------------
+-include_lib("cosFileTransfer/src/cosFileTransferApp.hrl").
+
+-include_lib("test_server/include/test_server.hrl").
+
+%%--------------- DEFINES ------------------------------------
+-define(default_timeout, ?t:minutes(20)).
+-define(match(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT ------~n~p~n",
+ [AcTuAlReS]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ exit(AcTuAlReS)
+ end
+ end()).
+
+-define(matchnopr(ExpectedRes, Expr),
+ fun() ->
+ AcTuAlReS = (catch (Expr)),
+ case AcTuAlReS of
+ ExpectedRes ->
+ io:format("------ CORRECT RESULT (~p) ------~n", [?LINE]),
+ AcTuAlReS;
+ _ ->
+ io:format("###### ERROR ERROR ######~n~p~n",
+ [AcTuAlReS]),
+ exit(AcTuAlReS)
+ end
+ end()).
+
+
+
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([all/0,suite/0,groups/0,
+ init_per_group/2,end_per_group/2,
+ cases/0,
+ init_per_suite/1,
+ end_per_suite/1,
+ fileIterator_api/1,
+ fts_ftp_file_api/1,
+ fts_ftp_file_ssl_api/1,
+ fts_ftp_dir_api/1,
+ fts_native_file_api/1,
+ fts_native_file_ssl_api/1,
+ fts_native_dir_api/1,
+ init_per_testcase/2,
+ end_per_testcase/2,
+ install_data/2,
+ uninstall_data/1,
+ slave_sup/0,
+ app_test/1]).
+
+%%-----------------------------------------------------------------
+%% Func: all/1
+%% Args:
+%% Returns:
+%%-----------------------------------------------------------------
+suite() ->
+ [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [fts_ftp_dir_api, fts_ftp_file_api,
+ fts_ftp_file_ssl_api, fts_native_dir_api,
+ fts_native_file_api, fts_native_file_ssl_api,
+ fileIterator_api, app_test].
+
+%%-----------------------------------------------------------------
+%% Init and cleanup functions.
+%%-----------------------------------------------------------------
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog=test_server:timetrap(?default_timeout),
+ [{watchdog, Dog}|Config].
+
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+init_per_suite(Config) ->
+ case code:which(crypto) of
+ Res when is_atom(Res) ->
+ {skip,"Could not start crypto!"};
+ _Else ->
+ orber:jump_start(),
+ cosProperty:install(),
+ cosProperty:start(),
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ %% Client
+ cosFileTransferApp:configure(ssl_client_certfile,
+ filename:join([Dir, "client", "cert.pem"])),
+ cosFileTransferApp:configure(ssl_client_cacertfile,
+ filename:join([Dir, "client", "cacerts.pem"])),
+ cosFileTransferApp:configure(ssl_client_verify, 1),
+ cosFileTransferApp:configure(ssl_client_depth, 0),
+ %% Server
+ cosFileTransferApp:configure(ssl_server_certfile,
+ filename:join([Dir, "server", "cert.pem"])),
+ cosFileTransferApp:configure(ssl_server_cacertfile,
+ filename:join([Dir, "server", "cacerts.pem"])),
+ cosFileTransferApp:configure(ssl_server_verify, 1),
+ cosFileTransferApp:configure(ssl_server_depth, 0),
+ crypto:start(),
+ ssl:start(),
+ cosFileTransferApp:install(),
+ cosFileTransferApp:start(),
+ if
+ is_list(Config) ->
+ Config;
+ true ->
+ exit("Config not a list")
+ end
+ end.
+
+end_per_suite(Config) ->
+ ssl:stop(),
+ crypto:stop(),
+ cosFileTransferApp:stop(),
+ cosProperty:stop(),
+ cosProperty:uninstall(),
+ cosFileTransferApp:uninstall(),
+ orber:jump_stop(),
+ Config.
+
+%%-----------------------------------------------------------------
+%% Local definitions
+%%-----------------------------------------------------------------
+-define(FTP_USER, "anonymous").
+-define(FTP_PASS, "fileTransfer_SUITE@localhost").
+-define(TEST_DIR,["/", "incoming"]).
+
+
+-define(FTP_PORT, 21).
+-define(FTP_ACC, "anonymous").
+
+-define(BAD_HOST, "badhostname").
+-define(BAD_USER, "baduser").
+-define(BAD_DIR, "baddirectory").
+
+-define(TEST_FILE_DATA, "If this file exists after a completed test an error occurred.").
+-define(TEST_FILE_DATA2, "1234567890123").
+
+
+%%-----------------------------------------------------------------
+%% aoo-file test
+%%-----------------------------------------------------------------
+app_test(doc) -> [];
+app_test(suite) -> [];
+app_test(_Config) ->
+ ?line ok=?t:app_test(cosFileTransfer),
+ ok.
+
+%%-----------------------------------------------------------------
+%% FileIterator API tests
+%%-----------------------------------------------------------------
+fileIterator_api(doc) -> ["CosFileTransfer FileIterator API tests.", ""];
+fileIterator_api(suite) -> [];
+fileIterator_api(Config) ->
+ case ftp_host(Config) of
+ {skipped, SkippedReason} ->
+ {skipped, SkippedReason};
+ Host ->
+
+ ?line {ok, Node} = create_node("fileIterator_api", 4008, normal),
+ ?line ?match(ok, remote_apply(Node, ?MODULE, install_data,
+ [tcp, {{'NATIVE',
+ 'cosFileTransferNATIVE_file'}, Host,
+ "fileIterator_api"}])),
+
+ %% Create a Virtual File System.
+%% ?line VFS = ?match({_,_,_,_,_,_},
+%% cosFileTransferApp:create_VFS({'NATIVE',
+%% 'cosFileTransferNATIVE_file'},
+%% [], Host, ?FTP_PORT)),
+ ?line VFS = ?matchnopr({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_},
+ corba:string_to_object("corbaname::1.2@localhost:4008/NameService#fileIterator_api")),
+
+ %% Start two File Transfer Sessions (Source and Target).
+ ?line {FS, Dir} = ?matchnopr({{_,_,_},{_,_,_}},
+ 'CosFileTransfer_VirtualFileSystem':login(VFS,
+ ?FTP_USER,
+ ?FTP_PASS,
+ ?FTP_ACC)),
+
+ %% Do some basic test on one of the Directories attributes.
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(Dir)),
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(Dir)),
+ ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(Dir)),
+ ?line ?matchnopr(FS, 'CosFileTransfer_Directory':'_get_associated_session'(Dir)),
+ {ok,[],FileIter} = ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir, 0)),
+ %% Usually the working directory for the test is not empty so no need for
+ %% creating files of our own?!
+ #any{value=Children} = ?match({any, _, _},
+ 'CosPropertyService_PropertySet':
+ get_property_value(Dir, "num_children")),
+
+ if
+ Children > 5 ->
+ ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_one(FileIter)),
+ ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_n(FileIter, 3)),
+ ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_n(FileIter,
+ Children)),
+ ?line ?matchnopr({false, _}, 'CosFileTransfer_FileIterator':next_one(FileIter)),
+ ?line ?match({false, []}, 'CosFileTransfer_FileIterator':next_n(FileIter, 1)),
+ ok;
+ true ->
+ ok
+ end,
+ ?line ?match(ok, 'CosFileTransfer_FileIterator':destroy(FileIter)),
+ ?line ?match(false, corba_object:non_existent(FS)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FS)),
+ %% To make sure Orber can remove it from mnesia.
+ timer:sleep(1000),
+ ?line ?match(true, corba_object:non_existent(FS)),
+ ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, ["fileIterator_api"])),
+ stop_orber_remote(Node, normal),
+ ok
+ end.
+
+
+%%-----------------------------------------------------------------
+%% FileTransferSession API tests
+%%-----------------------------------------------------------------
+fts_ftp_file_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""];
+fts_ftp_file_api(suite) -> [];
+fts_ftp_file_api(Config) ->
+ ?line {ok, Node} = create_node("ftp_file_api", 4004, normal),
+ file_helper(Config, 'FTP', ?TEST_DIR, Node, 4004, "ftp_file_api", tcp).
+
+fts_ftp_file_ssl_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""];
+fts_ftp_file_ssl_api(suite) -> [];
+fts_ftp_file_ssl_api(Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ ?line {ok, Node} = create_node("ftp_file_api_ssl", {4005, 1}, ssl),
+ file_helper(Config, 'FTP', ?TEST_DIR, Node, 4005, "ftp_file_api_ssl", ssl)
+ end.
+
+fts_native_file_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""];
+fts_native_file_api(suite) -> [];
+fts_native_file_api(Config) ->
+ ?line {ok, Node} = create_node("native_file_api", 4006, normal),
+ {ok, Pwd} = file:get_cwd(),
+ file_helper(Config,{'NATIVE', 'cosFileTransferNATIVE_file'},filename:split(Pwd),
+ Node, 4006, "native_file_api", tcp).
+
+fts_native_file_ssl_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""];
+fts_native_file_ssl_api(suite) -> [];
+fts_native_file_ssl_api(Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "No SSL-support for VxWorks."};
+ _ ->
+ ?line {ok, Node} = create_node("native_file_ssl_api", {4007, 1}, ssl),
+ {ok, Pwd} = file:get_cwd(),
+ file_helper(Config,{'NATIVE', 'cosFileTransferNATIVE_file'},filename:split(Pwd),
+ Node, 4007, "native_file_ssl_api", ssl)
+ end.
+
+
+
+file_helper(Config, WhichType, TEST_DIR, Node, Port, Name, Type) ->
+ case ftp_host(Config) of
+ {skipped, SkippedReason} ->
+ {skipped, SkippedReason};
+ Host ->
+ TEST_SOURCE = TEST_DIR ++ [create_name(remove_me_source)],
+ TEST_SOURCE2 = TEST_DIR ++ [create_name(remove_me_source)],
+ TEST_TARGET = TEST_DIR ++ [create_name(remove_me_target)],
+
+ io:format("<<<<<< CosFileTransfer Testing Configuration >>>>>>~n",[]),
+ io:format("Source: ~p~nTarget: ~p~n", [TEST_SOURCE, TEST_TARGET]),
+
+ ?line ?match(ok, remote_apply(Node, ?MODULE, install_data,
+ [Type, {WhichType, Host, Name}])),
+
+ ?line VFST = ?match({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_},
+ corba:string_to_object("corbaname::1.2@localhost:"++integer_to_list(Port)++"/NameService#"++Name)),
+
+
+ %% Create a Virtual File System.
+ ?line VFS = ?match({_,_,_,_,_,_},
+ cosFileTransferApp:create_VFS(WhichType, [], Host, ?FTP_PORT,
+ [{protocol, Type}])),
+ %% Start two File Transfer Sessions (Source and Target).
+ ?line {FST, _DirT} = ?match({{_,_,_},{_,_,_}},
+ 'CosFileTransfer_VirtualFileSystem':login(VFST,
+ ?FTP_USER,
+ ?FTP_PASS,
+ ?FTP_ACC)),
+ ?line {FSS, DirS} = ?match({{_,_,_,_,_,_},{_,_,_,_,_,_}},
+ 'CosFileTransfer_VirtualFileSystem':login(VFS,
+ ?FTP_USER,
+ ?FTP_PASS,
+ ?FTP_ACC)),
+
+ %% Do some basic test on one of the Directories attributes.
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(DirS)),
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(DirS)),
+ ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(DirS)),
+ ?line ?match(FSS, 'CosFileTransfer_Directory':'_get_associated_session'(DirS)),
+
+ %% Get a FileList before we create any new Files
+ ?line #'CosFileTransfer_FileWrapper'{the_file = Dir} =
+ ?match({'CosFileTransfer_FileWrapper', _, ndirectory},
+ 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_DIR)),
+ ?line {ok,FileList, Iter1} = ?match({ok,_,_}, 'CosFileTransfer_Directory':list(Dir, 10)),
+ ?line loop_files(FileList),
+
+ case Iter1 of
+ {'IOP_IOR',[],[]} ->
+ ok;
+ _->
+ ?line ?match(ok, 'CosFileTransfer_FileIterator':destroy(Iter1))
+ end,
+
+ #any{value=Count1} = ?match({any, _, _}, 'CosPropertyService_PropertySet':
+ get_property_value(Dir, "num_children")),
+
+ %% Now we want to transfer a file from source to target. First, we'll create
+ %% a a file to work with.
+ ?line create_file_on_source_node(WhichType, Config, Host,
+ filename:join(TEST_SOURCE), TEST_DIR,
+ ?TEST_FILE_DATA),
+ ?line create_file_on_source_node(WhichType, Config, Host,
+ filename:join(TEST_SOURCE2), TEST_DIR,
+ ?TEST_FILE_DATA2),
+
+ ?line #'CosFileTransfer_FileWrapper'{the_file = FileS} =
+ ?matchnopr({'CosFileTransfer_FileWrapper', _, nfile},
+ 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_SOURCE)),
+ ?line #'CosFileTransfer_FileWrapper'{the_file = FileS2} =
+ ?matchnopr({'CosFileTransfer_FileWrapper', _, nfile},
+ 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_SOURCE2)),
+
+ #any{value=Count2} = ?match({any, _, _}, 'CosPropertyService_PropertySet':
+ get_property_value(Dir, "num_children")),
+ timer:sleep(2000),
+ ?match(true, (Count1+2 == Count2)),
+
+ %% Create a target File
+ ?line FileT = ?matchnopr({_,_,_},
+ 'CosFileTransfer_FileTransferSession':create_file(FST, TEST_TARGET)),
+ %% Try to delete the non-existing file.
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_FileTransferSession':delete(FST, FileT)),
+
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':transfer(FSS, FileS, FileT)),
+
+ %% Remove this test when ftp supports append.
+ case WhichType of
+ {'NATIVE', 'cosFileTransferNATIVE_file'} ->
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':append(FSS, FileS, FileT)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':insert(FSS, FileS2, FileT, 7));
+ _->
+ ok
+ end,
+
+ %% Delete source and target files
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FSS, FileS)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FSS, FileS2)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FST, FileT)),
+
+ %% Should be back where we started.
+ timer:sleep(2000),
+ #any{value=Count3} = ?match({any, _, _}, 'CosPropertyService_PropertySet':
+ get_property_value(Dir, "num_children")),
+ ?match(true, (Count1 == Count3)),
+
+
+ ?line ?match(false, corba_object:non_existent(FSS)),
+ ?line ?match(false, corba_object:non_existent(FST)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FSS)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FST)),
+ %% To make sure Orber can remove it from mnesia.
+ timer:sleep(2000),
+ ?line ?match(true, corba_object:non_existent(FSS)),
+ ?line ?match(true, corba_object:non_existent(FST)),
+ ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, [Name])),
+ stop_orber_remote(Node, normal),
+ ok
+ end.
+
+%%-----------------------------------------------------------------
+%% FileTransferSession API tests
+%%-----------------------------------------------------------------
+fts_ftp_dir_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""];
+fts_ftp_dir_api(suite) -> [];
+fts_ftp_dir_api(Config) ->
+ ?line {ok, Node} = create_node("ftp_dir_api", 4009, normal),
+ dir_helper(Config, 'FTP', ?TEST_DIR, Node, 4009, "ftp_dir_api").
+
+
+fts_native_dir_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""];
+fts_native_dir_api(suite) -> [];
+fts_native_dir_api(Config) ->
+ ?line {ok, Node} = create_node("native_dir_api", 4010, normal),
+ {ok, Pwd} = file:get_cwd(),
+ dir_helper(Config, {'NATIVE', 'cosFileTransferNATIVE_file'},
+ filename:split(Pwd), Node, 4010, "native_dir_api").
+
+dir_helper(Config, WhichType, TEST_DIR, Node, Port, Name) ->
+ case ftp_host(Config) of
+ {skipped, SkippedReason} ->
+ {skipped, SkippedReason};
+ Host ->
+ TEST_DIR_LEVEL1 = TEST_DIR ++ [create_name(remove_me_dir1)],
+ TEST_DIR_LEVEL2 = TEST_DIR_LEVEL1 ++ [create_name(remove_me_dir2)],
+
+ io:format("<<<<<< CosFileTransfer Testing Configuration >>>>>>~n",[]),
+ io:format("Top Dir: ~p~nLevel2 Dir: ~p~n", [TEST_DIR_LEVEL1, TEST_DIR_LEVEL2]),
+
+ ?line ?match(ok, remote_apply(Node, ?MODULE, install_data,
+ [tcp, {WhichType, Host, Name}])),
+
+ ?line VFS = ?matchnopr({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_},
+ corba:string_to_object("corbaname::1.2@localhost:"++integer_to_list(Port)++"/NameService#"++Name)),
+
+ %% Start two File Transfer Sessions (Source and Target).
+ ?line {FS, DirS} = ?matchnopr({{'IOP_IOR',_,_}, _},
+ 'CosFileTransfer_VirtualFileSystem':login(VFS,
+ ?FTP_USER,
+ ?FTP_PASS,
+ ?FTP_ACC)),
+
+ %% Do some basic test on one of the Directories attributes.
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(DirS)),
+ ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(DirS)),
+ ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(DirS)),
+ ?line ?matchnopr(FS, 'CosFileTransfer_Directory':'_get_associated_session'(DirS)),
+
+ %% Create a Root Directory. Currently we only need to create one but
+ %% later on, when supporting other protocols than FTP it's not enough.
+ ?line Dir1 = 'CosFileTransfer_FileTransferSession':create_directory(FS,
+ TEST_DIR_LEVEL1),
+ io:format("<<<<<< CosFileTransfer Testing Properties >>>>>>~n",[]),
+ ?line ?match({ok, [tk_long, tk_boolean]},
+ 'CosFileTransfer_Directory':get_allowed_property_types(Dir1)),
+ ?line ?match({ok, [_,_]},
+ 'CosFileTransfer_Directory':get_allowed_properties(Dir1)),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property_with_mode(Dir1,
+ "num_children",
+ #any{typecode=tk_long, value=0},
+ fixed_readonly)),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property_with_mode(Dir1,
+ "wrong",
+ #any{typecode=tk_long, value=0},
+ fixed_readonly)),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property_with_mode(Dir1,
+ "num_children",
+ #any{typecode=tk_short, value=0},
+ fixed_readonly)),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property_with_mode(Dir1,
+ "num_children",
+ #any{typecode=tk_long, value=0},
+ fixed_normal)),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_properties_with_modes(Dir1,
+ [#'CosPropertyService_PropertyDef'
+ {property_name = "num_children",
+ property_value = #any{typecode=tk_long, value=0},
+ property_mode = fixed_readonly}])),
+ ?line ?match(fixed_readonly,
+ 'CosFileTransfer_Directory':get_property_mode(Dir1, "num_children")),
+ ?line ?match({true,
+ [#'CosPropertyService_PropertyMode'{property_name = "num_children",
+ property_mode = fixed_readonly}]},
+ 'CosFileTransfer_Directory':get_property_modes(Dir1, ["num_children"])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':set_property_mode(Dir1, "num_children", fixed_readonly)),
+
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ set_property_modes(Dir1,
+ [#'CosPropertyService_PropertyMode'
+ {property_name = "num_children",
+ property_mode = fixed_readonly}])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ set_property_modes(Dir1,
+ [#'CosPropertyService_PropertyMode'
+ {property_name = "wrong",
+ property_mode = fixed_readonly}])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ set_property_modes(Dir1,
+ [#'CosPropertyService_PropertyMode'
+ {property_name = "num_children",
+ property_mode = fixed_normal}])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property(Dir1,
+ "num_children",
+ #any{typecode=tk_long, value=0})),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property(Dir1,
+ "wrong",
+ #any{typecode=tk_long, value=0})),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property(Dir1,
+ "num_children",
+ #any{typecode=tk_short, value=0})),
+
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':define_property(Dir1,
+ "num_children",
+ #any{typecode=tk_long, value=0})),
+
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ define_properties(Dir1,
+ [#'CosPropertyService_Property'
+ {property_name = "num_children",
+ property_value = #any{typecode=tk_long,
+ value=0}}])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ define_properties(Dir1,
+ [#'CosPropertyService_Property'
+ {property_name = "wrong",
+ property_value = #any{typecode=tk_long,
+ value=0}}])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':
+ define_properties(Dir1,
+ [#'CosPropertyService_Property'
+ {property_name = "num_children",
+ property_value = #any{typecode=tk_short,
+ value=0}}])),
+ ?line ?match(2, 'CosFileTransfer_Directory':get_number_of_properties(Dir1)),
+
+ ?line ?match({ok, ["num_children", "is_directory"], {'IOP_IOR',[],[]}},
+ 'CosFileTransfer_Directory':get_all_property_names(Dir1, 2)),
+ ?line ?match({ok, ["is_directory"], _},
+ 'CosFileTransfer_Directory':get_all_property_names(Dir1, 1)),
+
+ ?line ?match(#any{},
+ 'CosFileTransfer_Directory':get_property_value(Dir1, "num_children")),
+ ?line ?match(#any{},
+ 'CosFileTransfer_Directory':get_property_value(Dir1, "is_directory")),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':get_property_value(Dir1, "wrong")),
+
+ ?line ?match({true,
+ [#'CosPropertyService_Property'{property_name = "num_children"}]},
+ 'CosFileTransfer_Directory':get_properties(Dir1, ["num_children"])),
+ ?line ?match({false,
+ [#'CosPropertyService_Property'{property_name = "wrong"}]},
+ 'CosFileTransfer_Directory':get_properties(Dir1, ["wrong"])),
+
+ ?line ?match({ok, [_],_},
+ 'CosFileTransfer_Directory':get_all_properties(Dir1, 1)),
+ ?line ?match({ok, [_,_], {'IOP_IOR',[],[]}},
+ 'CosFileTransfer_Directory':get_all_properties(Dir1, 2)),
+
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':delete_property(Dir1, "num_children")),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':delete_property(Dir1, "wrong")),
+
+
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':delete_properties(Dir1, ["num_children"])),
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_Directory':delete_properties(Dir1, ["wrong"])),
+ ?line ?match(false, 'CosFileTransfer_Directory':delete_all_properties(Dir1)),
+ ?line ?match(true,
+ 'CosFileTransfer_Directory':is_property_defined(Dir1, "num_children")),
+ ?line ?match(false,
+ 'CosFileTransfer_Directory':is_property_defined(Dir1, "wrong")),
+
+ %% The Top Dir should be empty and ...
+ ?line ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir1, 1000)),
+ ?line ?match( #any{value=0},
+ 'CosPropertyService_PropertySet':get_property_value(Dir1, "num_children")),
+ %% Create a sub-directory.
+ ?line Dir2 = 'CosFileTransfer_FileTransferSession':create_directory(FS,
+ TEST_DIR_LEVEL2),
+ ?line ?match( #any{value=1},
+ 'CosPropertyService_PropertySet':get_property_value(Dir1, "num_children")),
+
+ ?line ?match({ok, [_,_], {'IOP_IOR',[],[]}},
+ 'CosFileTransfer_Directory':get_all_properties(Dir1, 2)),
+ ?line {_,_,Iterator1} = ?match({ok, [_], _},
+ 'CosFileTransfer_Directory':get_all_properties(Dir1, 1)),
+ ?line ?match({false, [_]},
+ 'CosPropertyService_PropertiesIterator':next_n(Iterator1,4)),
+
+ ?line {_,_,Iterator0} = ?match({ok, [], _},
+ 'CosFileTransfer_Directory':get_all_properties(Dir1, 0)),
+
+ ?line ?match({false, [_, {'CosPropertyService_Property',
+ "num_children",{any,tk_long,1}}]},
+ 'CosPropertyService_PropertiesIterator':next_n(Iterator0,4)),
+
+ ?line ?match({true,
+ [#'CosPropertyService_Property'{property_name = "num_children"}]},
+ 'CosFileTransfer_Directory':get_properties(Dir1, ["num_children"])),
+
+ %% The Top Directory is not emtpy any more and ...
+ ?line {ok,[#'CosFileTransfer_FileWrapper'{the_file = DirRef}],_} =
+ ?matchnopr({ok,[{'CosFileTransfer_FileWrapper', _, ndirectory}],_},
+ 'CosFileTransfer_Directory':list(Dir1, 1000)),
+ %% ... its name eq. to 'TEST_DIR_LEVEL2'
+ ?line ?match(TEST_DIR_LEVEL2,
+ 'CosFileTransfer_Directory':'_get_complete_file_name'(DirRef)),
+
+ ?line #'CosFileTransfer_FileWrapper'{the_file = Dir3} =
+ ?matchnopr({'CosFileTransfer_FileWrapper', _, ndirectory},
+ 'CosFileTransfer_FileTransferSession':get_file(FS, TEST_DIR_LEVEL1)),
+
+ %% Must get the same result for the 'get_file' operation.
+ ?line {ok,[#'CosFileTransfer_FileWrapper'{the_file = DirRef2}],_} =
+ ?matchnopr({ok,[{'CosFileTransfer_FileWrapper', _, ndirectory}],_},
+ 'CosFileTransfer_Directory':list(Dir3,1000)),
+ ?line ?match(TEST_DIR_LEVEL2,
+ 'CosFileTransfer_Directory':'_get_complete_file_name'(DirRef2)),
+
+ %% Since the top directory isn't empty deleting it must fail.
+ ?line ?match({'EXCEPTION', _},
+ 'CosFileTransfer_FileTransferSession':delete(FS, Dir1)),
+
+ %% Delete the sub-directory and ...
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FS, Dir2)),
+ %% ... see if the top directory realyy is empty.
+ ?line ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir1, 1000)),
+
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FS, Dir1)),
+ %% Test if the top directory been removed as intended.
+ ?line ?match({'EXCEPTION', {'CosFileTransfer_FileNotFoundException', _, _}},
+ 'CosFileTransfer_FileTransferSession':get_file(FS, TEST_DIR_LEVEL1)),
+
+ ?line ?match(false, corba_object:non_existent(FS)),
+ ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FS)),
+ %% To make sure Orber can remove it from mnesia.
+ timer:sleep(1000),
+ ?line ?match(true, corba_object:non_existent(FS)),
+ ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, [Name])),
+ stop_orber_remote(Node, normal),
+ ok
+ end.
+
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+ftp_host(Config) ->
+ case ?config(ftp_remote_host, Config) of
+ undefined ->
+ {skipped, "The configuration parameter 'ftp_remote_host' not defined."};
+ Host ->
+ Host
+ end.
+
+loop_files([]) ->
+ io:format("@@@ DONE @@@~n", []);
+loop_files([#'CosFileTransfer_FileWrapper'{the_file = H}|T]) ->
+ FullName = 'CosFileTransfer_File':'_get_complete_file_name'(H),
+ Name = 'CosFileTransfer_File':'_get_name'(H),
+ io:format("FULL NAME: ~p SHORT NAME: ~p~n", [FullName, Name]),
+ loop_files(T).
+
+
+create_file_on_source_node('FTP', _Config, Host, FileName, Path, Data) ->
+ io:format("<<<<<< CosFileTransfer Testing File >>>>>>~n",[]),
+ io:format("Host: ~p~nPath: ~p~nFile: ~p~n", [Host, Path, FileName]),
+ {ok, Pid} = ?match({ok, _}, inets:start(ftpc, [{host, Host}], stand_alone)),
+ ?match(ok, ftp:user(Pid, ?FTP_USER, ?FTP_PASS)),
+ ?match(ok, ftp:cd(Pid, Path)),
+ ?match(ok, ftp:send_bin(Pid, list_to_binary(Data), FileName)),
+ ?match(ok, inets:stop(ftpc, Pid));
+create_file_on_source_node({'NATIVE', _}, _Config, Host, FileName, Path, Data) ->
+ io:format("<<<<<< CosFileTransfer Testing File >>>>>>~n",[]),
+ io:format("Host: ~p~nPath: ~p~nFile: ~p~n", [Host, Path, FileName]),
+ ?match(ok, file:write_file(FileName, list_to_binary(Data))).
+
+create_name(Type) ->
+ {MSec, Sec, USec} = erlang:now(),
+ lists:concat([Type,'_',MSec, '_', Sec, '_', USec]).
+
+
+
+
+%%------------------------------------------------------------
+%% function : create_node/4
+%% Arguments: Name - the name of the new node (atom())
+%% Port - which iiop_port (integer())
+%% Domain - which domain.
+%% Type - if /4 used the types defines the extra arguments
+%% to be used.
+%% Returns : {ok, Node} | {error, _}
+%% Effect : Starts a new slave-node with given (optinally)
+%% extra arguments. If fails it retries 'Retries' times.
+%%------------------------------------------------------------
+create_node(Name, Port, normal) ->
+ Args = basic_args(Name),
+ create_node(Name, Port, 10, normal, Args, []);
+create_node(Name, {Port, _Depth}, ssl) ->
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ Args = basic_args(Name),
+ {ok, Node} = create_node(list_to_atom(Name), Port, 10, ssl, Args, []),
+ %% Client
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_certfile,
+ filename:join([Dir, "client", "cert.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_cacertfile,
+ filename:join([Dir, "client", "cacerts.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_keyfile,
+ filename:join([Dir, "client", "key.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_verify, 1]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_depth, 0]),
+
+ %% Server
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_certfile,
+ filename:join([Dir, "server", "cert.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_cacertfile,
+ filename:join([Dir, "server", "cacerts.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_keyfile,
+ filename:join([Dir, "server", "key.pem"])]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_verify, 1]),
+ rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_depth, 0]),
+ {ok, Node}.
+
+%create_node(Name, {Port, Depth}, ssl) ->
+% TestLibs = filename:join(filename:dirname(code:which(?MODULE)), "ssl_data"),
+% Args = basic_args(Name),
+% SArgs = basic_ssl_args(TestLibs, Args),
+% LArgs = level_based_ssl(Depth, TestLibs, SArgs),
+% create_node(list_to_atom(Name), Port, 10, ssl, LArgs, [{sslpath, TestLibs}]).
+
+create_node(Name, Port, Retries, Type, Args, Options) ->
+ [_, Host] = ?match([_,_],string:tokens(atom_to_list(node()), [$@])),
+ case starter(Host, Name, Args) of
+ {ok, NewNode} ->
+ ?line ?match(pong, net_adm:ping(NewNode)),
+ {ok, Cwd} = file:get_cwd(),
+ Path = code:get_path(),
+ ?line ?match(ok, rpc:call(NewNode, file, set_cwd, [Cwd])),
+ true = rpc:call(NewNode, code, set_path, [Path]),
+ ?match(ok, start_orber_remote(NewNode, Type, Options, Port)),
+ spawn_link(NewNode, ?MODULE, slave_sup, []),
+ rpc:multicall([node() | nodes()], global, sync, []),
+ {ok, NewNode};
+ {error, Reason} when Retries == 0->
+ {error, Reason};
+ {error, Reason} ->
+ io:format("Could not start slavenode ~p ~p retrying~n",
+ [{Host, Name, Args}, Reason]),
+ timer:sleep(500),
+ create_node(Name, Port, Retries - 1, Type, Args, Options)
+ end.
+
+starter(Host, Name, Args) ->
+ case os:type() of
+ vxworks ->
+ test_server:start_node(Name, slave, [{args,Args}]);
+ _ ->
+ slave:start(Host, Name, Args)
+ end.
+
+slave_sup() ->
+ process_flag(trap_exit, true),
+ receive
+ {'EXIT', _, _} ->
+ case os:type() of
+ vxworks ->
+ erlang:halt();
+ _ ->
+ ignore
+ end
+ end.
+
+
+%%------------------------------------------------------------
+%% function : destroy_node
+%% Arguments: Node - which node to destroy.
+%% Type - normal | ssl
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+-ifdef(false).
+destroy_node(Node, Type) ->
+ stopper(Node, Type).
+
+stopper(Node, Type) ->
+ catch stop_orber_remote(Node, Type),
+ case os:type() of
+ vxworks ->
+ test_server:stop_node(Node);
+ _ ->
+ slave:stop(Node)
+ end.
+-endif.
+
+%%------------------------------------------------------------
+%% function : remote_apply
+%% Arguments: N - Node, M - Module,
+%% F - Function, A - Arguments (list)
+%% Returns :
+%% Effect :
+%%------------------------------------------------------------
+remote_apply(N, M,F,A) ->
+ case rpc:call(N, M, F, A) of
+ {badrpc, Reason} ->
+ exit(Reason);
+ Other ->
+ Other
+ end.
+
+%%------------------------------------------------------------
+%% function : stop_orber_remote
+%% Arguments: Node - which node to stop orber on.
+%% Type - normal | ssl | light | .......
+%% Returns : ok
+%% Effect : Stops orber on given node and, if specified,
+%% other applications or programs.
+%%------------------------------------------------------------
+stop_orber_remote(Node, ssl) ->
+ rpc:call(Node, ssl, stop, []),
+ rpc:call(Node, crypto, stop, []),
+ orb_rpc_blast(Node, ssl);
+stop_orber_remote(Node, Type) ->
+ orb_rpc_blast(Node, Type).
+
+orb_rpc_blast(Node, _) ->
+ rpc:call(Node, cosFileTransferApp, stop, []),
+ rpc:call(Node, cosProperty, stop, []),
+ rpc:call(Node, cosFileTransferApp, uninstall, []),
+ rpc:call(Node, cosProperty, uninstall, []),
+ rpc:call(Node, orber, jump_stop, []).
+
+%%------------------------------------------------------------
+%% function : start_orber_remote
+%% Arguments: Node - which node to start orber on.
+%% Type - normal | ssl | light | .......
+%% Returns : ok
+%% Effect : Starts orber on given node and, if specified,
+%% other applications or programs.
+%%------------------------------------------------------------
+start_orber_remote(Node, ssl, _Options, Port) ->
+ rpc:call(Node, ssl, start, []),
+ rpc:call(Node, crypto, start, []),
+ rpc:call(Node, ssl, seed, ["testing"]),
+ orb_rpc_setup(Node, ssl, Port);
+start_orber_remote(Node, Type, _, Port) ->
+ orb_rpc_setup(Node, Type, Port).
+
+orb_rpc_setup(Node, _, Port) ->
+ rpc:call(Node, orber, jump_start, [Port]),
+ rpc:call(Node, cosProperty, install, []),
+ rpc:call(Node, cosProperty, start, []),
+ rpc:call(Node, cosFileTransferApp, install, []).
+
+%%--------------- MISC FUNCTIONS -----------------------------
+basic_args(_Name) ->
+ TestLibs = filename:dirname(code:which(?MODULE)),
+ " -orber orber_debug_level 10" ++
+ " -pa " ++
+ TestLibs ++
+ " -pa " ++
+ filename:join(TestLibs, "all_SUITE_data") ++
+ " -pa " ++
+ filename:dirname(code:which(cosFileTransferApp)).
+
+-ifdef(false).
+basic_ssl_args(TestLibs, Args) ->
+% Args ++
+% " -cosFileTransfer ssl_client_certfile \\\"" ++
+% filename:join(TestLibs, "ssl_client_cert.pem") ++
+% "\\\" -cosFileTransfer ssl_server_certfile \\\""++
+% filename:join(TestLibs, "ssl_server_cert.pem")++"\\\"".
+
+ io:format("<<<<<< SSL LIBS ~p >>>>>>~n",[TestLibs]),
+ NewArgs = Args ++
+ " -cosFileTransfer ssl_client_certfile \\\"" ++
+ filename:join(TestLibs, "ssl_client_cert.pem") ++
+ "\\\" -cosFileTransfer ssl_server_certfile \\\""++
+ filename:join(TestLibs, "ssl_server_cert.pem")++"\\\"",
+ io:format("<<<<<< SSL LIBS ARGS ~p >>>>>>~n",[NewArgs]),
+ NewArgs.
+
+level_based_ssl(1, _TestLibs, Args) ->
+ Args;
+level_based_ssl(2, _TestLibs, Args) ->
+ Args.% ++
+% " -cosFileTransfer ssl_server_depth 2 " ++
+% " -cosFileTransfer ssl_client_depth 2 " ++
+% " -cosFileTransfer ssl_server_verify " ++
+% " -cosFileTransfer ssl_client_verify " ++
+% " -cosFileTransfer ssl_server_cacertfile " ++
+% " -cosFileTransfer ssl_client_cacertfile " ++
+
+-endif.
+
+install_data(Protocol, {WhichType, Host, Name}) ->
+ io:format("<<<<<< Starting ~p/~p VFS at ~p/~p>>>>>>~n",
+ [Protocol, WhichType, Host, Name]),
+ %% Create a Virtual File System.
+ ?line VFS = ?match({_,_,_,_,_,_},
+ cosFileTransferApp:create_VFS(WhichType, [], Host, ?FTP_PORT,
+ [{protocol, Protocol}])),
+ NS = corba:resolve_initial_references("NameService"),
+ NC1 = lname_component:set_id(lname_component:create(), Name),
+ N = lname:insert_component(lname:create(), 1, NC1),
+ 'CosNaming_NamingContext':rebind(NS, N, VFS).
+
+uninstall_data(Name) ->
+ ?line VFS = ?match({_,_,_,_,_,_},
+ corba:string_to_object("corbaname:rir:/NameService#"++Name)),
+ ?line ?match(ok, corba:dispose(VFS)),
+ ok.
+
+
+
+%%------------------- EOF MODULE-----------------------------------
diff --git a/lib/cosNotification/doc/src/notes.xml b/lib/cosNotification/doc/src/notes.xml
index de5a3e5f4c..125e25e67e 100644
--- a/lib/cosNotification/doc/src/notes.xml
+++ b/lib/cosNotification/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2010</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,60 @@
<file>notes.xml</file>
</header>
+ <section><title>cosNotification 1.1.16</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Eliminated Dialyzer warnings when using exit or throw.</p>
+ <p>
+ Own Id: OTP-9050</p>
+ </item>
+ </list>
+ </section>
+</section>
+
+ <section><title>cosNotification 1.1.15</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Switched from using the deprecated regexp to re instead.</p>
+ <p>
+ Own Id: OTP-8846</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section>
+ <title>cosNotification 1.1.14</title>
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Test suites published.</p>
+ <p>
+ Own Id: OTP-8543 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Added missing trailing bracket to define in hrl-file.</p>
+ <p>Own Id: OTP-8489 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
<section>
<title>cosNotification 1.1.14</title>
<section>
@@ -64,15 +118,15 @@
<list type="bulleted">
<item>
<p>Removed superfluous VT in the documentation.</p>
- <p>Own id: OTP-8353 Aux Id:</p>
+ <p>Own Id: OTP-8353 Aux Id:</p>
</item>
<item>
<p>Removed superfluous backslash in the documentation.</p>
- <p>Own id: OTP-8354 Aux Id:</p>
+ <p>Own Id: OTP-8354 Aux Id:</p>
</item>
<item>
<p>The documentation EIX file was not generated.</p>
- <p>Own id: OTP-8355 Aux Id:</p>
+ <p>Own Id: OTP-8355 Aux Id:</p>
</item>
</list>
</section>
@@ -104,7 +158,7 @@
<item>
<p>Obsolete guards, e.g. record vs is_record, has been changed
to avoid compiler warnings.</p>
- <p>Own id: OTP-7987</p>
+ <p>Own Id: OTP-7987</p>
</item>
</list>
</section>
@@ -118,7 +172,7 @@
<list type="bulleted">
<item>
<p>Updated file headers.</p>
- <p>Own id: OTP-7837 Aux Id:</p>
+ <p>Own Id: OTP-7837 Aux Id:</p>
</item>
</list>
</section>
@@ -132,7 +186,7 @@
<list type="bulleted">
<item>
<p>Documentation source included in open source releases.</p>
- <p>Own id: OTP-7595 Aux Id:</p>
+ <p>Own Id: OTP-7595 Aux Id:</p>
</item>
</list>
</section>
@@ -147,7 +201,7 @@
<item>
<p>The CosNotification proxy objects ignored the gcLimit option, instead
the gcTime value was used.</p>
- <p>Own id: OTP-7553 Aux Id:</p>
+ <p>Own Id: OTP-7553 Aux Id:</p>
</item>
</list>
</section>
@@ -161,7 +215,7 @@
<list type="bulleted">
<item>
<p>Updated file headers.</p>
- <p>Own id: OTP-7011</p>
+ <p>Own Id: OTP-7011</p>
</item>
</list>
</section>
@@ -175,7 +229,7 @@
<list type="bulleted">
<item>
<p>The documentation source has been converted from SGML to XML.</p>
- <p>Own id: OTP-6754</p>
+ <p>Own Id: OTP-6754</p>
</item>
</list>
</section>
@@ -189,7 +243,7 @@
<list type="bulleted">
<item>
<p>Minor Makefile changes.</p>
- <p>Own id: OTP-6701</p>
+ <p>Own Id: OTP-6701</p>
</item>
</list>
</section>
@@ -203,7 +257,7 @@
<list type="bulleted">
<item>
<p>Removed some unused code.</p>
- <p>Own id: OTP-6527</p>
+ <p>Own Id: OTP-6527</p>
</item>
</list>
</section>
@@ -219,7 +273,7 @@
<p>A user can now define the QoS EventReliability to be
Persistent. Note, this is only a lightweight version
and events will be lost if a proxy is terminated.</p>
- <p>Own id: OTP-5923</p>
+ <p>Own Id: OTP-5923</p>
</item>
</list>
</section>
@@ -235,7 +289,7 @@
<p>Possible to configure cosNotification not to type check,
by invoking corba_object:is_a/2, supplied IOR:s. When
a type check fails, the feedback has been improved.</p>
- <p>Own id: OTP-5823 Aux Id: seq10143</p>
+ <p>Own Id: OTP-5823 Aux Id: seq10143</p>
</item>
</list>
</section>
@@ -249,7 +303,7 @@
<list type="bulleted">
<item>
<p>The app-file contained duplicated modules.</p>
- <p>Own id: OTP-4976</p>
+ <p>Own Id: OTP-4976</p>
</item>
</list>
</section>
@@ -268,7 +322,7 @@
Interface Repository. It is necessary to re-compile all IDL-files
and use COS-applications, including Orber, compiled with
IC-4.2.</p>
- <p>Own id: OTP-4576</p>
+ <p>Own Id: OTP-4576</p>
</item>
</list>
</section>
diff --git a/lib/cosNotification/src/CosNotification_Common.erl b/lib/cosNotification/src/CosNotification_Common.erl
index 0e0f1da0d5..af9b2d4368 100644
--- a/lib/cosNotification/src/CosNotification_Common.erl
+++ b/lib/cosNotification/src/CosNotification_Common.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,7 +28,6 @@
%%--------------- INCLUDES -----------------------------------
-include_lib("orber/include/corba.hrl").
--include_lib("orber/include/ifr_types.hrl").
%% Application files
-include("CosNotification.hrl").
-include("CosNotifyChannelAdmin.hrl").
@@ -945,14 +944,19 @@ check_limits(LQS, NPR) ->
%% supported.
%%------------------------------------------------------------
validate_event_qos(Wanted, Curr) ->
- v_e_q_helper(Wanted, Curr, []),
- [].
+ case v_e_q_helper(Wanted, Curr, []) of
+ ok ->
+ [];
+ {error, Unsupp} ->
+ corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupp})
+ end.
+
v_e_q_helper([], _Curr, []) ->
- %% Parsed all and foynd no conflicts.
+ %% Parsed all and found no conflicts.
ok;
v_e_q_helper([], _Curr, Unsupp) ->
%% Not possible to use these requested QoS.
- corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupp});
+ {error, Unsupp};
%%--- EventReliability ---%%
v_e_q_helper([#'CosNotification_Property'{name=?not_EventReliability,
@@ -1071,30 +1075,38 @@ v_e_q_helper(What, _, _) ->
%% LQS - local representation of QoS.
%% Returns : {NewOMGStyleQoS, NewLocalQoS} | #'CosNotification_UnsupportedQoS'{}
%%------------------------------------------------------------
-set_properties([], Curr, channelAdm, _, [], NewQoS,_,_,LAS) ->
+set_properties(Wanted, Current, Type, Supported, Unsupp, NewQoS, Parent, Childs, LQS) ->
+ case do_set_properties(Wanted, Current, Type, Supported, Unsupp, NewQoS, Parent, Childs, LQS) of
+ {error, Exc} ->
+ corba:raise(Exc);
+ Result ->
+ Result
+ end.
+
+do_set_properties([], Curr, channelAdm, _, [], NewQoS,_,_,LAS) ->
merge_properties(NewQoS, Curr, LAS);
-set_properties([], Curr, _, _, [], NewQoS,_,_,LQS) ->
+do_set_properties([], Curr, _, _, [], NewQoS,_,_,LQS) ->
%% set_local_qos and merge_properties are help functions found at the end of QoS
%% functions.
NewLQS = set_local_qos(NewQoS, LQS),
merge_properties(NewQoS, Curr, NewLQS);
-set_properties([], _, channelAdm, _, Unsupp, _,_,_,_) ->
- corba:raise(#'CosNotification_UnsupportedAdmin'{admin_err = Unsupp});
-set_properties([], _, _, _, Unsupp, _,_,_,_) ->
- corba:raise(#'CosNotification_UnsupportedQoS'{qos_err = Unsupp});
+do_set_properties([], _, channelAdm, _, Unsupp, _,_,_,_) ->
+ {error, #'CosNotification_UnsupportedAdmin'{admin_err = Unsupp}};
+do_set_properties([], _, _, _, Unsupp, _,_,_,_) ->
+ {error, #'CosNotification_UnsupportedQoS'{qos_err = Unsupp}};
-set_properties([Req|Tail], Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS) ->
+do_set_properties([Req|Tail], Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS) ->
%% set_values and is_supported are help functions found at the end of QoS
%% functions.
case set_values(is_supported(Supported, Req), Req, Type, Curr, Parent, Childs,LQS) of
{unsupported, U} ->
- set_properties(Tail, Curr, Type, Supported, [U|Unsupp], NewQoS, Parent, Childs,LQS);
+ do_set_properties(Tail, Curr, Type, Supported, [U|Unsupp], NewQoS, Parent, Childs,LQS);
{ok, S, NewLQS} ->
- set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,NewLQS);
+ do_set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,NewLQS);
{ok, S} ->
- set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,LQS);
+ do_set_properties(Tail, Curr, Type, Supported, Unsupp, [S|NewQoS], Parent, Childs,LQS);
ok ->
- set_properties(Tail, Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS)
+ do_set_properties(Tail, Curr, Type, Supported, Unsupp, NewQoS, Parent, Childs,LQS)
end.
diff --git a/lib/cosNotification/src/cosNotification_Filter.erl b/lib/cosNotification/src/cosNotification_Filter.erl
index dd3b5beb93..7201f7d6e2 100644
--- a/lib/cosNotification/src/cosNotification_Filter.erl
+++ b/lib/cosNotification/src/cosNotification_Filter.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -877,9 +877,9 @@ check_wildcard(Types, Which, WC, Domain, Type) ->
end,
check_types(Types, Which, NewWC).
-%% Change '*' to '.*', see regexp:parse/2 documentation.
+%% Change '*' to '.*', see re:compile/1 documentation.
convert_wildcard([], Acc) ->
- case regexp:parse(lists:reverse(Acc)) of
+ case re:compile(lists:reverse(Acc)) of
{ok, Expr} ->
Expr;
_ ->
@@ -900,37 +900,37 @@ match_types(_, _, []) ->
false;
match_types(Domain, Type, [{domain, WCDomain, Type}|T]) ->
L=length(Domain),
- case catch regexp:matches(Domain, WCDomain) of
- {match, []} ->
+ case catch re:run(Domain, WCDomain) of
+ nomatch ->
match_types(Domain, Type, T);
- {match, [{1, L}]} ->
+ {match, [{0, L}]} ->
true;
_->
match_types(Domain, Type, T)
end;
match_types(Domain, Type, [{type, Domain, WCType}|T]) ->
L=length(Type),
- case catch regexp:matches(Type, WCType) of
- {match, []} ->
+ case catch re:run(Type, WCType) of
+ nomatch ->
match_types(Domain, Type, T);
- {match, [{1, L}]} ->
+ {match, [{0, L}]} ->
true;
_->
match_types(Domain, Type, T)
end;
match_types(Domain, Type, [{both, WCDomain, WCType}|T]) ->
L1=length(Domain),
- case catch regexp:matches(Domain, WCDomain) of
- {match, []} ->
+ case catch re:run(Domain, WCDomain) of
+ nomatch ->
match_types(Domain, Type, T);
- {match, [{1, L1}]} ->
+ {match, [{0, L1}]} ->
L2=length(Type),
- case catch regexp:matches(Type, WCType) of
- {match, []} ->
+ case catch re:run(Type, WCType) of
+ nomatch ->
match_types(Domain, Type, T);
- {match, [{1, L2}]} ->
+ {match, [{0, L2}]} ->
true;
- _->
+ _ ->
match_types(Domain, Type, T)
end;
_->
diff --git a/lib/cosNotification/test/Makefile b/lib/cosNotification/test/Makefile
index df8f9e919b..d29c9c3245 100644
--- a/lib/cosNotification/test/Makefile
+++ b/lib/cosNotification/test/Makefile
@@ -34,6 +34,7 @@ RELSYSDIR = $(RELEASE_PATH)/cosNotification_test
# Target Specs
# ----------------------------------------------------
TEST_SPEC_FILE = cosNotification.spec
+COVER_FILE = cosNotification.cover
IDL_FILES =
@@ -182,7 +183,7 @@ release_docs_spec:
release_tests_spec: tests
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
- $(ERL_FILES) $(RELSYSDIR)
+ $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR)
$(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
$(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
$(RELSYSDIR)/$(IDLOUTDIR)
diff --git a/lib/cosNotification/test/cosNotification.cover b/lib/cosNotification/test/cosNotification.cover
new file mode 100644
index 0000000000..604f313521
--- /dev/null
+++ b/lib/cosNotification/test/cosNotification.cover
@@ -0,0 +1,2 @@
+{incl_app,cosNotification,details}.
+
diff --git a/lib/cosNotification/test/cosNotification.spec b/lib/cosNotification/test/cosNotification.spec
index 8df89e7908..8ec1baca33 100644
--- a/lib/cosNotification/test/cosNotification.spec
+++ b/lib/cosNotification/test/cosNotification.spec
@@ -1,19 +1 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-{topcase, {dir, "../cosNotification_test"}}.
+{suites,"../cosNotification_test",all}.
diff --git a/lib/cosNotification/test/eventDB_SUITE.erl b/lib/cosNotification/test/eventDB_SUITE.erl
index 9ddfb3d902..ee521d4111 100644
--- a/lib/cosNotification/test/eventDB_SUITE.erl
+++ b/lib/cosNotification/test/eventDB_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %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
@@ -41,7 +41,7 @@
-include("idl_output/notify_test.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%%--------------- DEFINES ------------------------------------
-define(default_timeout, ?t:minutes(20)).
@@ -259,25 +259,37 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1, reorder_api/1, lookup_api/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ cases/0, init_per_suite/1, end_per_suite/1, reorder_api/1,
+ lookup_api/1,
discard_api/1, max_events_api/1, gc_api/1, auto_gc_api/1,
start_stop_time_api/1, mapping_filter_api/1, persisten_event_api/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
%%-----------------------------------------------------------------
%% Func: all/1
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for the cosNotification interfaces", ""];
-all(suite) -> {req,
- [mnesia, orber],
- {conf, init_all, cases(), finish_all}}.
-
-cases() ->
- [persisten_event_api, start_stop_time_api, mapping_filter_api,
- max_events_api, discard_api, reorder_api, lookup_api, gc_api,
- auto_gc_api].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [persisten_event_api, start_stop_time_api,
+ mapping_filter_api, max_events_api, discard_api,
+ reorder_api, lookup_api, gc_api, auto_gc_api].
@@ -290,12 +302,12 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
Path = code:which(?MODULE),
code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
orber:jump_start(),
@@ -308,7 +320,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
cosTime:stop(),
diff --git a/lib/cosNotification/test/generated_SUITE.erl b/lib/cosNotification/test/generated_SUITE.erl
index 34b84041f0..20abfde018 100644
--- a/lib/cosNotification/test/generated_SUITE.erl
+++ b/lib/cosNotification/test/generated_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
-module(generated_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -71,12 +71,12 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -84,52 +84,110 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["This suite is for testing IC generated files"];
-all(suite) ->
- ['CosNotification', 'CosNotification_AdminPropertiesAdmin',
- 'CosNotification_EventHeader', 'CosNotification_EventType',
- 'CosNotification_FixedEventHeader', 'CosNotification_NamedPropertyRange',
- 'CosNotification_Property', 'CosNotification_PropertyError',
- 'CosNotification_PropertyRange', 'CosNotification_QoSAdmin',
- 'CosNotification_StructuredEvent', 'CosNotification_UnsupportedAdmin',
- 'CosNotification_UnsupportedQoS', 'CosNotification_EventBatch',
- 'CosNotification_EventTypeSeq', 'CosNotification_NamedPropertyRangeSeq',
- 'CosNotification_PropertyErrorSeq', 'CosNotifyChannelAdmin_AdminLimit',
- 'CosNotifyChannelAdmin_AdminNotFound', 'CosNotifyChannelAdmin_ChannelNotFound',
- 'CosNotifyChannelAdmin_ConnectionAlreadyActive', 'CosNotifyChannelAdmin_ConnectionAlreadyInactive',
- 'CosNotifyChannelAdmin_NotConnected', 'CosNotifyChannelAdmin_AdminIDSeq',
- 'CosNotifyChannelAdmin_ChannelIDSeq', 'CosNotifyChannelAdmin_ProxyIDSeq',
- 'CosNotifyFilter_CallbackNotFound', 'CosNotifyFilter_ConstraintExp',
- 'CosNotifyFilter_ConstraintInfo', 'CosNotifyFilter_ConstraintNotFound',
- 'CosNotifyFilter_DuplicateConstraintID', 'CosNotifyFilter_FilterNotFound',
- 'CosNotifyFilter_InvalidConstraint', 'CosNotifyFilter_InvalidGrammar',
- 'CosNotifyFilter_InvalidValue', 'CosNotifyFilter_MappingConstraintInfo',
- 'CosNotifyFilter_MappingConstraintPair', 'CosNotifyFilter_UnsupportedFilterableData',
- 'CosNotifyFilter_CallbackIDSeq', 'CosNotifyFilter_ConstraintExpSeq',
- 'CosNotifyFilter_ConstraintIDSeq', 'CosNotifyFilter_ConstraintInfoSeq',
- 'CosNotifyFilter_FilterIDSeq', 'CosNotifyFilter_MappingConstraintInfoSeq',
- 'CosNotifyFilter_MappingConstraintPairSeq', 'CosNotifyComm_InvalidEventType',
- 'CosNotifyChannelAdmin_ConsumerAdmin', 'CosNotifyChannelAdmin_EventChannel',
- 'CosNotifyChannelAdmin_EventChannelFactory', 'CosNotifyChannelAdmin_ProxyConsumer',
- 'CosNotifyChannelAdmin_ProxyNotFound', 'CosNotifyChannelAdmin_ProxyPullConsumer',
- 'CosNotifyChannelAdmin_ProxyPullSupplier', 'CosNotifyChannelAdmin_ProxyPushConsumer',
- 'CosNotifyChannelAdmin_ProxyPushSupplier', 'CosNotifyChannelAdmin_ProxySupplier',
- 'CosNotifyChannelAdmin_SequenceProxyPullConsumer', 'CosNotifyChannelAdmin_SequenceProxyPullSupplier',
- 'CosNotifyChannelAdmin_SequenceProxyPushConsumer', 'CosNotifyChannelAdmin_SequenceProxyPushSupplier',
- 'CosNotifyChannelAdmin_StructuredProxyPullConsumer', 'CosNotifyChannelAdmin_StructuredProxyPullSupplier',
- 'CosNotifyChannelAdmin_StructuredProxyPushConsumer', 'CosNotifyChannelAdmin_StructuredProxyPushSupplier',
- 'CosNotifyChannelAdmin_SupplierAdmin', 'CosNotifyFilter_Filter',
- 'CosNotifyFilter_FilterAdmin', 'CosNotifyFilter_FilterFactory',
- 'CosNotifyFilter_MappingFilter', 'CosNotifyComm_NotifyPublish',
- 'CosNotifyComm_NotifySubscribe', 'CosNotifyComm_PullConsumer',
- 'CosNotifyComm_PullSupplier', 'CosNotifyComm_PushConsumer',
- 'CosNotifyComm_PushSupplier', 'CosNotifyComm_SequencePullConsumer',
- 'CosNotifyComm_SequencePullSupplier', 'CosNotifyComm_SequencePushConsumer',
- 'CosNotifyComm_SequencePushSupplier', 'CosNotifyComm_StructuredPullConsumer',
- 'CosNotifyComm_StructuredPullSupplier', 'CosNotifyComm_StructuredPushConsumer',
- 'CosNotifyComm_StructuredPushSupplier', 'oe_CosNotificationComm_Event',
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ ['CosNotification',
+ 'CosNotification_AdminPropertiesAdmin',
+ 'CosNotification_EventHeader',
+ 'CosNotification_EventType',
+ 'CosNotification_FixedEventHeader',
+ 'CosNotification_NamedPropertyRange',
+ 'CosNotification_Property',
+ 'CosNotification_PropertyError',
+ 'CosNotification_PropertyRange',
+ 'CosNotification_QoSAdmin',
+ 'CosNotification_StructuredEvent',
+ 'CosNotification_UnsupportedAdmin',
+ 'CosNotification_UnsupportedQoS',
+ 'CosNotification_EventBatch',
+ 'CosNotification_EventTypeSeq',
+ 'CosNotification_NamedPropertyRangeSeq',
+ 'CosNotification_PropertyErrorSeq',
+ 'CosNotifyChannelAdmin_AdminLimit',
+ 'CosNotifyChannelAdmin_AdminNotFound',
+ 'CosNotifyChannelAdmin_ChannelNotFound',
+ 'CosNotifyChannelAdmin_ConnectionAlreadyActive',
+ 'CosNotifyChannelAdmin_ConnectionAlreadyInactive',
+ 'CosNotifyChannelAdmin_NotConnected',
+ 'CosNotifyChannelAdmin_AdminIDSeq',
+ 'CosNotifyChannelAdmin_ChannelIDSeq',
+ 'CosNotifyChannelAdmin_ProxyIDSeq',
+ 'CosNotifyFilter_CallbackNotFound',
+ 'CosNotifyFilter_ConstraintExp',
+ 'CosNotifyFilter_ConstraintInfo',
+ 'CosNotifyFilter_ConstraintNotFound',
+ 'CosNotifyFilter_DuplicateConstraintID',
+ 'CosNotifyFilter_FilterNotFound',
+ 'CosNotifyFilter_InvalidConstraint',
+ 'CosNotifyFilter_InvalidGrammar',
+ 'CosNotifyFilter_InvalidValue',
+ 'CosNotifyFilter_MappingConstraintInfo',
+ 'CosNotifyFilter_MappingConstraintPair',
+ 'CosNotifyFilter_UnsupportedFilterableData',
+ 'CosNotifyFilter_CallbackIDSeq',
+ 'CosNotifyFilter_ConstraintExpSeq',
+ 'CosNotifyFilter_ConstraintIDSeq',
+ 'CosNotifyFilter_ConstraintInfoSeq',
+ 'CosNotifyFilter_FilterIDSeq',
+ 'CosNotifyFilter_MappingConstraintInfoSeq',
+ 'CosNotifyFilter_MappingConstraintPairSeq',
+ 'CosNotifyComm_InvalidEventType',
+ 'CosNotifyChannelAdmin_ConsumerAdmin',
+ 'CosNotifyChannelAdmin_EventChannel',
+ 'CosNotifyChannelAdmin_EventChannelFactory',
+ 'CosNotifyChannelAdmin_ProxyConsumer',
+ 'CosNotifyChannelAdmin_ProxyNotFound',
+ 'CosNotifyChannelAdmin_ProxyPullConsumer',
+ 'CosNotifyChannelAdmin_ProxyPullSupplier',
+ 'CosNotifyChannelAdmin_ProxyPushConsumer',
+ 'CosNotifyChannelAdmin_ProxyPushSupplier',
+ 'CosNotifyChannelAdmin_ProxySupplier',
+ 'CosNotifyChannelAdmin_SequenceProxyPullConsumer',
+ 'CosNotifyChannelAdmin_SequenceProxyPullSupplier',
+ 'CosNotifyChannelAdmin_SequenceProxyPushConsumer',
+ 'CosNotifyChannelAdmin_SequenceProxyPushSupplier',
+ 'CosNotifyChannelAdmin_StructuredProxyPullConsumer',
+ 'CosNotifyChannelAdmin_StructuredProxyPullSupplier',
+ 'CosNotifyChannelAdmin_StructuredProxyPushConsumer',
+ 'CosNotifyChannelAdmin_StructuredProxyPushSupplier',
+ 'CosNotifyChannelAdmin_SupplierAdmin',
+ 'CosNotifyFilter_Filter', 'CosNotifyFilter_FilterAdmin',
+ 'CosNotifyFilter_FilterFactory',
+ 'CosNotifyFilter_MappingFilter',
+ 'CosNotifyComm_NotifyPublish',
+ 'CosNotifyComm_NotifySubscribe',
+ 'CosNotifyComm_PullConsumer',
+ 'CosNotifyComm_PullSupplier',
+ 'CosNotifyComm_PushConsumer',
+ 'CosNotifyComm_PushSupplier',
+ 'CosNotifyComm_SequencePullConsumer',
+ 'CosNotifyComm_SequencePullSupplier',
+ 'CosNotifyComm_SequencePushConsumer',
+ 'CosNotifyComm_SequencePushSupplier',
+ 'CosNotifyComm_StructuredPullConsumer',
+ 'CosNotifyComm_StructuredPullSupplier',
+ 'CosNotifyComm_StructuredPushConsumer',
+ 'CosNotifyComm_StructuredPushSupplier',
+ oe_CosNotificationComm_Event,
'CosNotification_PropertySeq'].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -138,7 +196,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/cosNotification/test/grammar_SUITE.erl b/lib/cosNotification/test/grammar_SUITE.erl
index 30aec89e5f..6dbd353dbe 100644
--- a/lib/cosNotification/test/grammar_SUITE.erl
+++ b/lib/cosNotification/test/grammar_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %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
@@ -42,7 +42,7 @@
-include("idl_output/notify_test.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%%--------------- DEFINES ------------------------------------
-define(default_timeout, ?t:minutes(20)).
@@ -64,10 +64,11 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ cases/0, init_per_suite/1, end_per_suite/1,
union_api/1, enum_api/1, simple_types_api/1,
components_api/1, positional_api/1, variable_api/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
-import(cosNotification_Filter, [create_filter/1, eval/2]).
@@ -76,15 +77,25 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for the cosNotification interfaces", ""];
-all(suite) -> {req,
- [],
- {conf, init_all, cases(), finish_all}}.
-
-cases() ->
- [variable_api, union_api, enum_api, simple_types_api, components_api,
- positional_api].
-
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [variable_api, union_api, enum_api, simple_types_api,
+ components_api, positional_api].
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -96,14 +107,14 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
Path = code:which(?MODULE),
code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
if
@@ -113,7 +124,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
Config.
diff --git a/lib/cosNotification/test/notification_SUITE.erl b/lib/cosNotification/test/notification_SUITE.erl
index e2c560e4de..99a3f62bc2 100644
--- a/lib/cosNotification/test/notification_SUITE.erl
+++ b/lib/cosNotification/test/notification_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -40,7 +40,7 @@
-include("idl_output/notify_test.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%%--------------- DEFINES ------------------------------------
-define(default_timeout, ?t:minutes(20)).
@@ -123,10 +123,11 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1, qos_api/1, adm_api/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1, qos_api/1, adm_api/1,
cosevent_api/1, filter_adm_api/1, events_api/1, events2_api/1,
event_qos_api/1, filter_api/1, mapping_filter_api/1, subscription_api/1,
- init_per_testcase/2, fin_per_testcase/2, persistent_max_events_api/1,
+ init_per_testcase/2, end_per_testcase/2, persistent_max_events_api/1,
persistent_timeout_events_api/1, persistent_recover_events_api/1,
app_test/1]).
@@ -137,19 +138,28 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for the cosNotification interfaces", ""];
-all(suite) -> {req,
- [mnesia, orber],
- {conf, init_all, cases(), finish_all}}.
-
-cases() ->
- [persistent_max_events_api, persistent_timeout_events_api,
- persistent_recover_events_api, mapping_filter_api, filter_api, filter_adm_api,
- event_qos_api, qos_api, adm_api, cosevent_api, subscription_api,
- events_api, events2_api, app_test].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+cases() ->
+ [persistent_max_events_api,
+ persistent_timeout_events_api,
+ persistent_recover_events_api, mapping_filter_api,
+ filter_api, filter_adm_api, event_qos_api, qos_api,
+ adm_api, cosevent_api, subscription_api, events_api,
+ events2_api, app_test].
-
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -161,14 +171,14 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
Path = code:which(?MODULE),
code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
ok = corba:orb_init([{flags, 16#02}, {orber_debug_level, 10}]),
@@ -184,7 +194,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
cosNotificationApp:stop(),
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
diff --git a/lib/cosNotification/test/notify_test_impl.erl b/lib/cosNotification/test/notify_test_impl.erl
index 483610befd..dae7777089 100644
--- a/lib/cosNotification/test/notify_test_impl.erl
+++ b/lib/cosNotification/test/notify_test_impl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/cosNotification/vsn.mk b/lib/cosNotification/vsn.mk
index c03f0ef161..6613385579 100644
--- a/lib/cosNotification/vsn.mk
+++ b/lib/cosNotification/vsn.mk
@@ -1 +1,2 @@
-COSNOTIFICATION_VSN = 1.1.14
+COSNOTIFICATION_VSN = 1.1.16
+
diff --git a/lib/cosProperty/doc/src/notes.xml b/lib/cosProperty/doc/src/notes.xml
index 11e6205ee9..d7d52514ce 100644
--- a/lib/cosProperty/doc/src/notes.xml
+++ b/lib/cosProperty/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2010</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -54,6 +54,34 @@
<title>Fixed Bugs and Malfunctions</title>
<list type="bulleted">
<item>
+ <p>Eliminated Dialyzer warnings when using exit or throw.</p>
+ <p>Own id: OTP-9050 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosProperty 1.1.12</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Test suites published.</p>
+ <p>Own id: OTP-8543 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>cosProperty 1.1.11</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
<p>The documentation EIX file was not generated.</p>
<p>Own id: OTP-8355 Aux Id:</p>
</item>
diff --git a/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl
index b099026b88..202df42b61 100644
--- a/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl
+++ b/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -152,12 +152,18 @@ create_initial_propertysetdef(_OE_This, State, PropDefs) ->
%% Internal functions
%%======================================================================
evaluate_propertysetdef(SetDefs) ->
- evaluate_propertysetdef(SetDefs, [], []).
+ case evaluate_propertysetdef(SetDefs, [], []) of
+ {ok, NewProperties} ->
+ NewProperties;
+ {error, Exc} ->
+ corba:raise(#'CosPropertyService_MultipleExceptions'{exceptions = Exc})
+ end.
+
evaluate_propertysetdef([], NewProperties, []) ->
%% No exceptions found.
- NewProperties;
+ {ok, NewProperties};
evaluate_propertysetdef([], _, Exc) ->
- corba:raise(#'CosPropertyService_MultipleExceptions'{exceptions = Exc});
+ {error, Exc};
evaluate_propertysetdef([#'CosPropertyService_PropertyDef'
{property_name = Name,
property_value = Value,
diff --git a/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl
index ad3cdb62d4..4bc29b99ac 100644
--- a/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl
+++ b/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -153,12 +153,18 @@ create_initial_propertyset(_OE_This, State, Properties) ->
%% Internal functions
%%======================================================================
evaluate_propertyset(Sets) ->
- evaluate_propertyset(Sets, [], []).
+ case evaluate_propertyset(Sets, [], []) of
+ {ok, NewProperties} ->
+ NewProperties;
+ {error, Exc} ->
+ corba:raise(#'CosPropertyService_MultipleExceptions'{exceptions = Exc})
+ end.
+
evaluate_propertyset([], NewProperties, []) ->
%% No exceptions found.
- NewProperties;
+ {ok, NewProperties};
evaluate_propertyset([], _, Exc) ->
- corba:raise(#'CosPropertyService_MultipleExceptions'{exceptions = Exc});
+ {error, Exc};
evaluate_propertyset([#'CosPropertyService_Property'
{property_name = Name,
property_value = Value}|T], X, Exc) ->
diff --git a/lib/cosProperty/test/Makefile b/lib/cosProperty/test/Makefile
index ac0f4e298d..d4ae5cad3d 100644
--- a/lib/cosProperty/test/Makefile
+++ b/lib/cosProperty/test/Makefile
@@ -34,6 +34,7 @@ RELSYSDIR = $(RELEASE_PATH)/cosProperty_test
# Target Specs
# ----------------------------------------------------
TEST_SPEC_FILE = cosProperty.spec
+COVER_FILE = cosProperty.cover
IDL_FILES =
@@ -121,7 +122,7 @@ release_docs_spec:
release_tests_spec: tests
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
- $(ERL_FILES) $(RELSYSDIR)
+ $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
# $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
# $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
diff --git a/lib/cosProperty/test/cosProperty.cover b/lib/cosProperty/test/cosProperty.cover
new file mode 100644
index 0000000000..a0f5f17671
--- /dev/null
+++ b/lib/cosProperty/test/cosProperty.cover
@@ -0,0 +1,2 @@
+{incl_app,cosProperty,details}.
+
diff --git a/lib/cosProperty/test/cosProperty.spec b/lib/cosProperty/test/cosProperty.spec
index d3e0001eef..d3d44321c8 100644
--- a/lib/cosProperty/test/cosProperty.spec
+++ b/lib/cosProperty/test/cosProperty.spec
@@ -1,20 +1 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-{topcase, {dir, "../cosProperty_test"}}.
-
+{suites,"../cosProperty_test",all}.
diff --git a/lib/cosProperty/test/generated_SUITE.erl b/lib/cosProperty/test/generated_SUITE.erl
index 80a7953949..63c0c0dd6a 100644
--- a/lib/cosProperty/test/generated_SUITE.erl
+++ b/lib/cosProperty/test/generated_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
-module(generated_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -71,12 +71,12 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -84,21 +84,51 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["This suite is for testing IC generated files"];
-all(suite) ->
- ['CosPropertyService_ConflictingProperty', 'CosPropertyService_ConstraintNotSupported',
- 'CosPropertyService_FixedProperty', 'CosPropertyService_InvalidPropertyName',
- 'CosPropertyService_MultipleExceptions', 'CosPropertyService_Properties',
- 'CosPropertyService_Property', 'CosPropertyService_PropertyDef',
- 'CosPropertyService_PropertyDefs', 'CosPropertyService_PropertyException',
- 'CosPropertyService_PropertyExceptions', 'CosPropertyService_PropertyMode',
- 'CosPropertyService_PropertyModes', 'CosPropertyService_PropertyNames',
- 'CosPropertyService_PropertyNotFound', 'CosPropertyService_PropertyTypes',
- 'CosPropertyService_ReadOnlyProperty', 'CosPropertyService_UnsupportedMode',
- 'CosPropertyService_UnsupportedProperty', 'CosPropertyService_UnsupportedTypeCode',
- 'CosPropertyService_PropertyNamesIterator', 'CosPropertyService_PropertiesIterator',
- 'CosPropertyService_PropertySet', 'CosPropertyService_PropertySetDef',
- 'CosPropertyService_PropertySetDefFactory', 'CosPropertyService_PropertySetFactory'].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ ['CosPropertyService_ConflictingProperty',
+ 'CosPropertyService_ConstraintNotSupported',
+ 'CosPropertyService_FixedProperty',
+ 'CosPropertyService_InvalidPropertyName',
+ 'CosPropertyService_MultipleExceptions',
+ 'CosPropertyService_Properties',
+ 'CosPropertyService_Property',
+ 'CosPropertyService_PropertyDef',
+ 'CosPropertyService_PropertyDefs',
+ 'CosPropertyService_PropertyException',
+ 'CosPropertyService_PropertyExceptions',
+ 'CosPropertyService_PropertyMode',
+ 'CosPropertyService_PropertyModes',
+ 'CosPropertyService_PropertyNames',
+ 'CosPropertyService_PropertyNotFound',
+ 'CosPropertyService_PropertyTypes',
+ 'CosPropertyService_ReadOnlyProperty',
+ 'CosPropertyService_UnsupportedMode',
+ 'CosPropertyService_UnsupportedProperty',
+ 'CosPropertyService_UnsupportedTypeCode',
+ 'CosPropertyService_PropertyNamesIterator',
+ 'CosPropertyService_PropertiesIterator',
+ 'CosPropertyService_PropertySet',
+ 'CosPropertyService_PropertySetDef',
+ 'CosPropertyService_PropertySetDefFactory',
+ 'CosPropertyService_PropertySetFactory'].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%-----------------------------------------------------------------
@@ -109,7 +139,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/cosProperty/test/property_SUITE.erl b/lib/cosProperty/test/property_SUITE.erl
index 8fed3128ef..df6b56113e 100644
--- a/lib/cosProperty/test/property_SUITE.erl
+++ b/lib/cosProperty/test/property_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %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
@@ -32,7 +32,7 @@
-include_lib("cosProperty/src/cosProperty.hrl").
-include_lib("cosProperty/include/CosPropertyService.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%%--------------- DEFINES ------------------------------------
-define(default_timeout, ?t:minutes(20)).
@@ -86,8 +86,9 @@
%% External exports
%%-----------------------------------------------------------------
%% Fixed exports
--export([all/1, cases/0, init_all/1, finish_all/1,
- init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
%% Test cases
-export([create_setdef_api/1, create_set_api/1, define_with_mode_api/1,
define_api/1, names_iterator_api/1, properties_iterator_api/1,
@@ -98,16 +99,24 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for the cosProperty interfaces", ""];
-all(suite) -> {req,
- [mnesia, orber],
- {conf, init_all, cases(), finish_all}}.
-
-cases() ->
- [create_setdef_api, create_set_api, define_with_mode_api, define_api,
- names_iterator_api, properties_iterator_api, app_test].
-
-
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+cases() ->
+ [create_setdef_api, create_set_api,
+ define_with_mode_api, define_api, names_iterator_api,
+ properties_iterator_api, app_test].
%%-----------------------------------------------------------------
%% Init and cleanup functions.
@@ -120,14 +129,14 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
Path = code:which(?MODULE),
code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
orber:jump_start(),
@@ -141,7 +150,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
application:stop(cosProperty),
diff --git a/lib/cosProperty/vsn.mk b/lib/cosProperty/vsn.mk
index ca9a7ca77e..deb1eb0450 100644
--- a/lib/cosProperty/vsn.mk
+++ b/lib/cosProperty/vsn.mk
@@ -1 +1,2 @@
-COSPROPERTY_VSN = 1.1.12
+COSPROPERTY_VSN = 1.1.13
+
diff --git a/lib/cosTime/doc/src/notes.xml b/lib/cosTime/doc/src/notes.xml
index 40ebf42753..718ca23bc5 100644
--- a/lib/cosTime/doc/src/notes.xml
+++ b/lib/cosTime/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2010</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -33,6 +33,22 @@
</header>
<section>
+ <title>cosTime 1.1.10</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Eliminated Dialyzer warnings when using exit or throw.</p>
+ <p>
+ Own Id: OTP-9050 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosTime 1.1.9</title>
<section>
diff --git a/lib/cosTime/src/cosTime.erl b/lib/cosTime/src/cosTime.erl
index f4e67570ad..f7d03650af 100644
--- a/lib/cosTime/src/cosTime.erl
+++ b/lib/cosTime/src/cosTime.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -71,29 +71,39 @@
%%------------------------------------------------------------
install_time() ->
- install_loop(?IDL_TIME_MODULES,[]).
+ case install_loop(?IDL_TIME_MODULES,[]) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ exit(Reason)
+ end.
install_timerevent() ->
- install_loop(?IDL_TIMEREVENT_MODULES,[]).
+ case install_loop(?IDL_TIMEREVENT_MODULES,[]) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ exit(Reason)
+ end.
install_loop([], _) ->
ok;
install_loop([H|T], Accum) ->
case catch H:'oe_register'() of
{'EXIT',{unregistered,App}} ->
- ?write_ErrorMsg("Unable to register '~p'; application ~p not registered.
-Trying to unregister ~p~n", [H,App,Accum]),
+ ?write_ErrorMsg("Unable to register '~p'; application ~p not registered.\n"
+ "Trying to unregister ~p\n", [H,App,Accum]),
uninstall_loop(Accum, {exit, register});
{'EXCEPTION',_} ->
- ?write_ErrorMsg("Unable to register '~p'; propably already registered.
-You are adviced to confirm this.
-Trying to unregister ~p~n", [H,Accum]),
+ ?write_ErrorMsg("Unable to register '~p'; propably already registered.\n"
+ "You are adviced to confirm this.\n"
+ "Trying to unregister ~p\n", [H,Accum]),
uninstall_loop(Accum, {exit, register});
ok ->
install_loop(T, [H|Accum]);
_ ->
- ?write_ErrorMsg("Unable to register '~p'; reason unknown.
-Trying to unregister ~p~n", [H,Accum]),
+ ?write_ErrorMsg("Unable to register '~p'; reason unknown.\n"
+ "Trying to unregister ~p\n", [H,Accum]),
uninstall_loop(Accum, {exit, register})
end.
@@ -105,33 +115,43 @@ Trying to unregister ~p~n", [H,Accum]),
%%------------------------------------------------------------
uninstall_time() ->
- uninstall_loop(lists:reverse(?IDL_TIME_MODULES),ok).
+ case uninstall_loop(lists:reverse(?IDL_TIME_MODULES),ok) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ exit(Reason)
+ end.
uninstall_timerevent() ->
- uninstall_loop(lists:reverse(?IDL_TIMEREVENT_MODULES),ok).
+ case uninstall_loop(lists:reverse(?IDL_TIMEREVENT_MODULES),ok) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ exit(Reason)
+ end.
uninstall_loop([],ok) ->
ok;
uninstall_loop([],{exit, register}) ->
- exit({?MODULE, "oe_register failed"});
+ {error, {?MODULE, "oe_register failed"}};
uninstall_loop([],{exit, unregister}) ->
- exit({?MODULE, "oe_unregister failed"});
+ {error, {?MODULE, "oe_unregister failed"}};
uninstall_loop([],{exit, both}) ->
- exit({?MODULE, "oe_register and, for some of those already registered, oe_unregister failed"});
+ {error, {?MODULE, "oe_register and, for some of those already registered, oe_unregister failed"}};
uninstall_loop([H|T], Status) ->
case catch H:'oe_unregister'() of
ok ->
uninstall_loop(T, Status);
_ when Status == ok ->
- ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.
-You are adviced to confirm this.~n",[H]),
+ ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.\n"
+ "You are adviced to confirm this.~n",[H]),
uninstall_loop(T, {exit, unregister});
_ ->
- ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.
-You are adviced to confirm this.~n",[H]),
+ ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.\n"
+ "You are adviced to confirm this.~n",[H]),
uninstall_loop(T, {exit, both})
end.
-
+
%%------------------------------------------------------------
%% function : start/stop
%% Arguments:
diff --git a/lib/cosTime/test/Makefile b/lib/cosTime/test/Makefile
index fde5c4facc..96f469afcd 100644
--- a/lib/cosTime/test/Makefile
+++ b/lib/cosTime/test/Makefile
@@ -34,6 +34,7 @@ RELSYSDIR = $(RELEASE_PATH)/cosTime_test
# Target Specs
# ----------------------------------------------------
TEST_SPEC_FILE = cosTime.spec
+COVER_FILE = cosTime.cover
IDL_FILES =
@@ -127,7 +128,7 @@ release_docs_spec:
release_tests_spec: tests
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
- $(ERL_FILES) $(RELSYSDIR)
+ $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
# $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
# $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
diff --git a/lib/cosTime/test/cosTime.cover b/lib/cosTime/test/cosTime.cover
new file mode 100644
index 0000000000..81a05b8cfd
--- /dev/null
+++ b/lib/cosTime/test/cosTime.cover
@@ -0,0 +1,2 @@
+{incl_app,cosTime,details}.
+
diff --git a/lib/cosTime/test/cosTime.spec b/lib/cosTime/test/cosTime.spec
index 3f50946043..8bf6f740fe 100644
--- a/lib/cosTime/test/cosTime.spec
+++ b/lib/cosTime/test/cosTime.spec
@@ -1,19 +1 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-{topcase, {dir, "../cosTime_test"}}.
+{suites,"../cosTime_test",all}.
diff --git a/lib/cosTime/test/generated_SUITE.erl b/lib/cosTime/test/generated_SUITE.erl
index 3a2153528f..465d02288f 100644
--- a/lib/cosTime/test/generated_SUITE.erl
+++ b/lib/cosTime/test/generated_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
-module(generated_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -71,12 +71,12 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -84,13 +84,31 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["This suite is for testing IC generated files"];
-all(suite) ->
- ['TimeBase_IntervalT', 'TimeBase_UtcT', 'CosTime_TimeUnavailable',
- 'CosTimerEvent_TimerEventT', 'CosTime_TIO', 'CosTime_TimeService',
- 'CosTime_UTO', 'CosTimerEvent_TimerEventHandler',
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ ['TimeBase_IntervalT', 'TimeBase_UtcT',
+ 'CosTime_TimeUnavailable', 'CosTimerEvent_TimerEventT',
+ 'CosTime_TIO', 'CosTime_TimeService', 'CosTime_UTO',
+ 'CosTimerEvent_TimerEventHandler',
'CosTimerEvent_TimerEventService'].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -99,7 +117,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/cosTime/test/time_SUITE.erl b/lib/cosTime/test/time_SUITE.erl
index bb00395885..646097a086 100644
--- a/lib/cosTime/test/time_SUITE.erl
+++ b/lib/cosTime/test/time_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %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
@@ -27,9 +27,9 @@
%%--------------- INCLUDES -----------------------------------
--include("../src/cosTimeApp.hrl").
+-include_lib("cosTime/src/cosTimeApp.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%%--------------- DEFINES ------------------------------------
-define(default_timeout, ?t:minutes(20)).
@@ -67,8 +67,9 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1, time_api/1, timerevent_api/1,
- init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1, time_api/1, timerevent_api/1,
+ init_per_testcase/2, end_per_testcase/2,
app_test/1]).
%%-----------------------------------------------------------------
@@ -76,12 +77,22 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for the cosTime interfaces", ""];
-all(suite) -> {req,
- [mnesia, orber],
- {conf, init_all, cases(), finish_all}}.
-
-cases() ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
[time_api, timerevent_api, app_test].
@@ -97,14 +108,14 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
Path = code:which(?MODULE),
code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
mnesia:delete_schema([node()]),
@@ -123,7 +134,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
cosTime:uninstall_time(),
diff --git a/lib/cosTime/vsn.mk b/lib/cosTime/vsn.mk
index 429613fb61..ebc5aff1cc 100644
--- a/lib/cosTime/vsn.mk
+++ b/lib/cosTime/vsn.mk
@@ -1 +1,2 @@
-COSTIME_VSN = 1.1.9
+COSTIME_VSN = 1.1.10
+
diff --git a/lib/cosTransactions/test/Makefile b/lib/cosTransactions/test/Makefile
index 8b1264d404..6bc532aa82 100644
--- a/lib/cosTransactions/test/Makefile
+++ b/lib/cosTransactions/test/Makefile
@@ -38,6 +38,7 @@ RELSYSDIR = $(RELEASE_PATH)/cosTransactions_test
# Target Specs
# ----------------------------------------------------
TEST_SPEC_FILE = cosTransactions.spec
+COVER_FILE = cosTransactions.cover
IDL_FILES = \
@@ -142,7 +143,7 @@ release_docs_spec:
release_tests_spec: tests
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
- $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(COVER_FILE) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
$(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR)
$(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \
diff --git a/lib/cosTransactions/test/cosTransactions.cover b/lib/cosTransactions/test/cosTransactions.cover
new file mode 100644
index 0000000000..b27bae999d
--- /dev/null
+++ b/lib/cosTransactions/test/cosTransactions.cover
@@ -0,0 +1,2 @@
+{incl_app,cosTransactions,details}.
+
diff --git a/lib/cosTransactions/test/cosTransactions.spec b/lib/cosTransactions/test/cosTransactions.spec
index 8ad9259964..9918c8ca16 100644
--- a/lib/cosTransactions/test/cosTransactions.spec
+++ b/lib/cosTransactions/test/cosTransactions.spec
@@ -1,19 +1 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-{topcase, {dir, "../cosTransactions_test"}}.
+{suites,"../cosTransactions_test",all}.
diff --git a/lib/cosTransactions/test/etrap_test_lib.erl b/lib/cosTransactions/test/etrap_test_lib.erl
index 913a94510f..18a1cda35b 100644
--- a/lib/cosTransactions/test/etrap_test_lib.erl
+++ b/lib/cosTransactions/test/etrap_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/cosTransactions/test/generated_SUITE.erl b/lib/cosTransactions/test/generated_SUITE.erl
index cc54eb168e..65a94266ab 100644
--- a/lib/cosTransactions/test/generated_SUITE.erl
+++ b/lib/cosTransactions/test/generated_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,7 +26,7 @@
-module(generated_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -72,12 +72,12 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -85,21 +85,49 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["This suite is for testing IC generated files"];
-all(suite) ->
- ['CosTransactions_Control', 'CosTransactions_Coordinator',
- 'CosTransactions_HeuristicCommit', 'CosTransactions_HeuristicHazard',
- 'CosTransactions_HeuristicMixed', 'CosTransactions_HeuristicRollback',
- 'CosTransactions_Inactive', 'CosTransactions_InvalidControl',
- 'CosTransactions_NoTransaction', 'CosTransactions_NotPrepared',
- 'CosTransactions_NotSubtransaction', 'CosTransactions_RecoveryCoordinator',
- 'CosTransactions_Resource', 'CosTransactions_SubtransactionAwareResource',
- 'CosTransactions_SubtransactionsUnavailable', 'CosTransactions_Terminator',
- 'CosTransactions_TransactionFactory', 'CosTransactions_Unavailable',
- 'CosTransactions_SynchronizationUnavailable', 'CosTransactions_TransIdentity',
- 'CosTransactions_PropagationContext', 'CosTransactions_otid_t',
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ ['CosTransactions_Control',
+ 'CosTransactions_Coordinator',
+ 'CosTransactions_HeuristicCommit',
+ 'CosTransactions_HeuristicHazard',
+ 'CosTransactions_HeuristicMixed',
+ 'CosTransactions_HeuristicRollback',
+ 'CosTransactions_Inactive',
+ 'CosTransactions_InvalidControl',
+ 'CosTransactions_NoTransaction',
+ 'CosTransactions_NotPrepared',
+ 'CosTransactions_NotSubtransaction',
+ 'CosTransactions_RecoveryCoordinator',
+ 'CosTransactions_Resource',
+ 'CosTransactions_SubtransactionAwareResource',
+ 'CosTransactions_SubtransactionsUnavailable',
+ 'CosTransactions_Terminator',
+ 'CosTransactions_TransactionFactory',
+ 'CosTransactions_Unavailable',
+ 'CosTransactions_SynchronizationUnavailable',
+ 'CosTransactions_TransIdentity',
+ 'CosTransactions_PropagationContext',
+ 'CosTransactions_otid_t',
'CosTransactions_WrongTransaction', 'ETraP_Server'].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -108,7 +136,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/cosTransactions/test/transactions_SUITE.erl b/lib/cosTransactions/test/transactions_SUITE.erl
index 8385d5a0fb..27272eeb40 100644
--- a/lib/cosTransactions/test/transactions_SUITE.erl
+++ b/lib/cosTransactions/test/transactions_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,7 +28,7 @@
-include_lib("cosTransactions/include/CosTransactions.hrl").
-include("etrap_test_lib.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(default_timeout, ?t:minutes(20)).
@@ -36,20 +36,31 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1, resource_api/1, etrap_api/1,
- init_per_testcase/2, fin_per_testcase/2, app_test/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1, resource_api/1, etrap_api/1,
+ init_per_testcase/2, end_per_testcase/2, app_test/1]).
%%-----------------------------------------------------------------
%% Func: all/1
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for the cosTransactions interfaces", ""];
-all(suite) -> {req,
- [mnesia, orber],
- {conf, init_all, cases(), finish_all}}.
-
-cases() ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
[etrap_api, resource_api, app_test].
@@ -67,7 +78,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
'oe_etrap_test':'oe_unregister'(),
'oe_CosTransactions':'oe_unregister'(),
Path = code:which(?MODULE),
@@ -76,7 +87,7 @@ fin_per_testcase(_Case, Config) ->
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
mnesia:delete_schema([node()]),
mnesia:create_schema([node()]),
orber:install([node()]),
@@ -89,7 +100,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
application:stop(orber),
application:stop(mnesia),
mnesia:delete_schema([node()]),
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 85614a84c2..0e7e63eb73 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -62,10 +62,16 @@
# define ERL_VALGRIND_MAKE_MEM_DEFINED(ptr,size) \
VALGRIND_MAKE_MEM_DEFINED(ptr,size)
- # define ERL_VALGRIND_ASSERT_MEM_DEFINED(ptr,size) \
- ((void) ((VALGRIND_CHECK_MEM_IS_DEFINED(ptr,size) == 0) ? 1 : \
- (fprintf(stderr,"\r\n####### VALGRIND_ASSSERT(%p,%ld) failed at %s:%d\r\n",\
- (ptr),(long)(size), __FILE__, __LINE__), abort(), 0)))
+ # define ERL_VALGRIND_ASSERT_MEM_DEFINED(Ptr,Size) \
+ do { \
+ int __erl_valgrind_mem_defined = VALGRIND_CHECK_MEM_IS_DEFINED((Ptr),(Size)); \
+ if (__erl_valgrind_mem_defined != 0) { \
+ fprintf(stderr,"\r\n####### VALGRIND_ASSSERT(%p,%ld) failed at %s:%d\r\n", \
+ (Ptr),(long)(Size), __FILE__, __LINE__); \
+ abort(); \
+ } \
+ } while (0)
+
#else
# define ERL_VALGRIND_MAKE_MEM_DEFINED(ptr,size)
# define ERL_VALGRIND_ASSERT_MEM_DEFINED(ptr,size)
@@ -126,6 +132,7 @@ static ERL_NIF_TERM des_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
static ERL_NIF_TERM des_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM des_ede3_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rand_bytes_3(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
@@ -194,6 +201,8 @@ static ErlNifFunc nif_funcs[] = {
{"des_ecb_crypt", 3, des_ecb_crypt},
{"des_ede3_cbc_crypt", 6, des_ede3_cbc_crypt},
{"aes_cfb_128_crypt", 4, aes_cfb_128_crypt},
+ {"aes_ctr_encrypt", 3, aes_ctr_encrypt},
+ {"aes_ctr_decrypt", 3, aes_ctr_encrypt},
{"rand_bytes", 1, rand_bytes_1},
{"rand_bytes", 3, rand_bytes_3},
{"rand_uniform_nif", 2, rand_uniform_nif},
@@ -654,6 +663,34 @@ static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE
return ret;
}
+/* Common for both encrypt and decrypt
+*/
+static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Key, IVec, Data) */
+ ErlNifBinary key, ivec, text;
+ AES_KEY aes_key;
+ unsigned char ivec_clone[16]; /* writable copy */
+ unsigned char ecount_buf[AES_BLOCK_SIZE];
+ unsigned int num = 0;
+ ERL_NIF_TERM ret;
+
+ if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
+ || AES_set_encrypt_key(key.data, key.size*8, &aes_key) != 0
+ || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16
+ || !enif_inspect_iolist_as_binary(env, argv[2], &text)) {
+ return enif_make_badarg(env);
+ }
+ memcpy(ivec_clone, ivec.data, 16);
+ memset(ecount_buf, 0, sizeof(ecount_buf));
+ AES_ctr128_encrypt((unsigned char *) text.data,
+ enif_make_new_binary(env, text.size, &ret),
+ text.size, &aes_key, ivec_clone, ecount_buf, &num);
+
+ /* To do an incremental {en|de}cryption, the state to to keep between calls
+ must include ivec_clone, ecount_buf and num. */
+ return ret;
+}
+
static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Bytes) */
unsigned bytes;
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index e1431cfd81..c407350c47 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -53,7 +53,7 @@
<p>aes: Advanced Encryption Standard (AES) (FIPS 197) </p>
</item>
<item>
- <p>ecb, cbc, cfb, ofb: Recommendation for Block Cipher Modes
+ <p>ecb, cbc, cfb, ofb, ctr: Recommendation for Block Cipher Modes
of Operation (NIST SP 800-38A).</p>
</item>
<item>
@@ -557,6 +557,34 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
</desc>
</func>
<func>
+ <name>aes_ctr_encrypt(Key, IVec, Text) -> Cipher</name>
+ <fsummary>Encrypt <c>Text</c>according to AES in Counter mode</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Encrypts <c>Text</c> according to AES in Counter mode (CTR). <c>Text</c>
+ can be any number of bytes. <c>Key</c> is the AES key and must be either
+ 128, 192 or 256 bits long. <c>IVec</c> is an arbitrary initializing vector of 128 bits
+ (16 bytes).</p>
+ </desc>
+ </func>
+ <func>
+ <name>aes_ctr_decrypt(Key, IVec, Cipher) -> Text</name>
+ <fsummary>Decrypt <c>Cipher</c>according to AES in Counter mode</fsummary>
+ <type>
+ <v>Key = Cipher = iolist() | binary()</v>
+ <v>IVec = Text = binary()</v>
+ </type>
+ <desc>
+ <p>Decrypts <c>Cipher</c> according to AES in Counter mode (CTR). <c>Cipher</c>
+ can be any number of bytes. <c>Key</c> is the AES key and must be either
+ 128, 192 or 256 bits long. <c>IVec</c> is an arbitrary initializing vector of 128 bits
+ (16 bytes).</p>
+ </desc>
+ </func>
+ <func>
<name>erlint(Mpint) -> N</name>
<name>mpint(N) -> Mpint</name>
<fsummary>Convert between binary multi-precision integer and erlang big integer</fsummary>
diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index 3c571eb2a3..54dd0cb01f 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -30,6 +30,21 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
+<section><title>Crypto 2.0.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ AES CTR encryption support in <c>crypto</c>.</p>
+ <p>
+ Own Id: OTP-8752 Aux Id: seq11642 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Crypto 2.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 71fd91cafd..d6e2e033c0 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -51,6 +51,7 @@
-export([aes_cbc_128_encrypt/3, aes_cbc_128_decrypt/3]).
-export([aes_cbc_256_encrypt/3, aes_cbc_256_decrypt/3]).
-export([aes_cbc_ivec/1]).
+-export([aes_ctr_encrypt/3, aes_ctr_decrypt/3]).
-export([dh_generate_parameters/2, dh_check/1]). %% Testing see below
@@ -80,6 +81,7 @@
rc2_40_cbc_encrypt, rc2_40_cbc_decrypt,
%% idea_cbc_encrypt, idea_cbc_decrypt,
aes_cbc_256_encrypt, aes_cbc_256_decrypt,
+ aes_ctr_encrypt, aes_ctr_decrypt,
info_lib]).
-type rsa_digest_type() :: 'md5' | 'sha'.
@@ -542,6 +544,16 @@ aes_cbc_ivec(Data) when is_binary(Data) ->
aes_cbc_ivec(Data) when is_list(Data) ->
aes_cbc_ivec(list_to_binary(Data)).
+%%
+%% AES - in counter mode (CTR)
+%%
+-spec aes_ctr_encrypt(iodata(), binary(), iodata()) ->
+ binary().
+-spec aes_ctr_decrypt(iodata(), binary(), iodata()) ->
+ binary().
+
+aes_ctr_encrypt(_Key, _IVec, _Data) -> ?nif_stub.
+aes_ctr_decrypt(_Key, _IVec, _Cipher) -> ?nif_stub.
%%
%% XOR - xor to iolists and return a binary
diff --git a/lib/crypto/test/Makefile b/lib/crypto/test/Makefile
index e728875027..f4689a23df 100644
--- a/lib/crypto/test/Makefile
+++ b/lib/crypto/test/Makefile
@@ -76,7 +76,7 @@ release_spec:
release_tests_spec: $(TEST_TARGET)
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) crypto.spec $(RELTEST_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) crypto.spec crypto.cover $(RELTEST_FILES) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
release_docs_spec:
diff --git a/lib/crypto/test/blowfish_SUITE.erl b/lib/crypto/test/blowfish_SUITE.erl
index d117e7cc3d..735433cd47 100644
--- a/lib/crypto/test/blowfish_SUITE.erl
+++ b/lib/crypto/test/blowfish_SUITE.erl
@@ -23,7 +23,7 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("test_server_line.hrl").
-define(TIMEOUT, 120000). % 2 min
@@ -45,8 +45,12 @@
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- crypto:start(),
- Config.
+ case catch crypto:start() of
+ ok ->
+ Config;
+ _Else ->
+ {skip,"Could not start crypto!"}
+ end.
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
@@ -100,15 +104,20 @@ end_per_testcase(_TestCase, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test Blowfish functionality"];
-
-all(suite) ->
- [ecb,
- cbc,
- cfb64,
- ofb64
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+[ecb, cbc, cfb64, ofb64].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Test cases start here.
%%--------------------------------------------------------------------
diff --git a/lib/crypto/test/crypto.cover b/lib/crypto/test/crypto.cover
new file mode 100644
index 0000000000..61ee372ec5
--- /dev/null
+++ b/lib/crypto/test/crypto.cover
@@ -0,0 +1,2 @@
+{incl_app,crypto,details}.
+
diff --git a/lib/crypto/test/crypto.spec b/lib/crypto/test/crypto.spec
index 7ba5696189..cc09970cb3 100644
--- a/lib/crypto/test/crypto.spec
+++ b/lib/crypto/test/crypto.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../crypto_test"}}.
-
+{suites,"../crypto_test",all}.
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 06b284d50d..b29b067967 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -18,12 +18,11 @@
%%
-module(crypto_SUITE).
--include("test_server.hrl").
--include("test_server_line.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
+ end_per_testcase/2,
info/1,
link_test/1,
md5/1,
@@ -44,6 +43,7 @@
aes_cfb/1,
aes_cbc/1,
aes_cbc_iter/1,
+ aes_ctr/1,
mod_exp_test/1,
rand_uniform_test/1,
rsa_verify_test/1,
@@ -61,48 +61,41 @@
-export([hexstr2bin/1]).
-all(suite) ->
- [link_test,
- {conf,info,[md5,
- md5_update,
- md4,
- md4_update,
- md5_mac,
- md5_mac_io,
- sha,
- sha_update,
-%% sha256,
-%% sha256_update,
-%% sha512,
-%% sha512_update,
- des_cbc,
- aes_cfb,
- aes_cbc,
- aes_cbc_iter,
- des_cbc_iter,
- des_ecb,
- rand_uniform_test,
- rsa_verify_test,
- dsa_verify_test,
- rsa_sign_test,
- dsa_sign_test,
- rsa_encrypt_decrypt,
- dh,
- exor_test,
- rc4_test,
- rc4_stream_test,
- mod_exp_test,
- blowfish_cfb64,
- smp],
- cleanup}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [link_test, md5, md5_update, md4, md4_update, md5_mac,
+ md5_mac_io, sha, sha_update,
+ %% sha256, sha256_update, sha512,sha512_update,
+ des_cbc, aes_cfb, aes_cbc,
+ aes_cbc_iter, aes_ctr, des_cbc_iter, des_ecb, rand_uniform_test,
+ rsa_verify_test, dsa_verify_test, rsa_sign_test,
+ dsa_sign_test, rsa_encrypt_decrypt, dh, exor_test,
+ rc4_test, rc4_stream_test, mod_exp_test, blowfish_cfb64,
+ smp].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
init_per_testcase(_Name,Config) ->
io:format("init_per_testcase\n"),
?line crypto:start(),
Config.
-fin_per_testcase(_Name,Config) ->
- io:format("fin_per_testcase\n"),
+end_per_testcase(_Name,Config) ->
+ io:format("end_per_testcase\n"),
?line crypto:stop(),
Config.
@@ -619,6 +612,65 @@ aes_cbc_decrypt_iter(Key,IVec,Data, Acc) ->
aes_cbc_decrypt_iter(Key,IVec2,Rest, <<Acc/binary, Plain/binary>>).
+aes_ctr(doc) -> "CTR";
+aes_ctr(Config) when is_list(Config) ->
+ %% Sample data from NIST Spec.Publ. 800-38A
+ %% F.5.1 CTR-AES128.Encrypt
+ Key128 = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
+ Samples128 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
+ "6bc1bee22e409f96e93d7e117393172a", % Plaintext
+ "874d6191b620e3261bef6864990db6ce"},% Ciphertext
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ "ae2d8a571e03ac9c9eb76fac45af8e51",
+ "9806f66b7970fdff8617187bb9fffdff"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ "30c81c46a35ce411e5fbc1191a0a52ef",
+ "5ae4df3edbd5d35e5b4f09020db03eab"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
+ "f69f2445df4f9b17ad2b417be66c3710",
+ "1e031dda2fbe03d1792170a0f3009cee"}],
+ lists:foreach(fun(S) -> aes_ctr_do(Key128,S) end, Samples128),
+
+ %% F.5.3 CTR-AES192.Encrypt
+ Key192 = hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
+ Samples192 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
+ "6bc1bee22e409f96e93d7e117393172a", % Plaintext
+ "1abc932417521ca24f2b0459fe7e6e0b"},% Ciphertext
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ "ae2d8a571e03ac9c9eb76fac45af8e51",
+ "090339ec0aa6faefd5ccc2c6f4ce8e94"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ "30c81c46a35ce411e5fbc1191a0a52ef",
+ "1e36b26bd1ebc670d1bd1d665620abf7"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
+ "f69f2445df4f9b17ad2b417be66c3710",
+ "4f78a7f6d29809585a97daec58c6b050"}],
+ lists:foreach(fun(S) -> aes_ctr_do(Key192,S) end, Samples192),
+
+ %% F.5.5 CTR-AES256.Encrypt
+ Key256 = hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
+ Samples256 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
+ "6bc1bee22e409f96e93d7e117393172a", % Plaintext
+ "601ec313775789a5b7a7f504bbf3d228"},% Ciphertext
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ "ae2d8a571e03ac9c9eb76fac45af8e51",
+ "f443e3ca4d62b59aca84e990cacaf5c5"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ "30c81c46a35ce411e5fbc1191a0a52ef",
+ "2b0930daa23de94ce87017ba2d84988d"},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
+ "f69f2445df4f9b17ad2b417be66c3710",
+ "dfc9c58db67aada613c2dd08457941a6"}],
+ lists:foreach(fun(S) -> aes_ctr_do(Key256,S) end, Samples256).
+
+
+aes_ctr_do(Key,{IVec, Plain, Cipher}) ->
+ ?line I = hexstr2bin(IVec),
+ ?line P = hexstr2bin(Plain),
+ ?line C = crypto:aes_ctr_encrypt(Key, I, P),
+ ?line m(C, hexstr2bin(Cipher)),
+ ?line m(P, crypto:aes_ctr_decrypt(Key, I, C)).
+
%%
%%
mod_exp_test(doc) ->
diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk
index e3549f0c50..4b35c7c0b4 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 2.0.1
+CRYPTO_VSN = 2.0.2
diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml
index c72a5271ba..2f8bdc36a1 100644
--- a/lib/debugger/doc/src/notes.xml
+++ b/lib/debugger/doc/src/notes.xml
@@ -32,6 +32,20 @@
<p>This document describes the changes made to the Debugger
application.</p>
+<section><title>Debugger 3.2.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Miscellaneous updates</p>
+ <p>
+ Own Id: OTP-8976</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Debugger 3.2.4</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/debugger/test/Makefile b/lib/debugger/test/Makefile
index ac929038f7..47e307fcf9 100644
--- a/lib/debugger/test/Makefile
+++ b/lib/debugger/test/Makefile
@@ -99,7 +99,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
- $(INSTALL_DATA) debugger.spec $(RELSYSDIR)
+ $(INSTALL_DATA) debugger.spec debugger.cover $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/debugger/test/andor_SUITE.erl b/lib/debugger/test/andor_SUITE.erl
index 3482a22a34..68b2f521d6 100644
--- a/lib/debugger/test/andor_SUITE.erl
+++ b/lib/debugger/test/andor_SUITE.erl
@@ -20,35 +20,50 @@
%%
-module(andor_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
t_andalso/1,t_orelse/1,inside/1,overlap/1,
combined/1,in_case/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
?line Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
-cases() ->
- [t_andalso,t_orelse,inside,overlap,combined,in_case].
+cases() ->
+ [t_andalso, t_orelse, inside, overlap, combined,
+ in_case].
t_andalso(Config) when is_list(Config) ->
Bs = [true,false],
diff --git a/lib/debugger/test/bs_bincomp_SUITE.erl b/lib/debugger/test/bs_bincomp_SUITE.erl
index 8ca2b36f1c..f341700c3b 100644
--- a/lib/debugger/test/bs_bincomp_SUITE.erl
+++ b/lib/debugger/test/bs_bincomp_SUITE.erl
@@ -23,25 +23,45 @@
-module(bs_bincomp_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
byte_aligned/1,bit_aligned/1,extended_byte_aligned/1,
extended_bit_aligned/1,mixed/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [byte_aligned,bit_aligned,extended_byte_aligned,
- extended_bit_aligned,mixed].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [byte_aligned, bit_aligned, extended_byte_aligned,
+ extended_bit_aligned, mixed].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
byte_aligned(Config) when is_list(Config) ->
diff --git a/lib/debugger/test/bs_construct_SUITE.erl b/lib/debugger/test/bs_construct_SUITE.erl
index efc125c582..c51e7fbf4c 100644
--- a/lib/debugger/test/bs_construct_SUITE.erl
+++ b/lib/debugger/test/bs_construct_SUITE.erl
@@ -19,35 +19,49 @@
-module(bs_construct_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
test1/1, test2/1, test3/1, test4/1, test5/1, testf/1, not_used/1, in_guard/1,
coerce_to_float/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [test1, test2, test3, test4, test5, testf,
- not_used, in_guard, coerce_to_float].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [test1, test2, test3, test4, test5, testf, not_used,
+ in_guard, coerce_to_float].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
big(1) ->
diff --git a/lib/debugger/test/bs_match_bin_SUITE.erl b/lib/debugger/test/bs_match_bin_SUITE.erl
index 3966dc41ef..fe2a8d6698 100644
--- a/lib/debugger/test/bs_match_bin_SUITE.erl
+++ b/lib/debugger/test/bs_match_bin_SUITE.erl
@@ -21,33 +21,47 @@
-module(bs_match_bin_SUITE).
-author('[email protected]').
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
byte_split_binary/1,bit_split_binary/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [byte_split_binary,bit_split_binary].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [byte_split_binary, bit_split_binary].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
byte_split_binary(doc) -> "Tries to split a binary at all byte-aligned positions.";
diff --git a/lib/debugger/test/bs_match_int_SUITE.erl b/lib/debugger/test/bs_match_int_SUITE.erl
index 1159ac9ef8..c667e7cbce 100644
--- a/lib/debugger/test/bs_match_int_SUITE.erl
+++ b/lib/debugger/test/bs_match_int_SUITE.erl
@@ -20,35 +20,49 @@
-module(bs_match_int_SUITE).
-author('[email protected]').
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
integer/1,signed_integer/1,dynamic/1,more_dynamic/1,mml/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-import(lists, [seq/2]).
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [integer,signed_integer,dynamic,more_dynamic,mml].
+all() ->
+ [cases()].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [integer, signed_integer, dynamic, more_dynamic, mml].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
Dog = test_server:timetrap(?t:minutes(4)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
integer(suite) -> [];
diff --git a/lib/debugger/test/bs_match_misc_SUITE.erl b/lib/debugger/test/bs_match_misc_SUITE.erl
index 5e1160a8e9..e7ea355c9d 100644
--- a/lib/debugger/test/bs_match_misc_SUITE.erl
+++ b/lib/debugger/test/bs_match_misc_SUITE.erl
@@ -20,33 +20,47 @@
-module(bs_match_misc_SUITE).
-author('[email protected]').
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
bound_var/1,bound_tail/1,t_float/1,little_float/1,sean/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [bound_var,bound_tail,t_float,little_float,sean].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [bound_var, bound_tail, t_float, little_float, sean].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
bound_var(doc) -> "Test matching of bound variables.";
diff --git a/lib/debugger/test/bs_match_tail_SUITE.erl b/lib/debugger/test/bs_match_tail_SUITE.erl
index 7fa16b3c6a..282eebcd25 100644
--- a/lib/debugger/test/bs_match_tail_SUITE.erl
+++ b/lib/debugger/test/bs_match_tail_SUITE.erl
@@ -20,33 +20,47 @@
-module(bs_match_tail_SUITE).
-author('[email protected]').
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
aligned/1,unaligned/1,zero_tail/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [aligned,unaligned,zero_tail].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [aligned, unaligned, zero_tail].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
aligned(doc) -> "Test aligned tails.";
diff --git a/lib/debugger/test/bs_utf_SUITE.erl b/lib/debugger/test/bs_utf_SUITE.erl
index 3d69d2a101..b61638fa25 100644
--- a/lib/debugger/test/bs_utf_SUITE.erl
+++ b/lib/debugger/test/bs_utf_SUITE.erl
@@ -21,37 +21,50 @@
-module(bs_utf_SUITE).
--export([all/1,init_all/1,finish_all/1,
- init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1,end_per_suite/1,
+ init_per_testcase/2,end_per_testcase/2,
utf8_roundtrip/1,unused_utf_char/1,utf16_roundtrip/1,
utf32_roundtrip/1,guard/1,extreme_tripping/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-compile([no_jopt,time]).
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [utf8_roundtrip,unused_utf_char,utf16_roundtrip,
- utf32_roundtrip,guard,extreme_tripping].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [utf8_roundtrip, unused_utf_char, utf16_roundtrip,
+ utf32_roundtrip, guard, extreme_tripping].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
utf8_roundtrip(Config) when is_list(Config) ->
diff --git a/lib/debugger/test/bug_SUITE.erl b/lib/debugger/test/bug_SUITE.erl
index cf732c8115..d881b9ab08 100644
--- a/lib/debugger/test/bug_SUITE.erl
+++ b/lib/debugger/test/bug_SUITE.erl
@@ -20,18 +20,34 @@
%%
-module(bug_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
-
--export([ticket_tests/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([otp2163/1, otp4845/1]).
-all(suite) -> [ticket_tests].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, ticket_tests}].
+
+groups() ->
+ [{ticket_tests, [], [otp2163, otp4845]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-ticket_tests(doc) -> ["Tests tickets regarding bugs"];
-ticket_tests(suite) -> [otp2163, otp4845].
otp2163(doc) -> ["BIF exit reason"];
otp2163(suite) -> [];
diff --git a/lib/debugger/test/cleanup.erl b/lib/debugger/test/cleanup.erl
index 59b4c35ac7..5f1ea71d2e 100644
--- a/lib/debugger/test/cleanup.erl
+++ b/lib/debugger/test/cleanup.erl
@@ -20,11 +20,22 @@
%%
-module(cleanup).
--export([all/1, cleanup/1]).
+-export([all/0,groups/0,init_per_group/2,end_per_group/2, cleanup/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+all() ->
+[cleanup].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> {req, [interpreter], [cleanup]}.
cleanup(suite) -> [];
cleanup(_) ->
diff --git a/lib/debugger/test/dbg_ui_SUITE.erl b/lib/debugger/test/dbg_ui_SUITE.erl
index 629aac9fd6..e59c23442a 100644
--- a/lib/debugger/test/dbg_ui_SUITE.erl
+++ b/lib/debugger/test/dbg_ui_SUITE.erl
@@ -21,23 +21,17 @@
-module(dbg_ui_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% Test server specific exports
--export([all/1]).
--export([function_tests/1]).
-
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
% Test cases must be exported.
-export ([dbg_ui/1]).
-
-
-
-
% Manual test suites/cases exports
--export([manual_tests/1]).
-export([start1/1, interpret1/1, quit1/1,
start2/1, interpret2/1, break2/1, options2/1, quit2/1,
interpret3/1, all_step3/1,all_next3/1,save3/1,restore3/1,finish3/1,
@@ -46,33 +40,42 @@
attach5/1, normal5/1, exit5/1, options5/1,
distsetup6/1, all_step6/1, all_next6/1]).
-
-
-
--export([init_per_testcase/2, fin_per_testcase/2]).
-
-
+-export([init_per_testcase/2, end_per_testcase/2]).
init_per_testcase(_Func, Config) ->
Dog=test_server:timetrap(60*1000),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
-all (suite)->
- {req, [debugger], [function_tests, manual_tests]}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [dbg_ui, {group, manual_tests}].
+groups() ->
+ [{manual_tests, [],
+ [start1, interpret1, quit1, start2, interpret2, break2,
+ options2, interpret3, all_step3, all_next3, save3,
+ restore3, finish3, killinit3, killone3, killall3,
+ deleteone3, deleteall3, viewbreak4, delete4, attach5,
+ normal5, exit5, options5, distsetup6, all_step6,
+ all_next6]}].
-function_tests (doc) ->
- ["Tests documented functions"];
+init_per_suite(Config) ->
+ Config.
-function_tests (suite) ->
- [dbg_ui].
+end_per_suite(_Config) ->
+ ok.
+init_per_group(_GroupName, Config) ->
+ Config.
+end_per_group(_GroupName, Config) ->
+ Config.
dbg_ui (doc) ->
["Debugger GUI"];
@@ -84,7 +87,7 @@ dbg_ui (_Config) ->
case os:getenv("DISPLAY") of
false ->
{skipped,"No display"};
- Other when list(Other) ->
+ Other when is_list(Other) ->
% ?line {ok, Pid} = debugger:start (),
% ?line ok = is_pid (Pid),
% ?line true = erlang:is_process_alive(Pid),
@@ -93,11 +96,6 @@ dbg_ui (_Config) ->
{skipped,"Gunilla: Workaround"}
end.
-
-
-
-
-
%% check/2 - returns the result for the specified testcase.
%% pass - means the user has run the case, and it passed
%% fail - means the user has run the case, and it failed
@@ -162,23 +160,6 @@ check(Case, Config) ->
).
-
-
-manual_tests(doc) -> ["Manual tests"];
-manual_tests(suite) -> [start1, interpret1, quit1,
- start2, interpret2, break2, options2,
- interpret3, all_step3,all_next3,save3,restore3,finish3,
- killinit3, killone3, killall3, deleteone3, deleteall3,
- viewbreak4, delete4,
- attach5, normal5, exit5, options5,
- distsetup6, all_step6, all_next6
- ].
-
-
-
-
-
-
%% SET 1
?MAN_CASE(start1, "Start the debugger from the toolbar",
"Before proceeding with the test cases, please move or remove
diff --git a/lib/debugger/test/debugger.cover b/lib/debugger/test/debugger.cover
new file mode 100644
index 0000000000..509ddc0ec1
--- /dev/null
+++ b/lib/debugger/test/debugger.cover
@@ -0,0 +1,2 @@
+{incl_app,debugger,details}.
+
diff --git a/lib/debugger/test/debugger.spec b/lib/debugger/test/debugger.spec
index cc8a5aff37..7aef026e77 100644
--- a/lib/debugger/test/debugger.spec
+++ b/lib/debugger/test/debugger.spec
@@ -1 +1 @@
-{topcase, {dir, "../debugger_test"}}.
+{suites,"../debugger_test",all}.
diff --git a/lib/debugger/test/debugger_SUITE.erl b/lib/debugger/test/debugger_SUITE.erl
index 4bd9057f98..747d9e343d 100644
--- a/lib/debugger/test/debugger_SUITE.erl
+++ b/lib/debugger/test/debugger_SUITE.erl
@@ -22,19 +22,40 @@
%% Test break points.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
app_test/1,erts_debug/1,encrypted_debug_info/1,
no_abstract_code/1]).
-all(suite) ->
- [app_test,erts_debug,no_abstract_code,encrypted_debug_info].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [app_test, erts_debug, no_abstract_code,
+ encrypted_debug_info].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
Dog=test_server:timetrap(?t:minutes(0.5)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/debugger/test/erl_eval_SUITE.erl b/lib/debugger/test/erl_eval_SUITE.erl
index fd4d28b2c7..67ca3d4867 100644
--- a/lib/debugger/test/erl_eval_SUITE.erl
+++ b/lib/debugger/test/erl_eval_SUITE.erl
@@ -17,7 +17,8 @@
%% %CopyrightEnd%
-module(erl_eval_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([guard_1/1, guard_2/1,
match_pattern/1,
@@ -57,26 +58,43 @@
config(priv_dir,_) ->
".".
-else.
--include("test_server.hrl").
--export([init_per_testcase/2, fin_per_testcase/2]).
+-include_lib("test_server/include/test_server.hrl").
+-export([init_per_testcase/2, end_per_testcase/2]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-endif.
-all(doc) ->
- ["Test cases for the 'erl_eval' module."];
-all(suite) ->
- [guard_1, guard_2, match_pattern, string_plusplus, pattern_expr,
- match_bin, guard_3, guard_4,
- lc, simple_cases, unary_plus, apply_atom, otp_5269, otp_6539, otp_6543,
- otp_6787, otp_6977, otp_7550, otp_8133, funs, try_catch, eval_expr_5].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [guard_1, guard_2, match_pattern, string_plusplus,
+ pattern_expr, match_bin, guard_3, guard_4, lc,
+ simple_cases, unary_plus, apply_atom, otp_5269,
+ otp_6539, otp_6543, otp_6787, otp_6977, otp_7550,
+ otp_8133, funs, try_catch, eval_expr_5].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
guard_1(doc) ->
["(OTP-2405)"];
diff --git a/lib/debugger/test/exception_SUITE.erl b/lib/debugger/test/exception_SUITE.erl
index a74a93fd22..e6d627b40e 100644
--- a/lib/debugger/test/exception_SUITE.erl
+++ b/lib/debugger/test/exception_SUITE.erl
@@ -20,17 +20,31 @@
%%
-module(exception_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
badmatch/1,pending_errors/1,nil_arith/1]).
-export([bad_guy/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
[badmatch, pending_errors, nil_arith].
-define(try_match(E),
@@ -42,17 +56,17 @@ init_per_testcase(_Case, Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
badmatch(doc) -> "Test that deliberately bad matches are reported correctly.";
diff --git a/lib/debugger/test/fun_SUITE.erl b/lib/debugger/test/fun_SUITE.erl
index 721048b6b6..f56c6fe4bf 100644
--- a/lib/debugger/test/fun_SUITE.erl
+++ b/lib/debugger/test/fun_SUITE.erl
@@ -20,20 +20,33 @@
%%
-module(fun_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
- init_all/1,finish_all/1,
+ init_per_suite/1,end_per_suite/1,
good_call/1,bad_apply/1,bad_fun_call/1,badarity/1,
ext_badarity/1,otp_6061/1]).
-export([nothing/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [good_call,bad_apply,bad_fun_call,badarity,ext_badarity,otp_6061].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [good_call, bad_apply, bad_fun_call, badarity,
+ ext_badarity, otp_6061].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
@@ -45,12 +58,12 @@ end_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
good_call(Config) when is_list(Config) ->
diff --git a/lib/debugger/test/guard_SUITE.erl b/lib/debugger/test/guard_SUITE.erl
index b5269989c8..dd8a2fe4d5 100644
--- a/lib/debugger/test/guard_SUITE.erl
+++ b/lib/debugger/test/guard_SUITE.erl
@@ -20,7 +20,9 @@
%%
-module(guard_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
bad_arith/1,bad_tuple/1,test_heap_guards/1,guard_bifs/1,
type_tests/1,const_guard/1,
const_cond/1,basic_not/1,complex_not/1,
@@ -35,41 +37,52 @@
basic_andalso_orelse/1,traverse_dcd/1,
check_qlc_hrl/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-export([init/4]).
-import(lists, [member/2]).
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [bad_arith,bad_tuple,test_heap_guards,guard_bifs,type_tests,const_guard,
- const_cond,basic_not,complex_not,
- semicolon,complex_semicolon,
- comma,or_guard,more_or_guards,
- complex_or_guards,and_guard,
- xor_guard,more_xor_guards,
- build_in_guard,old_guard_tests,gbif,
- t_is_boolean,is_function_2,tricky,rel_ops,
- basic_andalso_orelse,traverse_dcd,check_qlc_hrl].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [bad_arith, bad_tuple, test_heap_guards, guard_bifs,
+ type_tests, const_guard, const_cond, basic_not,
+ complex_not, semicolon, complex_semicolon, comma,
+ or_guard, more_or_guards, complex_or_guards, and_guard,
+ xor_guard, more_xor_guards, build_in_guard,
+ old_guard_tests, gbif, t_is_boolean, is_function_2,
+ tricky, rel_ops, basic_andalso_orelse, traverse_dcd,
+ check_qlc_hrl].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
?line Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
bad_arith(doc) -> "Test that a bad arithmetic operation in a guard works correctly.";
diff --git a/lib/debugger/test/int_SUITE.erl b/lib/debugger/test/int_SUITE.erl
index 0326325888..fb3a828fa1 100644
--- a/lib/debugger/test/int_SUITE.erl
+++ b/lib/debugger/test/int_SUITE.erl
@@ -19,15 +19,16 @@
%%
-module(int_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([init_per_testcase/2, end_per_testcase/2]).
%% Test cases
--export([interpret/1, guards/1, list_suite/1, interpretable/1]).
--export([append/1, append_1/1, append_2/1, member/1, reverse/1]).
+-export([interpret/1, guards/1, interpretable/1]).
+-export([ append_1/1, append_2/1, member/1, reverse/1]).
%% Default timetrap timeout (set in init_per_testcase)
-define(default_timeout, ?t:minutes(1)).
@@ -59,8 +60,27 @@ end_per_testcase(_Case, Config) ->
?line test_server:timetrap_cancel(Dog),
?line ok.
-all(suite)->
- [interpret, guards, list_suite, interpretable].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [interpret, guards, {group, list_suite}, interpretable].
+
+groups() ->
+ [{list_suite, [], [{group, append}, reverse, member]},
+ {append, [], [append_1, append_2]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
interpret(suite) ->
[];
@@ -97,13 +117,7 @@ guards(Config) when is_list(Config) ->
ok = guards:guards().
-list_suite(suite) ->
- [append, reverse, member].
-append(doc) ->
- ["Tests lists1:append/1 & lists1:append/2"];
-append(suite) ->
- [append_1, append_2].
append_1(suite) ->
[];
diff --git a/lib/debugger/test/int_break_SUITE.erl b/lib/debugger/test/int_break_SUITE.erl
index b7b3c5598a..d2ffd2938d 100644
--- a/lib/debugger/test/int_break_SUITE.erl
+++ b/lib/debugger/test/int_break_SUITE.erl
@@ -22,15 +22,35 @@
%% Test break points.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
basic/1,cleanup/1]).
-export([auto_attach/1]).
-all(suite) ->
- [basic,cleanup].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic, cleanup].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line DataDir = ?config(data_dir, Config),
@@ -40,7 +60,7 @@ init_per_testcase(_Case, Config) ->
?line Dog = test_server:timetrap(?t:minutes(0.5)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
?line ok = io:format("Interpreted modules: ~p", [int:interpreted()]),
?line Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
diff --git a/lib/debugger/test/int_eval_SUITE.erl b/lib/debugger/test/int_eval_SUITE.erl
index 19b006e750..6051bfc5ed 100644
--- a/lib/debugger/test/int_eval_SUITE.erl
+++ b/lib/debugger/test/int_eval_SUITE.erl
@@ -22,7 +22,9 @@
%% Purpose: Deeper test of the evaluator.
--export([all/1,init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
bifs_outside_erlang/1, spawning/1, applying/1,
catch_and_throw/1, external_call/1, test_module_info/1,
apply_interpreted_fun/1, apply_uninterpreted_fun/1,
@@ -33,26 +35,41 @@
-define(IM, my_int_eval_module).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [bifs_outside_erlang,spawning,applying,catch_and_throw,
- external_call,test_module_info,
- apply_interpreted_fun,apply_uninterpreted_fun,
+suite() -> [{ct_hooks,[ts_install_cth]},
+ {timetrap,{minutes,1}}].
+
+all() ->
+ [bifs_outside_erlang, spawning, applying,
+ catch_and_throw, external_call, test_module_info,
+ apply_interpreted_fun, apply_uninterpreted_fun,
interpreted_exit, otp_8310].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(_Case, Config) ->
?line DataDir = ?config(data_dir, Config),
?line {module,?IM} = int:i(filename:join(DataDir, ?IM)),
?line ok = io:format("Interpreted modules: ~p",[int:interpreted()]),
- {ok, Dog} = timer:apply_after(timer:minutes(1),
- erlang, exit, [self(), kill]),
- [{watchdog,Dog}|Config].
+ Config.
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, _Config) ->
ok = io:format("Interpreted modules: ~p", [int:interpreted()]),
- Dog = ?config(watchdog, Config),
- timer:cancel(Dog),
ok.
bifs_outside_erlang(doc) ->
@@ -65,10 +82,7 @@ bifs_outside_erlang(Config) when is_list(Config) ->
Self = self(),
ok = io:format("Self: ~p", [Self]),
Info = ets:info(Id),
- {owner,Self} = lists:nth(2, Info),
- %% Was
- %% {owner,Self} = element(2, Info),
- %% in R10B.
+ Self = proplists:get_value(owner, Info),
?IM:ets_delete(Id),
ok
end,
diff --git a/lib/debugger/test/lc_SUITE.erl b/lib/debugger/test/lc_SUITE.erl
index a22a689ec8..f8ab9311e9 100644
--- a/lib/debugger/test/lc_SUITE.erl
+++ b/lib/debugger/test/lc_SUITE.erl
@@ -21,15 +21,29 @@
-module(lc_SUITE).
-author('[email protected]').
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
basic/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
[basic].
init_per_testcase(_Case, Config) ->
@@ -37,17 +51,17 @@ init_per_testcase(_Case, Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
basic(Config) when list(Config) ->
diff --git a/lib/debugger/test/record_SUITE.erl b/lib/debugger/test/record_SUITE.erl
index 06fd01555e..83351231d7 100644
--- a/lib/debugger/test/record_SUITE.erl
+++ b/lib/debugger/test/record_SUITE.erl
@@ -22,33 +22,47 @@
-module(record_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
errors/1,record_test/1,eval_once/1]).
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [errors,record_test,eval_once].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [errors, record_test, eval_once].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
-record(foo, {a,b,c,d}).
diff --git a/lib/debugger/test/trycatch_SUITE.erl b/lib/debugger/test/trycatch_SUITE.erl
index 5901cdc9e5..aa9d898c02 100644
--- a/lib/debugger/test/trycatch_SUITE.erl
+++ b/lib/debugger/test/trycatch_SUITE.erl
@@ -20,37 +20,51 @@
%%
-module(trycatch_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,init_all/1,finish_all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
+ init_per_suite/1,end_per_suite/1,
basic/1,lean_throw/1,try_of/1,try_after/1,%after_bind/1,
catch_oops/1,after_oops/1,eclectic/1,rethrow/1,
nested_of/1,nested_catch/1,nested_after/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [{conf,init_all,cases(),finish_all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [basic,lean_throw,try_of,try_after,%after_bind,
- catch_oops,after_oops,eclectic,rethrow,
- nested_of,nested_catch,nested_after].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [basic, lean_throw, try_of, try_after, catch_oops,
+ after_oops, eclectic, rethrow, nested_of, nested_catch,
+ nested_after].
init_per_testcase(_Case, Config) ->
test_lib:interpret(?MODULE),
Dog = test_server:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
?line test_lib:interpret(?MODULE),
?line true = lists:member(?MODULE, int:interpreted()),
- ok.
+ Config.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
ok.
basic(Conf) when is_list(Conf) ->
diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk
index 654dc11e20..b9786b4a75 100644
--- a/lib/debugger/vsn.mk
+++ b/lib/debugger/vsn.mk
@@ -1 +1 @@
-DEBUGGER_VSN = 3.2.4
+DEBUGGER_VSN = 3.2.5
diff --git a/lib/dialyzer/RELEASE_NOTES b/lib/dialyzer/RELEASE_NOTES
index 62b0c92f97..3fd5e9cc7d 100644
--- a/lib/dialyzer/RELEASE_NOTES
+++ b/lib/dialyzer/RELEASE_NOTES
@@ -3,8 +3,31 @@
(in reversed chronological order)
==============================================================================
-Version 2.3.0 (in Erlang/OTP R14)
----------------------------------
+Version 2.4.0 (in Erlang/OTP R14B01)
+------------------------------------
+ - Added ability to supply multiple PLTs for the analysis (option --plts).
+ Currently these PLTs must be independent (i.e., no module appears in more
+ than one PLT) and there must not include files with module name clashes.
+ - Strengthened and streamlined hard-coded type information for some BIFs
+ and key library functions.
+ - Fixed pretty rare infinite loop when refining the types of an SCC whose
+ functions all returned none() (thanks to Stavros Aronis).
+ - Fixed pretty rare crash when taking the infimum of two tuple_sets.
+ - Fixed pretty rare crash when using parameterized types containing unbound
+ variables (thanks to Nicolas Trangez for reporting it).
+ - Deeper unfolding of recursive types (thanks to Maria Christakis).
+ - Fixed some incomplete and erroneous specs in modules of kernel and stdlib.
+ - Fixed problems in the handling of remote types in records used as types
+ (thanks to Nico Kruber for the report and to Maria Christakis for the fix).
+ - Fixed handling of nested opaque types (thanks to Thorsten Schuett for
+ reporting it and to Maria Christakis for fixing it).
+
+Version 2.3.1 (in Erlang/OTP R14B)
+----------------------------------
+ - Eliminated warnings for auto-imported BIF clashes.
+
+Version 2.3.0 (in Erlang/OTP R14A)
+----------------------------------
- Dialyzer properly supports the new attribute -export_type and checks
that remote types only refer to exported types. A warning is produced
if some files/applications refer to types defined in modules which are
diff --git a/lib/dialyzer/doc/manual.txt b/lib/dialyzer/doc/manual.txt
index 470ddd6c73..cc6f9130c7 100644
--- a/lib/dialyzer/doc/manual.txt
+++ b/lib/dialyzer/doc/manual.txt
@@ -123,9 +123,10 @@ The exit status of the command line version is:
Usage: dialyzer [--help] [--version] [--shell] [--quiet] [--verbose]
- [-pa dir]* [--plt plt] [-Ddefine]* [-I include_dir]*
- [--output_plt file] [-Wwarn]* [--src] [--gui | --wx]
- [files_or_dirs] [-r dirs] [--apps applications] [-o outfile]
+ [-pa dir]* [--plt plt] [--plts plt*] [-Ddefine]*
+ [-I include_dir]* [--output_plt file] [-Wwarn]*
+ [--src] [--gui | --wx] [files_or_dirs] [-r dirs]
+ [--apps applications] [-o outfile]
[--build_plt] [--add_to_plt] [--remove_from_plt]
[--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
[--no_native]
@@ -134,59 +135,75 @@ Options:
files_or_dirs (for backwards compatibility also as: -c files_or_dirs)
Use Dialyzer from the command line to detect defects in the
specified files or directories containing .erl or .beam files,
- depending on the type of the analysis
+ depending on the type of the analysis.
-r dirs
Same as the previous but the specified directories are searched
recursively for subdirectories containing .erl or .beam files in
- them, depending on the type of analysis
+ them, depending on the type of analysis.
--apps applications
- Option typically used when building or modifying PLT as in:
+ Option typically used when building or modifying a plt as in:
dialyzer --build_plt --apps erts kernel stdlib mnesia ...
to conveniently refer to library applications corresponding to the
Erlang/OTP installation. However, the option is general and can also
be used during analysis in order to refer to Erlang/OTP applications.
In addition, file or directory names can also be included, as in:
dialyzer --apps inets ssl ./ebin ../other_lib/ebin/my_module.beam
+ -o outfile (or --output outfile)
+ When using Dialyzer from the command line, send the analysis
+ results to the specified outfile rather than to stdout.
--raw
When using Dialyzer from the command line, output the raw analysis
results (Erlang terms) instead of the formatted result.
The raw format is easier to post-process (for instance, to filter
- warnings or to output HTML pages)
+ warnings or to output HTML pages).
--src
- Override the default, which is to analyze BEAM bytecode, and
- analyze starting from Erlang source code instead
+ Override the default, which is to analyze BEAM files, and
+ analyze starting from Erlang source code instead.
-Dname (or -Dname=value)
- When analyzing from source, pass the define to Dialyzer (**)
+ When analyzing from source, pass the define to Dialyzer. (**)
-I include_dir
- When analyzing from source, pass the include_dir to Dialyzer (**)
+ When analyzing from source, pass the include_dir to Dialyzer. (**)
-pa dir
Include dir in the path for Erlang (useful when analyzing files
- that have '-include_lib()' directives)
+ that have '-include_lib()' directives).
--output_plt file
- Store the plt at the specified file after building it
+ Store the plt at the specified file after building it.
--plt plt
Use the specified plt as the initial plt (if the plt was built
- during setup the files will be checked for consistency)
+ during setup the files will be checked for consistency).
+ --plts plt*
+ Merge the specified plts to create the initial plt -- requires
+ that the plts are disjoint (i.e., do not have any module
+ appearing in more than one plt).
+ The plts are created in the usual way:
+ dialyzer --build_plt --output_plt plt_1 files_to_include
+ ...
+ dialyzer --build_plt --output_plt plt_n files_to_include
+ and then can be used in either of the following ways:
+ dialyzer files_to_analyze --plts plt_1 ... plt_n
+ or:
+ dialyzer --plts plt_1 ... plt_n -- files_to_analyze
+ (Note the -- delimiter in the second case)
-Wwarn
A family of options which selectively turn on/off warnings
- (for help on the names of warnings use dialyzer -Whelp)
+ (for help on the names of warnings use dialyzer -Whelp).
--shell
- Do not disable the Erlang shell while running the GUI
+ Do not disable the Erlang shell while running the GUI.
--version (or -v)
- Prints the Dialyzer version and some more information and exits
+ Print the Dialyzer version and some more information and exit.
--help (or -h)
- Prints this message and exits
+ Print this message and exit.
--quiet (or -q)
- Makes Dialyzer a bit more quiet
+ Make Dialyzer a bit more quiet.
--verbose
- Makes Dialyzer a bit more verbose
+ Make Dialyzer a bit more verbose.
--build_plt
The analysis starts from an empty plt and creates a new one from the
files specified with -c and -r. Only works for beam files.
Use --plt or --output_plt to override the default plt location.
--add_to_plt
The plt is extended to also include the files specified with -c and -r.
- Use --plt to specify wich plt to start from, and --output_plt to
+ Use --plt to specify which plt to start from, and --output_plt to
specify where to put the plt. Note that the analysis might include
files from the plt if they depend on the new files.
This option only works with beam files.
@@ -195,23 +212,23 @@ Options:
from the plt. Note that this may cause a re-analysis of the remaining
dependent files.
--check_plt
- Checks the plt for consistency and rebuilds it if it is not up-to-date.
+ Check the plt for consistency and rebuild it if it is not up-to-date.
--no_check_plt
Skip the plt check when running Dialyzer. Useful when working with
installed plts that never change.
--plt_info
- Makes Dialyzer print information about the plt and then quit. The plt
- can be specified with --plt.
+ Make Dialyzer print information about the plt and then quit. The plt
+ can be specified with --plt(s).
--get_warnings
- Makes Dialyzer emit warnings even when manipulating the plt. Only
- emits warnings for files that are actually analyzed.
+ Make Dialyzer emit warnings even when manipulating the plt. Warnings
+ are only emitted for files that are actually analyzed.
--dump_callgraph file
Dump the call graph into the specified file whose format is determined
by the file name extension. Supported extensions are: raw, dot, and ps.
If something else is used as file name extension, default format '.raw'
will be used.
--no_native (or -nn)
- Bypass the native code compilation of some key files that dialyzer
+ Bypass the native code compilation of some key files that Dialyzer
heuristically performs when dialyzing many files; this avoids the
compilation time but it may result in (much) longer analysis time.
--gui
@@ -231,12 +248,17 @@ Warning options:
Suppress warnings for unused functions.
-Wno_improper_lists
Suppress warnings for construction of improper lists.
+ -Wno_tuple_as_fun
+ Suppress warnings for using tuples instead of funs.
-Wno_fun_app
Suppress warnings for fun applications that will fail.
-Wno_match
Suppress warnings for patterns that are unused or cannot match.
+ -Wno_opaque
+ Suppress warnings for violations of opaqueness of data types.
-Wunmatched_returns ***
- Include warnings for function calls which ignore the return value(s).
+ Include warnings for function calls which ignore a structured return
+ value or do not match against one of many possible return value(s).
-Werror_handling ***
Include warnings for functions that only return by means of an exception.
-Wrace_conditions ***
@@ -257,7 +279,7 @@ The following options are also available but their use is not recommended:
Warn when the -spec is different than the success typing.
Note:
- *** These are options that turn on warnings rather than turning them off.
+ *** Identifies options that turn on warnings rather than turning them off.
-----------------------------------------------
@@ -294,6 +316,7 @@ Option :: {files, [Filename :: string()]}
| {defines, [{Macro :: atom(), Value :: term()}]}
| {from, src_code | byte_code} %% Defaults to byte_code
| {init_plt, FileName :: string()} %% If changed from default
+ | {plts, [FileName :: string()]} %% If changed from default
| {include_dirs, [DirName :: string()]}
| {output_file, FileName :: string()}
| {output_plt, FileName :: string()}
diff --git a/lib/dialyzer/doc/src/dialyzer.xml b/lib/dialyzer/doc/src/dialyzer.xml
index 1ec2ce830a..01a7e478bc 100644
--- a/lib/dialyzer/doc/src/dialyzer.xml
+++ b/lib/dialyzer/doc/src/dialyzer.xml
@@ -64,81 +64,144 @@
]]></code>
<p>Usage:</p>
<code type="none"><![CDATA[
- dialyzer [--help] [--version] [--shell] [--quiet] [--verbose]
- [-pa dir]* [--plt plt] [-Ddefine]* [-I include_dir]*
- [--output_plt file] [-Wwarn]* [--src]
- [-c applications] [-r applications] [-o outfile]
+ dialyzer [--help] [--version] [--shell] [--quiet] [--verbose]
+ [-pa dir]* [--plt plt] [--plts plt*] [-Ddefine]*
+ [-I include_dir]* [--output_plt file] [-Wwarn]*
+ [--src] [--gui | --wx] [files_or_dirs] [-r dirs]
+ [--apps applications] [-o outfile]
[--build_plt] [--add_to_plt] [--remove_from_plt]
[--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
+ [--no_native]
]]></code>
<p>Options:</p>
<taglist>
- <tag><c><![CDATA[-c applications]]></c>(or <c><![CDATA[--command-line applications]]></c>)</tag>
- <item>use Dialyzer from the command line (no GUI) to detect defects in the
- specified applications (directories or <c><![CDATA[.erl]]></c> or <c><![CDATA[.beam]]></c> files)</item>
- <tag><c><![CDATA[-r applications]]></c></tag>
- <item>same as <c><![CDATA[-c]]></c> only that directories are searched recursively for
- subdirectories containing <c><![CDATA[.erl]]></c> or <c><![CDATA[.beam]]></c> files (depending on the
- type of analysis)</item>
- <tag><c><![CDATA[-o outfile]]></c>(or <c><![CDATA[--output outfile]]></c>)</tag>
- <item>when using Dialyzer from the command line, send the analysis
- results in the specified <c><![CDATA[outfile]]></c> rather than in stdout</item>
- <tag><c><![CDATA[--src]]></c></tag>
- <item>override the default, which is to analyze debug compiled BEAM
- bytecode, and analyze starting from Erlang source code instead</item>
+ <tag><c><![CDATA[files_or_dirs]]></c> (for backwards compatibility also
+ as: <c><![CDATA[-c files_or_dirs]]></c></tag>
+ <item>Use Dialyzer from the command line to detect defects in the
+ specified files or directories containing <c><![CDATA[.erl]]></c> or
+ <c><![CDATA[.beam]]></c> files, depending on the type of the
+ analysis.</item>
+ <tag><c><![CDATA[-r dirs]]></c></tag>
+ <item>Same as the previous but the specified directories are searched
+ recursively for subdirectories containing <c><![CDATA[.erl]]></c> or
+ <c><![CDATA[.beam]]></c> files in them, depending on the type of
+ analysis.</item>
+ <tag><c><![CDATA[--apps applications]]></c></tag>
+ <item>Option typically used when building or modifying a plt as in:
+ <code type="none"><![CDATA[
+ dialyzer --build_plt --apps erts kernel stdlib mnesia ...
+ ]]></code>
+ to conveniently refer to library applications corresponding to the
+ Erlang/OTP installation. However, the option is general and can also
+ be used during analysis in order to refer to Erlang/OTP applications.
+ In addition, file or directory names can also be included, as in:
+ <code type="none"><![CDATA[
+ dialyzer --apps inets ssl ./ebin ../other_lib/ebin/my_module.beam
+ ]]></code></item>
+ <tag><c><![CDATA[-o outfile]]></c> (or
+ <c><![CDATA[--output outfile]]></c>)</tag>
+ <item>When using Dialyzer from the command line, send the analysis
+ results to the specified outfile rather than to stdout.</item>
<tag><c><![CDATA[--raw]]></c></tag>
<item>When using Dialyzer from the command line, output the raw analysis
- results (Erlang terms) instead of the formatted result.
- The raw format is easier to post-process (for instance, to filter
- warnings or to output HTML pages).</item>
- <tag><c><![CDATA[-Dname]]></c>(or <c><![CDATA[-Dname=value]]></c>)</tag>
- <item>when analyzing from source, pass the define to Dialyzer (**)</item>
+ results (Erlang terms) instead of the formatted result. The raw format
+ is easier to post-process (for instance, to filter warnings or to
+ output HTML pages).</item>
+ <tag><c><![CDATA[--src]]></c></tag>
+ <item>Override the default, which is to analyze BEAM files, and
+ analyze starting from Erlang source code instead.</item>
+ <tag><c><![CDATA[-Dname]]></c> (or <c><![CDATA[-Dname=value]]></c>)</tag>
+ <item>When analyzing from source, pass the define to Dialyzer. (**)</item>
<tag><c><![CDATA[-I include_dir]]></c></tag>
- <item>when analyzing from source, pass the <c><![CDATA[include_dir]]></c> to Dialyzer (**)</item>
+ <item>When analyzing from source, pass the <c><![CDATA[include_dir]]></c>
+ to Dialyzer. (**)</item>
<tag><c><![CDATA[-pa dir]]></c></tag>
- <item>Include <c><![CDATA[dir]]></c> in the path for Erlang. Useful when analyzing files
- that have <c><![CDATA[-include_lib()]]></c> directives.</item>
+ <item>Include <c><![CDATA[dir]]></c> in the path for Erlang (useful when
+ analyzing files that have <c><![CDATA['-include_lib()']]></c>
+ directives).</item>
<tag><c><![CDATA[--output_plt file]]></c></tag>
- <item>Store the PLT at the specified location after building it.</item>
+ <item>Store the plt at the specified file after building it.</item>
<tag><c><![CDATA[--plt plt]]></c></tag>
- <item>Use the specified plt as the initial persistent lookup table.</item>
+ <item>Use the specified plt as the initial plt (if the plt was built
+ during setup the files will be checked for consistency).</item>
+ <tag><c><![CDATA[--plts plt*]]></c></tag>
+ <item>Merge the specified plts to create the initial plt -- requires
+ that the plts are disjoint (i.e., do not have any module
+ appearing in more than one plt).
+ The plts are created in the usual way:
+ <code type="none"><![CDATA[
+ dialyzer --build_plt --output_plt plt_1 files_to_include
+ ...
+ dialyzer --build_plt --output_plt plt_n files_to_include
+ ]]></code>
+ and then can be used in either of the following ways:
+ <code type="none"><![CDATA[
+ dialyzer files_to_analyze --plts plt_1 ... plt_n
+ ]]></code>
+ or:
+ <code type="none"><![CDATA[
+ dialyzer --plts plt_1 ... plt_n -- files_to_analyze
+ ]]></code>
+ (Note the -- delimiter in the second case)</item>
<tag><c><![CDATA[-Wwarn]]></c></tag>
- <item>a family of option which selectively turn on/off warnings.
- (for help on the names of warnings use <c><![CDATA[dialyzer -Whelp]]></c>)</item>
+ <item>A family of options which selectively turn on/off warnings
+ (for help on the names of warnings use
+ <c><![CDATA[dialyzer -Whelp]]></c>).</item>
<tag><c><![CDATA[--shell]]></c></tag>
- <item>do not disable the Erlang shell while running the GUI</item>
- <tag><c><![CDATA[--version (or -v)]]></c></tag>
- <item>prints the Dialyzer version and some more information and exits</item>
- <tag><c><![CDATA[--help (or -h)]]></c></tag>
- <item>prints this message and exits</item>
- <tag><c><![CDATA[--quiet (or -q)]]></c></tag>
- <item>makes Dialyzer a bit more quiet</item>
+ <item>Do not disable the Erlang shell while running the GUI.</item>
+ <tag><c><![CDATA[--version]]></c> (or <c><![CDATA[-v]]></c>)</tag>
+ <item>Print the Dialyzer version and some more information and
+ exit.</item>
+ <tag><c><![CDATA[--help]]></c> (or <c><![CDATA[-h]]></c>)</tag>
+ <item>Print this message and exit.</item>
+ <tag><c><![CDATA[--quiet]]></c> (or <c><![CDATA[-q]]></c>)</tag>
+ <item>Make Dialyzer a bit more quiet.</item>
<tag><c><![CDATA[--verbose]]></c></tag>
- <item>makes Dialyzer a bit more verbose</item>
- <tag><c><![CDATA[--check_plt]]></c></tag>
- <item>Only checks if the initial PLT is up to date and rebuilds it if this is not the case</item>
- <tag><c><![CDATA[--no_check_plt (or -n)]]></c></tag>
- <item>Skip the PLT integrity check when running Dialyzer.
- Useful when working with installed PLTs that never change.</item>
+ <item>Make Dialyzer a bit more verbose.</item>
<tag><c><![CDATA[--build_plt]]></c></tag>
- <item>The analysis starts from an empty PLT and creates a new one from
- the files specified with -c and -r. Only works for beam files.
- Use --plt or --output_plt to override the default PLT location.</item>
- <tag><c><![CDATA[--add_to_plt]]></c></tag>
- <item> The PLT is extended to also include the files specified with
- -c and -r. Use --plt to specify which PLT to start from, and --output_plt
- to specify where to put the PLT. Note that the analysis might include
- files from the PLT if they depend on the new files.
- This option only works with beam files.</item>
+ <item>The analysis starts from an empty plt and creates a new one from
+ the files specified with <c><![CDATA[-c]]></c> and
+ <c><![CDATA[-r]]></c>. Only works for beam files. Use
+ <c><![CDATA[--plt]]></c> or <c><![CDATA[--output_plt]]></c> to
+ override the default plt location.</item>
+ <tag><c><![CDATA[--add_to_plt]]></c></tag>
+ <item>The plt is extended to also include the files specified with
+ <c><![CDATA[-c]]></c> and <c><![CDATA[-r]]></c>. Use
+ <c><![CDATA[--plt]]></c> to specify which plt to start from,
+ and <c><![CDATA[--output_plt]]></c> to specify where to put the plt.
+ Note that the analysis might include files from the plt if they depend
+ on the new files. This option only works with beam files.</item>
<tag><c><![CDATA[--remove_from_plt]]></c></tag>
- <item>The information from the files specified with -c and -r is removed
- from the PLT. Note that this may cause a re-analysis of the remaining
- dependent files.</item>
+ <item>The information from the files specified with
+ <c><![CDATA[-c]]></c> and <c><![CDATA[-r]]></c> is removed
+ from the plt. Note that this may cause a re-analysis of the remaining
+ dependent files.</item>
+ <tag><c><![CDATA[--check_plt]]></c></tag>
+ <item>Check the plt for consistency and rebuild it if it is not
+ up-to-date.</item>
+ <tag><c><![CDATA[--no_check_plt]]></c></tag>
+ <item>Skip the plt check when running Dialyzer. Useful when working with
+ installed plts that never change.</item>
+ <tag><c><![CDATA[--plt_info]]></c></tag>
+ <item>Make Dialyzer print information about the plt and then quit. The
+ plt can be specified with <c><![CDATA[--plt(s)]]></c>.</item>
<tag><c><![CDATA[--get_warnings]]></c></tag>
- <item>Makes Dialyzer emit warnings even when manipulating the PLT. Only
- emits warnings for files that are actually analyzed. The default is to
- not emit any warnings when manipulating the PLT. This option has no
- effect when performing a normal analysis.</item>
+ <item>Make Dialyzer emit warnings even when manipulating the plt.
+ Warnings are only emitted for files that are actually analyzed.</item>
+ <tag><c><![CDATA[--dump_callgraph file]]></c></tag>
+ <item>Dump the call graph into the specified file whose format is
+ determined by the file name extension. Supported extensions are: raw,
+ dot, and ps. If something else is used as file name extension, default
+ format '.raw' will be used.</item>
+ <tag><c><![CDATA[--no_native]]></c> (or <c><![CDATA[-nn]]></c>)</tag>
+ <item>Bypass the native code compilation of some key files that Dialyzer
+ heuristically performs when dialyzing many files; this avoids the
+ compilation time but it may result in (much) longer analysis
+ time.</item>
+ <tag><c><![CDATA[--gui]]></c></tag>
+ <item>Use the gs-based GUI.</item>
+ <tag><c><![CDATA[--wx]]></c></tag>
+ <item>Use the wx-based GUI..</item>
</taglist>
<note>
<p>* denotes that multiple occurrences of these options are possible.</p>
@@ -148,33 +211,49 @@
<p>Warning options:</p>
<taglist>
<tag><c><![CDATA[-Wno_return]]></c></tag>
- <item>Suppress warnings for functions of no return.</item>
+ <item>Suppress warnings for functions that will never return a
+ value.</item>
<tag><c><![CDATA[-Wno_unused]]></c></tag>
<item>Suppress warnings for unused functions.</item>
<tag><c><![CDATA[-Wno_improper_lists]]></c></tag>
<item>Suppress warnings for construction of improper lists.</item>
+ <tag><c><![CDATA[-Wno_tuple_as_fun]]></c></tag>
+ <item>Suppress warnings for using tuples instead of funs.</item>
<tag><c><![CDATA[-Wno_fun_app]]></c></tag>
<item>Suppress warnings for fun applications that will fail.</item>
<tag><c><![CDATA[-Wno_match]]></c></tag>
<item>Suppress warnings for patterns that are unused or cannot
match.</item>
+ <tag><c><![CDATA[-Wno_opaque]]></c></tag>
+ <item>Suppress warnings for violations of opaqueness of data types.</item>
+ <tag><c><![CDATA[-Wunmatched_returns]]></c>***</tag>
+ <item>Include warnings for function calls which ignore a structured return
+ value or do not match against one of many possible return
+ value(s).</item>
<tag><c><![CDATA[-Werror_handling]]></c>***</tag>
<item>Include warnings for functions that only return by means of an
exception.</item>
- <tag><c><![CDATA[-Wunmatched_returns]]></c>***</tag>
- <item>Include warnings for function calls which ignore a structured return
- value or do not match against one of many possible return value(s).</item>
+ <tag><c><![CDATA[-Wrace_conditions]]></c>***</tag>
+ <item>Include warnings for possible race conditions.</item>
+ <tag><c><![CDATA[-Wbehaviours]]></c>***</tag>
+ <item>Include warnings about behaviour callbacks which drift from the
+ published recommended interfaces.</item>
<tag><c><![CDATA[-Wunderspecs]]></c>***</tag>
<item>Warn about underspecified functions
- (the -spec is strictly more allowing than the success typing)</item>
+ (the -spec is strictly more allowing than the success typing).</item>
+ </taglist>
+ <p>The following options are also available but their use is not
+ recommended: (they are mostly for Dialyzer developers and internal
+ debugging)</p>
+ <taglist>
<tag><c><![CDATA[-Woverspecs]]></c>***</tag>
<item>Warn about overspecified functions
- (the -spec is strictly less allowing than the success typing)</item>
+ (the -spec is strictly less allowing than the success typing).</item>
<tag><c><![CDATA[-Wspecdiffs]]></c>***</tag>
- <item>Warn when the -spec is different than the success typing</item>
+ <item>Warn when the -spec is different than the success typing.</item>
</taglist>
<note>
- <p>*** These are options that turn on warnings rather than
+ <p>*** Identifies options that turn on warnings rather than
turning them off.</p>
</note>
</section>
@@ -203,6 +282,7 @@ Option : {files, [Filename : string()]}
| {defines, [{Macro: atom(), Value : term()}]}
| {from, src_code | byte_code} %% Defaults to byte_code
| {init_plt, FileName : string()} %% If changed from default
+ | {plts, [FileName :: string()]} %% If changed from default
| {include_dirs, [DirName : string()]}
| {output_file, FileName : string()}
| {output_plt, FileName :: string()}
@@ -215,8 +295,11 @@ WarnOpts : no_return
| no_improper_lists
| no_fun_app
| no_match
+ | no_opaque
| no_fail_call
| error_handling
+ | race_conditions
+ | behaviours
| unmatched_returns
| overspecs
| underspecs
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index ac3857b9ef..3678291be7 100755
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -31,6 +31,40 @@
<p>This document describes the changes made to the Dialyzer
application.</p>
+<section><title>Dialyzer 2.4.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> - Fixed pretty rare infinite loop when refining the
+ types of an SCC whose functions all returned none()
+ (thanks to Stavros Aronis). </p><p> - Fixed pretty rare
+ crash when taking the infimum of two tuple_sets. </p>
+ <p>
+ Own Id: OTP-8979</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> - Added ability to supply multiple PLTs for the
+ analysis (option --plts). Currently these PLTs must be
+ independent (i.e., no module appears in more than one
+ PLT) and there must not include files with module name
+ clashes.</p><p> - Strengthened and streamlined hard-coded
+ type information for some BIFs and key library
+ functions.</p>
+ <p>
+ Own Id: OTP-8962</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Dialyzer 2.3.1</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl
index d8fd073ca6..471f9fccd2 100644
--- a/lib/dialyzer/src/dialyzer.erl
+++ b/lib/dialyzer/src/dialyzer.erl
@@ -106,27 +106,35 @@ cl_print_plt_info(Opts) ->
end,
doit(F).
-print_plt_info(#options{init_plt = PLT, output_file = OutputFile}) ->
+print_plt_info(#options{init_plts = PLTs, output_file = OutputFile}) ->
+ PLTInfo = get_plt_info(PLTs),
+ do_print_plt_info(PLTInfo, OutputFile).
+
+get_plt_info([PLT|PLTs]) ->
String =
case dialyzer_plt:included_files(PLT) of
{ok, Files} ->
- io_lib:format("The PLT ~s includes the following files:\n~p\n",
+ io_lib:format("The PLT ~s includes the following files:\n~p\n\n",
[PLT, Files]);
{error, read_error} ->
- Msg = io_lib:format("Could not read the PLT file ~p\n", [PLT]),
+ Msg = io_lib:format("Could not read the PLT file ~p\n\n", [PLT]),
throw({dialyzer_error, Msg});
{error, no_such_file} ->
- Msg = io_lib:format("The PLT file ~p does not exist\n", [PLT]),
+ Msg = io_lib:format("The PLT file ~p does not exist\n\n", [PLT]),
throw({dialyzer_error, Msg})
end,
+ String ++ get_plt_info(PLTs);
+get_plt_info([]) -> "".
+
+do_print_plt_info(PLTInfo, OutputFile) ->
case OutputFile =:= none of
true ->
- io:format("~s", [String]),
+ io:format("~s", [PLTInfo]),
?RET_NOTHING_SUSPICIOUS;
false ->
case file:open(OutputFile, [write]) of
{ok, FileDesc} ->
- io:format(FileDesc, "~s", [String]),
+ io:format(FileDesc, "~s", [PLTInfo]),
ok = file:close(FileDesc),
?RET_NOTHING_SUSPICIOUS;
{error, Reason} ->
@@ -225,6 +233,8 @@ plt_info(Plt) ->
%% Machinery
%%-----------
+-type doit_ret() :: {'ok', dial_ret()} | {'error', string()}.
+
doit(F) ->
try
{ok, F()}
@@ -233,13 +243,17 @@ doit(F) ->
{error, lists:flatten(Msg)}
end.
+-spec cl_error(string()) -> no_return().
+
cl_error(Msg) ->
cl_halt({error, Msg}, #options{}).
+-spec gui_halt(doit_ret(), #options{}) -> no_return().
+
gui_halt(R, Opts) ->
cl_halt(R, Opts#options{report_mode = quiet}).
--spec cl_halt({'ok',dial_ret()} | {'error',string()}, #options{}) -> no_return().
+-spec cl_halt(doit_ret(), #options{}) -> no_return().
cl_halt({ok, R = ?RET_NOTHING_SUSPICIOUS}, #options{report_mode = quiet}) ->
halt(R);
@@ -379,7 +393,7 @@ message_to_string({spec_missing_fun, [M, F, A]}) ->
[M, F, A]);
%%----- Warnings for opaque type violations -------------------
message_to_string({call_with_opaque, [M, F, Args, ArgNs, ExpArgs]}) ->
- io_lib:format("The call ~w:~w~s contains ~s argument when ~s\n",
+ io_lib:format("The call ~w:~w~s contains ~s when ~s\n",
[M, F, Args, form_positions(ArgNs), form_expected(ExpArgs)]);
message_to_string({call_without_opaque, [M, F, Args, ExpectedTriples]}) ->
io_lib:format("The call ~w:~w~s does not have ~s\n",
diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl
index 2da8ed2e5d..1d98574585 100644
--- a/lib/dialyzer/src/dialyzer.hrl
+++ b/lib/dialyzer/src/dialyzer.hrl
@@ -129,7 +129,7 @@
defines = [] :: [dial_define()],
from = byte_code :: start_from(),
get_warnings = maybe :: boolean() | 'maybe',
- init_plt = none :: 'none' | file:filename(),
+ init_plts = [] :: [file:filename()],
include_dirs = [] :: [file:filename()],
output_plt = none :: 'none' | file:filename(),
legal_warnings = ordsets:new() :: ordset(dial_warn_tag()),
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index 3438cc8c7e..abad1f3a75 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -21,7 +21,7 @@
%%%-------------------------------------------------------------------
%%% File : dialyzer_analysis_callgraph.erl
%%% Author : Tobias Lindahl <[email protected]>
-%%% Description :
+%%% Description :
%%%
%%% Created : 5 Apr 2005 by Tobias Lindahl <[email protected]>
%%%-------------------------------------------------------------------
@@ -32,7 +32,7 @@
-include("dialyzer.hrl").
--record(analysis_state,
+-record(analysis_state,
{
codeserver :: dialyzer_codeserver:codeserver(),
analysis_type = succ_typings :: anal_type(),
@@ -44,7 +44,7 @@
plt :: dialyzer_plt:plt(),
start_from = byte_code :: start_from(),
use_contracts = true :: boolean(),
- behaviours = {false,[]} :: {boolean(),[atom()]}
+ behaviours = {false,[]} :: {boolean(),[atom()]}
}).
-record(server_state, {parent :: pid(), legal_warnings :: [dial_warn_tag()]}).
@@ -83,10 +83,10 @@ loop(#server_state{parent = Parent, legal_warnings = LegalWarnings} = State,
send_warnings(Parent, SendWarnings)
end,
loop(State, Analysis, ExtCalls);
- {AnalPid, cserver, CServer, Plt} ->
+ {AnalPid, cserver, CServer, Plt} ->
send_codeserver_plt(Parent, CServer, Plt),
loop(State, Analysis, ExtCalls);
- {AnalPid, done, Plt, DocPlt} ->
+ {AnalPid, done, Plt, DocPlt} ->
case ExtCalls =:= none of
true ->
send_analysis_done(Parent, Plt, DocPlt);
@@ -176,7 +176,7 @@ analysis_start(Parent, Analysis) ->
NonExportsList = sets:to_list(NonExports),
Plt3 = dialyzer_plt:delete_list(State3#analysis_state.plt, NonExportsList),
Plt4 = dialyzer_plt:delete_contract_list(Plt3, NonExportsList),
- send_codeserver_plt(Parent, CServer, State3#analysis_state.plt),
+ send_codeserver_plt(Parent, CServer, State3#analysis_state.plt),
send_analysis_done(Parent, Plt4, State3#analysis_state.doc_plt).
analyze_callgraph(Callgraph, State) ->
@@ -229,24 +229,24 @@ compile_and_store(Files, #analysis_state{codeserver = CServer,
{error, Reason} ->
{TmpCG, TmpCServer, [{File, Reason}|TmpFailed], TmpNoWarn,
TmpMods};
- {ok, NewCG, NoWarn, NewCServer, Mod} ->
+ {ok, NewCG, NoWarn, NewCServer, Mod} ->
{NewCG, NewCServer, TmpFailed, NoWarn++TmpNoWarn,
[Mod|TmpMods]}
end
end;
byte_code ->
- fun(File, {TmpCG, TmpCServer, TmpFailed, TmpNoWarn, TmpMods}) ->
+ fun(File, {TmpCG, TmpCServer, TmpFailed, TmpNoWarn, TmpMods}) ->
case compile_byte(File, TmpCG, TmpCServer, UseContracts) of
{error, Reason} ->
{TmpCG, TmpCServer, [{File, Reason}|TmpFailed], TmpNoWarn,
TmpMods};
- {ok, NewCG, NoWarn, NewCServer, Mod} ->
+ {ok, NewCG, NoWarn, NewCServer, Mod} ->
{NewCG, NewCServer, TmpFailed, NoWarn++TmpNoWarn,
[Mod|TmpMods]}
end
end
end,
- {NewCallgraph1, NewCServer, Failed, NoWarn, Modules} =
+ {NewCallgraph1, NewCServer, Failed, NoWarn, Modules} =
lists:foldl(Fun, {Callgraph, CServer, [], [], []}, Files),
case Failed =:= [] of
true ->
@@ -255,7 +255,7 @@ compile_and_store(Files, #analysis_state{codeserver = CServer,
lists:foldl(fun({Mod, F}, Dict) -> dict:append(Mod, F, Dict) end,
dict:new(), NewFiles),
check_for_duplicate_modules(ModDict);
- false ->
+ false ->
Msg = io_lib:format("Could not scan the following file(s): ~p",
[lists:flatten(Failed)]),
exit({error, Msg})
@@ -268,14 +268,14 @@ compile_and_store(Files, #analysis_state{codeserver = CServer,
if UnknownBehaviours =:= [] -> ok;
true -> send_unknown_behaviours(Parent, UnknownBehaviours)
end,
- State1 = State#analysis_state{behaviours = {BehChk,KnownBehaviours}},
+ State1 = State#analysis_state{behaviours = {BehChk, KnownBehaviours}},
NewCallgraph2 = cleanup_callgraph(State1, NewCServer, NewCallgraph1, Modules),
{T3, _} = statistics(runtime),
Msg2 = io_lib:format("done in ~.2f secs\n", [(T3-T2)/1000]),
- send_log(Parent, Msg2),
+ send_log(Parent, Msg2),
{NewCallgraph2, sets:from_list(NoWarn), NewCServer}.
-cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent,
+cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent,
codeserver = CodeServer,
behaviours = {BehChk, KnownBehaviours}
},
@@ -298,9 +298,9 @@ cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent,
not dialyzer_plt:contains_mfa(InitPlt, To)],
{BadCalls1, RealExtCalls} =
if ExtCalls1 =:= [] -> {[], []};
- true ->
+ true ->
ModuleSet = sets:from_list(Modules),
- lists:partition(fun({_From, {M, _F, _A}}) ->
+ lists:partition(fun({_From, {M, _F, _A}}) ->
sets:is_element(M, ModuleSet) orelse
dialyzer_plt:contains_module(InitPlt, M)
end, ExtCalls1)
@@ -367,14 +367,14 @@ compile_byte(File, Callgraph, CServer, UseContracts) ->
case dialyzer_utils:get_record_and_type_info(AbstrCode) of
{error, _} = Error -> Error;
{ok, RecInfo} ->
- CServer1 =
+ CServer1 =
dialyzer_codeserver:store_temp_records(Mod, RecInfo, CServer),
case UseContracts of
true ->
case dialyzer_utils:get_spec_info(Mod, AbstrCode, RecInfo) of
{error, _} = Error -> Error;
{ok, SpecInfo} ->
- CServer2 =
+ CServer2 =
dialyzer_codeserver:store_temp_contracts(Mod, SpecInfo,
CServer1),
store_core(Mod, Core, NoWarn, Callgraph, CServer2)
@@ -455,8 +455,12 @@ expand_files([File|Left], Ext, FileAcc) ->
case filelib:is_dir(File) of
true ->
{ok, List} = file:list_dir(File),
- NewFiles =
- [filename:join(File, X) || X <- List, filename:extension(X) =:= Ext],
+ NewFiles = lists:foldl(fun (X, Acc) ->
+ case filename:extension(X) =:= Ext of
+ true -> [filename:join(File, X)|Acc];
+ false -> Acc
+ end
+ end, FileAcc, List),
expand_files(Left, Ext, NewFiles);
false ->
expand_files(Left, Ext, [File|FileAcc])
diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl
index 616e2465dc..1987c1732c 100644
--- a/lib/dialyzer/src/dialyzer_cl.erl
+++ b/lib/dialyzer/src/dialyzer_cl.erl
@@ -81,11 +81,15 @@ build_plt(Opts) ->
init_opts_for_build(Opts) ->
case Opts#options.output_plt =:= none of
true ->
- case Opts#options.init_plt of
- none -> Opts#options{init_plt = none, output_plt = get_default_plt()};
- Plt -> Opts#options{init_plt = none, output_plt = Plt}
+ case Opts#options.init_plts of
+ [] -> Opts#options{output_plt = get_default_output_plt()};
+ [Plt] -> Opts#options{init_plts = [], output_plt = Plt};
+ Plts ->
+ Msg = io_lib:format("Could not build multiple PLT files: ~s\n",
+ [format_plts(Plts)]),
+ error(Msg)
end;
- false -> Opts#options{init_plt = none}
+ false -> Opts#options{init_plts = []}
end.
%%--------------------------------------------------------------------
@@ -98,39 +102,58 @@ add_to_plt(Opts) ->
init_opts_for_add(Opts) ->
case Opts#options.output_plt =:= none of
true ->
- case Opts#options.init_plt of
- none -> Opts#options{output_plt = get_default_plt(),
- init_plt = get_default_plt()};
- Plt -> Opts#options{output_plt = Plt}
+ case Opts#options.init_plts of
+ [] -> Opts#options{output_plt = get_default_output_plt(),
+ init_plts = get_default_init_plt()};
+ [Plt] -> Opts#options{output_plt = Plt};
+ Plts ->
+ Msg = io_lib:format("Could not add to multiple PLT files: ~s\n",
+ [format_plts(Plts)]),
+ error(Msg)
end;
false ->
- case Opts#options.init_plt =:= none of
- true -> Opts#options{init_plt = get_default_plt()};
+ case Opts#options.init_plts =:= [] of
+ true -> Opts#options{init_plts = get_default_init_plt()};
false -> Opts
end
end.
%%--------------------------------------------------------------------
-check_plt(Opts) ->
+check_plt(#options{init_plts = []} = Opts) ->
Opts1 = init_opts_for_check(Opts),
- report_check(Opts),
- plt_common(Opts1, [], []).
+ report_check(Opts1),
+ plt_common(Opts1, [], []);
+check_plt(#options{init_plts = Plts} = Opts) ->
+ check_plt_aux(Plts, Opts).
+
+check_plt_aux([_] = Plt, Opts) ->
+ Opts1 = Opts#options{init_plts = Plt},
+ Opts2 = init_opts_for_check(Opts1),
+ report_check(Opts2),
+ plt_common(Opts2, [], []);
+check_plt_aux([Plt|Plts], Opts) ->
+ Opts1 = Opts#options{init_plts = [Plt]},
+ Opts2 = init_opts_for_check(Opts1),
+ report_check(Opts2),
+ plt_common(Opts2, [], []),
+ check_plt_aux(Plts, Opts).
init_opts_for_check(Opts) ->
- Plt =
- case Opts#options.init_plt of
- none -> get_default_plt();
- Plt0 -> Plt0
+ InitPlt =
+ case Opts#options.init_plts of
+ []-> get_default_init_plt();
+ Plt -> Plt
end,
+ [OutputPlt] = InitPlt,
Opts#options{files = [],
files_rec = [],
analysis_type = plt_check,
defines = [],
from = byte_code,
- init_plt = Plt,
+ init_plts = InitPlt,
include_dirs = [],
- output_plt = Plt,
+ output_plt = OutputPlt,
use_contracts = true
}.
@@ -144,21 +167,25 @@ remove_from_plt(Opts) ->
init_opts_for_remove(Opts) ->
case Opts#options.output_plt =:= none of
true ->
- case Opts#options.init_plt of
- none -> Opts#options{output_plt = get_default_plt(),
- init_plt = get_default_plt()};
- Plt -> Opts#options{output_plt = Plt}
+ case Opts#options.init_plts of
+ [] -> Opts#options{output_plt = get_default_output_plt(),
+ init_plts = get_default_init_plt()};
+ [Plt] -> Opts#options{output_plt = Plt};
+ Plts ->
+ Msg = io_lib:format("Could not remove from multiple PLT files: ~s\n",
+ [format_plts(Plts)]),
+ error(Msg)
end;
false ->
- case Opts#options.init_plt =:= none of
- true -> Opts#options{init_plt = get_default_plt()};
+ case Opts#options.init_plts =:= [] of
+ true -> Opts#options{init_plts = get_default_init_plt()};
false -> Opts
end
end.
%%--------------------------------------------------------------------
-plt_common(Opts, RemoveFiles, AddFiles) ->
+plt_common(#options{init_plts = [InitPlt]} = Opts, RemoveFiles, AddFiles) ->
case check_plt(Opts, RemoveFiles, AddFiles) of
ok ->
case Opts#options.report_mode of
@@ -174,7 +201,7 @@ plt_common(Opts, RemoveFiles, AddFiles) ->
report_failed_plt_check(Opts, DiffMd5),
{AnalFiles, RemovedMods, ModDeps1} =
expand_dependent_modules(Md5, DiffMd5, ModDeps),
- Plt = clean_plt(Opts#options.init_plt, RemovedMods),
+ Plt = clean_plt(InitPlt, RemovedMods),
case AnalFiles =:= [] of
true ->
%% Only removed stuff. Just write the PLT.
@@ -186,19 +213,19 @@ plt_common(Opts, RemoveFiles, AddFiles) ->
end;
{error, no_such_file} ->
Msg = io_lib:format("Could not find the PLT: ~s\n~s",
- [Opts#options.init_plt, default_plt_error_msg()]),
+ [InitPlt, default_plt_error_msg()]),
error(Msg);
{error, not_valid} ->
Msg = io_lib:format("The file: ~s is not a valid PLT file\n~s",
- [Opts#options.init_plt, default_plt_error_msg()]),
+ [InitPlt, default_plt_error_msg()]),
error(Msg);
{error, read_error} ->
Msg = io_lib:format("Could not read the PLT: ~s\n~s",
- [Opts#options.init_plt, default_plt_error_msg()]),
+ [InitPlt, default_plt_error_msg()]),
error(Msg);
{error, {no_file_to_remove, F}} ->
Msg = io_lib:format("Could not remove the file ~s from the PLT: ~s\n",
- [F, Opts#options.init_plt]),
+ [F, InitPlt]),
error(Msg)
end.
@@ -218,8 +245,7 @@ default_plt_error_msg() ->
%%--------------------------------------------------------------------
-check_plt(Opts, RemoveFiles, AddFiles) ->
- Plt = Opts#options.init_plt,
+check_plt(#options{init_plts = [Plt]} = Opts, RemoveFiles, AddFiles) ->
case dialyzer_plt:check_plt(Plt, RemoveFiles, AddFiles) of
{old_version, _MD5} = OldVersion ->
report_old_version(Opts),
@@ -234,14 +260,14 @@ check_plt(Opts, RemoveFiles, AddFiles) ->
%%--------------------------------------------------------------------
-report_check(#options{report_mode = ReportMode, init_plt = InitPlt}) ->
+report_check(#options{report_mode = ReportMode, init_plts = [InitPlt]}) ->
case ReportMode of
quiet -> ok;
_ ->
io:format(" Checking whether the PLT ~s is up-to-date...", [InitPlt])
end.
-report_old_version(#options{report_mode = ReportMode, init_plt = InitPlt}) ->
+report_old_version(#options{report_mode = ReportMode, init_plts = [InitPlt]}) ->
case ReportMode of
quiet -> ok;
_ ->
@@ -264,7 +290,7 @@ report_failed_plt_check(#options{analysis_type = AnalType,
report_analysis_start(#options{analysis_type = Type,
report_mode = ReportMode,
- init_plt = InitPlt,
+ init_plts = InitPlts,
output_plt = OutputPlt}) ->
case ReportMode of
quiet -> ok;
@@ -272,6 +298,7 @@ report_analysis_start(#options{analysis_type = Type,
io:format(" "),
case Type of
plt_add ->
+ [InitPlt] = InitPlts,
case InitPlt =:= OutputPlt of
true -> io:format("Adding information to ~s...", [OutputPlt]);
false -> io:format("Adding information from ~s to ~s...",
@@ -282,6 +309,7 @@ report_analysis_start(#options{analysis_type = Type,
plt_check ->
io:format("Rebuilding the information in ~s...", [OutputPlt]);
plt_remove ->
+ [InitPlt] = InitPlts,
case InitPlt =:= OutputPlt of
true -> io:format("Removing information from ~s...", [OutputPlt]);
false -> io:format("Removing information from ~s to ~s...",
@@ -320,16 +348,28 @@ report_md5_diff(List) ->
%%--------------------------------------------------------------------
-get_default_plt() ->
+get_default_init_plt() ->
+ [dialyzer_plt:get_default_plt()].
+
+get_default_output_plt() ->
dialyzer_plt:get_default_plt().
%%--------------------------------------------------------------------
+format_plts([Plt]) -> Plt;
+format_plts([Plt|Plts]) ->
+ Plt ++ ", " ++ format_plts(Plts).
+
+%%--------------------------------------------------------------------
+
do_analysis(Options) ->
Files = get_files_from_opts(Options),
- case Options#options.init_plt of
- none -> do_analysis(Files, Options, dialyzer_plt:new(), none);
- File -> do_analysis(Files, Options, dialyzer_plt:from_file(File), none)
+ case Options#options.init_plts of
+ [] -> do_analysis(Files, Options, dialyzer_plt:new(), none);
+ PltFiles ->
+ Plts = [dialyzer_plt:from_file(F) || F <- PltFiles],
+ Plt = dialyzer_plt:merge_plts_or_report_conflicts(PltFiles, Plts),
+ do_analysis(Files, Options, Plt, none)
end.
do_analysis(Files, Options, Plt, PltInfo) ->
@@ -559,7 +599,7 @@ cl_loop(State, LogCache) ->
cl_loop(State, LogCache)
end.
--spec failed_anal_msg(string(), [_]) -> string().
+-spec failed_anal_msg(string(), [_]) -> nonempty_string().
failed_anal_msg(Reason, LogCache) ->
Msg = "Analysis failed with error: " ++ Reason ++ "\n",
diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl
index 0160b84abc..5ca7599b35 100644
--- a/lib/dialyzer/src/dialyzer_cl_parse.erl
+++ b/lib/dialyzer/src/dialyzer_cl_parse.erl
@@ -138,11 +138,17 @@ cl(["-pa", Path|T]) ->
true -> cl(T);
{error, _} -> error("Bad directory for -pa: "++Path)
end;
-cl(["--plt", PLT|T]) ->
- put(dialyzer_init_plt, PLT),
- cl(T);
cl(["--plt"]) ->
error("No plt specified for --plt");
+cl(["--plt", PLT|T]) ->
+ put(dialyzer_init_plts, [PLT]),
+ cl(T);
+cl(["--plts"]) ->
+ error("No plts specified for --plts");
+cl(["--plts"|T]) ->
+ {PLTs, NewT} = get_plts(T, []),
+ put(dialyzer_init_plts, PLTs),
+ cl(NewT);
cl(["-q"|T]) ->
put(dialyzer_options_report_mode, quiet),
cl(T);
@@ -284,7 +290,7 @@ common_options() ->
[{defines, get(dialyzer_options_defines)},
{from, get(dialyzer_options_from)},
{include_dirs, get(dialyzer_include)},
- {init_plt, get(dialyzer_init_plt)},
+ {plts, get(dialyzer_init_plts)},
{output_plt, get(dialyzer_output_plt)},
{report_mode, get(dialyzer_options_report_mode)},
{use_spec, get(dialyzer_options_use_contracts)},
@@ -309,6 +315,13 @@ get_lib_dir([], Acc) ->
%%-----------------------------------------------------------------------
+get_plts(["--"|T], Acc) -> {lists:reverse(Acc), T};
+get_plts(["-"++_Opt = H|T], Acc) -> {lists:reverse(Acc), [H|T]};
+get_plts([H|T], Acc) -> get_plts(T, [H|Acc]);
+get_plts([], Acc) -> {lists:reverse(Acc), []}.
+
+%%-----------------------------------------------------------------------
+
help_warnings() ->
S = warning_options_msg(),
io:put_chars(S),
@@ -316,9 +329,10 @@ help_warnings() ->
help_message() ->
S = "Usage: dialyzer [--help] [--version] [--shell] [--quiet] [--verbose]
- [-pa dir]* [--plt plt] [-Ddefine]* [-I include_dir]*
- [--output_plt file] [-Wwarn]* [--src] [--gui | --wx]
- [files_or_dirs] [-r dirs] [--apps applications] [-o outfile]
+ [-pa dir]* [--plt plt] [--plts plt*] [-Ddefine]*
+ [-I include_dir]* [--output_plt file] [-Wwarn]*
+ [--src] [--gui | --wx] [files_or_dirs] [-r dirs]
+ [--apps applications] [-o outfile]
[--build_plt] [--add_to_plt] [--remove_from_plt]
[--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
[--no_native]
@@ -326,13 +340,13 @@ Options:
files_or_dirs (for backwards compatibility also as: -c files_or_dirs)
Use Dialyzer from the command line to detect defects in the
specified files or directories containing .erl or .beam files,
- depending on the type of the analysis
+ depending on the type of the analysis.
-r dirs
Same as the previous but the specified directories are searched
recursively for subdirectories containing .erl or .beam files in
- them, depending on the type of analysis
+ them, depending on the type of analysis.
--apps applications
- Option typically used when building or modifying a PLT as in:
+ Option typically used when building or modifying a plt as in:
dialyzer --build_plt --apps erts kernel stdlib mnesia ...
to conveniently refer to library applications corresponding to the
Erlang/OTP installation. However, the option is general and can also
@@ -341,73 +355,86 @@ Options:
dialyzer --apps inets ssl ./ebin ../other_lib/ebin/my_module.beam
-o outfile (or --output outfile)
When using Dialyzer from the command line, send the analysis
- results to the specified \"outfile\" rather than to stdout
+ results to the specified outfile rather than to stdout.
--raw
When using Dialyzer from the command line, output the raw analysis
results (Erlang terms) instead of the formatted result.
The raw format is easier to post-process (for instance, to filter
- warnings or to output HTML pages)
+ warnings or to output HTML pages).
--src
Override the default, which is to analyze BEAM files, and
- analyze starting from Erlang source code instead
+ analyze starting from Erlang source code instead.
-Dname (or -Dname=value)
- When analyzing from source, pass the define to Dialyzer (**)
+ When analyzing from source, pass the define to Dialyzer. (**)
-I include_dir
- When analyzing from source, pass the include_dir to Dialyzer (**)
+ When analyzing from source, pass the include_dir to Dialyzer. (**)
-pa dir
Include dir in the path for Erlang (useful when analyzing files
- that have '-include_lib()' directives)
+ that have '-include_lib()' directives).
--output_plt file
- Store the plt at the specified file after building it
+ Store the plt at the specified file after building it.
--plt plt
Use the specified plt as the initial plt (if the plt was built
- during setup the files will be checked for consistency)
+ during setup the files will be checked for consistency).
+ --plts plt*
+ Merge the specified plts to create the initial plt -- requires
+ that the plts are disjoint (i.e., do not have any module
+ appearing in more than one plt).
+ The plts are created in the usual way:
+ dialyzer --build_plt --output_plt plt_1 files_to_include
+ ...
+ dialyzer --build_plt --output_plt plt_n files_to_include
+ and then can be used in either of the following ways:
+ dialyzer files_to_analyze --plts plt_1 ... plt_n
+ or:
+ dialyzer --plts plt_1 ... plt_n -- files_to_analyze
+ (Note the -- delimiter in the second case)
-Wwarn
A family of options which selectively turn on/off warnings
- (for help on the names of warnings use dialyzer -Whelp)
+ (for help on the names of warnings use dialyzer -Whelp).
--shell
- Do not disable the Erlang shell while running the GUI
+ Do not disable the Erlang shell while running the GUI.
--version (or -v)
- Prints the Dialyzer version and some more information and exits
+ Print the Dialyzer version and some more information and exit.
--help (or -h)
- Prints this message and exits
+ Print this message and exit.
--quiet (or -q)
- Makes Dialyzer a bit more quiet
+ Make Dialyzer a bit more quiet.
--verbose
- Makes Dialyzer a bit more verbose
+ Make Dialyzer a bit more verbose.
--build_plt
The analysis starts from an empty plt and creates a new one from the
files specified with -c and -r. Only works for beam files.
- Use --plt or --output_plt to override the default plt location.
+ Use --plt(s) or --output_plt to override the default plt location.
--add_to_plt
The plt is extended to also include the files specified with -c and -r.
- Use --plt to specify wich plt to start from, and --output_plt to
- specify where to put the plt. Note that the analysis might include
- files from the plt if they depend on the new files.
+ Use --plt(s) to specify which plt to start from, and --output_plt to
+ specify where to put the plt. Note that the analysis might include
+ files from the plt if they depend on the new files.
This option only works with beam files.
--remove_from_plt
The information from the files specified with -c and -r is removed
from the plt. Note that this may cause a re-analysis of the remaining
dependent files.
--check_plt
- Checks the plt for consistency and rebuilds it if it is not up-to-date.
+ Check the plt for consistency and rebuild it if it is not up-to-date.
Actually, this option is of rare use as it is on by default.
--no_check_plt (or -n)
Skip the plt check when running Dialyzer. Useful when working with
installed plts that never change.
--plt_info
- Makes Dialyzer print information about the plt and then quit. The plt
- can be specified with --plt.
+ Make Dialyzer print information about the plt and then quit. The plt
+ can be specified with --plt(s).
--get_warnings
- Makes Dialyzer emit warnings even when manipulating the plt. Only
- emits warnings for files that are actually analyzed.
+ Make Dialyzer emit warnings even when manipulating the plt. Warnings
+ are only emitted for files that are actually analyzed.
--dump_callgraph file
Dump the call graph into the specified file whose format is determined
by the file name extension. Supported extensions are: raw, dot, and ps.
If something else is used as file name extension, default format '.raw'
will be used.
--no_native (or -nn)
- Bypass the native code compilation of some key files that dialyzer
+ Bypass the native code compilation of some key files that Dialyzer
heuristically performs when dialyzing many files; this avoids the
compilation time but it may result in (much) longer analysis time.
--gui
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index bf80c6f470..bcdcf2685d 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -163,20 +163,23 @@ process_contract_remote_types(CodeServer) ->
check_contracts(Contracts, Callgraph, FunTypes) ->
FoldFun =
fun(Label, Type, NewContracts) ->
- {ok, {M,F,A} = MFA} = dialyzer_callgraph:lookup_name(Label, Callgraph),
- case orddict:find(MFA, Contracts) of
- {ok, {_FileLine, Contract}} ->
- case check_contract(Contract, Type) of
- ok ->
- case erl_bif_types:is_known(M, F, A) of
- true ->
- %% Disregard the contracts since
- %% this is a known function.
- NewContracts;
- false ->
- [{MFA, Contract}|NewContracts]
+ case dialyzer_callgraph:lookup_name(Label, Callgraph) of
+ {ok, {M,F,A} = MFA} ->
+ case orddict:find(MFA, Contracts) of
+ {ok, {_FileLine, Contract}} ->
+ case check_contract(Contract, Type) of
+ ok ->
+ case erl_bif_types:is_known(M, F, A) of
+ true ->
+ %% Disregard the contracts since
+ %% this is a known function.
+ NewContracts;
+ false ->
+ [{MFA, Contract}|NewContracts]
+ end;
+ {error, _Error} -> NewContracts
end;
- {error, _Error} -> NewContracts
+ error -> NewContracts
end;
error -> NewContracts
end
diff --git a/lib/dialyzer/src/dialyzer_gui.erl b/lib/dialyzer/src/dialyzer_gui.erl
index f353638cdf..4436330f7f 100644
--- a/lib/dialyzer/src/dialyzer_gui.erl
+++ b/lib/dialyzer/src/dialyzer_gui.erl
@@ -88,8 +88,8 @@
-spec start(#options{}) -> ?RET_NOTHING_SUSPICIOUS.
-start(DialyzerOptions = #options{from = From, init_plt = InitPltFile,
- legal_warnings = LegalWarnings}) ->
+start(#options{from = From, init_plts = InitPltFiles,
+ legal_warnings = LegalWarnings} = DialyzerOptions) ->
process_flag(trap_exit, true),
GS = gs:start(),
@@ -336,9 +336,13 @@ start(DialyzerOptions = #options{from = From, init_plt = InitPltFile,
gs:config(Packer, WH),
{ok, CWD} = file:get_cwd(),
- InitPlt = try dialyzer_plt:from_file(InitPltFile)
- catch throw:{dialyzer_error, _} -> dialyzer_plt:new()
- end,
+ InitPlt =
+ case InitPltFiles of
+ [] -> dialyzer_plt:new();
+ _ ->
+ Plts = [dialyzer_plt:from_file(F) || F <- InitPltFiles],
+ dialyzer_plt:merge_plts_or_report_conflicts(InitPltFiles, Plts)
+ end,
State = #gui_state{add_all = AddAll,
add_file = AddFile,
diff --git a/lib/dialyzer/src/dialyzer_gui_wx.erl b/lib/dialyzer/src/dialyzer_gui_wx.erl
index 2e309d7ec1..e711c15ea7 100644
--- a/lib/dialyzer/src/dialyzer_gui_wx.erl
+++ b/lib/dialyzer/src/dialyzer_gui_wx.erl
@@ -88,7 +88,7 @@ start(DialyzerOptions) ->
State = wx:batch(fun() -> create_window(Wx, DialyzerOptions) end),
gui_loop(State).
-create_window(Wx, DialyzerOptions) ->
+create_window(Wx, #options{init_plts = InitPltFiles} = DialyzerOptions) ->
{ok, Host} = inet:gethostname(),
%%---------- initializing frame ---------
@@ -258,11 +258,15 @@ create_window(Wx, DialyzerOptions) ->
plt = PltMenu,
options =OptionsMenu,
help = HelpMenu},
-
- InitPlt = try dialyzer_plt:from_file(DialyzerOptions#options.init_plt)
- catch throw:{dialyzer_error, _} -> dialyzer_plt:new()
- end,
+ InitPlt =
+ case InitPltFiles of
+ [] -> dialyzer_plt:new();
+ _ ->
+ Plts = [dialyzer_plt:from_file(F) || F <- InitPltFiles],
+ dialyzer_plt:merge_plts_or_report_conflicts(InitPltFiles, Plts)
+ end,
+
#gui_state{add = AddButton,
add_dir = AddDirButton,
add_rec = AddRecButton,
diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl
index 010625b7bd..2c0afa6e2b 100644
--- a/lib/dialyzer/src/dialyzer_options.erl
+++ b/lib/dialyzer/src/dialyzer_options.erl
@@ -53,14 +53,21 @@ build(Opts) ->
InitPlt = dialyzer_plt:get_default_plt(),
DefaultOpts = #options{},
DefaultOpts1 = DefaultOpts#options{legal_warnings = DefaultWarns1,
- init_plt = InitPlt},
- try
- NewOpts = build_options(Opts, DefaultOpts1),
+ init_plts = [InitPlt]},
+ try
+ Opts1 = preprocess_opts(Opts),
+ NewOpts = build_options(Opts1, DefaultOpts1),
postprocess_opts(NewOpts)
catch
throw:{dialyzer_options_error, Msg} -> {error, Msg}
end.
+preprocess_opts([]) -> [];
+preprocess_opts([{init_plt, File}|Opts]) ->
+ [{plts, [File]}|preprocess_opts(Opts)];
+preprocess_opts([Opt|Opts]) ->
+ [Opt|preprocess_opts(Opts)].
+
postprocess_opts(Opts = #options{}) ->
Opts1 = check_output_plt(Opts),
adapt_get_warnings(Opts1).
@@ -144,9 +151,9 @@ build_options([{OptionName, Value} = Term|Rest], Options) ->
build_options(Rest, Options#options{from = Value});
get_warnings ->
build_options(Rest, Options#options{get_warnings = Value});
- init_plt ->
- assert_filenames([Term], [Value]),
- build_options(Rest, Options#options{init_plt = Value});
+ plts ->
+ assert_filenames(Term, Value),
+ build_options(Rest, Options#options{init_plts = Value});
include_dirs ->
assert_filenames(Term, Value),
OldVal = Options#options.include_dirs,
diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl
index 0f5be3b7f2..a7ba270c41 100644
--- a/lib/dialyzer/src/dialyzer_plt.erl
+++ b/lib/dialyzer/src/dialyzer_plt.erl
@@ -51,6 +51,7 @@
lookup_contract/2,
lookup_module/2,
merge_plts/1,
+ merge_plts_or_report_conflicts/2,
new/0,
plt_and_info_from_file/1,
get_specs/1,
@@ -244,9 +245,10 @@ from_file(FileName, ReturnInfo) ->
[FileName, Reason]))
end.
--type inc_file_err_rsn() :: 'no_such_file' | 'read_error'.
+-type err_rsn() :: 'not_valid' | 'no_such_file' | 'read_error'.
+
-spec included_files(file:filename()) -> {'ok', [file:filename()]}
- | {'error', inc_file_err_rsn()}.
+ | {'error', err_rsn()}.
included_files(FileName) ->
case get_record_from_file(FileName) of
@@ -291,6 +293,38 @@ merge_plts(List) ->
exported_types = sets_merge(ExpTypesList),
contracts = table_merge(ContractsList)}.
+-spec merge_disj_plts([plt()]) -> plt().
+
+merge_disj_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_disj_merge(InfoList),
+ types = table_disj_merge(TypesList),
+ exported_types = sets_disj_merge(ExpTypesList),
+ contracts = table_disj_merge(ContractsList)}.
+
+-spec merge_plts_or_report_conflicts([file:filename()], [plt()]) -> plt().
+
+merge_plts_or_report_conflicts(PltFiles, Plts) ->
+ try
+ merge_disj_plts(Plts)
+ catch throw:{dialyzer_error, not_disjoint_plts} ->
+ IncFiles = lists:append([begin {ok, Fs} = included_files(F), Fs end
+ || F <- PltFiles]),
+ ConfFiles = find_duplicates(IncFiles),
+ Msg = io_lib:format("Could not merge PLTs since they are not disjoint\n"
+ "The following files are included in more than one "
+ "PLTs:\n~p\n", [ConfFiles]),
+ error(Msg)
+ end.
+
+find_duplicates(List) ->
+ ModList = [filename:basename(E) || E <- List],
+ SortedList = lists:usort(ModList),
+ lists:usort(ModList -- SortedList).
+
-spec to_file(file:filename(), plt(), mod_deps(), {[file_md5()], mod_deps()}) -> 'ok'.
to_file(FileName,
@@ -320,8 +354,7 @@ to_file(FileName,
end.
-type md5_diff() :: [{'differ', atom()} | {'removed', atom()}].
--type check_error() :: 'not_valid' | 'no_such_file' | 'read_error'
- | {'no_file_to_remove', file:filename()}.
+-type check_error() :: err_rsn() | {'no_file_to_remove', file:filename()}.
-spec check_plt(file:filename(), [file:filename()], [file:filename()]) ->
'ok'
@@ -556,6 +589,25 @@ table_merge([Plt|Plts], Acc) ->
NewAcc = dict:merge(fun(_Key, Val, Val) -> Val end, Plt, Acc),
table_merge(Plts, NewAcc).
+table_disj_merge([H|T]) ->
+ table_disj_merge(T, H).
+
+table_disj_merge([], Acc) ->
+ Acc;
+table_disj_merge([Plt|Plts], Acc) ->
+ case table_is_disjoint(Plt, Acc) of
+ true ->
+ NewAcc = dict:merge(fun(_Key, _Val1, _Val2) -> gazonk end,
+ Plt, Acc),
+ table_disj_merge(Plts, NewAcc);
+ false -> throw({dialyzer_error, not_disjoint_plts})
+ end.
+
+table_is_disjoint(T1, T2) ->
+ K1 = dict:fetch_keys(T1),
+ K2 = dict:fetch_keys(T2),
+ lists:all(fun(E) -> not lists:member(E, K2) end, K1).
+
sets_merge([H|T]) ->
sets_merge(T, H).
@@ -565,6 +617,19 @@ sets_merge([Plt|Plts], Acc) ->
NewAcc = sets:union(Plt, Acc),
sets_merge(Plts, NewAcc).
+sets_disj_merge([H|T]) ->
+ sets_disj_merge(T, H).
+
+sets_disj_merge([], Acc) ->
+ Acc;
+sets_disj_merge([Plt|Plts], Acc) ->
+ case sets:is_disjoint(Plt, Acc) of
+ true ->
+ NewAcc = sets:union(Plt, Acc),
+ sets_disj_merge(Plts, NewAcc);
+ false -> throw({dialyzer_error, not_disjoint_plts})
+ end.
+
%%---------------------------------------------------------------------------
%% Debug utilities.
diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl
index ec8d613b96..ee9d5e88a3 100644
--- a/lib/dialyzer/src/dialyzer_races.erl
+++ b/lib/dialyzer/src/dialyzer_races.erl
@@ -118,7 +118,7 @@
var_map :: dict()}).
-type case_tags() :: 'beg_case' | #beg_clause{} | #end_clause{} | #end_case{}.
--type code() :: [#dep_call{} | #warn_call{} | #fun_call{} |
+-type code() :: [#dep_call{} | #fun_call{} | #warn_call{} |
#curr_fun{} | #let_tag{} | case_tags() | race_tag()].
-type table_var() :: label() | ?no_label.
@@ -479,23 +479,11 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList,
_Other ->
{RaceList, [], NestingLevel, false}
end;
- #dep_call{call_name = ets_lookup, args = DepCallArgs} ->
+ #dep_call{call_name = ets_lookup} ->
case RaceWarnTag of
?WARN_ETS_LOOKUP_INSERT ->
- [Tab, Names, _, _] = DepCallArgs,
- case compare_var_list(Tab,
- dialyzer_callgraph:get_public_tables(Callgraph),
- RaceVarMap)
- orelse
- length(Names --
- dialyzer_callgraph:get_named_tables(Callgraph)) <
- length(Names) of
- true ->
- {[Head#dep_call{var_map = RaceVarMap}|RaceList],
- [], NestingLevel, false};
- false ->
- {RaceList, [], NestingLevel, false}
- end;
+ {[Head#dep_call{var_map = RaceVarMap}|RaceList],
+ [], NestingLevel, false};
_Other ->
{RaceList, [], NestingLevel, false}
end;
@@ -517,23 +505,11 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList,
_Other ->
{RaceList, [], NestingLevel, false}
end;
- #warn_call{call_name = ets_insert, args = WarnCallArgs} ->
+ #warn_call{call_name = ets_insert} ->
case RaceWarnTag of
?WARN_ETS_LOOKUP_INSERT ->
- [Tab, Names, _, _] = WarnCallArgs,
- case compare_var_list(Tab,
- dialyzer_callgraph:get_public_tables(Callgraph),
- RaceVarMap)
- orelse
- length(Names --
- dialyzer_callgraph:get_named_tables(Callgraph)) <
- length(Names) of
- true ->
- {[Head#warn_call{var_map = RaceVarMap}|RaceList],
- [], NestingLevel, false};
- false ->
- {RaceList, [], NestingLevel, false}
- end;
+ {[Head#warn_call{var_map = RaceVarMap}|RaceList],
+ [], NestingLevel, false};
_Other ->
{RaceList, [], NestingLevel, false}
end;
diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl
index 3effb1c2e6..c45615d670 100644
--- a/lib/dialyzer/src/dialyzer_typesig.erl
+++ b/lib/dialyzer/src/dialyzer_typesig.erl
@@ -314,6 +314,7 @@ traverse(Tree, DefinedVars, State) ->
error -> t_fun(length(Vars), t_none());
{ok, Dom} -> t_fun(Dom, t_none())
end,
+ TreeVar = mk_var(Tree),
State2 =
try
State1 = case state__add_prop_constrs(Tree, State0) of
@@ -321,20 +322,21 @@ traverse(Tree, DefinedVars, State) ->
PropState -> PropState
end,
{BodyState, BodyVar} = traverse(Body, DefinedVars1, State1),
- state__store_conj(mk_var(Tree), eq,
+ state__store_conj(TreeVar, eq,
t_fun(mk_var_list(Vars), BodyVar), BodyState)
catch
throw:error ->
- state__store_conj(mk_var(Tree), eq, FunFailType, State0)
+ state__store_conj(TreeVar, eq, FunFailType, State0)
end,
Cs = state__cs(State2),
- State3 = state__store_constrs(mk_var(Tree), Cs, State2),
- Ref = mk_constraint_ref(mk_var(Tree), get_deps(Cs)),
+ State3 = state__store_constrs(TreeVar, Cs, State2),
+ Ref = mk_constraint_ref(TreeVar, get_deps(Cs)),
OldCs = state__cs(State),
State4 = state__new_constraint_context(State3),
State5 = state__store_conj_list([OldCs, Ref], State4),
State6 = state__store_fun_arity(Tree, State5),
- {State6, mk_var(Tree)};
+ State7 = state__add_fun_to_scc(TreeVar, State6),
+ {State7, TreeVar};
'let' ->
Vars = cerl:let_vars(Tree),
Arg = cerl:let_arg(Tree),
@@ -580,7 +582,7 @@ handle_try(Tree, DefinedVars, State) ->
mk_conj_constraint_list([HandlerCs,
mk_constraint(TreeVar, eq, HandlerVar)]),
Disj = mk_disj_constraint_list([Conj1, Conj2]),
- {Disj, mk_var(Tree)};
+ {Disj, TreeVar};
{false, true} ->
{mk_conj_constraint_list([ArgBodyCs,
mk_constraint(TreeVar, eq, BodyVar)]),
@@ -1404,9 +1406,13 @@ get_bif_constr({erlang, 'or', 2}, Dst, [Arg1, Arg2] = Args, _State) ->
ArgV1 = mk_fun_var(ArgFun(Arg2), [Arg2, Dst]),
ArgV2 = mk_fun_var(ArgFun(Arg1), [Arg1, Dst]),
DstV = mk_fun_var(DstFun, Args),
- Disj = mk_disj_constraint_list([mk_constraint(Arg1, sub, True),
- mk_constraint(Arg2, sub, True),
- mk_constraint(Dst, sub, False)]),
+ F = fun(A) ->
+ try [mk_constraint(A, sub, True)]
+ catch throw:error -> []
+ end
+ end,
+ Constrs = F(Arg1) ++ F(Arg2),
+ Disj = mk_disj_constraint_list([mk_constraint(Dst, sub, False)|Constrs]),
mk_conj_constraint_list([mk_constraint(Dst, sub, DstV),
mk_constraint(Arg1, sub, ArgV1),
mk_constraint(Arg2, sub, ArgV2),
@@ -2070,7 +2076,7 @@ new_state(SCC0, NextLabel, CallGraph, Plt, PropTypes) ->
NameMap = dict:from_list([{MFA, Var} || {MFA, {Var, _Fun}, _Rec} <- SCC0]),
SCC = [mk_var(Fun) || {_MFA, {_Var, Fun}, _Rec} <- SCC0],
#state{callgraph = CallGraph, name_map = NameMap, next_label = NextLabel,
- prop_types = PropTypes, plt = Plt, scc = SCC}.
+ prop_types = PropTypes, plt = Plt, scc = ordsets:from_list(SCC)}.
state__set_rec_dict(State, RecDict) ->
State#state{records = RecDict}.
@@ -2161,6 +2167,9 @@ get_apply_constr(FunLabels, Dst, ArgTypes, #state{callgraph = CG} = State) ->
state__scc(#state{scc = SCC}) ->
SCC.
+state__add_fun_to_scc(Fun, #state{scc = SCC} = State) ->
+ State#state{scc = ordsets:add_element(Fun, SCC)}.
+
state__plt(#state{plt = PLT}) ->
PLT.
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index a9da229061..248fdf6835 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -66,7 +66,7 @@ print_types1([{opaque, _Name} = Key|T], RecDict) ->
io:format("\n~w: ~w\n", [Key, erl_types:t_from_form(Form, RecDict)]),
print_types1(T, RecDict);
print_types1([{record, _Name} = Key|T], RecDict) ->
- {ok, [{Arity, Fields} = AF]} = dict:find(Key, RecDict),
+ {ok, [{_Arity, _Fields} = AF]} = dict:find(Key, RecDict),
io:format("~w: ~w\n\n", [Key, AF]),
print_types1(T, RecDict).
-define(debug(D_), print_types(D_)).
@@ -211,9 +211,9 @@ get_record_and_type_info([_Other|Left], Module, Records, RecDict) ->
get_record_and_type_info([], _Module, Records, RecDict) ->
case type_record_fields(lists:reverse(Records), RecDict) of
{ok, _NewRecDict} = Ok ->
- ?debug(NewRecDict),
+ ?debug(_NewRecDict),
Ok;
- {Name, {error, Error}} ->
+ {error, Name, Error} ->
{error, lists:flatten(io_lib:format(" Error while parsing #~w{}: ~s\n",
[Name, Error]))}
end.
@@ -269,9 +269,9 @@ type_record_fields([RecKey|Recs], RecDict) ->
RecDict2 = dict:update(RecKey, Fun, RecDict1),
type_record_fields(Recs, RecDict2)
catch
- throw:{error, _} = Error ->
+ throw:{error, Error} ->
{record, Name} = RecKey,
- {Name, Error}
+ {error, Name, Error}
end.
-spec process_record_remote_types(dialyzer_codeserver:codeserver()) -> dialyzer_codeserver:codeserver().
@@ -378,7 +378,7 @@ sets_filter([Mod|Mods], ExpTypes) ->
-spec src_compiler_opts() -> [compile:option(),...].
src_compiler_opts() ->
- [no_copt, to_core, binary, return_errors,
+ [no_copt, to_core, binary, return_errors,
no_inline, strict_record_tests, strict_record_updates,
no_is_record_optimization].
diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk
index d3574e0a71..b2902e95ed 100644
--- a/lib/dialyzer/vsn.mk
+++ b/lib/dialyzer/vsn.mk
@@ -1 +1 @@
-DIALYZER_VSN = 2.3.1
+DIALYZER_VSN = 2.4.0
diff --git a/lib/docbuilder/doc/src/notes.xml b/lib/docbuilder/doc/src/notes.xml
index 019cf1b083..4b8c04f323 100644
--- a/lib/docbuilder/doc/src/notes.xml
+++ b/lib/docbuilder/doc/src/notes.xml
@@ -31,6 +31,21 @@
<p>This document describes the changes made to the DocBuilder
application.</p>
+<section><title>Docbuilder 0.9.8.9</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Fix compatibility issues with docbuilder for R11
+ documentation patches. </p>
+ <p>
+ Own Id: OTP-8946</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Docbuilder 0.9.8.8</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/docbuilder/src/docb_main.erl b/lib/docbuilder/src/docb_main.erl
index 87a1401a02..4f5f035a65 100644
--- a/lib/docbuilder/src/docb_main.erl
+++ b/lib/docbuilder/src/docb_main.erl
@@ -34,14 +34,23 @@
%% Parses the source file File and transforms the result to html,
%% latex and/or man page format.
process(File, Opts) ->
-
- File1 = File ++ ".tmpconv",
- os:cmd("sed -e 's/xi:include[ \t]*href/include file/g' -e 's/xmlns:xi=\"http:\\/\\/www.w3.org\\/2001\\/XInclude\"//g' < " ++
- File ++ ".xml > " ++ File1 ++ ".xml"), %LATH
+
+ SrcType = docb_util:lookup_option(src_type, Opts),
+
+ File1 =
+ case SrcType of
+ ".xml" ->
+ FileTmp = File ++ ".tmpconv",
+ os:cmd("sed -e 's/xi:include[ \t]*href/include file/g' -e 's/xmlns:xi=\"http:\\/\\/www.w3.org\\/2001\\/XInclude\"//g' < " ++
+ File ++ ".xml > " ++ FileTmp ++ ".xml"),
+ FileTmp;
+ ".sgml" ->
+ File
+ end,
case parse1(File1, Opts) of
errors ->
- file:delete(File1 ++ ".xml"),
+ delete_tmp_file(SrcType, File1),
errors;
{ok, Tree} ->
From = element(1, Tree),
@@ -62,15 +71,21 @@ process(File, Opts) ->
Result = [transform(From, To, Opts, File, Tree)||To <- Tos],
case lists:member(transformation_error,Result) of
true ->
- file:delete(File1 ++ ".xml"),
+ delete_tmp_file(SrcType, File1),
errors;
_ ->
- file:delete(File1 ++ ".xml"),
+ delete_tmp_file(SrcType, File1),
ok
end
end.
+
+delete_tmp_file(".xml", File) ->
+ file:delete(File ++ ".xml");
+delete_tmp_file(_, _) ->
+ ok.
+
%%----------------------------------------------------------------------
%% parse(File, Opts) -> {ok, Tree} | errors
diff --git a/lib/docbuilder/test/Makefile b/lib/docbuilder/test/Makefile
index 080479ee71..96b940033e 100644
--- a/lib/docbuilder/test/Makefile
+++ b/lib/docbuilder/test/Makefile
@@ -71,7 +71,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(SPEC_FILES) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SPEC_FILES) docb.cover $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/docbuilder/test/docb.cover b/lib/docbuilder/test/docb.cover
new file mode 100644
index 0000000000..80bab6eba7
--- /dev/null
+++ b/lib/docbuilder/test/docb.cover
@@ -0,0 +1,2 @@
+{incl_app,docbuilder,details}
+
diff --git a/lib/docbuilder/test/docb_SUITE.erl b/lib/docbuilder/test/docb_SUITE.erl
index c871130521..d286824539 100644
--- a/lib/docbuilder/test/docb_SUITE.erl
+++ b/lib/docbuilder/test/docb_SUITE.erl
@@ -17,13 +17,32 @@
%%
-module(docb_SUITE).
--export([all/1,html/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2,html/1]).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("kernel/include/file.hrl").
-all(suite) -> [html].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+[html].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
html(suite) -> [];
html(Config) when is_list(Config) ->
diff --git a/lib/docbuilder/vsn.mk b/lib/docbuilder/vsn.mk
index b23ee521c7..1209b80d94 100644
--- a/lib/docbuilder/vsn.mk
+++ b/lib/docbuilder/vsn.mk
@@ -1 +1 @@
-DOCB_VSN = 0.9.8.8
+DOCB_VSN = 0.9.8.9
diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml
index 83ad27ed31..afcccf22b5 100644
--- a/lib/edoc/doc/src/notes.xml
+++ b/lib/edoc/doc/src/notes.xml
@@ -31,6 +31,21 @@
<p>This document describes the changes made to the EDoc
application.</p>
+<section><title>Edoc 0.7.6.8</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Compiler warnings were eliminated.</p>
+ <p>
+ Own Id: OTP-8855</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Edoc 0.7.6.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/edoc/src/edoc_layout.erl b/lib/edoc/src/edoc_layout.erl
index 900f0b3040..6cc2f5cd9b 100644
--- a/lib/edoc/src/edoc_layout.erl
+++ b/lib/edoc/src/edoc_layout.erl
@@ -482,7 +482,7 @@ local_defs([]) -> [];
local_defs(Es) ->
[?NL,
{ul, [{class, "definitions"}],
- lists:concat([[{li, [{tt, localdef(E)}]}, ?NL] || E <- Es])}].
+ lists:append([[{li, [{tt, localdef(E)}]}, ?NL] || E <- Es])}].
localdef(E = #xmlElement{content = Es}) ->
(case get_elem(typevar, Es) of
diff --git a/lib/edoc/src/edoc_lib.erl b/lib/edoc/src/edoc_lib.erl
index 5b7fb1e0d2..c1f95a7a67 100644
--- a/lib/edoc/src/edoc_lib.erl
+++ b/lib/edoc/src/edoc_lib.erl
@@ -288,11 +288,13 @@ parse_expr(S, L) ->
%% content in e.g.
%% <a href="overview-summary.html#mtag-author">`@author'</a> tags.
-%% @type info() = #info{name = string(),
-%% mail = string(),
-%% uri = string()}
+%% @type info() = #info{name = string(),
+%% email = string(),
+%% uri = string()}
--record(info, {name = "", email = "", uri = ""}).
+-record(info, {name = "" :: string(),
+ email = "" :: string(),
+ uri = "" :: string()}).
parse_contact(S, L) ->
I = scan_name(S, L, #info{}, []),
@@ -988,6 +990,14 @@ get_plugin(Key, Default, Opts) ->
%% ---------------------------------------------------------------------
%% Error handling
+-type line() :: erl_scan:line().
+-type err() :: 'eof'
+ | {'missing', char()}
+ | {line(), atom(), string()}
+ | string().
+
+-spec throw_error(err(), line()) -> no_return().
+
throw_error({missing, C}, L) ->
throw_error({"missing '~c'.", [C]}, L);
throw_error(eof, L) ->
diff --git a/lib/edoc/src/edoc_macros.erl b/lib/edoc/src/edoc_macros.erl
index 2874e2940c..5b512cb53a 100644
--- a/lib/edoc/src/edoc_macros.erl
+++ b/lib/edoc/src/edoc_macros.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @private
%% @copyright 2001-2005 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -317,6 +315,14 @@ macro_content([C | Cs], As, L, N) ->
macro_content([], _As, _L, _N) ->
throw('end').
+-type line() :: erl_scan:line().
+-type err() :: 'unterminated_macro'
+ | 'macro_name'
+ | {'macro_name', string()}
+ | {string(), [string()]}.
+
+-spec throw_error(line(), err()) -> no_return().
+
throw_error(L, unterminated_macro) ->
throw_error(L, {"unexpected end of macro.", []});
throw_error(L, macro_name) ->
diff --git a/lib/edoc/src/edoc_parser.yrl b/lib/edoc/src/edoc_parser.yrl
index 0eea8ae66f..91ee5a1b2b 100644
--- a/lib/edoc/src/edoc_parser.yrl
+++ b/lib/edoc/src/edoc_parser.yrl
@@ -404,6 +404,8 @@ parse_throws(S, L) ->
%% ---------------------------------------------------------------------
+-spec throw_error(term(), erl_scan:line()) -> no_return().
+
throw_error({L, M, D}, _L0) ->
throw({error,L,{format_error,M,D}});
throw_error({parse_spec, E}, L) ->
diff --git a/lib/edoc/src/edoc_refs.erl b/lib/edoc/src/edoc_refs.erl
index c2146bbe02..edc30674c0 100644
--- a/lib/edoc/src/edoc_refs.erl
+++ b/lib/edoc/src/edoc_refs.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @private
%% @copyright 2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/edoc/src/edoc_tags.erl b/lib/edoc/src/edoc_tags.erl
index 1f2cb99c75..c0b861e08a 100644
--- a/lib/edoc/src/edoc_tags.erl
+++ b/lib/edoc/src/edoc_tags.erl
@@ -330,6 +330,10 @@ parse_typedef(Data, Line, _Env, _Where) ->
Def
end.
+-type line() :: erl_scan:line().
+
+-spec parse_file(_, line(), _, _) -> no_return().
+
parse_file(Data, Line, Env, _Where) ->
case edoc_lib:parse_expr(Data, Line) of
{string, _, File0} ->
@@ -344,6 +348,8 @@ parse_file(Data, Line, Env, _Where) ->
throw_error(Line, file_not_string)
end.
+-spec parse_header(_, line(), _, _) -> no_return().
+
parse_header(Data, Line, Env, {Where, _}) ->
parse_header(Data, Line, Env, Where);
parse_header(Data, Line, Env, Where) when is_list(Where) ->
@@ -362,6 +368,13 @@ parse_header(Data, Line, Env, Where) when is_list(Where) ->
throw_error(Line, file_not_string)
end.
+-type err() :: 'file_not_string'
+ | {'file_not_found', file:filename()}
+ | {'read_file', file:filename(), term()}
+ | string().
+
+-spec throw_error(line(), err()) -> no_return().
+
throw_error(L, {read_file, File, R}) ->
throw_error(L, {"error reading file '~s': ~w",
[edoc_lib:filename(File), R]});
diff --git a/lib/edoc/src/edoc_types.erl b/lib/edoc/src/edoc_types.erl
index 85c9ee6f2a..b0255f793d 100644
--- a/lib/edoc/src/edoc_types.erl
+++ b/lib/edoc/src/edoc_types.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/edoc/test/Makefile b/lib/edoc/test/Makefile
index 4ce9799f6d..f77bbaa09b 100644
--- a/lib/edoc/test/Makefile
+++ b/lib/edoc/test/Makefile
@@ -59,7 +59,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
- $(INSTALL_DATA) edoc.spec $(RELSYSDIR)
+ $(INSTALL_DATA) edoc.spec edoc.cover $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/edoc/test/edoc.cover b/lib/edoc/test/edoc.cover
new file mode 100644
index 0000000000..50140fafde
--- /dev/null
+++ b/lib/edoc/test/edoc.cover
@@ -0,0 +1,2 @@
+{incl_app,edoc,details}.
+
diff --git a/lib/edoc/test/edoc.spec b/lib/edoc/test/edoc.spec
index 8443a28028..8371427270 100644
--- a/lib/edoc/test/edoc.spec
+++ b/lib/edoc/test/edoc.spec
@@ -1 +1 @@
-{topcase, {dir, "../edoc_test"}}.
+{suites,"../edoc_test",all}.
diff --git a/lib/edoc/test/edoc_SUITE.erl b/lib/edoc/test/edoc_SUITE.erl
index ea833f89b2..0d57591e3e 100644
--- a/lib/edoc/test/edoc_SUITE.erl
+++ b/lib/edoc/test/edoc_SUITE.erl
@@ -17,17 +17,36 @@
%%
-module(edoc_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%% Test cases
-export([build_std/1]).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[build_std].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
build_std(suite) ->
[];
build_std(doc) ->
diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk
index 75e9a5c971..e030174862 100644
--- a/lib/edoc/vsn.mk
+++ b/lib/edoc/vsn.mk
@@ -1 +1 @@
-EDOC_VSN = 0.7.6.7
+EDOC_VSN = 0.7.6.8
diff --git a/lib/erl_docgen/Makefile b/lib/erl_docgen/Makefile
index c5bed632a5..93a6353cac 100644
--- a/lib/erl_docgen/Makefile
+++ b/lib/erl_docgen/Makefile
@@ -1,19 +1,20 @@
-# ``The contents of this file are subject to the Erlang Public License,
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
+# retrieved online at http://www.erlang.org/.
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
#
-# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-# AB. All Rights Reserved.''
-#
-# $Id$
+# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
@@ -22,9 +23,11 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
# Macros
#
-SUB_DIRECTORIES = priv
+SUB_DIRECTORIES = src priv
#doc/src
+include vsn.mk
+VSN = $(ERL_DOCGEN_VSN)
SPECIAL_TARGETS =
diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml
index 5b5398fec6..c7a7926c40 100644
--- a/lib/erl_docgen/doc/src/notes.xml
+++ b/lib/erl_docgen/doc/src/notes.xml
@@ -29,7 +29,36 @@
<file>notes.xml</file>
</header>
<p>This document describes the changes made to the erl_docgen application.</p>
- <section><title>Erl_Docgen 0.2.2</title>
+ <section><title>Erl_Docgen 0.2.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix format_man_pages so it handles all man sections
+ and remove warnings/errors in various man pages. </p>
+ <p>
+ Own Id: OTP-8600</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Support for using Dialyzer specifications and types
+ has been added. This is an experimental release; changes
+ are expected before the new functionality is used when
+ building the OTP documentation. </p>
+ <p>
+ Own Id: OTP-8720</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Docgen 0.2.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/erl_docgen/ebin/.gitignore b/lib/erl_docgen/ebin/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/erl_docgen/ebin/.gitignore
diff --git a/lib/erl_docgen/priv/bin/specs_gen.escript b/lib/erl_docgen/priv/bin/specs_gen.escript
new file mode 100644
index 0000000000..840fed6dd5
--- /dev/null
+++ b/lib/erl_docgen/priv/bin/specs_gen.escript
@@ -0,0 +1,129 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+%%% <script> [-I<dir>]... [-o<dir>] [-module Module] [File]
+%%%
+%%% Use EDoc and the layout module 'otp_specs' to create an XML file
+%%% containing Dialyzer types and specifications (-type, -spec).
+%%%
+%%% Options:
+%%%
+%%% "-o<dir>" The output directory for the created file.
+%%% Default is ".".
+%%% "-I<dir>" Directory to be searched when including a file.
+%%% "-module Module"
+%%% Module name to use when there is no File argument.
+%%% A temporary file will be created.
+%%% Exactly one of -module Module and File must be given.
+%%%
+%%% The name of the generated file is "specs_<module>.xml". Its exact
+%%% format is not further described here.
+
+main(Args) ->
+ case catch parse(Args, [], ".", no_module) of
+ {ok, FileSpec, InclFs, Dir} ->
+ call_edoc(FileSpec, InclFs, Dir);
+ {error, Msg} ->
+ io:format("~s\n", [Msg]),
+ usage()
+ end.
+
+parse(["-o"++Dir | Opts], InclFs, _, Module) ->
+ parse(Opts, InclFs, Dir, Module);
+parse(["-I"++I | Opts], InclFs, Dir, Module) ->
+ parse(Opts, [I | InclFs], Dir, Module);
+parse(["-module", Module | Opts], InclFs, Dir, _) ->
+ parse(Opts, InclFs, Dir, Module);
+parse([File], InclFs, Dir, no_module) ->
+ {ok, {file, File}, lists:reverse(InclFs), Dir};
+parse([_], _, _, _) ->
+ {error, io_lib:format("Cannot have both -module option and file", [])};
+parse([], _, _, no_module) ->
+ {error, io_lib:format("Missing -module option or file", [])};
+parse([], InclFs, Dir, Module) ->
+ {ok, {module, Module}, lists:reverse(InclFs), Dir};
+parse(Args, _, _, _) ->
+ {error, io_lib:format("Bad arguments: ~p", [Args])}.
+
+usage() ->
+ io:format("usage: ~s [-I<include_dir>]... [-o<out_dir>] "
+ "[-module <module>] [file]\n", [escript:script_name()]),
+ halt(1).
+
+call_edoc(FileSpec, InclFs, Dir) ->
+ Incl = [{includes, InclFs}],
+ Pre = [{preprocess, true}],
+ Choice = [{dialyzer_specs, all}],
+ DirOpt = [{dir, Dir}],
+ Pretty = [{pretty_print, erl_pp}],
+ Layout = [{layout, otp_specs},
+ {file_suffix, ".specs"},
+ {stylesheet, ""}],
+ Warn = [{report_missing_type, false},
+ {report_type_mismatch, false}],
+ OptionList = (DirOpt ++ Choice ++ Pre ++ Warn ++ Pretty ++ Layout ++ Incl),
+ {File, TmpFile} = case FileSpec of
+ {file, File0} ->
+ {File0, false};
+ {module, Module} ->
+ {create_tmp_file(Dir, Module), true}
+ end,
+ try edoc:files([File], OptionList) of
+ ok ->
+ clean_up(Dir, File, TmpFile),
+ rename(Dir, File)
+ catch
+ _:_ ->
+ io:format("EDoc could not process file '~s'\n", [File]),
+ clean_up(Dir, File, TmpFile),
+ halt(3)
+ end.
+
+rename(Dir, F) ->
+ Mod = filename:basename(F, ".erl"),
+ Old = filename:join(Dir, Mod ++ ".specs"),
+ New = filename:join(Dir, "specs_" ++ Mod ++ ".xml"),
+ case file:rename(Old, New) of
+ ok ->
+ ok;
+ {error, R} ->
+ R1 = file:format_error(R),
+ io:format("could not rename file '~s': ~s\n", [New, R1]),
+ halt(2)
+ end.
+
+clean_up(Dir, File, TmpFile) ->
+ [file:delete(File) || TmpFile],
+ _ = [file:delete(filename:join(Dir, F)) ||
+ F <- ["packages-frame.html",
+ "overview-summary.html",
+ "modules-frame.html",
+ "index.html", "erlang.png", "edoc-info"]],
+ ok.
+
+create_tmp_file(Dir, Module) ->
+ TmpFile = filename:join(Dir, Module++".erl"),
+ case file:write_file(TmpFile, "-module(" ++ Module ++ ").\n") of
+ ok ->
+ TmpFile;
+ {error, R} ->
+ R1 = file:format_error(R),
+ io:format("could not write file '~s': ~s\n", [TmpFile, R1]),
+ halt(2)
+ end.
diff --git a/lib/erl_docgen/priv/bin/xref_mod_app.escript b/lib/erl_docgen/priv/bin/xref_mod_app.escript
new file mode 100755
index 0000000000..fcc3a96ada
--- /dev/null
+++ b/lib/erl_docgen/priv/bin/xref_mod_app.escript
@@ -0,0 +1,107 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+%%% Find all applications and all modules given a root directory.
+%%% Output an XML file that can be used for finding which application
+%%% a given module belongs to.
+%%%
+%%% Options:
+%%%
+%%% "-topdir <D>" Applications are found under D/lib/.
+%%% The default value is $ERL_TOP.
+%%%
+%%% "-outfile <F>" Output is written onto F.
+%%% The default value is "mod2app.xml".
+%%%
+%%% The output file has the following format:
+%%%
+%%% <?xml version="1.0"?>
+%%% <mod2app>
+%%% <module name="ModName1">AppName1</module>
+%%% ...
+%%% <mod2app>
+%%%
+%%% meaning that module ModName1 resides in application AppName1.
+
+main(Args) ->
+ case catch parse(Args, os:getenv("ERL_TOP"), "mod2app.xml") of
+ {ok, TopDir, OutFile} ->
+ case modapp(TopDir) of
+ [] ->
+ io:format("no applications found\n"),
+ halt(3);
+ MA ->
+ Layout = layout(MA),
+ XML = xmerl:export_simple(Layout, xmerl_xml),
+ write_file(XML, OutFile)
+ end;
+ {error, Msg} ->
+ io:format("~s\n", [Msg]),
+ usage()
+ end.
+
+parse(["-topdir", TopDir | Opts], _, OutFile) ->
+ parse(Opts, TopDir, OutFile);
+parse(["-outfile", OutFile | Opts], TopDir, _) ->
+ parse(Opts, TopDir, OutFile);
+parse([], TopDir, OutFile) ->
+ {ok, TopDir, OutFile};
+parse([Opt | _], _, _) ->
+ {error, io_lib:format("Bad option: ~p", [Opt])}.
+
+usage() ->
+ io:format("usage: ~s [-topdir <dir>] [-outfile <file>]\n",
+ [escript:script_name()]),
+ halt(1).
+
+modapp(TopDir) ->
+ AppDirs = filelib:wildcard(filename:join([TopDir,"lib","*"])),
+ AM = [appmods(D) || D <- AppDirs],
+ lists:keysort(1, [{M,A} || {A,Ms} <- AM, M <- Ms]).
+
+%% It's OK if too much data is generated as long as all applications
+%% and all modules are mentioned.
+appmods(D) ->
+ ErlFiles = filelib:wildcard(filename:join([D,"src","*.erl"])),
+ AppV = filename:basename(D),
+ App = case string:rstr(AppV, "-") of
+ 0 -> AppV;
+ P -> string:sub_string(AppV, 1, P-1)
+ end,
+ {App, [filename:basename(EF, ".erl") || EF <- ErlFiles]}.
+
+-include_lib("xmerl/include/xmerl.hrl").
+
+-define(IND(N), lists:duplicate(N, $\s)).
+-define(NL, "\n").
+
+layout(MAL) ->
+ ML = lists:append([[?IND(2),{module,[{name,M}],[A]},?NL] || {M,A} <- MAL]),
+ [?NL,{mod2app,[?NL|ML]},?NL].
+
+write_file(Text, File) ->
+ case file:open(File, [write]) of
+ {ok, FD} ->
+ io:put_chars(FD, Text),
+ ok = file:close(FD);
+ {error, R} ->
+ R1 = file:format_error(R),
+ io:format("could not write file '~s': ~s\n", [File, R1]),
+ halt(2)
+ end.
diff --git a/lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd b/lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd
index 7b9974fbda..c1237766e1 100644
--- a/lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd
+++ b/lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd
@@ -26,15 +26,18 @@
<!ELEMENT description (%block;|quote|br|marker|warning|note)* >
<!ELEMENT funcs (func)+ >
-<!ELEMENT func (name+,fsummary,type?,desc?) >
+<!ELEMENT func (name+,type_desc+,fsummary,type?,desc?) >
<!-- ELEMENT name is defined in each ref dtd -->
<!ELEMENT fsummary (#PCDATA|c|em)* >
<!ELEMENT type (v,d?)+ >
<!ELEMENT v (#PCDATA) >
<!ELEMENT d (#PCDATA|c|em)* >
-<!ELEMENT desc (%block;|quote|br|marker|warning|note)* >
+<!ELEMENT desc (%block;|quote|br|marker|warning|note|anno)* >
<!ELEMENT authors (aname,email)+ >
<!ELEMENT aname (#PCDATA) >
<!ELEMENT email (#PCDATA) >
<!ELEMENT section (marker*,title,(%block;|quote|br|marker|
warning|note)*) >
+<!ELEMENT datatypes (datatype)+ >
+<!ELEMENT datatype (name+,desc?) >
+<!ELEMENT type_desc (#PCDATA) >
diff --git a/lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd b/lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd
index 21656a1446..9905086ff4 100644
--- a/lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd
+++ b/lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd
@@ -22,7 +22,7 @@
%common.refs;
<!ELEMENT erlref (header,module,modulesummary,description,
- (section|funcs)*,authors?) >
+ (section|funcs|datatypes)*,authors?) >
<!ELEMENT module (#PCDATA) >
<!ELEMENT modulesummary (#PCDATA) >
diff --git a/lib/erl_docgen/priv/dtd_man_entities/xhtml-lat1.ent b/lib/erl_docgen/priv/dtd_man_entities/xhtml-lat1.ent
index 3df9970a43..7a07e2c406 100644
--- a/lib/erl_docgen/priv/dtd_man_entities/xhtml-lat1.ent
+++ b/lib/erl_docgen/priv/dtd_man_entities/xhtml-lat1.ent
@@ -21,26 +21,26 @@
<!ENTITY sect "&#167;"> <!-- section sign, U+00A7 ISOnum -->
<!ENTITY uml "&#168;"> <!-- diaeresis = spacing diaeresis,
U+00A8 ISOdia -->
-<!ENTITY copy "&#169;"> <!-- copyright sign, U+00A9 ISOnum -->
+<!ENTITY copy "(C)"> <!-- copyright sign, U+00A9 ISOnum -->
<!ENTITY ordf "&#170;"> <!-- feminine ordinal indicator, U+00AA ISOnum -->
-<!ENTITY laquo "&#171;"> <!-- left-pointing double angle quotation mark
- = left pointing guillemet, U+00AB ISOnum -->
+<!ENTITY laquo "&#34;"> <!-- left-pointing double angle quotation mark
+ = left pointing guillemetn = " in man pages, U+00AB ISOnum -->
<!ENTITY not "&#172;"> <!-- not sign = discretionary hyphen,
U+00AC ISOnum -->
-<!ENTITY shy "&#173;"> <!-- soft hyphen = discretionary hyphen,
+<!ENTITY shy ""> <!-- soft hyphen = discretionary hyphen,
U+00AD ISOnum -->
-<!ENTITY reg "&#174;"> <!-- registered sign = registered trade mark sign,
+<!ENTITY reg "(R)"> <!-- registered sign = registered trade mark sign,
U+00AE ISOnum -->
<!ENTITY macr "&#175;"> <!-- macron = spacing macron = overline
= APL overbar, U+00AF ISOdia -->
<!ENTITY deg "&#176;"> <!-- degree sign, U+00B0 ISOnum -->
-<!ENTITY plusmn "&#177;"> <!-- plus-minus sign = plus-or-minus sign,
+<!ENTITY plusmn "+/-"> <!-- plus-minus sign = plus-or-minus sign,
U+00B1 ISOnum -->
<!ENTITY sup2 "&#178;"> <!-- superscript two = superscript digit two
= squared, U+00B2 ISOnum -->
<!ENTITY sup3 "&#179;"> <!-- superscript three = superscript digit three
= cubed, U+00B3 ISOnum -->
-<!ENTITY acute "&#180;"> <!-- acute accent = spacing acute,
+<!ENTITY acute "'"> <!-- acute accent = spacing acute,
U+00B4 ISOdia -->
<!ENTITY micro "&#181;"> <!-- micro sign, U+00B5 ISOnum -->
<!ENTITY para "&#182;"> <!-- pilcrow sign = paragraph sign,
@@ -62,134 +62,134 @@
= fraction three quarters, U+00BE ISOnum -->
<!ENTITY iquest "&#191;"> <!-- inverted question mark
= turned question mark, U+00BF ISOnum -->
-<!ENTITY Agrave "&#192;"> <!-- latin capital letter A with grave
+<!ENTITY Agrave "A"> <!-- latin capital letter A with grave
= latin capital letter A grave,
U+00C0 ISOlat1 -->
-<!ENTITY Aacute "&#193;"> <!-- latin capital letter A with acute,
+<!ENTITY Aacute "A"> <!-- latin capital letter A with acute,
U+00C1 ISOlat1 -->
-<!ENTITY Acirc "&#194;"> <!-- latin capital letter A with circumflex,
+<!ENTITY Acirc "A"> <!-- latin capital letter A with circumflex,
U+00C2 ISOlat1 -->
-<!ENTITY Atilde "&#195;"> <!-- latin capital letter A with tilde,
+<!ENTITY Atilde "A"> <!-- latin capital letter A with tilde,
U+00C3 ISOlat1 -->
-<!ENTITY Auml "&#196;"> <!-- latin capital letter A with diaeresis,
+<!ENTITY Auml "A"> <!-- latin capital letter A with diaeresis,
U+00C4 ISOlat1 -->
-<!ENTITY Aring "&#197;"> <!-- latin capital letter A with ring above
+<!ENTITY Aring "A"> <!-- latin capital letter A with ring above
= latin capital letter A ring,
U+00C5 ISOlat1 -->
-<!ENTITY AElig "&#198;"> <!-- latin capital letter AE
+<!ENTITY AElig "AE"> <!-- latin capital letter AE
= latin capital ligature AE,
U+00C6 ISOlat1 -->
-<!ENTITY Ccedil "&#199;"> <!-- latin capital letter C with cedilla,
+<!ENTITY Ccedil "C"> <!-- latin capital letter C with cedilla,
U+00C7 ISOlat1 -->
-<!ENTITY Egrave "&#200;"> <!-- latin capital letter E with grave,
+<!ENTITY Egrave "E"> <!-- latin capital letter E with grave,
U+00C8 ISOlat1 -->
-<!ENTITY Eacute "&#201;"> <!-- latin capital letter E with acute,
+<!ENTITY Eacute "E"> <!-- latin capital letter E with acute,
U+00C9 ISOlat1 -->
-<!ENTITY Ecirc "&#202;"> <!-- latin capital letter E with circumflex,
+<!ENTITY Ecirc "E"> <!-- latin capital letter E with circumflex,
U+00CA ISOlat1 -->
-<!ENTITY Euml "&#203;"> <!-- latin capital letter E with diaeresis,
+<!ENTITY Euml "E"> <!-- latin capital letter E with diaeresis,
U+00CB ISOlat1 -->
-<!ENTITY Igrave "&#204;"> <!-- latin capital letter I with grave,
+<!ENTITY Igrave "I"> <!-- latin capital letter I with grave,
U+00CC ISOlat1 -->
-<!ENTITY Iacute "&#205;"> <!-- latin capital letter I with acute,
+<!ENTITY Iacute "I"> <!-- latin capital letter I with acute,
U+00CD ISOlat1 -->
-<!ENTITY Icirc "&#206;"> <!-- latin capital letter I with circumflex,
+<!ENTITY Icirc "I"> <!-- latin capital letter I with circumflex,
U+00CE ISOlat1 -->
-<!ENTITY Iuml "&#207;"> <!-- latin capital letter I with diaeresis,
+<!ENTITY Iuml "I"> <!-- latin capital letter I with diaeresis,
U+00CF ISOlat1 -->
<!ENTITY ETH "&#208;"> <!-- latin capital letter ETH, U+00D0 ISOlat1 -->
-<!ENTITY Ntilde "&#209;"> <!-- latin capital letter N with tilde,
+<!ENTITY Ntilde "N"> <!-- latin capital letter N with tilde,
U+00D1 ISOlat1 -->
-<!ENTITY Ograve "&#210;"> <!-- latin capital letter O with grave,
+<!ENTITY Ograve "O"> <!-- latin capital letter O with grave,
U+00D2 ISOlat1 -->
-<!ENTITY Oacute "&#211;"> <!-- latin capital letter O with acute,
+<!ENTITY Oacute "O"> <!-- latin capital letter O with acute,
U+00D3 ISOlat1 -->
-<!ENTITY Ocirc "&#212;"> <!-- latin capital letter O with circumflex,
+<!ENTITY Ocirc "O"> <!-- latin capital letter O with circumflex,
U+00D4 ISOlat1 -->
-<!ENTITY Otilde "&#213;"> <!-- latin capital letter O with tilde,
+<!ENTITY Otilde "O"> <!-- latin capital letter O with tilde,
U+00D5 ISOlat1 -->
-<!ENTITY Ouml "&#214;"> <!-- latin capital letter O with diaeresis,
+<!ENTITY Ouml "O"> <!-- latin capital letter O with diaeresis,
U+00D6 ISOlat1 -->
-<!ENTITY times "&#215;"> <!-- multiplication sign, U+00D7 ISOnum -->
+<!ENTITY times "x"> <!-- multiplication sign, U+00D7 ISOnum -->
<!ENTITY Oslash "&#216;"> <!-- latin capital letter O with stroke
= latin capital letter O slash,
U+00D8 ISOlat1 -->
-<!ENTITY Ugrave "&#217;"> <!-- latin capital letter U with grave,
+<!ENTITY Ugrave "U"> <!-- latin capital letter U with grave,
U+00D9 ISOlat1 -->
-<!ENTITY Uacute "&#218;"> <!-- latin capital letter U with acute,
+<!ENTITY Uacute "U"> <!-- latin capital letter U with acute,
U+00DA ISOlat1 -->
-<!ENTITY Ucirc "&#219;"> <!-- latin capital letter U with circumflex,
+<!ENTITY Ucirc "U"> <!-- latin capital letter U with circumflex,
U+00DB ISOlat1 -->
-<!ENTITY Uuml "&#220;"> <!-- latin capital letter U with diaeresis,
+<!ENTITY Uuml "U"> <!-- latin capital letter U with diaeresis,
U+00DC ISOlat1 -->
-<!ENTITY Yacute "&#221;"> <!-- latin capital letter Y with acute,
+<!ENTITY Yacute "Y"> <!-- latin capital letter Y with acute,
U+00DD ISOlat1 -->
<!ENTITY THORN "&#222;"> <!-- latin capital letter THORN,
U+00DE ISOlat1 -->
<!ENTITY szlig "&#223;"> <!-- latin small letter sharp s = ess-zed,
U+00DF ISOlat1 -->
-<!ENTITY agrave "&#224;"> <!-- latin small letter a with grave
+<!ENTITY agrave "a"> <!-- latin small letter a with grave
= latin small letter a grave,
U+00E0 ISOlat1 -->
-<!ENTITY aacute "&#225;"> <!-- latin small letter a with acute,
+<!ENTITY aacute "a"> <!-- latin small letter a with acute,
U+00E1 ISOlat1 -->
-<!ENTITY acirc "&#226;"> <!-- latin small letter a with circumflex,
+<!ENTITY acirc "a"> <!-- latin small letter a with circumflex,
U+00E2 ISOlat1 -->
-<!ENTITY atilde "&#227;"> <!-- latin small letter a with tilde,
+<!ENTITY atilde "a"> <!-- latin small letter a with tilde,
U+00E3 ISOlat1 -->
-<!ENTITY auml "&#228;"> <!-- latin small letter a with diaeresis,
+<!ENTITY auml "a"> <!-- latin small letter a with diaeresis,
U+00E4 ISOlat1 -->
-<!ENTITY aring "&#229;"> <!-- latin small letter a with ring above
+<!ENTITY aring "a"> <!-- latin small letter a with ring above
= latin small letter a ring,
U+00E5 ISOlat1 -->
-<!ENTITY aelig "&#230;"> <!-- latin small letter ae
+<!ENTITY aelig "ae"> <!-- latin small letter ae
= latin small ligature ae, U+00E6 ISOlat1 -->
-<!ENTITY ccedil "&#231;"> <!-- latin small letter c with cedilla,
+<!ENTITY ccedil "c"> <!-- latin small letter c with cedilla,
U+00E7 ISOlat1 -->
-<!ENTITY egrave "&#232;"> <!-- latin small letter e with grave,
+<!ENTITY egrave "e"> <!-- latin small letter e with grave,
U+00E8 ISOlat1 -->
-<!ENTITY eacute "&#233;"> <!-- latin small letter e with acute,
+<!ENTITY eacute "e"> <!-- latin small letter e with acute,
U+00E9 ISOlat1 -->
-<!ENTITY ecirc "&#234;"> <!-- latin small letter e with circumflex,
+<!ENTITY ecirc "e"> <!-- latin small letter e with circumflex,
U+00EA ISOlat1 -->
-<!ENTITY euml "&#235;"> <!-- latin small letter e with diaeresis,
+<!ENTITY euml "e"> <!-- latin small letter e with diaeresis,
U+00EB ISOlat1 -->
-<!ENTITY igrave "&#236;"> <!-- latin small letter i with grave,
+<!ENTITY igrave "i"> <!-- latin small letter i with grave,
U+00EC ISOlat1 -->
-<!ENTITY iacute "&#237;"> <!-- latin small letter i with acute,
+<!ENTITY iacute "i"> <!-- latin small letter i with acute,
U+00ED ISOlat1 -->
-<!ENTITY icirc "&#238;"> <!-- latin small letter i with circumflex,
+<!ENTITY icirc "i"> <!-- latin small letter i with circumflex,
U+00EE ISOlat1 -->
-<!ENTITY iuml "&#239;"> <!-- latin small letter i with diaeresis,
+<!ENTITY iuml "i"> <!-- latin small letter i with diaeresis,
U+00EF ISOlat1 -->
<!ENTITY eth "&#240;"> <!-- latin small letter eth, U+00F0 ISOlat1 -->
-<!ENTITY ntilde "&#241;"> <!-- latin small letter n with tilde,
+<!ENTITY ntilde "n"> <!-- latin small letter n with tilde,
U+00F1 ISOlat1 -->
-<!ENTITY ograve "&#242;"> <!-- latin small letter o with grave,
+<!ENTITY ograve "o"> <!-- latin small letter o with grave,
U+00F2 ISOlat1 -->
-<!ENTITY oacute "&#243;"> <!-- latin small letter o with acute,
+<!ENTITY oacute "o"> <!-- latin small letter o with acute,
U+00F3 ISOlat1 -->
-<!ENTITY ocirc "&#244;"> <!-- latin small letter o with circumflex,
+<!ENTITY ocirc "o"> <!-- latin small letter o with circumflex,
U+00F4 ISOlat1 -->
-<!ENTITY otilde "&#245;"> <!-- latin small letter o with tilde,
+<!ENTITY otilde "o"> <!-- latin small letter o with tilde,
U+00F5 ISOlat1 -->
-<!ENTITY ouml "&#246;"> <!-- latin small letter o with diaeresis,
+<!ENTITY ouml "o"> <!-- latin small letter o with diaeresis,
U+00F6 ISOlat1 -->
<!ENTITY divide "&#247;"> <!-- division sign, U+00F7 ISOnum -->
-<!ENTITY oslash "&#248;"> <!-- latin small letter o with stroke,
+<!ENTITY oslash "o"> <!-- latin small letter o with stroke,
= latin small letter o slash,
U+00F8 ISOlat1 -->
-<!ENTITY ugrave "&#249;"> <!-- latin small letter u with grave,
+<!ENTITY ugrave "u"> <!-- latin small letter u with grave,
U+00F9 ISOlat1 -->
-<!ENTITY uacute "&#250;"> <!-- latin small letter u with acute,
+<!ENTITY uacute "u"> <!-- latin small letter u with acute,
U+00FA ISOlat1 -->
-<!ENTITY ucirc "&#251;"> <!-- latin small letter u with circumflex,
+<!ENTITY ucirc "u"> <!-- latin small letter u with circumflex,
U+00FB ISOlat1 -->
-<!ENTITY uuml "&#252;"> <!-- latin small letter u with diaeresis,
+<!ENTITY uuml "u"> <!-- latin small letter u with diaeresis,
U+00FC ISOlat1 -->
-<!ENTITY yacute "&#253;"> <!-- latin small letter y with acute,
+<!ENTITY yacute "y"> <!-- latin small letter y with acute,
U+00FD ISOlat1 -->
<!ENTITY thorn "&#254;"> <!-- latin small letter thorn with,
U+00FE ISOlat1 -->
-<!ENTITY yuml "&#255;"> <!-- latin small letter y with diaeresis,
+<!ENTITY yuml "y"> <!-- latin small letter y with diaeresis,
U+00FF ISOlat1 -->
diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl
index bba0f97645..732560e303 100644
--- a/lib/erl_docgen/priv/xsl/db_html.xsl
+++ b/lib/erl_docgen/priv/xsl/db_html.xsl
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
#
# %CopyrightBegin%
#
@@ -17,15 +17,315 @@
# under the License.
#
# %CopyrightEnd%
-
+
-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
+ xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<xsl:include href="db_html_params.xsl"/>
+ <!-- Start of Dialyzer type/spec tags.
+ See also the template matching "name" and the template "menu.funcs"
+ -->
+
+ <xsl:param name="specs_file" select="''"/>
+ <xsl:variable name="i" select="document($specs_file)"></xsl:variable>
+
+ <xsl:param name="mod2app_file" select="''"/>
+ <xsl:variable name="m2a" select="document($mod2app_file)"></xsl:variable>
+ <xsl:key name="mod2app" match="module" use="@name"/>
+
+ <xsl:template name="err">
+ <xsl:param name="m"/>
+ <xsl:param name="n"/>
+ <xsl:param name="a"/>
+ <xsl:param name="s"/>
+ <xsl:message terminate="yes">
+ Error <xsl:if test="$m != ''"><xsl:value-of select ="$m"/>:</xsl:if>
+ <xsl:value-of
+ select="$n"/>/<xsl:value-of
+ select="$a"/>: <xsl:value-of select="$s"/>
+ </xsl:message>
+ </xsl:template>
+
+ <xsl:template name="spec_name">
+ <xsl:variable name="curModule" select="ancestor::erlref/module"/>
+ <xsl:variable name="mod" select="@mod"/>
+ <xsl:variable name="name" select="@name"/>
+ <xsl:variable name="arity" select="@arity"/>
+ <xsl:variable name="clause" select="@clause"/>
+ <xsl:variable name="spec0" select=
+ "$i/specs/module[@name=$curModule]/spec
+ [name=$name and arity=$arity
+ and (string-length($mod) = 0 or module = $mod)]"/>
+ <xsl:variable name="spec" select="$spec0[string-length($clause) = 0
+ or position() = $clause]"/>
+ <xsl:if test="count($spec) = 0">
+ <xsl:call-template name="err">
+ <xsl:with-param name="m" select="$mod"/>
+ <xsl:with-param name="n" select="$name"/>
+ <xsl:with-param name="a" select="$arity"/>
+ <xsl:with-param name="s">unknown spec</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:variable name="arity_clause">
+ <xsl:choose>
+ <xsl:when test="string-length(@clause) > 0">
+ <xsl:value-of select="@arity"/>/<xsl:value-of select="@clause"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@arity"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="ancestor::cref">
+ <xsl:message terminate="yes">
+ Error: did not expect a 'name' tag with name/arity attributes here!
+ </xsl:message>
+ </xsl:when>
+ <xsl:when test="ancestor::erlref">
+ <a name="{$name}-{$arity_clause}"></a>
+ <xsl:choose>
+ <xsl:when test="string(@with_guards) = 'no'">
+ <xsl:apply-templates select="$spec/contract/clause/head"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="contract">
+ <xsl:with-param name="contract" select="$spec/contract"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="contract">
+ <xsl:param name="contract"/>
+ <xsl:call-template name="clause">
+ <xsl:with-param name="clause" select="$contract/clause"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template name="clause">
+ <xsl:param name="clause"/>
+ <xsl:variable name="type_desc" select="../type_desc"/>
+ <xsl:for-each select="$clause">
+ <xsl:apply-templates select="head"/>
+ <xsl:if test="count(guard) > 0">
+ <xsl:call-template name="guard">
+ <xsl:with-param name="guard" select="guard"/>
+ <xsl:with-param name="type_desc" select="$type_desc"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="head">
+ <span class="bold_code">
+ <xsl:apply-templates/>
+ </span>
+ <br/>
+ </xsl:template>
+
+ <xsl:template name="guard">
+ <xsl:param name="guard"/>
+ <xsl:param name="type_desc"/>
+ <div class="REFBODY"><p>Types:</p>
+ <xsl:call-template name="subtype">
+ <xsl:with-param name="subtype" select="$guard/subtype"/>
+ <xsl:with-param name="type_desc" select="$type_desc"/>
+ </xsl:call-template>
+ </div>
+ </xsl:template>
+
+ <xsl:template name="subtype">
+ <xsl:param name="subtype"/>
+ <xsl:param name="type_desc"/>
+ <xsl:for-each select="$subtype">
+ <xsl:variable name="tname" select="typename"/>
+ <xsl:variable name="tdesc" select="$type_desc[@name = $tname]"/>
+ <div class="REFTYPES">
+ <span class="bold_code">
+ <xsl:apply-templates select="string"/>
+ </span>
+ </div>
+ <xsl:apply-templates select="$type_desc[@name = $tname]"/>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Note: <type_desc> has not been implemented for data types. -->
+
+ <!-- Similar to <d> -->
+ <xsl:template match="type_desc">
+ <div class="REFBODY">
+ <xsl:apply-templates/>
+ </div>
+ </xsl:template>
+
+ <!-- This is for debugging. All modules! -->
+ <xsl:template match="all_etypes">
+ <xsl:for-each select= "$i//type">
+ <pre>
+ <span class="bold_code">
+ <xsl:apply-templates select="typedecl"/>
+ </span><xsl:text>
+</xsl:text>
+ </pre>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Datatypes -->
+ <xsl:template match="datatypes">
+ <h3>
+ <xsl:text>DATA TYPES</xsl:text>
+ </h3>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <!-- Datatype -->
+ <xsl:template match="datatype">
+ <p><xsl:apply-templates select="name"/></p>
+ <xsl:apply-templates select="desc"/>
+ </xsl:template>
+
+ <xsl:template match="typehead">
+ <span class="bold_code">
+ <xsl:apply-templates/>
+ </span><br/>
+ </xsl:template>
+
+ <!-- local_defs -->
+ <xsl:template match="local_defs">
+ <div class="REFBODY">
+ <xsl:apply-templates>
+ </xsl:apply-templates>
+ </div>
+ </xsl:template>
+
+ <xsl:template match="local_def">
+ <div class="REFTYPES">
+ <span class="bold_code">
+ <xsl:apply-templates/>
+ </span>
+ </div>
+ </xsl:template>
+
+ <xsl:template name="type_name">
+ <xsl:variable name="curModule" select="ancestor::erlref/module"/>
+ <xsl:variable name="mod" select="@mod"/>
+ <xsl:variable name="name" select="@name"/>
+ <xsl:variable name="n_vars">
+ <xsl:choose>
+ <xsl:when test="string-length(@n_vars) > 0">
+ <xsl:value-of select="@n_vars"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="0"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="string-length($name) > 0">
+ <xsl:variable name="type" select=
+ "$i/specs/module[@name=$curModule]/type
+ [name=$name and n_vars=$n_vars
+ and (string-length($mod) = 0 or module = $mod)]"/>
+
+ <xsl:if test="count($type) != 1">
+ <xsl:call-template name="err">
+ <xsl:with-param name="m" select="$mod"/>
+ <xsl:with-param name="n" select="$name"/>
+ <xsl:with-param name="a" select="$n_vars"/>
+ <xsl:with-param name="s">unknown type</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates select="$type/typedecl"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <span class="bold_code">
+ <xsl:value-of select="."/>
+ </span>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Used both in <datatype> and in <func>! -->
+ <xsl:template match="anno">
+ <xsl:variable name="curModule" select="ancestor::erlref/module"/>
+ <xsl:variable name="anno" select="normalize-space(text())"/>
+ <xsl:variable name="namespec"
+ select="ancestor::desc/preceding-sibling::name"/>
+ <xsl:if test="count($namespec) = 0 and string-length($specs_file) > 0">
+ <xsl:call-template name="err">
+ <xsl:with-param name="s">cannot find 'name' (<xsl:value-of select="$anno"/>)
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:variable name="mod" select="$namespec/@mod"/>
+ <xsl:variable name="name" select="$namespec/@name"/>
+ <xsl:variable name="arity" select="$namespec/@arity"/>
+ <xsl:variable name="clause" select="$namespec/@clause"/>
+ <xsl:variable name="tmp_n_vars" select="$namespec/@n_vars"/>
+ <xsl:variable name="n_vars">
+ <xsl:choose>
+ <xsl:when test="string-length($tmp_n_vars) > 0">
+ <xsl:value-of select="$tmp_n_vars"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="0"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="spec0" select=
+ "$i/specs/module[@name=$curModule]/spec
+ [name=$name and arity=$arity
+ and (string-length($mod) = 0 or module = $mod)]"/>
+ <xsl:variable name="spec_annos" select=
+ "$spec0[string-length($clause) = 0
+ or position() = $clause]/anno[.=$anno]"/>
+ <xsl:variable name="type_annos" select=
+ "$i/specs/module[@name=$curModule]/type
+ [name=$name and n_vars=$n_vars
+ and (string-length($mod) = 0 or module = $mod)]/anno[.=$anno]"/>
+
+ <xsl:if test="count($spec_annos) = 0
+ and count($type_annos) = 0
+ and string-length($specs_file) > 0">
+ <xsl:variable name="n">
+ <xsl:choose>
+ <xsl:when test="string-length($arity) = 0">
+ <xsl:value-of select="$n_vars"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$arity"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:call-template name="err">
+ <xsl:with-param name="m" select="$mod"/>
+ <xsl:with-param name="n" select="$name"/>
+ <xsl:with-param name="a" select="$n"/>
+ <xsl:with-param name="s">unknown annotation <xsl:value-of select="$anno"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:value-of select="$anno"/>
+ </xsl:template>
+
+ <!-- Used for indentation of formatted types and specs -->
+ <xsl:template match="nbsp">
+ <xsl:text>&#160;</xsl:text>
+ </xsl:template>
+
+ <!-- End of Dialyzer type/spec tags -->
+
<!-- Page layout -->
<xsl:template name="pagelayout">
<xsl:param name="chapnum"/>
@@ -36,19 +336,19 @@
<title>Erlang -- <xsl:value-of select="header/title"/></title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000">
-
+
<div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="{$topdocdir}/js/flipmenu/flipmenu.js"/>
<script id="js2" type="text/javascript" src="{$topdocdir}/js/erlresolvelinks.js"></script>
<script language="JavaScript" type="text/javascript">
<xsl:text disable-output-escaping="yes"><![CDATA[
- <!--
+ <!--
function getWinHeight() {
var myHeight = 0;
if( typeof( window.innerHeight ) == 'number' ) {
//Non-IE
myHeight = window.innerHeight;
- } else if( document.documentElement && ( document.documentElement.clientWidth ||
+ } else if( document.documentElement && ( document.documentElement.clientWidth ||
document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myHeight = document.documentElement.clientHeight;
@@ -56,7 +356,7 @@
//IE 4 compatible
myHeight = document.body.clientHeight;
}
- return myHeight;
+ return myHeight;
}
function setscrollpos() {
@@ -64,16 +364,16 @@
document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
}
- function addEvent(obj, evType, fn){
- if (obj.addEventListener){
- obj.addEventListener(evType, fn, true);
- return true;
- } else if (obj.attachEvent){
- var r = obj.attachEvent("on"+evType, fn);
- return r;
- } else {
- return false;
- }
+ function addEvent(obj, evType, fn){
+ if (obj.addEventListener){
+ obj.addEventListener(evType, fn, true);
+ return true;
+ } else if (obj.attachEvent){
+ var r = obj.attachEvent("on"+evType, fn);
+ return r;
+ } else {
+ return false;
+ }
}
addEvent(window, 'load', setscrollpos);
@@ -85,7 +385,7 @@
<xsl:with-param name="chapnum" select="$chapnum"/>
<xsl:with-param name="curModule" select="$curModule"/>
</xsl:call-template>
-
+
<div id="content">
<div class="innertube">
@@ -124,17 +424,17 @@
<xsl:if test="$lname = 'releasenotes'">
<!-- .../part -->
<xsl:call-template name="releasenotes.content" />
- </xsl:if>
+ </xsl:if>
<xsl:if test="$lname = 'part'">
<!-- .../part -->
<xsl:call-template name="part.content" />
- </xsl:if>
+ </xsl:if>
<xsl:if test="$lname = 'chapter'">
<!-- .../part/chapter -->
<xsl:call-template name="chapter.content">
<xsl:with-param name="chapnum" select="$chapnum"/>
</xsl:call-template>
- </xsl:if>
+ </xsl:if>
<xsl:if test="$lname = 'application'">
<!-- .../application -->
<xsl:call-template name="app.content" />
@@ -178,37 +478,37 @@
<small>
<xsl:if test="boolean(/book/parts/part)">
<a href="users_guide.html">User's Guide</a><br/>
- </xsl:if>
+ </xsl:if>
<xsl:if test="boolean(/book/applications)">
<a href="index.html">Reference Manual</a><br/>
- </xsl:if>
+ </xsl:if>
<xsl:if test="boolean(/book/releasenotes)">
<a href="release_notes.html">Release Notes</a><br/>
- </xsl:if>
+ </xsl:if>
<a href="{$pdfdir}/{$appname}-{$appver}.pdf">PDF</a><br/>
<a href="{$topdocdir}/index.html">Top</a>
</small>
</xsl:template>
-
+
<xsl:template name="menu_middle">
<!-- small>
<xsl:choose>
<xsl:when test="ancestor::parts">
<a href="users_guide_bibliography.html">Bibliography</a><br/>
<a href="users_guide_glossary.html">Glossary</a><br/>
- </xsl:when>
- <xsl:when test="ancestor::applications">
+ </xsl:when>
+ <xsl:when test="ancestor::applications">
<a href="ref_man_bibliography.html">Bibliography</a><br/>
<a href="ref_man_glossary.html">Glossary</a><br/>
- </xsl:when>
+ </xsl:when>
</xsl:choose>
</small -->
<br/>
<a href="javascript:openAllFlips()">Expand All</a><br/>
<a href="javascript:closeAllFlips()">Contract All</a>
- </xsl:template>
-
+ </xsl:template>
+
<!-- Book -->
<xsl:template match="/book">
@@ -243,7 +543,7 @@
<!-- Chapter/Section -->
<xsl:template match="chapter/section">
- <xsl:param name="chapnum"/>
+ <xsl:param name="chapnum"/>
<h3>
<a name="{generate-id(title)}">
<xsl:value-of select="$chapnum"/>.<xsl:number/>&#160;
@@ -302,7 +602,7 @@
<!-- Lists -->
-
+
<xsl:template match="list">
<xsl:param name="chapnum"/>
<ul>
@@ -330,7 +630,7 @@
</xsl:apply-templates>
</dl>
</xsl:template>
-
+
<xsl:template match="taglist/tag">
<xsl:param name="chapnum"/>
<dt>
@@ -377,7 +677,7 @@
</xsl:apply-templates>
</p>
</div>
- </div>
+ </div>
</xsl:template>
<!-- Paragraph -->
@@ -402,7 +702,7 @@
</xsl:template>
<xsl:template match="em">
- <strong><xsl:apply-templates/></strong>
+ <strong><xsl:apply-templates/></strong>
</xsl:template>
<!-- Code -->
@@ -507,7 +807,7 @@
<!-- Part -->
<xsl:template match="part">
<!-- Generate Glossary for Users Guide -->
- <!--xsl:call-template name="glossary">
+ <!--xsl:call-template name="glossary">
<xsl:with-param name="type">users_guide</xsl:with-param>
</xsl:call-template-->
@@ -530,9 +830,9 @@
<center><h4>Version <xsl:value-of select="$appver"/></h4></center>
<center><h4><xsl:value-of select="$gendate"/></h4></center>
-
+
<xsl:apply-templates select="chapter"/>
-
+
</xsl:template>
<!-- Menu.ug -->
@@ -565,10 +865,10 @@
</xsl:call-template>
</ul>
</div>
- </div>
+ </div>
</xsl:template>
-
-
+
+
<xsl:template name="menu.chapter">
<xsl:param name="entries"/>
<xsl:param name="chapnum"/>
@@ -596,7 +896,7 @@
<a href="{$chapter_file}.html">
Top of chapter
</a>
- </li>
+ </li>
<xsl:call-template name="menu.section">
<xsl:with-param name="entries"
select="section[title]"/>
@@ -623,7 +923,7 @@
<!-- Chapter (if top tag)-->
<xsl:template match="/chapter">
- <xsl:document href="{substring-before(header/file, '.xml')}.html" method="html" encoding="UTF-8" indent="yes"
+ <xsl:document href="{substring-before(header/file, '.xml')}.html" method="html" encoding="UTF-8" indent="yes"
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN">
<xsl:call-template name="pagelayout">
@@ -635,7 +935,7 @@
<!-- Chapter -->
<xsl:template match="chapter">
- <xsl:document href="{substring-before(header/file, '.xml')}.html" method="html" encoding="UTF-8" indent="yes"
+ <xsl:document href="{substring-before(header/file, '.xml')}.html" method="html" encoding="UTF-8" indent="yes"
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN">
<xsl:call-template name="pagelayout">
@@ -670,7 +970,7 @@
<xsl:template match="application">
<!-- Generate Glossary for Ref. Manual -->
- <!--xsl:call-template name="glossary">
+ <!--xsl:call-template name="glossary">
<xsl:with-param name="type">ref_man</xsl:with-param>
</xsl:call-template-->
@@ -678,7 +978,7 @@
<!--xsl:call-template name="bibliography">
<xsl:with-param name="type">ref_man</xsl:with-param>
</xsl:call-template-->
-
+
<xsl:document href="{$outdir}/index.html" method="html" encoding="UTF-8" indent="yes" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN">
@@ -695,9 +995,9 @@
<center><h4>Version <xsl:value-of select="$appver"/></h4></center>
<center><h4><xsl:value-of select="$gendate"/></h4></center>
-
+
<xsl:apply-templates select="erlref|cref|comref|fileref|appref"/>
-
+
</xsl:template>
<!-- Menu.ref -->
@@ -730,16 +1030,16 @@
</xsl:call-template>
</ul>
</div>
- </div>
+ </div>
</xsl:template>
-
-
+
+
<xsl:template name="menu.ref2">
<xsl:param name="entries"/>
<!--xsl:param name="genFuncMenu"/-->
<xsl:param name="curModule"/>
<xsl:for-each select="$entries">
-
+
<xsl:variable name="cval">
<xsl:choose>
<xsl:when test="local-name() = 'erlref'">
@@ -767,9 +1067,9 @@
<xsl:when test="local-name() = 'fileref'">false</xsl:when>
<xsl:when test="descendant::funcs">true</xsl:when>
<xsl:otherwise>false</xsl:otherwise>
- </xsl:choose>
+ </xsl:choose>
</xsl:variable>
-
+
<xsl:variable name="expanded">
<xsl:choose>
<xsl:when test="$curModule = $cval">true</xsl:when>
@@ -796,7 +1096,7 @@
<a href="{$link_cval}.html">
Top of manual page
</a>
- </li>
+ </li>
<xsl:call-template name="menu.funcs">
<xsl:with-param name="entries"
select="funcs/func/name"/>
@@ -823,7 +1123,7 @@
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
- </xsl:choose>
+ </xsl:choose>
</xsl:for-each>
</xsl:template>
@@ -831,7 +1131,7 @@
<xsl:template name="menu.funcs">
<xsl:param name="entries"/>
<xsl:param name="basename"/>
-
+
<xsl:for-each select="$entries">
<xsl:choose>
@@ -840,74 +1140,97 @@
<xsl:choose>
<xsl:when test="string-length($fname) > 0">
<li title="{$fname}">
- <a href="{$basename}.html#{$fname}">
+ <a href="{$basename}.html#{$fname}">
<xsl:value-of select="$fname"/>()
</a>
- </li>
+ </li>
</xsl:when>
<xsl:otherwise>
<li title="{name/nametext}">
- <a href="{$basename}.html#{name/nametext}">
+ <a href="{$basename}.html#{name/nametext}">
<xsl:value-of select="nametext"/>()
- </a>
- </li>
+ </a>
+ </li>
</xsl:otherwise>
- </xsl:choose>
+ </xsl:choose>
</xsl:when>
-
+
<xsl:when test="ancestor::erlref">
-
+
<xsl:variable name="tmpstring">
<xsl:value-of select="substring-before(substring-after(., '('), '->')"/>
- </xsl:variable>
-
+ </xsl:variable>
+
<xsl:variable name="ustring">
<xsl:choose>
<xsl:when test="string-length($tmpstring) > 0">
<xsl:call-template name="remove-paren">
<xsl:with-param name="string" select="$tmpstring"/>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="remove-paren">
<xsl:with-param name="string" select="substring-after(., '(')"/>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:otherwise>
</xsl:choose>
- </xsl:variable>
-
+ </xsl:variable>
+
<xsl:variable name="arity">
- <xsl:call-template name="calc-arity">
- <xsl:with-param name="string" select="substring-before($ustring, ')')"/>
- <xsl:with-param name="no-of-pars" select="0"/>
- </xsl:call-template>
- </xsl:variable>
-
+ <xsl:choose>
+ <xsl:when test="string-length(@arity) > 0">
+ <!-- Dialyzer spec -->
+ <xsl:choose>
+ <xsl:when test="string-length(@clause) > 0">
+ <xsl:value-of select="@arity"/>/<xsl:value-of select="@clause"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@arity"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="calc-arity">
+ <xsl:with-param name="string" select="substring-before($ustring, ')')"/>
+ <xsl:with-param name="no-of-pars" select="0"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
<xsl:variable name="fname">
- <xsl:variable name="fname1">
- <xsl:value-of select="substring-before(., '(')"/>
- </xsl:variable>
- <xsl:variable name="fname2">
- <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
- </xsl:variable>
<xsl:choose>
- <xsl:when test="string-length($fname2) > 0">
- <xsl:value-of select="$fname2"/>
+ <xsl:when test="string-length(@name) > 0">
+ <!-- Dialyzer spec -->
+ <xsl:value-of select="@name"/>
</xsl:when>
<xsl:otherwise>
- <xsl:value-of select="$fname1"/>
+ <xsl:variable name="fname1">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:variable>
+ <xsl:variable name="fname2">
+ <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($fname2) > 0">
+ <xsl:value-of select="$fname2"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fname1"/>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
-
+
<li title="{$fname}-{$arity}">
- <a href="{$basename}.html#{$fname}-{$arity}">
+ <a href="{$basename}.html#{$fname}-{$arity}">
<xsl:value-of select="$fname"/>/<xsl:value-of select="$arity"/>
</a>
- </li>
+ </li>
</xsl:when>
</xsl:choose>
-
+
</xsl:for-each>
</xsl:template>
@@ -1148,7 +1471,7 @@
<!-- Func -->
<xsl:template match="func">
<xsl:param name="partnum"/>
-
+
<p><xsl:apply-templates select="name"/></p>
<xsl:apply-templates select="fsummary|type|desc">
@@ -1159,33 +1482,48 @@
<xsl:template match="name">
+ <xsl:choose>
+ <!-- @arity is mandatory when referring to a specification -->
+ <xsl:when test="string-length(@arity) > 0">
+ <xsl:call-template name="spec_name"/>
+ </xsl:when>
+ <xsl:when test="ancestor::datatype">
+ <xsl:call-template name="type_name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="name">
<xsl:variable name="tmpstring">
<xsl:value-of select="substring-before(substring-after(., '('), '->')"/>
- </xsl:variable>
+ </xsl:variable>
<xsl:variable name="ustring">
<xsl:choose>
<xsl:when test="string-length($tmpstring) > 0">
<xsl:call-template name="remove-paren">
<xsl:with-param name="string" select="$tmpstring"/>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="remove-paren">
<xsl:with-param name="string" select="substring-after(., '(')"/>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:otherwise>
</xsl:choose>
- </xsl:variable>
-
+ </xsl:variable>
+
<xsl:variable name="arity">
<xsl:call-template name="calc-arity">
<xsl:with-param name="string" select="substring-before($ustring, ')')"/>
- <xsl:with-param name="no-of-pars" select="0"/>
+ <xsl:with-param name="no-of-pars" select="0"/>
</xsl:call-template>
- </xsl:variable>
-
+ </xsl:variable>
+
<xsl:choose>
<xsl:when test="ancestor::cref">
<a name="{substring-before(nametext, '(')}"><span class="bold_code"><xsl:value-of select="ret"/><xsl:text> </xsl:text><xsl:value-of select="nametext"/></span></a><br/>
@@ -1199,7 +1537,7 @@
<xsl:value-of select="substring-after($fname1, 'erlang:')"/>
</xsl:variable>
<xsl:choose>
- <xsl:when test="string-length($fname2) > 0">
+ <xsl:when test="string-length($fname2) > 0">
<xsl:value-of select="$fname2"/>
</xsl:when>
<xsl:otherwise>
@@ -1213,21 +1551,20 @@
<span class="bold_code"><xsl:value-of select="."/></span>
</xsl:otherwise>
</xsl:choose>
-
- </xsl:template>
+ </xsl:template>
<!-- Type -->
<xsl:template match="type">
<xsl:param name="partnum"/>
- <div class="REFBODY"><p>Types:</p>
+ <div class="REFBODY"><p>Types:</p>
<xsl:apply-templates>
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
</div>
-
+
</xsl:template>
@@ -1286,16 +1623,37 @@
<xsl:variable name="modulepart"><xsl:value-of select="substring-before($filepart, ':')"/></xsl:variable>
<xsl:choose>
<xsl:when test="string-length($modulepart) > 0">
- <xsl:variable name="filepart1"><xsl:value-of select="substring-after($filepart, ':')"/></xsl:variable>
+ <xsl:variable name="filepart1"><xsl:value-of select="substring-after($filepart, ':')"/></xsl:variable>
<span class="bold_code"><a href="javascript:erlhref('{$topdocdir}/../','{$modulepart}','{$filepart1}.html#{$linkpart}');"><xsl:apply-templates/></a></span>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
+ <!-- Dialyzer seealso (the application is unknown) -->
+ <xsl:when test="string-length($specs_file) > 0
+ and count($i/specs/module[@name=$filepart]) = 0">
+ <!-- Deemed to slow; use key() instead
+ <xsl:variable name="app"
+ select="$m2a/mod2app/module[@name=$filepart]"/>
+ -->
+ <xsl:variable name="reftext" select="text()"/>
+ <xsl:for-each select="$m2a">
+ <xsl:variable name="app" select="key('mod2app', $filepart)"/>
+ <xsl:choose>
+ <xsl:when test="string-length($app) > 0">
+ <span class="bold_code"><a href="javascript:erlhref('{$topdocdir}/../','{$app}','{$filepart}.html');"><xsl:value-of select="$reftext"/></a></span>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- Unknown application; no link -->
+ <xsl:value-of select="$reftext"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:when>
<xsl:when test="string-length($linkpart) > 0">
<span class="bold_code"><a href="{$filepart}.html#{$linkpart}"><xsl:apply-templates/></a></span>
</xsl:when>
- <xsl:otherwise>
- <span class="bold_code"><a href="{$filepart}.html"><xsl:apply-templates/></a></span>
+ <xsl:otherwise>
+ <span class="bold_code"><a href="{$filepart}.html"><xsl:apply-templates/></a></span>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
@@ -1308,16 +1666,16 @@
</xsl:when>
<xsl:otherwise>
<xsl:variable name="modulepart"><xsl:value-of select="substring-before(@marker, ':')"/></xsl:variable>
-
+
<xsl:choose>
<xsl:when test="string-length($modulepart) > 0">
- <xsl:variable name="filepart1"><xsl:value-of select="substring-after(@marker, ':')"/></xsl:variable>
+ <xsl:variable name="filepart1"><xsl:value-of select="substring-after(@marker, ':')"/></xsl:variable>
<span class="bold_code"><a href="javascript:erlhref('{$topdocdir}/../','{$modulepart}','{$filepart1}.html');"><xsl:apply-templates/></a></span>
</xsl:when>
<xsl:otherwise>
- <span class="bold_code"><a href="{@marker}.html"><xsl:apply-templates/></a></span>
+ <span class="bold_code"><a href="{@marker}.html"><xsl:apply-templates/></a></span>
</xsl:otherwise>
- </xsl:choose>
+ </xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
@@ -1342,16 +1700,16 @@
<xsl:choose>
<xsl:when test="ancestor::parts">
<a href="users_guide_glossary.html#{@id}"><xsl:value-of select="@id"/></a>
- </xsl:when>
- <xsl:when test="ancestor::applications">
+ </xsl:when>
+ <xsl:when test="ancestor::applications">
<a href="ref_man_glossary.html#{@id}"><xsl:value-of select="@id"/></a>
- </xsl:when>
+ </xsl:when>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<a href="{$topdocdir}/glossary.html#{@id}"><xsl:value-of select="@id"/></a>
</xsl:otherwise>
- </xsl:choose -->
+ </xsl:choose -->
</xsl:template>
<xsl:template match="cite">
@@ -1375,9 +1733,9 @@
<center><h4>Version <xsl:value-of select="$appver"/></h4></center>
<center><h4><xsl:value-of select="$gendate"/></h4></center>
-
+
<xsl:apply-templates select="chapter"/>
-
+
</xsl:template>
<!-- Menu.rn -->
@@ -1410,7 +1768,7 @@
</xsl:call-template>
</ul>
</div>
- </div>
+ </div>
</xsl:template>
<!-- Glossary -->
@@ -1423,14 +1781,14 @@
<title>Erlang Documentation -- <xsl:value-of select="header/title"/></title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000">
-
+
<div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="{$topdocdir}/js/flipmenu/flipmenu.js"/>
<script id="js2" type="text/javascript" src="{$topdocdir}/js/erlresolvelinks.js"></script>
<!-- Generate menu -->
<xsl:call-template name="menu"/>
-
+
<div id="content">
<div class="innertube">
<h1>Glossary</h1>
@@ -1478,14 +1836,14 @@
<title>Erlang Documentation -- <xsl:value-of select="header/title"/></title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000">
-
+
<div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="{$topdocdir}/js/flipmenu/flipmenu.js"/>
<script id="js2" type="text/javascript" src="{$topdocdir}/js/erlresolvelinks.js"></script>
<!-- Generate menu -->
<xsl:call-template name="menu"/>
-
+
<div id="content">
<div class="innertube">
<h1>Bibliography</h1>
@@ -1498,8 +1856,8 @@
<tr>
<td><xsl:value-of select="@id"/></td>
<td><xsl:value-of select="citedef"/></td>
- </tr>
- </xsl:if>
+ </tr>
+ </xsl:if>
</xsl:for-each>
</table>
@@ -1529,7 +1887,7 @@
<xsl:template name="calc-arity">
<xsl:param name="string"/>
<xsl:param name="no-of-pars"/>
-
+
<xsl:variable name="length">
<xsl:value-of select="string-length($string)"/>
</xsl:variable>
@@ -1538,8 +1896,8 @@
<xsl:when test="$length > 0">
<xsl:call-template name="calc-arity">
<xsl:with-param name="string" select="substring-after($string, ',')"/>
- <xsl:with-param name="no-of-pars" select="$no-of-pars+1"/>
- </xsl:call-template>
+ <xsl:with-param name="no-of-pars" select="$no-of-pars+1"/>
+ </xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$no-of-pars"/>
@@ -1554,9 +1912,9 @@
<xsl:variable name="str1">
<xsl:call-template name="remove-paren-1">
<xsl:with-param name="string" select="$string"/>
- <xsl:with-param name="start">(</xsl:with-param>
- <xsl:with-param name="end">)</xsl:with-param>
- </xsl:call-template>
+ <xsl:with-param name="start">(</xsl:with-param>
+ <xsl:with-param name="end">)</xsl:with-param>
+ </xsl:call-template>
</xsl:variable>
<xsl:variable name="str2">
@@ -1564,7 +1922,7 @@
<xsl:with-param name="string" select="$str1"/>
<xsl:with-param name="start">{</xsl:with-param>
<xsl:with-param name="end">}</xsl:with-param>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:variable>
<xsl:variable name="str3">
@@ -1572,7 +1930,7 @@
<xsl:with-param name="string" select="$str2"/>
<xsl:with-param name="start">[</xsl:with-param>
<xsl:with-param name="end">]</xsl:with-param>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:variable>
<xsl:value-of select="$str3"/>
@@ -1584,7 +1942,7 @@
<xsl:param name="string"/>
<xsl:param name="start"/>
<xsl:param name="end"/>
-
+
<xsl:variable name="tmp1">
<xsl:value-of select="substring-before($string, $start)"/>
</xsl:variable>
@@ -1597,7 +1955,7 @@
<xsl:variable name="retstring">
<xsl:call-template name="remove-paren">
<xsl:with-param name="string" select="$tmp2"/>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat(concat($tmp1, 'x'), $retstring)"/>
</xsl:when>
diff --git a/lib/erl_docgen/priv/xsl/db_man.xsl b/lib/erl_docgen/priv/xsl/db_man.xsl
index 71c4a66707..2a8fb9fe3e 100644
--- a/lib/erl_docgen/priv/xsl/db_man.xsl
+++ b/lib/erl_docgen/priv/xsl/db_man.xsl
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
#
# %CopyrightBegin%
#
@@ -17,24 +17,294 @@
# under the License.
#
# %CopyrightEnd%
-
+
-->
<xsl:stylesheet version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:preserve-space elements="code pre"/>
<xsl:strip-space elements="*"/>
<xsl:output method="text" encoding="UTF-8" indent="no"/>
+ <!-- Start of Dialyzer type/spec tags. See also the template matching "name"
+ -->
+
+ <!-- Note: specs data for *one* module (as opposed to html and pdf) -->
+ <xsl:param name="specs_file" select="''"/>
+ <xsl:variable name="i" select="document($specs_file)"></xsl:variable>
+
+ <xsl:template name="err">
+ <xsl:param name="m"/>
+ <xsl:param name="n"/>
+ <xsl:param name="a"/>
+ <xsl:param name="s"/>
+ <xsl:message terminate="yes">
+ Error <xsl:if test="$m != ''"><xsl:value-of select ="$m"/>:</xsl:if>
+ <xsl:value-of
+ select="$n"/>/<xsl:value-of
+ select="$a"/>: <xsl:value-of select="$s"/>
+ </xsl:message>
+ </xsl:template>
+
+ <xsl:template name="spec_name">
+ <xsl:variable name="curModule" select="ancestor::erlref/module"/>
+ <xsl:variable name="mod" select="@mod"/>
+ <xsl:variable name="name" select="@name"/>
+ <xsl:variable name="arity" select="@arity"/>
+ <xsl:variable name="clause" select="@clause"/>
+ <xsl:variable name="spec0" select=
+ "$i/module[@name=$curModule]/spec
+ [name=$name and arity=$arity
+ and (string-length($mod) = 0 or module = $mod)]"/>
+ <xsl:variable name="spec" select="$spec0[string-length($clause) = 0
+ or position() = $clause]"/>
+ <xsl:if test="count($spec) = 0">
+ <xsl:call-template name="err">
+ <xsl:with-param name="m" select="$mod"/>
+ <xsl:with-param name="n" select="$name"/>
+ <xsl:with-param name="a" select="$arity"/>
+ <xsl:with-param name="s">unknown spec</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:choose>
+ <xsl:when test="ancestor::cref">
+ <xsl:message terminate="yes">
+ Error: did not expect a 'name' tag with name/arity attributes here!
+ </xsl:message>
+ </xsl:when>
+ <xsl:when test="ancestor::erlref">
+ <xsl:choose>
+ <xsl:when test="string(@with_guards) = 'no'">
+ <xsl:apply-templates select="$spec/contract/clause/head"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="contract">
+ <xsl:with-param name="contract" select="$spec/contract"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>&#10;.br</xsl:text>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="contract">
+ <xsl:param name="contract"/>
+ <xsl:call-template name="clause">
+ <xsl:with-param name="clause" select="$contract/clause"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template name="clause">
+ <xsl:param name="clause"/>
+ <xsl:variable name="type_desc" select="../type_desc"/>
+ <xsl:for-each select="$clause">
+ <xsl:apply-templates select="head"/>
+ <xsl:if test="count(guard) > 0">
+ <xsl:call-template name="guard">
+ <xsl:with-param name="guard" select="guard"/>
+ <xsl:with-param name="type_desc" select="$type_desc"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="head">
+ <xsl:text>&#10;.nf&#10;</xsl:text>
+ <xsl:text>&#10;.B&#10;</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&#10;.br</xsl:text>
+ <xsl:text>&#10;.fi</xsl:text>
+ </xsl:template>
+
+ <xsl:template name="guard">
+ <xsl:param name="guard"/>
+ <xsl:param name="type_desc"/>
+ <xsl:text>&#10;.RS</xsl:text>
+ <xsl:text>&#10;.TP</xsl:text>
+ <xsl:text>&#10;Types</xsl:text>
+ <xsl:call-template name="subtype">
+ <xsl:with-param name="subtype" select="$guard/subtype"/>
+ <xsl:with-param name="type_desc" select="$type_desc"/>
+ </xsl:call-template>
+ <xsl:text>&#10;.RE</xsl:text>
+ </xsl:template>
+
+ <xsl:template name="subtype">
+ <xsl:param name="subtype"/>
+ <xsl:param name="type_desc"/>
+ <xsl:for-each select="$subtype">
+ <xsl:variable name="tname" select="typename"/>
+ <xsl:variable name="tdesc" select="$type_desc[@name = $tname]"/>
+ <xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates select="string"/>
+ <xsl:text>&#10;.br</xsl:text>
+ <xsl:apply-templates select="$type_desc[@name = $tname]"/>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Note: <type_desc> has not been implemented for data types. -->
+
+ <!-- Similar to <d> -->
+ <xsl:template match="type_desc">
+ <xsl:text>&#10;</xsl:text><xsl:apply-templates/>
+ <xsl:text>&#10;.br</xsl:text>
+ </xsl:template>
+
+ <!-- Datatypes -->
+ <xsl:template match="datatypes">
+ <xsl:text>&#10;.SH DATA TYPES</xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <!-- Datatype -->
+ <xsl:template match="datatype">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="typehead">
+ <xsl:text>&#10;.nf&#10;</xsl:text>
+ <xsl:text>&#10;.B&#10;</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&#10;.br</xsl:text>
+ <xsl:text>&#10;.fi</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="local_defs">
+ <xsl:text>&#10;.RS</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&#10;.RE</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="local_def">
+ <xsl:text>&#10;</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&#10;.br</xsl:text>
+ </xsl:template>
+
+ <xsl:template name="type_name">
+ <xsl:variable name="curModule" select="ancestor::erlref/module"/>
+ <xsl:variable name="mod" select="@mod"/>
+ <xsl:variable name="name" select="@name"/>
+ <xsl:variable name="n_vars">
+ <xsl:choose>
+ <xsl:when test="string-length(@n_vars) > 0">
+ <xsl:value-of select="@n_vars"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="0"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="string-length($name) > 0">
+ <xsl:variable name="type" select=
+ "$i/module[@name=$curModule]/type
+ [name=$name and n_vars=$n_vars
+ and (string-length($mod) = 0 or module = $mod)]"/>
+
+ <xsl:if test="count($type) != 1">
+ <xsl:call-template name="err">
+ <xsl:with-param name="m" select="$mod"/>
+ <xsl:with-param name="n" select="$name"/>
+ <xsl:with-param name="a" select="$n_vars"/>
+ <xsl:with-param name="s">unknown type</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates select="$type/typedecl"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>&#10;.nf&#10;</xsl:text>
+ <xsl:text>&#10;.B&#10;</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&#10;.br</xsl:text>
+ <xsl:text>&#10;.fi</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Used both in <datatype> and in <func>! -->
+ <xsl:template match="anno">
+ <xsl:variable name="curModule" select="ancestor::erlref/module"/>
+ <xsl:variable name="anno" select="normalize-space(text())"/>
+ <xsl:variable name="namespec"
+ select="ancestor::desc/preceding-sibling::name"/>
+ <xsl:if test="count($namespec) = 0 and string-length($specs_file) > 0">
+ <xsl:call-template name="err">
+ <xsl:with-param name="s">cannot find 'name' (<xsl:value-of select="$anno"/>)
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:variable name="mod" select="$namespec/@mod"/>
+ <xsl:variable name="name" select="$namespec/@name"/>
+ <xsl:variable name="arity" select="$namespec/@arity"/>
+ <xsl:variable name="clause" select="$namespec/@clause"/>
+ <xsl:variable name="tmp_n_vars" select="$namespec/@n_vars"/>
+ <xsl:variable name="n_vars">
+ <xsl:choose>
+ <xsl:when test="string-length($tmp_n_vars) > 0">
+ <xsl:value-of select="$tmp_n_vars"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="0"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="spec0" select=
+ "$i/module[@name=$curModule]/spec
+ [name=$name and arity=$arity
+ and (string-length($mod) = 0 or module = $mod)]"/>
+ <xsl:variable name="spec_annos" select=
+ "$spec0[string-length($clause) = 0
+ or position() = $clause]/anno[.=$anno]"/>
+ <xsl:variable name="type_annos" select=
+ "$i/module[@name=$curModule]/type
+ [name=$name and n_vars=$n_vars
+ and (string-length($mod) = 0 or module = $mod)]/anno[.=$anno]"/>
+
+ <xsl:if test="count($spec_annos) = 0
+ and count($type_annos) = 0
+ and string-length($specs_file) > 0">
+ <xsl:variable name="n">
+ <xsl:choose>
+ <xsl:when test="string-length($arity) = 0">
+ <xsl:value-of select="$n_vars"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$arity"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:call-template name="err">
+ <xsl:with-param name="m" select="$mod"/>
+ <xsl:with-param name="n" select="$name"/>
+ <xsl:with-param name="a" select="$n"/>
+ <xsl:with-param name="s">unknown annotation <xsl:value-of select="$anno"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:value-of select="$anno"/>
+ </xsl:template>
+
+ <!-- Used for indentation of formatted types and specs -->
+ <xsl:template match="nbsp">
+ <xsl:text> </xsl:text>
+ </xsl:template>
+
+ <!-- End of Dialyzer type/spec tags -->
+
<!-- Header -->
<xsl:template match="header">
</xsl:template>
-
+
<!-- Section/Title -->
<xsl:template match="section/title">
</xsl:template>
-
+
<!-- *ref/Section -->
<xsl:template match="erlref/section|comref/section|cref/section|fileref/section|appref/section">
<xsl:text>&#10;.SH "</xsl:text><xsl:value-of select="translate(title, 'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/><xsl:text>"&#10;</xsl:text>
@@ -49,11 +319,11 @@
<!-- Lists -->
-
+
<xsl:template match="list">
<xsl:text>&#10;.RS 2</xsl:text>
<xsl:apply-templates/>
- <xsl:text>&#10;.RE</xsl:text>
+ <xsl:text>&#10;.RE&#10;</xsl:text>
</xsl:template>
<xsl:template match="list/item">
@@ -66,9 +336,9 @@
<xsl:template match="taglist">
<xsl:text>&#10;.RS 2</xsl:text>
<xsl:apply-templates select="tag|item"/>
- <xsl:text>&#10;.RE</xsl:text>
+ <xsl:text>&#10;.RE&#10;</xsl:text>
</xsl:template>
-
+
<xsl:template match="taglist/tag">
<xsl:text>&#10;.TP 2&#10;</xsl:text>
<xsl:text>.B&#10;</xsl:text>
@@ -76,7 +346,7 @@
</xsl:template>
<xsl:template match="taglist/item">
- <xsl:apply-templates/>
+ <xsl:apply-templates/>
</xsl:template>
<xsl:template match="item/p">
@@ -88,10 +358,10 @@
<xsl:value-of select="$content"/>
</xsl:when>
<xsl:otherwise>
- <xsl:text>&#10;.RS 2</xsl:text>
- <xsl:text>&#10;.LP&#10;&#10;.LP&#10;</xsl:text>
+ <xsl:text>&#10;.RS 2</xsl:text>
+ <xsl:text>&#10;.LP&#10;&#10;.LP&#10;</xsl:text>
<xsl:value-of select="$content"/>
- <xsl:text>&#10;.RE</xsl:text>
+ <xsl:text>&#10;.RE</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
@@ -171,7 +441,7 @@
<xsl:template match="application">
<xsl:apply-templates/>
</xsl:template>
-
+
<!-- Erlref -->
<xsl:template match="/erlref">
<xsl:variable name="companyname">
@@ -184,7 +454,7 @@
<xsl:text>.TH </xsl:text><xsl:value-of select="module"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Erlang Module Definition"&#10;</xsl:text>
<xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="module"/><xsl:text> \- </xsl:text><xsl:value-of select="modulesummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:value-of select="module"/><xsl:text> \- </xsl:text><xsl:value-of select="modulesummary"/><xsl:text>&#10;</xsl:text>
<xsl:apply-templates/>
</xsl:template>
@@ -199,7 +469,7 @@
</xsl:variable>
<xsl:text>.TH </xsl:text><xsl:value-of select="com"/><xsl:text> 1 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "User Commands"&#10;</xsl:text>
<xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="com"/><xsl:text> \- </xsl:text><xsl:value-of select="comsummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:value-of select="com"/><xsl:text> \- </xsl:text><xsl:value-of select="comsummary"/><xsl:text>&#10;</xsl:text>
<xsl:apply-templates/>
</xsl:template>
@@ -214,7 +484,7 @@
</xsl:variable>
<xsl:text>.TH </xsl:text><xsl:value-of select="lib"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "C Library Functions"&#10;</xsl:text>
<xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="lib"/><xsl:text> \- </xsl:text><xsl:value-of select="libsummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:value-of select="lib"/><xsl:text> \- </xsl:text><xsl:value-of select="libsummary"/><xsl:text>&#10;</xsl:text>
<xsl:apply-templates/>
</xsl:template>
@@ -229,7 +499,7 @@
</xsl:variable>
<xsl:text>.TH </xsl:text><xsl:value-of select="file"/><xsl:text> 5 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Files"&#10;</xsl:text>
<xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="file"/><xsl:text> \- </xsl:text><xsl:value-of select="filesummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:value-of select="file"/><xsl:text> \- </xsl:text><xsl:value-of select="filesummary"/><xsl:text>&#10;</xsl:text>
<xsl:apply-templates/>
</xsl:template>
@@ -244,7 +514,7 @@
</xsl:variable>
<xsl:text>.TH </xsl:text><xsl:value-of select="app"/><xsl:text> 7 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Erlang Application Definition"&#10;</xsl:text>
<xsl:text>.SH NAME&#10;</xsl:text>
- <xsl:value-of select="app"/><xsl:text> \- </xsl:text><xsl:value-of select="appsummary"/><xsl:text>&#10;</xsl:text>
+ <xsl:value-of select="app"/><xsl:text> \- </xsl:text><xsl:value-of select="appsummary"/><xsl:text>&#10;</xsl:text>
<xsl:apply-templates/>
</xsl:template>
@@ -271,10 +541,26 @@
<!-- Func -->
<xsl:template match="func">
<xsl:text>&#10;.LP</xsl:text>
- <xsl:apply-templates/>
+ <xsl:apply-templates select="name"/>
+ <xsl:apply-templates select="fsummary|type|desc"/>
</xsl:template>
<xsl:template match="name">
+ <xsl:choose>
+ <!-- @arity is mandatory when referring to a specification -->
+ <xsl:when test="string-length(@arity) > 0">
+ <xsl:call-template name="spec_name"/>
+ </xsl:when>
+ <xsl:when test="ancestor::datatype">
+ <xsl:call-template name="type_name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="name">
<xsl:text>&#10;.B&#10;</xsl:text>
<xsl:apply-templates/>
<xsl:text>&#10;.br</xsl:text>
@@ -296,7 +582,7 @@
<xsl:text>&#10;</xsl:text><xsl:value-of select="normalize-space(text())"/>
<xsl:text>&#10;.br</xsl:text>
</xsl:template>
-
+
<!-- D -->
<xsl:template match="d">
<xsl:text>&#10;</xsl:text><xsl:apply-templates/>
@@ -316,7 +602,7 @@
<!-- This tag is skipped for now. -->
</xsl:template>
-
+
<!-- Authors -->
<xsl:template match="authors">
<xsl:text>&#10;.SH AUTHORS</xsl:text>
@@ -338,19 +624,26 @@
<!-- Do not noramlize any text within pre and code tags. -->
<xsl:template match="pre/text()">
- <xsl:value-of select="."/>
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="." />
+ <xsl:with-param name="replace" select="&quot;\&quot;" />
+ <xsl:with-param name="with" select="&quot;\\&quot;" />
+ </xsl:call-template>
</xsl:template>
<xsl:template match="code/text()">
- <xsl:value-of select="."/>
+ <xsl:call-template name="replace-string">
+ <xsl:with-param name="text" select="." />
+ <xsl:with-param name="replace" select="&quot;\&quot;" />
+ <xsl:with-param name="with" select="&quot;\\&quot;" />
+ </xsl:call-template>
</xsl:template>
-
<!-- Replace ' by \&' ans . by \&. -->
<xsl:template match="text()">
<xsl:variable name="startstring">
<xsl:value-of select="normalize-space()"/><xsl:text> </xsl:text>
- </xsl:variable>
+ </xsl:variable>
<xsl:variable name="rep1">
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="$startstring" />
diff --git a/lib/erl_docgen/priv/xsl/db_pdf.xsl b/lib/erl_docgen/priv/xsl/db_pdf.xsl
index e12b4d219a..1e80c360b8 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
#
# %CopyrightBegin%
#
@@ -17,7 +17,7 @@
# under the License.
#
# %CopyrightEnd%
-
+
-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
@@ -27,16 +27,310 @@
<xsl:include href="db_pdf_params.xsl"/>
+ <!-- Start of Dialyzer type/spec tags.
+ See also the template matching "name" and the template "bookmarks6"
+ -->
+
+ <xsl:param name="specs_file" select="''"/>
+ <xsl:variable name="i" select="document($specs_file)"></xsl:variable>
+
+ <xsl:template name="err">
+ <xsl:param name="m"/>
+ <xsl:param name="n"/>
+ <xsl:param name="a"/>
+ <xsl:param name="s"/>
+ <xsl:message terminate="yes">
+ Error <xsl:if test="$m != ''"><xsl:value-of select ="$m"/>:</xsl:if>
+ <xsl:value-of
+ select="$n"/>/<xsl:value-of
+ select="$a"/>: <xsl:value-of select="$s"/>
+ </xsl:message>
+ </xsl:template>
+
+ <xsl:template name="spec_name">
+ <xsl:variable name="curModule" select="ancestor::erlref/module"/>
+ <xsl:variable name="mod" select="@mod"/>
+ <xsl:variable name="name" select="@name"/>
+ <xsl:variable name="arity" select="@arity"/>
+ <xsl:variable name="clause" select="@clause"/>
+ <xsl:variable name="spec0" select=
+ "$i/specs/module[@name=$curModule]/spec
+ [name=$name and arity=$arity
+ and (string-length($mod) = 0 or module = $mod)]"/>
+ <xsl:variable name="spec" select="$spec0[string-length($clause) = 0
+ or position() = $clause]"/>
+ <xsl:if test="count($spec) = 0">
+ <xsl:call-template name="err">
+ <xsl:with-param name="m" select="$mod"/>
+ <xsl:with-param name="n" select="$name"/>
+ <xsl:with-param name="a" select="$arity"/>
+ <xsl:with-param name="s">unknown spec</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:choose>
+ <xsl:when test="ancestor::cref">
+ <xsl:message terminate="yes">
+ Error: did not expect a 'name' tag with name/arity attributes here!
+ </xsl:message>
+ </xsl:when>
+ <xsl:when test="ancestor::erlref">
+ <fo:block id="{generate-id()}">
+ <xsl:choose>
+ <xsl:when test="string(@with_guards) = 'no'">
+ <xsl:apply-templates select="$spec/contract/clause/head"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="contract">
+ <xsl:with-param name="contract" select="$spec/contract"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </fo:block>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="contract">
+ <xsl:param name="contract"/>
+ <xsl:call-template name="clause">
+ <xsl:with-param name="clause" select="$contract/clause"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template name="clause">
+ <xsl:param name="clause"/>
+ <xsl:variable name="type_desc" select="../type_desc"/>
+ <xsl:for-each select="$clause">
+ <xsl:apply-templates select="head"/>
+ <xsl:if test="count(guard) > 0">
+ <xsl:call-template name="guard">
+ <xsl:with-param name="guard" select="guard"/>
+ <xsl:with-param name="type_desc" select="$type_desc"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="head">
+ <fo:block xsl:use-attribute-sets="function-name">
+ <xsl:apply-templates/>
+ </fo:block>
+ </xsl:template>
+
+ <xsl:template name="guard">
+ <fo:block>
+ <xsl:text>Types:</xsl:text>
+ </fo:block>
+ <fo:list-block xsl:use-attribute-sets="type-listblock">
+ <xsl:call-template name="subtype">
+ <xsl:with-param name="subtype" select="$guard/subtype"/>
+ <xsl:with-param name="type_desc" select="$type_desc"/>
+ </xsl:call-template>
+ </fo:list-block>
+ </xsl:template>
+
+ <xsl:template name="subtype">
+ <xsl:param name="subtype"/>
+ <xsl:param name="type_desc"/>
+ <xsl:for-each select="$subtype">
+ <xsl:variable name="tname" select="typename"/>
+ <xsl:variable name="tdesc" select="$type_desc[@name = $tname]"/>
+ <fo:list-item xsl:use-attribute-sets="type-listitem">
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>
+ </fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()" format="justify">
+ <fo:block font-weight="bold">
+ <xsl:apply-templates select="string"/>
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <xsl:apply-templates select="$type_desc[@name = $tname]"/>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- Note: <type_desc> has not been implemented for data types. -->
+
+ <!-- Similar to <d> -->
+ <xsl:template match="type_desc">
+ <fo:list-item xsl:use-attribute-sets="type-listitem">
+ <fo:list-item-label end-indent="label-end()"><fo:block></fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()" format="justify">
+ <fo:block>
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </xsl:template>
+
+ <!-- Datatypes -->
+ <xsl:template match="datatypes">
+ <fo:block xsl:use-attribute-sets="h3">
+ <xsl:text>Data Types</xsl:text>
+ </fo:block>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <!-- Datatype -->
+ <xsl:template match="datatype">
+ <fo:block xsl:use-attribute-sets="function-name">
+ <xsl:apply-templates select="name"/>
+ </fo:block>
+ <xsl:apply-templates select="desc"/>
+ </xsl:template>
+
+ <!-- Like <head>... -->
+ <xsl:template match="typehead">
+ <fo:block xsl:use-attribute-sets="function-name">
+ <xsl:apply-templates/>
+ </fo:block>
+ </xsl:template>
+
+ <!-- Like <guard>, except "Types:"... -->
+ <xsl:template match="local_defs">
+ <fo:list-block xsl:use-attribute-sets="type-listblock">
+ <xsl:apply-templates/>
+ </fo:list-block>
+ </xsl:template>
+
+ <!-- Like <subtype>... -->
+ <xsl:template match="local_def">
+ <fo:list-item xsl:use-attribute-sets="type-listitem">
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>
+ </fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()" format="justify">
+ <fo:block font-weight="bold">
+ <xsl:apply-templates/>
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </xsl:template>
+
+ <xsl:template name="type_name">
+ <xsl:variable name="curModule" select="ancestor::erlref/module"/>
+ <xsl:variable name="mod" select="@mod"/>
+ <xsl:variable name="name" select="@name"/>
+ <xsl:variable name="n_vars">
+ <xsl:choose>
+ <xsl:when test="string-length(@n_vars) > 0">
+ <xsl:value-of select="@n_vars"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="0"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="string-length($name) > 0">
+ <xsl:variable name="type" select=
+ "$i/specs/module[@name=$curModule]/type
+ [name=$name and n_vars=$n_vars
+ and (string-length($mod) = 0 or module = $mod)]"/>
+
+ <xsl:if test="count($type) != 1">
+ <xsl:call-template name="err">
+ <xsl:with-param name="m" select="$mod"/>
+ <xsl:with-param name="n" select="$name"/>
+ <xsl:with-param name="a" select="$n_vars"/>
+ <xsl:with-param name="s">unknown type</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates select="$type/typedecl"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <fo:inline font-weight="bold" xsl:use-attribute-sets="type-listitem">
+ <xsl:value-of select="."/>
+ </fo:inline>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Used both in <datatype> and in <func>! -->
+ <xsl:template match="anno">
+ <xsl:variable name="curModule" select="ancestor::erlref/module"/>
+ <xsl:variable name="anno" select="normalize-space(text())"/>
+ <xsl:variable name="namespec"
+ select="ancestor::desc/preceding-sibling::name"/>
+ <xsl:if test="count($namespec) = 0 and string-length($specs_file) > 0">
+ <xsl:call-template name="err">
+ <xsl:with-param name="s">cannot find 'name' (<xsl:value-of select="$anno"/>)
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:variable name="mod" select="$namespec/@mod"/>
+ <xsl:variable name="name" select="$namespec/@name"/>
+ <xsl:variable name="arity" select="$namespec/@arity"/>
+ <xsl:variable name="clause" select="$namespec/@clause"/>
+ <xsl:variable name="tmp_n_vars" select="$namespec/@n_vars"/>
+ <xsl:variable name="n_vars">
+ <xsl:choose>
+ <xsl:when test="string-length($tmp_n_vars) > 0">
+ <xsl:value-of select="$tmp_n_vars"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="0"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="spec0" select=
+ "$i/specs/module[@name=$curModule]/spec
+ [name=$name and arity=$arity
+ and (string-length($mod) = 0 or module = $mod)]"/>
+ <xsl:variable name="spec_annos" select=
+ "$spec0[string-length($clause) = 0
+ or position() = $clause]/anno[.=$anno]"/>
+ <xsl:variable name="type_annos" select=
+ "$i/specs/module[@name=$curModule]/type
+ [name=$name and n_vars=$n_vars
+ and (string-length($mod) = 0 or module = $mod)]/anno[.=$anno]"/>
+
+ <xsl:if test="count($spec_annos) = 0
+ and count($type_annos) = 0
+ and string-length($specs_file) > 0">
+ <xsl:variable name="n">
+ <xsl:choose>
+ <xsl:when test="string-length($arity) = 0">
+ <xsl:value-of select="$n_vars"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$arity"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:call-template name="err">
+ <xsl:with-param name="m" select="$mod"/>
+ <xsl:with-param name="n" select="$name"/>
+ <xsl:with-param name="a" select="$n"/>
+ <xsl:with-param name="s">unknown annotation <xsl:value-of select="$anno"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:value-of select="$anno"/>
+ </xsl:template>
+
+ <!-- Used for indentation of formatted types and specs -->
+ <xsl:template match="nbsp">
+ <xsl:text>&#160;</xsl:text>
+ </xsl:template>
+
+ <!-- End of Dialyzer type/spec tags -->
<xsl:template match="/">
<xsl:apply-templates select="book"/>
</xsl:template>
-
+
<xsl:template match="book">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
- <!-- Master pages -->
+ <!-- Master pages -->
<fo:layout-master-set>
<fo:simple-page-master
master-name="cover"
@@ -47,7 +341,7 @@
<xsl:attribute name="page-width">
<xsl:value-of select="$page-width"/>
</xsl:attribute>
- <fo:region-body
+ <fo:region-body
margin="0mm"/>
</fo:simple-page-master>
@@ -63,7 +357,7 @@
<xsl:attribute name="page-width">
<xsl:value-of select="$page-width"/>
</xsl:attribute>
- <fo:region-body
+ <fo:region-body
margin-top="15mm"
margin-bottom="20mm"/>
<fo:region-before
@@ -100,10 +394,10 @@
<fo:page-sequence-master master-name="document">
<fo:repeatable-page-master-alternatives>
- <fo:conditional-page-master-reference
+ <fo:conditional-page-master-reference
master-reference="left-page"
odd-or-even="even"/>
- <fo:conditional-page-master-reference
+ <fo:conditional-page-master-reference
master-reference="right-page"
odd-or-even="odd"/>
</fo:repeatable-page-master-alternatives>
@@ -166,7 +460,7 @@
<fo:flow flow-name="xsl-region-body">
<fo:block>
-
+
</fo:block>
<xsl:apply-templates select="parts"/>
@@ -189,7 +483,7 @@
<!-- Cover page -->
<xsl:template match="header/title">
- <fo:page-sequence
+ <fo:page-sequence
font-family="sans-serif"
force-page-count="even"
master-reference="cover">
@@ -242,7 +536,7 @@
the License for the specific language governing rights and limitations
under the License.
- The Initial Developer of the Original Code is
+ The Initial Developer of the Original Code is
-->
<xsl:value-of select="$companyname"/>.
</fo:block>
@@ -281,22 +575,22 @@
<xsl:template name="bookmarks1">
<xsl:param name="entries"/>
<xsl:if test="$entries != ''">
-
+
<fo:bookmark internal-destination="{generate-id(/book/parts/part)}"
starting-state="hide">
<fo:bookmark-title>User's Guide</fo:bookmark-title>
-
+
<xsl:for-each select="$entries">
<xsl:call-template name="bookmarks2">
<xsl:with-param name="entries"
select="chapter[header/title]"/>
</xsl:call-template>
</xsl:for-each>
-
+
</fo:bookmark>
</xsl:if>
</xsl:template>
-
+
<xsl:template name="bookmarks2">
<xsl:param name="entries"/>
<xsl:for-each select="$entries">
@@ -341,7 +635,7 @@
starting-state="hide">
<fo:bookmark-title>Reference Manual</fo:bookmark-title>
<xsl:for-each select="$entries">
-
+
<xsl:call-template name="bookmarks5">
<xsl:with-param name="entries"
select="erlref[module]|comref[com]|cref[lib]|fileref[file]|appref[app]"/>
@@ -387,7 +681,7 @@
<fo:bookmark internal-destination="{generate-id(nametext)}" starting-state="hide">
<xsl:variable name="fname">
<xsl:value-of select="substring-before(nametext, '(')"/>
- </xsl:variable>
+ </xsl:variable>
<fo:bookmark-title>
<xsl:choose>
<xsl:when test="string-length($fname) > 0">
@@ -396,7 +690,7 @@
<xsl:otherwise>
<xsl:value-of select="nametext"/>()
</xsl:otherwise>
- </xsl:choose>
+ </xsl:choose>
</fo:bookmark-title>
</fo:bookmark>
</xsl:when>
@@ -404,60 +698,76 @@
<fo:bookmark internal-destination="{generate-id(.)}" starting-state="hide">
<xsl:variable name="tmpstring">
<xsl:value-of select="substring-before(substring-after(., '('), '->')"/>
- </xsl:variable>
+ </xsl:variable>
<xsl:variable name="ustring">
<xsl:choose>
<xsl:when test="string-length($tmpstring) > 0">
<xsl:call-template name="remove-paren">
<xsl:with-param name="string" select="$tmpstring"/>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="remove-paren">
<xsl:with-param name="string" select="substring-after(., '(')"/>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:otherwise>
</xsl:choose>
- </xsl:variable>
+ </xsl:variable>
<xsl:variable name="arity">
- <xsl:call-template name="calc-arity">
- <xsl:with-param name="string" select="substring-before($ustring, ')')"/>
- <xsl:with-param name="no-of-pars" select="0"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:variable name="fname">
- <xsl:variable name="fname1">
- <xsl:value-of select="substring-before(., '(')"/>
- </xsl:variable>
- <xsl:variable name="fname2">
- <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="string-length($fname2) > 0">
- <xsl:value-of select="$fname2"/>
- </xsl:when>
+ <xsl:choose>
+ <xsl:when test="string-length(@arity) > 0">
+ <!-- Dialyzer spec -->
+ <xsl:value-of select="@arity"/>
+ </xsl:when>
<xsl:otherwise>
- <xsl:value-of select="$fname1"/>
+ <xsl:call-template name="calc-arity">
+ <xsl:with-param name="string" select="substring-before($ustring, ')')"/>
+ <xsl:with-param name="no-of-pars" select="0"/>
+ </xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
+ <xsl:variable name="fname">
+ <xsl:choose>
+ <xsl:when test="string-length(@name) > 0">
+ <!-- Dialyzer spec -->
+ <xsl:value-of select="@name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="fname1">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:variable>
+ <xsl:variable name="fname2">
+ <xsl:value-of select="substring-after($fname1, 'erlang:')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($fname2) > 0">
+ <xsl:value-of select="$fname2"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$fname1"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
<fo:bookmark-title>
<xsl:value-of select="$fname"/>/<xsl:value-of select="$arity"/>
</fo:bookmark-title>
</fo:bookmark>
</xsl:when>
</xsl:choose>
-
+
</xsl:for-each>
</xsl:template>
<!-- UG part -->
-
+
<!-- Parts -->
<xsl:template match="parts">
<xsl:apply-templates select="part"/>
@@ -491,7 +801,7 @@
<xsl:value-of select="$partnum"/>.<xsl:number/>&#160;&#160;<xsl:value-of select="header/title"/>
</fo:marker>
<xsl:value-of select="$partnum"/>.<xsl:number/>&#160;&#160;<xsl:value-of select="header/title"/>
-
+
</fo:block>
<xsl:apply-templates select="section|quote|warning|note|br|image|marker|table|p|pre|code|list|taglist|codeinclude|erleval">
@@ -567,7 +877,7 @@
</xsl:template>
<!-- Lists -->
-
+
<xsl:template match="list">
<xsl:param name="partnum"/>
<fo:list-block xsl:use-attribute-sets="listblock">
@@ -692,7 +1002,7 @@
</xsl:variable>
<fo:block xsl:use-attribute-sets="code">
- <xsl:apply-templates select="text()"/>
+ <xsl:apply-templates select="text()"/>
</fo:block>
<xsl:if test="@caption">
@@ -711,7 +1021,7 @@
</xsl:variable>
<fo:block xsl:use-attribute-sets="code">
- <xsl:apply-templates/>
+ <xsl:apply-templates/>
</fo:block>
<xsl:if test="@caption">
@@ -734,23 +1044,23 @@
<xsl:variable name="partnum">
<xsl:number level="any" from="book" count="part|application"/>
</xsl:variable>
-
- <fo:block xsl:use-attribute-sets="h1" id="{generate-id()}">
+
+ <fo:block xsl:use-attribute-sets="h1" id="{generate-id()}">
<xsl:if test="/book/header/title">
<xsl:value-of select="$partnum"/>&#160;&#160;&#160;
<xsl:text>Reference Manual</xsl:text>
- </xsl:if>
+ </xsl:if>
</fo:block>
-
-
+
+
<xsl:apply-templates select="description">
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
-
+
<xsl:apply-templates select="erlref|comref|cref|fileref|appref">
<xsl:with-param name="partnum" select="$partnum"/>
</xsl:apply-templates>
-
+
</xsl:template>
<!-- Erlref -->
@@ -763,7 +1073,7 @@
<fo:marker marker-class-name="chapter-title">
<xsl:value-of select="module"/>
</fo:marker>
- <xsl:value-of select="module"/>
+ <xsl:value-of select="module"/>
</fo:block>
<xsl:text>Erlang module</xsl:text>
</fo:block>
@@ -784,7 +1094,7 @@
<fo:marker marker-class-name="chapter-title">
<xsl:value-of select="com"/>
</fo:marker>
- <xsl:value-of select="com"/>
+ <xsl:value-of select="com"/>
</fo:block>
<xsl:text>Command</xsl:text>
</fo:block>
@@ -805,7 +1115,7 @@
<fo:marker marker-class-name="chapter-title">
<xsl:value-of select="lib"/>
</fo:marker>
- <xsl:value-of select="lib"/>
+ <xsl:value-of select="lib"/>
</fo:block>
<xsl:text>C Library</xsl:text>
</fo:block>
@@ -826,7 +1136,7 @@
<fo:marker marker-class-name="chapter-title">
<xsl:value-of select="file"/>
</fo:marker>
- <xsl:value-of select="file"/>
+ <xsl:value-of select="file"/>
</fo:block>
<xsl:text>Name</xsl:text>
</fo:block>
@@ -847,7 +1157,7 @@
<fo:marker marker-class-name="chapter-title">
<xsl:value-of select="app"/>
</fo:marker>
- <xsl:value-of select="app"/>
+ <xsl:value-of select="app"/>
</fo:block>
<xsl:text>Application</xsl:text>
</fo:block>
@@ -900,9 +1210,7 @@
<xsl:template match="func">
<xsl:param name="partnum"/>
- <fo:block xsl:use-attribute-sets="function-name">
- <xsl:apply-templates select="name"/>
- </fo:block>
+ <xsl:apply-templates select="name"/>
<xsl:apply-templates select="fsummary|type|desc">
<xsl:with-param name="partnum" select="$partnum"/>
@@ -914,15 +1222,35 @@
<xsl:template match="name">
<xsl:param name="partnum"/>
<xsl:choose>
+ <!-- @arity is mandatory when referring to a specification -->
+ <xsl:when test="string-length(@arity) > 0">
+ <xsl:call-template name="spec_name"/>
+ </xsl:when>
+ <xsl:when test="ancestor::datatype">
+ <xsl:call-template name="type_name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <fo:block xsl:use-attribute-sets="function-name">
+ <xsl:call-template name="name">
+ <xsl:with-param name="partnum" select="$partnum"/>
+ </xsl:call-template>
+ </fo:block>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="name">
+ <xsl:param name="partnum"/>
+ <xsl:choose>
<xsl:when test="ancestor::cref">
<fo:block id="{generate-id(nametext)}">
- <xsl:value-of select="ret"/><xsl:text> </xsl:text><xsl:value-of select="nametext"/>
- </fo:block>
+ <xsl:value-of select="ret"/><xsl:text> </xsl:text><xsl:value-of select="nametext"/>
+ </fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block id="{generate-id(.)}">
- <xsl:value-of select="."/>
- </fo:block>
+ <xsl:value-of select="."/>
+ </fo:block>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
@@ -931,9 +1259,9 @@
<!-- Type -->
<xsl:template match="type">
<xsl:param name="partnum"/>
-
+
<fo:block>
- <xsl:text>Types:</xsl:text>
+ <xsl:text>Types:</xsl:text>
</fo:block>
<fo:list-block xsl:use-attribute-sets="type-listblock">
@@ -1001,9 +1329,9 @@
<xsl:param name="chapnum"/>
<xsl:variable name="tabnum">
<xsl:number level="any" from="chapter" count="table"/>
- </xsl:variable>
+ </xsl:variable>
<fo:table xsl:use-attribute-sets="table">
- <fo:table-body>
+ <fo:table-body>
<xsl:apply-templates select="row">
<xsl:with-param name="chapnum" select="$chapnum"/>
<xsl:with-param name="tabnum" select="$tabnum"/>
@@ -1107,7 +1435,7 @@
<xsl:template name="calc-arity">
<xsl:param name="string"/>
<xsl:param name="no-of-pars"/>
-
+
<xsl:variable name="length">
<xsl:value-of select="string-length($string)"/>
</xsl:variable>
@@ -1116,8 +1444,8 @@
<xsl:when test="$length > 0">
<xsl:call-template name="calc-arity">
<xsl:with-param name="string" select="substring-after($string, ',')"/>
- <xsl:with-param name="no-of-pars" select="$no-of-pars+1"/>
- </xsl:call-template>
+ <xsl:with-param name="no-of-pars" select="$no-of-pars+1"/>
+ </xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$no-of-pars"/>
@@ -1131,9 +1459,9 @@
<xsl:variable name="str1">
<xsl:call-template name="remove-paren-1">
<xsl:with-param name="string" select="$string"/>
- <xsl:with-param name="start">(</xsl:with-param>
- <xsl:with-param name="end">)</xsl:with-param>
- </xsl:call-template>
+ <xsl:with-param name="start">(</xsl:with-param>
+ <xsl:with-param name="end">)</xsl:with-param>
+ </xsl:call-template>
</xsl:variable>
<xsl:variable name="str2">
@@ -1141,7 +1469,7 @@
<xsl:with-param name="string" select="$str1"/>
<xsl:with-param name="start">{</xsl:with-param>
<xsl:with-param name="end">}</xsl:with-param>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:variable>
<xsl:variable name="str3">
@@ -1149,7 +1477,7 @@
<xsl:with-param name="string" select="$str2"/>
<xsl:with-param name="start">[</xsl:with-param>
<xsl:with-param name="end">]</xsl:with-param>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:variable>
<xsl:value-of select="$str3"/>
@@ -1161,7 +1489,7 @@
<xsl:param name="string"/>
<xsl:param name="start"/>
<xsl:param name="end"/>
-
+
<xsl:variable name="tmp1">
<xsl:value-of select="substring-before($string, $start)"/>
</xsl:variable>
@@ -1174,7 +1502,7 @@
<xsl:variable name="retstring">
<xsl:call-template name="remove-paren">
<xsl:with-param name="string" select="$tmp2"/>
- </xsl:call-template>
+ </xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat(concat($tmp1, 'x'), $retstring)"/>
</xsl:when>
diff --git a/lib/erl_docgen/src/Makefile b/lib/erl_docgen/src/Makefile
new file mode 100644
index 0000000000..8e81bccd59
--- /dev/null
+++ b/lib/erl_docgen/src/Makefile
@@ -0,0 +1,96 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(ERL_DOCGEN_VSN)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/erl_docgen-$(VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+MODULES = \
+ otp_specs
+
+HRL_FILES =
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
+
+APP_FILE = erl_docgen.app
+
+APP_SRC = $(APP_FILE).src
+APP_TARGET = $(EBIN)/$(APP_FILE)
+
+APPUP_FILE = erl_docgen.appup
+
+APPUP_SRC= $(APPUP_FILE).src
+APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_COMPILE_FLAGS += -I../../xmerl/include
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+
+# ----------------------------------------------------
+# Special Build Targets
+# ----------------------------------------------------
+
+$(APP_TARGET): $(APP_SRC) ../vsn.mk
+ sed -e 's;%VSN%;$(VSN);' $< > $@
+
+$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
+ sed -e 's;%VSN%;$(VSN);' $< > $@
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)/src
+ $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src
+ $(INSTALL_DIR) $(RELSYSDIR)/ebin
+ $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
+
+release_docs_spec:
+
diff --git a/lib/erl_docgen/src/erl_docgen.app.src b/lib/erl_docgen/src/erl_docgen.app.src
new file mode 100644
index 0000000000..1720464b6d
--- /dev/null
+++ b/lib/erl_docgen/src/erl_docgen.app.src
@@ -0,0 +1,12 @@
+{application, erl_docgen,
+ [{description, "Misc tools for building documentation"},
+ {vsn, "%VSN%"},
+ {modules, [otp_specs
+ ]
+ },
+ {registered,[]},
+ {applications, [kernel,stdlib]},
+ {env, []
+ }
+ ]
+}.
diff --git a/lib/erl_docgen/src/erl_docgen.appup.src b/lib/erl_docgen/src/erl_docgen.appup.src
new file mode 100644
index 0000000000..54a63833e6
--- /dev/null
+++ b/lib/erl_docgen/src/erl_docgen.appup.src
@@ -0,0 +1 @@
+{"%VSN%",[],[]}.
diff --git a/lib/erl_docgen/src/otp_specs.erl b/lib/erl_docgen/src/otp_specs.erl
new file mode 100644
index 0000000000..728ddb2e6e
--- /dev/null
+++ b/lib/erl_docgen/src/otp_specs.erl
@@ -0,0 +1,701 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(otp_specs).
+
+-export([module/2, package/2, overview/2, type/1]).
+
+-include("xmerl.hrl").
+
+-define(XML_EXPORT, xmerl_xml).
+-define(DEFAULT_XML_EXPORT, ?XML_EXPORT).
+-define(DEFAULT_PP, erl_pp).
+-define(IND(N), #xmlText{value="\n" ++ lists:duplicate(N, $\s)}).
+-define(NL, "\n").
+
+module(Element, Options) ->
+ XML = layout_module(Element, init_opts(Options)),
+ Export = proplists:get_value(xml_export, Options,
+ ?DEFAULT_XML_EXPORT),
+ xmerl:export_simple(XML, Export, [#xmlAttribute{name=prolog,
+ value=""}]).
+
+-record(opts, {pretty_print, file_suffix}).
+
+init_opts(Options) ->
+ #opts{pretty_print = proplists:get_value(pretty_print,
+ Options, ?DEFAULT_PP),
+ %% It *is* depending on edoc.hrl!
+ file_suffix = proplists:get_value(file_suffix, Options, ".html")}.
+
+layout_module(#xmlElement{name = module, content = Es}=E, Opts) ->
+ Name = get_attrval(name, E),
+ Functions = [{function_name(Elem), Elem} ||
+ Elem <- get_content(functions, Es)],
+ Types = [{type_name(Elem), Elem} || Elem <- get_content(typedecls, Es)],
+ Body = [{module,
+ [{name,[Name]}],
+ ([?NL] ++ types(lists:sort(Types), Opts)
+ ++ functions(lists:sort(Functions), Opts)
+ ++ timestamp())}],
+ Body.
+
+timestamp() ->
+ [{timestamp, [io_lib:fwrite("Generated by EDoc, ~s, ~s.",
+ [edoc_lib:datestr(date()),
+ edoc_lib:timestr(time())])]},?NL].
+
+functions(Fs, Opts) ->
+ lists:flatmap(fun ({Name, E}) -> function(Name, E, Opts) end, Fs).
+
+function(Name, #xmlElement{content = Es}, Opts) ->
+ TS = get_content(typespec, Es),
+ Spec = typespec(TS, Opts),
+ [{spec,(Name
+ ++ [?IND(2),{contract,Spec}]
+ ++ typespec_annos(TS))},
+ ?NL].
+
+function_name(E) ->
+ [] = get_attrval(module, E),
+ [?IND(2),{name,[atom(get_attrval(name, E))]},
+ ?IND(2),{arity,[get_attrval(arity, E)]}].
+
+label_anchor(Content, E) ->
+ case get_attrval(label, E) of
+ "" -> Content;
+ Ref -> [{marker, [{id, Ref}], Content}]
+ end.
+
+typespec([], _Opts) -> [];
+typespec(Es, Opts) ->
+ {Head, LDefs} = collect_clause(Es, Opts),
+ clause(Head, LDefs) ++ [?IND(2)].
+
+collect_clause(Es, Opts) ->
+ Name = t_name(get_elem(erlangName, Es)),
+ Defs = get_elem(localdef, Es),
+ [Type] = get_elem(type, Es),
+ {format_spec(Name, Type, Opts), collect_local_defs(Defs, Opts)}.
+
+clause(Head, LDefs) ->
+ FC = [?IND(6),{head,Head}] ++ local_clause_defs(LDefs),
+ [?IND(4),{clause,FC}].
+
+local_clause_defs([]) -> [];
+local_clause_defs(LDefs) ->
+ LocalDefs = [{subtype,T} || T <- coalesce_local_defs(LDefs, [])],
+ [?IND(6),{guard,margin(8, LocalDefs)}].
+
+types(Ts, Opts) ->
+ lists:flatmap(fun ({Name, E}) -> typedecl(Name, E, Opts) end, Ts).
+
+typedecl(Name, E=#xmlElement{content = Es}, Opts) ->
+ TD = get_content(typedef, Es),
+ TypeDef = typedef(E, TD, Opts),
+ [{type,(Name
+ ++ [?IND(2),{typedecl, TypeDef}]
+ ++ typedef_annos(TD))},
+ ?NL].
+
+type_name(#xmlElement{content = Es}) ->
+ Typedef = get_content(typedef, Es),
+ [E] = get_elem(erlangName, Typedef),
+ Args = get_content(argtypes, Typedef),
+ [] = get_attrval(module, E),
+ [?IND(2),{name,[atom(get_attrval(name, E))]},
+ ?IND(2),{n_vars,[integer_to_list(length(Args))]}].
+
+typedef(E, Es, Opts) ->
+ Ns = get_elem(erlangName, Es),
+ Name =
+ ([t_name(Ns), "("]
+ ++ seq(fun t_utype_elem/1, get_content(argtypes, Es), [")"])),
+ LDefs = collect_local_defs(get_elem(localdef, Es), Opts),
+ TypeHead = case get_elem(type, Es) of
+ [] -> label_anchor(Name, E);
+ Type -> (label_anchor(Name, E)
+ ++ format_type(Name, Type, Opts))
+ end,
+ ([?IND(6),{typehead,TypeHead}]
+ ++ local_type_defs(LDefs, [])).
+
+local_type_defs([], _) -> [];
+local_type_defs(LDefs, Last) ->
+ LocalDefs = [{local_def,T} || T <- coalesce_local_defs(LDefs, Last)],
+ [?IND(6),{local_defs,margin(8, LocalDefs)}].
+
+collect_local_defs(Es, Opts) ->
+ [collect_localdef(E, Opts) || E <- Es].
+
+collect_localdef(E = #xmlElement{content = Es}, Opts) ->
+ Name = case get_elem(typevar, Es) of
+ [] ->
+ label_anchor(N0 = t_abstype(get_content(abstype, Es)), E);
+ [V] ->
+ N0 = t_var(V)
+ end,
+ {Name,N0,format_type(N0, get_elem(type, Es), Opts)}.
+
+%% "A = t(), B = t()" is coalesced into "A = B = t()".
+%% Names as B above are kept, but the formated string is empty.
+coalesce_local_defs([], _Last) ->
+ [];
+coalesce_local_defs([{Name,N0,TypeS} | L], Last) when Name =:= N0 ->
+ cld(L, [{Name,N0}], TypeS, Last);
+coalesce_local_defs([{Name,N0,TypeS} | L], Last) ->
+ [local_def(N0, Name, TypeS, Last, L) | coalesce_local_defs(L, Last)].
+
+cld([{Name,N0,TypeS} | L], Names, TypeS, Last) when Name =:= N0 ->
+ cld(L, [{Name,N0} | Names], TypeS, Last);
+cld(L, Names0, TypeS, Last) ->
+ Names = [{_,Name0} | Names1] = lists:reverse(Names0),
+ NS = join([N || {N,_} <- Names], [" = "]),
+ ([local_def(Name0, NS, TypeS, Last, L) |
+ [local_def(N0, "", "", [], L) || {_,N0} <- Names1]]
+ ++ coalesce_local_defs(L, Last)).
+
+local_def(Name, NS, TypeS, Last, L) ->
+ [{typename,Name},{string,NS ++ TypeS ++ [Last || L =:= []]}].
+
+%% join([], Sep) when is_list(Sep) ->
+%% [];
+join([H|T], Sep) ->
+ H ++ lists:append([Sep ++ X || X <- T]).
+
+%% Use the default formatting of EDoc, which creates references, and
+%% then insert newlines and indentation according to erl_pp (the
+%% (fast) Erlang pretty printer).
+format_spec(Name, Type, #opts{pretty_print = erl_pp}=Opts) ->
+ try
+ L = t_clause(Name, Type),
+ O = pp_clause(Name, Type),
+ {R, ".\n"} = diaf(L, O, Opts),
+ R
+ catch _:_ ->
+ %% Example: "@spec ... -> record(a)"
+ format_spec(Name, Type, Opts#opts{pretty_print=default})
+ end;
+format_spec(Sep, Type, _Opts) ->
+ t_clause(Sep, Type).
+
+t_clause(Name, Type) ->
+ #xmlElement{content = [#xmlElement{name = 'fun', content = C}]} = Type,
+ [Name] ++ t_fun(C).
+
+pp_clause(Pre, Type) ->
+ Types = ot_utype([Type]),
+ Atom = lists:duplicate(iolist_size(Pre), $a),
+ L1 = erl_pp:attribute({attribute,0,spec,{{list_to_atom(Atom),0},[Types]}}),
+ "-spec " ++ L2 = lists:flatten(L1),
+ L3 = Pre ++ lists:nthtail(length(Atom), L2),
+ re:replace(L3, "\n ", "\n", [{return,list},global]).
+
+format_type(Name, Type, #opts{pretty_print = erl_pp}=Opts) ->
+ try
+ L = t_utype(Type),
+ O = pp_type(Name, Type),
+ {R, ".\n"} = diaf(L, O, Opts),
+ [" = "] ++ R
+ catch _:_ ->
+ %% Example: "t() = record(a)."
+ format_type(Name, Type, Opts#opts{pretty_print=default})
+ end;
+format_type(_Name, Type, _Opts) ->
+ [" = "] ++ t_utype(Type).
+
+pp_type(Prefix, Type) ->
+ Atom = list_to_atom(lists:duplicate(iolist_size(Prefix), $a)),
+ L1 = erl_pp:attribute({attribute,0,type,{Atom,ot_utype(Type),[]}}),
+ {L2,N} = case lists:dropwhile(fun(C) -> C =/= $: end, lists:flatten(L1)) of
+ ":: " ++ L3 -> {L3,9}; % compensation for extra "()" and ":"
+ "::\n" ++ L3 -> {"\n"++L3,6}
+ end,
+ Ss = lists:duplicate(N, $\s),
+ re:replace(L2, "\n"++Ss, "\n", [{return,list},global]).
+
+diaf(L, O0, Opts) ->
+ {R0, O} = diaf(L, [], O0, [], Opts),
+ R1 = rewrite_some_predefs(lists:reverse(R0)),
+ R = indentation(lists:flatten(R1)),
+ {R, O}.
+
+diaf([C | L], St, [C | O], R, Opts) ->
+ diaf(L, St, O, [[C] | R], Opts);
+diaf(" "++L, St, O, R, Opts) ->
+ diaf(L, St, O, R, Opts);
+diaf("", [Cs | St], O, R, Opts) ->
+ diaf(Cs, St, O, R, Opts);
+diaf("", [], O, R, _Opts) ->
+ {R, O};
+diaf(L, St, " "++O, R, Opts) ->
+ diaf(L, St, O, [" " | R], Opts);
+diaf(L, St, "\n"++O, R, Opts) ->
+ Ss = lists:takewhile(fun(C) -> C =:= $\s end, O),
+ diaf(L, St, lists:nthtail(length(Ss), O), ["\n"++Ss | R], Opts);
+diaf([{seealso, HRef0, S0} | L], St, O0, R, Opts) ->
+ {S, O} = diaf(S0, app_fix(O0), Opts),
+ HRef = fix_mod_ref(HRef0, Opts),
+ diaf(L, St, O, [{seealso, HRef, S} | R], Opts);
+diaf("="++L, St, "::"++O, R, Opts) ->
+ %% EDoc uses "=" for record field types; Dialyzer uses "::". Maybe
+ %% there should be an option for this, possibly affecting other
+ %% similar discrepancies.
+ diaf(L, St, O, ["=" | R], Opts);
+diaf([Cs | L], St, O, R, Opts) ->
+ diaf(Cs, [L | St], O, R, Opts).
+
+rewrite_some_predefs(S) ->
+ xpredef(lists:flatten(S)).
+
+xpredef([]) ->
+ [];
+xpredef("neg_integer()"++L) ->
+ ["integer() =< -1"] ++ xpredef(L);
+xpredef("non_neg_integer()"++L) ->
+ ["integer() >= 0"] ++ xpredef(L);
+xpredef("pos_integer()"++L) ->
+ ["integer() >= 1"] ++ xpredef(L);
+xpredef([T | Es]) when is_tuple(T) ->
+ [T | xpredef(Es)];
+xpredef([E | Es]) ->
+ [[E] | xpredef(Es)].
+
+indentation([]) ->
+ [];
+indentation([$\n|L]) ->
+ [{br,[]}|indent(L)];
+indentation([T | Es]) when is_tuple(T) ->
+ [T | indentation(Es)];
+indentation([E|L]) ->
+ [[E]|indentation(L)].
+
+indent([$\s|L]) ->
+ [{nbsp,[]}|indent(L)];
+indent(L) ->
+ indentation(L).
+
+app_fix(L) ->
+ try
+ {"//" ++ R1,L2} = app_fix(L, 1),
+ [App, Mod] = string:tokens(R1, "/"),
+ "//" ++ atom(App) ++ "/" ++ atom(Mod) ++ L2
+ catch _:_ -> L
+ end.
+
+app_fix(L, I) -> % a bit slow
+ {L1, L2} = lists:split(I, L),
+ case erl_scan:tokens([], L1 ++ ". ", 1) of
+ {done, {ok,[{atom,_,Atom}|_],_}, _} -> {atom_to_list(Atom), L2};
+ _ -> app_fix(L, I+1)
+ end.
+
+%% Remove the file suffix from module references.
+fix_mod_ref(HRef, #opts{file_suffix = ""}) ->
+ HRef;
+fix_mod_ref([{marker, S}]=HRef0, #opts{file_suffix = FS}) ->
+ {A, B} = lists:splitwith(fun(C) -> C =/= $# end, S),
+ case lists:member($:, A) of
+ true ->
+ HRef0; % should "save" most application references "http:"
+ false ->
+ case {lists:suffix(FS, A), B} of
+ {true, "#"++_} ->
+ [{marker, lists:sublist(A, length(A)-length(FS)) ++ B}];
+ _ ->
+ HRef0
+ end
+ end.
+
+see(E, Es) ->
+ case href(E) of
+ [] -> Es;
+ Ref ->
+ [{seealso, Ref, Es}]
+ end.
+
+href(E) ->
+ case get_attrval(href, E) of
+ "" -> [];
+ URI ->
+ [{marker, URI}]
+ end.
+
+atom(String) ->
+ io_lib:write_atom(list_to_atom(String)).
+
+t_name([E]) ->
+ N = get_attrval(name, E),
+ case get_attrval(module, E) of
+ "" -> atom(N);
+ M ->
+ S = atom(M) ++ ":" ++ atom(N),
+ case get_attrval(app, E) of
+ "" -> S;
+ A -> "//" ++ atom(A) ++ "/" ++ S
+ end
+ end.
+
+t_utype([E]) ->
+ t_utype_elem(E).
+
+t_utype_elem(E=#xmlElement{content = Es}) ->
+ case get_attrval(name, E) of
+ "" -> t_type(Es);
+ Name ->
+ T = t_type(Es),
+ case T of
+ [Name] -> T; % avoid generating "Foo::Foo"
+ T -> [Name] ++ ["::"] ++ T
+ end
+ end.
+
+t_type([E=#xmlElement{name = typevar}]) ->
+ t_var(E);
+t_type([E=#xmlElement{name = atom}]) ->
+ t_atom(E);
+t_type([E=#xmlElement{name = integer}]) ->
+ t_integer(E);
+t_type([E=#xmlElement{name = range}]) ->
+ t_range(E);
+t_type([E=#xmlElement{name = binary}]) ->
+ t_binary(E);
+t_type([E=#xmlElement{name = float}]) ->
+ t_float(E);
+t_type([#xmlElement{name = nil}]) ->
+ t_nil();
+t_type([#xmlElement{name = list, content = Es}]) ->
+ t_list(Es);
+t_type([#xmlElement{name = nonempty_list, content = Es}]) ->
+ t_nonempty_list(Es);
+t_type([#xmlElement{name = tuple, content = Es}]) ->
+ t_tuple(Es);
+t_type([#xmlElement{name = 'fun', content = Es}]) ->
+ ["fun("] ++ t_fun(Es) ++ [")"];
+t_type([E = #xmlElement{name = record, content = Es}]) ->
+ t_record(E, Es);
+t_type([E = #xmlElement{name = abstype, content = Es}]) ->
+ t_abstype(E, Es);
+t_type([#xmlElement{name = union, content = Es}]) ->
+ t_union(Es).
+
+t_var(E) ->
+ [get_attrval(name, E)].
+
+t_atom(E) ->
+ [get_attrval(value, E)].
+
+t_integer(E) ->
+ [get_attrval(value, E)].
+
+t_range(E) ->
+ [get_attrval(value, E)].
+
+t_binary(E) ->
+ [get_attrval(value, E)].
+
+t_float(E) ->
+ [get_attrval(value, E)].
+
+t_nil() ->
+ ["[]"].
+
+t_list(Es) ->
+ ["["] ++ t_utype(get_elem(type, Es)) ++ ["]"].
+
+t_nonempty_list(Es) ->
+ ["["] ++ t_utype(get_elem(type, Es)) ++ [", ...]"].
+
+t_tuple(Es) ->
+ ["{"] ++ seq(fun t_utype_elem/1, Es, ["}"]).
+
+t_fun(Es) ->
+ ["("] ++ seq(fun t_utype_elem/1, get_content(argtypes, Es),
+ [") -> "] ++ t_utype(get_elem(type, Es))).
+
+t_record(E, Es) ->
+ Name = ["#"] ++ t_type(get_elem(atom, Es)),
+ case get_elem(field, Es) of
+ [] ->
+ see(E, [Name, "{}"]);
+ Fs ->
+ see(E, Name) ++ ["{"] ++ seq(fun t_field/1, Fs, ["}"])
+ end.
+
+t_field(#xmlElement{content = Es}) ->
+ t_type(get_elem(atom, Es)) ++ [" = "] ++ t_utype(get_elem(type, Es)).
+
+t_abstype(E, Es) ->
+ Name = t_name(get_elem(erlangName, Es)),
+ case get_elem(type, Es) of
+ [] ->
+ see(E, [Name, "()"]);
+ Ts ->
+ see(E, [Name]) ++ ["("] ++ seq(fun t_utype_elem/1, Ts, [")"])
+ end.
+
+t_abstype(Es) ->
+ ([t_name(get_elem(erlangName, Es)), "("]
+ ++ seq(fun t_utype_elem/1, get_elem(type, Es), [")"])).
+
+t_union(Es) ->
+ seq(fun t_utype_elem/1, Es, " | ", []).
+
+seq(F, Es, Tail) ->
+ seq(F, Es, ", ", Tail).
+
+seq(F, [E], _Sep, Tail) ->
+ F(E) ++ Tail;
+seq(F, [E | Es], Sep, Tail) ->
+ F(E) ++ [Sep] ++ seq(F, Es, Sep, Tail);
+seq(_F, [], _Sep, Tail) ->
+ Tail.
+
+get_elem(Name, [#xmlElement{name = Name} = E | Es]) ->
+ [E | get_elem(Name, Es)];
+get_elem(Name, [_ | Es]) ->
+ get_elem(Name, Es);
+get_elem(_, []) ->
+ [].
+
+get_attr(Name, [#xmlAttribute{name = Name} = A | As]) ->
+ [A | get_attr(Name, As)];
+get_attr(Name, [_ | As]) ->
+ get_attr(Name, As);
+get_attr(_, []) ->
+ [].
+
+get_attrval(Name, #xmlElement{attributes = As}) ->
+ case get_attr(Name, As) of
+ [#xmlAttribute{value = V}] ->
+ V;
+ [] -> ""
+ end.
+
+get_content(Name, Es) ->
+ case get_elem(Name, Es) of
+ [#xmlElement{content = Es1}] ->
+ Es1;
+ [] -> []
+ end.
+
+overview(_, _Options) -> [].
+
+package(_, _Options) -> [].
+
+type(_) -> [].
+
+%% ---------------------------------------------------------------------
+
+ot_utype([E]) ->
+ ot_utype_elem(E).
+
+ot_utype_elem(E=#xmlElement{content = Es}) ->
+ case get_attrval(name, E) of
+ "" -> ot_type(Es);
+ N ->
+ Name = {var,0,list_to_atom(N)},
+ T = ot_type(Es),
+ case T of
+ Name -> T;
+ T -> {ann_type,0,[Name, T]}
+ end
+ end.
+
+ot_type([E=#xmlElement{name = typevar}]) ->
+ ot_var(E);
+ot_type([E=#xmlElement{name = atom}]) ->
+ ot_atom(E);
+ot_type([E=#xmlElement{name = integer}]) ->
+ ot_integer(E);
+ot_type([E=#xmlElement{name = range}]) ->
+ ot_range(E);
+ot_type([E=#xmlElement{name = binary}]) ->
+ ot_binary(E);
+ot_type([E=#xmlElement{name = float}]) ->
+ ot_float(E);
+ot_type([#xmlElement{name = nil}]) ->
+ ot_nil();
+ot_type([#xmlElement{name = list, content = Es}]) ->
+ ot_list(Es);
+ot_type([#xmlElement{name = nonempty_list, content = Es}]) ->
+ ot_nonempty_list(Es);
+ot_type([#xmlElement{name = tuple, content = Es}]) ->
+ ot_tuple(Es);
+ot_type([#xmlElement{name = 'fun', content = Es}]) ->
+ ot_fun(Es);
+ot_type([#xmlElement{name = record, content = Es}]) ->
+ ot_record(Es);
+ot_type([#xmlElement{name = abstype, content = Es}]) ->
+ ot_abstype(Es);
+ot_type([#xmlElement{name = union, content = Es}]) ->
+ ot_union(Es).
+
+ot_var(E) ->
+ {var,0,list_to_atom(get_attrval(name, E))}.
+
+ot_atom(E) ->
+ {ok, [Atom], _} = erl_scan:string(get_attrval(value, E), 0),
+ Atom.
+
+ot_integer(E) ->
+ {integer,0,list_to_integer(get_attrval(value, E))}.
+
+ot_range(E) ->
+ [I1, I2] = string:tokens(get_attrval(value, E), "."),
+ {type,0,range,[{integer,0,list_to_integer(I1)},
+ {integer,0,list_to_integer(I2)}]}.
+
+ot_binary(E) ->
+ {Base, Unit} =
+ case string:tokens(get_attrval(value, E), ",:*><") of
+ [] ->
+ {0, 0};
+ ["_",B] ->
+ {list_to_integer(B), 0};
+ ["_","_",U] ->
+ {0, list_to_integer(U)};
+ ["_",B,_,"_",U] ->
+ {list_to_integer(B), list_to_integer(U)}
+ end,
+ {type,0,binary,[{integer,0,Base},{integer,0,Unit}]}.
+
+ot_float(E) ->
+ {float,0,list_to_float(get_attrval(value, E))}.
+
+ot_nil() ->
+ {nil,0}.
+
+ot_list(Es) ->
+ {type,0,list,[ot_utype(get_elem(type, Es))]}.
+
+ot_nonempty_list(Es) ->
+ {type,0,nonempty_list,[ot_utype(get_elem(type, Es))]}.
+
+ot_tuple(Es) ->
+ {type,0,tuple,[ot_utype_elem(E) || E <- Es]}.
+
+ot_fun(Es) ->
+ Range = ot_utype(get_elem(type, Es)),
+ Args = [ot_utype_elem(A) || A <- get_content(argtypes, Es)],
+ {type,0,'fun',[{type,0,product,Args},Range]}.
+
+ot_record(Es) ->
+ {type,0,record,[ot_type(get_elem(atom, Es)) |
+ [ot_field(F) || F <- get_elem(field, Es)]]}.
+
+ot_field(#xmlElement{content = Es}) ->
+ {type,0,field_type,
+ [ot_type(get_elem(atom, Es)), ot_utype(get_elem(type, Es))]}.
+
+ot_abstype(Es) ->
+ ot_name(get_elem(erlangName, Es),
+ [ot_utype_elem(Elem) || Elem <- get_elem(type, Es)]).
+
+ot_union(Es) ->
+ {type,0,union,[ot_utype_elem(E) || E <- Es]}.
+
+ot_name(Es, T) ->
+ case ot_name(Es) of
+ [Mod, ":", Atom] ->
+ {remote_type,0,[{atom,0,list_to_atom(Mod)},
+ {atom,0,list_to_atom(Atom)},T]};
+ "tuple" when T =:= [] ->
+ {type,0,tuple,any};
+ Atom ->
+ {type,0,list_to_atom(Atom),T}
+ end.
+
+ot_name([E]) ->
+ Atom = get_attrval(name, E),
+ case get_attrval(module, E) of
+ "" -> Atom;
+ M ->
+ case get_attrval(app, E) of
+ "" ->
+ [M, ":", Atom];
+ A ->
+ ["//"++A++"/" ++ M, ":", Atom] % EDoc only!
+ end
+ end.
+
+%% Returns exactly those annotations that can be referred to. Note
+%% that a Dialyzer type/spec (currently) can have more annotations
+%% than can be represented by EDoc types. Note also that edoc_dia
+%% has annotated all type variables with themselves.
+typespec_annos([]) -> [?NL];
+typespec_annos([_|Es]) ->
+ annotations(clause_annos(Es)).
+
+clause_annos(Es) ->
+ [annos(get_elem(type, Es)), local_defs_annos(get_elem(localdef, Es))].
+
+typedef_annos(Es) ->
+ annotations([(case get_elem(type, Es) of
+ [] -> [];
+ T -> annos(T)
+ end
+ ++ lists:flatmap(fun annos_elem/1,
+ get_content(argtypes, Es))),
+ local_defs_annos(get_elem(localdef, Es))]).
+
+local_defs_annos(Es) ->
+ lists:flatmap(fun localdef_annos/1, Es).
+
+localdef_annos(#xmlElement{content = Es}) ->
+ annos(get_elem(type, Es)).
+
+annotations(AnnoL) ->
+ Annos = lists:usort(lists:flatten(AnnoL)),
+ margin(2, Annos).
+
+margin(N, L) ->
+ lists:append([[?IND(N),E] || E <- L]) ++ [?IND(N-2)].
+
+annos([E]) ->
+ annos_elem(E).
+
+annos_elem(E=#xmlElement{content = Es}) ->
+ case get_attrval(name, E) of
+ "" -> annos_type(Es);
+ "..." -> annos_type(Es); % compensate for a kludge in edoc_dia.erl
+ N ->
+ [{anno,[N]} | annos_type(Es)]
+ end.
+
+annos_type([#xmlElement{name = list, content = Es}]) ->
+ annos(get_elem(type, Es));
+annos_type([#xmlElement{name = nonempty_list, content = Es}]) ->
+ annos(get_elem(type, Es));
+annos_type([#xmlElement{name = tuple, content = Es}]) ->
+ lists:flatmap(fun annos_elem/1, Es);
+annos_type([#xmlElement{name = 'fun', content = Es}]) ->
+ (annos(get_elem(type, Es))
+ ++ lists:flatmap(fun annos_elem/1, get_content(argtypes, Es)));
+annos_type([#xmlElement{name = record, content = Es}]) ->
+ lists:append([annos(get_elem(type, Es1)) ||
+ #xmlElement{content = Es1} <- get_elem(field, Es)]);
+annos_type([#xmlElement{name = abstype, content = Es}]) ->
+ lists:flatmap(fun annos_elem/1, get_elem(type, Es));
+annos_type([#xmlElement{name = union, content = Es}]) ->
+ lists:flatmap(fun annos_elem/1, Es);
+annos_type([E=#xmlElement{name = typevar}]) ->
+ annos_elem(E);
+annos_type(_) ->
+ [].
diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk
index 0bc01f7d49..fb0f5ca0cd 100644
--- a/lib/erl_docgen/vsn.mk
+++ b/lib/erl_docgen/vsn.mk
@@ -1 +1 @@
-ERL_DOCGEN_VSN = 0.2.2
+ERL_DOCGEN_VSN = 0.2.3
diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml
index d7af7a1b67..de4e4b4301 100644
--- a/lib/erl_interface/doc/src/ei.xml
+++ b/lib/erl_interface/doc/src/ei.xml
@@ -641,12 +641,14 @@ ei_x_encode_empty_list(&amp;x);
<p></p>
<pre>
~a - an atom, char*
+~c - a character, char
~s - a string, char*
~i - an integer, int
~l - a long integer, long int
~u - a unsigned long integer, unsigned long int
~f - a float, float
~d - a double float, double float
+~p - an Erlang PID, erlang_pid*
</pre>
<p>For instance, to encode a tuple with some stuff:</p>
<pre>
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index 8e379463ad..de5ba61938 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -30,6 +30,70 @@
</header>
<p>This document describes the changes made to the Erl_interface application.</p>
+<section><title>Erl_Interface 3.7.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ erl_call: remove get_hostent</p>
+ <p>
+ get_hostent does not properly handle IPv4 addresses on
+ little endian platforms and fails with hostnames
+ beginning with a number. Remove get_hostent and use
+ ei_gethostbyname directly since gethostbyname supports
+ IPv4 addresses.</p>
+ <p>
+ (Thanks to Michael Santos)</p>
+ <p>
+ Own Id: OTP-8890</p>
+ </item>
+ <item>
+ <p> teach ei_x_format to handle unary - and + (Thanks to
+ Steve Vinoski)</p>
+ <p>
+ Own Id: OTP-8891</p>
+ </item>
+ <item>
+ <p>Fix zero byte allocation in registry. (Thanks to
+ Michael Santos)</p>
+ <p>
+ Own Id: OTP-8893</p>
+ </item>
+ <item>
+ <p> Check the length of the node name to prevent an
+ overflow. Memory error control of ei_alloc_big. (Thanks
+ to Michael Santos) </p>
+ <p>
+ Own Id: OTP-8943</p>
+ </item>
+ <item>
+ <p>
+ erl_term_len() in erl_interface could returned too large
+ values for integers (since R14B) and too small values for
+ refs (since R9B).</p>
+ <p>
+ Own Id: OTP-8945</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erl_Interface 3.7.1.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The <c>erl_interface</c> tracelevel for erlang messages was incorrect. This has now been fixed.
+ </p>
+ <p>
+ Own Id: OTP-8874</p>
+ </item>
+ </list>
+ </section>
+
+</section>
<section><title>Erl_Interface 3.7.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h
index 466d84bb99..ae815b414a 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -80,21 +80,24 @@
#define ERL_NO_TIMEOUT -1
/* these are the control message types */
-#define ERL_LINK 1
-#define ERL_SEND 2
-#define ERL_EXIT 3
-#define ERL_UNLINK 4
-#define ERL_NODE_LINK 5
-#define ERL_REG_SEND 6
-#define ERL_GROUP_LEADER 7
-#define ERL_EXIT2 8
-#define ERL_PASS_THROUGH 'p'
+#define ERL_LINK 1
+#define ERL_SEND 2
+#define ERL_EXIT 3
+#define ERL_UNLINK 4
+#define ERL_NODE_LINK 5
+#define ERL_REG_SEND 6
+#define ERL_GROUP_LEADER 7
+#define ERL_EXIT2 8
+#define ERL_PASS_THROUGH 'p'
/* new ones for tracing, from Kenneth */
-#define ERL_SEND_TT 12
-#define ERL_EXIT_TT 13
-#define ERL_REG_SEND_TT 16
-#define ERL_EXIT2_TT 18
+#define ERL_SEND_TT 12
+#define ERL_EXIT_TT 13
+#define ERL_REG_SEND_TT 16
+#define ERL_EXIT2_TT 18
+#define ERL_MONITOR_P 19
+#define ERL_DEMONITOR_P 20
+#define ERL_MONITOR_P_EXIT 21
/* -------------------------------------------------------------------- */
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index 99ccba0686..6dc6ebb348 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -938,7 +938,7 @@ int ei_do_receive_msg(int fd, int staticbuffer_p,
return ERL_ERROR;
}
x->index = x->buffsz;
- switch (msg->msgtype) { /* FIXME are these all? */
+ switch (msg->msgtype) { /* FIXME does not handle trace tokens and monitors */
case ERL_SEND:
case ERL_REG_SEND:
case ERL_LINK:
@@ -946,7 +946,6 @@ int ei_do_receive_msg(int fd, int staticbuffer_p,
case ERL_GROUP_LEADER:
case ERL_EXIT:
case ERL_EXIT2:
- case ERL_NODE_LINK:
return ERL_MSG;
default:
@@ -1329,6 +1328,7 @@ static int send_name_or_challenge(int fd, char *nodename,
put8(s, 'n');
put16be(s, version);
put32be(s, (DFLAG_EXTENDED_REFERENCES
+ | DFLAG_DIST_MONITOR
| DFLAG_EXTENDED_PIDS_PORTS
| DFLAG_FUN_TAGS
| DFLAG_NEW_FUN_TAGS
diff --git a/lib/erl_interface/src/connect/eirecv.c b/lib/erl_interface/src/connect/eirecv.c
index 51fc32d65c..86852f947d 100644
--- a/lib/erl_interface/src/connect/eirecv.c
+++ b/lib/erl_interface/src/connect/eirecv.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-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
@@ -107,7 +107,7 @@ ei_recv_internal (int fd,
switch (msg->msgtype) {
case ERL_SEND: /* { SEND, Cookie, ToPid } */
- if (ei_tracelevel > 0) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_atom(header,&index,msg->cookie)
|| ei_decode_pid(header,&index,&msg->to))
{
@@ -118,7 +118,7 @@ ei_recv_internal (int fd,
break;
case ERL_REG_SEND: /* { REG_SEND, From, Cookie, ToName } */
- if (ei_tracelevel > 0) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
|| ei_decode_atom(header,&index,msg->cookie)
|| ei_decode_atom(header,&index,msg->toname))
@@ -133,7 +133,7 @@ ei_recv_internal (int fd,
case ERL_LINK: /* { LINK, From, To } */
case ERL_UNLINK: /* { UNLINK, From, To } */
case ERL_GROUP_LEADER: /* { GROUP_LEADER, From, To } */
- if (ei_tracelevel > 1) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
|| ei_decode_pid(header,&index,&msg->to))
{
@@ -145,7 +145,7 @@ ei_recv_internal (int fd,
case ERL_EXIT: /* { EXIT, From, To, Reason } */
case ERL_EXIT2: /* { EXIT2, From, To, Reason } */
- if (ei_tracelevel > 1) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
|| ei_decode_pid(header,&index,&msg->to))
{
@@ -156,7 +156,7 @@ ei_recv_internal (int fd,
break;
case ERL_SEND_TT: /* { SEND_TT, Cookie, ToPid, TraceToken } */
- if (ei_tracelevel > 0) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_atom(header,&index,msg->cookie)
|| ei_decode_pid(header,&index,&msg->to)
|| ei_decode_trace(header,&index,&msg->token))
@@ -169,7 +169,7 @@ ei_recv_internal (int fd,
break;
case ERL_REG_SEND_TT: /* { REG_SEND_TT, From, Cookie, ToName, TraceToken } */
- if (ei_tracelevel > 0) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
|| ei_decode_atom(header,&index,msg->cookie)
|| ei_decode_atom(header,&index,msg->toname)
@@ -184,7 +184,7 @@ ei_recv_internal (int fd,
case ERL_EXIT_TT: /* { EXIT_TT, From, To, TraceToken, Reason } */
case ERL_EXIT2_TT: /* { EXIT2_TT, From, To, TraceToken, Reason } */
- if (ei_tracelevel > 1) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
|| ei_decode_pid(header,&index,&msg->to)
|| ei_decode_trace(header,&index,&msg->token))
@@ -196,10 +196,6 @@ ei_recv_internal (int fd,
ei_trace(1,&msg->token); /* turn on tracing */
break;
- case ERL_NODE_LINK: /* { NODE_LINK } */
- if (ei_tracelevel > 1) show_this_msg = 1;
- break;
-
default:
/* unknown type, just put any remaining bytes into buffer */
break;
diff --git a/lib/erl_interface/src/connect/send.c b/lib/erl_interface/src/connect/send.c
index cd832db4ea..57e32903cf 100644
--- a/lib/erl_interface/src/connect/send.c
+++ b/lib/erl_interface/src/connect/send.c
@@ -87,8 +87,7 @@ int ei_send_encoded_tmo(int fd, const erlang_pid *to,
put8(s, ERL_PASS_THROUGH); /* 1 */
/*** sum: 1070 */
- /* FIXME incorrect level */
- if (ei_tracelevel > 0)
+ if (ei_tracelevel >= 4)
ei_show_sendmsg(stderr,header,msg);
#ifdef HAVE_WRITEV
diff --git a/lib/erl_interface/src/connect/send_exit.c b/lib/erl_interface/src/connect/send_exit.c
index 098797c96d..d4e6605a2c 100644
--- a/lib/erl_interface/src/connect/send_exit.c
+++ b/lib/erl_interface/src/connect/send_exit.c
@@ -88,8 +88,7 @@ int ei_send_exit_tmo(int fd, const erlang_pid *from, const erlang_pid *to,
put32be(s, index - 4); /* 4 */
put8(s, ERL_PASS_THROUGH); /* 1 */
/*** sum: len + 1080 */
- /* FIXME incorrect level */
- if (ei_tracelevel > 1)
+ if (ei_tracelevel >= 4)
ei_show_sendmsg(stderr,msgbuf,NULL);
ei_write_fill_t(fd,msgbuf,index,ms);
diff --git a/lib/erl_interface/src/connect/send_reg.c b/lib/erl_interface/src/connect/send_reg.c
index 8f0e40309c..779b1b8359 100644
--- a/lib/erl_interface/src/connect/send_reg.c
+++ b/lib/erl_interface/src/connect/send_reg.c
@@ -82,8 +82,7 @@ int ei_send_reg_encoded_tmo(int fd, const erlang_pid *from,
put32be(s, index + msglen - 4); /* 4 */
put8(s, ERL_PASS_THROUGH); /* 1 */
/*** sum: 1336 */
- /* FIXME incorrect level.... */
- if (ei_tracelevel > 0)
+ if (ei_tracelevel >= 4)
ei_show_sendmsg(stderr,header,msg);
#ifdef HAVE_WRITEV
diff --git a/lib/erl_interface/src/decode/decode_atom.c b/lib/erl_interface/src/decode/decode_atom.c
index b247bd4e17..ef28838b79 100644
--- a/lib/erl_interface/src/decode/decode_atom.c
+++ b/lib/erl_interface/src/decode/decode_atom.c
@@ -31,6 +31,8 @@ int ei_decode_atom(const char *buf, int *index, char *p)
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
+
if (p) {
memmove(p,s,len);
p[len] = (char)0;
diff --git a/lib/erl_interface/src/decode/decode_big.c b/lib/erl_interface/src/decode/decode_big.c
index efe9c6e5d9..b5e9b45a3b 100644
--- a/lib/erl_interface/src/decode/decode_big.c
+++ b/lib/erl_interface/src/decode/decode_big.c
@@ -74,7 +74,7 @@ erlang_big *ei_alloc_big(unsigned int digit_bytes) {
memset(b,(char)0,sizeof(erlang_big));
if ( (b->digits = malloc(2*n)) == NULL) {
free(b);
- return 0;
+ return NULL;
}
b->arity = digit_bytes;
diff --git a/lib/erl_interface/src/decode/decode_pid.c b/lib/erl_interface/src/decode/decode_pid.c
index 5f2aec3b44..48a0c68240 100644
--- a/lib/erl_interface/src/decode/decode_pid.c
+++ b/lib/erl_interface/src/decode/decode_pid.c
@@ -33,6 +33,8 @@ int ei_decode_pid(const char *buf, int *index, erlang_pid *p)
if (get8(s) != ERL_ATOM_EXT) return -1;
len = get16be(s);
+
+ if (len > MAXATOMLEN) return -1;
if (p) {
memmove(p->node, s, len);
diff --git a/lib/erl_interface/src/decode/decode_port.c b/lib/erl_interface/src/decode/decode_port.c
index 7fb7d8d414..296ebae024 100644
--- a/lib/erl_interface/src/decode/decode_port.c
+++ b/lib/erl_interface/src/decode/decode_port.c
@@ -34,6 +34,8 @@ int ei_decode_port(const char *buf, int *index, erlang_port *p)
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
+
if (p) {
memmove(p->node, s, len);
p->node[len] = (char)0;
diff --git a/lib/erl_interface/src/decode/decode_ref.c b/lib/erl_interface/src/decode/decode_ref.c
index 6fc2cd6533..691b51fe2d 100644
--- a/lib/erl_interface/src/decode/decode_ref.c
+++ b/lib/erl_interface/src/decode/decode_ref.c
@@ -35,6 +35,8 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
+
if (p) {
memmove(p->node, s, len);
p->node[len] = (char)0;
@@ -62,6 +64,7 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
/* then the nodename */
if (get8(s) != ERL_ATOM_EXT) return -1;
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
if (p) {
memmove(p->node, s, len);
diff --git a/lib/erl_interface/src/epmd/epmd_publish.c b/lib/erl_interface/src/epmd/epmd_publish.c
index a9b8727747..d45fe644c0 100644
--- a/lib/erl_interface/src/epmd/epmd_publish.c
+++ b/lib/erl_interface/src/epmd/epmd_publish.c
@@ -69,6 +69,12 @@ static int ei_epmd_r4_publish (int port, const char *alive, unsigned ms)
int n;
int res, creation;
+ if (len > sizeof(buf)-2)
+ {
+ erl_errno = ERANGE;
+ return -1;
+ }
+
s = buf;
put16be(s,len);
diff --git a/lib/erl_interface/src/epmd/epmd_unpublish.c b/lib/erl_interface/src/epmd/epmd_unpublish.c
index 08662fe1ec..495cbab44c 100644
--- a/lib/erl_interface/src/epmd/epmd_unpublish.c
+++ b/lib/erl_interface/src/epmd/epmd_unpublish.c
@@ -59,6 +59,11 @@ int ei_unpublish_tmo(const char *alive, unsigned ms)
int len = 1 + strlen(alive);
int fd, res;
+ if (len > sizeof(buf)-3) {
+ erl_errno = ERANGE;
+ return -1;
+ }
+
put16be(s,len);
put8(s,EI_EPMD_STOP_REQ);
strcpy(s, alive);
diff --git a/lib/erl_interface/src/legacy/erl_connect.c b/lib/erl_interface/src/legacy/erl_connect.c
index 3c8c946506..e77bd5db37 100644
--- a/lib/erl_interface/src/legacy/erl_connect.c
+++ b/lib/erl_interface/src/legacy/erl_connect.c
@@ -180,9 +180,7 @@ int erl_xconnect(Erl_IpAddr addr, char *alivename)
*
* Close a connection. FIXME call ei_close_connection() later.
*
- * Returns valid file descriptor on success and < 0 on failure.
- * Set erl_errno to EHOSTUNREACH, ENOMEM, EIO or errno from socket(2)
- * or connect(2).
+ * Returns 0 on success and -1 on failure.
*
***************************************************************************/
@@ -250,7 +248,8 @@ int erl_send(int fd, ETERM *to ,ETERM *msg)
return -1;
}
- strcpy(topid.node, (char *)ERL_PID_NODE(to));
+ strncpy(topid.node, (char *)ERL_PID_NODE(to), sizeof(topid.node));
+ topid.node[sizeof(topid.node)-1] = '\0';
topid.num = ERL_PID_NUMBER(to);
topid.serial = ERL_PID_SERIAL(to);
topid.creation = ERL_PID_CREATION(to);
diff --git a/lib/erl_interface/src/legacy/erl_format.c b/lib/erl_interface/src/legacy/erl_format.c
index 9848e9296a..b17269213f 100644
--- a/lib/erl_interface/src/legacy/erl_format.c
+++ b/lib/erl_interface/src/legacy/erl_format.c
@@ -116,7 +116,7 @@ static lvar *lvar_alloc(void)
lvar *tmp;
if ((tmp = ef.idle) == NULL) {
- tmp = (lvar *) malloc(sizeof(lvar)); /* FIXME check result */
+ tmp = (lvar *) erl_malloc(sizeof(lvar));
}
else {
tmp = ef.idle;
diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c
index 18315bfbd3..5cfb5e2124 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
@@ -511,29 +511,28 @@ static int erl_term_len_helper(ETERM *ep, int dist)
case ERL_INTEGER:
i = ep->uval.ival.i;
- if ((i > ERL_MAX) || (i < ERL_MIN)) len = 7;
- else if ((i < 256) && (i >= 0)) len = 2;
+ if ((i < 256) && (i >= 0)) len = 2;
else len = 5;
break;
case ERL_U_INTEGER:
u = ep->uval.uival.u;
- if (u > ERL_MAX) len = 7;
+ if ((int)u < 0) len = 7;
else if (u < 256) len = 2;
else len = 5;
break;
case ERL_LONGLONG:
l = ep->uval.llval.i;
- if ((l > ((long long) ERL_MAX)) ||
- (l < ((long long) ERL_MIN))) len = 11;
+ if ((l > ((long long) INT_MAX)) ||
+ (l < ((long long) INT_MIN))) len = 11;
else if ((l < 256) && (l >= 0)) len = 2;
else len = 5;
break;
case ERL_U_LONGLONG:
ul = ep->uval.ullval.u;
- if (ul > ((unsigned long long) ERL_MAX)) len = 11;
+ if (ul > ((unsigned long long) INT_MAX)) len = 11;
else if (ul < 256) len = 2;
else len = 5;
break;
@@ -546,12 +545,7 @@ static int erl_term_len_helper(ETERM *ep, int dist)
case ERL_REF:
i = strlen((char *)ERL_REF_NODE(ep));
- if (dist >= 4 && ERL_REF_LEN(ep) > 1) {
- len = 1 + 2 + (i+3) + 1 + ERL_REF_LEN(ep) * 4;
- } else {
- /* 1 + N + 4 + 1 where N = 3 + strlen */
- len = 9 + i;
- }
+ len = 1 + 2 + (i+3) + 1 + ERL_REF_LEN(ep) * 4;
break;
case ERL_PORT:
@@ -668,7 +662,7 @@ len = i
#define STATIC_NODE_BUF_SZ 30
#define SET_NODE(node,node_buf,cp,len) \
-if (len >= STATIC_NODE_BUF_SZ) node = malloc(len+1); \
+if (len >= STATIC_NODE_BUF_SZ) node = erl_malloc(len+1); \
else node = node_buf; \
memcpy(node, cp, len); \
node[len] = '\0'
@@ -1540,7 +1534,7 @@ static int cmp_string_list(unsigned char **e1, unsigned char **e2) {
if ( e1_len < 256 ) {
bp = buf;
} else {
- bp = malloc(5+(2*e1_len)+1);
+ bp = erl_malloc(5+(2*e1_len)+1);
}
bp[0] = ERL_LIST_EXT;
@@ -1652,11 +1646,14 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
min = (i < j) ? i : j;
k = 0;
while (1) {
- if (k++ == min)
- return compare_top_ext(e1 , e2);
- if ((ret = compare_top_ext(e1 , e2)) == 0)
- continue;
- return ret;
+ if (k++ == min){
+ if (i == j) return 0;
+ if (i < j) return -1;
+ return 1;
+ }
+ if ((ret = compare_top_ext(e1 , e2)) == 0)
+ continue;
+ return ret;
}
case ERL_STRING_EXT:
i = (**e1 << 8) | ((*e1)[1]);
@@ -1890,8 +1887,11 @@ static int cmp_big_big(unsigned char**e1, unsigned char **e2)
ei_get_type((char *)*e1,&i1,&t1,&n1);
ei_get_type((char *)*e2,&i2,&t2,&n2);
- b1 = ei_alloc_big(n1);
- b2 = ei_alloc_big(n2);
+ if ( (b1 = ei_alloc_big(n1)) == NULL) return -1;
+ if ( (b2 = ei_alloc_big(n2)) == NULL) {
+ ei_free_big(b1);
+ return 1;
+ }
ei_decode_big((char *)*e1,&i1,b1);
ei_decode_big((char *)*e2,&i2,b2);
diff --git a/lib/erl_interface/src/legacy/erl_timeout.c b/lib/erl_interface/src/legacy/erl_timeout.c
index af1a4a1f3a..6ef5d258ed 100644
--- a/lib/erl_interface/src/legacy/erl_timeout.c
+++ b/lib/erl_interface/src/legacy/erl_timeout.c
@@ -74,7 +74,7 @@ jmp_buf *timeout_setup(int ms)
t.it_value.tv_usec = (ms % 1000) * 1000;
/* get a jump buffer and save it */
- j = malloc(sizeof(*j)); /* FIXME check result */
+ j = erl_malloc(sizeof(*j));
j->siginfo = s;
push(j);
diff --git a/lib/erl_interface/src/legacy/global_register.c b/lib/erl_interface/src/legacy/global_register.c
index 3a4de8b08e..f12eb6b448 100644
--- a/lib/erl_interface/src/legacy/global_register.c
+++ b/lib/erl_interface/src/legacy/global_register.c
@@ -31,7 +31,7 @@ int erl_global_register(int fd, const char *name, ETERM *pid)
int index = 0;
erlang_pid self;
erlang_msg msg;
- int needlink, needatom;
+ int needlink, needatom, needmonitor;
int arity;
int version;
int msglen;
@@ -65,7 +65,7 @@ int erl_global_register(int fd, const char *name, ETERM *pid)
if (ei_send_reg_encoded(fd,&self,"rex",buf,index)) return -1;
/* get the reply: expect link and an atom, or just an atom */
- needlink = needatom = 1;
+ needlink = needatom = needmonitor = 1;
while (1) {
/* get message */
while (1) {
@@ -78,9 +78,15 @@ int erl_global_register(int fd, const char *name, ETERM *pid)
case ERL_LINK:
/* got link */
if (!needlink) return -1;
- needlink = 0;
+ needlink = 0;
break;
+ case ERL_MONITOR_P-10:
+ /* got monitor */
+ if (!needmonitor) { return -1;}
+ needmonitor = 0;
+ break;
+
case ERL_SEND:
/* got message - does it contain our atom? */
if (!needatom) return -1;
diff --git a/lib/erl_interface/src/legacy/global_unregister.c b/lib/erl_interface/src/legacy/global_unregister.c
index 514dbc3c68..97a1c2d03c 100644
--- a/lib/erl_interface/src/legacy/global_unregister.c
+++ b/lib/erl_interface/src/legacy/global_unregister.c
@@ -37,7 +37,7 @@ int erl_global_unregister(int fd, const char *name)
erlang_msg msg;
int i;
int version,arity,msglen;
- int needunlink, needatom;
+ int needunlink, needatom, needdemonitor;
/* make a self pid */
self->num = fd;
@@ -57,7 +57,7 @@ int erl_global_unregister(int fd, const char *name)
if (ei_send_reg_encoded(fd,self,"rex",buf,index)) return -1;
/* get the reply: expect unlink and an atom, or just an atom */
- needunlink = needatom = 1;
+ needunlink = needatom = needdemonitor = 1;
while (1) {
/* get message */
while (1) {
@@ -68,11 +68,17 @@ int erl_global_unregister(int fd, const char *name)
switch (i) {
case ERL_UNLINK:
- /* got link */
+ /* got unlink */
if (!needunlink) return -1;
needunlink = 0;
break;
+ case ERL_DEMONITOR_P-10:
+ /* got demonitor */
+ if (!needdemonitor) return -1;
+ needdemonitor = 0;
+ break;
+
case ERL_SEND:
/* got message - does it contain our atom? */
if (!needatom) return -1;
diff --git a/lib/erl_interface/src/misc/ei_decode_term.c b/lib/erl_interface/src/misc/ei_decode_term.c
index 75c5dc9460..9b238c1e90 100644
--- a/lib/erl_interface/src/misc/ei_decode_term.c
+++ b/lib/erl_interface/src/misc/ei_decode_term.c
@@ -49,6 +49,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
return ei_decode_double(buf, index, &term->value.d_val);
case ERL_ATOM_EXT:
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
memcpy(term->value.atom_name, s, len);
term->value.atom_name[len] = '\0';
s += len;
@@ -57,6 +58,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
/* first the nodename */
if (get8(s) != ERL_ATOM_EXT) return -1;
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
memcpy(term->value.ref.node, s, len);
term->value.ref.node[len] = '\0';
s += len;
@@ -71,6 +73,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
/* then the nodename */
if (get8(s) != ERL_ATOM_EXT) return -1;
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
memcpy(term->value.ref.node, s, len);
term->value.ref.node[len] = '\0';
s += len;
@@ -87,6 +90,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
case ERL_PORT_EXT:
if (get8(s) != ERL_ATOM_EXT) return -1;
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
memcpy(term->value.port.node, s, len);
term->value.port.node[len] = '\0';
term->value.port.id = get32be(s) & 0x0fffffff; /* 28 bits */;
@@ -96,6 +100,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
if (get8(s) != ERL_ATOM_EXT) return -1;
/* name first */
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
memcpy(term->value.pid.node, s, len);
term->value.pid.node[len] = '\0';
s += len;
diff --git a/lib/erl_interface/src/misc/ei_format.c b/lib/erl_interface/src/misc/ei_format.c
index 08235d0ebe..dbd7a4479a 100644
--- a/lib/erl_interface/src/misc/ei_format.c
+++ b/lib/erl_interface/src/misc/ei_format.c
@@ -47,10 +47,12 @@
* array of unions.
*/
union arg {
+ char c;
char* s;
long l;
unsigned long u;
double d;
+ erlang_pid* pid;
};
static int eiformat(const char** s, union arg** args, ei_x_buff* x);
@@ -106,6 +108,8 @@ static int eiformat(const char** fmt, union arg** args, ei_x_buff* x)
default:
if (isdigit((int)*p))
res = pdigit(&p, x);
+ else if ((*p == '-' || *p == '+') && isdigit((int)*(p+1)))
+ res = pdigit(&p, x);
else if (islower((int)*p))
res = patom(&p, x);
else
@@ -149,6 +153,8 @@ static int pdigit(const char** fmt, ei_x_buff* x)
double d;
long l;
+ if (**fmt == '-' || **fmt == '+')
+ (*fmt)++;
for (;;) {
c = *(*fmt)++;
if (isdigit((int)c))
@@ -220,12 +226,14 @@ static int pquotedatom(const char** fmt, ei_x_buff* x)
/*
* The format letters are:
* a - An atom
+ * c - A character
* s - A string
* i - An integer
* l - A long integer
* u - An unsigned long integer
* f - A float
* d - A double float
+ * p - An Erlang PID
*/
static int pformat(const char** fmt, union arg** args, ei_x_buff* x)
{
@@ -236,6 +244,10 @@ static int pformat(const char** fmt, union arg** args, ei_x_buff* x)
res = ei_x_encode_atom(x, (*args)->s);
(*args)++;
break;
+ case 'c':
+ res = ei_x_encode_char(x, (*args)->c);
+ (*args)++;
+ break;
case 's':
res = ei_x_encode_string(x, (*args)->s);
(*args)++;
@@ -257,6 +269,10 @@ static int pformat(const char** fmt, union arg** args, ei_x_buff* x)
res = ei_x_encode_double(x, (*args)->d);
(*args)++;
break;
+ case 'p':
+ res = ei_x_encode_pid(x, (*args)->pid);
+ (*args)++;
+ break;
default:
res = -1;
break;
@@ -392,6 +408,9 @@ static int read_args(const char* fmt, va_list ap, union arg **argp)
return -1; /* Error, string not complete */
}
switch (*p++) {
+ case 'c':
+ args[i++].c = (char) va_arg(ap, int);
+ break;
case 'a':
case 's':
args[i++].s = va_arg(ap, char*);
@@ -411,6 +430,9 @@ static int read_args(const char* fmt, va_list ap, union arg **argp)
case 'd':
args[i++].d = va_arg(ap, double);
break;
+ case 'p':
+ args[i++].pid = va_arg(ap, erlang_pid*);
+ break;
default:
ei_free(args); /* Invalid specifier */
return -1;
diff --git a/lib/erl_interface/src/misc/ei_portio.c b/lib/erl_interface/src/misc/ei_portio.c
index c4e397f1e0..a3f6f63fff 100644
--- a/lib/erl_interface/src/misc/ei_portio.c
+++ b/lib/erl_interface/src/misc/ei_portio.c
@@ -166,6 +166,9 @@ int ei_writev_fill_t(int fd, const struct iovec *iov, int iovcnt, unsigned
if (done < sum) {
if (iov_base == NULL) {
iov_base = malloc(sizeof(struct iovec) * iovcnt);
+ if (iov_base == NULL) {
+ return -1;
+ }
memcpy(iov_base, iov, sizeof(struct iovec) * iovcnt);
current_iov = iov_base;
}
diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c
index 98473f780e..5fc6b3542c 100644
--- a/lib/erl_interface/src/misc/ei_printterm.c
+++ b/lib/erl_interface/src/misc/ei_printterm.c
@@ -253,7 +253,8 @@ static int print_term(FILE* fp, ei_x_buff* x,
erlang_big *b;
char *ds;
- b = ei_alloc_big(n);
+ if ( (b = ei_alloc_big(n)) == NULL) goto err;
+
if (ei_decode_big(buf, index, b) < 0) {
ei_free_big(b);
goto err;
diff --git a/lib/erl_interface/src/misc/show_msg.c b/lib/erl_interface/src/misc/show_msg.c
index 14bea5e01f..194296798b 100644
--- a/lib/erl_interface/src/misc/show_msg.c
+++ b/lib/erl_interface/src/misc/show_msg.c
@@ -181,11 +181,6 @@ int ei_show_sendmsg(FILE *stream, const char *header, const char *msgbuf)
mbuf = header;
break;
- case ERL_NODE_LINK:
- /* nothing to do */
- mbuf = header;
- break;
-
default:
break;
}
@@ -241,10 +236,6 @@ static void show_msg(FILE *stream, int direction, const erlang_msg *msg,
show_pid(stream,&msg->to);
break;
- case ERL_NODE_LINK:
- fprintf(stream,"NODE_LINK");
- break;
-
case ERL_REG_SEND:
fprintf(stream,"REG_SEND From: ");
show_pid(stream,&msg->from);
diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c
index 448de9aa23..33ff6da7c9 100644
--- a/lib/erl_interface/src/prog/erl_call.c
+++ b/lib/erl_interface/src/prog/erl_call.c
@@ -118,7 +118,6 @@ static void usage_arg(const char *progname, const char *switchname);
static void usage_error(const char *progname, const char *switchname);
static void usage(const char *progname);
static int get_module(char **mbuf, char **mname);
-static struct hostent* get_hostent(char *host);
static int do_connect(ei_cnode *ec, char *nodename, struct call_flags *flags);
static int read_stdin(char **buf);
static void split_apply_string(char *str, char **mod,
@@ -367,8 +366,8 @@ int erl_call(int argc, char **argv)
* Expand name to a real name (may be ip-address)
*/
/* FIXME better error string */
- if ((hp = get_hostent(host)) == 0) {
- fprintf(stderr,"erl_call: can't get_hostent(%s)\n", host);
+ if ((hp = ei_gethostbyname(host)) == 0) {
+ fprintf(stderr,"erl_call: can't ei_gethostbyname(%s)\n", host);
exit(1);
}
/* If shortnames, cut off the name at first '.' */
@@ -604,32 +603,6 @@ int erl_call(int argc, char **argv)
*
***************************************************************************/
-/*
- * Get host entry (by address or name)
- */
-/* FIXME: will fail on names like '2fun4you'. */
-static struct hostent* get_hostent(char *host)
-{
- if (isdigit((int)*host)) {
- struct in_addr ip_addr;
- int b1, b2, b3, b4;
- long addr;
-
- /* FIXME: Use inet_aton() (or inet_pton() and get v6 for free). */
- if (sscanf(host, "%d.%d.%d.%d", &b1, &b2, &b3, &b4) != 4) {
- return NULL;
- }
- addr = inet_addr(host);
- ip_addr.s_addr = htonl(addr);
-
- return ei_gethostbyaddr((char *)&ip_addr,sizeof(struct in_addr), AF_INET);
- }
-
- return ei_gethostbyname(host);
-} /* get_hostent */
-
-
-
/*
* This function does only return on success.
diff --git a/lib/erl_interface/src/registry/reg_dump.c b/lib/erl_interface/src/registry/reg_dump.c
index 50a6949177..dfec96b43c 100644
--- a/lib/erl_interface/src/registry/reg_dump.c
+++ b/lib/erl_interface/src/registry/reg_dump.c
@@ -157,7 +157,7 @@ static int mn_send_delete(int fd, erlang_pid *mnesia, const char *key)
int len = strlen(key) + 32; /* 32 is a slight overestimate */
if (len > EISMALLBUF)
- if (!(dbuf = malloc(index)))
+ if (!(dbuf = malloc(len)))
return -1;
msgbuf = (dbuf ? dbuf : sbuf);
@@ -187,7 +187,7 @@ static int mn_send_write(int fd, erlang_pid *mnesia, const char *key, ei_reg_obj
int len = 32 + keylen + obj->size;
if (len > EISMALLBUF)
- if (!(dbuf = malloc(index)))
+ if (!(dbuf = malloc(len)))
return -1;
msgbuf = (dbuf ? dbuf : sbuf);
diff --git a/lib/erl_interface/src/registry/reg_restore.c b/lib/erl_interface/src/registry/reg_restore.c
index 27918d2364..aeb33c784a 100644
--- a/lib/erl_interface/src/registry/reg_restore.c
+++ b/lib/erl_interface/src/registry/reg_restore.c
@@ -266,7 +266,7 @@ int ei_reg_restore(int fd, ei_reg *reg, const char *mntab)
/* make sure receive buffer can handle largest expected message */
len = maxkey + maxobj + 512;
if (len > EISMALLBUF)
- if (!(dbuf = malloc(index))) {
+ if (!(dbuf = malloc(len))) {
ei_send_exit(fd,&self,&mnesia,"cannot allocate space for incoming data");
return -1;
}
diff --git a/lib/erl_interface/test/Makefile b/lib/erl_interface/test/Makefile
index b7a1a4e4d8..c8aa6f5a6d 100644
--- a/lib/erl_interface/test/Makefile
+++ b/lib/erl_interface/test/Makefile
@@ -33,6 +33,7 @@ MODULES= \
ei_print_SUITE \
ei_tmo_SUITE \
erl_connect_SUITE \
+ erl_global_SUITE \
erl_eterm_SUITE \
erl_ext_SUITE \
erl_format_SUITE \
@@ -41,9 +42,9 @@ MODULES= \
runner
SPEC_FILES = \
- erl_interface.spec \
- erl_interface.dynspec \
- erl_interface.spec.vxworks
+ erl_interface.spec
+
+COVER_FILE = erl_interface.cover
ERL_FILES = $(MODULES:%=%.erl)
@@ -71,7 +72,7 @@ release_spec:
release_tests_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SPEC_FILES) $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/erl_interface/test/ei_accept_SUITE.erl b/lib/erl_interface/test/ei_accept_SUITE.erl
index a97c874e5f..d3d37fce6c 100644
--- a/lib/erl_interface/test/ei_accept_SUITE.erl
+++ b/lib/erl_interface/test/ei_accept_SUITE.erl
@@ -20,21 +20,42 @@
%%
-module(ei_accept_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ei_accept_SUITE_data/ei_accept_test_cases.hrl").
--export([all/1, init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
ei_accept/1, ei_threaded_accept/1]).
-import(runner, [get_term/1,send_term/2]).
-all(suite) -> [ei_accept, ei_threaded_accept].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [ei_accept, ei_threaded_accept].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
Dog = ?t:timetrap(?t:seconds(30)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/erl_interface/test/ei_connect_SUITE.erl b/lib/erl_interface/test/ei_connect_SUITE.erl
index fe82a73ef9..47247dd891 100644
--- a/lib/erl_interface/test/ei_connect_SUITE.erl
+++ b/lib/erl_interface/test/ei_connect_SUITE.erl
@@ -20,37 +20,53 @@
%%
-module(ei_connect_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ei_connect_SUITE_data/ei_connect_test_cases.hrl").
-export([
- all/1,
- init_per_testcase/2,
- fin_per_testcase/2,
-
- ei_send/1,
- ei_reg_send/1,
- ei_rpc/1,
- rpc_test/1,
- ei_send_funs/1,
- ei_threaded_send/1,
- ei_set_get_tracelevel/1
+ all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,
+ end_per_testcase/2,
+
+ ei_send/1,
+ ei_reg_send/1,
+ ei_format_pid/1,
+ ei_rpc/1,
+ rpc_test/1,
+ ei_send_funs/1,
+ ei_threaded_send/1,
+ ei_set_get_tracelevel/1
]).
-import(runner, [get_term/1,send_term/2]).
-all(suite) -> [ ei_send,
- ei_reg_send,
- ei_rpc,
- ei_send_funs,
- ei_threaded_send,
- ei_set_get_tracelevel].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [ei_send, ei_reg_send, ei_rpc, ei_format_pid, ei_send_funs,
+ ei_threaded_send, ei_set_get_tracelevel].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
init_per_testcase(_Case, Config) ->
Dog = ?t:timetrap(?t:minutes(0.25)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -67,6 +83,19 @@ ei_send(Config) when is_list(Config) ->
?line runner:recv_eot(P),
ok.
+ei_format_pid(Config) when is_list(Config) ->
+ ?line S = self(),
+ ?line P = runner:start(?interpret),
+ ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ ?line {ok,Fd} = ei_connect(P, node()),
+
+ ?line ok = ei_format_pid(P, Fd, S),
+ ?line receive S -> ok end,
+
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
ei_send_funs(Config) when is_list(Config) ->
?line P = runner:start(?interpret),
?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
@@ -189,6 +218,10 @@ ei_send(P, Fd, To, Msg) ->
send_command(P, ei_send, [Fd,To,Msg]),
get_send_result(P).
+ei_format_pid(P, Fd, To) ->
+ send_command(P, ei_format_pid, [Fd, To]),
+ get_send_result(P).
+
ei_send_funs(P, Fd, To, Msg) ->
send_command(P, ei_send_funs, [Fd,To,Msg]),
get_send_result(P).
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
index debd3e789b..8183ac9dd8 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
@@ -35,6 +35,7 @@
static void cmd_ei_connect_init(char* buf, int len);
static void cmd_ei_connect(char* buf, int len);
static void cmd_ei_send(char* buf, int len);
+static void cmd_ei_format_pid(char* buf, int len);
static void cmd_ei_send_funs(char* buf, int len);
static void cmd_ei_reg_send(char* buf, int len);
static void cmd_ei_rpc(char* buf, int len);
@@ -57,6 +58,7 @@ static struct {
"ei_reg_send", 3, cmd_ei_reg_send,
"ei_rpc", 4, cmd_ei_rpc,
"ei_set_get_tracelevel", 1, cmd_ei_set_get_tracelevel,
+ "ei_format_pid", 2, cmd_ei_format_pid,
};
@@ -111,7 +113,7 @@ static void cmd_ei_connect_init(char* buf, int len)
ei_x_buff res;
if (ei_decode_long(buf, &index, &l) < 0)
fail("expected int");
- sprintf(b, "c%d", l);
+ sprintf(b, "c%ld", l);
/* FIXME don't use internal and maybe use skip?! */
ei_get_type_internal(buf, &index, &type, &size);
if (ei_decode_atom(buf, &index, cookie) < 0)
@@ -183,6 +185,25 @@ static void cmd_ei_send(char* buf, int len)
ei_x_free(&x);
}
+static void cmd_ei_format_pid(char* buf, int len)
+{
+ int index = 0;
+ long fd;
+ erlang_pid pid;
+ ei_x_buff x;
+
+ if (ei_decode_long(buf, &index, &fd) < 0)
+ fail("expected long");
+ if (ei_decode_pid(buf, &index, &pid) < 0)
+ fail("expected pid (node)");
+ if (ei_x_new_with_version(&x) < 0)
+ fail("ei_x_new_with_version");
+ if (ei_x_format_wo_ver(&x, "~p", &pid) < 0)
+ fail("ei_x_format_wo_ver");
+ send_errno_result(ei_send(fd, &pid, x.buff, x.index));
+ ei_x_free(&x);
+}
+
static void cmd_ei_send_funs(char* buf, int len)
{
int index = 0, n;
diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl
index 09a37409f2..8a653078a7 100644
--- a/lib/erl_interface/test/ei_decode_SUITE.erl
+++ b/lib/erl_interface/test/ei_decode_SUITE.erl
@@ -20,12 +20,13 @@
%%
-module(ei_decode_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ei_decode_SUITE_data/ei_decode_test_cases.hrl").
-export(
[
- all/1,
+ all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
test_ei_decode_long/1,
test_ei_decode_ulong/1,
test_ei_decode_longlong/1,
@@ -35,16 +36,29 @@
test_ei_decode_misc/1
]).
-all(suite) ->
- [
- test_ei_decode_long,
- test_ei_decode_ulong,
- test_ei_decode_longlong,
- test_ei_decode_ulonglong,
- test_ei_decode_char,
- test_ei_decode_nonoptimal,
- test_ei_decode_misc
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [test_ei_decode_long, test_ei_decode_ulong,
+ test_ei_decode_longlong, test_ei_decode_ulonglong,
+ test_ei_decode_char, test_ei_decode_nonoptimal,
+ test_ei_decode_misc].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% ---------------------------------------------------------------------------
@@ -232,7 +246,7 @@ send_integers(P) ->
?line send_term_as_binary(P, 16#80000000), % SMALL_BIG_EXT new smallest pos(*)
?line send_term_as_binary(P,-16#80000001), % SMALL_BIG_EXT new largest neg (*)
- case erlang:system_info(wordsize) of
+ case erlang:system_info({wordsize,external}) of
4 ->
?line send_term_as_binary(P, 16#80000000),% SMALL_BIG_EXT u32
?line send_term_as_binary(P, 16#ffffffff),% SMALL_BIG_EXT largest u32
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE.erl b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
index c19c1d0887..0a1eda41e1 100644
--- a/lib/erl_interface/test/ei_decode_encode_SUITE.erl
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-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
@@ -20,19 +20,36 @@
%%
-module(ei_decode_encode_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ei_decode_encode_SUITE_data/ei_decode_encode_test_cases.hrl").
-export(
[
- all/1,
+ all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
test_ei_decode_encode/1
]).
-all(suite) ->
- [
- test_ei_decode_encode
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [test_ei_decode_encode].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% ---------------------------------------------------------------------------
diff --git a/lib/erl_interface/test/ei_encode_SUITE.erl b/lib/erl_interface/test/ei_encode_SUITE.erl
index 6b9de4f093..1674274bc9 100644
--- a/lib/erl_interface/test/ei_encode_SUITE.erl
+++ b/lib/erl_interface/test/ei_encode_SUITE.erl
@@ -20,12 +20,13 @@
%%
-module(ei_encode_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ei_encode_SUITE_data/ei_encode_test_cases.hrl").
-export(
[
- all/1,
+ all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
test_ei_encode_long/1,
test_ei_encode_ulong/1,
test_ei_encode_longlong/1,
@@ -35,16 +36,29 @@
test_ei_encode_fails/1
]).
-all(suite) ->
- [
- test_ei_encode_long,
- test_ei_encode_ulong,
- test_ei_encode_longlong,
- test_ei_encode_ulonglong,
- test_ei_encode_char,
- test_ei_encode_misc,
- test_ei_encode_fails
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [test_ei_encode_long, test_ei_encode_ulong,
+ test_ei_encode_longlong, test_ei_encode_ulonglong,
+ test_ei_encode_char, test_ei_encode_misc,
+ test_ei_encode_fails].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% ---------------------------------------------------------------------------
diff --git a/lib/erl_interface/test/ei_format_SUITE.erl b/lib/erl_interface/test/ei_format_SUITE.erl
index 7871f07ae9..a6eafc79cf 100644
--- a/lib/erl_interface/test/ei_format_SUITE.erl
+++ b/lib/erl_interface/test/ei_format_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -20,15 +20,17 @@
%%
-module(ei_format_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ei_format_SUITE_data/ei_format_test_cases.hrl").
-export([
- format_wo_ver/1,
- all/1,
- atoms/1,
- tuples/1,
- lists/1
+ format_wo_ver/1,
+ all/0, suite/0,groups/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ atoms/1,
+ tuples/1,
+ lists/1
]).
-import(runner, [get_term/1]).
@@ -36,12 +38,26 @@
%% This test suite test the erl_format() function.
%% It uses the port program "ei_format_test".
-all(suite) -> [
- format_wo_ver,
- atoms,
- tuples,
- lists
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [format_wo_ver, atoms, tuples, lists].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Tests formatting various atoms.
@@ -155,7 +171,7 @@ format_wo_ver(suite) -> [];
format_wo_ver(Config) when is_list(Config) ->
?line P = runner:start(?format_wo_ver),
- ?line {term, [{a, "b"}, {c, 10}]} = get_term(P),
+ ?line {term, [-1, 2, $c, {a, "b"}, {c, 10}]} = get_term(P),
?line runner:recv_eot(P),
ok.
diff --git a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
index a969ded3dc..a6eeb25abc 100644
--- a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
+++ b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
@@ -176,7 +176,7 @@ TESTCASE(format_wo_ver) {
ei_x_buff x;
ei_x_new (&x);
- ei_x_format(&x, "[{~a,~s},{~a,~i}]", "a", "b", "c", 10);
+ ei_x_format(&x, "[-1, +2, ~c, {~a,~s},{~a,~i}]", 'c', "a", "b", "c", 10);
send_bin_term(&x);
free(x.buff);
diff --git a/lib/erl_interface/test/ei_print_SUITE.erl b/lib/erl_interface/test/ei_print_SUITE.erl
index a0f15338c6..7e656650a8 100644
--- a/lib/erl_interface/test/ei_print_SUITE.erl
+++ b/lib/erl_interface/test/ei_print_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -20,17 +20,38 @@
%%
-module(ei_print_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ei_print_SUITE_data/ei_print_test_cases.hrl").
--export([all/1, atoms/1, tuples/1, lists/1, strings/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ atoms/1, tuples/1, lists/1, strings/1]).
-import(runner, [get_term/1]).
%% This test suite test the ei_print() function.
%% It uses the port program "ei_format_test".
-all(suite) -> [atoms, tuples, lists, strings].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [atoms, tuples, lists, strings].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Tests formatting various atoms.
diff --git a/lib/erl_interface/test/ei_tmo_SUITE.erl b/lib/erl_interface/test/ei_tmo_SUITE.erl
index e7a2465421..52cf2b160d 100644
--- a/lib/erl_interface/test/ei_tmo_SUITE.erl
+++ b/lib/erl_interface/test/ei_tmo_SUITE.erl
@@ -20,18 +20,39 @@
%%
-module(ei_tmo_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/inet.hrl").
-include("ei_tmo_SUITE_data/ei_tmo_test_cases.hrl").
-define(dummy_host,test01).
--export([all/1, init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
framework_check/1, ei_accept_tmo/1, ei_connect_tmo/1, ei_send_tmo/1,
ei_recv_tmo/1]).
-all(suite) -> [framework_check,ei_accept_tmo,ei_connect_tmo,
- ei_send_tmo,ei_recv_tmo].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [framework_check, ei_accept_tmo, ei_connect_tmo,
+ ei_send_tmo, ei_recv_tmo].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
Dog = ?t:timetrap(?t:minutes(1)),
@@ -43,7 +64,7 @@ init_per_testcase(_Case, Config) ->
end,
[{vxsim,Bool},{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/erl_interface/test/erl_connect_SUITE.erl b/lib/erl_interface/test/erl_connect_SUITE.erl
index 0d6539d98f..0483a393d4 100644
--- a/lib/erl_interface/test/erl_connect_SUITE.erl
+++ b/lib/erl_interface/test/erl_connect_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -20,22 +20,42 @@
%%
-module(erl_connect_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("erl_connect_SUITE_data/erl_connect_test_cases.hrl").
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
erl_send/1,erl_reg_send/1, erl_send_cookie_file/1]).
-import(runner, [get_term/1,send_term/2]).
-all(suite) ->
- [erl_send,erl_reg_send,erl_send_cookie_file].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [erl_send, erl_reg_send, erl_send_cookie_file].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
Dog = ?t:timetrap(?t:minutes(0.25)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/erl_interface/test/erl_eterm_SUITE.erl b/lib/erl_interface/test/erl_eterm_SUITE.erl
index 634e2f9aa0..21de1efa2e 100644
--- a/lib/erl_interface/test/erl_eterm_SUITE.erl
+++ b/lib/erl_interface/test/erl_eterm_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
%%
-module(erl_eterm_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("erl_eterm_SUITE_data/eterm_test_cases.hrl").
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -33,7 +33,9 @@
%%% 5. Miscellanous functions.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--export([all/1, build_terms/1, round_trip_conversion/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ build_terms/1, round_trip_conversion/1,
decode_terms/1, decode_float/1,
t_erl_mk_int/1, t_erl_mk_list/1,
basic_copy/1,
@@ -73,38 +75,38 @@
%% This test suite controls the running of the C language functions
%% in eterm_test.c and print_term.c.
-all(suite) -> [build_terms, round_trip_conversion,
- decode_terms, decode_float,
- t_erl_mk_int, t_erl_mk_list,
- basic_copy,
- t_erl_mk_atom,
- t_erl_mk_binary,
- t_erl_mk_empty_list,
- t_erl_mk_float,
- t_erl_mk_pid,
- t_erl_mk_xpid,
- t_erl_mk_port,
- t_erl_mk_xport,
- t_erl_mk_ref,
- t_erl_mk_long_ref,
- t_erl_mk_string,
- t_erl_mk_estring,
- t_erl_mk_tuple,
- t_erl_mk_uint,
- t_erl_mk_var,
- t_erl_size,
- t_erl_var_content,
- t_erl_element,
- t_erl_cons,
- t_erl_length, t_erl_hd, t_erl_tl,
- type_checks, extractor_macros,
- t_erl_iolist_length, t_erl_iolist_to_binary,
- t_erl_iolist_to_string,
- erl_print_term, print_string,
- t_erl_free_compound,
- high_chaparal,
- broken_data,
- cnode_1].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [build_terms, round_trip_conversion, decode_terms,
+ decode_float, t_erl_mk_int, t_erl_mk_list, basic_copy,
+ t_erl_mk_atom, t_erl_mk_binary, t_erl_mk_empty_list,
+ t_erl_mk_float, t_erl_mk_pid, t_erl_mk_xpid,
+ t_erl_mk_port, t_erl_mk_xport, t_erl_mk_ref,
+ t_erl_mk_long_ref, t_erl_mk_string, t_erl_mk_estring,
+ t_erl_mk_tuple, t_erl_mk_uint, t_erl_mk_var, t_erl_size,
+ t_erl_var_content, t_erl_element, t_erl_cons,
+ t_erl_length, t_erl_hd, t_erl_tl, type_checks,
+ extractor_macros, t_erl_iolist_length,
+ t_erl_iolist_to_binary, t_erl_iolist_to_string,
+ erl_print_term, print_string, t_erl_free_compound,
+ high_chaparal, broken_data, cnode_1].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
index f273efd532..80d7f69520 100644
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ * Copyright Ericsson AB 1997-2010. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -98,14 +98,30 @@ static void encode_decode(ETERM* original, const char* text)
{
static unsigned char encoded[16*1024];
ETERM* new_terms;
- int bytes = erl_encode(original, encoded);
+ ETERM* head;
+ int bytes;
+ int len;
+
+ /* If a list, check the elements one by one first */
+ head = erl_hd(original);
+ if (head != NULL) {
+ encode_decode(head, "CAR");
+ encode_decode(erl_tl(original), "CDR");
+ }
+ bytes = erl_encode(original, encoded);
if (bytes == 0) {
fail("failed to encode terms");
}
else if (bytes > sizeof(encoded)) {
fail("encoded terms buffer overflow");
}
+ else if (bytes != (len=erl_term_len(original))) {
+ fprintf(stderr, "bytes(%d) != len(%d) for term ", bytes, len);
+ erl_print_term(stderr, original);
+ fprintf(stderr, " [%s]\r\n", text);
+ fail("erl_encode and erl_term_len do not agree");
+ }
else if ((new_terms = erl_decode(encoded)) == NULL) {
fail("failed to decode terms");
}
diff --git a/lib/erl_interface/test/erl_ext_SUITE.erl b/lib/erl_interface/test/erl_ext_SUITE.erl
index dbafea0e39..38b01e73cf 100644
--- a/lib/erl_interface/test/erl_ext_SUITE.erl
+++ b/lib/erl_interface/test/erl_ext_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,27 +20,42 @@
%%
-module(erl_ext_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("erl_ext_SUITE_data/ext_test_cases.hrl").
-export([
- all/1,
- compare_tuple/1,
- compare_list/1,
- compare_string/1,
- compare_list_string/1,
- compare_nc_ext/1
+ all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ compare_tuple/1,
+ compare_list/1,
+ compare_string/1,
+ compare_list_string/1,
+ compare_nc_ext/1
]).
-import(runner, [get_term/1]).
-all(suite) -> [
- compare_tuple,
- compare_list,
- compare_string,
- compare_list_string,
- compare_nc_ext
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [compare_tuple, compare_list, compare_string,
+ compare_list_string, compare_nc_ext].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
compare_tuple(suite) -> [];
compare_tuple(doc) -> [];
diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
index ba1a6c66da..59e0e0cce7 100644
--- a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
+++ b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
@@ -82,6 +82,11 @@ TESTCASE(compare_list) {
// erlang:term_to_binary([34,{a,n},a,erlang])
unsigned char term2[] = {131,108,0,0,0,4,97,34,104,2,100,0,1,97,100,0,1,110,100,0,1,97,100,0,6,101,114,108,97,110,103,106};
+ // erlang:term_to_binary([0])
+ unsigned char term3[] = {131,107,0,1,0};
+ // erlang:term_to_binary([0, 1000])
+ unsigned char term4[] = {131,108,0,0,0,2,97,0,98,0,0,3,232,106};
+
erl_init(NULL, 0);
start_a = term1;
start_b = term2;
@@ -90,6 +95,13 @@ TESTCASE(compare_list) {
test_compare_ext("lists", start_a, end_a, start_b, end_b, 1);
+ start_a = term3;
+ start_b = term4;
+ end_a = term3 + sizeof(term3);
+ end_b = term4 + sizeof(term4);
+
+ test_compare_ext("lists1", start_a, end_a, start_b, end_b, -1);
+
report(1);
}
diff --git a/lib/erl_interface/test/erl_format_SUITE.erl b/lib/erl_interface/test/erl_format_SUITE.erl
index 81a0bca80f..9905669ef9 100644
--- a/lib/erl_interface/test/erl_format_SUITE.erl
+++ b/lib/erl_interface/test/erl_format_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,17 +20,37 @@
%%
-module(erl_format_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("erl_format_SUITE_data/format_test_cases.hrl").
--export([all/1, atoms/1, tuples/1, lists/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, atoms/1, tuples/1, lists/1]).
-import(runner, [get_term/1]).
%% This test suite test the erl_format() function.
%% It uses the port program "format_test".
-all(suite) -> [atoms, tuples, lists].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [atoms, tuples, lists].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Tests formatting various atoms.
diff --git a/lib/erl_interface/test/erl_global_SUITE.erl b/lib/erl_interface/test/erl_global_SUITE.erl
new file mode 100644
index 0000000000..604d72dd24
--- /dev/null
+++ b/lib/erl_interface/test/erl_global_SUITE.erl
@@ -0,0 +1,142 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(erl_global_SUITE).
+
+-include_lib("test_server/include/test_server.hrl").
+-include("erl_global_SUITE_data/erl_global_test_cases.hrl").
+
+-export([all/0,suite/0,init_per_suite/1,end_per_suite/1,
+ init_per_testcase/2,end_per_testcase/2,
+ erl_global_registration/1, erl_global_whereis/1, erl_global_names/1]).
+
+-import(runner, [get_term/1,send_term/2]).
+
+-define(GLOBAL_NAME, global_register_node_test).
+
+all() ->
+ [erl_global_registration, erl_global_whereis, erl_global_names].
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?t:minutes(0.25)),
+ [{watchdog, Dog}|Config].
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+erl_global_registration(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0),
+
+ ?line ok = erl_global_register(P, Fd, ?GLOBAL_NAME),
+ ?line ok = erl_global_unregister(P, Fd, ?GLOBAL_NAME),
+
+ ?line 0 = erl_close_connection(P,Fd),
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+erl_global_whereis(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0),
+
+ ?line Self = self(),
+ ?line yes = global:register_name(?GLOBAL_NAME, Self),
+ ?line Self = erl_global_whereis(P, Fd, ?GLOBAL_NAME),
+ ?line global:unregister_name(?GLOBAL_NAME),
+ ?line 0 = erl_close_connection(P, Fd),
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+erl_global_names(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0),
+
+ ?line Self = self(),
+ ?line global:register_name(?GLOBAL_NAME, Self),
+ ?line {Names1, _N1} = erl_global_names(P, Fd),
+ ?line true = lists:member(atom_to_list(?GLOBAL_NAME), Names1),
+ ?line global:unregister_name(?GLOBAL_NAME),
+ ?line {Names2, _N2} = erl_global_names(P, Fd),
+ ?line false = lists:member(atom_to_list(?GLOBAL_NAME), Names2),
+ ?line 0 = erl_close_connection(P, Fd),
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+%%% Interface functions for erl_interface functions.
+
+erl_connect(P, Node, Num, Cookie, Creation) ->
+ send_command(P, erl_connect, [Num, Node, Cookie, Creation]),
+ case get_term(P) of
+ {term,{Fd,_}} when Fd >= 0 -> {ok,Fd};
+ {term,{-1,Errno}} -> {error,Errno}
+ end.
+
+erl_close_connection(P, FD) ->
+ send_command(P, erl_close_connection, [FD]),
+ case get_term(P) of
+ {term,Int} when is_integer(Int) -> Int
+ end.
+
+erl_global_register(P, Fd, Name) ->
+ send_command(P, erl_global_register, [Fd,Name]),
+ get_send_result(P).
+
+erl_global_whereis(P, Fd, Name) ->
+ send_command(P, erl_global_whereis, [Fd,Name]),
+ case get_term(P) of
+ {term, What} ->
+ What
+ end.
+
+erl_global_names(P, Fd) ->
+ send_command(P, erl_global_names, [Fd]),
+ case get_term(P) of
+ {term, What} ->
+ What
+ end.
+
+erl_global_unregister(P, Fd, Name) ->
+ send_command(P, erl_global_unregister, [Fd,Name]),
+ get_send_result(P).
+
+get_send_result(P) ->
+ case get_term(P) of
+ {term,{1,_}} -> ok;
+ {term,{0, 0}} -> ok;
+ {term,{-1, Errno}} -> {error,Errno};
+ {term,{_,_}}->
+ ?t:fail(bad_return_value)
+ end.
+
+send_command(P, Name, Args) ->
+ runner:send_term(P, {Name,list_to_tuple(Args)}).
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..8e3fcb924e
--- /dev/null
+++ b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+erl_global_test_decl.c: erl_global_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run erl_global_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..ef846bc440
--- /dev/null
+++ b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src
@@ -0,0 +1,41 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBERL = $(LIBPATH)/@erl_interface_lib@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/runner@obj@ \
+ $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+OBJS = erl_global_test@obj@ erl_global_test_decl@obj@
+
+all: erl_global_test@exe@
+
+erl_global_test@exe@: $(OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(OBJS) $(LIBFLAGS)
+
+clean:
+ $(RM) $(OBJS)
+ $(RM) erl_global_test@exe@
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c b/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
new file mode 100644
index 0000000000..dc0d8a0091
--- /dev/null
+++ b/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
@@ -0,0 +1,263 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Purpose: Tests the functions in erl_global.c.
+ *
+ * See the erl_global_SUITE.erl file for a "table of contents".
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "runner.h"
+
+static void cmd_erl_connect(ETERM* args);
+static void cmd_erl_global_register(ETERM *args);
+static void cmd_erl_global_whereis(ETERM *args);
+static void cmd_erl_global_names(ETERM *args);
+static void cmd_erl_global_unregister(ETERM *args);
+static void cmd_erl_close_connection(ETERM *args);
+
+static void send_errno_result(int value);
+
+static struct {
+ char* name;
+ int num_args; /* Number of arguments. */
+ void (*func)(ETERM* args);
+} commands[] = {
+ "erl_connect", 4, cmd_erl_connect,
+ "erl_close_connection", 1, cmd_erl_close_connection,
+ "erl_global_register", 2, cmd_erl_global_register,
+ "erl_global_whereis", 2, cmd_erl_global_whereis,
+ "erl_global_names", 1, cmd_erl_global_names,
+ "erl_global_unregister", 2, cmd_erl_global_unregister,
+};
+
+
+/*
+ * Sends a list contaning all data types to the Erlang side.
+ */
+
+TESTCASE(interpret)
+{
+ ETERM* term;
+
+ erl_init(NULL, 0);
+
+ outer_loop:
+
+ term = get_term();
+
+ if (term == NULL) {
+ report(1);
+ return;
+ } else {
+ ETERM* Func;
+ ETERM* Args;
+ int i;
+
+ if (!ERL_IS_TUPLE(term) || ERL_TUPLE_SIZE(term) != 2) {
+ fail("term should be a tuple of size 2");
+ }
+
+ Func = erl_element(1, term);
+ if (!ERL_IS_ATOM(Func)) {
+ fail("function name should be an atom");
+ }
+ Args = erl_element(2, term);
+ if (!ERL_IS_TUPLE(Args)) {
+ fail("function arguments should be a tuple");
+ }
+ erl_free_term(term);
+ for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
+ int n = strlen(commands[i].name);
+ if (ERL_ATOM_SIZE(Func) != n) {
+ continue;
+ }
+ if (memcmp(ERL_ATOM_PTR(Func), commands[i].name, n) == 0) {
+ erl_free_term(Func);
+ if (ERL_TUPLE_SIZE(Args) != commands[i].num_args) {
+ fail("wrong number of arguments");
+ }
+ commands[i].func(Args);
+ erl_free_term(Args);
+ goto outer_loop;
+ }
+ }
+ fail("bad command");
+ }
+}
+
+#define VERIFY_TYPE(Test, Term) \
+if (!Test(Term)) { \
+ fail("wrong type for " #Term); \
+} else { \
+}
+
+static void
+cmd_erl_connect(ETERM* args)
+{
+ ETERM* number;
+ ETERM* node;
+ ETERM* cookie;
+
+ int res;
+ char buffer[256];
+
+ number = ERL_TUPLE_ELEMENT(args, 0);
+ VERIFY_TYPE(ERL_IS_INTEGER, number);
+ node = ERL_TUPLE_ELEMENT(args, 1);
+ VERIFY_TYPE(ERL_IS_ATOM, node);
+ cookie = ERL_TUPLE_ELEMENT(args, 2);
+ VERIFY_TYPE(ERL_IS_ATOM, cookie);
+
+ if (ERL_ATOM_SIZE(cookie) == 0) {
+ res = erl_connect_init(ERL_INT_VALUE(number), 0, 0);
+ } else {
+ memcpy(buffer, ERL_ATOM_PTR(cookie), ERL_ATOM_SIZE(cookie));
+ buffer[ERL_ATOM_SIZE(cookie)] = '\0';
+ res = erl_connect_init(ERL_INT_VALUE(number), buffer, 0);
+ }
+
+ if(!res) {
+ send_errno_result(res);
+ return;
+ }
+
+ memcpy(buffer, ERL_ATOM_PTR(node), ERL_ATOM_SIZE(node));
+ buffer[ERL_ATOM_SIZE(node)] = '\0';
+ send_errno_result(erl_connect(buffer));
+}
+
+static void
+cmd_erl_close_connection(ETERM* args)
+{
+ ETERM* number;
+ ETERM* res;
+
+ number = ERL_TUPLE_ELEMENT(args, 0);
+ VERIFY_TYPE(ERL_IS_INTEGER, number);
+ res = erl_mk_int(erl_close_connection(ERL_INT_VALUE(number)));
+ send_term(res);
+ erl_free_term(res);
+}
+
+static void
+cmd_erl_global_register(ETERM* args)
+{
+ ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
+ ETERM* name = ERL_TUPLE_ELEMENT(args, 1);
+ ETERM* pid = erl_mk_pid(erl_thisnodename(), 14, 0, 0);
+
+ char buffer[256];
+
+ VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
+ VERIFY_TYPE(ERL_IS_ATOM, name);
+
+ memcpy(buffer, ERL_ATOM_PTR(name), ERL_ATOM_SIZE(name));
+ buffer[ERL_ATOM_SIZE(name)] = '\0';
+
+ send_errno_result(erl_global_register(ERL_INT_VALUE(fd_term), buffer, pid));
+ erl_free_term(pid);
+}
+
+static void
+cmd_erl_global_whereis(ETERM* args)
+{
+ ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
+ ETERM* name = ERL_TUPLE_ELEMENT(args, 1);
+ ETERM* pid = NULL;
+
+ char buffer[256];
+
+ VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
+ VERIFY_TYPE(ERL_IS_ATOM, name);
+
+ memcpy(buffer, ERL_ATOM_PTR(name), ERL_ATOM_SIZE(name));
+ buffer[ERL_ATOM_SIZE(name)] = '\0';
+
+ pid = erl_global_whereis(ERL_INT_VALUE(fd_term), buffer, NULL);
+ send_term(pid);
+ erl_free_term(pid);
+}
+
+static void
+cmd_erl_global_names(ETERM* args)
+{
+ ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
+
+ ETERM* res_array[2], *res_tuple, *name;
+ char** names = NULL;
+ int count = 0, i;
+
+ VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
+
+ names = erl_global_names(ERL_INT_VALUE(fd_term), &count);
+
+ res_array[0] = erl_mk_empty_list();
+ for(i=0; i<count; i++) {
+ name = erl_mk_string(names[i]);
+ res_array[0] = erl_cons(name, res_array[0]);
+ }
+
+ free(names);
+
+ res_array[1] = erl_mk_int(count);
+ res_tuple = erl_mk_tuple(res_array, 2);
+
+ send_term(res_tuple);
+
+ erl_free_compound(res_array[0]);
+ erl_free_term(res_array[1]);
+ erl_free_term(res_tuple);
+}
+
+static void
+cmd_erl_global_unregister(ETERM* args)
+{
+ ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
+ ETERM* name = ERL_TUPLE_ELEMENT(args, 1);
+
+ char buffer[256];
+
+ VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
+ VERIFY_TYPE(ERL_IS_ATOM, name);
+
+ memcpy(buffer, ERL_ATOM_PTR(name), ERL_ATOM_SIZE(name));
+ buffer[ERL_ATOM_SIZE(name)] = '\0';
+
+ send_errno_result(erl_global_unregister(ERL_INT_VALUE(fd_term), buffer));
+}
+
+static void
+send_errno_result(int value)
+{
+ ETERM* res_array[2];
+ ETERM* res_tuple;
+
+ res_array[0] = erl_mk_int(value);
+ res_array[1] = erl_mk_int(erl_errno);
+ res_tuple = erl_mk_tuple(res_array, 2);
+ send_term(res_tuple);
+ erl_free_term(res_array[0]);
+ erl_free_term(res_array[1]);
+ erl_free_term(res_tuple);
+}
diff --git a/lib/erl_interface/test/erl_interface.cover b/lib/erl_interface/test/erl_interface.cover
new file mode 100644
index 0000000000..879201a3cd
--- /dev/null
+++ b/lib/erl_interface/test/erl_interface.cover
@@ -0,0 +1,2 @@
+{incl_app,erl_interface,details}.
+
diff --git a/lib/erl_interface/test/erl_interface.spec b/lib/erl_interface/test/erl_interface.spec
index 2789bd3e2c..a0a7acfa50 100644
--- a/lib/erl_interface/test/erl_interface.spec
+++ b/lib/erl_interface/test/erl_interface.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../erl_interface_test"}}.
-
+{suites,"../erl_interface_test",all}.
diff --git a/lib/erl_interface/test/erl_match_SUITE.erl b/lib/erl_interface/test/erl_match_SUITE.erl
index f506638544..da5788722c 100644
--- a/lib/erl_interface/test/erl_match_SUITE.erl
+++ b/lib/erl_interface/test/erl_match_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,10 +20,12 @@
%%
-module(erl_match_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("erl_match_SUITE_data/match_test_cases.hrl").
--export([all/1, atoms/1, lists/1, tuples/1, references/1, pids/1, ports/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ atoms/1, lists/1, tuples/1, references/1, pids/1, ports/1,
bind/1, integers/1, floats/1, binaries/1, strings/1]).
%% For interactive running of matcher.
@@ -31,8 +33,27 @@
%% This test suite tests the erl_match() function.
-all(suite) -> [atoms, lists, tuples, references, pids, ports, bind,
- integers, floats, binaries, strings].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [atoms, lists, tuples, references, pids, ports, bind,
+ integers, floats, binaries, strings].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
atoms(suite) -> [];
atoms(Config) when is_list(Config) ->
diff --git a/lib/erl_interface/test/port_call_SUITE.erl b/lib/erl_interface/test/port_call_SUITE.erl
index 895e29ad2e..33755c3431 100644
--- a/lib/erl_interface/test/port_call_SUITE.erl
+++ b/lib/erl_interface/test/port_call_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -31,17 +31,37 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--export([all/1, basic/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, basic/1]).
% Private exports
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [basic].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+[basic].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
basic(suite) -> [];
basic(Config) when is_list(Config) ->
case os:type() of
+ {unix, linux} ->
+ do_basic(Config);
{unix, sunos} ->
do_basic(Config);
{win32,_} ->
diff --git a/lib/erl_interface/test/runner.erl b/lib/erl_interface/test/runner.erl
index b72723c6a5..e41440708a 100644
--- a/lib/erl_interface/test/runner.erl
+++ b/lib/erl_interface/test/runner.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index c642cc5002..ffda886553 100644
--- a/lib/erl_interface/vsn.mk
+++ b/lib/erl_interface/vsn.mk
@@ -1 +1 @@
-EI_VSN = 3.7.1
+EI_VSN = 3.7.2
diff --git a/lib/et/doc/src/notes.xml b/lib/et/doc/src/notes.xml
index 4ce7548414..cd4787c5e7 100644
--- a/lib/et/doc/src/notes.xml
+++ b/lib/et/doc/src/notes.xml
@@ -36,6 +36,21 @@
one section in this document. The title of each section is the
version number of <c>Event Tracer (ET)</c>.</p>
+<section><title>ET 1.4.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix error when module et was used in et_selector
+ trace patterns. </p>
+ <p>
+ Own Id: OTP-8904</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>ET 1.4.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/et/src/et_selector.erl b/lib/et/src/et_selector.erl
index f39f21aa70..c8e9c907b2 100644
--- a/lib/et/src/et_selector.erl
+++ b/lib/et/src/et_selector.erl
@@ -115,13 +115,13 @@ change_pattern({Mod, Pattern}) when is_atom(Mod) ->
old_ctp({Mod, _Fun, Args}) ->
case Mod of
- et -> ignore;
+ et -> {ok, ignore};
_ -> dbg:ctp({Mod, report_event, Args})
end.
old_tp({Mod, _Fun, Args}, Pattern) ->
case Mod of
- et -> ignore;
+ et -> {ok, ignore};
_ -> dbg:tp({Mod, report_event, Args}, Pattern)
end.
diff --git a/lib/et/test/Makefile b/lib/et/test/Makefile
index 7227ae8fd8..2125f9622a 100644
--- a/lib/et/test/Makefile
+++ b/lib/et/test/Makefile
@@ -71,7 +71,7 @@ release_spec: opt
release_tests_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) et.spec $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) et.spec et.cover $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
$(INSTALL_SCRIPT) ett $(RELSYSDIR)
$(INSTALL_DATA) $(INSTALL_PROGS) $(RELSYSDIR)
# chmod -f -R u+w $(RELSYSDIR)
diff --git a/lib/et/test/et.cover b/lib/et/test/et.cover
new file mode 100644
index 0000000000..471e6d985d
--- /dev/null
+++ b/lib/et/test/et.cover
@@ -0,0 +1,2 @@
+{incl_app,et,details}.
+
diff --git a/lib/et/test/et.spec b/lib/et/test/et.spec
index 69cd8d7582..09993a217a 100644
--- a/lib/et/test/et.spec
+++ b/lib/et/test/et.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../et_test"}}.
-
+{suites,"../et_test",all}.
diff --git a/lib/et/test/et_test_lib.erl b/lib/et/test/et_test_lib.erl
index b91b63786c..c1bfeb9fc0 100644
--- a/lib/et/test/et_test_lib.erl
+++ b/lib/et/test/et_test_lib.erl
@@ -95,7 +95,7 @@ wx_init_per_suite(Config) ->
exit({skipped, "Can not test on MacOSX"});
{unix, _} ->
io:format("DISPLAY ~s~n", [os:getenv("DISPLAY")]),
- case proplists:get_value(xserver, Config, none) of
+ case ct:get_config(xserver, none) of
none -> ignore;
Server -> os:putenv("DISPLAY", Server)
end;
@@ -295,7 +295,7 @@ eval_test_case(Mod, Fun, Config) ->
test_case_evaluator(Mod, Fun, [Config]) ->
NewConfig = Mod:init_per_testcase(Fun, Config),
R = apply(Mod, Fun, [NewConfig]),
- Mod:fin_per_testcase(Fun, NewConfig),
+ Mod:end_per_testcase(Fun, NewConfig),
exit({test_case_ok, R}).
wait_for_evaluator(Pid, Mod, Fun, Config) ->
@@ -311,12 +311,12 @@ wait_for_evaluator(Pid, Mod, Fun, Config) ->
{'EXIT', Pid, {skipped, Reason}} ->
log("<WARNING> Test case ~w skipped, because ~p~n",
[{Mod, Fun}, Reason]),
- Mod:fin_per_testcase(Fun, Config),
+ Mod:end_per_testcase(Fun, Config),
{skip, {Mod, Fun}, Reason};
{'EXIT', Pid, Reason} ->
log("<ERROR> Eval process ~w exited, because\n\t~p~n",
[{Mod, Fun}, Reason]),
- Mod:fin_per_testcase(Fun, Config),
+ Mod:end_per_testcase(Fun, Config),
{crash, {Mod, Fun}, Reason}
end.
diff --git a/lib/et/test/et_wx_SUITE.erl b/lib/et/test/et_wx_SUITE.erl
index 1a16ca69a3..6109ed4e04 100644
--- a/lib/et/test/et_wx_SUITE.erl
+++ b/lib/et/test/et_wx_SUITE.erl
@@ -18,8 +18,9 @@
-module(et_wx_SUITE).
--export([all/0, init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
-compile(export_all).
@@ -36,16 +37,22 @@ init_per_testcase(Func,Config) ->
et_test_lib:init_per_testcase(Func,Config).
end_per_testcase(Func,Config) ->
et_test_lib:end_per_testcase(Func,Config).
-fin_per_testcase(Func,Config) -> %% For test_server
- et_test_lib:end_per_testcase(Func,Config).
%% SUITE specification
-all() ->
- all(suite).
-all(suite) ->
- [
- start_all_windows
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [start_all_windows].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% The test cases
diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk
index b5b7fa52f4..d7cfd7bc84 100644
--- a/lib/et/vsn.mk
+++ b/lib/et/vsn.mk
@@ -1 +1 @@
-ET_VSN = 1.4.1
+ET_VSN = 1.4.2
diff --git a/lib/eunit/doc/src/Makefile b/lib/eunit/doc/src/Makefile
index 19be96d763..2cdc579275 100644
--- a/lib/eunit/doc/src/Makefile
+++ b/lib/eunit/doc/src/Makefile
@@ -146,7 +146,7 @@ debug opt:
clean clean_docs:
rm -rf $(HTMLDIR)/*
rm -f $(MAN3DIR)/*
- rm -f $(XML_CHAPTER_FILES) *.html
+ rm -f $(XML_REF3_FILES) $(XML_CHAPTER_FILES) *.html
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
rm -f errs core *~
diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml
index 974ba1db4e..1717dd7988 100644
--- a/lib/eunit/doc/src/notes.xml
+++ b/lib/eunit/doc/src/notes.xml
@@ -32,6 +32,21 @@
</header>
<p>This document describes the changes made to the EUnit application.</p>
+<section><title>Eunit 2.1.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix format_man_pages so it handles all man sections
+ and remove warnings/errors in various man pages. </p>
+ <p>
+ Own Id: OTP-8600</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Eunit 2.1.5</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/eunit/src/eunit.erl b/lib/eunit/src/eunit.erl
index 59084a52fb..4a86a108cf 100644
--- a/lib/eunit/src/eunit.erl
+++ b/lib/eunit/src/eunit.erl
@@ -16,7 +16,7 @@
%% $Id: eunit.erl 339 2009-04-05 14:10:47Z rcarlsson $
%%
%% @copyright 2004-2009 Micka�l R�mond, Richard Carlsson
-%% @author Micka�l R�mond <[email protected]>
+%% @author Micka&euml;l R&eacute;mond <[email protected]>
%% [http://www.process-one.net/]
%% @author Richard Carlsson <[email protected]>
%% [http://user.it.uu.se/~richardc/]
diff --git a/lib/eunit/src/eunit_surefire.erl b/lib/eunit/src/eunit_surefire.erl
index aeda31d251..eb994a990a 100644
--- a/lib/eunit/src/eunit_surefire.erl
+++ b/lib/eunit/src/eunit_surefire.erl
@@ -15,7 +15,7 @@
%%
%% $Id: $
%%
-%% @author Micka�l R�mond <[email protected]>
+%% @author Micka&euml;l R&eacute;mond <[email protected]>
%% @copyright 2009 Micka�l R�mond, Paul Guyot
%% @see eunit
%% @doc Surefire reports for EUnit (Format used by Maven and Atlassian
diff --git a/lib/eunit/test/Makefile b/lib/eunit/test/Makefile
index 74d485d1cc..a2d276f619 100644
--- a/lib/eunit/test/Makefile
+++ b/lib/eunit/test/Makefile
@@ -75,7 +75,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) eunit.dynspec $(EMAKEFILE) \
+ $(INSTALL_DATA) eunit.spec $(EMAKEFILE) \
$(COVERFILE) $(ERL_FILES) \
$(RELSYSDIR)
diff --git a/lib/eunit/test/eunit.cover b/lib/eunit/test/eunit.cover
index d1eaf770b6..00c09127a8 100644
--- a/lib/eunit/test/eunit.cover
+++ b/lib/eunit/test/eunit.cover
@@ -1,3 +1,5 @@
+{incl_app,eunit,details}.
+
%% -*- erlang -*-
-{exclude,[eunit_test]}.
+{excl_mods,eunit,[eunit_test]}.
diff --git a/lib/eunit/test/eunit.dynspec b/lib/eunit/test/eunit.dynspec
deleted file mode 100644
index c1d345ac14..0000000000
--- a/lib/eunit/test/eunit.dynspec
+++ /dev/null
@@ -1,6 +0,0 @@
-%% -*- erlang -*-
-%% You can test this file using this command.
-%% file:script("eunit.dynspec", [{'Os',"Unix"}]).
-
-[].
-
diff --git a/lib/eunit/test/eunit.spec b/lib/eunit/test/eunit.spec
new file mode 100644
index 0000000000..2db7731a7e
--- /dev/null
+++ b/lib/eunit/test/eunit.spec
@@ -0,0 +1,3 @@
+%% -*- erlang -*-
+{suites,"../eunit_test",all}.
+
diff --git a/lib/eunit/test/eunit_SUITE.erl b/lib/eunit/test/eunit_SUITE.erl
index 4ebcec6f5d..0f57905d17 100644
--- a/lib/eunit/test/eunit_SUITE.erl
+++ b/lib/eunit/test/eunit_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% 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
@@ -18,13 +18,32 @@
%%
-module(eunit_SUITE).
--export([all/1,eunit_test/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,eunit_test/1]).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[eunit_test].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
eunit_test(Config) when is_list(Config) ->
ok = file:set_cwd(code:lib_dir(eunit)),
ok = eunit:test(eunit).
diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk
index 3bfa9c8000..e1965630e3 100644
--- a/lib/eunit/vsn.mk
+++ b/lib/eunit/vsn.mk
@@ -1 +1 @@
-EUNIT_VSN = 2.1.5
+EUNIT_VSN = 2.1.6
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 6eeeab3610..309c118107 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -48,6 +48,7 @@
t_boolean/0,
t_byte/0,
t_char/0,
+ t_charlist/0,
t_cons/0,
t_cons/2,
t_cons_hd/1,
@@ -124,7 +125,8 @@
t_tuple/1,
t_tuple_args/1,
t_tuple_size/1,
- t_tuple_subtypes/1
+ t_tuple_subtypes/1,
+ t_unicode_string/0
]).
-ifdef(DO_ERL_BIF_TYPES_TEST).
@@ -192,7 +194,7 @@ type(binary, referenced_byte_size, 1, Xs) ->
type(code, add_path, 1, Xs) ->
strict(arg_types(code, add_path, 1), Xs,
fun (_) ->
- t_sup(t_boolean(),
+ t_sup(t_atom('true'),
t_tuple([t_atom('error'), t_atom('bad_directory')]))
end);
type(code, add_patha, 1, Xs) ->
@@ -1219,7 +1221,7 @@ type(erlang, monitor_node, 3, Xs) ->
strict(arg_types(erlang, monitor_node, 3), Xs,
fun (_) -> t_atom('true') end);
type(erlang, nif_error, 1, _) ->
- t_any();
+ t_any(); % this BIF and the next one are stubs for NIFs and never return
type(erlang, nif_error, 2, Xs) ->
strict(arg_types(erlang, nif_error, 2), Xs, fun (_) -> t_any() end);
type(erlang, node, 0, _) -> t_node();
@@ -1865,6 +1867,8 @@ type(erts_debug, flat_size, 1, Xs) ->
strict(arg_types(erts_debug, flat_size, 1), Xs, fun (_) -> t_integer() end);
type(erts_debug, get_internal_state, 1, _) ->
t_any();
+type(erts_debug, instructions, 0, _) ->
+ t_list(t_list(t_byte()));
type(erts_debug, lock_counters, 1, Xs) ->
strict(arg_types(erts_debug, lock_counters, 1), Xs,
fun ([Arg]) ->
@@ -1970,38 +1974,40 @@ type(ets, slot, 2, Xs) ->
strict(arg_types(ets, slot, 2), Xs,
fun (_) -> t_sup(t_list(t_tuple()), t_atom('$end_of_table')) end);
type(ets, update_counter, 3, Xs) ->
- strict(arg_types(ets, update_counter, 3), Xs, fun (_) -> t_integer() end);
+ strict(arg_types(ets, update_counter, 3), Xs,
+ fun ([_, _, Op]) ->
+ case t_is_integer(Op) of
+ true -> t_integer();
+ false ->
+ case t_is_tuple(Op) of
+ true -> t_integer();
+ false ->
+ case t_is_list(Op) of
+ true -> t_list(t_integer());
+ false ->
+ case t_is_nil(Op) of
+ true -> t_nil();
+ false -> t_sup([t_integer(), t_list(t_integer())])
+ end
+ end
+ end
+ end
+ end);
type(ets, update_element, 3, Xs) ->
strict(arg_types(ets, update_element, 3), Xs, fun (_) -> t_boolean() end);
%%-- file ---------------------------------------------------------------------
-type(file, close, 1, Xs) ->
- strict(arg_types(file, close, 1), Xs, fun (_) -> t_file_return() end);
-type(file, delete, 1, Xs) ->
- strict(arg_types(file, delete, 1), Xs, fun (_) -> t_file_return() end);
-type(file, get_cwd, 0, _) ->
- t_sup(t_tuple([t_atom('ok'), t_string()]),
- t_tuple([t_atom('error'), t_file_posix_error()]));
-type(file, make_dir, 1, Xs) ->
- strict(arg_types(file, make_dir, 1), Xs, fun (_) -> t_file_return() end);
-type(file, open, 2, Xs) ->
- strict(arg_types(file, open, 2), Xs,
- fun (_) ->
- t_sup([t_tuple([t_atom('ok'), t_file_io_device()]),
- t_tuple([t_atom('error'), t_file_posix_error()])])
- end);
-type(file, read_file, 1, Xs) ->
- strict(arg_types(file, read_file, 1), Xs,
- fun (_) ->
- t_sup([t_tuple([t_atom('ok'), t_binary()]),
- t_tuple([t_atom('error'), t_file_posix_error()])])
- end);
-type(file, set_cwd, 1, Xs) ->
- strict(arg_types(file, set_cwd, 1), Xs,
- fun (_) -> t_sup(t_atom('ok'),
- t_tuple([t_atom('error'), t_file_posix_error()]))
- end);
-type(file, write_file, 2, Xs) ->
- strict(arg_types(file, write_file, 2), Xs, fun (_) -> t_file_return() end);
+type(file, native_name_encoding, 0, _) ->
+ t_file_encoding();
+%%-- prim_file ----------------------------------------------------------------
+type(prim_file, internal_name2native, 1, Xs) ->
+ strict(arg_types(prim_file, internal_name2native, 1), Xs,
+ fun (_) -> t_binary() end);
+type(prim_file, internal_native2name, 1, Xs) ->
+ strict(arg_types(prim_file, internal_native2name, 1), Xs,
+ fun (_) -> t_prim_file_name() end);
+type(prim_file, internal_normalize_utf8, 1, Xs) ->
+ strict(arg_types(prim_file, internal_normalize_utf8, 1), Xs,
+ fun (_) -> t_binary() end);
%%-- gen_tcp ------------------------------------------------------------------
%% NOTE: All type information for this module added to avoid loss of precision
type(gen_tcp, accept, 1, Xs) ->
@@ -3345,7 +3351,7 @@ arg_types(code, all_loaded, 0) ->
arg_types(code, compiler_dir, 0) ->
[];
arg_types(code, del_path, 1) ->
- [t_sup(t_string(), t_atom())]; % OBS: doc differs from add_path/1 - why?
+ [t_sup(t_string(), t_atom())]; % OBS: differs from add_path/1
arg_types(code, delete, 1) ->
[t_atom()];
arg_types(code, ensure_loaded, 1) ->
@@ -3393,7 +3399,7 @@ arg_types(code, replace_path, 2) ->
arg_types(code, root_dir, 0) ->
[];
arg_types(code, set_path, 1) ->
- [t_string()];
+ [t_list(t_string())];
arg_types(code, soft_purge, 1) ->
arg_types(code, delete, 1);
arg_types(code, stick_mod, 1) ->
@@ -3797,7 +3803,7 @@ arg_types(erlang, now, 0) ->
arg_types(erlang, open_port, 2) ->
[t_sup(t_atom(), t_sup([t_tuple([t_atom('spawn'), t_string()]),
t_tuple([t_atom('spawn_driver'), t_string()]),
- t_tuple([t_atom('spawn_executable'), t_string()]),
+ t_tuple([t_atom('spawn_executable'), t_sup(t_unicode_string(),t_binary())]),
t_tuple([t_atom('fd'), t_integer(), t_integer()])])),
t_list(t_sup(t_sup([t_atom('stream'),
t_atom('exit_status'),
@@ -3813,8 +3819,8 @@ arg_types(erlang, open_port, 2) ->
t_tuple([t_atom('line'), t_integer()]),
t_tuple([t_atom('cd'), t_string()]),
t_tuple([t_atom('env'), t_list(t_tuple(2))]), % XXX: More
- t_tuple([t_atom('args'), t_list(t_string())]),
- t_tuple([t_atom('arg0'), t_string()])])))];
+ t_tuple([t_atom('args'), t_list(t_sup(t_unicode_string(),t_binary()))]),
+ t_tuple([t_atom('arg0'),t_sup(t_unicode_string(),t_binary())])])))];
arg_types(erlang, phash, 2) ->
[t_any(), t_pos_integer()];
arg_types(erlang, phash2, 1) ->
@@ -4089,6 +4095,8 @@ arg_types(erts_debug, flat_size, 1) ->
[t_any()];
arg_types(erts_debug, get_internal_state, 1) ->
[t_any()];
+arg_types(erts_debug, instructions, 0) ->
+ [];
arg_types(erts_debug, lock_counters, 1) ->
[t_sup([t_atom(enabled),
t_atom(info),
@@ -4181,32 +4189,22 @@ arg_types(ets, setopts, 2) ->
t_tuple([t_atom('heir'), t_atom('none')])),
[t_tab(), t_sup(Opt, t_list(Opt))];
arg_types(ets, update_counter, 3) ->
- [t_tab(), t_any(), t_sup(t_integer(),
- t_sup(t_tuple([t_integer(), t_integer()]),
- t_tuple([t_integer(), t_integer(),
- t_integer(), t_integer()])))];
+ Int = t_integer(),
+ UpdateOp = t_sup(t_tuple([Int, Int]), t_tuple([Int, Int, Int, Int])),
+ [t_tab(), t_any(), t_sup([UpdateOp, t_list(UpdateOp), Int])];
arg_types(ets, update_element, 3) ->
PosValue = t_tuple([t_integer(), t_any()]),
[t_tab(), t_any(), t_sup(PosValue, t_list(PosValue))];
%%------- file ----------------------------------------------------------------
-arg_types(file, close, 1) ->
- [t_file_io_device()];
-arg_types(file, delete, 1) ->
- [t_file_name()];
-arg_types(file, get_cwd, 0) ->
+arg_types(file, native_name_encoding, 0) ->
[];
-arg_types(file, make_dir, 1) ->
- [t_file_name()];
-arg_types(file, open, 2) ->
- [t_file_name(), t_list(t_file_open_option())];
-arg_types(file, read_file, 1) ->
- [t_file_name()];
-arg_types(file, set_cwd, 1) ->
- [t_file_name()];
-arg_types(file, write, 2) ->
- [t_file_io_device(), t_iodata()];
-arg_types(file, write_file, 2) ->
- [t_file_name(), t_sup(t_binary(), t_list())];
+%%-- prim_file ----------------------------------------------------------------
+arg_types(prim_file, internal_name2native, 1) ->
+ [t_prim_file_name()];
+arg_types(prim_file, internal_native2name, 1) ->
+ [t_binary()];
+arg_types(prim_file, internal_normalize_utf8, 1) ->
+ [t_binary()];
%%------- gen_tcp -------------------------------------------------------------
arg_types(gen_tcp, accept, 1) ->
[t_socket()];
@@ -4525,11 +4523,11 @@ arg_types(os, timestamp, 0) ->
arg_types(re, compile, 1) ->
[t_iodata()];
arg_types(re, compile, 2) ->
- [t_iodata(), t_list(t_re_compile_option())];
+ [t_sup(t_iodata(), t_charlist()), t_list(t_re_compile_option())];
arg_types(re, run, 2) ->
- [t_iodata(), t_re_RE()];
+ [t_sup(t_iodata(), t_charlist()), t_re_RE()];
arg_types(re, run, 3) ->
- [t_iodata(), t_re_RE(), t_list(t_re_run_option())];
+ [t_sup(t_iodata(), t_charlist()), t_re_RE(), t_list(t_re_run_option())];
%%------- string --------------------------------------------------------------
arg_types(string, chars, 2) ->
[t_char(), t_non_neg_integer()];
@@ -4638,7 +4636,7 @@ t_httppacket() ->
t_HttpHeader(), t_atom('http_eoh'), t_HttpError()]).
t_endian() ->
- t_sup([t_atom('big'), t_atom('little')]).
+ t_sup(t_atom('big'), t_atom('little')).
%% =====================================================================
%% Types for the binary module
@@ -4669,16 +4667,16 @@ t_HttpRequest() ->
t_tuple([t_atom('http_request'), t_HttpMethod(), t_HttpUri(), t_HttpVersion()]).
t_HttpResponse() ->
- t_tuple([t_atom('http_response'), t_HttpVersion(), t_integer(), t_string()]).
+ t_tuple([t_atom('http_response'), t_HttpVersion(), t_integer(), t_HttpString()]).
t_HttpHeader() ->
- t_tuple([t_atom('http_header'), t_integer(), t_HttpField(), t_any(), t_string()]).
+ t_tuple([t_atom('http_header'), t_integer(), t_HttpField(), t_any(), t_HttpString()]).
t_HttpError() ->
- t_tuple([t_atom('http_error'), t_string()]).
+ t_tuple([t_atom('http_error'), t_HttpString()]).
t_HttpMethod() ->
- t_sup(t_HttpMethodAtom(), t_string()).
+ t_sup(t_HttpMethodAtom(), t_HttpString()).
t_HttpMethodAtom() ->
t_atoms(['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE']).
@@ -4687,18 +4685,18 @@ t_HttpUri() ->
t_sup([t_atom('*'),
t_tuple([t_atom('absoluteURI'),
t_sup(t_atom('http'), t_atom('https')),
- t_string(),
+ t_HttpString(),
t_sup(t_non_neg_integer(), t_atom('undefined')),
- t_string()]),
- t_tuple([t_atom('scheme'), t_string(), t_string()]),
- t_tuple([t_atom('abs_path'), t_string()]),
- t_string()]).
+ t_HttpString()]),
+ t_tuple([t_atom('scheme'), t_HttpString(), t_HttpString()]),
+ t_tuple([t_atom('abs_path'), t_HttpString()]),
+ t_HttpString()]).
t_HttpVersion() ->
t_tuple([t_non_neg_integer(), t_non_neg_integer()]).
t_HttpField() ->
- t_sup(t_HttpFieldAtom(), t_string()).
+ t_sup(t_HttpFieldAtom(), t_HttpString()).
t_HttpFieldAtom() ->
t_atoms(['Cache-Control', 'Connection', 'Date', 'Pragma', 'Transfer-Encoding',
@@ -4715,6 +4713,9 @@ t_HttpFieldAtom() ->
'Set-Cookie', 'Set-Cookie2', 'X-Forwarded-For', 'Cookie',
'Keep-Alive', 'Proxy-Connection']).
+t_HttpString() ->
+ t_sup(t_string(),t_binary()).
+
%% =====================================================================
%% These are used for the built-in functions of 'code'
%% =====================================================================
@@ -4945,10 +4946,11 @@ t_matchres() ->
%% From the 'ets' documentation
%%-----------------------------
%% Option = Type | Access | named_table | {keypos,Pos}
-%% | {heir,pid(),HeirData} | {heir,none}
-%% | {write_concurrency,boolean()}
+%% | {heir,pid(),HeirData} | {heir,none} | Tweaks
%% Type = set | ordered_set | bag | duplicate_bag
%% Access = public | protected | private
+%% Tweaks = {write_concurrency,boolean()}
+%% | {read_concurrency,boolean()} | compressed
%% Pos = integer()
%% HeirData = term()
t_ets_new_options() ->
@@ -4960,10 +4962,12 @@ t_ets_new_options() ->
t_atom('protected'),
t_atom('private'),
t_atom('named_table'),
+ t_tuple([t_atom('keypos'), t_integer()]),
t_tuple([t_atom('heir'), t_pid(), t_any()]),
t_tuple([t_atom('heir'), t_atom('none')]),
- t_tuple([t_atom('keypos'), t_integer()]),
- t_tuple([t_atom('write_concurrency'), t_boolean()])])).
+ t_tuple([t_atom('write_concurrency'), t_boolean()]),
+ t_tuple([t_atom('read_concurrency'), t_boolean()]),
+ t_atom('compressed')])).
t_ets_info_items() ->
t_sup([t_atom('fixed'),
@@ -4979,68 +4983,11 @@ t_ets_info_items() ->
t_atom('type')]).
%% =====================================================================
-%% These are used for the built-in functions of 'file'
+%% These are used for the built-in functions of 'prim_file'
%% =====================================================================
-t_file_io_device() ->
- t_sup(t_pid(), t_tuple([t_atom('file_descriptor'), t_atom(), t_any()])).
-
-t_file_name() ->
- t_sup([t_atom(),
- t_string(),
- %% DeepList = [char() | atom() | DeepList] -- approximation below
- t_list(t_sup([t_atom(), t_string(), t_list()]))]).
-
-t_file_open_option() ->
- t_sup([t_atom('read'),
- t_atom('write'),
- t_atom('append'),
- t_atom('raw'),
- t_atom('binary'),
- t_atom('delayed_write'),
- t_atom('read_ahead'),
- t_atom('compressed'),
- t_tuple([t_atom('delayed_write'),
- t_pos_integer(), t_non_neg_integer()]),
- t_tuple([t_atom('read_ahead'), t_pos_integer()])]).
-
-%% This lists all Posix errors that can occur in file:*/* functions
-t_file_posix_error() ->
- t_sup([t_atom('eacces'),
- t_atom('eagain'),
- t_atom('ebadf'),
- t_atom('ebusy'),
- t_atom('edquot'),
- t_atom('eexist'),
- t_atom('efault'),
- t_atom('efbig'),
- t_atom('eintr'),
- t_atom('einval'),
- t_atom('eio'),
- t_atom('eisdir'),
- t_atom('eloop'),
- t_atom('emfile'),
- t_atom('emlink'),
- t_atom('enametoolong'),
- t_atom('enfile'),
- t_atom('enodev'),
- t_atom('enoent'),
- t_atom('enomem'),
- t_atom('enospc'),
- t_atom('enotblk'),
- t_atom('enotdir'),
- t_atom('enotsup'),
- t_atom('enxio'),
- t_atom('eperm'),
- t_atom('epipe'),
- t_atom('erofs'),
- t_atom('espipe'),
- t_atom('esrch'),
- t_atom('estale'),
- t_atom('exdev')]).
-
-t_file_return() ->
- t_sup(t_atom('ok'), t_tuple([t_atom('error'), t_file_posix_error()])).
+t_prim_file_name() ->
+ t_sup(t_unicode_string(), t_binary()).
%% =====================================================================
%% These are used for the built-in functions of 'gen_tcp'
@@ -5197,13 +5144,14 @@ t_re_MP() -> %% it's supposed to be an opaque data type
t_tuple([t_atom('re_pattern'), t_integer(), t_integer(), t_binary()]).
t_re_RE() ->
- t_sup(t_re_MP(), t_iodata()).
+ t_sup([t_re_MP(), t_iodata(), t_charlist()]).
t_re_compile_option() ->
- t_sup([t_atoms(['anchored', 'caseless', 'dollar_endonly', 'dotall',
- 'extended', 'firstline', 'multiline', 'no_auto_capture',
- 'dupnames', 'ungreedy']),
- t_tuple([t_atom('newline'), t_re_NLSpec()])]).
+ t_sup([t_atoms(['unicode', 'anchored', 'caseless', 'dollar_endonly',
+ 'dotall', 'extended', 'firstline', 'multiline',
+ 'no_auto_capture', 'dupnames', 'ungreedy']),
+ t_tuple([t_atom('newline'), t_re_NLSpec()]),
+ t_atoms(['bsr_anycrlf', 'bsr_unicode'])]).
t_re_run_option() ->
t_sup([t_atoms(['anchored', 'global', 'notbol', 'noteol', 'notempty']),
@@ -5220,7 +5168,7 @@ t_re_Type() ->
t_atoms(['index', 'list', 'binary']).
t_re_NLSpec() ->
- t_atoms(['cr', 'crlf', 'lf', 'anycrlf']).
+ t_atoms(['cr', 'crlf', 'lf', 'anycrlf', 'any']).
t_re_ValueSpec() ->
t_sup(t_atoms(['all', 'all_but_first', 'first', 'none']), t_re_ValueList()).
@@ -5242,7 +5190,12 @@ t_ML() -> % a binary or a possibly deep list of integers or binaries
t_sup(t_list(t_sup([t_integer(), t_binary(), t_list()])), t_binary()).
t_encoding() ->
- t_atoms(['latin1', 'unicode', 'utf8', 'utf16', 'utf32']).
+ t_sup([t_atoms(['latin1', 'unicode', 'utf8', 'utf16', 'utf32']),
+ t_tuple([t_atom('utf16'), t_endian()]),
+ t_tuple([t_atom('utf32'), t_endian()])]).
+
+t_file_encoding() ->
+ t_atoms(['latin1', 'utf8']).
t_encoding_a2b() -> % for the 2nd arg of atom_to_binary/2 and binary_to_atom/2
t_atoms(['latin1', 'unicode', 'utf8']).
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 9a40be6d14..080d6936b2 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -29,7 +29,7 @@
%% In late 2008, Manouk Manoukian and Kostis Sagonas added support for
%% opaque types to the structure-based representation of types.
%% During February and March 2009, Kostis Sagonas significantly
-%% cleaned up the type representation added spec declarations.
+%% cleaned up the type representation and added spec declarations.
%%
%% ======================================================================
@@ -62,6 +62,7 @@
t_boolean/0,
t_byte/0,
t_char/0,
+ t_charlist/0,
t_collect_vars/1,
t_cons/0,
t_cons/2,
@@ -195,6 +196,7 @@
t_tuple_size/1,
t_tuple_sizes/1,
t_tuple_subtypes/1,
+ t_unicode_string/0,
t_unify/2,
t_unify/3,
t_unit/0,
@@ -714,12 +716,13 @@ t_solve_remote_type(#remote{mod = RemMod, name = Name, args = Args} = RemType,
case lookup_type(Name, RemDict) of
{type, {_Mod, Type, ArgNames}} when ArgsLen =:= length(ArgNames) ->
{NewType, NewCycle, NewRR} =
- case unfold(RemType, C) of
+ case can_unfold_more(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]}
+ false ->
+ {t_any(), C, [RemType]}
end,
{RT, RR} = t_solve_remote(NewType, ET, R, NewCycle),
RetRR = NewRR ++ RR,
@@ -733,9 +736,11 @@ t_solve_remote_type(#remote{mod = RemMod, name = Name, args = Args} = RemType,
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]}
+ case can_unfold_more(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,
@@ -1452,6 +1457,26 @@ t_is_tuple(_) -> false.
%% Non-primitive types, including some handy syntactic sugar types
%%
+-spec t_unicode_string() -> erl_type().
+
+t_unicode_string() ->
+ t_list(t_unicode_char()).
+
+-spec t_charlist() -> erl_type().
+
+t_charlist() ->
+ t_charlist(1).
+
+-spec t_charlist(non_neg_integer()) -> erl_type().
+
+t_charlist(N) when N > 0 ->
+ t_maybe_improper_list(t_sup([t_unicode_char(),
+ t_unicode_binary(),
+ t_charlist(N-1)]),
+ t_sup(t_unicode_binary(), t_nil()));
+t_charlist(0) ->
+ t_maybe_improper_list(t_any(), t_sup(t_unicode_binary(), t_nil())).
+
-spec t_constant() -> erl_type().
t_constant() ->
@@ -1546,6 +1571,16 @@ t_parameterized_module() ->
t_timeout() ->
t_sup(t_non_neg_integer(), t_atom('infinity')).
+-spec t_unicode_binary() -> erl_type().
+
+t_unicode_binary() ->
+ t_binary(). % with characters encoded in UTF-8 coding standard
+
+-spec t_unicode_char() -> erl_type().
+
+t_unicode_char() ->
+ t_integer(). % representing a valid unicode codepoint
+
%%-----------------------------------------------------------------------------
%% Some built-in opaque types
%%
@@ -2124,7 +2159,8 @@ t_elements(?identifier(IDs)) ->
t_elements(?list(_, _, _) = T) -> [T];
t_elements(?number(_, _) = T) ->
case T of
- ?number(?any, ?unknown_qual) -> [T];
+ ?number(?any, ?unknown_qual) ->
+ [?float, ?integer(?any)];
?float -> [T];
?integer(?any) -> [T];
?int_range(_, _) -> [T];
@@ -2171,10 +2207,10 @@ t_inf(?var(_), T, _Mode) -> subst_all_vars_to_any(T);
t_inf(T, ?var(_), _Mode) -> subst_all_vars_to_any(T);
t_inf(?any, T, _Mode) -> subst_all_vars_to_any(T);
t_inf(T, ?any, _Mode) -> subst_all_vars_to_any(T);
-t_inf(?unit, _, _Mode) -> ?unit;
-t_inf(_, ?unit, _Mode) -> ?unit;
t_inf(?none, _, _Mode) -> ?none;
t_inf(_, ?none, _Mode) -> ?none;
+t_inf(?unit, _, _Mode) -> ?unit; % ?unit cases should appear below ?none
+t_inf(_, ?unit, _Mode) -> ?unit;
t_inf(T, T, _Mode) -> subst_all_vars_to_any(T);
t_inf(?atom(Set1), ?atom(Set2), _) ->
case set_intersection(Set1, Set2) of
@@ -2383,14 +2419,16 @@ inf_tuple_sets(L1, L2, Mode) ->
List -> ?tuple_set(List)
end.
-inf_tuple_sets([{Arity, Tuples1}|Left1], [{Arity, Tuples2}|Left2], Acc, Mode) ->
+inf_tuple_sets([{Arity, Tuples1}|Ts1], [{Arity, Tuples2}|Ts2], Acc, Mode) ->
case inf_tuples_in_sets(Tuples1, Tuples2, Mode) of
- [] -> inf_tuple_sets(Left1, Left2, Acc, Mode);
- NewTuples -> inf_tuple_sets(Left1, Left2, [{Arity, NewTuples}|Acc], Mode)
+ [] -> inf_tuple_sets(Ts1, Ts2, Acc, Mode);
+ [?tuple_set([{Arity, NewTuples}])] ->
+ inf_tuple_sets(Ts1, Ts2, [{Arity, NewTuples}|Acc], Mode);
+ NewTuples -> inf_tuple_sets(Ts1, Ts2, [{Arity, NewTuples}|Acc], Mode)
end;
-inf_tuple_sets(L1 = [{Arity1, _}|Left1], L2 = [{Arity2, _}|Left2], Acc, Mode) ->
- if Arity1 < Arity2 -> inf_tuple_sets(Left1, L2, Acc, Mode);
- Arity1 > Arity2 -> inf_tuple_sets(L1, Left2, Acc, Mode)
+inf_tuple_sets([{Arity1, _}|Ts1] = L1, [{Arity2, _}|Ts2] = L2, Acc, Mode) ->
+ if Arity1 < Arity2 -> inf_tuple_sets(Ts1, L2, Acc, Mode);
+ Arity1 > Arity2 -> inf_tuple_sets(L1, Ts2, Acc, Mode)
end;
inf_tuple_sets([], _, Acc, _Mode) -> lists:reverse(Acc);
inf_tuple_sets(_, [], Acc, _Mode) -> lists:reverse(Acc).
@@ -2406,17 +2444,17 @@ inf_tuples_in_sets(L1, [?tuple(Elements2, _, ?any)], Mode) ->
inf_tuples_in_sets(L1, L2, Mode) ->
inf_tuples_in_sets(L1, L2, [], Mode).
-inf_tuples_in_sets([?tuple(Elements1, Arity, Tag)|Left1],
- [?tuple(Elements2, Arity, Tag)|Left2], Acc, Mode) ->
+inf_tuples_in_sets([?tuple(Elements1, Arity, Tag)|Ts1],
+ [?tuple(Elements2, Arity, Tag)|Ts2], Acc, Mode) ->
case t_inf_lists_strict(Elements1, Elements2, Mode) of
- bottom -> inf_tuples_in_sets(Left1, Left2, Acc, Mode);
- NewElements ->
- inf_tuples_in_sets(Left1, Left2, [?tuple(NewElements, Arity, Tag)|Acc], Mode)
+ bottom -> inf_tuples_in_sets(Ts1, Ts2, Acc, Mode);
+ NewElements ->
+ inf_tuples_in_sets(Ts1, Ts2, [?tuple(NewElements, Arity, Tag)|Acc], Mode)
end;
-inf_tuples_in_sets([?tuple(_, _, Tag1)|Left1] = L1,
- [?tuple(_, _, Tag2)|Left2] = L2, Acc, Mode) ->
- if Tag1 < Tag2 -> inf_tuples_in_sets(Left1, L2, Acc, Mode);
- Tag1 > Tag2 -> inf_tuples_in_sets(L1, Left2, Acc, Mode)
+inf_tuples_in_sets([?tuple(_, _, Tag1)|Ts1] = L1,
+ [?tuple(_, _, Tag2)|Ts2] = L2, Acc, Mode) ->
+ if Tag1 < Tag2 -> inf_tuples_in_sets(Ts1, L2, Acc, Mode);
+ Tag1 > Tag2 -> inf_tuples_in_sets(L1, Ts2, Acc, Mode)
end;
inf_tuples_in_sets([], _, Acc, _Mode) -> lists:reverse(Acc);
inf_tuples_in_sets(_, [], Acc, _Mode) -> lists:reverse(Acc).
@@ -2763,7 +2801,9 @@ t_subtract_list(T, []) ->
-spec t_subtract(erl_type(), erl_type()) -> erl_type().
t_subtract(_, ?any) -> ?none;
+t_subtract(_, ?var(_)) -> ?none;
t_subtract(?any, _) -> ?any;
+t_subtract(?var(_) = T, _) -> T;
t_subtract(T, ?unit) -> T;
t_subtract(?unit, _) -> ?unit;
t_subtract(?none, _) -> ?none;
@@ -2791,13 +2831,13 @@ t_subtract(?opaque(Set1), ?opaque(Set2)) ->
Set -> ?opaque(Set)
end;
t_subtract(?matchstate(Pres1, Slots1), ?matchstate(Pres2, _Slots2)) ->
- Pres = t_subtract(Pres1,Pres2),
+ Pres = t_subtract(Pres1, Pres2),
case t_is_none(Pres) of
true -> ?none;
- false -> ?matchstate(Pres,Slots1)
+ false -> ?matchstate(Pres, Slots1)
end;
-t_subtract(?matchstate(Present,Slots),_) ->
- ?matchstate(Present,Slots);
+t_subtract(?matchstate(Present, Slots), _) ->
+ ?matchstate(Present, Slots);
t_subtract(?nil, ?nil) ->
?none;
t_subtract(?nil, ?nonempty_list(_, _)) ->
@@ -2817,7 +2857,7 @@ t_subtract(?list(Contents1, Termination1, Size1) = T,
true ->
case {Size1, Size2} of
{?nonempty_qual, ?unknown_qual} -> ?none;
- {?unknown_qual, ?nonempty_qual} -> Termination1;
+ {?unknown_qual, ?nonempty_qual} -> ?nil;
{S, S} -> ?none
end;
false ->
@@ -2919,7 +2959,7 @@ t_subtract(T, ?product(_)) ->
T;
t_subtract(?union(U1), ?union(U2)) ->
subtract_union(U1, U2);
-t_subtract(T1, T2) ->
+t_subtract(T1, T2) ->
?union(U1) = force_union(T1),
?union(U2) = force_union(T2),
subtract_union(U1, U2).
@@ -3390,211 +3430,263 @@ t_from_form(Form, RecDict) ->
-spec t_from_form(parse_form(), dict(), dict()) -> erl_type().
t_from_form(Form, RecDict, VarDict) ->
- {T, _R} = t_from_form(Form, [], RecDict, VarDict),
+ {T, _R} = t_from_form(Form, [], false, RecDict, VarDict),
T.
-type type_names() :: [{'type' | 'opaque' | 'record', atom()}].
--spec t_from_form(parse_form(), type_names(), dict(), dict()) ->
+-spec t_from_form(parse_form(), type_names(), boolean(), dict(), dict()) ->
{erl_type(), type_names()}.
-t_from_form({var, _L, '_'}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({var, _L, '_'}, _TypeNames, _InOpaque, _RecDict, _VarDict) ->
{t_any(), []};
-t_from_form({var, _L, Name}, _TypeNames, _RecDict, VarDict) ->
+t_from_form({var, _L, Name}, _TypeNames, _InOpaque, _RecDict, VarDict) ->
case dict:find(Name, VarDict) of
error -> {t_var(Name), []};
{ok, Val} -> {Val, []}
end;
-t_from_form({ann_type, _L, [_Var, Type]}, TypeNames, RecDict, VarDict) ->
- t_from_form(Type, TypeNames, RecDict, VarDict);
-t_from_form({paren_type, _L, [Type]}, TypeNames, RecDict, VarDict) ->
- t_from_form(Type, TypeNames, RecDict, VarDict);
+t_from_form({ann_type, _L, [_Var, Type]}, TypeNames, InOpaque, RecDict,
+ VarDict) ->
+ t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict);
+t_from_form({paren_type, _L, [Type]}, TypeNames, InOpaque, RecDict,
+ VarDict) ->
+ t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict);
t_from_form({remote_type, _L, [{atom, _, Module}, {atom, _, Type}, Args]},
- TypeNames, RecDict, VarDict) ->
- {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict),
+ TypeNames, InOpaque, RecDict, VarDict) ->
+ {L, R} = list_from_form(Args, TypeNames, InOpaque, RecDict, VarDict),
{t_remote(Module, Type, L), R};
-t_from_form({atom, _L, Atom}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({atom, _L, Atom}, _TypeNames, _InOpaque, _RecDict, _VarDict) ->
{t_atom(Atom), []};
-t_from_form({integer, _L, Int}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({integer, _L, Int}, _TypeNames, _InOpaque, _RecDict, _VarDict) ->
{t_integer(Int), []};
-t_from_form({op, _L, _Op, _Arg} = Op, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({op, _L, _Op, _Arg} = Op, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
case erl_eval:partial_eval(Op) of
{integer, _, Val} ->
{t_integer(Val), []};
- _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Op])})
+ _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])})
end;
-t_from_form({op, _L, _Op, _Arg1, _Arg2} = Op, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({op, _L, _Op, _Arg1, _Arg2} = Op, _TypeNames, _InOpaque,
+ _RecDict, _VarDict) ->
case erl_eval:partial_eval(Op) of
{integer, _, Val} ->
{t_integer(Val), []};
- _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Op])})
+ _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])})
end;
-t_from_form({type, _L, any, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, any, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_any(), []};
-t_from_form({type, _L, arity, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, arity, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_arity(), []};
-t_from_form({type, _L, array, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, array, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_array(), []};
-t_from_form({type, _L, atom, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, atom, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_atom(), []};
-t_from_form({type, _L, binary, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, binary, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_binary(), []};
t_from_form({type, _L, binary, [Base, Unit]} = Type,
- _TypeNames, _RecDict, _VarDict) ->
+ _TypeNames, _InOpaque, _RecDict, _VarDict) ->
case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of
{{integer, _, BaseVal},
{integer, _, UnitVal}}
when BaseVal >= 0, UnitVal >= 0 ->
{t_bitstr(UnitVal, BaseVal), []};
- _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Type])})
+ _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])})
end;
-t_from_form({type, _L, bitstring, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, bitstring, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_bitstr(), []};
-t_from_form({type, _L, bool, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, bool, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_boolean(), []}; % XXX: Temporarily
-t_from_form({type, _L, boolean, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, boolean, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_boolean(), []};
-t_from_form({type, _L, byte, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, byte, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_byte(), []};
-t_from_form({type, _L, char, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, char, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_char(), []};
-t_from_form({type, _L, dict, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, dict, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_dict(), []};
-t_from_form({type, _L, digraph, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, digraph, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_digraph(), []};
-t_from_form({type, _L, float, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, float, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_float(), []};
-t_from_form({type, _L, function, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, function, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_fun(), []};
-t_from_form({type, _L, 'fun', []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, 'fun', []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_fun(), []};
t_from_form({type, _L, 'fun', [{type, _, any, []}, Range]}, TypeNames,
- RecDict, VarDict) ->
- {T, R} = t_from_form(Range, TypeNames, RecDict, VarDict),
+ InOpaque, RecDict, VarDict) ->
+ {T, R} = t_from_form(Range, TypeNames, InOpaque, RecDict, VarDict),
{t_fun(T), R};
t_from_form({type, _L, 'fun', [{type, _, product, Domain}, Range]},
- TypeNames, RecDict, VarDict) ->
- {L, R1} = list_from_form(Domain, TypeNames, RecDict, VarDict),
- {T, R2} = t_from_form(Range, TypeNames, RecDict, VarDict),
+ TypeNames, InOpaque, RecDict, VarDict) ->
+ {L, R1} = list_from_form(Domain, TypeNames, InOpaque, RecDict, VarDict),
+ {T, R2} = t_from_form(Range, TypeNames, InOpaque, RecDict, VarDict),
{t_fun(L, T), R1 ++ R2};
-t_from_form({type, _L, gb_set, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, gb_set, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_gb_set(), []};
-t_from_form({type, _L, gb_tree, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, gb_tree, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_gb_tree(), []};
-t_from_form({type, _L, identifier, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, identifier, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_identifier(), []};
-t_from_form({type, _L, integer, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, integer, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_integer(), []};
-t_from_form({type, _L, iodata, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, iodata, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_iodata(), []};
-t_from_form({type, _L, iolist, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, iolist, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_iolist(), []};
-t_from_form({type, _L, list, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, list, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_list(), []};
-t_from_form({type, _L, list, [Type]}, TypeNames, RecDict, VarDict) ->
- {T, R} = t_from_form(Type, TypeNames, RecDict, VarDict),
+t_from_form({type, _L, list, [Type]}, TypeNames, InOpaque, RecDict,
+ VarDict) ->
+ {T, R} = t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict),
{t_list(T), R};
-t_from_form({type, _L, mfa, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, mfa, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_mfa(), []};
-t_from_form({type, _L, module, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, module, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_module(), []};
-t_from_form({type, _L, nil, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, nil, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_nil(), []};
-t_from_form({type, _L, neg_integer, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, neg_integer, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_neg_integer(), []};
-t_from_form({type, _L, non_neg_integer, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, non_neg_integer, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_non_neg_integer(), []};
-t_from_form({type, _L, no_return, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, no_return, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_unit(), []};
-t_from_form({type, _L, node, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, node, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_node(), []};
-t_from_form({type, _L, none, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, none, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_none(), []};
-t_from_form({type, _L, nonempty_list, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, nonempty_list, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_nonempty_list(), []};
-t_from_form({type, _L, nonempty_list, [Type]}, TypeNames, RecDict, VarDict) ->
- {T, R} = t_from_form(Type, TypeNames, RecDict, VarDict),
+t_from_form({type, _L, nonempty_list, [Type]}, TypeNames, InOpaque, RecDict,
+ VarDict) ->
+ {T, R} = t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict),
{t_nonempty_list(T), R};
t_from_form({type, _L, nonempty_improper_list, [Cont, Term]}, TypeNames,
- RecDict, VarDict) ->
- {T1, R1} = t_from_form(Cont, TypeNames, RecDict, VarDict),
- {T2, R2} = t_from_form(Term, TypeNames, RecDict, VarDict),
+ InOpaque, RecDict, VarDict) ->
+ {T1, R1} = t_from_form(Cont, TypeNames, InOpaque, RecDict, VarDict),
+ {T2, R2} = t_from_form(Term, TypeNames, InOpaque, RecDict, VarDict),
{t_cons(T1, T2), R1 ++ R2};
t_from_form({type, _L, nonempty_maybe_improper_list, []}, _TypeNames,
- _RecDict, _VarDict) ->
+ _InOpaque, _RecDict, _VarDict) ->
{t_cons(?any, ?any), []};
-t_from_form({type, _L, nonempty_maybe_improper_list, [Cont, Term]}, TypeNames,
- RecDict, VarDict) ->
- {T1, R1} = t_from_form(Cont, TypeNames, RecDict, VarDict),
- {T2, R2} = t_from_form(Term, TypeNames, RecDict, VarDict),
+t_from_form({type, _L, nonempty_maybe_improper_list, [Cont, Term]},
+ TypeNames, InOpaque, RecDict, VarDict) ->
+ {T1, R1} = t_from_form(Cont, TypeNames, InOpaque, RecDict, VarDict),
+ {T2, R2} = t_from_form(Term, TypeNames, InOpaque, RecDict, VarDict),
{t_cons(T1, T2), R1 ++ R2};
-t_from_form({type, _L, nonempty_string, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, nonempty_string, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_nonempty_string(), []};
-t_from_form({type, _L, number, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, number, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_number(), []};
-t_from_form({type, _L, pid, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, pid, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_pid(), []};
-t_from_form({type, _L, port, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, port, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_port(), []};
-t_from_form({type, _L, pos_integer, []}, _TypeNames, _RecDict, _VarDict) ->
- {t_pos_integer(), []};
-t_from_form({type, _L, maybe_improper_list, []}, _TypeNames, _RecDict,
+t_from_form({type, _L, pos_integer, []}, _TypeNames, _InOpaque, _RecDict,
_VarDict) ->
+ {t_pos_integer(), []};
+t_from_form({type, _L, maybe_improper_list, []}, _TypeNames, _InOpaque,
+ _RecDict, _VarDict) ->
{t_maybe_improper_list(), []};
-t_from_form({type, _L, maybe_improper_list, [Content, Termination]}, TypeNames,
- RecDict, VarDict) ->
- {T1, R1} = t_from_form(Content, TypeNames, RecDict, VarDict),
- {T2, R2} = t_from_form(Termination, TypeNames, RecDict, VarDict),
+t_from_form({type, _L, maybe_improper_list, [Content, Termination]},
+ TypeNames, InOpaque, RecDict, VarDict) ->
+ {T1, R1} = t_from_form(Content, TypeNames, InOpaque, RecDict, VarDict),
+ {T2, R2} = t_from_form(Termination, TypeNames, InOpaque, RecDict, VarDict),
{t_maybe_improper_list(T1, T2), R1 ++ R2};
-t_from_form({type, _L, product, Elements}, TypeNames, RecDict, VarDict) ->
- {L, R} = list_from_form(Elements, TypeNames, RecDict, VarDict),
+t_from_form({type, _L, product, Elements}, TypeNames, InOpaque, RecDict,
+ VarDict) ->
+ {L, R} = list_from_form(Elements, TypeNames, InOpaque, RecDict, VarDict),
{t_product(L), R};
-t_from_form({type, _L, queue, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, queue, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_queue(), []};
t_from_form({type, _L, range, [From, To]} = Type,
- _TypeNames, _RecDict, _VarDict) ->
+ _TypeNames, _InOpaque, _RecDict, _VarDict) ->
case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
- {{integer, _, FromVal},
- {integer, _, ToVal}} ->
+ {{integer, _, FromVal}, {integer, _, ToVal}} ->
{t_from_range(FromVal, ToVal), []};
- _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Type])})
+ _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])})
end;
-t_from_form({type, _L, record, [Name|Fields]}, TypeNames, RecDict, VarDict) ->
- record_from_form(Name, Fields, TypeNames, RecDict, VarDict);
-t_from_form({type, _L, reference, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, record, [Name|Fields]}, TypeNames, InOpaque, RecDict,
+ VarDict) ->
+ record_from_form(Name, Fields, TypeNames, InOpaque, RecDict, VarDict);
+t_from_form({type, _L, reference, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_reference(), []};
-t_from_form({type, _L, set, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, set, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_set(), []};
-t_from_form({type, _L, string, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, string, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_string(), []};
-t_from_form({type, _L, term, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, term, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_any(), []};
-t_from_form({type, _L, tid, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, tid, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_tid(), []};
-t_from_form({type, _L, timeout, []}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, timeout, []}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_timeout(), []};
-t_from_form({type, _L, tuple, any}, _TypeNames, _RecDict, _VarDict) ->
+t_from_form({type, _L, tuple, any}, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{t_tuple(), []};
-t_from_form({type, _L, tuple, Args}, TypeNames, RecDict, VarDict) ->
- {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict),
+t_from_form({type, _L, tuple, Args}, TypeNames, InOpaque, RecDict, VarDict) ->
+ {L, R} = list_from_form(Args, TypeNames, InOpaque, RecDict, VarDict),
{t_tuple(L), R};
-t_from_form({type, _L, union, Args}, TypeNames, RecDict, VarDict) ->
- {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict),
+t_from_form({type, _L, union, Args}, TypeNames, InOpaque, RecDict, VarDict) ->
+ {L, R} = list_from_form(Args, TypeNames, InOpaque, RecDict, VarDict),
{t_sup(L), R};
-t_from_form({type, _L, Name, Args}, TypeNames, RecDict, VarDict) ->
+t_from_form({type, _L, Name, Args}, TypeNames, InOpaque, RecDict, VarDict) ->
case lookup_type(Name, RecDict) of
{type, {_Module, Type, ArgNames}} when length(Args) =:= length(ArgNames) ->
- case unfold({type, Name}, TypeNames) of
+ case can_unfold_more({type, Name}, TypeNames) of
true ->
List = lists:zipwith(
fun(ArgName, ArgType) ->
{Ttemp, _R} = t_from_form(ArgType, TypeNames,
- RecDict, VarDict),
+ InOpaque, RecDict,
+ VarDict),
{ArgName, Ttemp}
end,
ArgNames, Args),
TmpVarDict = dict:from_list(List),
- {T, R} = t_from_form(Type, [{type, Name}|TypeNames], RecDict,
- TmpVarDict),
+ {T, R} = t_from_form(Type, [{type, Name}|TypeNames], InOpaque,
+ RecDict, TmpVarDict),
case lists:member({type, Name}, R) of
true -> {t_limit(T, ?REC_TYPE_LIMIT), R};
false -> {T, R}
@@ -3603,26 +3695,32 @@ t_from_form({type, _L, Name, Args}, TypeNames, RecDict, VarDict) ->
end;
{opaque, {Module, Type, ArgNames}} when length(Args) =:= length(ArgNames) ->
{Rep, Rret} =
- case unfold({opaque, Name}, TypeNames) of
+ case can_unfold_more({opaque, Name}, TypeNames) of
true ->
List = lists:zipwith(
fun(ArgName, ArgType) ->
- {Ttemp, _R} = t_from_form(ArgType, TypeNames,
- RecDict, VarDict),
+ {Ttemp, _R} = t_from_form(ArgType, TypeNames,
+ InOpaque, RecDict,
+ VarDict),
{ArgName, Ttemp}
end,
ArgNames, Args),
TmpVarDict = dict:from_list(List),
- {T, R} = t_from_form(Type, [{opaque, Name}|TypeNames], RecDict,
- TmpVarDict),
+ {T, R} = t_from_form(Type, [{opaque, Name}|TypeNames], true,
+ RecDict, TmpVarDict),
case lists:member({opaque, Name}, R) of
true -> {t_limit(T, ?REC_TYPE_LIMIT), R};
false -> {T, R}
end;
false -> {t_any(), [{opaque, Name}]}
end,
- Tret = t_from_form({opaque, -1, Name, {Module, Args, Rep}},
- RecDict, VarDict),
+ Tret =
+ case InOpaque of
+ true -> Rep;
+ false ->
+ t_from_form({opaque, -1, Name, {Module, Args, Rep}},
+ RecDict, VarDict)
+ end,
{Tret, Rret};
{type, _} ->
throw({error, io_lib:format("Unknown type ~w\n", [Name])});
@@ -3631,15 +3729,16 @@ t_from_form({type, _L, Name, Args}, TypeNames, RecDict, VarDict) ->
error ->
throw({error, io_lib:format("Unable to find type ~w\n", [Name])})
end;
-t_from_form({opaque, _L, Name, {Mod, Args, Rep}}, _TypeNames, _RecDict,
- _VarDict) ->
+t_from_form({opaque, _L, Name, {Mod, Args, Rep}}, _TypeNames, _InOpaque,
+ _RecDict, _VarDict) ->
case Args of
[] -> {t_opaque(Mod, Name, Args, Rep), []};
_ -> throw({error, "Polymorphic opaque types not supported yet"})
end.
-record_from_form({atom, _, Name}, ModFields, TypeNames, RecDict, VarDict) ->
- case unfold({record, Name}, TypeNames) of
+record_from_form({atom, _, Name}, ModFields, TypeNames, InOpaque, RecDict,
+ VarDict) ->
+ case can_unfold_more({record, Name}, TypeNames) of
true ->
case lookup_record(Name, RecDict) of
{ok, DeclFields} ->
@@ -3649,14 +3748,15 @@ record_from_form({atom, _, Name}, ModFields, TypeNames, RecDict, VarDict) ->
{DeclFields1, R1} =
case lists:all(fun(Elem) -> Elem end, AreTyped) of
true -> {DeclFields, []};
- false -> fields_from_form(DeclFields, TypeNames1,
+ false -> fields_from_form(DeclFields, TypeNames1, InOpaque,
RecDict, dict:new())
end,
{GetModRec, R2} = get_mod_record(ModFields, DeclFields1,
- TypeNames1, RecDict, VarDict),
+ TypeNames1, InOpaque,
+ RecDict, VarDict),
case GetModRec of
{error, FieldName} ->
- throw({error, io_lib:format("Illegal declaration of ~w#{~w}\n",
+ throw({error, io_lib:format("Illegal declaration of #~w{~w}\n",
[Name, FieldName])});
{ok, NewFields} ->
{t_tuple(
@@ -3664,17 +3764,18 @@ record_from_form({atom, _, Name}, ModFields, TypeNames, RecDict, VarDict) ->
R1 ++ R2}
end;
error ->
- throw({error, erlang:error(io_lib:format("Unknown record #~w{}\n",
- [Name]))})
+ throw({error, io_lib:format("Unknown record #~w{}\n", [Name])})
end;
false -> {t_any(), []}
end.
-get_mod_record([], DeclFields, _TypeNames, _RecDict, _VarDict) ->
+get_mod_record([], DeclFields, _TypeNames, _InOpaque, _RecDict,
+ _VarDict) ->
{{ok, DeclFields}, []};
-get_mod_record(ModFields, DeclFields, TypeNames, RecDict, VarDict) ->
+get_mod_record(ModFields, DeclFields, TypeNames, InOpaque, RecDict,
+ VarDict) ->
DeclFieldsDict = orddict:from_list(DeclFields),
- {ModFieldsDict, R} = build_field_dict(ModFields, TypeNames,
+ {ModFieldsDict, R} = build_field_dict(ModFields, TypeNames, InOpaque,
RecDict, VarDict),
case get_mod_record(DeclFieldsDict, ModFieldsDict, []) of
{error, _FieldName} = Error -> {Error, R};
@@ -3684,21 +3785,23 @@ get_mod_record(ModFields, DeclFields, TypeNames, RecDict, VarDict) ->
R}
end.
-build_field_dict(FieldTypes, TypeNames, RecDict, VarDict) ->
- build_field_dict(FieldTypes, TypeNames, RecDict, VarDict, []).
+build_field_dict(FieldTypes, TypeNames, InOpaque, RecDict, VarDict) ->
+ build_field_dict(FieldTypes, TypeNames, InOpaque, RecDict, VarDict, []).
build_field_dict([{type, _, field_type, [{atom, _, Name}, Type]}|Left],
- TypeNames, RecDict, VarDict, Acc) ->
- {T, R1} = t_from_form(Type, TypeNames, RecDict, VarDict),
+ TypeNames, InOpaque, RecDict, VarDict, Acc) ->
+ {T, R1} = t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict),
NewAcc = [{Name, T}|Acc],
- {D, R2} = build_field_dict(Left, TypeNames, RecDict, VarDict, NewAcc),
+ {D, R2} = build_field_dict(Left, TypeNames, InOpaque, RecDict, VarDict,
+ NewAcc),
{D, R1 ++ R2};
-build_field_dict([], _TypeNames, _RecDict, _VarDict, Acc) ->
+build_field_dict([], _TypeNames, _InOpaque, _RecDict, _VarDict, Acc) ->
{orddict:from_list(Acc), []}.
get_mod_record([{FieldName, DeclType}|Left1],
[{FieldName, ModType}|Left2], Acc) ->
- case t_is_var(ModType) orelse t_is_subtype(ModType, DeclType) of
+ case t_is_var(ModType) orelse t_is_remote(ModType) orelse
+ t_is_subtype(ModType, DeclType) of
false -> {error, FieldName};
true -> get_mod_record(Left1, Left2, [{FieldName, ModType}|Acc])
end;
@@ -3711,18 +3814,19 @@ get_mod_record(DeclFields, [], Acc) ->
get_mod_record(_, [{FieldName2, _ModType}|_], _Acc) ->
{error, FieldName2}.
-fields_from_form([], _TypeNames, _RecDict, _VarDict) ->
+fields_from_form([], _TypeNames, _InOpaque, _RecDict, _VarDict) ->
{[], []};
-fields_from_form([{Name, Type}|Tail], TypeNames, RecDict, VarDict) ->
- {T, R1} = t_from_form(Type, TypeNames, RecDict, VarDict),
- {F, R2} = fields_from_form(Tail, TypeNames, RecDict, VarDict),
+fields_from_form([{Name, Type}|Tail], TypeNames, InOpaque, RecDict,
+ VarDict) ->
+ {T, R1} = t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict),
+ {F, R2} = fields_from_form(Tail, TypeNames, InOpaque, RecDict, VarDict),
{[{Name, T}|F], R1 ++ R2}.
-list_from_form([], _TypeNames, _RecDict, _VarDict) ->
+list_from_form([], _TypeNames, _InOpaque, _RecDict, _VarDict) ->
{[], []};
-list_from_form([H|Tail], TypeNames, RecDict, VarDict) ->
- {T, R1} = t_from_form(H, TypeNames, RecDict, VarDict),
- {L, R2} = list_from_form(Tail, TypeNames, RecDict, VarDict),
+list_from_form([H|Tail], TypeNames, InOpaque, RecDict, VarDict) ->
+ {T, R1} = t_from_form(H, TypeNames, InOpaque, RecDict, VarDict),
+ {L, R2} = list_from_form(Tail, TypeNames, InOpaque, RecDict, VarDict),
{[T|L], R1 ++ R2}.
-spec t_form_to_string(parse_form()) -> string().
@@ -3881,8 +3985,9 @@ lookup_type(Name, RecDict) ->
type_is_defined(TypeOrOpaque, Name, RecDict) ->
dict:is_key({TypeOrOpaque, Name}, RecDict).
-unfold(TypeName, TypeNames) ->
- not lists:member(TypeName, TypeNames).
+can_unfold_more(TypeName, TypeNames) ->
+ Fun = fun(E, Acc) -> case E of TypeName -> Acc + 1; _ -> Acc end end,
+ lists:foldl(Fun, 0, TypeNames) < ?REC_TYPE_LIMIT.
%% -----------------------------------
%% Set
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index cf30db0482..8c9dbc0c18 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -30,6 +30,39 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.7.8.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Several type specifications for standard libraries were
+ wrong in the R14B01 release. This is now corrected. The
+ corrections concern types in re,io,filename and the
+ module erlang itself.</p>
+ <p>
+ Own Id: OTP-9008</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Hipe 3.7.8</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Compiler warnings were eliminated.</p>
+ <p>
+ Own Id: OTP-8855</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Hipe 3.7.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index 1f8be4040e..d7eb035551 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -369,6 +369,10 @@ trans_fun([{bif,BifName,{f,Lbl},[_] = Args,Reg}|Instructions], Env) ->
trans_fun([{bif,BifName,{f,Lbl},[_,_] = Args,Reg}|Instructions], Env) ->
{BifInsts,Env1} = trans_bif(2,BifName,Lbl,Args,Reg,Env),
[hipe_icode:mk_comment({bif2,BifName})|BifInsts] ++ trans_fun(Instructions,Env1);
+%%--- bif3 ---
+trans_fun([{bif,BifName,{f,Lbl},[_,_,_] = Args,Reg}|Instructions], Env) ->
+ {BifInsts,Env1} = trans_bif(3,BifName,Lbl,Args,Reg,Env),
+ [hipe_icode:mk_comment({bif3,BifName})|BifInsts] ++ trans_fun(Instructions,Env1);
%%--- allocate
trans_fun([{allocate,StackSlots,_}|Instructions], Env) ->
trans_allocate(StackSlots) ++ trans_fun(Instructions,Env);
@@ -914,7 +918,7 @@ trans_fun([{bs_add, {f,Lbl}, [Old,New,Unit], Res}|Instructions], Env) ->
Succ = mk_label(new),
[hipe_icode:mk_primop([Temp], '*',
[NewVar, hipe_icode:mk_const(Unit)],
- hipe_icode:label_name(Succ), Lbl),
+ hipe_icode:label_name(Succ), map_label(Lbl)),
Succ]
end
end,
@@ -926,7 +930,7 @@ trans_fun([{bs_add, {f,Lbl}, [Old,New,Unit], Res}|Instructions], Env) ->
[FailLbl,
hipe_icode:mk_fail([hipe_icode:mk_const(badarg)], error)]};
true ->
- {Lbl, []}
+ {map_label(Lbl), []}
end,
IsPos =
[hipe_icode:mk_if('>=', [Temp, hipe_icode:mk_const(0)],
diff --git a/lib/hipe/icode/hipe_icode_callgraph.erl b/lib/hipe/icode/hipe_icode_callgraph.erl
index 95182fc002..3dba8e1071 100644
--- a/lib/hipe/icode/hipe_icode_callgraph.erl
+++ b/lib/hipe/icode/hipe_icode_callgraph.erl
@@ -25,8 +25,6 @@
%% in hipe_icode_type.erl.
%%
%% Created : 7 Jun 2004 by Tobias Lindahl <[email protected]>
-%%
-%% $Id$
%%-----------------------------------------------------------------------
-module(hipe_icode_callgraph).
@@ -48,7 +46,7 @@
-type mfa_icode() :: {mfa(), #icode{}}.
--record(icode_callgraph, {codedict :: dict(), ordered_sccs :: [[atom()]]}).
+-record(icode_callgraph, {codedict :: dict(), ordered_sccs :: [[mfa()]]}).
%%------------------------------------------------------------------------
%% Exported functions
@@ -78,7 +76,7 @@ construct_callgraph(List) ->
to_list(#icode_callgraph{codedict = Dict, ordered_sccs = SCCs}) ->
FlatList = lists:flatten(SCCs),
- [{Mod, dict:fetch(Mod, Dict)} || Mod <- FlatList].
+ [{MFA, dict:fetch(MFA, Dict)} || MFA <- FlatList].
%%------------------------------------------------------------------------
diff --git a/lib/hipe/icode/hipe_icode_primops.erl b/lib/hipe/icode/hipe_icode_primops.erl
index b0fe7eb708..a413531c07 100644
--- a/lib/hipe/icode/hipe_icode_primops.erl
+++ b/lib/hipe/icode/hipe_icode_primops.erl
@@ -2,19 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -26,9 +26,6 @@
%% Notes :
%% History : * 2001-06-13 Erik Johansson ([email protected]):
%% Created.
-%%
-%% $Id$
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(hipe_icode_primops).
@@ -197,7 +194,7 @@ fails(#element{}) -> true;
%% fails(#gc_test{}) -> ???
fails({hipe_bs_primop, {bs_start_match, _}}) -> true;
fails({hipe_bs_primop, {{bs_start_match, bitstr}, _}}) -> true;
-fails({hipe_bs_primop, {{bs_start_match, ok_matchstate}, _}}) -> false;
+fails({hipe_bs_primop, {{bs_start_match, ok_matchstate}, _}}) -> true;
fails({hipe_bs_primop, {bs_get_binary, _, _}}) -> true;
fails({hipe_bs_primop, {bs_get_binary_all, _, _}}) -> true;
fails({hipe_bs_primop, {bs_get_binary_all_2, _, _}}) -> true;
diff --git a/lib/hipe/icode/hipe_icode_range.erl b/lib/hipe/icode/hipe_icode_range.erl
index bcc857acf4..c7e6a451af 100644
--- a/lib/hipe/icode/hipe_icode_range.erl
+++ b/lib/hipe/icode/hipe_icode_range.erl
@@ -843,7 +843,7 @@ compare_with_integer(N, OldVarRange) ->
%%== Ranges ==================================================================
--spec pp_ann(#ann{} | erl_types:erl_type()) -> [string()].
+-spec pp_ann(#ann{} | erl_types:erl_type()) -> string().
pp_ann(#ann{range=#range{range=R, other=false}}) ->
pp_range(R);
@@ -1365,7 +1365,7 @@ range_bnot(Range) ->
Minus_one = range_init({-1,-1}, false),
range_add(range_mult(Range, Minus_one), Minus_one).
--spec width(range_rep() | integer()) -> 'pos_inf' | non_neg_integer().
+-spec width(range_rep() | inf_integer()) -> 'pos_inf' | non_neg_integer().
width({Min, Max}) -> inf_max([width(Min), width(Max)]);
width(pos_inf) -> pos_inf;
diff --git a/lib/hipe/icode/hipe_icode_type.erl b/lib/hipe/icode/hipe_icode_type.erl
index 6726d62b53..3f9488d7c3 100644
--- a/lib/hipe/icode/hipe_icode_type.erl
+++ b/lib/hipe/icode/hipe_icode_type.erl
@@ -2,19 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%%--------------------------------------------------------------------
@@ -23,8 +23,6 @@
%%% Description : Propagate type information.
%%%
%%% Created : 25 Feb 2003 by Tobias Lindahl <[email protected]>
-%%%
-%%% $Id$
%%%--------------------------------------------------------------------
-module(hipe_icode_type).
@@ -39,8 +37,6 @@
update__info/2, new__info/1, return__info/1,
return_none/0, return_none_args/2, return_any_args/2]).
--compile({no_auto_import,[min/2,max/2]}).
-
%%=====================================================================
-include("../main/hipe.hrl").
@@ -80,7 +76,7 @@
%-define(server_debug, fun(X, Y) -> io:format("~p server: ~s ~p~n", [self(), X, Y]) end).
-define(server_debug, fun(_, _) -> ok end).
--import(erl_types, [min/2, max/2, number_min/1, number_max/1,
+-import(erl_types, [number_min/1, number_max/1,
t_any/0, t_atom/1, t_atom/0, t_atom_vals/1,
t_binary/0, t_bitstr/0, t_bitstr_base/1, t_bitstr_unit/1,
t_boolean/0, t_cons/0, t_constant/0,
@@ -496,10 +492,10 @@ integer_range_less_then_propagator(IntArg1, IntArg2) ->
Min2 = number_min(IntArg2),
Max2 = number_max(IntArg2),
%% is this the same as erl_types:t_subtract?? no ... ??
- TrueMax1 = min(Max1, erl_bif_types:infinity_add(Max2, -1)),
- TrueMin2 = max(erl_bif_types:infinity_add(Min1, 1), Min2),
- FalseMin1 = max(Min1, Min2),
- FalseMax2 = min(Max1, Max2),
+ TrueMax1 = erl_types:min(Max1, erl_bif_types:infinity_add(Max2, -1)),
+ TrueMin2 = erl_types:max(erl_bif_types:infinity_add(Min1, 1), Min2),
+ FalseMin1 = erl_types:max(Min1, Min2),
+ FalseMax2 = erl_types:min(Max1, Max2),
{t_from_range(Min1, TrueMax1),
t_from_range(TrueMin2, Max2),
t_from_range(FalseMin1, Max1),
diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl
index c80fb6a0a2..570e4d9d17 100644
--- a/lib/hipe/main/hipe.erl
+++ b/lib/hipe/main/hipe.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%
%%
%% ====================================================================
@@ -25,7 +25,6 @@
%% Purpose :
%% Notes :
%% History : * 1998-01-28 Erik Johansson ([email protected]): Created.
-%% CVS : $Id$
%% ====================================================================
%% @doc This is the direct interface to the HiPE compiler.
%%
@@ -506,7 +505,7 @@ compile(Name, File, Opts0) ->
run_compiler(Name, DisasmFun, IcodeFun, NewOpts)
end.
--spec compile_core(mod(), _, compile_file(), comp_options()) ->
+-spec compile_core(mod(), cerl:c_module(), compile_file(), comp_options()) ->
{'ok', compile_ret()} | {'error', term()}.
compile_core(Name, Core0, File, Opts) ->
@@ -535,7 +534,7 @@ compile_core(Name, Core0, File, Opts) ->
%%
%% @see compile/3
--spec compile(mod(), _, compile_file(), comp_options()) ->
+-spec compile(mod(), cerl:c_module() | [], compile_file(), comp_options()) ->
{'ok', compile_ret()} | {'error', term()}.
compile(Name, [], File, Opts) ->
@@ -790,7 +789,7 @@ finalize_fun(MfaIcodeList, Exports, Opts) ->
FalseVal when (FalseVal =:= undefined) orelse (FalseVal =:= false) ->
[finalize_fun_sequential(MFAIcode, Opts, #comp_servers{})
|| {_MFA, _Icode} = MFAIcode <- MfaIcodeList];
- TrueVal when (TrueVal =:= true) or (TrueVal =:= debug) ->
+ TrueVal when (TrueVal =:= true) orelse (TrueVal =:= debug) ->
finalize_fun_concurrent(MfaIcodeList, Exports, Opts)
end.
@@ -939,6 +938,8 @@ assemble(CompiledCode, Closures, Exports, Options) ->
hipe_sparc_assemble:assemble(CompiledCode, Closures, Exports, Options);
powerpc ->
hipe_ppc_assemble:assemble(CompiledCode, Closures, Exports, Options);
+ ppc64 ->
+ hipe_ppc_assemble:assemble(CompiledCode, Closures, Exports, Options);
arm ->
hipe_arm_assemble:assemble(CompiledCode, Closures, Exports, Options);
x86 ->
@@ -1048,7 +1049,7 @@ post(Res, Icode, Options) ->
%% --------------------------------------------------------------------
%% @doc Returns the current HiPE version as a string().
--spec version() -> string().
+-spec version() -> nonempty_string().
version() ->
?VERSION_STRING().
@@ -1390,6 +1391,8 @@ o1_opts() ->
Common;
powerpc ->
Common;
+ ppc64 ->
+ Common;
arm ->
Common -- [inline_fp]; % Pointless optimising for absent hardware
x86 ->
@@ -1411,6 +1414,8 @@ o2_opts() ->
Common;
powerpc ->
Common;
+ ppc64 ->
+ Common;
arm ->
Common;
x86 ->
@@ -1429,6 +1434,8 @@ o3_opts() ->
Common;
powerpc ->
Common;
+ ppc64 ->
+ Common;
arm ->
Common;
x86 ->
diff --git a/lib/hipe/main/hipe_main.erl b/lib/hipe/main/hipe_main.erl
index fe9bc83fd2..e81642fb33 100644
--- a/lib/hipe/main/hipe_main.erl
+++ b/lib/hipe/main/hipe_main.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%
%%
%% @doc This is the HiPE compiler's main "loop".
@@ -102,7 +102,7 @@ compile_icode(MFA, LinearIcode0, Options, Servers, DebugState) ->
?opt_start_timer("Icode"),
LinearIcode1 = icode_no_comment(LinearIcode0, Options),
IcodeCfg0 = icode_linear_to_cfg(LinearIcode1, Options),
- %%hipe_icode_cfg:pp(IcodeCfg1),
+ %% hipe_icode_cfg:pp(IcodeCfg0),
IcodeCfg1 = icode_handle_exceptions(IcodeCfg0, MFA, Options),
IcodeCfg3 = icode_inline_bifs(IcodeCfg1, Options),
pp(IcodeCfg3, MFA, icode, pp_icode, Options, Servers),
diff --git a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
index ac555b933c..ce33af453a 100644
--- a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
@@ -389,23 +389,23 @@ decrement_each([N|Ns], OldLow, IG, Vis, K) ->
%% {Spilled_node, Low_degree_neighbors, New_interference_graph}
spill(IG, Vis, Spill, K, SpillLimit, Target) ->
- Ns = list_ig(IG),
- Costs = spill_costs(Ns, IG, Vis, Spill, SpillLimit, Target),
- ?report3("spill costs are ~p~n",[Costs]),
- ActualCosts = lists:sort(Costs),
- ?report3("actual costs are ~p~n",[ActualCosts]),
+ Ns = list_ig(IG),
+ Costs = spill_costs(Ns, IG, Vis, Spill, SpillLimit, Target),
+ ?report3("spill costs are ~p~n", [Costs]),
+ ActualCosts = lists:sort(Costs),
+ ?report3("actual costs are ~p~n", [ActualCosts]),
case ActualCosts of
- [] ->
- ?error_msg("There is no node to spill",[]),
+ [] ->
+ ?error_msg("There is no node to spill", []),
?EXIT('no node to spill');
[{_Cost,N}|_] ->
{Low, NewIG} = decrement_neighbors(N, [], IG, Vis, K),
- %?report("spilled node ~p at cost ~p (~p now ready)~n",[N,Cost,Low]),
+ %% ?report("spilled node ~p at cost ~p (~p now ready)~n", [N,Cost,Low]),
{N, Low, NewIG}
end.
spill_costs([], _IG, _Vis, _Spill, _SpillLimit, _Target) ->
- [];
+ [];
spill_costs([{N,Info}|Ns], IG, Vis, Spill, SpillLimit, Target) ->
case degree(Info) of
0 -> spill_costs(Ns,IG,Vis,Spill, SpillLimit, Target);
@@ -451,28 +451,28 @@ select_colors([{X,colorable}|Xs], IG, Cols, PhysRegs, K) ->
{Reg,NewCols} = select_color(X, IG, Cols, PhysRegs),
?report("~p~n",[Reg]),
[{X,{reg,Reg}} | select_colors(Xs, IG, NewCols, PhysRegs, K)];
-%select_colors([{X,{spill,M}}|Xs], IG, Cols, PhysRegs, K) ->
-% ?report('spilled: ~p~n',[X]),
-% %% Check if optimistic coloring could have found a color
-% case catch select_color(X,IG,Cols,K) of
-% {'EXIT',_} -> % no color possible
-% ?report('(no optimistic color)~n',[]),
-% [{X,{spill,M}}|select_colors(Xs, IG, Cols, PhysRegs, K)];
-% {Reg,NewCols} ->
-% ?report('(optimistic color: ~p)~n',[Reg]),
-% [{X,{reg,Reg}}|select_colors(Xs, IG, Cols, PhysRegs, K)]
-% end.
+%%select_colors([{X,{spill,M}}|Xs], IG, Cols, PhysRegs, K) ->
+%% ?report('spilled: ~p~n',[X]),
+%% %% Check if optimistic coloring could have found a color
+%% case catch select_color(X,IG,Cols,K) of
+%% {'EXIT',_} -> % no color possible
+%% ?report('(no optimistic color)~n',[]),
+%% [{X,{spill,M}}|select_colors(Xs, IG, Cols, PhysRegs, K)];
+%% {Reg,NewCols} ->
+%% ?report('(optimistic color: ~p)~n',[Reg]),
+%% [{X,{reg,Reg}}|select_colors(Xs, IG, Cols, PhysRegs, K)]
+%% end.
%% Old code / pessimistic coloring:
select_colors([{X,{spill,M}}|Xs], IG, Cols, PhysRegs, K) ->
?report("spilled: ~p~n",[X]),
%% Check if optimistic coloring could have found a color
-% case catch select_color(X,IG,Cols,K) of
-% {'EXIT',_} -> % no color possible
-% ?report('(no optimistic color)~n',[]);
-% {Reg,NewCols} ->
-% ?report('(optimistic color: ~p)~n',[Reg])
-% end,
+%% case catch select_color(X,IG,Cols,K) of
+%% {'EXIT',_} -> % no color possible
+%% ?report('(no optimistic color)~n',[]);
+%% {Reg,NewCols} ->
+%% ?report('(optimistic color: ~p)~n',[Reg])
+%% end,
[{X,{spill,M}} | select_colors(Xs, IG, Cols, PhysRegs, K)].
select_color(X, IG, Cols, PhysRegs) ->
diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl
index ef06b2abf8..d93f423f0c 100644
--- a/lib/hipe/rtl/hipe_rtl.erl
+++ b/lib/hipe/rtl/hipe_rtl.erl
@@ -354,6 +354,8 @@
phi_arglist_update/2,
phi_redirect_pred/3]).
+-export_type([alub_cond/0]).
+
%%
%% RTL
%%
@@ -590,6 +592,9 @@ branch_pred(#branch{p=P}) -> P.
%% alub
%%
+-type alub_cond() :: 'eq' | 'ne' | 'ge' | 'geu' | 'gt' | 'gtu' | 'le'
+ | 'leu' | 'lt' | 'ltu' | 'overflow' | 'not_overflow'.
+
mk_alub(Dst, Src1, Op, Src2, Cond, True, False) ->
mk_alub(Dst, Src1, Op, Src2, Cond, True, False, 0.5).
mk_alub(Dst, Src1, Op, Src2, Cond, True, False, P) ->
diff --git a/lib/hipe/rtl/hipe_rtl_arith.inc b/lib/hipe/rtl/hipe_rtl_arith.inc
index 31fedd927e..9e80fa5e13 100644
--- a/lib/hipe/rtl/hipe_rtl_arith.inc
+++ b/lib/hipe/rtl/hipe_rtl_arith.inc
@@ -119,7 +119,8 @@ eval_alu(Op, Arg1, Arg2) ->
%% there are cases where we can evaluate a subset of the bits, but can
%% not do a full eval-alub call (eg. a + 0 gives no carry)
%%
--spec eval_cond_bits(atom(), boolean(), boolean(), boolean(), boolean()) -> boolean().
+-spec eval_cond_bits(hipe_rtl:alub_cond(), boolean(),
+ boolean(), boolean(), boolean()) -> boolean().
eval_cond_bits(Cond, N, Z, V, C) ->
case Cond of
@@ -146,9 +147,7 @@ eval_cond_bits(Cond, N, Z, V, C) ->
'overflow' ->
V;
'not_overflow' ->
- not V;
- _ ->
- ?EXIT({'condition code not handled',Cond})
+ not V
end.
eval_alub(Op, Cond, Arg1, Arg2) ->
diff --git a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
index 76c0a88933..64d723d15d 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
@@ -93,8 +93,6 @@
-include("../ssa/hipe_ssa_const_prop.inc").
-type bool_lattice() :: 'true' | 'false' | 'top' | 'bottom'.
--type conditional() :: 'eq' | 'ne' | 'ge' | 'geu' | 'gt' | 'gtu' | 'le'
- | 'leu' | 'lt' | 'ltu' | 'overflow' | 'not_overflow'.
%%-----------------------------------------------------------------------------
%% Procedure : visit_expression/2
@@ -400,7 +398,7 @@ maybe_top_or_bottom([top | Rest], _) -> maybe_top_or_bottom(Rest, top);
maybe_top_or_bottom([bottom | _], _) -> bottom;
maybe_top_or_bottom([_ | Rest], TB) -> maybe_top_or_bottom(Rest, TB).
--spec partial_eval_branch(conditional(), bool_lattice(), bool_lattice(),
+-spec partial_eval_branch(hipe_rtl:alub_cond(), bool_lattice(), bool_lattice(),
bool_lattice() | 0, bool_lattice() | 0) ->
bool_lattice().
partial_eval_branch(Cond, N0, Z0, V0, C0) ->
@@ -441,14 +439,14 @@ visit_alub(Inst, Env) ->
hipe_rtl:alub_false_label(Inst)];
top -> [];
_ ->
- %if the partial branch cannot be evaluated we must execute the
- % instruction at runtime.
+ %% if the partial branch cannot be evaluated we must execute the
+ %% instruction at runtime.
case partial_eval_branch(hipe_rtl:alub_cond(Inst), N, Z, C, V) of
bottom -> [hipe_rtl:alub_true_label(Inst),
hipe_rtl:alub_false_label(Inst)];
top -> [];
- true -> [hipe_rtl:alub_true_label(Inst) ];
- false -> [hipe_rtl:alub_false_label(Inst) ]
+ true -> [hipe_rtl:alub_true_label(Inst)];
+ false -> [hipe_rtl:alub_false_label(Inst)]
end
end,
{[], NewSSA, NewEnv} = set_to(hipe_rtl:alub_dst(Inst), NewVal, Env),
@@ -944,8 +942,8 @@ update_branch(Inst, Env) ->
%% some small helpers.
alub_to_move(Inst, Res, Lab) ->
- [ hipe_rtl:mk_move(hipe_rtl:alub_dst(Inst), Res),
- hipe_rtl:mk_goto(Lab) ].
+ [hipe_rtl:mk_move(hipe_rtl:alub_dst(Inst), Res),
+ hipe_rtl:mk_goto(Lab)].
make_alub_subst_list(bottom, _, Tail) -> Tail;
make_alub_subst_list(top, Src, _) ->
@@ -970,13 +968,13 @@ update_alub(Inst, Env) ->
%% move and the branch. We can however replace variable with constants:
S1 = make_alub_subst_list(Val1, Src1, []),
S2 = make_alub_subst_list(Val2, Src2, S1),
- [ hipe_rtl:subst_uses(S2, Inst) ];
- _ -> % we know where we will be going, let's find out what Dst should be.
- % knowing where we are going means that at most one of the values is
- % bottom, hence we can replace the alu-instr with a move.
- % remember, a = b + 0 can give us enough info to know what jump to
- % do without knowing the value of a. (I wonder if this will ever
- % actualy happen ;)
+ [hipe_rtl:subst_uses(S2, Inst)];
+ _ -> %% we know where we will be going, let's find out what Dst should be.
+ %% knowing where we are going means that at most one of the values is
+ %% bottom, hence we can replace the alu-instr with a move.
+ %% remember, a = b + 0 can give us enough info to know what jump to
+ %% do without knowing the value of a. (I wonder if this will ever
+ %% actualy happen ;)
Res = case ResVal of
bottom -> % something nonconstant.
if (Val1 =:= bottom) -> Src1;
@@ -985,11 +983,12 @@ update_alub(Inst, Env) ->
_ -> hipe_rtl:mk_imm(ResVal)
end,
case CondRes of
- top -> io:format("oops. something VERY bad: ~w ~w V1 & 2 ~w ~w\n",
- [Inst, {ResVal, N, Z, C, V} , Val1, Val2]),
- [Inst ];
- true -> alub_to_move(Inst, Res, hipe_rtl:alub_true_label(Inst));
- false -> alub_to_move(Inst, Res, hipe_rtl:alub_false_label(Inst))
+ top ->
+ io:format("oops. something VERY bad: ~w ~w V1 & 2 ~w ~w\n",
+ [Inst, {ResVal, N, Z, C, V} , Val1, Val2]),
+ [Inst];
+ true -> alub_to_move(Inst, Res, hipe_rtl:alub_true_label(Inst));
+ false -> alub_to_move(Inst, Res, hipe_rtl:alub_false_label(Inst))
end
end.
@@ -1050,7 +1049,7 @@ update_phi(Instruction, Environment) ->
%%-----------------------------------------------------------------------------
-%% make sure that all precoloured rgisters are taken out of the equation.
+%% make sure that all precoloured registers are taken out of the equation.
lookup_lattice_value(X, Environment) ->
case hipe_rtl_arch:is_precoloured(X) or hipe_rtl:is_const_label(X) of
true ->
diff --git a/lib/hipe/tools/hipe_tool.erl b/lib/hipe/tools/hipe_tool.erl
index a1bd79895d..990805ceca 100644
--- a/lib/hipe/tools/hipe_tool.erl
+++ b/lib/hipe/tools/hipe_tool.erl
@@ -56,9 +56,9 @@
-record(state, {win_created = false :: boolean(),
mindex = 0 :: integer(),
- mod :: module(),
+ mod :: atom(),
funs = [] :: [fa()],
- mods = [] :: [module()],
+ mods = [] :: [atom()],
options = [o2] :: comp_options(),
compiling = false :: 'false' | pid()
}).
@@ -291,8 +291,7 @@ update_code_listbox(State) ->
integer_to_list(length(Mods))++")"),
catch gs:config(code_listbox, [{data, Mods},
{items, Mods},
- {selection, 0}
- ]),
+ {selection, 0}]),
update_module_box(State#state{mods = Mods}, 0, Mods, "")
end
end.
@@ -367,7 +366,7 @@ update_text(Lab, Text) ->
%% @doc Returns a list of all loaded modules.
%%---------------------------------------------------------------------
--spec mods() -> [module()].
+-spec mods() -> [atom()].
mods() ->
[Mod || {Mod,_File} <- code:all_loaded()].
@@ -382,25 +381,26 @@ funs(Mod) ->
native_code(Mod) ->
Mod:module_info(native_addresses).
--spec mfas(module(), [fa()]) -> [mfa()].
+-spec mfas(atom(), [fa()]) -> [mfa()].
mfas(Mod, Funs) ->
[{Mod,F,A} || {F,A} <- Funs].
--spec fun_names(module(), [fa()], [fa_address()], boolean()) -> string().
+-spec fun_names(atom(), [fa()], [fa_address()], boolean()) -> [string()].
fun_names(M, Funs, NativeCode, Prof) ->
- [list_to_atom(atom_to_list(F) ++ "/" ++ integer_to_list(A) ++
- (case in_native(F, A, NativeCode) of
- true -> " [native] ";
- false -> ""
- end)
- ++
- if Prof ->
- (catch integer_to_list(hipe_bifs:call_count_get({M,F,A})));
- true -> ""
- end) ||
- {F,A} <- Funs].
+ [atom_to_list(F) ++ "/" ++ integer_to_list(A)
+ ++
+ (case in_native(F, A, NativeCode) of
+ true -> " [native] ";
+ false -> ""
+ end)
+ ++
+ if Prof ->
+ (catch integer_to_list(hipe_bifs:call_count_get({M,F,A})));
+ true -> ""
+ end
+ || {F,A} <- Funs].
-spec in_native(atom(), arity(), [fa_address()]) -> boolean().
@@ -461,7 +461,7 @@ get_compile(Info) ->
false -> []
end.
--spec is_profiled(module()) -> boolean().
+-spec is_profiled(atom()) -> boolean().
is_profiled(Mod) ->
case hipe_bifs:call_count_get({Mod,module_info,0}) of
@@ -478,7 +478,7 @@ compile(State) ->
P = spawn(fun() -> c(Parent, State#state.mod, State#state.options) end),
State#state{compiling = P}.
--spec c(pid(), module(), comp_options()) -> 'ok'.
+-spec c(pid(), atom(), comp_options()) -> 'ok'.
c(Parent, Mod, Options) ->
Res = hipe:c(Mod, Options),
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index 8e421ce9b2..513b1f4943 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.7.7
+HIPE_VSN = 3.7.8.1
diff --git a/lib/hipe/x86/hipe_x86_spill_restore.erl b/lib/hipe/x86/hipe_x86_spill_restore.erl
index e60c446e17..cd927669fb 100644
--- a/lib/hipe/x86/hipe_x86_spill_restore.erl
+++ b/lib/hipe/x86/hipe_x86_spill_restore.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% ====================================================================
@@ -71,9 +71,9 @@ firstPass(Defun) ->
case hipe_x86_cfg:reverse_postorder(CFG0) of
[Label1, Label2|_] ->
SaveTreeElement = saveTreeLookup(Label2, SaveTree),
- %% FilteredSaveTreeElement is the to be spilled temps around the function call.
- %% They are spilled just before move formals
- FilteredSaveTreeElement = [Temp || Temp <- SaveTreeElement, temp_is_pseudo(Temp)],
+ %% FilteredSaveTreeElement is the to be spilled temps around the
+ %% function call. They are spilled just before move formals.
+ FilteredSaveTreeElement = [T || T <- SaveTreeElement, temp_is_pseudo(T)],
Block = hipe_x86_cfg:bb(CFG1, Label1),
Code = hipe_bb:code(Block),
%% The following statements are tedious but work ok.
@@ -83,7 +83,7 @@ firstPass(Defun) ->
%% Another solution may be to introduce another block.
MoveCodes = lists:sublist(Code, length(Code)-1),
JumpCode = lists:last(Code),
- hipe_x86_cfg:bb_add(CFG1, Label1, hipe_bb:mk_bb(MoveCodes ++ [hipe_x86:mk_pseudo_spill(FilteredSaveTreeElement)] ++ [JumpCode]));
+ hipe_x86_cfg:bb_add(CFG1, Label1, hipe_bb:mk_bb(MoveCodes ++ [hipe_x86:mk_pseudo_spill(FilteredSaveTreeElement), JumpCode]));
_ ->
CFG1
end.
@@ -110,13 +110,12 @@ firstPassHelper([Label|Labels], Liveness, CFG, SaveTree) ->
NewBlock = hipe_bb:code_update(Block, NewCode),
NewCFG = hipe_x86_cfg:bb_add(CFG, Label, NewBlock),
SizeOfSet = setSize(NewIntersectedList),
-
%% if the Intersected Save List is not empty, insert it in the save tree.
if SizeOfSet =/= 0 ->
- UpdatedSaveTree = gb_trees:insert(Label,NewIntersectedList,SaveTree),
- firstPassHelper(Labels, Liveness, NewCFG,UpdatedSaveTree);
+ UpdatedSaveTree = gb_trees:insert(Label, NewIntersectedList, SaveTree),
+ firstPassHelper(Labels, Liveness, NewCFG, UpdatedSaveTree);
true ->
- firstPassHelper(Labels, Liveness, NewCFG,SaveTree)
+ firstPassHelper(Labels, Liveness, NewCFG, SaveTree)
end;
firstPassHelper([], _, CFG, SaveTree) ->
{CFG, SaveTree}.
@@ -125,17 +124,15 @@ firstPassHelper([], _, CFG, SaveTree) ->
firstPassDoBlock(Insts, LiveOut, IntersectedSaveList) ->
lists:foldr(fun firstPassDoInsn/2, {LiveOut,IntersectedSaveList,[]}, Insts).
-firstPassDoInsn(I, {LiveOut,IntersectedSaveList,PrevInsts} ) ->
+firstPassDoInsn(I, {LiveOut,IntersectedSaveList,PrevInsts}) ->
case I of
#pseudo_call{} ->
do_pseudo_call(I, {LiveOut,IntersectedSaveList,PrevInsts});
_ -> % other instructions
DefinedList = from_list( ?HIPE_X86_LIVENESS:defines(I)),
UsedList = from_list(?HIPE_X86_LIVENESS:uses(I)),
-
NewLiveOut = subtract(union(LiveOut, UsedList), DefinedList),
- NewIntersectedSaveList = subtract(IntersectedSaveList, DefinedList),
-
+ NewIntersectedSaveList = subtract(IntersectedSaveList, DefinedList),
{NewLiveOut, NewIntersectedSaveList, [I|PrevInsts]}
end.
@@ -162,7 +159,7 @@ saveTreeLookup(Label, SaveTree) ->
[]
end.
-%% Performs the second pass of the algoritm.
+%% Performs the second pass of the algorithm.
%% It basically eliminates the unnecessary spills and introduces restores.
%% Works top down
secondPass(CFG0) ->
@@ -306,7 +303,8 @@ addRestoreBlockToEdge(PseudoCall, ContLabel, CFG, TempArgsList) ->
NewCFG = hipe_x86_cfg:bb_add(CFG, NextLabel, NewBlock),
{NewCFG, NewPseudoCall}.
-%% used instead of hipe_x86_cfg:redirect_jmp since it does not handle pseudo_call calls.
+%% used instead of hipe_x86_cfg:redirect_jmp since it does not handle
+%% pseudo_call calls.
redirect_pseudo_call(I = #pseudo_call{contlab=ContLabel}, Old, New) ->
case Old =:= ContLabel of
true -> I#pseudo_call{contlab=New};
@@ -323,8 +321,8 @@ temp_is_pseudo(Temp) ->
%% Set operations where the module name is an easily changeable macro
%%---------------------------------------------------------------------
-union(Set1,Set2) ->
- ?SET_MODULE:union(Set1,Set2).
+union(Set1, Set2) ->
+ ?SET_MODULE:union(Set1, Set2).
setSize(Set) ->
?SET_MODULE:size(Set).
diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml
index 6684547572..5f6c31069c 100644
--- a/lib/ic/doc/src/notes.xml
+++ b/lib/ic/doc/src/notes.xml
@@ -31,6 +31,26 @@
</header>
<section>
+ <title>IC 4.2.26</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Partial support for recursive structs and unions. Only available
+ for the erl_corba backend and requires that Light IFR is used.
+ I.e. the IC option {light_ifr, true} and that Orber is configured
+ in such a way that Light IFR is activated. Recursive TypeCode is
+ currently not supported.</p>
+ <p>
+ Own Id: OTP-8868 Aux Id: seq11633</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>IC 4.2.25</title>
<section>
diff --git a/lib/ic/src/ic_forms.erl b/lib/ic/src/ic_forms.erl
index 7409ddeb7b..fc46a2ed40 100644
--- a/lib/ic/src/ic_forms.erl
+++ b/lib/ic/src/ic_forms.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -65,6 +65,7 @@ get_line(X) when is_record(X, scoped_id) -> X#scoped_id.line;
get_line(X) when is_record(X, module) -> get_line(X#module.id);
get_line(X) when is_record(X, interface) -> get_line(X#interface.id);
get_line(X) when is_record(X, forward) -> get_line(X#forward.id);
+get_line(X) when is_record(X, constr_forward) -> get_line(X#constr_forward.id);
get_line(X) when is_record(X, const) -> get_line(X#const.id);
get_line(X) when is_record(X, typedef) -> get_line(X#typedef.id);
get_line(X) when is_record(X, struct) -> get_line(X#struct.id);
@@ -114,6 +115,7 @@ get_line(_) -> -1.
get_id2(X) when is_record(X, module) -> get_id(X#module.id);
get_id2(X) when is_record(X, interface) -> get_id(X#interface.id);
get_id2(X) when is_record(X, forward) -> get_id(X#forward.id);
+get_id2(X) when is_record(X, constr_forward) -> get_id(X#constr_forward.id);
get_id2(X) when is_record(X, const) -> get_id(X#const.id);
get_id2(X) when is_record(X, typedef) -> get_id(hd(X#typedef.id));
get_id2(X) when is_record(X, struct) -> get_id(X#struct.id);
@@ -156,6 +158,7 @@ get_type(X) when is_record(X, param) -> X#param.type.
%% Temporary place
get_tk(X) when is_record(X, interface) -> X#interface.tk;
get_tk(X) when is_record(X, forward) -> X#forward.tk;
+get_tk(X) when is_record(X, constr_forward) -> X#constr_forward.tk;
get_tk(X) when is_record(X, const) -> X#const.tk;
get_tk(X) when is_record(X, type_dcl) -> X#type_dcl.tk;
get_tk(X) when is_record(X, typedef) -> X#typedef.tk;
@@ -228,6 +231,7 @@ clean_up_scope([N|Ns],Found) ->
get_type_code2(_, _, X) when is_record(X, interface) -> X#interface.tk;
get_type_code2(_, _, X) when is_record(X, forward) -> X#forward.tk;
+get_type_code2(_, _, X) when is_record(X, constr_forward) -> X#constr_forward.tk;
get_type_code2(_, _, X) when is_record(X, const) -> X#const.tk;
get_type_code2(_, _, X) when is_record(X, type_dcl) -> X#type_dcl.tk;
get_type_code2(_, _, X) when is_record(X, typedef) ->
diff --git a/lib/ic/src/ic_pragma.erl b/lib/ic/src/ic_pragma.erl
index 9165e3b03b..45cb64c9c8 100644
--- a/lib/ic/src/ic_pragma.erl
+++ b/lib/ic/src/ic_pragma.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -60,7 +60,7 @@ pragma_reg(G,X) ->
init_pragma_status(S),
registerOptions(G,S),
pragma_reg_all(G, S, [], X),
- denote_specific_code_opts(G), %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ denote_specific_code_opts(G),
case get_pragma_compilation_status(S) of
true ->
%% Remove ugly pragmas from form
@@ -132,6 +132,7 @@ applyCodeOpt(G) ->
%% This removes all pragma records from the form.
%% When debugged, it can be enbodied in pragma_reg_all.
+cleanup(undefined,C) -> C;
cleanup([],C) -> C;
cleanup([X|Xs],CSF) ->
cleanup(Xs, CSF++cleanup(X)).
@@ -279,7 +280,12 @@ pragma_reg(G, S, N, X) when is_record(X, union) ->
pragma_reg(G, S, N, X) when is_record(X, struct) ->
mk_ref(G,[get_id2(X) | N],struct_ref),
mk_file_data(G,X,N,struct),
- pragma_reg_all(G, S, N, X#struct.body);
+ case X#struct.body of
+ undefined ->
+ ok;
+ _ ->
+ pragma_reg_all(G, S, N, X#struct.body)
+ end;
pragma_reg(G, _S, N, X) when is_record(X, attr) ->
XX = #id_of{type=X},
diff --git a/lib/ic/src/ic_symtab.erl b/lib/ic/src/ic_symtab.erl
index 889c75e3a2..d710154a5d 100644
--- a/lib/ic/src/ic_symtab.erl
+++ b/lib/ic/src/ic_symtab.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -69,6 +69,8 @@ store(G, N, X) ->
ets:insert(G#genobj.symtab, {Name, X});
{ok, Y} when is_record(Y, forward) ->
ets:insert(G#genobj.symtab, {Name, X});
+ {ok, Y} when is_record(Y, constr_forward) ->
+ ets:insert(G#genobj.symtab, {Name, X});
{ok, _Y} ->
ic_error:error(G, {multiply_defined, X})
end.
diff --git a/lib/ic/src/icforms.hrl b/lib/ic/src/icforms.hrl
index d1869e6330..1b394a11b4 100644
--- a/lib/ic/src/icforms.hrl
+++ b/lib/ic/src/icforms.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -34,6 +34,7 @@
-record(module, {id, body}).
-record(interface, {id, inherit, body, inherit_body, tk}).
-record(forward, {id, tk}).
+-record(constr_forward, {id, tk}).
-record(const, {type, id, val, tk}).
-record(type_dcl, {type, tk}).
-record(typedef, {type, id, tk}).
diff --git a/lib/ic/src/icparse.yrl b/lib/ic/src/icparse.yrl
index 25b0f452e7..d0dd6cde4c 100644
--- a/lib/ic/src/icparse.yrl
+++ b/lib/ic/src/icparse.yrl
@@ -1,21 +1,20 @@
-%%<copyright>
-%% <year>1997-2007</year>
-%% <holder>Ericsson AB, All Rights Reserved</holder>
-%%</copyright>
-%%<legalnotice>
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
-%% The Initial Developer of the Original Code is Ericsson AB.
-%%</legalnotice>
+%%
+%% %CopyrightEnd%
%%
%%------------------------------------------------------------
%% Yecc spec for IDL
@@ -150,6 +149,7 @@ Nonterminals
'ZorM_<integer_literal>'
'<fixed_pt_type>'
'<fixed_pt_const_type>'
+ '<constr_forward_decl>'
.
@@ -473,6 +473,7 @@ OE_preproc -> '#' '<integer_literal>' '<string_literal>'
'<type_dcl>' -> '<struct_type>' : '$1' .
'<type_dcl>' -> '<union_type>' : '$1' .
'<type_dcl>' -> '<enum_type>' : '$1' .
+'<type_dcl>' -> '<constr_forward_decl>' : '$1' .
%% (28) NIY multiple declarators (FIXED)
'<type_declarator>' -> '<type_spec>' '<declarators>'
@@ -832,6 +833,9 @@ OE_preproc -> '#' '<integer_literal>' '<string_literal>'
'<fixed_pt_type>' -> 'fixed' '<' '<positive_int_const>' ',' '<positive_int_const>' '>'
: #fixed{digits='$3',scale='$5'} .
+%% (99)
+'<constr_forward_decl>' -> 'struct' '<identifier>' : #constr_forward{id='$2', tk=tk_struct} .
+'<constr_forward_decl>' -> 'union' '<identifier>' : #constr_forward{id='$2', tk=tk_union} .
%% Added clause
'ZorM_<string_literal>' -> '$empty' : [] .
diff --git a/lib/ic/src/ictype.erl b/lib/ic/src/ictype.erl
index 4704191bee..9e20801464 100644
--- a/lib/ic/src/ictype.erl
+++ b/lib/ic/src/ictype.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -407,6 +407,18 @@ check(G, S, N, X) when is_record(X, forward) ->
tktab_add(G, S, N, X, {tk_objref, ictk:get_IR_ID(G, N, X), ic_forms:get_id2(X)}),
X;
+check(G, S, N, #constr_forward{tk = tk_struct} = X) ->
+ ?STDDBG,
+ ID = ic_forms:get_id2(X),
+ Module = list_to_atom(string:join(lists:reverse([ID|N]), "_")),
+ tktab_add(G, S, N, X, {tk_struct, ictk:get_IR_ID(G, N, X), ID, Module}),
+ X;
+check(G, S, N, #constr_forward{tk = tk_union} = X) ->
+ ?STDDBG,
+ ID = ic_forms:get_id2(X),
+ Module = list_to_atom(string:join(lists:reverse([ID|N]), "_")),
+ tktab_add(G, S, N, X, {tk_union, ictk:get_IR_ID(G, N, X), ID, [], [], Module}),
+ X;
check(G, S, N, X) when is_record(X, const) ->
?STDDBG,
@@ -427,21 +439,6 @@ check(G, S, N, X) when is_record(X, const) ->
end
end;
-check(G, S, N, X) when is_record(X, const) ->
- ?STDDBG,
- case tk_base(G, S, N, ic_forms:get_type(X)) of
- Err when element(1, Err) == error -> X;
- TK ->
- check_const_tk(G, S, N, X, TK),
- case iceval:eval_const(G, S, N, TK, X#const.val) of
- Err when element(1, Err) == error -> X;
- Val ->
- V = iceval:get_val(Val),
- tktab_add(G, S, N, X, TK, V),
- X#const{val=V, tk=TK}
- end
- end;
-
check(G, S, N, X) when is_record(X, except) ->
?STDDBG,
TK = tk(G, S, N, X),
@@ -795,9 +792,15 @@ tktab_add_id(G, S, N, X, Id, TK, Aux) ->
Name = [Id | N],
UName = mk_uppercase(Name),
case ets:lookup(S, Name) of
- [{_, forward, _, _}] when is_record(X, interface) -> ok;
- [XX] when is_record(X, forward) andalso element(2, XX)==interface -> ok;
- [_] -> ic_error:error(G, {multiply_defined, X});
+ [{_, forward, _, _}] when is_record(X, interface) ->
+ ok;
+ [{_, constr_forward, _, _}] when is_record(X, union) orelse
+ is_record(X, struct) ->
+ ok;
+ [XX] when is_record(X, forward) andalso element(2, XX)==interface ->
+ ok;
+ [_] ->
+ ic_error:error(G, {multiply_defined, X});
[] ->
case ets:lookup(S, UName) of
[] -> ok;
diff --git a/lib/ic/test/Makefile b/lib/ic/test/Makefile
index 1142159d19..988e7e7985 100644
--- a/lib/ic/test/Makefile
+++ b/lib/ic/test/Makefile
@@ -33,7 +33,7 @@ RELSYSDIR = $(RELEASE_PATH)/ic_test
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
-TEST_SPEC_FILE = ic.spec ic.spec.vxworks
+TEST_SPEC_FILE = ic.spec
IDL_FILES =
@@ -251,7 +251,7 @@ release_tests_spec: tests
$(INSTALL_DIR) $(RELSYSDIR)/erl_client_c_server_SUITE_data
$(INSTALL_DIR) $(RELSYSDIR)/erl_client_c_server_proto_SUITE_data
$(INSTALL_DIR) $(RELSYSDIR)/java_client_erl_server_SUITE_data
- $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) $(ERL_FILES) \
+ $(INSTALL_DATA) $(IDL_FILES) ic.cover $(TEST_SPEC_FILE) $(ERL_FILES) \
$(RELSYSDIR)
$(INSTALL_DATA) $(COMPILER_TEST_FILES) $(RELSYSDIR)/ic_SUITE_data
$(INSTALL_DATA) $(COMPILER_TEST_FILES2) \
diff --git a/lib/ic/test/c_client_erl_server_SUITE.erl b/lib/ic/test/c_client_erl_server_SUITE.erl
index 40c1395d10..038172c311 100644
--- a/lib/ic/test/c_client_erl_server_SUITE.erl
+++ b/lib/ic/test/c_client_erl_server_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -24,10 +24,12 @@
-module(c_client_erl_server_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
--export([init_per_testcase/2, fin_per_testcase/2,
- all/1, void_test/1, long_test/1, long_long_test/1,
+-export([init_per_testcase/2, end_per_testcase/2,
+ all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ void_test/1, long_test/1, long_long_test/1,
unsigned_short_test/1, unsigned_long_test/1,
unsigned_long_long_test/1, double_test/1, char_test/1,
wchar_test/1, octet_test/1, bool_test/1, struct_test/1,
@@ -57,25 +59,40 @@ init_per_testcase(_Case, Config) ->
WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
DataDir = ?config(data_dir, Config),
code:del_path(DataDir),
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of IC with a C-client and an Erlang generic server. "
- "The communication is via Erlang distribution.";
-all(suite) ->
- [void_test, long_test, long_long_test, unsigned_short_test,
- unsigned_long_test, unsigned_long_long_test, double_test,
- char_test, wchar_test, octet_test, bool_test, struct_test,
- struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
- seq5_test, array1_test, array2_test, enum_test, string1_test,
- string2_test, string3_test, string4_test, pid_test, port_test,
- ref_test, term_test, typedef_test, inline_sequence_test,
- term_sequence_test, term_struct_test, wstring1_test].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+all() ->
+ [void_test, long_test, long_long_test,
+ unsigned_short_test, unsigned_long_test,
+ unsigned_long_long_test, double_test, char_test,
+ wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test,
+ seq4_test, seq5_test, array1_test, array2_test,
+ enum_test, string1_test, string2_test, string3_test,
+ string4_test, pid_test, port_test, ref_test, term_test,
+ typedef_test, inline_sequence_test, term_sequence_test,
+ term_struct_test, wstring1_test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
array1_test(doc) -> "";
array1_test(suite) -> [];
diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE.erl b/lib/ic/test/c_client_erl_server_proto_SUITE.erl
index 58309a2221..172e4de6d1 100644
--- a/lib/ic/test/c_client_erl_server_proto_SUITE.erl
+++ b/lib/ic/test/c_client_erl_server_proto_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,10 +23,12 @@
%%----------------------------------------------------------------------
-module(c_client_erl_server_proto_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
--export([init_per_testcase/2, fin_per_testcase/2,
- all/1, void_test/1, long_test/1, long_long_test/1,
+-export([init_per_testcase/2, end_per_testcase/2,
+ all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ void_test/1, long_test/1, long_long_test/1,
unsigned_short_test/1, unsigned_long_test/1,
unsigned_long_long_test/1, double_test/1, char_test/1,
wchar_test/1, octet_test/1, bool_test/1, struct_test/1,
@@ -56,25 +58,40 @@ init_per_testcase(_Case, Config) ->
WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
DataDir = ?config(data_dir, Config),
code:del_path(DataDir),
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of IC with a C-client and an Erlang generic server. "
- "The communication is via Erlang distribution.";
-all(suite) ->
- [void_test, long_test, long_long_test, unsigned_short_test,
- unsigned_long_test, unsigned_long_long_test, double_test,
- char_test, wchar_test, octet_test, bool_test, struct_test,
- struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
- seq5_test, array1_test, array2_test, enum_test, string1_test,
- string2_test, string3_test, string4_test, pid_test, port_test,
- ref_test, term_test, typedef_test, inline_sequence_test,
- term_sequence_test, term_struct_test, wstring1_test].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+all() ->
+ [void_test, long_test, long_long_test,
+ unsigned_short_test, unsigned_long_test,
+ unsigned_long_long_test, double_test, char_test,
+ wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test,
+ seq4_test, seq5_test, array1_test, array2_test,
+ enum_test, string1_test, string2_test, string3_test,
+ string4_test, pid_test, port_test, ref_test, term_test,
+ typedef_test, inline_sequence_test, term_sequence_test,
+ term_struct_test, wstring1_test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
array1_test(doc) -> "";
array1_test(suite) -> [];
diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl
index 595c5bf483..53bf99c917 100644
--- a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl
+++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,10 +23,12 @@
%%----------------------------------------------------------------------
-module(c_client_erl_server_proto_tmo_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
--export([init_per_testcase/2, fin_per_testcase/2,
- all/1, void_test/1, long_test/1, long_long_test/1,
+-export([init_per_testcase/2, end_per_testcase/2,
+ all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ void_test/1, long_test/1, long_long_test/1,
unsigned_short_test/1, unsigned_long_test/1,
unsigned_long_long_test/1, double_test/1, char_test/1,
wchar_test/1, octet_test/1, bool_test/1, struct_test/1,
@@ -56,24 +58,41 @@ init_per_testcase(_Case, Config) ->
WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
DataDir = ?config(data_dir, Config),
code:del_path(DataDir),
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of IC with a C-client and an Erlang generic server. "
- "The communication is via Erlang distribution.";
-all(suite) ->
- [void_test, long_test, long_long_test, unsigned_short_test,
- unsigned_long_test, unsigned_long_long_test, double_test,
- char_test, wchar_test, octet_test, bool_test, struct_test,
- struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
- seq5_test, array1_test, array2_test, enum_test, string1_test,
- string2_test, string3_test, string4_test, pid_test, port_test,
- ref_test, term_test, typedef_test, inline_sequence_test,
- term_sequence_test, term_struct_test, wstring1_test].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [void_test, long_test, long_long_test,
+ unsigned_short_test, unsigned_long_test,
+ unsigned_long_long_test, double_test, char_test,
+ wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test,
+ seq4_test, seq5_test, array1_test, array2_test,
+ enum_test, string1_test, string2_test, string3_test,
+ string4_test, pid_test, port_test, ref_test, term_test,
+ typedef_test, inline_sequence_test, term_sequence_test,
+ term_struct_test, wstring1_test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
array1_test(doc) -> "";
diff --git a/lib/ic/test/erl_client_c_server_SUITE.erl b/lib/ic/test/erl_client_c_server_SUITE.erl
index c5f5b6a218..a42dbb9604 100644
--- a/lib/ic/test/erl_client_c_server_SUITE.erl
+++ b/lib/ic/test/erl_client_c_server_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -24,9 +24,9 @@
-module(erl_client_c_server_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
--export([init_per_testcase/2, fin_per_testcase/2, all/1, void_test/1,
+-export([init_per_testcase/2, end_per_testcase/2,all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, void_test/1,
long_test/1, longlong_test/1, ushort_test/1, ulong_test/1,
ulonglong_test/1, double_test/1, char_test/1, wchar_test/1,
octet_test/1, bool_test/1, struct_test/1, struct2_test/1,
@@ -57,24 +57,40 @@ init_per_testcase(_Case, Config) ->
WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
DataDir = ?config(data_dir, Config),
code:del_path(DataDir),
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of IC with an Erlang client and a C server. "
- "The communication is via Erlang distribution.";
-all(suite) ->
- [void_test, long_test, longlong_test, ushort_test,
- ulong_test, ulonglong_test, double_test,
- char_test, wchar_test, octet_test, bool_test, struct_test,
- struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
- seq5_test, array1_test, array2_test, enum_test, string1_test,
- string2_test, string3_test, string4_test, pid_test, port_test,
- ref_test, term_test, typedef_test, inline_sequence_test,
- term_sequence_test, term_struct_test, wstring1_test].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+[void_test, long_test, longlong_test, ushort_test,
+ ulong_test, ulonglong_test, double_test, char_test,
+ wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test,
+ seq4_test, seq5_test, array1_test, array2_test,
+ enum_test, string1_test, string2_test, string3_test,
+ string4_test, pid_test, port_test, ref_test, term_test,
+ typedef_test, inline_sequence_test, term_sequence_test,
+ term_struct_test, wstring1_test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
array1_test(doc) -> "";
diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE.erl b/lib/ic/test/erl_client_c_server_proto_SUITE.erl
index d75feb621a..c8ad4042e4 100644
--- a/lib/ic/test/erl_client_c_server_proto_SUITE.erl
+++ b/lib/ic/test/erl_client_c_server_proto_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -24,9 +24,9 @@
-module(erl_client_c_server_proto_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
--export([init_per_testcase/2, fin_per_testcase/2, all/1, void_test/1,
+-export([init_per_testcase/2, end_per_testcase/2,all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, void_test/1,
long_test/1, longlong_test/1, ushort_test/1, ulong_test/1,
ulonglong_test/1, double_test/1, char_test/1, wchar_test/1,
octet_test/1, bool_test/1, struct_test/1, struct2_test/1,
@@ -57,24 +57,40 @@ init_per_testcase(_Case, Config) ->
WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
DataDir = ?config(data_dir, Config),
code:del_path(DataDir),
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of IC with an Erlang client and a C server. "
- "The communication is via Erlang distribution.";
-all(suite) ->
- [void_test, long_test, longlong_test, ushort_test,
- ulong_test, ulonglong_test, double_test,
- char_test, wchar_test, octet_test, bool_test, struct_test,
- struct2_test, seq1_test, seq2_test, seq3_test, seq4_test,
- seq5_test, array1_test, array2_test, enum_test, string1_test,
- string2_test, string3_test, string4_test, pid_test, port_test,
- ref_test, term_test, typedef_test, inline_sequence_test,
- term_sequence_test, term_struct_test, wstring1_test].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+[void_test, long_test, longlong_test, ushort_test,
+ ulong_test, ulonglong_test, double_test, char_test,
+ wchar_test, octet_test, bool_test, struct_test,
+ struct2_test, seq1_test, seq2_test, seq3_test,
+ seq4_test, seq5_test, array1_test, array2_test,
+ enum_test, string1_test, string2_test, string3_test,
+ string4_test, pid_test, port_test, ref_test, term_test,
+ typedef_test, inline_sequence_test, term_sequence_test,
+ term_struct_test, wstring1_test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
array1_test(doc) -> "";
diff --git a/lib/ic/test/ic.cover b/lib/ic/test/ic.cover
new file mode 100644
index 0000000000..5a679c8b6f
--- /dev/null
+++ b/lib/ic/test/ic.cover
@@ -0,0 +1,2 @@
+{incl_app,ic,details}.
+
diff --git a/lib/ic/test/ic.spec b/lib/ic/test/ic.spec
index 280c2aba47..22905dcee4 100644
--- a/lib/ic/test/ic.spec
+++ b/lib/ic/test/ic.spec
@@ -1 +1 @@
-{topcase, {dir, "../ic_test"}}.
+{suites,"../ic_test",all}.
diff --git a/lib/ic/test/ic_SUITE.erl b/lib/ic/test/ic_SUITE.erl
index 6682c82f01..6a9d1325e1 100644
--- a/lib/ic/test/ic_SUITE.erl
+++ b/lib/ic/test/ic_SUITE.erl
@@ -22,9 +22,10 @@
%%%----------------------------------------------------------------------
-module(ic_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-include_lib("orber/src/orber_ifr.hrl").
@@ -33,36 +34,36 @@
%% The type cases
--export([type/1, type_norm/1]).
+-export([ type_norm/1]).
%% The syntax case
--export([syntax/1]).
+-export([]).
-export([syntax1/1, syntax2/1, syntax3/1, syntax4/1, syntax5/1, syntax6/1]).
%% The constant cases
--export([const/1]).
+-export([]).
-export([const_norm/1, const_bad_tk/1, const_bad_type/1]).
-export([const_bad_comb/1]).
%% The union cases
--export([union/1]).
+-export([]).
-export([union_norm/1, union_type/1, union_mult_err/1, union_case_mult/1]).
-export([union_default/1]).
%% The enum cases
--export([enum/1]).
+-export([]).
-export([enum_norm/1]).
%% The struct cases
--export([struct/1]).
+-export([]).
-export([struct_norm/1]).
%% The oneway cases
--export([oneway/1]).
+-export([]).
-export([oneway_norm/1, oneway_raises/1, oneway_out/1, oneway_void/1, oneway_followed/1]).
%% The attributes cases
--export([attr/1]).
+-export([]).
-export([attr_norm/1]).
%% The raises registration case
@@ -72,12 +73,12 @@
%% The typeID case
%% general stuff
--export([general/1]).
+-export([]).
-export([typeid/1, undef_id/1, dir/1, nasty_names/1, coss/1, mult_ids/1]).
-export([forward/1, include/1, app_test/1]).
%% inheritance stuff
--export([inherit/1, inherit_norm/1, inherit_warn/1, inherit_err/1]).
+-export([ inherit_norm/1, inherit_warn/1, inherit_err/1]).
%% Standard options to the ic compiler, NOTE unholy use of OutDir
@@ -86,10 +87,46 @@
%% Top of cases
-all(doc) ->
- [];
-all(suite) -> [app_test, const, union, enum, attr, type, struct, general, inherit,
- oneway, syntax, raises_reg].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [app_test, {group, const}, {group, union},
+ {group, enum}, {group, attr}, {group, type},
+ {group, struct}, {group, general}, {group, inherit},
+ {group, oneway}, {group, syntax}, raises_reg].
+
+groups() ->
+ [{const, [],
+ [const_norm, const_bad_tk, const_bad_type,
+ const_bad_comb]},
+ {union, [],
+ [union_norm, union_type, union_mult_err,
+ union_case_mult, union_default]},
+ {enum, [], [enum_norm]}, {struct, [], [struct_norm]},
+ {general, [],
+ [typeid, undef_id, mult_ids, forward, include,
+ nasty_names]},
+ {inherit, [],
+ [inherit_norm, inherit_warn, inherit_err]},
+ {oneway, [],
+ [oneway_norm, oneway_out, oneway_raises, oneway_void,
+ oneway_followed]},
+ {attr, [], [attr_norm]}, {type, [], [type_norm]},
+ {syntax, [],
+ [syntax1, syntax2, syntax3, syntax4, syntax5, syntax6]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
app_test(doc) -> [];
@@ -103,7 +140,6 @@ app_test(_Config) ->
%% Test of constant expressions.
%%
-const(suite) -> [const_norm, const_bad_tk, const_bad_type, const_bad_comb].
const_norm(doc) ->
@@ -159,10 +195,6 @@ const_bad_comb(Config) when is_list(Config) ->
-union(suite) -> [union_norm, union_type, union_mult_err, union_case_mult,
- union_default];
-union(doc) ->
- ["Checks allowed usage of the union as well as the illegal cases"].
union_norm(doc) ->
@@ -277,9 +309,6 @@ union_case_mult(Config) when is_list(Config) ->
%% Enum cases
%%
-enum(suite) -> [enum_norm];
-enum(doc) ->
- ["Checks allowed usage of the enum as well as the illegal cases"].
enum_norm(doc) ->
["Checks that normal enum declarations works."];
@@ -300,9 +329,6 @@ enum_norm(Config) when is_list(Config) ->
%% Struct cases
%%
-struct(suite) -> [struct_norm];
-struct(doc) ->
- ["Checks allowed usage of the struct as well as the illegal cases"].
struct_norm(doc) ->
["Checks that normal struct declarations works."];
@@ -331,10 +357,6 @@ struct_norm(Config) when is_list(Config) ->
%% General cases
%%
-general(doc) ->
- ["Check general things like directories and type identifier",
- "detection."];
-general(suite) -> [typeid, undef_id, mult_ids, forward, include, nasty_names].
%% coss (add sometimes, takes 440 seconds!)
typeid(doc) ->
@@ -490,9 +512,6 @@ include(Config) when is_list(Config) ->
%% Inhertit cases
%%
-inherit(doc) ->
- ["Check the inheritance mechanism."];
-inherit(suite) -> [inherit_norm, inherit_warn, inherit_err].
inherit_norm(doc) ->
["Checks that normal inheritance works."];
@@ -547,9 +566,6 @@ inherit_err(Config) when is_list(Config) ->
ok.
-oneway(doc) ->
- ["Check the oneway operation mechanism."];
-oneway(suite) -> [oneway_norm, oneway_out, oneway_raises, oneway_void, oneway_followed ].
oneway_norm(doc) ->
["Checks that normal oneway operations works."];
@@ -618,9 +634,6 @@ oneway_followed(Config) when is_list(Config) ->
?line ok = compile(OutDir, oneway_followed_files(), [load]),
ok.
-attr(doc) ->
- ["Check that attributes work."];
-attr(suite) -> [attr_norm].
attr_norm(doc) ->
["Checks that normal attr operations works."];
@@ -636,9 +649,6 @@ attr_norm(Config) when is_list(Config) ->
?line ok = compile(OutDir, attr_norm_files(), [load]),
ok.
-type(doc) ->
- ["Check that typeibutes work."];
-type(suite) -> [type_norm].
type_norm(doc) ->
["Checks all types are handled."];
@@ -655,9 +665,6 @@ type_norm(Config) when is_list(Config) ->
ok.
-syntax(doc) ->
- ["Check that syntax errors are discovered."];
-syntax(suite) -> [syntax1, syntax2, syntax3, syntax4, syntax5, syntax6].
syntax1(suite) -> [];
syntax1(Config) when is_list(Config) ->
diff --git a/lib/ic/test/ic_be_SUITE.erl b/lib/ic/test/ic_be_SUITE.erl
index e3caf7bdff..3693d22cd2 100644
--- a/lib/ic/test/ic_be_SUITE.erl
+++ b/lib/ic/test/ic_be_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,10 +22,11 @@
%%%----------------------------------------------------------------------
-module(ic_be_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,plain/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,plain/1]).
-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])).
@@ -33,7 +34,26 @@
%% Top of cases
-all(suite) -> [plain].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [plain].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
diff --git a/lib/ic/test/ic_pp_SUITE.erl b/lib/ic/test/ic_pp_SUITE.erl
index d68242bf3a..27d404239f 100644
--- a/lib/ic/test/ic_pp_SUITE.erl
+++ b/lib/ic/test/ic_pp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,7 +22,7 @@
%%----------------------------------------------------------------------
-module(ic_pp_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
@@ -32,50 +32,57 @@
-define(GCC, "g++").
-define(GCC_VER, "2.95.3").
--export([all/1]).
--export([arg/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([arg_norm/1]).
--export([cascade/1]).
-export([cascade_norm/1]).
--export([comment/1]).
-export([comment_norm/1]).
--export([concat/1]).
-export([concat_norm/1]).
--export([define/1]).
-export([define_norm/1]).
--export(['if'/1]).
-export([if_norm/1]).
-export([if_zero/1]).
--export([misc/1]).
-export([misc_norm/1]).
--export([improp_nest_constr/1]).
-export([improp_nest_constr_norm/1]).
--export([inc/1]).
-export([inc_norm/1]).
--export([line/1]).
-export([line_norm/1]).
--export([nopara/1]).
-export([nopara_norm/1]).
--export([predef/1]).
-export([predef_norm/1]).
--export([predef_time/1]).
-export([predef_time_norm/1]).
--export([self_ref/1]).
-export([self_ref_norm/1]).
--export([separate/1]).
-export([separate_norm/1]).
--export([swallow_sc/1]).
-export([swallow_sc_norm/1]).
--export([unintended_grp/1]).
-export([unintended_grp_norm/1]).
--export([cases/0, init_all/1, finish_all/1]).
+-export([cases/0, init_per_suite/1, end_per_suite/1]).
-all(doc) -> ["Preprocessing tests for IC"];
-all(suite) ->
- {req, [], {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-init_all(Config) ->
+all() ->
+ cases().
+
+groups() ->
+ [{arg, [], [arg_norm]}, {cascade, [], [cascade_norm]},
+ {comment, [], [comment_norm]},
+ {concat, [], [concat_norm]},
+ {define, [], [define_norm]}, {inc, [], [inc_norm]},
+ {improp_nest_constr, [], [improp_nest_constr_norm]},
+ {misc, [], [misc_norm]}, {line, [], [line_norm]},
+ {nopara, [], [nopara_norm]},
+ {predef, [], [predef_norm]},
+ {predef_time, [], [predef_time_norm]},
+ {self_ref, [], [self_ref_norm]},
+ {separate, [], [separate_norm]},
+ {swallow_sc, [], [swallow_sc_norm]},
+ {unintended_grp, [], [unintended_grp_norm]},
+ {'if', [],[if_norm, if_zero]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(Config) ->
if
is_list(Config) ->
case os:type() of
@@ -120,14 +127,18 @@ skip_white([$\t|T]) -> skip_white(T);
skip_white(L) -> L.
-finish_all(Config) ->
+end_per_suite(Config) ->
Config.
-cases() ->
- [arg, cascade, comment, concat, define, misc, 'if', improp_nest_constr, inc,
- line, nopara, predef, predef_time, self_ref, separate, swallow_sc,
- unintended_grp].
+cases() ->
+ [{group, arg}, {group, cascade}, {group, comment},
+ {group, concat}, {group, define}, {group, misc}, {group, 'if'},
+ {group, improp_nest_constr}, {group, inc},
+ {group, line}, {group, nopara}, {group, predef},
+ {group, predef_time}, {group, self_ref},
+ {group, separate}, {group, swallow_sc},
+ {group, unintended_grp}].
@@ -135,8 +146,6 @@ cases() ->
%% arg
%%--------------------------------------------------------------------
-arg(suite) -> [arg_norm];
-arg(doc) -> ["Check #define with some arguments"].
arg_norm(doc) -> ["Checks arguments for #define."];
arg_norm(suite) -> [];
@@ -153,8 +162,6 @@ arg_norm(Config) when is_list(Config) ->
%% cascade
%%--------------------------------------------------------------------
-cascade(suite) -> [cascade_norm];
-cascade(doc) -> ["Check cascade #define"].
cascade_norm(doc) -> ["Check cascade #define."];
cascade_norm(suite) -> [];
@@ -171,8 +178,6 @@ cascade_norm(Config) when is_list(Config) ->
%% comment
%%--------------------------------------------------------------------
-comment(suite) -> [comment_norm];
-comment(doc) -> ["Check comments"].
comment_norm(doc) -> ["Check comments."];
comment_norm(suite) -> [];
@@ -189,8 +194,6 @@ comment_norm(Config) when is_list(Config) ->
%% concat
%%--------------------------------------------------------------------
-concat(suite) -> [concat_norm];
-concat(doc) -> ["Check concatinations, i.e ## "].
concat_norm(doc) -> ["Check concatinations, i.e ## ."];
concat_norm(suite) -> [];
@@ -207,8 +210,6 @@ concat_norm(Config) when is_list(Config) ->
%% define
%%--------------------------------------------------------------------
-define(suite) -> [define_norm];
-define(doc) -> ["Check misceleaneous #define"].
define_norm(doc) -> ["Check misceleaneous #define."];
define_norm(suite) -> [];
@@ -225,10 +226,6 @@ define_norm(Config) when is_list(Config) ->
%% if
%%--------------------------------------------------------------------
-'if'(suite) -> [if_norm, if_zero];
-'if'(doc) -> ["Check #if, #elif, and #endif. Note these are not implementen and will ~n
- result in an error message from internal_pp"].
-
if_norm(doc) -> ["Check #if, #elif, and #endif. ."];
if_norm(suite) -> [];
if_norm(Config) when is_list(Config) ->
@@ -254,8 +251,6 @@ if_zero(Config) when is_list(Config) ->
%% inc
%%--------------------------------------------------------------------
-inc(suite) -> [inc_norm];
-inc(doc) -> ["Check #include"].
inc_norm(doc) -> ["Check #include."];
inc_norm(suite) -> [];
@@ -273,8 +268,6 @@ inc_norm(Config) when is_list(Config) ->
%% improp_nest_constr
%%--------------------------------------------------------------------
-improp_nest_constr(suite) -> [improp_nest_constr_norm];
-improp_nest_constr(doc) -> ["Check improperly nested constructs"].
improp_nest_constr_norm(doc) -> ["Check improperly nested constructs."];
improp_nest_constr_norm(suite) -> [];
@@ -291,8 +284,6 @@ improp_nest_constr_norm(Config) when is_list(Config) ->
%% misc
%%--------------------------------------------------------------------
-misc(suite) -> [misc_norm];
-misc(doc) -> ["Misceleaneous checks"].
misc_norm(doc) -> ["Misceleaneous checks."];
misc_norm(suite) -> [];
@@ -309,8 +300,6 @@ misc_norm(Config) when is_list(Config) ->
%% line
%%--------------------------------------------------------------------
-line(suite) -> [line_norm];
-line(doc) -> ["Checks #line"].
line_norm(doc) -> ["Checks #line."];
line_norm(suite) -> [];
@@ -327,8 +316,6 @@ line_norm(Config) when is_list(Config) ->
%% nopara
%%--------------------------------------------------------------------
-nopara(suite) -> [nopara_norm];
-nopara(doc) -> ["Checks #define with no parameters"].
nopara_norm(doc) -> ["Checks #define with no parameters."];
nopara_norm(suite) -> [];
@@ -345,8 +332,6 @@ nopara_norm(Config) when is_list(Config) ->
%% predef
%%--------------------------------------------------------------------
-predef(suite) -> [predef_norm];
-predef(doc) -> ["Checks predefined macros. Note: not __TIME__ and __DATE__"].
predef_norm(doc) -> ["Checks predefined macros. Note: not __TIME__ and __DATE__."];
predef_norm(suite) -> [];
@@ -363,8 +348,6 @@ predef_norm(Config) when is_list(Config) ->
%% predef_time
%%--------------------------------------------------------------------
-predef_time(suite) -> [predef_time_norm];
-predef_time(doc) -> ["Checks the predefined macros __TIME__ and __DATE__"].
predef_time_norm(doc) -> ["Checks the predefined macros __TIME__ and __DATE__."];
predef_time_norm(suite) -> [];
@@ -381,8 +364,6 @@ predef_time_norm(Config) when is_list(Config) ->
%% self_ref
%%--------------------------------------------------------------------
-self_ref(suite) -> [self_ref_norm];
-self_ref(doc) -> ["Checks self referring macros"].
self_ref_norm(doc) -> ["Checks self referring macros."];
self_ref_norm(suite) -> [];
@@ -399,8 +380,6 @@ self_ref_norm(Config) when is_list(Config) ->
%% separate
%%--------------------------------------------------------------------
-separate(suite) -> [separate_norm];
-separate(doc) -> ["Checks separete expansion of macro arguments"].
separate_norm(doc) -> ["Checks separete expansion of macro arguments."];
separate_norm(suite) -> [];
@@ -417,8 +396,6 @@ separate_norm(Config) when is_list(Config) ->
%% swallow_sc
%%--------------------------------------------------------------------
-swallow_sc(suite) -> [swallow_sc_norm];
-swallow_sc(doc) -> ["Checks swallowing an undesirable semicolon"].
swallow_sc_norm(doc) -> ["Checks swallowing an undesirable semicolon."];
swallow_sc_norm(suite) -> [];
@@ -435,8 +412,6 @@ swallow_sc_norm(Config) when is_list(Config) ->
%% unintended_grp
%%--------------------------------------------------------------------
-unintended_grp(suite) -> [unintended_grp_norm];
-unintended_grp(doc) -> ["Checks unintended grouping of arithmetic"].
unintended_grp_norm(doc) -> ["Checks unintended grouping of arithmetic."];
unintended_grp_norm(suite) -> [];
diff --git a/lib/ic/test/ic_pragma_SUITE.erl b/lib/ic/test/ic_pragma_SUITE.erl
index 0edb5d4717..65fda2e3b9 100644
--- a/lib/ic/test/ic_pragma_SUITE.erl
+++ b/lib/ic/test/ic_pragma_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -27,12 +27,13 @@
%%-----------------------------------------------------------------
-module(ic_pragma_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, init_all/1, finish_all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1]).
-export([ifr_pragma_reg/1, pragma_error/1, uggly_pragmas/1]).
@@ -53,18 +54,28 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [ifr_pragma_reg,pragma_error,uggly_pragmas].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [ifr_pragma_reg, pragma_error, uggly_pragmas].
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
-init_all(Config) ->
+init_per_suite(Config) ->
io:format("Setting up.....~n"),
mnesia:stop(),
mnesia:delete_schema([node()]),
@@ -79,7 +90,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
io:format("Setting down.....~n"),
orber:stop(),
orber:uninstall(),
diff --git a/lib/ic/test/ic_register_SUITE.erl b/lib/ic/test/ic_register_SUITE.erl
index ae7578199a..6a9dea5a3d 100644
--- a/lib/ic/test/ic_register_SUITE.erl
+++ b/lib/ic/test/ic_register_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,12 +26,13 @@
%%-----------------------------------------------------------------
-module(ic_register_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, init_all/1, finish_all/1, ifr_reg_unreg/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1, ifr_reg_unreg/1]).
-export([ifr_inheritence_reg/1,ifr_reg_unreg_with_inheritence/1]).
-export([ifr_reg_unreg_with_inheritence_bad_order/1]).
@@ -57,20 +58,31 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [ifr_reg_unreg,ifr_reg_unreg_with_inheritence,
- ifr_reg_unreg_with_inheritence_bad_order,ifr_inheritence_reg].
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [ifr_reg_unreg, ifr_reg_unreg_with_inheritence,
+ ifr_reg_unreg_with_inheritence_bad_order,
+ ifr_inheritence_reg].
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
-init_all(Config) ->
+init_per_suite(Config) ->
io:format("Setting up.....~n"),
mnesia:stop(),
mnesia:delete_schema([node()]),
@@ -85,7 +97,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
io:format("Setting down.....~n"),
orber:stop(),
orber:uninstall(),
diff --git a/lib/ic/test/java_client_erl_server_SUITE.erl b/lib/ic/test/java_client_erl_server_SUITE.erl
index ee77ef0c4e..bd87ce24d9 100644
--- a/lib/ic/test/java_client_erl_server_SUITE.erl
+++ b/lib/ic/test/java_client_erl_server_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,10 +22,12 @@
%%%----------------------------------------------------------------------
-module(java_client_erl_server_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,init_all/1,finish_all/1,init_per_testcase/2,fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1,end_per_suite/1,
+ init_per_testcase/2,end_per_testcase/2]).
-export([marshal_ll/1,marshal_ull/1,
marshal_l/1,marshal_ul/1,
marshal_s/1,marshal_us/1,
@@ -36,19 +38,27 @@
%% Top of cases
-all(doc) ->
- "Test of IC with a Java-client and an Erlang generic server. "
- "The communication is via Erlang distribution.";
-all(suite) -> {conf,init_all,cases(),finish_all}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() -> [marshal_ll,marshal_ull,
- marshal_l,marshal_ul,
- marshal_s,marshal_us,
- marshal_c,marshal_wc,
- marshal_str,
- marshal_any_3,marshal_any_2].
+all() ->
+ cases().
-init_all(Config) when is_list(Config) ->
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [marshal_ll, marshal_ull, marshal_l, marshal_ul,
+ marshal_s, marshal_us, marshal_c, marshal_wc,
+ marshal_str, marshal_any_3, marshal_any_2].
+
+init_per_suite(Config) when is_list(Config) ->
case case code:priv_dir(jinterface) of
{error,bad_name} ->
false;
@@ -76,7 +86,7 @@ find_executable([E|T]) ->
Path -> Path
end.
-finish_all(Config) -> Config.
+end_per_suite(Config) -> Config.
@@ -98,7 +108,7 @@ init_per_testcase(_Case, Config) ->
WatchDog = test_server:timetrap(test_server:seconds(20)),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
DataDir = ?config(data_dir, Config),
code:del_path(DataDir),
WatchDog = ?config(watchdog, Config),
diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk
index 074d0b3d39..6d6c7fa625 100644
--- a/lib/ic/vsn.mk
+++ b/lib/ic/vsn.mk
@@ -1 +1 @@
-IC_VSN = 4.2.25
+IC_VSN = 4.2.26
diff --git a/lib/inets/doc/src/ftp.xml b/lib/inets/doc/src/ftp.xml
index 25dfe716fc..ca902d8d9d 100644
--- a/lib/inets/doc/src/ftp.xml
+++ b/lib/inets/doc/src/ftp.xml
@@ -107,7 +107,7 @@
<tag>{mode, Mode}</tag>
<item>
<marker id="mode"></marker>
- <p>Mode = <c>active | passive</c> </p>>
+ <p>Mode = <c>active | passive</c> </p>
<p>Default is <c>passive</c>. </p>
</item>
diff --git a/lib/inets/doc/src/http_client.xml b/lib/inets/doc/src/http_client.xml
index ea8053cafa..4542211d71 100644
--- a/lib/inets/doc/src/http_client.xml
+++ b/lib/inets/doc/src/http_client.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
@@ -42,10 +42,10 @@
dynamically in runtime. Each client profile will spawn a new
process to handle each request unless there is a possibility to use
a persistent connection with or without pipelining.
- The client will add a host header and an empty
- te header if there are no such headers present in the request.</p>
+ The client will add a <c>host</c> header and an empty
+ <c>te</c> header if there are no such headers present in the request.</p>
- <p>The clients supports ipv6 as long as the underlying mechanisms also do
+ <p>The client supports ipv6 as long as the underlying mechanisms also do
so.</p>
</section>
@@ -57,7 +57,7 @@
[{inets, [{services, [{httpc, PropertyList}]}]}]
</pre>
<p>For valid properties see
- <seealso marker="http">httpc(3)</seealso>. </p>
+ <seealso marker="httpc">httpc(3)</seealso>. </p>
</section>
<section>
@@ -87,7 +87,7 @@
httpc:request("http://www.erlang.org").
</code>
<p>An ordinary asynchronous request. The result will be sent
- to the calling process on the form {http, {ReqestId, Result}}</p>
+ to the calling process in the form <c>{http, {ReqestId, Result}}</c></p>
<code type="erl">
5 > {ok, RequestId} =
httpc:request(get, {"http://www.erlang.org", []}, [], [{sync, false}]).
diff --git a/lib/inets/doc/src/http_server.xml b/lib/inets/doc/src/http_server.xml
index 68dfd1add0..47ed9cd229 100644
--- a/lib/inets/doc/src/http_server.xml
+++ b/lib/inets/doc/src/http_server.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
@@ -766,7 +766,7 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
<code>
-module(mnesia_test).
-export([start/0,load_data/0]).
--include("mod_auth.hrl").
+-include_lib("mod_auth.hrl").
first_start() ->
mnesia:create_schema([node()]),
diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml
index 8b04b4c7f3..6dcf2d6d17 100644
--- a/lib/inets/doc/src/httpc.xml
+++ b/lib/inets/doc/src/httpc.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">
<erlref>
@@ -36,7 +36,7 @@
<note>
<p>When starting the Inets application a manager process for the
default profile will be started. The functions in this API
- that does not explicitly use a profile will accesses the
+ that do not explicitly use a profile will access the
default profile. A profile keeps track of proxy options,
cookies and other options that can be applied to more than one
request. </p>
@@ -121,7 +121,7 @@ ssl_options() = {verify, code()} |
application or started dynamically in runtime by calling the
inets application API <c>inets:start(httpc, ServiceConfig)</c>, or
<c>inets:start(httpc, ServiceConfig, How)</c>
- see <seealso marker="inets">inets(3)</seealso> Below follows a
+ see <seealso marker="inets">inets(3)</seealso>. Below follows a
description of the available configuration options.</p>
<taglist>
<tag>{profile, profile()}</tag>
@@ -133,8 +133,8 @@ ssl_options() = {verify, code()} |
as session cookies.</item>
</taglist>
- <p>The client can be stopped using inets:stop(httpc, Pid) or
- inets:stop(httpc, Profile).</p>
+ <p>The client can be stopped using <c>inets:stop(httpc, Pid)</c> or
+ <c>inets:stop(httpc, Profile)</c>.</p>
<marker id="request1"></marker>
</section>
@@ -152,7 +152,7 @@ ssl_options() = {verify, code()} |
<v>Reason = term() </v>
</type>
<desc>
- <p>Equivalent to httpc:request(get, {Url, []}, [], []).</p>
+ <p>Equivalent to <c>httpc:request(get, {Url, []}, [], [])</c>.</p>
<marker id="request2"></marker>
</desc>
@@ -176,7 +176,8 @@ ssl_options() = {verify, code()} |
{autoredirect, boolean()} |
{proxy_auth, {userstring(), passwordstring()}} |
{version, http_version()} |
- {relaxed, boolean()}</v>
+ {relaxed, boolean()} |
+ {url_encode, boolean()}</v>
<v>timeout() = integer() >= 0 | infinity</v>
<v>Options = options()</v>
<v>options() = [option()]</v>
@@ -204,7 +205,7 @@ ssl_options() = {verify, code()} |
<desc>
<p>Sends a HTTP-request. The function can be both synchronous
and asynchronous. In the later case the function will return
- {ok, RequestId} and later on the information will be delivered
+ <c>{ok, RequestId}</c> and later on the information will be delivered
to the <c>receiver</c> depending on that value. </p>
<p>Http option (<c>http_option()</c>) details: </p>
@@ -212,7 +213,7 @@ ssl_options() = {verify, code()} |
<tag><c><![CDATA[timeout]]></c></tag>
<item>
<p>Timeout time for the request. </p>
- <p>The clock start ticking as soon as the request has been
+ <p>The clock starts ticking as soon as the request has been
sent. </p>
<p>Time is in milliseconds. </p>
<p>Defaults to <c>infinity</c>. </p>
@@ -249,11 +250,11 @@ ssl_options() = {verify, code()} |
<tag><c><![CDATA[autoredirect]]></c></tag>
<item>
- <p>Should the client automatically retreive the information
+ <p>Should the client automatically retrieve the information
from the new URI and return that as the result instead
of a 30X-result code. </p>
<p>Note that for some 30X-result codes automatic redirect
- is not allowed in these cases the 30X-result will always
+ is not allowed. In these cases the 30X-result will always
be returned. </p>
<p>Defaults to <c>true</c>. </p>
</item>
@@ -270,16 +271,21 @@ ssl_options() = {verify, code()} |
<c>HTTP/0.9</c> client. By default this is an <c>HTTP/1.1</c>
client. When using <c>HTTP/1.0</c> persistent connections will
not be used. </p>
- <p>Defaults to the trsing <c>"HTTP/1.1"</c>. </p>
+ <p>Defaults to the string <c>"HTTP/1.1"</c>. </p>
</item>
<tag><c><![CDATA[relaxed]]></c></tag>
<item>
- <p>If set to true workarounds for known server deviations from
+ <p>If set to <c>true</c> workarounds for known server deviations from
the HTTP-standard are enabled. </p>
<p>Defaults to <c>false</c>. </p>
</item>
+ <tag><c><![CDATA[url_encode]]></c></tag>
+ <item>
+ <p>Will apply Percent-encoding, also known as URL encoding on the URL.</p>
+ <p>Defaults to <c>false</c>. </p>
+ </item>
</taglist>
<p>Option (<c>option()</c>) details: </p>
@@ -294,21 +300,21 @@ ssl_options() = {verify, code()} |
<item>
<p>Streams the body of a 200 or 206 response to the calling
process or to a file. When streaming to the calling process
- using the option <c>self</c> the the following stream messages
- will be sent to that process: {http, {RequestId,
+ using the option <c>self</c> the following stream messages
+ will be sent to that process: <c>{http, {RequestId,
stream_start, Headers}, {http, {RequestId, stream,
- BinBodyPart}, {http, {RequestId, stream_end, Headers}. When
+ BinBodyPart}, {http, {RequestId, stream_end, Headers}</c>. When
streaming to to the calling processes using the option
<c>{self, once}</c> the first message will have an additional
- element e.i. {http, {RequestId, stream_start, Headers, Pid},
+ element e.i. <c>{http, {RequestId, stream_start, Headers, Pid}</c>,
this is the process id that should be used as an argument to
- http:stream_next/1 to trigger the next message to be sent to
+ <c>http:stream_next/1</c> to trigger the next message to be sent to
the calling process. </p>
<p>Note that it is possible that chunked encoding will add
- headers so that there are more headers in the stream_end
- message than in the stream_start.
+ headers so that there are more headers in the <c>stream_end</c>
+ message than in the <c>stream_start</c>.
When streaming to a file and the request is asynchronous the
- message {http, {RequestId, saved_to_file}} will be sent. </p>
+ message <c>{http, {RequestId, saved_to_file}}</c> will be sent. </p>
<p>Defaults to <c>none</c>. </p>
</item>
@@ -336,7 +342,7 @@ ssl_options() = {verify, code()} |
case insenstive. This feature should only be used if there is
no other way to communicate with the server or for testing
purpose. Also note that when this option is used no headers
- will be automatically added, all necessary headers has to be
+ will be automatically added, all necessary headers have to be
provided by the user. </p>
<p>Defaults to <c>false</c>. </p>
</item>
@@ -346,22 +352,22 @@ ssl_options() = {verify, code()} |
<p>Socket options to be used for this and subsequent
request(s). </p>
<p>Overrides any value set by the
- <seealso marker="set_options">set_options</seealso>
+ <seealso marker="#set_options">set_options</seealso>
function. </p>
<p>Note that the validity of the options are <em>not</em>
checked in any way. </p>
<p>Note that this may change the socket behaviour
(see <seealso marker="kernel:inet#setopts">inet:setopts/2</seealso>)
- for an already existing, and therefor already connected
+ for an already existing one, and therefore an already connected
request handler. </p>
- <p>By defaults the socket options set by the
+ <p>By default the socket options set by the
<seealso marker="#set_options">set_options/1,2</seealso>
- function is used when establishing connection. </p>
+ function are used when establishing a connection. </p>
</item>
<tag><c><![CDATA[receiver]]></c></tag>
<item>
- <p>Defines how the client will deliver the result for a
+ <p>Defines how the client will deliver the result of an
asynchroneous request (<c>sync</c> has the value
<c>false</c>). </p>
@@ -393,7 +399,7 @@ apply(Module, Function, [ReplyInfo | Args])
</item>
</taglist>
- <p>In all cases above, <c>ReplyInfo</c> has the following
+ <p>In all of the above cases, <c>ReplyInfo</c> has the following
structure: </p>
<pre>
@@ -468,46 +474,46 @@ apply(Module, Function, [ReplyInfo | Args])
<v>IpDesc = string()</v>
<d>ex: "134.138" or "[FEDC:BA98" (all IP-addresses starting with 134.138 or FEDC:BA98), "66.35.250.150" or "[2010:836B:4179::836B:4179]" (a complete IP-address).</d>
<v>MaxSessions = integer() </v>
- <d>Default is <em>2</em>.
+ <d>Default is <c>2</c>.
Maximum number of persistent connections to a host.</d>
<v>MaxKeepAlive = integer() </v>
- <d>Default is <em>5</em>.
+ <d>Default is <c>5</c>.
Maximum number of outstanding requests on the same connection to
a host.</d>
<v>KeepAliveTimeout = integer() </v>
- <d>Default is <em>120000</em> (= 2 min).
+ <d>Default is <c>120000</c> (= 2 min).
If a persistent connection is idle longer than the
- keep_alive_timeout the client will close the connection.
- The server may also have a such a time out but you should
+ <c>keep_alive_timeout</c> the client will close the connection.
+ The server may also have such a time out but you should
not count on it!</d>
<v>MaxPipeline = integer() </v>
- <d>Default is <em>2</em>.
+ <d>Default is <c>2</c>.
Maximum number of outstanding requests on a pipelined connection to a host.</d>
<v>PipelineTimeout = integer() </v>
- <d>Default is <em>0</em>,
+ <d>Default is <c>0</c>,
which will result in pipelining not being used.
If a persistent connection is idle longer than the
- pipeline_timeout the client will close the connection. </d>
+ <c>pipeline_timeout</c> the client will close the connection. </d>
<v>CookieMode = enabled | disabled | verify </v>
- <d>Default is <em>disabled</em>.
+ <d>Default is <c>disabled</c>.
If Cookies are enabled all valid cookies will automatically be
saved in the client manager's cookie database.
- If the option verify is used the function http:verify_cookie/2
- has to be called for the cookie to be saved.</d>
+ If the option <c>verify</c> is used the function <c>store_cookies/2</c>
+ has to be called for the cookies to be saved.</d>
<v>IpFamily = inet | inet6 | inet6fb4 </v>
- <d>By default <em>inet</em>.
+ <d>By default <c>inet</c>.
When it is set to <c>inet6fb4</c> you can use both ipv4 and ipv6.
It first tries <c>inet6</c> and if that does not works falls back to <c>inet</c>.
The option is here to provide a workaround for buggy ipv6 stacks to ensure that
ipv4 will always work.</d>
<v>IpAddress = ip_address() </v>
<d>If the host has several network interfaces, this option specifies which one to use.
- See gen_tcp:connect/3,4 for more info. </d>
+ See <seealso marker="kernel:gen_tcp#connect">gen_tcp:connect/3,4</seealso> for more info. </d>
<v>Port = integer() </v>
<d>Specify which local port number to use.
- See gen_tcp:connect/3,4 for more info. </d>
+ See <seealso marker="kernel:gen_tcp#connect">gen_tcp:connect/3,4</seealso> for more info. </d>
<v>VerboseMode = false | verbose | debug | trace </v>
- <d>Default is <em>false</em>.
+ <d>Default is <c>false</c>.
This option is used to switch on (or off)
different levels of erlang trace on the client.
It is a debug feature.</d>
@@ -521,14 +527,14 @@ apply(Module, Function, [ReplyInfo | Args])
alive and use persistent connections
with or without pipeline depending on configuration
and current circumstances. The HTTP/1.1 specification does not
- provide a guideline for how many requests that would be
+ provide a guideline for how many requests would be
ideal to be sent on a persistent connection,
this very much depends on the
application. Note that a very long queue of requests may cause a
- user perceived delays as earlier request may take a long time
+ user perceived delay as earlier requests may take a long time
to complete. The HTTP/1.1 specification does suggest a
limit of 2 persistent connections per server, which is the
- default value of the max_sessions option. </p>
+ default value of the <c>max_sessions</c> option. </p>
</note>
<marker id="stream_next"></marker>
@@ -547,14 +553,14 @@ apply(Module, Function, [ReplyInfo | Args])
<p>Triggers the next message to be streamed, e.i.
same behavior as active once for sockets.</p>
- <marker id="verify_cookie"></marker>
- <marker id="store_cookie"></marker>
+ <marker id="verify_cookies"></marker>
+ <marker id="store_cookies"></marker>
</desc>
</func>
<func>
- <name>store_cookie(SetCookieHeaders, Url) -> </name>
- <name>store_cookie(SetCookieHeaders, Url, Profile) -> ok | {error, Reason}</name>
+ <name>store_cookies(SetCookieHeaders, Url) -> </name>
+ <name>store_cookies(SetCookieHeaders, Url, Profile) -> ok | {error, Reason}</name>
<fsummary>Saves the cookies defined in SetCookieHeaders in the client profile's cookie database.</fsummary>
<type>
<v>SetCookieHeaders = headers() - where field = "set-cookie"</v>
@@ -564,7 +570,7 @@ apply(Module, Function, [ReplyInfo | Args])
<desc>
<p>Saves the cookies defined in SetCookieHeaders
in the client profile's cookie database. You need to
- call this function if you set the option cookies to <c>verify</c>.
+ call this function if you have set the option <c>cookies</c> to <c>verify</c>.
If no profile is specified the default profile will be used.
</p>
@@ -574,16 +580,16 @@ apply(Module, Function, [ReplyInfo | Args])
<func>
<name>cookie_header(Url) -> </name>
- <name>cookie_header(Url, Profile) -> header() | {error, Rason}</name>
+ <name>cookie_header(Url, Profile) -> header() | {error, Reason}</name>
<fsummary>Returns the cookie header that would be sent when
- making a request to Url using the profile Profile.</fsummary>
+ making a request to Url using the profile <c>Profile</c>.</fsummary>
<type>
<v>Url = url()</v>
<v>Profile = profile()</v>
</type>
<desc>
<p>Returns the cookie header that would be sent
- when making a request to Url using the profile Profile.
+ when making a request to <c>Url</c> using the profile <c>Profile</c>.
If no profile is specified the default profile will be used.
</p>
@@ -600,7 +606,7 @@ apply(Module, Function, [ReplyInfo | Args])
<v>Profile = profile()</v>
</type>
<desc>
- <p>Resets (clears) the cookie database for the specified Profile.
+ <p>Resets (clears) the cookie database for the specified <c>Profile</c>.
If no profile is specified the default profile will be used.
</p>
</desc>
@@ -636,4 +642,3 @@ apply(Module, Function, [ReplyInfo | Args])
</section>
</erlref>
-
diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml
index 847605fe93..62f4e18f82 100644
--- a/lib/inets/doc/src/httpd.xml
+++ b/lib/inets/doc/src/httpd.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">
<erlref>
@@ -421,7 +421,7 @@ bytes
Beware of trailing space in Replacement that will be used.
If you must have a space in Re use e.g the character encoding
- <code>\040</code> see <seealso marker="re">re(3)</seealso>.
+ <code>\040</code> see <seealso marker="stdlib:re">re(3)</seealso>.
</item>
<tag>{directory_index, [string()]}</tag>
@@ -931,6 +931,10 @@ bytes
connection
}).
</code>
+
+ <p>To acess the record in your callback-module use </p>
+ <code> -include_lib("inets/include/httpd.hrl"). </code>
+
<p>The fields of the <c>mod</c> record has the following meaning:
</p>
<taglist>
@@ -978,10 +982,10 @@ bytes
<c>parsed_header</c> contains all HTTP header fields from the
HTTP-request stored in a list as key-value tuples. See RFC 2616
for a listing of all header fields. For example the date field
- would be stored as: <c>{"date","Wed, 15 Oct 1997 14:35:17 GMT"}.
+ would be stored as: <c>{"date","Wed, 15 Oct 1997 14:35:17 GMT"} </c>.
RFC 2616 defines that HTTP is a case insensitive protocol and
the header fields may be in lower case or upper case. Httpd will
- ensure that all header field names are in lower case. </c>.
+ ensure that all header field names are in lower case.
</item>
<tag><c>entity_body</c></tag>
<item>The <c>Entity-Body</c> as defined
diff --git a/lib/inets/doc/src/mod_auth.xml b/lib/inets/doc/src/mod_auth.xml
index f3628c8297..9503add2e0 100644
--- a/lib/inets/doc/src/mod_auth.xml
+++ b/lib/inets/doc/src/mod_auth.xml
@@ -111,7 +111,8 @@
</desc>
</func>
<func>
- <name>list_users(Options) -> {ok, Users} | {error, Reason} &lt;name>list_users(Port, Dir) -> {ok, Users} | {error, Reason}</name>
+ <name>list_users(Options) -> {ok, Users} | {error, Reason}</name>
+ <name>list_users(Port, Dir) -> {ok, Users} | {error, Reason}</name>
<name>list_users(Address, Port, Dir) -> {ok, Users} | {error, Reason}</name>
<fsummary>List users in the user database.</fsummary>
<type>
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 7b16189860..11b0af4310 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -32,7 +32,50 @@
<file>notes.xml</file>
</header>
- <section><title>Inets 5.5</title>
+ <section><title>Inets 5.5.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fix format_man_pages so it handles all man sections
+ and remove warnings/errors in various man pages. </p>
+ <p>
+ Own Id: OTP-8600</p>
+ </item>
+ <item>
+ <p>
+ [httpc] Pipelined and queued requests not processed when
+ connection closed remotelly.</p>
+ <p>
+ Own Id: OTP-8906</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Miscellaneous inet6 related problems.</p>
+ <p>
+ Own Id: OTP-8927</p>
+ </item>
+ <item>
+ <p>
+ Updated http-server to make sure URLs in error-messages
+ are URL-encoded. Added support in http-client to use
+ URL-encoding. Also added the missing include directory
+ for the inets application.</p>
+ <p>
+ Own Id: OTP-8940 Aux Id: seq11735 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Inets 5.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/inets/include/httpd.hrl b/lib/inets/include/httpd.hrl
new file mode 100644
index 0000000000..a7e63ca670
--- /dev/null
+++ b/lib/inets/include/httpd.hrl
@@ -0,0 +1,41 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-ifndef(httpd_hrl).
+-define(httpd_hrl, true).
+
+-include_lib("kernel/include/file.hrl").
+
+-record(init_data,{peername,resolve}).
+
+-record(mod,{init_data,
+ data=[],
+ socket_type=ip_comm,
+ socket,
+ config_db,
+ method,
+ absolute_uri=[],
+ request_uri,
+ http_version,
+ request_line,
+ parsed_header=[],
+ entity_body,
+ connection}).
+-endif. % -ifdef(httpd_hrl).
diff --git a/lib/inets/include/mod_auth.hrl b/lib/inets/include/mod_auth.hrl
new file mode 100644
index 0000000000..cf931e681a
--- /dev/null
+++ b/lib/inets/include/mod_auth.hrl
@@ -0,0 +1,33 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-ifndef(mod_auth_hrl).
+-define(mod_auth_hrl, true).
+
+-record(httpd_user,
+ {username,
+ password,
+ user_data}).
+
+-record(httpd_group,
+ {name,
+ userlist}).
+
+-endif. % -ifdef(mod_auth_hrl).
diff --git a/lib/inets/src/http_client/Makefile b/lib/inets/src/http_client/Makefile
index 575c6efaec..0397b48ab2 100644
--- a/lib/inets/src/http_client/Makefile
+++ b/lib/inets/src/http_client/Makefile
@@ -51,7 +51,6 @@ MODULES = \
httpc_profile_sup \
httpc_response \
httpc_request \
- http_uri \
HRL_FILES = httpc_internal.hrl
diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl
index 8cf82df809..7490bb0e46 100644
--- a/lib/inets/src/http_client/httpc.erl
+++ b/lib/inets/src/http_client/httpc.erl
@@ -255,7 +255,7 @@ set_option(Key, Value, Profile) ->
%% Description: Store the cookies from <SetCookieHeaders>
%% in the cookie database
%% for the profile <Profile>. This function shall be used when the option
-%% cookie is set to verify.
+%% cookies is set to verify.
%%-------------------------------------------------------------------------
store_cookies(SetCookieHeaders, Url) ->
store_cookies(SetCookieHeaders, Url, default_profile()).
@@ -454,16 +454,21 @@ handle_request(Method, Url,
HeadersRecord = header_record(NewHeaders, Host2, HTTPOptions),
Receiver = proplists:get_value(receiver, Options),
SocketOpts = proplists:get_value(socket_opts, Options),
+ UrlEncodeBool = HTTPOptions#http_options.url_encode,
+ MaybeEscPath = url_encode(Path, UrlEncodeBool),
+ MaybeEscQuery = url_encode(Query, UrlEncodeBool),
+ AbsUri = url_encode(Url, UrlEncodeBool),
+
Request = #request{from = Receiver,
scheme = Scheme,
address = {Host, Port},
- path = Path,
- pquery = Query,
+ path = MaybeEscPath,
+ pquery = MaybeEscQuery,
method = Method,
headers = HeadersRecord,
content = {ContentType, Body},
settings = HTTPOptions,
- abs_uri = Url,
+ abs_uri = AbsUri,
userinfo = UserInfo,
stream = Stream,
headers_as_is = headers_as_is(Headers0, Options),
@@ -483,6 +488,11 @@ handle_request(Method, Url,
Error
end.
+url_encode(URI, true) ->
+ http_uri:encode(URI);
+url_encode(URI, false) ->
+ URI.
+
chunkify_fun(BodyFun) ->
fun(eof_body_fun) ->
eof;
@@ -606,12 +616,8 @@ http_options_default() ->
(_) ->
error
end,
- AutoRedirectPost = fun(Value) when (Value =:= true) orelse
- (Value =:= false) ->
- {ok, Value};
- (_) ->
- error
- end,
+ AutoRedirectPost = boolfun(),
+
SslPost = fun(Value) when is_list(Value) ->
{ok, {?HTTP_DEFAULT_SSL_KIND, Value}};
({ssl, SslOptions}) when is_list(SslOptions) ->
@@ -629,12 +635,8 @@ http_options_default() ->
(_) ->
error
end,
- RelaxedPost = fun(Value) when (Value =:= true) orelse
- (Value =:= false) ->
- {ok, Value};
- (_) ->
- error
- end,
+ RelaxedPost = boolfun(),
+
ConnTimeoutPost =
fun(Value) when is_integer(Value) andalso (Value >= 0) ->
{ok, Value};
@@ -643,6 +645,8 @@ http_options_default() ->
(_) ->
error
end,
+
+ UrlDecodePost = boolfun(),
[
{version, {value, "HTTP/1.1"}, #http_options.version, VersionPost},
{timeout, {value, ?HTTP_REQUEST_TIMEOUT}, #http_options.timeout, TimeoutPost},
@@ -650,18 +654,21 @@ http_options_default() ->
{ssl, {value, {?HTTP_DEFAULT_SSL_KIND, []}}, #http_options.ssl, SslPost},
{proxy_auth, {value, undefined}, #http_options.proxy_auth, ProxyAuthPost},
{relaxed, {value, false}, #http_options.relaxed, RelaxedPost},
+ {url_encode, {value, false}, #http_options.url_encode, UrlDecodePost},
%% this field has to be *after* the timeout option (as that field is used for the default value)
{connect_timeout, {field, #http_options.timeout}, #http_options.connect_timeout, ConnTimeoutPost}
].
+boolfun() ->
+ fun(Value) when (Value =:= true) orelse
+ (Value =:= false) ->
+ {ok, Value};
+ (_) ->
+ error
+ end.
request_options_defaults() ->
- VerifyBoolean =
- fun(Value) when ((Value =:= true) orelse (Value =:= false)) ->
- ok;
- (_) ->
- error
- end,
+ VerifyBoolean = boolfun(),
VerifySync = VerifyBoolean,
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 8af6613fa2..cb6f3e2841 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -713,33 +713,38 @@ terminate(normal,
profile_name = ProfileName,
request = Request,
timers = Timers,
- pipeline = Pipeline}) ->
+ pipeline = Pipeline,
+ keep_alive = KeepAlive} = State) ->
?hcrt("terminate(normal) - remote close",
[{id, Id}, {profile, ProfileName}]),
%% Clobber session
(catch httpc_manager:delete_session(Id, ProfileName)),
+ maybe_retry_queue(Pipeline, State),
+ maybe_retry_queue(KeepAlive, State),
+
%% Cancel timers
- #timers{request_timers = ReqTmrs, queue_timer = QTmr} = Timers,
- cancel_timer(QTmr, timeout_queue),
- lists:foreach(fun({_, Timer}) -> cancel_timer(Timer, timeout) end,
- ReqTmrs),
+ cancel_timers(Timers),
%% Maybe deliver answers to requests
- deliver_answers([Request | queue:to_list(Pipeline)]),
+ deliver_answer(Request),
%% And, just in case, close our side (**really** overkill)
http_transport:close(SocketType, Socket);
-terminate(_, #state{session = #session{id = Id,
- socket = Socket,
- socket_type = SocketType},
+terminate(Reason, #state{session = #session{id = Id,
+ socket = Socket,
+ socket_type = SocketType},
request = undefined,
profile_name = ProfileName,
timers = Timers,
pipeline = Pipeline,
keep_alive = KeepAlive} = State) ->
+ ?hcrt("terminate",
+ [{id, Id}, {profile, ProfileName}, {reason, Reason}]),
+
+ %% Clobber session
(catch httpc_manager:delete_session(Id, ProfileName)),
maybe_retry_queue(Pipeline, State),
@@ -772,59 +777,55 @@ maybe_send_answer(#request{from = answer_sent}, _Reason, State) ->
maybe_send_answer(Request, Answer, State) ->
answer_request(Request, Answer, State).
-deliver_answers([]) ->
- ?hcrd("deliver answer done", []),
- ok;
-deliver_answers([#request{id = Id, from = From} = Request | Requests])
+deliver_answer(#request{id = Id, from = From} = Request)
when is_pid(From) ->
Response = httpc_response:error(Request, socket_closed_remotely),
?hcrd("deliver answer", [{id, Id}, {from, From}, {response, Response}]),
- httpc_response:send(From, Response),
- deliver_answers(Requests);
-deliver_answers([Request|Requests]) ->
+ httpc_response:send(From, Response);
+deliver_answer(Request) ->
?hcrd("skip deliver answer", [{request, Request}]),
- deliver_answers(Requests).
+ ok.
%%--------------------------------------------------------------------
%% Func: code_change(_OldVsn, State, Extra) -> {ok, NewState}
%% Purpose: Convert process state when code is changed
%%--------------------------------------------------------------------
-code_change(_, #state{request = Request, pipeline = Queue} = State,
- [{from, '5.0.1'}, {to, '5.0.2'}]) ->
- Settings = new_http_options(Request#request.settings),
- NewRequest = Request#request{settings = Settings},
- NewQueue = new_queue(Queue, fun new_http_options/1),
- {ok, State#state{request = NewRequest, pipeline = NewQueue}};
-
-code_change(_, #state{request = Request, pipeline = Queue} = State,
- [{from, '5.0.2'}, {to, '5.0.1'}]) ->
- Settings = old_http_options(Request#request.settings),
- NewRequest = Request#request{settings = Settings},
- NewQueue = new_queue(Queue, fun old_http_options/1),
- {ok, State#state{request = NewRequest, pipeline = NewQueue}};
+%% code_change(_, #state{request = Request, pipeline = Queue} = State,
+%% [{from, '5.0.1'}, {to, '5.0.2'}]) ->
+%% Settings = new_http_options(Request#request.settings),
+%% NewRequest = Request#request{settings = Settings},
+%% NewQueue = new_queue(Queue, fun new_http_options/1),
+%% {ok, State#state{request = NewRequest, pipeline = NewQueue}};
+
+%% code_change(_, #state{request = Request, pipeline = Queue} = State,
+%% [{from, '5.0.2'}, {to, '5.0.1'}]) ->
+%% Settings = old_http_options(Request#request.settings),
+%% NewRequest = Request#request{settings = Settings},
+%% NewQueue = new_queue(Queue, fun old_http_options/1),
+%% {ok, State#state{request = NewRequest, pipeline = NewQueue}};
code_change(_, State, _) ->
{ok, State}.
-new_http_options({http_options, TimeOut, AutoRedirect, SslOpts,
- Auth, Relaxed}) ->
- {http_options, "HTTP/1.1", TimeOut, AutoRedirect, SslOpts,
- Auth, Relaxed}.
-
-old_http_options({http_options, _, TimeOut, AutoRedirect,
- SslOpts, Auth, Relaxed}) ->
- {http_options, TimeOut, AutoRedirect, SslOpts, Auth, Relaxed}.
-
-new_queue(Queue, Fun) ->
- List = queue:to_list(Queue),
- NewList =
- lists:map(fun(Request) ->
- Settings =
- Fun(Request#request.settings),
- Request#request{settings = Settings}
- end, List),
- queue:from_list(NewList).
+%% new_http_options({http_options, TimeOut, AutoRedirect, SslOpts,
+%% Auth, Relaxed}) ->
+%% {http_options, "HTTP/1.1", TimeOut, AutoRedirect, SslOpts,
+%% Auth, Relaxed}.
+
+%% old_http_options({http_options, _, TimeOut, AutoRedirect,
+%% SslOpts, Auth, Relaxed}) ->
+%% {http_options, TimeOut, AutoRedirect, SslOpts, Auth, Relaxed}.
+
+%% new_queue(Queue, Fun) ->
+%% List = queue:to_list(Queue),
+%% NewList =
+%% lists:map(fun(Request) ->
+%% Settings =
+%% Fun(Request#request.settings),
+%% Request#request{settings = Settings}
+%% end, List),
+%% queue:from_list(NewList).
%%%--------------------------------------------------------------------
@@ -854,12 +855,18 @@ connect(SocketType, ToAddress,
inet6fb4 ->
Opts3 = [inet6 | Opts2],
case http_transport:connect(SocketType, ToAddress, Opts3, Timeout) of
- {error, Reason} when ((Reason =:= nxdomain) orelse
- (Reason =:= eafnosupport)) ->
+ {error, _Reason} = Error ->
Opts4 = [inet | Opts2],
- http_transport:connect(SocketType, ToAddress, Opts4, Timeout);
- Other ->
- Other
+ case http_transport:connect(SocketType,
+ ToAddress, Opts4, Timeout) of
+ {error, _} ->
+ %% Reply with the "original" error
+ Error;
+ OK ->
+ OK
+ end;
+ OK ->
+ OK
end;
_ ->
Opts3 = [IpFamily | Opts2],
@@ -1440,6 +1447,12 @@ answer_request(#request{id = RequestId, from = From} = Request, Msg,
timers =
Timers#timers{request_timers =
lists:delete(Timer, RequestTimers)}}.
+
+cancel_timers(#timers{request_timers = ReqTmrs, queue_timer = QTmr}) ->
+ cancel_timer(QTmr, timeout_queue),
+ CancelTimer = fun({_, Timer}) -> cancel_timer(Timer, timeout) end,
+ lists:foreach(CancelTimer, ReqTmrs).
+
cancel_timer(undefined, _) ->
ok;
cancel_timer(Timer, TimeoutMsg) ->
diff --git a/lib/inets/src/http_client/httpc_internal.hrl b/lib/inets/src/http_client/httpc_internal.hrl
index 3cdd95a02b..1d8a5b6a92 100644
--- a/lib/inets/src/http_client/httpc_internal.hrl
+++ b/lib/inets/src/http_client/httpc_internal.hrl
@@ -60,7 +60,11 @@
relaxed = false,
%% integer() - ms before a connect times out
- connect_timeout = ?HTTP_REQUEST_CTIMEOUT
+ connect_timeout = ?HTTP_REQUEST_CTIMEOUT,
+
+ %% bool() - Use %-encoding rfc 2396
+ url_encode
+
}
).
diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl
index 1e1bde220b..591cb78c29 100644
--- a/lib/inets/src/http_client/httpc_manager.erl
+++ b/lib/inets/src/http_client/httpc_manager.erl
@@ -734,10 +734,11 @@ handle_connect_and_send(_StarterPid, ReqId, HandlerPid, Result,
ok;
[] ->
- error_report(Profile,
- "handler (~p) successfully started "
- "for unknown request ~p => canceling",
- [HandlerPid, ReqId]),
+ ?hcri("handler successfully started "
+ "for unknown request => canceling",
+ [{profile, Profile},
+ {handler, HandlerPid},
+ {request, ReqId}]),
httpc_handler:cancel(ReqId, HandlerPid)
end.
diff --git a/lib/inets/src/http_lib/Makefile b/lib/inets/src/http_lib/Makefile
index 5dac3b0c00..aaf3cfb995 100644
--- a/lib/inets/src/http_lib/Makefile
+++ b/lib/inets/src/http_lib/Makefile
@@ -45,7 +45,8 @@ MODULES = \
http_transport\
http_util \
http_request \
- http_response
+ http_response \
+ http_uri
HRL_FILES = http_internal.hrl
diff --git a/lib/inets/src/http_lib/http_transport.erl b/lib/inets/src/http_lib/http_transport.erl
index b8121852b8..0024d19fc1 100644
--- a/lib/inets/src/http_lib/http_transport.erl
+++ b/lib/inets/src/http_lib/http_transport.erl
@@ -192,24 +192,31 @@ listen_ip_comm(Addr, Port) ->
case IpFamily of
inet6fb4 ->
Opts2 = [inet6 | Opts],
+ ?hlrt("try ipv6 listen", [{port, NewPort}, {opts, Opts2}]),
case (catch gen_tcp:listen(NewPort, Opts2)) of
{error, Reason} when ((Reason =:= nxdomain) orelse
(Reason =:= eafnosupport)) ->
Opts3 = [inet | Opts],
+ ?hlrt("ipv6 listen failed - try ipv4 instead",
+ [{reason, Reason}, {port, NewPort}, {opts, Opts3}]),
gen_tcp:listen(NewPort, Opts3);
%% This is when a given hostname has resolved to a
%% IPv4-address. The inet6-option together with a
%% {ip, IPv4} option results in badarg
- {'EXIT', _} ->
+ {'EXIT', Reason} ->
Opts3 = [inet | Opts],
+ ?hlrt("ipv6 listen exit - try ipv4 instead",
+ [{reason, Reason}, {port, NewPort}, {opts, Opts3}]),
gen_tcp:listen(NewPort, Opts3);
Other ->
+ ?hlrt("ipv6 listen done", [{other, Other}]),
Other
end;
_ ->
Opts2 = [IpFamily | Opts],
+ ?hlrt("listen", [{port, NewPort}, {opts, Opts2}]),
gen_tcp:listen(NewPort, Opts2)
end.
diff --git a/lib/inets/src/http_client/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl
index 615a0d8ec4..44b9face0b 100644
--- a/lib/inets/src/http_client/http_uri.erl
+++ b/lib/inets/src/http_lib/http_uri.erl
@@ -1,26 +1,26 @@
%%
%% %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(http_uri).
--export([parse/1]).
+-export([parse/1, encode/1, decode/1]).
%%%=========================================================================
%%% API
@@ -34,10 +34,25 @@ parse(AbsURI) ->
{UserInfo, Host, Port, Path, Query} ->
{Scheme, UserInfo, Host, Port, Path, Query};
_ ->
- {error, {malformed_url, AbsURI}}
+ {error, {malformed_url, AbsURI}}
end
end.
+encode(URI) ->
+ Reserved = sets:from_list([$;, $:, $@, $&, $=, $+, $,, $/, $?,
+ $#, $[, $], $<, $>, $\", ${, $}, $|,
+ $\\, $', $^, $%, $ ]),
+ lists:append(lists:map(fun(Char) ->
+ uri_encode(Char, Reserved)
+ end, URI)).
+
+decode([$%,Hex1,Hex2|Rest]) ->
+ [hex2dec(Hex1)*16+hex2dec(Hex2)|decode(Rest)];
+decode([First|Rest]) ->
+ [First|decode(Rest)];
+decode([]) ->
+ [].
+
%%%========================================================================
%%% Internal functions
%%%========================================================================
@@ -56,7 +71,7 @@ parse_scheme(AbsURI) ->
parse_uri_rest(Scheme, "//" ++ URIPart) ->
- {Authority, PathQuery} =
+ {Authority, PathQuery} =
case split_uri(URIPart, "/", URIPart, 1, 0) of
Split = {_, _} ->
Split;
@@ -68,7 +83,7 @@ parse_uri_rest(Scheme, "//" ++ URIPart) ->
{URIPart,""}
end
end,
-
+
{UserInfo, HostPort} = split_uri(Authority, "@", {"", Authority}, 1, 1),
{Host, Port} = parse_host_port(Scheme, HostPort),
{Path, Query} = parse_path_query(PathQuery),
@@ -78,7 +93,6 @@ parse_uri_rest(Scheme, "//" ++ URIPart) ->
parse_path_query(PathQuery) ->
{Path, Query} = split_uri(PathQuery, "\\?", {PathQuery, ""}, 1, 0),
{path(Path), Query}.
-
parse_host_port(Scheme,"[" ++ HostPort) -> %ipv6
DefaultPort = default_port(Scheme),
@@ -90,12 +104,12 @@ parse_host_port(Scheme, HostPort) ->
DefaultPort = default_port(Scheme),
{Host, Port} = split_uri(HostPort, ":", {HostPort, DefaultPort}, 1, 1),
{Host, int_port(Port)}.
-
+
split_uri(UriPart, SplitChar, NoMatchResult, SkipLeft, SkipRight) ->
case inets_regexp:first_match(UriPart, SplitChar) of
{match, Match, _} ->
{string:substr(UriPart, 1, Match - SkipLeft),
- string:substr(UriPart, Match + SkipRight, length(UriPart))};
+ string:substr(UriPart, Match + SkipRight, length(UriPart))};
nomatch ->
NoMatchResult
end.
@@ -114,3 +128,15 @@ path("") ->
"/";
path(Path) ->
Path.
+
+uri_encode(Char, Reserved) ->
+ case sets:is_element(Char, Reserved) of
+ true ->
+ [ $% | http_util:integer_to_hexlist(Char)];
+ false ->
+ [Char]
+ end.
+
+hex2dec(X) when (X>=$0) andalso (X=<$9) -> X-$0;
+hex2dec(X) when (X>=$A) andalso (X=<$F) -> X-$A+10;
+hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10.
diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile
index 879e605217..55cc68dede 100644
--- a/lib/inets/src/http_server/Makefile
+++ b/lib/inets/src/http_server/Makefile
@@ -82,7 +82,7 @@ MODULES = \
mod_security \
mod_security_server
-HRL_FILES = httpd.hrl httpd_internal.hrl mod_auth.hrl
+HRL_FILES = httpd.hrl httpd_internal.hrl mod_auth.hrl
ERL_FILES = $(MODULES:%=%.erl)
@@ -98,9 +98,8 @@ include ../inets_app/inets.mk
ERL_COMPILE_FLAGS += \
$(INETS_FLAGS) \
$(INETS_ERL_COMPILE_FLAGS) \
- -I../../include \
-I../inets_app \
- -I../http_lib
+ -I../http_lib \
# ----------------------------------------------------
diff --git a/lib/inets/src/http_server/httpd.erl b/lib/inets/src/http_server/httpd.erl
index fb5fa1c758..93608dbf96 100644
--- a/lib/inets/src/http_server/httpd.erl
+++ b/lib/inets/src/http_server/httpd.erl
@@ -24,7 +24,6 @@
-include("httpd.hrl").
-
%% Behavior callbacks
-export([
start_standalone/1,
@@ -271,8 +270,8 @@ foreach([KeyValue|Rest]) ->
{ok, Plus2Space, _} = inets_regexp:gsub(KeyValue,"[\+]"," "),
case inets_regexp:split(Plus2Space,"=") of
{ok,[Key|Value]} ->
- [{httpd_util:decode_hex(Key),
- httpd_util:decode_hex(lists:flatten(Value))}|foreach(Rest)];
+ [{http_uri:decode(Key),
+ http_uri:decode(lists:flatten(Value))}|foreach(Rest)];
{ok,_} ->
foreach(Rest)
end.
diff --git a/lib/inets/src/http_server/httpd.hrl b/lib/inets/src/http_server/httpd.hrl
index 0db8a029bb..4eba833e2c 100644
--- a/lib/inets/src/http_server/httpd.hrl
+++ b/lib/inets/src/http_server/httpd.hrl
@@ -1,82 +1,27 @@
%%
%% %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%
%%
+%% %CopyrightEnd%
%%
+%% This is a simple wrapper for code that has not been updated to
+%% handle the move of this file to the include dir.
--include_lib("kernel/include/file.hrl").
-
--ifndef(SERVER_SOFTWARE).
--define(SERVER_SOFTWARE,"inets/develop"). % Define in Makefile!
--endif.
--define(SERVER_PROTOCOL,"HTTP/1.1").
--define(DEFAULT_MODS, [mod_alias, mod_auth, mod_esi, mod_actions, mod_cgi,
- mod_dir, mod_get, mod_head, mod_log, mod_disk_log]).
--define(SOCKET_CHUNK_SIZE,8192).
--define(SOCKET_MAX_POLL,25).
--define(FILE_CHUNK_SIZE,64*1024).
--define(GATEWAY_INTERFACE,"CGI/1.1").
--define(NICE(Reason),lists:flatten(atom_to_list(?MODULE)++": "++Reason)).
--define(DEFAULT_CONTEXT,
- [{errmsg,"[an error occurred while processing this directive]"},
- {timefmt,"%A, %d-%b-%y %T %Z"},
- {sizefmt,"abbrev"}]).
-
-
--ifdef(inets_error).
--define(ERROR(Format, Args), io:format("E(~p:~p:~p) : "++Format++"~n",
- [self(),?MODULE,?LINE]++Args)).
--else.
--define(ERROR(F,A),[]).
--endif.
-
--ifdef(inets_log).
--define(LOG(Format, Args), io:format("L(~p:~p:~p) : "++Format++"~n",
- [self(),?MODULE,?LINE]++Args)).
--else.
--define(LOG(F,A),[]).
--endif.
-
--ifdef(inets_debug).
--define(DEBUG(Format, Args), io:format("D(~p:~p:~p) : "++Format++"~n",
- [self(),?MODULE,?LINE]++Args)).
--else.
--define(DEBUG(F,A),[]).
--endif.
-
--ifdef(inets_cdebug).
--define(CDEBUG(Format, Args), io:format("C(~p:~p:~p) : "++Format++"~n",
- [self(),?MODULE,?LINE]++Args)).
--else.
--define(CDEBUG(F,A),[]).
--endif.
+-ifndef(src_httpd_hrl).
+-define(src_httpd_hrl, true).
+-include_lib("inets/include/httpd.hrl").
--record(init_data,{peername,resolve}).
--record(mod,{init_data,
- data=[],
- socket_type=ip_comm,
- socket,
- config_db,
- method,
- absolute_uri=[],
- request_uri,
- http_version,
- request_line,
- parsed_header=[],
- entity_body,
- connection}).
+-endif. % -ifdef(src_httpd_hrl).
diff --git a/lib/inets/src/http_server/httpd_acceptor.erl b/lib/inets/src/http_server/httpd_acceptor.erl
index c261eff6b2..bcebb6a9e3 100644
--- a/lib/inets/src/http_server/httpd_acceptor.erl
+++ b/lib/inets/src/http_server/httpd_acceptor.erl
@@ -21,6 +21,7 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
%% Internal application API
-export([start_link/5, start_link/6]).
diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl
index 8438c4037e..f4d8a6c09f 100644
--- a/lib/inets/src/http_server/httpd_conf.erl
+++ b/lib/inets/src/http_server/httpd_conf.erl
@@ -31,8 +31,8 @@
validate_properties/1]).
-define(VMODULE,"CONF").
--include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("httpd.hrl").
-include_lib("inets/src/http_lib/http_internal.hrl").
diff --git a/lib/inets/src/http_server/httpd_file.erl b/lib/inets/src/http_server/httpd_file.erl
index 5fd529100e..7e21d9e158 100644
--- a/lib/inets/src/http_server/httpd_file.erl
+++ b/lib/inets/src/http_server/httpd_file.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,11 +22,13 @@
-export([handle_error/4]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
+
handle_error(eacces, Op, ModData, Path) ->
- handle_error(403, Op, ModData, Path,"");
+ handle_error(403, Op, ModData, Path,"Forbidden");
handle_error(enoent, Op, ModData, Path) ->
- handle_error(404, Op, ModData, Path,"");
+ handle_error(404, Op, ModData, Path,"File not found");
handle_error(enotdir, Op, ModData, Path) ->
handle_error(404, Op, ModData, Path,
": A component of the file name is not a directory");
@@ -34,8 +36,8 @@ handle_error(emfile, Op, _ModData, Path) ->
handle_error(500, Op, none, Path, ": To many open files");
handle_error({enfile,_}, Op, _ModData, Path) ->
handle_error(500, Op, none, Path, ": File table overflow");
-handle_error(_Reason, Op, _ModData, Path) ->
- handle_error(500, Op, none, Path, "").
+handle_error(_Reason, Op, ModData, Path) ->
+ handle_error(404, Op, ModData, Path, "File not found").
handle_error(StatusCode, Op, none, Path, Reason) ->
{StatusCode, none, ?NICE("Can't " ++ Op ++ Path ++ Reason)};
diff --git a/lib/inets/src/http_server/httpd_internal.hrl b/lib/inets/src/http_server/httpd_internal.hrl
index 38b0ddefd3..108469ea0a 100644
--- a/lib/inets/src/http_server/httpd_internal.hrl
+++ b/lib/inets/src/http_server/httpd_internal.hrl
@@ -21,7 +21,50 @@
-ifndef(httpd_internal_hrl).
-define(httpd_internal_hrl, true).
--include_lib("inets/src/inets_app/inets_internal.hrl").
+-ifndef(SERVER_SOFTWARE).
+-define(SERVER_SOFTWARE,"inets/develop"). % Define in Makefile!
+-endif.
+-define(SERVER_PROTOCOL,"HTTP/1.1").
+-define(DEFAULT_MODS, [mod_alias, mod_auth, mod_esi, mod_actions, mod_cgi,
+ mod_dir, mod_get, mod_head, mod_log, mod_disk_log]).
+-define(SOCKET_CHUNK_SIZE,8192).
+-define(SOCKET_MAX_POLL,25).
+-define(FILE_CHUNK_SIZE,64*1024).
+-define(GATEWAY_INTERFACE,"CGI/1.1").
+-define(NICE(Reason),lists:flatten(atom_to_list(?MODULE)++": "++Reason)).
+-define(DEFAULT_CONTEXT,
+ [{errmsg,"[an error occurred while processing this directive]"},
+ {timefmt,"%A, %d-%b-%y %T %Z"},
+ {sizefmt,"abbrev"}]).
+
+
+-ifdef(inets_error).
+-define(ERROR(Format, Args), io:format("E(~p:~p:~p) : "++Format++"~n",
+ [self(),?MODULE,?LINE]++Args)).
+-else.
+-define(ERROR(F,A),[]).
+-endif.
+
+-ifdef(inets_log).
+-define(LOG(Format, Args), io:format("L(~p:~p:~p) : "++Format++"~n",
+ [self(),?MODULE,?LINE]++Args)).
+-else.
+-define(LOG(F,A),[]).
+-endif.
+
+-ifdef(inets_debug).
+-define(DEBUG(Format, Args), io:format("D(~p:~p:~p) : "++Format++"~n",
+ [self(),?MODULE,?LINE]++Args)).
+-else.
+-define(DEBUG(F,A),[]).
+-endif.
+
+-ifdef(inets_cdebug).
+-define(CDEBUG(Format, Args), io:format("C(~p:~p:~p) : "++Format++"~n",
+ [self(),?MODULE,?LINE]++Args)).
+-else.
+-define(CDEBUG(F,A),[]).
+-endif.
-define(SERVICE, httpd).
-define(hdri(Label, Content), ?report_important(Label, ?SERVICE, Content)).
diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl
index 883acbf585..7084d9824a 100644
--- a/lib/inets/src/http_server/httpd_request.erl
+++ b/lib/inets/src/http_server/httpd_request.erl
@@ -304,9 +304,9 @@ validate_uri(RequestURI) ->
UriNoQueryNoHex =
case string:str(RequestURI, "?") of
0 ->
- (catch httpd_util:decode_hex(RequestURI));
+ (catch http_uri:decode(RequestURI));
Ndx ->
- (catch httpd_util:decode_hex(string:left(RequestURI, Ndx)))
+ (catch http_uri:decode(string:left(RequestURI, Ndx)))
end,
case UriNoQueryNoHex of
{'EXIT',_Reason} ->
diff --git a/lib/inets/src/http_server/httpd_script_env.erl b/lib/inets/src/http_server/httpd_script_env.erl
index a742cbef76..d3115150b0 100644
--- a/lib/inets/src/http_server/httpd_script_env.erl
+++ b/lib/inets/src/http_server/httpd_script_env.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -23,6 +23,7 @@
-export([create_env/3]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
%%%=========================================================================
%%% Internal application API
diff --git a/lib/inets/src/http_server/httpd_sup.erl b/lib/inets/src/http_server/httpd_sup.erl
index 1507c6852a..f94e5459c1 100644
--- a/lib/inets/src/http_server/httpd_sup.erl
+++ b/lib/inets/src/http_server/httpd_sup.erl
@@ -37,7 +37,7 @@
-define(TIMEOUT, 15000).
-include("httpd_internal.hrl").
-
+-include("inets_internal.hrl").
%%%=========================================================================
%%% API
diff --git a/lib/inets/src/http_server/httpd_util.erl b/lib/inets/src/http_server/httpd_util.erl
index cfad79638f..789f12652b 100644
--- a/lib/inets/src/http_server/httpd_util.erl
+++ b/lib/inets/src/http_server/httpd_util.erl
@@ -21,7 +21,7 @@
-export([ip_address/2, lookup/2, lookup/3, multi_lookup/2,
lookup_mime/2, lookup_mime/3, lookup_mime_default/2,
lookup_mime_default/3, reason_phrase/1, message/3, rfc1123_date/0,
- rfc1123_date/1, day/1, month/1, decode_hex/1,
+ rfc1123_date/1, day/1, month/1,
flatlength/1, split_path/1, split_script_path/1,
suffix/1, split/3, uniq/1,
make_name/2,make_name/3,make_name/4,strip/1,
@@ -32,7 +32,7 @@
dir_validate/2, file_validate/2, mime_type_validate/1,
mime_types_validate/1, custom_date/0]).
--export([encode_hex/1]).
+-export([encode_hex/1, decode_hex/1]).
-include_lib("kernel/include/file.hrl").
ip_address({_,_,_,_} = Address, _IpFamily) ->
@@ -175,13 +175,13 @@ reason_phrase(_) -> "Internal Server Error".
%% message
message(301,URL,_) ->
- "The document has moved <A HREF=\""++URL++"\">here</A>.";
+ "The document has moved <A HREF=\""++ maybe_encode(URL) ++"\">here</A>.";
message(304, _URL,_) ->
"The document has not been changed.";
message(400,none,_) ->
"Your browser sent a query that this server could not understand.";
message(400,Msg,_) ->
- "Your browser sent a query that this server could not understand. "++Msg;
+ "Your browser sent a query that this server could not understand. "++ maybe_encode(Msg);
message(401,none,_) ->
"This server could not verify that you
are authorized to access the document you
@@ -190,9 +190,9 @@ credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.";
message(403,RequestURI,_) ->
- "You don't have permission to access "++RequestURI++" on this server.";
+ "You don't have permission to access "++ maybe_encode(RequestURI) ++" on this server.";
message(404,RequestURI,_) ->
- "The requested URL "++RequestURI++" was not found on this server.";
+ "The requested URL " ++ maybe_encode(RequestURI) ++ " was not found on this server.";
message(408, Timeout, _) ->
Timeout;
message(412,none,_) ->
@@ -200,7 +200,7 @@ message(412,none,_) ->
message(413, Reason,_) ->
"Entity: " ++ Reason;
message(414,ReasonPhrase,_) ->
- "Message "++ReasonPhrase++".";
+ "Message "++ ReasonPhrase ++".";
message(416,ReasonPhrase,_) ->
ReasonPhrase;
@@ -216,15 +216,23 @@ message(501,{Method, RequestURI, HTTPVersion}, _ConfigDB) ->
if
is_atom(Method) ->
atom_to_list(Method)++
- " to "++RequestURI++" ("++HTTPVersion++") not supported.";
+ " to "++ maybe_encode(RequestURI)++" ("++HTTPVersion++") not supported.";
is_list(Method) ->
Method++
- " to "++RequestURI++" ("++HTTPVersion++") not supported."
+ " to "++ maybe_encode(RequestURI)++" ("++HTTPVersion++") not supported."
end;
message(503, String, _ConfigDB) ->
"This service in unavailable due to: "++String.
+maybe_encode(URI) ->
+ case lists:member($%, URI) of
+ true ->
+ URI;
+ false ->
+ http_uri:encode(URI)
+ end.
+
%%convert_rfc_date(Date)->{{YYYY,MM,DD},{HH,MIN,SEC}}
convert_request_date([D,A,Y,DateType| Rest])->
@@ -381,16 +389,11 @@ month(12) -> "Dec".
%% decode_hex
-decode_hex([$%,Hex1,Hex2|Rest]) ->
- [hex2dec(Hex1)*16+hex2dec(Hex2)|decode_hex(Rest)];
-decode_hex([First|Rest]) ->
- [First|decode_hex(Rest)];
-decode_hex([]) ->
- [].
+decode_hex(URI) ->
+ http_uri:decode(URI).
-hex2dec(X) when (X>=$0) andalso (X=<$9) -> X-$0;
-hex2dec(X) when (X>=$A) andalso (X=<$F) -> X-$A+10;
-hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10.
+encode_hex(URI) ->
+ http_uri:encode(URI).
%% flatlength
flatlength(List) ->
@@ -411,7 +414,7 @@ split_path(Path) ->
case inets_regexp:match(Path,"[\?].*\$") of
%% A QUERY_STRING exists!
{match,Start,Length} ->
- {httpd_util:decode_hex(string:substr(Path,1,Start-1)),
+ {http_uri:decode(string:substr(Path,1,Start-1)),
string:substr(Path,Start,Length)};
%% A possible PATH_INFO exists!
nomatch ->
@@ -419,9 +422,9 @@ split_path(Path) ->
end.
split_path([],SoFar) ->
- {httpd_util:decode_hex(lists:reverse(SoFar)),[]};
+ {http_uri:decode(lists:reverse(SoFar)),[]};
split_path([$/|Rest],SoFar) ->
- Path=httpd_util:decode_hex(lists:reverse(SoFar)),
+ Path=http_uri:decode(lists:reverse(SoFar)),
case file:read_file_info(Path) of
{ok,FileInfo} when FileInfo#file_info.type =:= regular ->
{Path,[$/|Rest]};
@@ -454,7 +457,7 @@ pathinfo_querystring([C|Rest], SoFar) ->
pathinfo_querystring(Rest, [C|SoFar]).
split_script_path([$?|QueryString], SoFar) ->
- Path = httpd_util:decode_hex(lists:reverse(SoFar)),
+ Path = http_uri:decode(lists:reverse(SoFar)),
case file:read_file_info(Path) of
{ok,FileInfo} when FileInfo#file_info.type =:= regular ->
{Path, [$?|QueryString]};
@@ -464,7 +467,7 @@ split_script_path([$?|QueryString], SoFar) ->
not_a_script
end;
split_script_path([], SoFar) ->
- Path = httpd_util:decode_hex(lists:reverse(SoFar)),
+ Path = http_uri:decode(lists:reverse(SoFar)),
case file:read_file_info(Path) of
{ok,FileInfo} when FileInfo#file_info.type =:= regular ->
{Path, []};
@@ -474,7 +477,7 @@ split_script_path([], SoFar) ->
not_a_script
end;
split_script_path([$/|Rest], SoFar) ->
- Path = httpd_util:decode_hex(lists:reverse(SoFar)),
+ Path = http_uri:decode(lists:reverse(SoFar)),
case file:read_file_info(Path) of
{ok, FileInfo} when FileInfo#file_info.type =:= regular ->
{Path, [$/|Rest]};
@@ -608,9 +611,6 @@ hexlist_to_integer(List)->
%%----------------------------------------------------------------------
%%Converts an integer to an hexlist
%%----------------------------------------------------------------------
-encode_hex(Num)->
- integer_to_hexlist(Num).
-
integer_to_hexlist(Num) when is_integer(Num) ->
http_util:integer_to_hexlist(Num).
@@ -735,7 +735,6 @@ valid_accept_timeout(A) ->
valid_config(_) ->
ok.
-
%%----------------------------------------------------------------------
%% Enable debugging,
%%----------------------------------------------------------------------
diff --git a/lib/inets/src/http_server/mod_actions.erl b/lib/inets/src/http_server/mod_actions.erl
index d50ed4b16c..c3946ff9b4 100644
--- a/lib/inets/src/http_server/mod_actions.erl
+++ b/lib/inets/src/http_server/mod_actions.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,6 +21,7 @@
-export([do/1,load/2, store/2]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
%% do
diff --git a/lib/inets/src/http_server/mod_alias.erl b/lib/inets/src/http_server/mod_alias.erl
index 9c5a8cc1c6..0b9fe4cfe0 100644
--- a/lib/inets/src/http_server/mod_alias.erl
+++ b/lib/inets/src/http_server/mod_alias.erl
@@ -29,6 +29,7 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-define(VMODULE,"ALIAS").
diff --git a/lib/inets/src/http_server/mod_auth.erl b/lib/inets/src/http_server/mod_auth.erl
index 07cafb4726..85a87ab884 100644
--- a/lib/inets/src/http_server/mod_auth.erl
+++ b/lib/inets/src/http_server/mod_auth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -38,6 +38,7 @@
-include("httpd.hrl").
-include("mod_auth.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-define(VMODULE,"AUTH").
diff --git a/lib/inets/src/http_server/mod_auth.hrl b/lib/inets/src/http_server/mod_auth.hrl
index 9b316cecc4..674e6d1652 100644
--- a/lib/inets/src/http_server/mod_auth.hrl
+++ b/lib/inets/src/http_server/mod_auth.hrl
@@ -1,29 +1,27 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-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%
%%
+%% %CopyrightEnd%
%%
+%% This is a simple wrapper for code that has not been updated to
+%% handle the move of this file to the include dir.
+
+-ifndef(src_mod_auth_hrl).
+-define(src_mod_auth_hrl, true).
--record(httpd_user,
- {username,
- password,
- user_data}).
+-include_lib("inets/include/mod_auth.hrl").
--record(httpd_group,
- {name,
- userlist}).
-
+-endif. % -ifdef(src_mod_auth_hrl).
diff --git a/lib/inets/src/http_server/mod_auth_dets.erl b/lib/inets/src/http_server/mod_auth_dets.erl
index bc6c2b70a0..a48725d5d9 100644
--- a/lib/inets/src/http_server/mod_auth_dets.erl
+++ b/lib/inets/src/http_server/mod_auth_dets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -35,6 +35,7 @@
-export([store_directory_data/3]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
-include("mod_auth.hrl").
store_directory_data(_Directory, DirData, Server_root) ->
diff --git a/lib/inets/src/http_server/mod_auth_plain.erl b/lib/inets/src/http_server/mod_auth_plain.erl
index d88859d28a..c0a83711ba 100644
--- a/lib/inets/src/http_server/mod_auth_plain.erl
+++ b/lib/inets/src/http_server/mod_auth_plain.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,6 +22,8 @@
-include("httpd.hrl").
-include("mod_auth.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
+
-define(VMODULE,"AUTH_PLAIN").
diff --git a/lib/inets/src/http_server/mod_auth_server.erl b/lib/inets/src/http_server/mod_auth_server.erl
index 5f9e59be9d..947273bd9e 100644
--- a/lib/inets/src/http_server/mod_auth_server.erl
+++ b/lib/inets/src/http_server/mod_auth_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,6 +22,7 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-behaviour(gen_server).
diff --git a/lib/inets/src/http_server/mod_cgi.erl b/lib/inets/src/http_server/mod_cgi.erl
index 33605b9698..c854166c29 100644
--- a/lib/inets/src/http_server/mod_cgi.erl
+++ b/lib/inets/src/http_server/mod_cgi.erl
@@ -27,6 +27,7 @@
-export([do/1, load/2, store/2]).
-include("http_internal.hrl").
+-include("httpd_internal.hrl").
-include("httpd.hrl").
-define(VMODULE,"CGI").
diff --git a/lib/inets/src/http_server/mod_dir.erl b/lib/inets/src/http_server/mod_dir.erl
index cdc7cc01e4..d791ee28e9 100644
--- a/lib/inets/src/http_server/mod_dir.erl
+++ b/lib/inets/src/http_server/mod_dir.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,9 +18,11 @@
%%
%%
-module(mod_dir).
--export([do/1]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
+
+-export([do/1]).
%% do
@@ -57,7 +59,7 @@ do_dir(Info) ->
case file:read_file_info(DefaultPath) of
{ok,FileInfo} when FileInfo#file_info.type == directory ->
DecodedRequestURI =
- httpd_util:decode_hex(Info#mod.request_uri),
+ http_uri:decode(Info#mod.request_uri),
?DEBUG("do_dir -> ~n"
" Path: ~p~n"
" DefaultPath: ~p~n"
diff --git a/lib/inets/src/http_server/mod_disk_log.erl b/lib/inets/src/http_server/mod_disk_log.erl
index 95e0d00c70..5a3766de66 100644
--- a/lib/inets/src/http_server/mod_disk_log.erl
+++ b/lib/inets/src/http_server/mod_disk_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,7 +28,7 @@
-define(VMODULE,"DISK_LOG").
-include("httpd.hrl").
-
+-include("httpd_internal.hrl").
%%%=========================================================================
%%% API
diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl
index f7877aa9e2..929185a67a 100644
--- a/lib/inets/src/http_server/mod_esi.erl
+++ b/lib/inets/src/http_server/mod_esi.erl
@@ -30,6 +30,7 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-define(VMODULE,"ESI").
-define(DEFAULT_ERL_TIMEOUT,15000).
diff --git a/lib/inets/src/http_server/mod_get.erl b/lib/inets/src/http_server/mod_get.erl
index 9fd1fcec47..5cb30e3d97 100644
--- a/lib/inets/src/http_server/mod_get.erl
+++ b/lib/inets/src/http_server/mod_get.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
-module(mod_get).
-export([do/1]).
-include("httpd.hrl").
-
+-include("httpd_internal.hrl").
%% do
do(Info) ->
diff --git a/lib/inets/src/http_server/mod_head.erl b/lib/inets/src/http_server/mod_head.erl
index 8b08d61651..c346fd4d23 100644
--- a/lib/inets/src/http_server/mod_head.erl
+++ b/lib/inets/src/http_server/mod_head.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/inets/src/http_server/mod_htaccess.erl b/lib/inets/src/http_server/mod_htaccess.erl
index d8835198f5..e1f66d01c8 100644
--- a/lib/inets/src/http_server/mod_htaccess.erl
+++ b/lib/inets/src/http_server/mod_htaccess.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -23,6 +23,7 @@
-export([do/1, load/2, store/2]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Public methods that interface the eswapi %%
diff --git a/lib/inets/src/http_server/mod_include.erl b/lib/inets/src/http_server/mod_include.erl
index 534eba8a36..35f45bdd33 100644
--- a/lib/inets/src/http_server/mod_include.erl
+++ b/lib/inets/src/http_server/mod_include.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,6 +21,7 @@
-export([do/1,parse/2,config/6,include/6,echo/6,fsize/6,flastmod/6,exec/6]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
-define(VMODULE,"INCLUDE").
@@ -186,9 +187,9 @@ document_uri(ConfigDB, RequestURI) ->
FileName = string:substr(Path,Start,Length),
case inets_regexp:match(VirtualPath, FileName++"\$") of
{match, _, _} ->
- httpd_util:decode_hex(VirtualPath)++AfterPath;
+ http_uri:decode(VirtualPath)++AfterPath;
nomatch ->
- string:strip(httpd_util:decode_hex(VirtualPath),right,$/)++
+ string:strip(http_uri:decode(VirtualPath),right,$/)++
"/"++FileName++AfterPath
end.
diff --git a/lib/inets/src/http_server/mod_log.erl b/lib/inets/src/http_server/mod_log.erl
index de24d5a569..c8a2ec0dc4 100644
--- a/lib/inets/src/http_server/mod_log.erl
+++ b/lib/inets/src/http_server/mod_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,6 +26,7 @@
-export([do/1, load/2, store/2, remove/1]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
-define(VMODULE,"LOG").
%%%=========================================================================
diff --git a/lib/inets/src/http_server/mod_range.erl b/lib/inets/src/http_server/mod_range.erl
index 0698fb9099..a0408cba79 100644
--- a/lib/inets/src/http_server/mod_range.erl
+++ b/lib/inets/src/http_server/mod_range.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -20,7 +20,7 @@
-module(mod_range).
-export([do/1]).
-include("httpd.hrl").
-
+-include("httpd_internal.hrl").
%% do
do(Info) ->
diff --git a/lib/inets/src/http_server/mod_responsecontrol.erl b/lib/inets/src/http_server/mod_responsecontrol.erl
index 79e2e1bdba..5d5b60cdbd 100644
--- a/lib/inets/src/http_server/mod_responsecontrol.erl
+++ b/lib/inets/src/http_server/mod_responsecontrol.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,6 +22,7 @@
-export([do/1]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
do(Info) ->
?DEBUG("do -> response_control",[]),
diff --git a/lib/inets/src/http_server/mod_security.erl b/lib/inets/src/http_server/mod_security.erl
index 95793e1cfb..41988732ad 100644
--- a/lib/inets/src/http_server/mod_security.erl
+++ b/lib/inets/src/http_server/mod_security.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -32,6 +32,7 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-define(VMODULE,"SEC").
diff --git a/lib/inets/src/http_server/mod_security_server.erl b/lib/inets/src/http_server/mod_security_server.erl
index 58060686b3..784b3eba70 100644
--- a/lib/inets/src/http_server/mod_security_server.erl
+++ b/lib/inets/src/http_server/mod_security_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -45,6 +45,7 @@
-include("httpd.hrl").
-include("httpd_internal.hrl").
+-include("inets_internal.hrl").
-behaviour(gen_server).
diff --git a/lib/inets/src/http_server/mod_trace.erl b/lib/inets/src/http_server/mod_trace.erl
index df482228d8..7233925783 100644
--- a/lib/inets/src/http_server/mod_trace.erl
+++ b/lib/inets/src/http_server/mod_trace.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/inets/src/inets_app/Makefile b/lib/inets/src/inets_app/Makefile
index 4632ff3b68..20e22917e2 100644
--- a/lib/inets/src/inets_app/Makefile
+++ b/lib/inets/src/inets_app/Makefile
@@ -47,7 +47,9 @@ MODULES = \
inets_sup \
inets_regexp
-HRL_FILES = inets_internal.hrl
+INTERNAL_HRL_FILES = inets_internal.hrl
+EXTERNAL_HRL_FILES = ../../include/httpd.hrl \
+ ../../include/mod_auth.hrl
ERL_FILES = $(MODULES:%=%.erl)
@@ -74,8 +76,7 @@ include inets.mk
ERL_COMPILE_FLAGS += \
$(INETS_FLAGS) \
- $(INETS_ERL_COMPILE_FLAGS) \
- -I../../include
+ $(INETS_ERL_COMPILE_FLAGS)
# ----------------------------------------------------
@@ -110,7 +111,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)/src
$(INSTALL_DIR) $(RELSYSDIR)/src/inets_app
- $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/inets_app
+ $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/inets_app
+ $(INSTALL_DIR) $(RELSYSDIR)/include
+ $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) $(RELSYSDIR)/include
$(INSTALL_DIR) $(RELSYSDIR)/ebin
$(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index 84d8c9278d..0194c65db9 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -18,6 +18,11 @@
{"%VSN%",
[
+ {"5.5",
+ [
+ {restart_application, inets}
+ ]
+ },
{"5.4",
[
{restart_application, inets}
@@ -29,6 +34,11 @@
[
{restart_application, inets}
]
+ },
+ {"5.4",
+ [
+ {restart_application, inets}
+ ]
}
]
}.
diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile
index bb7f2186af..4b803cfbe2 100644
--- a/lib/inets/test/Makefile
+++ b/lib/inets/test/Makefile
@@ -200,7 +200,8 @@ SOURCE = $(ERL_FILES) $(HRL_FILES)
TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
-INETS_SPECS = inets.spec inets.spec.vxworks
+INETS_SPECS = inets.spec
+COVER_FILE = inets.cover
INETS_FILES = inets.config $(INETS_SPECS)
# SUB_SUITES = \
@@ -222,10 +223,10 @@ MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
ifeq ($(MAKE_EMAKE),)
BUILDTARGET = $(TARGET_FILES)
-RELTEST_FILES = $(INETS_SPECS) $(SOURCE)
+RELTEST_FILES = $(COVER_FILE) $(INETS_SPECS) $(SOURCE)
else
BUILDTARGET = emakebuild
-RELTEST_FILES = $(EMAKEFILE) $(INETS_SPECS) $(SOURCE)
+RELTEST_FILES = $(EMAKEFILE) $(COVER_FILE) $(INETS_SPECS) $(SOURCE)
endif
@@ -288,16 +289,20 @@ release_spec: opt
$(INSTALL_DATA) $(INETS_FILES) $(RELSYSDIR)/test
@for d in $(DATADIRS); do \
echo "installing data dir $$d"; \
- echo $$d/TAR.exclude2 > $$d/TAR.exclude2; \
- cat $$d/TAR.exclude >> $$d/TAR.exclude2; \
- find $$d -name '*.contrib*' >> $$d/TAR.exclude2; \
- find $$d -name '*.keep*' >> $$d/TAR.exclude2; \
- find $$d -name '*.mkelem*' >> $$d/TAR.exclude2; \
- find $$d -name '*~' >> $$d/TAR.exclude2; \
- find $$d -name 'erl_crash.dump' >> $$d/TAR.exclude2; \
- find $$d -name 'core' >> $$d/TAR.exclude2; \
- find $$d -name '.cmake.state' >> $$d/TAR.exclude2; \
- tar cfX - $$d/TAR.exclude2 $$d | (cd $(RELSYSDIR)/test; tar xf -); \
+ if test -f $$d/TAR.exclude; then \
+ echo $$d/TAR.exclude2 > $$d/TAR.exclude2; \
+ cat $$d/TAR.exclude >> $$d/TAR.exclude2; \
+ find $$d -name '*.contrib*' >> $$d/TAR.exclude2; \
+ find $$d -name '*.keep*' >> $$d/TAR.exclude2; \
+ find $$d -name '*.mkelem*' >> $$d/TAR.exclude2; \
+ find $$d -name '*~' >> $$d/TAR.exclude2; \
+ find $$d -name 'erl_crash.dump' >> $$d/TAR.exclude2; \
+ find $$d -name 'core' >> $$d/TAR.exclude2; \
+ find $$d -name '.cmake.state' >> $$d/TAR.exclude2; \
+ tar cfX - $$d/TAR.exclude2 $$d | (cd $(RELSYSDIR)/test; tar xf -); \
+ else \
+ tar cf - $$d | (cd $(RELSYSDIR)/test; tar xf -); \
+ fi; \
done
release_tests_spec: opt
diff --git a/lib/inets/test/ftp_SUITE.erl b/lib/inets/test/ftp_SUITE.erl
index e7404f945b..7059bb12cf 100644
--- a/lib/inets/test/ftp_SUITE.erl
+++ b/lib/inets/test/ftp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -20,29 +20,14 @@
-module(ftp_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
% -export([init_per_testcase/2, end_per_testcase/2]).
-export([init_per_suite/1, end_per_suite/1]).
-%% Test cases must be exported.
--export([solaris8_test/1,
- solaris9_test/1,
- solaris10_test/1,
- linux_x86_test/1,
- linux_ppc_test/1,
- macosx_x86_test/1,
- macosx_ppc_test/1,
- openbsd_test/1,
- freebsd_test/1,
- netbsd_test/1,
- windows_xp_test/1,
- windows_2003_server_test/1,
- ticket_tests/1]).
-
-define(FTP_USER, "anonymous").
-define(FTP_PASS, passwd()).
-define(FTP_PORT, 21).
@@ -72,52 +57,44 @@
%% Description: Returns documentation/test cases in this test suite
%% or a skip tuple if the platform is not supported.
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test the ftp client in the inets application."];
-all(suite) ->
- [
- solaris8_test,
- solaris9_test,
- solaris10_test,
- linux_x86_test,
- linux_ppc_test,
- macosx_x86_test,
- macosx_ppc_test,
- openbsd_test,
- freebsd_test,
- netbsd_test,
- windows_xp_test,
- windows_2003_server_test,
- ticket_tests
- ].
-
-solaris8_test(suite) ->
- [{ftp_solaris8_sparc_test,all}].
-solaris9_test(suite) ->
- [{ftp_solaris9_sparc_test,all}].
-solaris10_test(suite) ->
- [{ftp_solaris10_sparc_test,all}, {ftp_solaris10_x86_test,all}].
-linux_x86_test(suite) ->
- [{ftp_linux_x86_test,all}].
-linux_ppc_test(suite) ->
- [{ftp_linux_ppc_test,all}].
-macosx_x86_test(suite) ->
- [{ftp_macosx_x86_test,all}].
-macosx_ppc_test(suite) ->
- [{ftp_macosx_ppc_test,all}].
-openbsd_test(suite) ->
- [{ftp_openbsd_x86_test,all}].
-freebsd_test(suite) ->
- [{ftp_freebsd_x86_test,all}].
-netbsd_test(suite) ->
- [{ftp_netbsd_x86_test,all}].
-windows_xp_test(suite) ->
- [{ftp_windows_xp_test,all}].
-windows_2003_server_test(suite) ->
- [{ftp_windows_2003_server_test,all}].
-
-ticket_tests(suite) ->
- [{ftp_ticket_test, all}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, solaris8_test}, {group, solaris9_test},
+ {group, solaris10_test}, {group, linux_x86_test},
+ {group, linux_ppc_test}, {group, macosx_x86_test},
+ {group, macosx_ppc_test}, {group, openbsd_test},
+ {group, freebsd_test}, {group, netbsd_test},
+ {group, windows_xp_test},
+ {group, windows_2003_server_test},
+ {group, ticket_tests}].
+
+groups() ->
+ [{solaris8_test, [], [{ftp_solaris8_sparc_test, all}]},
+ {solaris9_test, [], [{ftp_solaris9_sparc_test, all}]},
+ {solaris10_test, [],
+ [{ftp_solaris10_sparc_test, all},
+ {ftp_solaris10_x86_test, all}]},
+ {linux_x86_test, [], [{ftp_linux_x86_test, all}]},
+ {linux_ppc_test, [], [{ftp_linux_ppc_test, all}]},
+ {macosx_x86_test, [], [{ftp_macosx_x86_test, all}]},
+ {macosx_ppc_test, [], [{ftp_macosx_ppc_test, all}]},
+ {openbsd_test, [], [{ftp_openbsd_x86_test, all}]},
+ {freebsd_test, [], [{ftp_freebsd_x86_test, all}]},
+ {netbsd_test, [], [{ftp_netbsd_x86_test, all}]},
+ {windows_xp_test, [], [{ftp_windows_xp_test, all}]},
+ {windows_2003_server_test, [],
+ [{ftp_windows_2003_server_test, all}]},
+ {ticket_tests, [], [{ftp_ticket_test, all}]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
diff --git a/lib/inets/test/ftp_format_SUITE.erl b/lib/inets/test/ftp_format_SUITE.erl
index 9ca6575b2d..3a8cb9a3d0 100644
--- a/lib/inets/test/ftp_format_SUITE.erl
+++ b/lib/inets/test/ftp_format_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -20,23 +20,44 @@
-module(ftp_format_SUITE).
-author('[email protected]').
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
-include("ftp_internal.hrl").
%% Test server specific exports
--export([all/1, init_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
%% Test cases must be exported.
--export([ftp_response/1, ftp_150/1,
- ftp_200/1, ftp_220/1, ftp_226/1, ftp_257/1, ftp_331/1, ftp_425/1,
- ftp_other_status_codes/1, ftp_multiple_lines/1,
- ftp_multipel_ctrl_messages/1, format_error/1]).
+-export([ ftp_150/1,
+ ftp_200/1, ftp_220/1, ftp_226/1, ftp_257/1, ftp_331/1, ftp_425/1,
+ ftp_other_status_codes/1, ftp_multiple_lines/1,
+ ftp_multipel_ctrl_messages/1, format_error/1]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, ftp_response}, format_error].
+
+groups() ->
+ [{ftp_response, [],
+ [ftp_150, ftp_200, ftp_220, ftp_226, ftp_257, ftp_331,
+ ftp_425, ftp_other_status_codes, ftp_multiple_lines,
+ ftp_multipel_ctrl_messages]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(doc) ->
- ["Test library functions for the ftp client."];
-all(suite) ->
- [ftp_response, format_error].
init_per_testcase(_, Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
@@ -51,14 +72,6 @@ end_per_testcase(_, Config) ->
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-ftp_response(doc) ->
- ["Test ftp_response:parse_lines/3 and ftp_response:interpret/1."
- " This test case will simulate that the "
- "message will be recived a little at the time on a socket and the "
- "package may be broken up into smaller parts at arbitrary point."];
-ftp_response(suite) ->
- [ftp_150, ftp_200, ftp_220, ftp_226, ftp_257, ftp_331, ftp_425,
- ftp_other_status_codes, ftp_multiple_lines, ftp_multipel_ctrl_messages].
ftp_150(doc) ->
["Especially check that respons can be devided in a random place."];
diff --git a/lib/inets/test/ftp_freebsd_x86_test.erl b/lib/inets/test/ftp_freebsd_x86_test.erl
index 457e18ffbe..1d66779882 100644
--- a/lib/inets/test/ftp_freebsd_x86_test.erl
+++ b/lib/inets/test/ftp_freebsd_x86_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -86,23 +86,30 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
%% Test cases starts here.
%%--------------------------------------------------------------------
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_linux_ppc_test.erl b/lib/inets/test/ftp_linux_ppc_test.erl
index ad38137678..bba97237f1 100644
--- a/lib/inets/test/ftp_linux_ppc_test.erl
+++ b/lib/inets/test/ftp_linux_ppc_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -23,7 +23,7 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -87,23 +87,30 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
%% Test cases starts here.
%%--------------------------------------------------------------------
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_linux_x86_test.erl b/lib/inets/test/ftp_linux_x86_test.erl
index b9c88d121a..bbefd8231e 100644
--- a/lib/inets/test/ftp_linux_x86_test.erl
+++ b/lib/inets/test/ftp_linux_x86_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -86,30 +86,30 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
-
-all(suite) ->
- [
- open,
- open_port,
- passive,
- active,
- api_missuse,
- not_owner,
- progress_report
- ].
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Test cases starts here.
%%--------------------------------------------------------------------
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_macosx_ppc_test.erl b/lib/inets/test/ftp_macosx_ppc_test.erl
index cf548a73c0..c9f33b8beb 100644
--- a/lib/inets/test/ftp_macosx_ppc_test.erl
+++ b/lib/inets/test/ftp_macosx_ppc_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -87,21 +87,28 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+[open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_macosx_x86_test.erl b/lib/inets/test/ftp_macosx_x86_test.erl
index 5566d4feaa..17b7160b95 100644
--- a/lib/inets/test/ftp_macosx_x86_test.erl
+++ b/lib/inets/test/ftp_macosx_x86_test.erl
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -86,22 +86,29 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+[open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
%% Test cases starts here.
%%--------------------------------------------------------------------
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_netbsd_x86_test.erl b/lib/inets/test/ftp_netbsd_x86_test.erl
index a5711b7bde..bb474852c5 100644
--- a/lib/inets/test/ftp_netbsd_x86_test.erl
+++ b/lib/inets/test/ftp_netbsd_x86_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -86,22 +86,29 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
%% Test cases starts here.
%%--------------------------------------------------------------------
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_openbsd_x86_test.erl b/lib/inets/test/ftp_openbsd_x86_test.erl
index 4833b6332b..54fce702a0 100644
--- a/lib/inets/test/ftp_openbsd_x86_test.erl
+++ b/lib/inets/test/ftp_openbsd_x86_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -23,7 +23,7 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -87,23 +87,30 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
%% Test cases starts here.
%%--------------------------------------------------------------------
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_solaris10_sparc_test.erl b/lib/inets/test/ftp_solaris10_sparc_test.erl
index 6066195f9b..0da50dc91b 100644
--- a/lib/inets/test/ftp_solaris10_sparc_test.erl
+++ b/lib/inets/test/ftp_solaris10_sparc_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -87,23 +87,30 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
%% Test cases starts here.
%%--------------------------------------------------------------------
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_solaris10_x86_test.erl b/lib/inets/test/ftp_solaris10_x86_test.erl
index 3bd99fc3f2..3e7045bb4d 100644
--- a/lib/inets/test/ftp_solaris10_x86_test.erl
+++ b/lib/inets/test/ftp_solaris10_x86_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% 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
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD, ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_), ?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -88,23 +88,30 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
%% Test cases starts here.
%%--------------------------------------------------------------------
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_solaris8_sparc_test.erl b/lib/inets/test/ftp_solaris8_sparc_test.erl
index 9764071cd9..23dbfc8fe3 100644
--- a/lib/inets/test/ftp_solaris8_sparc_test.erl
+++ b/lib/inets/test/ftp_solaris8_sparc_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -86,22 +86,29 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
%% Test cases starts here.
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_solaris9_sparc_test.erl b/lib/inets/test/ftp_solaris9_sparc_test.erl
index a9f77bbdac..896e2f497f 100644
--- a/lib/inets/test/ftp_solaris9_sparc_test.erl
+++ b/lib/inets/test/ftp_solaris9_sparc_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -85,22 +85,29 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
%% Test cases starts here.
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl
index c539b7c17c..5ae0298b29 100644
--- a/lib/inets/test/ftp_suite_lib.erl
+++ b/lib/inets/test/ftp_suite_lib.erl
@@ -21,8 +21,8 @@
-module(ftp_suite_lib).
--include("test_server.hrl").
--include("test_server_line.hrl").
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("test_server/include/test_server_line.hrl").
-include("inets_test_lib.hrl").
%% Test server specific exports
@@ -74,7 +74,7 @@ tickets(suite) ->
ftpd_init(FtpdTag, Config) ->
%% Get the host name(s) of FTP server
Hosts =
- case ?config(ftpd_hosts, Config) of
+ case ct:get_config(ftpd_hosts) of
undefined ->
ftpd_hosts(data_dir(Config));
H ->
@@ -129,7 +129,7 @@ get_ftpd_host([Host|Hosts]) ->
dirty_select_ftpd_host(Config) ->
Hosts =
- case ?config(ftpd_hosts, Config) of
+ case ct:get_config(ftpd_hosts) of
undefined ->
ftpd_hosts(data_dir(Config));
H ->
diff --git a/lib/inets/test/ftp_ticket_test.erl b/lib/inets/test/ftp_ticket_test.erl
index 6748df03bb..fe4ab35728 100644
--- a/lib/inets/test/ftp_ticket_test.erl
+++ b/lib/inets/test/ftp_ticket_test.erl
@@ -35,17 +35,27 @@ end_per_testcase(Case, Config) ->
ftp_suite_lib:end_per_testcase(Case, Config).
-all(suite) ->
- {conf,init,tickets(),fin}.
+all() ->
+ tickets().
-init(Config) ->
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(Config) ->
?LIB_MOD:ftpd_init(ticket_test, Config).
-tickets() ->
+tickets() ->
[ticket_6035].
-fin(Config) ->
+end_per_suite(Config) ->
?LIB_MOD:ftpd_fin(Config).
ticket_6035(X) -> ?LIB_MOD:ticket_6035(X).
diff --git a/lib/inets/test/ftp_windows_2003_server_test.erl b/lib/inets/test/ftp_windows_2003_server_test.erl
index d24318d04f..57f1ae8358 100644
--- a/lib/inets/test/ftp_windows_2003_server_test.erl
+++ b/lib/inets/test/ftp_windows_2003_server_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -86,22 +86,29 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
%% Test cases starts here.
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/ftp_windows_xp_test.erl b/lib/inets/test/ftp_windows_xp_test.erl
index bc161e4f6a..06d919ba00 100644
--- a/lib/inets/test/ftp_windows_xp_test.erl
+++ b/lib/inets/test/ftp_windows_xp_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,7 +22,7 @@
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(LIB_MOD,ftp_suite_lib).
-define(CASE_WRAPPER(_A_,_B_,_C_),?LIB_MOD:wrapper(_A_,_B_,_C_)).
@@ -86,20 +86,27 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test ftp client"];
+all() ->
+ [open, open_port, {group, passive}, {group, active},
+ api_missuse, not_owner, {group, progress_report}].
+
+groups() ->
+ [{passive, [], ftp_suite_lib:passive(suite)},
+ {active, [], ftp_suite_lib:active(suite)},
+ {progress_report, [],
+ ftp_suite_lib:progress_report(suite)}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [open, open_port, passive, active, api_missuse,
- not_owner, progress_report].
open(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open/1).
open_port(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:open_port/1).
-passive(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:passive/1).
-active(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:active/1).
api_missuse(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:api_missuse/1).
not_owner(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:not_owner/1).
-progress_report(X) -> ?CASE_WRAPPER(?PLATFORM,X,fun ?LIB_MOD:progress_report/1).
passive_user(X) -> ?LIB_MOD:passive_user(X).
passive_pwd(X) -> ?LIB_MOD:passive_pwd(X).
diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl
index 79945f0f4d..f05dfd78bc 100644
--- a/lib/inets/test/http_format_SUITE.erl
+++ b/lib/inets/test/http_format_SUITE.erl
@@ -21,28 +21,49 @@
-module(http_format_SUITE).
-author('[email protected]').
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
-include("http_internal.hrl").
%% Test server specific exports
--export([all/1, init_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, init_per_testcase/2, end_per_testcase/2]).
%% Test cases must be exported.
--export([chunk/1, chunk_decode/1, chunk_encode/1,
- chunk_extensions_otp_6005/1, chunk_decode_otp_6264/1,
- chunk_decode_empty_chunk_otp_6511/1,
- chunk_decode_trailer/1,
- http_response/1, http_request/1, validate_request_line/1, script/1,
- esi_parse_headers/1, cgi_parse_headers/1,
- is_absolut_uri/1, convert_netscapecookie_date/1]).
-
-all(doc) ->
- ["Test library functions to the http client and server."];
-all(suite) ->
- [chunk,
- http_response, http_request, validate_request_line,
- script, is_absolut_uri, convert_netscapecookie_date].
+-export([ chunk_decode/1, chunk_encode/1,
+ chunk_extensions_otp_6005/1, chunk_decode_otp_6264/1,
+ chunk_decode_empty_chunk_otp_6511/1,
+ chunk_decode_trailer/1,
+ http_response/1, http_request/1, validate_request_line/1,
+ esi_parse_headers/1, cgi_parse_headers/1,
+ is_absolut_uri/1, convert_netscapecookie_date/1]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, chunk}, http_response, http_request,
+ validate_request_line, {group, script}, is_absolut_uri,
+ convert_netscapecookie_date].
+
+groups() ->
+ [{script, [], [esi_parse_headers, cgi_parse_headers]},
+ {chunk, [],
+ [chunk_decode, chunk_encode, chunk_extensions_otp_6005,
+ chunk_decode_otp_6264,
+ chunk_decode_empty_chunk_otp_6511,
+ chunk_decode_trailer]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_, Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
@@ -57,17 +78,7 @@ end_per_testcase(_, Config) ->
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-script(doc) ->
- ["Test header parsing in esi/cgi functionality."];
-script(suite) ->
- [esi_parse_headers, cgi_parse_headers].
-
-chunk(doc) ->
- ["Test chunk encoding"];
-chunk(suite) ->
- [chunk_decode, chunk_encode, chunk_extensions_otp_6005,
- chunk_decode_otp_6264, chunk_decode_empty_chunk_otp_6511,
- chunk_decode_trailer].
+
%%-------------------------------------------------------------------------
chunk_decode(doc) ->
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 6947f75b3d..41737a0d74 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -24,7 +24,7 @@
-module(httpc_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
-include_lib("kernel/include/file.hrl").
@@ -59,6 +59,49 @@
%% or a skip tuple if the platform is not supported.
%%--------------------------------------------------------------------
+<<<<<<< variant A
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [proxy_options, proxy_head, proxy_get, proxy_trace,
+ proxy_post, proxy_put, proxy_delete, proxy_auth,
+ proxy_headers, proxy_emulate_lower_versions,
+ http_options, http_head, http_get, http_post,
+ http_dummy_pipe, http_inets_pipe, http_trace,
+ http_async, http_save_to_file, http_save_to_file_async,
+ http_headers, http_headers_dummy, http_bad_response,
+ ssl_head, ossl_head, essl_head, ssl_get, ossl_get,
+ essl_get, ssl_trace, ossl_trace, essl_trace,
+ http_redirect, http_redirect_loop,
+ http_internal_server_error, http_userinfo, http_cookie,
+ http_server_does_not_exist, http_invalid_http,
+ http_emulate_lower_versions, http_relaxed,
+ page_does_not_exist, proxy_page_does_not_exist,
+ proxy_https_not_supported, http_stream,
+ http_stream_once, proxy_stream, parse_url, options,
+ ipv6, headers_as_is, {group, tickets}].
+
+groups() ->
+ [{tickets, [],
+ [hexed_query_otp_6191, empty_body_otp_6243,
+ empty_response_header_otp_6830,
+ transfer_encoding_otp_6807, proxy_not_modified_otp_6821,
+ no_content_204_otp_6982, missing_CR_otp_7304,
+ {group, otp_7883}, {group, otp_8154}, {group, otp_8106},
+ otp_8056, otp_8352, otp_8371, otp_8739]},
+ {otp_7883, [], [otp_7883_1, otp_7883_2]},
+ {otp_8154, [], [otp_8154_1]},
+ {otp_8106, [],
+ [otp_8106_pid, otp_8106_fun, otp_8106_mfa]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+>>>>>>> variant B
all(doc) ->
["Test the http client in the intes application."];
all(suite) ->
@@ -118,6 +161,66 @@ all(suite) ->
tickets
].
+####### Ancestor
+all(doc) ->
+ ["Test the http client in the intes application."];
+all(suite) ->
+ [
+ proxy_options,
+ proxy_head,
+ proxy_get,
+ proxy_trace,
+ proxy_post,
+ proxy_put,
+ proxy_delete,
+ proxy_auth,
+ proxy_headers,
+ proxy_emulate_lower_versions,
+ http_options,
+ http_head,
+ http_get,
+ http_post,
+ http_dummy_pipe,
+ http_inets_pipe,
+ http_trace,
+ http_async,
+ http_save_to_file,
+ http_save_to_file_async,
+ http_headers,
+ http_headers_dummy,
+ http_bad_response,
+ ssl_head,
+ ossl_head,
+ essl_head,
+ ssl_get,
+ ossl_get,
+ essl_get,
+ ssl_trace,
+ ossl_trace,
+ essl_trace,
+ http_redirect,
+ http_redirect_loop,
+ http_internal_server_error,
+ http_userinfo,
+ http_cookie,
+ http_server_does_not_exist,
+ http_invalid_http,
+ http_emulate_lower_versions,
+ http_relaxed,
+ page_does_not_exist,
+ proxy_page_does_not_exist,
+ proxy_https_not_supported,
+ http_stream,
+ http_stream_once,
+ proxy_stream,
+ parse_url,
+ options,
+ ipv6,
+ headers_as_is,
+ tickets
+ ].
+
+======= end
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
%% Config - [tuple()]
@@ -229,6 +332,8 @@ init_per_testcase(Case, Timeout, Config) ->
tsp("init_per_testcase -> [proxy case] start inets"),
inets:start(),
tsp("init_per_testcase -> [proxy case] start ssl"),
+ application:start(crypto),
+ application:start(public_key),
case (catch application:start(ssl)) of
ok ->
[{watchdog, Dog} | TmpConfig];
@@ -255,9 +360,14 @@ init_per_testcase(Case, Timeout, Config) ->
[{watchdog, Dog}, {local_server, Server} | TmpConfig2]
end,
+ %% httpc:set_options([{proxy, {{?PROXY, ?PROXY_PORT},
+ %% ["localhost", ?IPV6_LOCAL_HOST]}}]),
+
httpc:set_options([{proxy, {{?PROXY, ?PROXY_PORT},
- ["localhost", ?IPV6_LOCAL_HOST]}}]),
- %% snmp:set_trace([gen_tcp, inet_tcp, prim_inet]),
+ ["localhost", ?IPV6_LOCAL_HOST]}},
+ {ipfamily, inet6fb4}]),
+
+ %% snmp:set_trace([gen_tcp]),
NewConfig.
@@ -291,25 +401,6 @@ finish(Config) ->
%% Test cases starts here.
%%-------------------------------------------------------------------------
-tickets(doc) ->
- ["."];
-tickets(suite) ->
- [
- hexed_query_otp_6191,
- empty_body_otp_6243,
- empty_response_header_otp_6830,
- transfer_encoding_otp_6807,
- proxy_not_modified_otp_6821,
- no_content_204_otp_6982,
- missing_CR_otp_7304,
- otp_7883,
- otp_8154,
- otp_8106,
- otp_8056,
- otp_8352,
- otp_8371,
- otp_8739
- ].
%%-------------------------------------------------------------------------
@@ -511,7 +602,7 @@ http_relaxed(Config) when is_list(Config) ->
DummyServerPid ! stop,
ok = httpc:set_options([{ipv6, enabled}]),
- %% ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ %% ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
@@ -529,7 +620,7 @@ http_dummy_pipe(Config) when is_list(Config) ->
test_pipeline(URL),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
http_inets_pipe(doc) ->
@@ -891,7 +982,7 @@ http_headers_dummy(Config) when is_list(Config) ->
], "text/plain", FooBar},
[], []),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
@@ -915,7 +1006,7 @@ http_bad_response(Config) when is_list(Config) ->
test_server:format("Wrong Statusline: ~p~n", [Reason]),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
@@ -1197,7 +1288,7 @@ http_redirect(Config) when is_list(Config) ->
tsp("http_redirect -> stop dummy server"),
DummyServerPid ! stop,
tsp("http_redirect -> reset ipfamily option (to inet6fb4)"),
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
tsp("http_redirect -> done"),
ok;
@@ -1221,7 +1312,7 @@ http_redirect_loop(Config) when is_list(Config) ->
{ok, {{_,300,_}, [_ | _], _}}
= httpc:request(get, {URL, []}, [], []),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
%%-------------------------------------------------------------------------
@@ -1255,7 +1346,7 @@ http_internal_server_error(Config) when is_list(Config) ->
ets:delete(unavailable),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
@@ -1282,7 +1373,7 @@ http_userinfo(Config) when is_list(Config) ->
httpc:request(get, {URLUnAuth, []}, [], []),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
@@ -1311,9 +1402,9 @@ http_cookie(Config) when is_list(Config) ->
ets:delete(cookie),
- ok = httpc:set_options([{cookies, disabled}, {ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{cookies, disabled}]),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
%%-------------------------------------------------------------------------
@@ -1683,7 +1774,7 @@ http_stream_once(Config) when is_list(Config) ->
p("http_stream_once -> stop dummy server", []),
DummyServerPid ! stop,
p("http_stream_once -> set ipfamily to inet6fb4", []),
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
p("http_stream_once -> done", []),
ok.
@@ -1806,6 +1897,8 @@ parse_url(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
+ipv6() ->
+ [{require,ipv6_hosts}].
ipv6(doc) ->
["Test ipv6."];
ipv6(suite) ->
@@ -1814,7 +1907,7 @@ ipv6(Config) when is_list(Config) ->
{ok, Hostname} = inet:gethostname(),
case lists:member(list_to_atom(Hostname),
- ?config(ipv6_hosts, Config)) of
+ ct:get_config(ipv6_hosts)) of
true ->
{DummyServerPid, Port} = dummy_server(self(), ipv6),
@@ -1887,7 +1980,7 @@ http_invalid_http(Config) when is_list(Config) ->
test_server:format("Parse error: ~p ~n", [Reason]),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
@@ -1941,7 +2034,7 @@ transfer_encoding_otp_6807(Config) when is_list(Config) ->
"/capital_transfer_encoding.html",
{ok, {{_,200,_}, [_|_], [_ | _]}} = httpc:request(URL),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
@@ -1973,7 +2066,7 @@ empty_response_header_otp_6830(Config) when is_list(Config) ->
URL = ?URL_START ++ integer_to_list(Port) ++ "/no_headers.html",
{ok, {{_,200,_}, [], [_ | _]}} = httpc:request(URL),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
@@ -1990,7 +2083,7 @@ no_content_204_otp_6982(Config) when is_list(Config) ->
URL = ?URL_START ++ integer_to_list(Port) ++ "/no_content.html",
{ok, {{_,204,_}, [], []}} = httpc:request(URL),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
@@ -2008,14 +2101,12 @@ missing_CR_otp_7304(Config) when is_list(Config) ->
URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_CR.html",
{ok, {{_,200,_}, _, [_ | _]}} = httpc:request(URL),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
%%-------------------------------------------------------------------------
-otp_7883(suite) ->
- [otp_7883_1, otp_7883_2].
otp_7883_1(doc) ->
["OTP-7883-sync"];
@@ -2030,7 +2121,7 @@ otp_7883_1(Config) when is_list(Config) ->
{error, socket_closed_remotely} = httpc:request(URL),
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
otp_7883_2(doc) ->
@@ -2057,14 +2148,12 @@ otp_7883_2(Config) when is_list(Config) ->
end,
DummyServerPid ! stop,
- ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ ok = httpc:set_options([{ipfamily, inet6fb4}]),
ok.
%%-------------------------------------------------------------------------
-otp_8154(suite) ->
- [otp_8154_1].
otp_8154_1(doc) ->
["OTP-8154"];
@@ -2344,12 +2433,6 @@ f(F, A) -> lists:flatten(io_lib:format(F,A)).
%%-------------------------------------------------------------------------
-otp_8106(suite) ->
- [
- otp_8106_pid,
- otp_8106_fun,
- otp_8106_mfa
- ].
otp_8106_pid(doc) ->
diff --git a/lib/inets/test/httpc_cookie_SUITE.erl b/lib/inets/test/httpc_cookie_SUITE.erl
index ad5df656c6..a9eddac6eb 100644
--- a/lib/inets/test/httpc_cookie_SUITE.erl
+++ b/lib/inets/test/httpc_cookie_SUITE.erl
@@ -19,11 +19,11 @@
%%
-module(httpc_cookie_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
%% Test server specific exports
--export([all/1, init_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, init_per_testcase/2, end_per_testcase/2]).
%% Test cases must be exported.
-export([session_cookies_only/1, netscape_cookies/1,
@@ -116,22 +116,29 @@ end_per_testcase(Case, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Describe the main purpose of this suite"];
-
-all(suite) ->
- [
- session_cookies_only,
- netscape_cookies,
- cookie_cancel,
- cookie_expires,
- persistent_cookie,
- domain_cookie,
- secure_cookie,
- update_cookie,
- update_cookie_session,
- cookie_attributes
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [session_cookies_only, netscape_cookies, cookie_cancel,
+ cookie_expires, persistent_cookie, domain_cookie,
+ secure_cookie, update_cookie, update_cookie_session,
+ cookie_attributes].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Test cases starts here.
%%--------------------------------------------------------------------
diff --git a/lib/inets/test/httpd_1_1.erl b/lib/inets/test/httpd_1_1.erl
index 055d034bec..2a6110e3ea 100644
--- a/lib/inets/test/httpd_1_1.erl
+++ b/lib/inets/test/httpd_1_1.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 3255cbec06..95ee15d08f 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -20,28 +20,17 @@
-module(httpd_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("test_server_line.hrl").
-include("inets_test_lib.hrl").
-include_lib("kernel/include/file.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([init_per_testcase/2, end_per_testcase/2,
init_per_suite/1, end_per_suite/1]).
-%% Test cases must be exported.
--export([
- ip/1,
- ssl/1, pssl/1, ossl/1, essl/1,
- http_1_1_ip/1,
- http_1_0_ip/1,
- http_0_9_ip/1,
- ipv6/1,
- tickets/1
- ]).
-
%% Core Server tests
-export([
ip_mod_alias/1,
@@ -249,19 +238,109 @@
%% Description: Returns documentation/test cases in this test suite
%% or a skip tuple if the platform is not supported.
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test the http server in the intes application."];
-all(suite) ->
- [
- ip,
- ssl,
- http_1_1_ip,
- http_1_0_ip,
- http_0_9_ip,
- %% ipv6,
- tickets
- ].
-
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, ip}, {group, ssl}, {group, http_1_1_ip},
+ {group, http_1_0_ip}, {group, http_0_9_ip},
+ {group, tickets}].
+
+groups() ->
+ [{ip, [],
+ [ip_mod_alias, ip_mod_actions, ip_mod_security,
+ ip_mod_auth, ip_mod_auth_api, ip_mod_auth_mnesia_api,
+ ip_mod_htaccess, ip_mod_cgi, ip_mod_esi, ip_mod_get,
+ ip_mod_head, ip_mod_all, ip_load_light, ip_load_medium,
+ ip_load_heavy, ip_dos_hostname, ip_time_test,
+ ip_restart_no_block, ip_restart_disturbing_block,
+ ip_restart_non_disturbing_block,
+ ip_block_disturbing_idle, ip_block_non_disturbing_idle,
+ ip_block_503, ip_block_disturbing_active,
+ ip_block_non_disturbing_active,
+ ip_block_disturbing_active_timeout_not_released,
+ ip_block_disturbing_active_timeout_released,
+ ip_block_non_disturbing_active_timeout_not_released,
+ ip_block_non_disturbing_active_timeout_released,
+ ip_block_disturbing_blocker_dies,
+ ip_block_non_disturbing_blocker_dies]},
+ {ssl, [],
+ [{group, pssl}, {group, ossl}, {group, essl}]},
+ {pssl, [],
+ [pssl_mod_alias, pssl_mod_actions, pssl_mod_security,
+ pssl_mod_auth, pssl_mod_auth_api,
+ pssl_mod_auth_mnesia_api, pssl_mod_htaccess,
+ pssl_mod_cgi, pssl_mod_esi, pssl_mod_get, pssl_mod_head,
+ pssl_mod_all, pssl_load_light, pssl_load_medium,
+ pssl_load_heavy, pssl_dos_hostname, pssl_time_test,
+ pssl_restart_no_block, pssl_restart_disturbing_block,
+ pssl_restart_non_disturbing_block,
+ pssl_block_disturbing_idle,
+ pssl_block_non_disturbing_idle, pssl_block_503,
+ pssl_block_disturbing_active,
+ pssl_block_non_disturbing_active,
+ pssl_block_disturbing_active_timeout_not_released,
+ pssl_block_disturbing_active_timeout_released,
+ pssl_block_non_disturbing_active_timeout_not_released,
+ pssl_block_non_disturbing_active_timeout_released,
+ pssl_block_disturbing_blocker_dies,
+ pssl_block_non_disturbing_blocker_dies]},
+ {ossl, [],
+ [ossl_mod_alias, ossl_mod_actions, ossl_mod_security,
+ ossl_mod_auth, ossl_mod_auth_api,
+ ossl_mod_auth_mnesia_api, ossl_mod_htaccess,
+ ossl_mod_cgi, ossl_mod_esi, ossl_mod_get, ossl_mod_head,
+ ossl_mod_all, ossl_load_light, ossl_load_medium,
+ ossl_load_heavy, ossl_dos_hostname, ossl_time_test,
+ ossl_restart_no_block, ossl_restart_disturbing_block,
+ ossl_restart_non_disturbing_block,
+ ossl_block_disturbing_idle,
+ ossl_block_non_disturbing_idle, ossl_block_503,
+ ossl_block_disturbing_active,
+ ossl_block_non_disturbing_active,
+ ossl_block_disturbing_active_timeout_not_released,
+ ossl_block_disturbing_active_timeout_released,
+ ossl_block_non_disturbing_active_timeout_not_released,
+ ossl_block_non_disturbing_active_timeout_released,
+ ossl_block_disturbing_blocker_dies,
+ ossl_block_non_disturbing_blocker_dies]},
+ {essl, [],
+ [essl_mod_alias, essl_mod_actions, essl_mod_security,
+ essl_mod_auth, essl_mod_auth_api,
+ essl_mod_auth_mnesia_api, essl_mod_htaccess,
+ essl_mod_cgi, essl_mod_esi, essl_mod_get, essl_mod_head,
+ essl_mod_all, essl_load_light, essl_load_medium,
+ essl_load_heavy, essl_dos_hostname, essl_time_test,
+ essl_restart_no_block, essl_restart_disturbing_block,
+ essl_restart_non_disturbing_block,
+ essl_block_disturbing_idle,
+ essl_block_non_disturbing_idle, essl_block_503,
+ essl_block_disturbing_active,
+ essl_block_non_disturbing_active,
+ essl_block_disturbing_active_timeout_not_released,
+ essl_block_disturbing_active_timeout_released,
+ essl_block_non_disturbing_active_timeout_not_released,
+ essl_block_non_disturbing_active_timeout_released,
+ essl_block_disturbing_blocker_dies,
+ essl_block_non_disturbing_blocker_dies]},
+ {http_1_1_ip, [],
+ [ip_host, ip_chunked, ip_expect, ip_range, ip_if_test,
+ ip_http_trace, ip_http1_1_head,
+ ip_mod_cgi_chunked_encoding_test]},
+ {http_1_0_ip, [],
+ [ip_head_1_0, ip_get_1_0, ip_post_1_0]},
+ {http_0_9_ip, [], [ip_get_0_9]},
+ {ipv6, [], [ipv6_hostname, ipv6_address]},
+ {tickets, [],
+ [ticket_5775, ticket_5865, ticket_5913, ticket_6003,
+ ticket_7304]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
%% Config - [tuple()]
@@ -615,219 +694,23 @@ end_per_testcase2(Case, Config) ->
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-ip(doc) ->
- ["HTTP tests using TCP/IP"];
-ip(suite) ->
- [
- ip_mod_alias,
- ip_mod_actions,
- ip_mod_security,
- ip_mod_auth,
- ip_mod_auth_api,
- ip_mod_auth_mnesia_api,
- ip_mod_htaccess,
- ip_mod_cgi,
- ip_mod_esi,
- ip_mod_get,
- ip_mod_head,
- ip_mod_all,
- ip_load_light,
- ip_load_medium,
- ip_load_heavy,
- ip_dos_hostname,
- ip_time_test,
- ip_restart_no_block,
- ip_restart_disturbing_block,
- ip_restart_non_disturbing_block,
- ip_block_disturbing_idle,
- ip_block_non_disturbing_idle,
- ip_block_503,
- ip_block_disturbing_active,
- ip_block_non_disturbing_active,
- ip_block_disturbing_active_timeout_not_released,
- ip_block_disturbing_active_timeout_released,
- ip_block_non_disturbing_active_timeout_not_released,
- ip_block_non_disturbing_active_timeout_released,
- ip_block_disturbing_blocker_dies,
- ip_block_non_disturbing_blocker_dies
- ].
%%-------------------------------------------------------------------------
-ssl(doc) ->
- ["HTTP test using SSL"];
-ssl(suite) ->
- [
- pssl,
- ossl,
- essl
- ].
-pssl(doc) ->
- ["HTTP test using SSL - using old way of configuring SSL"];
-pssl(suite) ->
- [
- pssl_mod_alias,
- pssl_mod_actions,
- pssl_mod_security,
- pssl_mod_auth,
- pssl_mod_auth_api,
- pssl_mod_auth_mnesia_api,
- pssl_mod_htaccess,
- pssl_mod_cgi,
- pssl_mod_esi,
- pssl_mod_get,
- pssl_mod_head,
- pssl_mod_all,
- pssl_load_light,
- pssl_load_medium,
- pssl_load_heavy,
- pssl_dos_hostname,
- pssl_time_test,
- pssl_restart_no_block,
- pssl_restart_disturbing_block,
- pssl_restart_non_disturbing_block,
- pssl_block_disturbing_idle,
- pssl_block_non_disturbing_idle,
- pssl_block_503,
- pssl_block_disturbing_active,
- pssl_block_non_disturbing_active,
- pssl_block_disturbing_active_timeout_not_released,
- pssl_block_disturbing_active_timeout_released,
- pssl_block_non_disturbing_active_timeout_not_released,
- pssl_block_non_disturbing_active_timeout_released,
- pssl_block_disturbing_blocker_dies,
- pssl_block_non_disturbing_blocker_dies
- ].
-ossl(doc) ->
- ["HTTP test using SSL - using new way of configuring usage of old SSL"];
-ossl(suite) ->
- [
- ossl_mod_alias,
- ossl_mod_actions,
- ossl_mod_security,
- ossl_mod_auth,
- ossl_mod_auth_api,
- ossl_mod_auth_mnesia_api,
- ossl_mod_htaccess,
- ossl_mod_cgi,
- ossl_mod_esi,
- ossl_mod_get,
- ossl_mod_head,
- ossl_mod_all,
- ossl_load_light,
- ossl_load_medium,
- ossl_load_heavy,
- ossl_dos_hostname,
- ossl_time_test,
- ossl_restart_no_block,
- ossl_restart_disturbing_block,
- ossl_restart_non_disturbing_block,
- ossl_block_disturbing_idle,
- ossl_block_non_disturbing_idle,
- ossl_block_503,
- ossl_block_disturbing_active,
- ossl_block_non_disturbing_active,
- ossl_block_disturbing_active_timeout_not_released,
- ossl_block_disturbing_active_timeout_released,
- ossl_block_non_disturbing_active_timeout_not_released,
- ossl_block_non_disturbing_active_timeout_released,
- ossl_block_disturbing_blocker_dies,
- ossl_block_non_disturbing_blocker_dies
- ].
-essl(doc) ->
- ["HTTP test using SSL - using new way of configuring usage of new SSL"];
-essl(suite) ->
- [
- essl_mod_alias,
- essl_mod_actions,
- essl_mod_security,
- essl_mod_auth,
- essl_mod_auth_api,
- essl_mod_auth_mnesia_api,
- essl_mod_htaccess,
- essl_mod_cgi,
- essl_mod_esi,
- essl_mod_get,
- essl_mod_head,
- essl_mod_all,
- essl_load_light,
- essl_load_medium,
- essl_load_heavy,
- essl_dos_hostname,
- essl_time_test,
- essl_restart_no_block,
- essl_restart_disturbing_block,
- essl_restart_non_disturbing_block,
- essl_block_disturbing_idle,
- essl_block_non_disturbing_idle,
- essl_block_503,
- essl_block_disturbing_active,
- essl_block_non_disturbing_active,
- essl_block_disturbing_active_timeout_not_released,
- essl_block_disturbing_active_timeout_released,
- essl_block_non_disturbing_active_timeout_not_released,
- essl_block_non_disturbing_active_timeout_released,
- essl_block_disturbing_blocker_dies,
- essl_block_non_disturbing_blocker_dies
- ].
%%-------------------------------------------------------------------------
-http_1_1_ip(doc) ->
- ["HTTP/1.1"];
-http_1_1_ip(suite) ->
- [
- ip_host,
- ip_chunked,
- ip_expect,
- ip_range,
- ip_if_test,
- ip_http_trace,
- ip_http1_1_head,
- ip_mod_cgi_chunked_encoding_test
- ].
%%-------------------------------------------------------------------------
-http_1_0_ip(doc) ->
- ["HTTP/1.0"];
-http_1_0_ip(suite) ->
- [
- ip_head_1_0,
- ip_get_1_0,
- ip_post_1_0
- ].
%%-------------------------------------------------------------------------
-http_0_9_ip(doc) ->
- ["HTTP/0.9"];
-http_0_9_ip(suite) ->
- [
- ip_get_0_9
- ].
%%-------------------------------------------------------------------------
-ipv6(doc) ->
- ["Tests ipv6 functionality."];
-ipv6(suite) ->
- [
- ipv6_hostname,
- ipv6_address
- ].
%%-------------------------------------------------------------------------
-tickets(doc) ->
- ["Test cases for reported bugs."];
-tickets(suite) ->
- [
- ticket_5775,
- ticket_5865,
- ticket_5913,
- ticket_6003,
- ticket_7304
- ].
%%-------------------------------------------------------------------------
ip_mod_alias(doc) ->
diff --git a/lib/inets/test/httpd_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl
index f86c1fcb49..dcea200a1a 100644
--- a/lib/inets/test/httpd_basic_SUITE.erl
+++ b/lib/inets/test/httpd_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -19,20 +19,26 @@
%%
-module(httpd_basic_SUITE).
--include("test_server.hrl").
--include("test_server_line.hrl").
+-include_lib("common_test/include/ct.hrl").
%% Note: This directive should only be used in test suites.
-compile(export_all).
-all(doc) ->
- ["Basic test of httpd."];
+-define(URL_START, "http://localhost:").
-all(suite) ->
- [
- uri_too_long_414,
- header_too_long_413
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [uri_too_long_414, header_too_long_413, escaped_url_in_error_body].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
@@ -131,6 +137,31 @@ header_too_long_413(Config) when is_list(Config) ->
{version, "HTTP/1.1"}]),
inets:stop(httpd, Pid).
+escaped_url_in_error_body(doc) ->
+ ["Test Url-encoding see OTP-8940"];
+escaped_url_in_error_body(suite) ->
+ [];
+escaped_url_in_error_body(Config) when is_list(Config) ->
+ HttpdConf = ?config(httpd_conf, Config),
+ {ok, Pid} = inets:start(httpd, [{port, 0} | HttpdConf]),
+ Info = httpd:info(Pid),
+ Port = proplists:get_value(port, Info),
+ Address = proplists:get_value(bind_address, Info),
+ Path = "/<b>this_is_bold<b>",
+ URL = ?URL_START ++ integer_to_list(Port) ++ Path,
+ EscapedPath = http_uri:encode(Path),
+ {ok, {404, Body}} = httpc:request(get, {URL, []},
+ [{url_encode, true}],
+ [{version, "HTTP/1.0"}, {full_result, false}]),
+ EscapedPath = find_URL_path(string:tokens(Body, " ")),
+ {ok, {404, Body1}} = httpc:request(get, {URL, []}, [],
+ [{version, "HTTP/1.0"}, {full_result, false}]),
+ EscapedPath = find_URL_path(string:tokens(Body1, " ")),
+ inets:stop(httpd, Pid).
-
-
+find_URL_path([]) ->
+ "";
+find_URL_path(["URL", URL | _]) ->
+ URL;
+find_URL_path([_ | Rest]) ->
+ find_URL_path(Rest).
diff --git a/lib/inets/test/httpd_load.erl b/lib/inets/test/httpd_load.erl
index 9bb9f9f94e..83520033dc 100644
--- a/lib/inets/test/httpd_load.erl
+++ b/lib/inets/test/httpd_load.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/inets/test/inets.cover b/lib/inets/test/inets.cover
new file mode 100644
index 0000000000..fd0ca41db3
--- /dev/null
+++ b/lib/inets/test/inets.cover
@@ -0,0 +1,2 @@
+{incl_app,inets,details}.
+
diff --git a/lib/inets/test/inets.spec b/lib/inets/test/inets.spec
index a9b4524295..ed102f8219 100644
--- a/lib/inets/test/inets.spec
+++ b/lib/inets/test/inets.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../inets_test"}}.
-{hosts, ["tuor"]}.
+{suites,"../inets_test",all}.
diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl
index 56983caace..8e3ba226b9 100644
--- a/lib/inets/test/inets_SUITE.erl
+++ b/lib/inets/test/inets_SUITE.erl
@@ -19,7 +19,7 @@
%%
-module(inets_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
-include("inets_test_lib.hrl").
@@ -28,25 +28,26 @@
-define(NUM_DEFAULT_SERVICES, 1).
-all(doc) ->
- ["Test suites for the inets application."];
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, app_test}, {group, appup_test},
+ {group, services_test}, httpd_reload].
+
+groups() ->
+ [{services_test, [],
+ [start_inets, start_httpc, start_httpd, start_ftpc,
+ start_tftpd]},
+ {app_test, [], [{inets_app_test, all}]},
+ {appup_test, [], [{inets_appup_test, all}]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [
- app_test,
- appup_test,
- services_test,
- httpd_reload
- ].
-services_test(suite) ->
- [
- start_inets,
- start_httpc,
- start_httpd,
- start_ftpc,
- start_tftpd
- ].
%%--------------------------------------------------------------------
@@ -100,11 +101,7 @@ end_per_testcase(_, Config) ->
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-app_test(suite) ->
- [{inets_app_test, all}].
-appup_test(suite) ->
- [{inets_appup_test, all}].
%%-------------------------------------------------------------------------
diff --git a/lib/inets/test/inets_app_test.erl b/lib/inets/test/inets_app_test.erl
index 6bdb9bb308..11b507fa26 100644
--- a/lib/inets/test/inets_app_test.erl
+++ b/lib/inets/test/inets_app_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -39,28 +39,31 @@ init_per_testcase(undef_funcs, Config) ->
init_per_testcase(_, Config) ->
Config.
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- fields,
- modules,
- exportall,
- app_depend,
- undef_funcs
- ],
- {req, [], {conf, app_init, Cases, app_fin}}.
+all() ->
+ [fields, modules, exportall, app_depend,
+ undef_funcs].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-app_init(suite) -> [];
-app_init(doc) -> [];
-app_init(Config) when is_list(Config) ->
+init_per_suite(suite) -> [];
+init_per_suite(doc) -> [];
+init_per_suite(Config) when is_list(Config) ->
case is_app(inets) of
{ok, AppFile} ->
io:format("AppFile: ~n~p~n", [AppFile]),
@@ -81,9 +84,9 @@ is_app(App) ->
end.
-app_fin(suite) -> [];
-app_fin(doc) -> [];
-app_fin(Config) when is_list(Config) ->
+end_per_suite(suite) -> [];
+end_per_suite(doc) -> [];
+end_per_suite(Config) when is_list(Config) ->
Config.
diff --git a/lib/inets/test/inets_appup_test.erl b/lib/inets/test/inets_appup_test.erl
index d580c6c4c5..7ed237243e 100644
--- a/lib/inets/test/inets_appup_test.erl
+++ b/lib/inets/test/inets_appup_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,40 +18,47 @@
%%
%%
%%----------------------------------------------------------------------
-%% Purpose: Verify the application specifics of the Megaco application
+%% Purpose: Verify the application specifics of the Inets application
%%----------------------------------------------------------------------
-module(inets_appup_test).
-compile(export_all).
+-compile({no_auto_import,[error/1]}).
-include("inets_test_lib.hrl").
-% t() -> megaco_test_lib:t(?MODULE).
-% t(Case) -> megaco_test_lib:t({?MODULE, Case}).
+ % t() -> megaco_test_lib:t(?MODULE).
+ % t(Case) -> megaco_test_lib:t({?MODULE, Case}).
%% Test server callbacks
init_per_testcase(_Case, Config) ->
Config.
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- appup
- ],
- {req, [], {conf, appup_init, Cases, appup_fin}}.
+all() ->
+ [appup].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-appup_init(suite) -> [];
-appup_init(doc) -> [];
-appup_init(Config) when is_list(Config) ->
+init_per_suite(suite) -> [];
+init_per_suite(doc) -> [];
+init_per_suite(Config) when is_list(Config) ->
AppFile = file_name(inets, ".app"),
AppupFile = file_name(inets, ".appup"),
[{app_file, AppFile}, {appup_file, AppupFile}|Config].
@@ -62,9 +69,9 @@ file_name(App, Ext) ->
filename:join([LibDir, "ebin", atom_to_list(App) ++ Ext]).
-appup_fin(suite) -> [];
-appup_fin(doc) -> [];
-appup_fin(Config) when is_list(Config) ->
+end_per_suite(suite) -> [];
+end_per_suite(doc) -> [];
+end_per_suite(Config) when is_list(Config) ->
Config.
diff --git a/lib/inets/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl
index 1e701bc074..fb29ab279f 100644
--- a/lib/inets/test/inets_sup_SUITE.erl
+++ b/lib/inets/test/inets_sup_SUITE.erl
@@ -20,22 +20,27 @@
-module(inets_sup_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
%% Note: This directive should only be used in test suites.
-compile(export_all).
-all(doc) ->
- ["Test that the inets supervisorstructur is the expected one."];
-all(suite) ->
- [
- default_tree,
- ftpc_worker,
- tftpd_worker,
- httpd_subtree,
- httpc_subtree
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [default_tree, ftpc_worker, tftpd_worker, httpd_subtree,
+ httpc_subtree].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl
index 86fc2d1a32..c56a714f5a 100644
--- a/lib/inets/test/inets_test_lib.erl
+++ b/lib/inets/test/inets_test_lib.erl
@@ -329,6 +329,9 @@ connect(ip_comm, Host, Port, Opts) ->
{error, eafnosupport} ->
tsp("eafnosupport opts: ~p", [Opts]),
connect(ip_comm, Host, Port, lists:delete(inet6, Opts));
+ {error, enetunreach} ->
+ tsp("eafnosupport opts: ~p", [Opts]),
+ connect(ip_comm, Host, Port, lists:delete(inet6, Opts));
{error, {enfile,_}} ->
tsp("Error enfile"),
{error, enfile};
diff --git a/lib/inets/test/tftp_SUITE.erl b/lib/inets/test/tftp_SUITE.erl
index 5768fff88b..79e9682ca4 100644
--- a/lib/inets/test/tftp_SUITE.erl
+++ b/lib/inets/test/tftp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -64,24 +64,34 @@ default_config() ->
init_per_testcase(Case, Config) ->
tftp_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) when is_list(Config) ->
- tftp_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) when is_list(Config) ->
+ tftp_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Test suites for TFTP."];
-
-all(suite) ->
- [
- simple,
- extra,
- reuse_connection,
- resend_client,
- resend_server
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [simple, extra, reuse_connection, resend_client,
+ resend_server].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Simple
diff --git a/lib/inets/test/tftp_test_lib.erl b/lib/inets/test/tftp_test_lib.erl
index 3729309b0e..e9b691828f 100644
--- a/lib/inets/test/tftp_test_lib.erl
+++ b/lib/inets/test/tftp_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -32,7 +32,7 @@ init_per_testcase(_Case, Config) when is_list(Config) ->
?IGNORE(application:stop(inets)),
Config.
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
?IGNORE(application:stop(inets)),
Config.
@@ -143,7 +143,7 @@ eval(Mod, Fun, Config) ->
Config2 = Mod:init_per_testcase(Fun, Config),
Pid = spawn_link(?MODULE, do_eval, [self(), Mod, Fun, Config2]),
R = wait_for_evaluator(Pid, Mod, Fun, Config2, []),
- Mod:fin_per_testcase(Fun, Config2),
+ Mod:end_per_testcase(Fun, Config2),
global:unregister_name(tftp_test_case_sup),
process_flag(trap_exit, Flag),
R.
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index 5eff9e4e3f..67737ee552 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -1,5 +1,24 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
APPLICATION = inets
-INETS_VSN = 5.5
+INETS_VSN = 5.5.2
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
diff --git a/lib/inviso/test/Makefile b/lib/inviso/test/Makefile
index 27fe99703a..cd372624b5 100644
--- a/lib/inviso/test/Makefile
+++ b/lib/inviso/test/Makefile
@@ -52,7 +52,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) inviso.spec $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) inviso.spec inviso.cover $(ERL_FILES) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/inviso/test/inviso.cover b/lib/inviso/test/inviso.cover
new file mode 100644
index 0000000000..e23b9fa59b
--- /dev/null
+++ b/lib/inviso/test/inviso.cover
@@ -0,0 +1,2 @@
+{incl_app,inviso,details}.
+
diff --git a/lib/inviso/test/inviso.spec b/lib/inviso/test/inviso.spec
index d655771d64..49f9b0b460 100644
--- a/lib/inviso/test/inviso.spec
+++ b/lib/inviso/test/inviso.spec
@@ -1 +1 @@
-{topcase, {dir, "../inviso_test"}}.
+{suites,"../inviso_test",all}.
diff --git a/lib/inviso/test/inviso_tool_SUITE.erl b/lib/inviso/test/inviso_tool_SUITE.erl
index 206e117c86..d59e3b5fa8 100644
--- a/lib/inviso/test/inviso_tool_SUITE.erl
+++ b/lib/inviso/test/inviso_tool_SUITE.erl
@@ -1,19 +1,21 @@
-% ``The contents of this file are subject to the Erlang Public License,
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
+%% retrieved online at http://www.erlang.org/.
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
-%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-%% AB. All Rights Reserved.''
-%%
-%% $Id$
+%%
+%% %CopyrightEnd%
+%%
%%
%% Description:
%% Test suite for the inviso_tool. It is here assumed that inviso works
@@ -26,20 +28,27 @@
-module(inviso_tool_SUITE).
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("kernel/include/file.hrl").
-define(l,?line).
-all(suite) ->
- [
- dist_basic_1,
- dist_rtc,
- dist_reconnect,
- dist_adopt,
- dist_history,
- dist_start_session_special
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [dist_basic_1, dist_rtc, dist_reconnect, dist_adopt,
+ dist_history, dist_start_session_special].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%% -----------------------------------------------------------------------------
init_per_suite(Config) ->
@@ -89,7 +98,7 @@ init_per_testcase(_Case,Config) ->
insert_timetraphandle_config(TH,NewConfig2).
%% -----------------------------------------------------------------------------
-fin_per_testcase(_Case,Config) ->
+end_per_testcase(_Case,Config) ->
?l test_server:stop_node(get_remotenode_config(inviso1,Config)),
?l test_server:stop_node(get_remotenode_config(inviso2,Config)),
?l test_server:timetrap_cancel(get_timetraphandle_config(Config)),
@@ -220,6 +229,10 @@ dist_basic_1(Config) when list(Config) ->
Nodes),
%% Start a test process at every node with a runtime component.
?l lists:foreach(fun(N)->spawn(N,?MODULE,test_proc_init,[]) end,Nodes),
+
+ %% Let the processes start
+ timer:sleep(100),
+
%% Find the pids of the test processes.
?l TestProcs=lists:map(fun(N)->rpc:call(N,erlang,whereis,[inviso_tool_test_proc]) end,
Nodes),
@@ -500,6 +513,10 @@ dist_rtc(Config) when is_list(Config) ->
Nodes),
%% Start a test process at every node with a runtime component.
?l lists:foreach(fun(N)->spawn(N,?MODULE,test_proc_init,[]) end,Nodes),
+
+ %% Let the processes start
+ timer:sleep(100),
+
%% Find the pids of the test processes.
?l TestProcs=lists:map(fun(N)->rpc:call(N,erlang,whereis,[inviso_tool_test_proc]) end,
Nodes),
@@ -553,6 +570,10 @@ dist_reconnect(Config) when list(Config) ->
?l start_inviso_tool_session(CNode,[],1,Nodes),
%% Start a test process at every node with a runtime component.
?l lists:foreach(fun(N)->spawn(N,?MODULE,test_proc_init,[]) end,Nodes),
+
+ %% Let the processes start
+ timer:sleep(100),
+
%% Find the pids of the test processes.
?l TestProcs=lists:map(fun(N)->rpc:call(N,erlang,whereis,[inviso_tool_test_proc]) end,
Nodes),
diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml
index a571de6916..879634561b 100644
--- a/lib/jinterface/doc/src/notes.xml
+++ b/lib/jinterface/doc/src/notes.xml
@@ -30,6 +30,22 @@
</header>
<p>This document describes the changes made to the Jinterface application.</p>
+<section><title>Jinterface 1.5.3.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The OtpMbox class did not have a hash() method, which it
+ should have because it overrides equals().</p>
+ <p>
+ Own Id: OTP-8854</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Jinterface 1.5.3.1</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
index ab0b299bf9..9ba6a4a0ab 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
@@ -1,7 +1,7 @@
/*
* %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
@@ -68,7 +68,6 @@ public abstract class AbstractConnection extends Thread {
protected static final int sendTag = 2;
protected static final int exitTag = 3;
protected static final int unlinkTag = 4;
- protected static final int nodeLinkTag = 5;
protected static final int regSendTag = 6;
protected static final int groupLeaderTag = 7;
protected static final int exit2Tag = 8;
@@ -697,7 +696,6 @@ public abstract class AbstractConnection extends Thread {
// absolutely no idea what to do with these, so we ignore
// them...
case groupLeaderTag: // { GROUPLEADER, FromPid, ToPid}
- case nodeLinkTag: // { NODELINK }
// (just show trace)
if (traceLevel >= ctrlThreshold) {
System.out.println("<- " + headerType(head) + " "
@@ -880,9 +878,6 @@ public abstract class AbstractConnection extends Thread {
case unlinkTag:
return "UNLINK";
- case nodeLinkTag:
- return "NODELINK";
-
case regSendTag:
return "REG_SEND";
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
index 80d8a5ccae..6f507bf4bb 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
@@ -1,7 +1,7 @@
/*
* %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
@@ -54,7 +54,6 @@ public class OtpMsg {
public static final int sendTag = 2;
public static final int exitTag = 3;
public static final int unlinkTag = 4;
- /* public static final int nodeLinkTag = 5; */
public static final int regSendTag = 6;
/* public static final int groupLeaderTag = 7; */
public static final int exit2Tag = 8;
diff --git a/lib/jinterface/test/Makefile b/lib/jinterface/test/Makefile
index 36955d1e91..ac9556c2f7 100644
--- a/lib/jinterface/test/Makefile
+++ b/lib/jinterface/test/Makefile
@@ -32,7 +32,8 @@ RELSYSDIR = $(RELEASE_PATH)/jinterface_test
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
-TEST_SPEC_FILE = jinterface.dynspec
+TEST_SPEC_FILE = jinterface.spec
+COVER_FILE = jinterface.cover
MODULES = nc_SUITE \
jinterface_SUITE
@@ -80,5 +81,5 @@ release_docs_spec:
release_tests_spec: tests
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(TEST_SPEC_FILE) $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(TEST_SPEC_FILE) $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/jinterface/test/jinterface.cover b/lib/jinterface/test/jinterface.cover
new file mode 100644
index 0000000000..d4edcd99d2
--- /dev/null
+++ b/lib/jinterface/test/jinterface.cover
@@ -0,0 +1,2 @@
+{incl_app,jinterface,details}.
+
diff --git a/lib/jinterface/test/jinterface.dynspec b/lib/jinterface/test/jinterface.spec
index 44712521df..99bc0f4005 100644
--- a/lib/jinterface/test/jinterface.dynspec
+++ b/lib/jinterface/test/jinterface.spec
@@ -17,16 +17,4 @@
%%
%% %CopyrightEnd%
%%
-%% You can test this file using this command.
-%% file:script("jinterface.dynspec", [{'Os',"Unix"}]).
-
-case case code:priv_dir(jinterface) of
- {error,bad_name} -> false;
- P -> filelib:is_dir(P) end of
- true ->
- [];
- false ->
- NoApp = "No jinterface application",
- [{skip,{nc_SUITE,NoApp}},
- {skip,{jinterface_SUITE,NoApp}}]
-end.
+{suites,"../jinterface_test",all}.
diff --git a/lib/jinterface/test/jinterface_SUITE.erl b/lib/jinterface/test/jinterface_SUITE.erl
index ea097680dd..e608bcb093 100644
--- a/lib/jinterface/test/jinterface_SUITE.erl
+++ b/lib/jinterface/test/jinterface_SUITE.erl
@@ -18,7 +18,8 @@
%%
-module(jinterface_SUITE).
--export([all/1, init_per_suite/1, end_per_suite/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
init_per_testcase/2, end_per_testcase/2]).
-export([nodename/1, register_and_whereis/1, get_names/1, boolean_atom/1,
@@ -31,13 +32,14 @@
erl_link_java_exit/1, java_link_erl_exit/1,
internal_link_linking_exits/1, internal_link_linked_exits/1,
internal_unlink_linking_exits/1, internal_unlink_linked_exits/1,
- normal_exit/1, kill_mbox/1, kill_erl_proc_from_java/1,
- kill_mbox_from_erlang/1, erl_exit_with_reason_any_term/1,
+ normal_exit/1, kill_mbox/1,kill_erl_proc_from_java/1,
+ kill_mbox_from_erlang/1,
+ erl_exit_with_reason_any_term/1,
java_exit_with_reason_any_term/1,
status_handler_localStatus/1, status_handler_remoteStatus/1,
status_handler_connAttempt/1]).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
-define(debug,true).
@@ -80,14 +82,21 @@
%%%-----------------------------------------------------------------
%%% INIT/END
%%%-----------------------------------------------------------------
-all(suite) ->
- lists:append([
- fundamental(),
- ping(),
- send_receive(),
- link_unlink(),
- status_handler()
- ]).
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ lists:append([fundamental(), ping(), send_receive(),
+ link_unlink(), status_handler()]).
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
fundamental() ->
[
@@ -154,11 +163,22 @@ status_handler() ->
init_per_suite(Config) when is_list(Config) ->
- jitu:init_all(Config).
+ case case code:priv_dir(jinterface) of
+ {error,bad_name} -> false;
+ P -> filelib:is_dir(P) end of
+ true ->
+ jitu:init_all(Config);
+ false ->
+ {skip,"No jinterface application"}
+ end.
end_per_suite(Config) when is_list(Config) ->
jitu:finish_all(Config).
+init_per_testcase(Case, _Config)
+ when Case =:= kill_mbox;
+ Case =:= kill_mbox_from_erlang ->
+ {skip, "Not yet implemented"};
init_per_testcase(_Case,Config) ->
Dog = ?t:timetrap({seconds,10}),
[{watch_dog,Dog}|Config].
diff --git a/lib/jinterface/test/nc_SUITE.erl b/lib/jinterface/test/nc_SUITE.erl
index 82dd3c2535..03f6f2036c 100644
--- a/lib/jinterface/test/nc_SUITE.erl
+++ b/lib/jinterface/test/nc_SUITE.erl
@@ -19,11 +19,11 @@
-module(nc_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
init_per_suite/1,
end_per_suite/1,
init_per_testcase/2,
@@ -50,30 +50,34 @@
%% Top of cases
-all(doc) -> [];
-all(suite) -> [pid_roundtrip,
- port_roundtrip,
- ref_roundtrip,
- new_float,
- old_stuff,
- binary_roundtrip,
- decompress_roundtrip,
- compress_roundtrip,
- integer_roundtrip,
- fun_roundtrip,
- lists_roundtrip,
- lists_roundtrip_2,
- lists_iterator,
- unicode,
- unicode_list_to_string,
- unicode_string_to_list,
- connect].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+all() ->
+ [pid_roundtrip, port_roundtrip, ref_roundtrip,
+ new_float, old_stuff, binary_roundtrip,
+ decompress_roundtrip, compress_roundtrip,
+ integer_roundtrip, fun_roundtrip, lists_roundtrip,
+ lists_roundtrip_2, lists_iterator, unicode,
+ unicode_list_to_string, unicode_string_to_list, connect].
+groups() ->
+ [].
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
init_per_suite(Config) when is_list(Config) ->
- jitu:init_all(Config).
+ case case code:priv_dir(jinterface) of
+ {error,bad_name} -> false;
+ P -> filelib:is_dir(P) end of
+ true ->
+ jitu:init_all(Config);
+ false ->
+ {skip,"No jinterface application"}
+ end.
end_per_suite(Config) ->
jitu:finish_all(Config).
diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk
index ed085b5d4d..24ffe7c5e6 100644
--- a/lib/jinterface/vsn.mk
+++ b/lib/jinterface/vsn.mk
@@ -1 +1 @@
-JINTERFACE_VSN = 1.5.3.1
+JINTERFACE_VSN = 1.5.3.2
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 2044b074ee..36fce464c5 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -36,6 +36,61 @@
other Erlang processes to continue executing in parallel with
the file operations. See the command line flag
<c>+A</c> in <seealso marker="erts:erl">erl(1)</seealso>.</p>
+
+ <p>The Erlang VM supports file names in Unicode to a limited
+ extent. Depending on how the VM is started (with the parameter
+ <c>+fnu</c> or <c>+fnl</c>), file names given can contain
+ characters > 255 and the VM system will convert file names
+ back and forth to the native file name encoding.</p>
+
+ <p>The default behavior for Unicode character translation depends
+ on to what extent the underlying OS/filesystem enforces consistent
+ naming. On OSes where all file names are ensured to be in one or
+ another encoding, Unicode is the default (currently this holds for
+ Windows and MacOSX). On OSes with completely transparent file
+ naming (i.e. all Unixes except MacOSX), ISO-latin-1 file naming is
+ the default. The reason for the ISO-latin-1 default is that
+ file names are not guaranteed to be possible to interpret according to
+ the Unicode encoding expected (i.e. UTF-8), and file names that
+ cannot be decoded will only be accessible by using &quot;raw
+ file names&quot;, in other word file names given as binaries.</p>
+
+ <p>As file names are traditionally not binaries in Erlang,
+ applications that need to handle raw file names need to be
+ converted, why the Unicode mode for file names is not default on
+ systems having completely transparent file naming.</p>
+
+ <note>As of R14B01, the most basic file handling modules
+ (<c>file</c>, <c>prim_file</c>, <c>filelib</c> and
+ <c>filename</c>) accept raw file names, but the rest of OTP is not
+ guaranteed to handle them, why Unicode file naming on systems
+ where it is not default is still considered experimental.</note>
+
+ <p>Raw file names is a new feature in OTP R14B01, which allows the
+ user to supply completely uninterpreted file names to the
+ underlying OS/filesystem. They are supplied as binaries, where it
+ is up to the user to supply a correct encoding for the
+ environment. The function <c>file:native_name_encoding()</c> can
+ be used to check what encoding the VM is working in. If the
+ function returns <c>latin1</c> file names are not in any way
+ converted to Unicode, if it is <c>utf8</c>, raw file names should
+ be encoded as UTF-8 if they are to follow the convention of the VM
+ (and usually the convention of the OS as well). Using raw
+ file names is useful if you have a filesystem with inconsistent
+ file naming, where some files are named in UTF-8 encoding while
+ others are not. A file:list_dir on such mixed file name systems
+ when the VM is in Unicode file name mode might return file names as
+ raw binaries as they cannot be interpreted as Unicode
+ file names. Raw file names can also be used to give UTF-8 encoded
+ file names even though the VM is not started in Unicode file name
+ translation mode.</p>
+
+ <p>Note that on Windows, <c>file:native_name_encoding()</c>
+ returns <c>utf8</c> per default, which is the format for raw
+ file names even on Windows, although the underlying OS specific
+ code works in a limited version of little endian UTF16. As far as
+ the Erlang programmer is concerned, Windows native Unicode format
+ is UTF-8...</p>
</description>
<section>
@@ -47,8 +102,14 @@ iodata() = iolist() | binary()
io_device()
as returned by file:open/2, a process handling IO protocols
-name() = string() | atom() | DeepList
+name() = string() | atom() | DeepList | RawFilename
DeepList = [char() | atom() | DeepList]
+ RawFilename = binary()
+ If VM is in unicode filename mode, string() and char() are allowed to be > 255.
+ RawFilename is a filename not subject to Unicode translation, meaning that it
+ can contain characters not conforming to the Unicode encoding expected from the
+ filesystem (i.e. non-UTF-8 characters although the VM is started in Unicode
+ filename mode).
posix()
an atom which is named from the POSIX error codes used in
@@ -598,13 +659,24 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
+ <name>native_name_encoding() -> latin1 | utf8</name>
+ <fsummary>Return the VM's configured filename encoding.</fsummary>
+ <desc>
+ <p>This function returns the configured default file name encoding to use for raw file names. Generally an application supplying file names raw (as binaries), should obey the character encoding returned by this function.</p>
+ <p>By default, the VM uses ISO-latin-1 file name encoding on filesystems and/or OSes that use completely transparent file naming. This includes all Unix versions except MacOSX, where the vfs layer enforces UTF-8 file naming. By giving the experimental option <c>+fnu</c> when starting Erlang, UTF-8 translation of file names can be turned on even for those systems. If Unicode file name translation is in effect, the system behaves as usual as long as file names conform to the encoding, but will return file names that are not properly encoded in UTF-8 as raw file names (i.e. binaries).</p>
+ <p>On Windows, this function also returns <c>utf8</c> by default. The OS uses a pure Unicode naming scheme and file names are always possible to interpret as valid Unicode. The fact that the underlying Windows OS actually encodes file names using little endian UTF-16 can be ignored by the Erlang programmer. Windows and MacOSX are the only operating systems where the VM operates in Unicode file name mode by default.</p>
+ </desc>
+ </func>
+ <func>
<name>open(Filename, Modes) -> {ok, IoDevice} | {error, Reason}</name>
<fsummary>Open a file</fsummary>
<type>
<v>Filename = name()</v>
<v>Modes = [Mode]</v>
- <v>&nbsp;Mode = read | write | append | exclusive | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed</v>
+ <v>&nbsp;Mode = read | write | append | exclusive | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed | {encoding, Encoding}</v>
<v>&nbsp;&nbsp;Size = Delay = int()</v>
+ <v>&nbsp;&nbsp;Encoding = latin1 | unicode | utf8 | utf16 | {utf16, Endian} | utf32 | {utf32, Endian}</v>
+ <v>&nbsp;&nbsp;&nbsp;&nbsp;Endian = big | little</v>
<v>IoDevice = io_device()</v>
<v>Reason = ext_posix() | system_limit</v>
</type>
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index 8e7192a496..aa171c77c2 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -74,6 +74,7 @@ posix()
socket()
as returned by accept/1,2 and connect/3,4</code>
+ <marker id="connect"></marker>
</section>
<funcs>
<func>
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index 2ae230152c..a22c0a8346 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -220,6 +220,69 @@ fe80::204:acff:fe17:bf38
<p>Returns the local hostname. Will never fail.</p>
</desc>
</func>
+
+ <func>
+ <name>getifaddrs() -> {ok,Iflist} | {error,posix}</name>
+ <fsummary>Return a list of interfaces and their addresses</fsummary>
+ <type>
+ <v>Iflist = {Ifname,[Ifopt]}</v>
+ <v>Ifname = string()</v>
+ <v>Ifopt = {flag,[Flag]} | {addr,Addr} | {netmask,Netmask}
+ | {broadaddr,Broadaddr} | {dstaddr,Dstaddr}
+ | {hwaddr,Hwaddr}</v>
+ <v>Flag = up | broadcast | loopback | pointtopoint
+ | running | multicast</v>
+ <v>Addr = Netmask = Broadadddr = Dstaddr = ip_address()</v>
+ <v>Hwaddr = [byte()]</v>
+ </type>
+ </func>
+ <desc>
+ <p>
+ Returns a list of 2-tuples containing interface names and the
+ interface's addresses. <c>Ifname</c> is a Unicode string.
+ <c>Hwaddr</c> is hardware dependent, e.g on Ethernet interfaces
+ it is the 6-byte Ethernet address (MAC address (EUI-48 address)).
+ </p>
+ <p>
+ The <c>{addr,Addr}</c>, <c>{netmask,_}</c> and <c>{broadaddr,_}</c>
+ tuples are repeated in the result list iff the interface has multiple
+ addresses. If you come across an interface that has
+ multiple <c>{flag,_}</c> or <c>{hwaddr,_}</c> tuples you have
+ a really strange interface or possibly a bug in this function.
+ The <c>{flag,_}</c> tuple is mandatory, all other optional.
+ </p>
+ <p>
+ Do not rely too much on the order of <c>Flag</c> atoms or
+ <c>Ifopt</c> tuples. There are some rules, though:
+ <list>
+ <item>
+ Immediately after <c>{addr,_}</c> follows <c>{netmask,_}</c>
+ </item>
+ <item>
+ Immediately thereafter follows <c>{broadaddr,_}</c> if
+ the <c>broadcast</c> flag is <em>not</em> set and the
+ <c>pointtopoint</c>flag <em>is</em> set.
+ </item>
+ <item>
+ Any <c>{netmask,_}</c>, <c>{broadaddr,_}</c> or
+ <c>{dstaddr,_}</c> tuples that follow an <c>{addr,_}</c>
+ tuple concerns that address.
+ </item>
+ </list>
+ </p>
+ <p>
+ The <c>{hwaddr,_}</c> tuple is not returned on Solaris since the
+ hardware address historically belongs to the link layer and only
+ the superuser can read such addresses.
+ </p>
+ <p>
+ On Windows, the data is fetched from quite different OS API
+ functions, so the <c>Netmask</c> and <c>Broadaddr</c>
+ values may be calculated, just as some <c>Flag</c> values.
+ You have been warned. Report flagrant bugs.
+ </p>
+ </desc>
+
<func>
<name>getopts(Socket, Options) -> {ok, OptionValues} | {error, posix()}</name>
<fsummary>Get one or more options for a socket</fsummary>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index 9859183390..29580a4cd1 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -30,6 +30,68 @@
</header>
<p>This document describes the changes made to the Kernel application.</p>
+<section><title>Kernel 2.14.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The Erlang VM now supports Unicode filenames. The feature
+ is turned on by default on systems where Unicode
+ filenames are mandatory (Windows and MacOSX), but can be
+ enabled on other systems with the '+fnu' emulator option.
+ Enabling the Unicode filename feature on systems where it
+ is not default is however considered experimental and not
+ to be used for production. Together with the Unicode file
+ name support, the concept of "raw filenames" is
+ introduced, which means filenames provided without
+ implicit unicode encoding translation. Raw filenames are
+ provided as binaries, not lists. For further information,
+ see stdlib users guide and the chapter about using
+ Unicode in Erlang. Also see the file module manual page.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8887</p>
+ </item>
+ <item>
+ <p>
+ There is now a new function inet:getifaddrs/0 modeled
+ after C library function getifaddrs() on BSD and LInux
+ that reports existing interfaces and their addresses on
+ the host. This replaces the undocumented and unsupported
+ inet:getiflist/0 and inet:ifget/2.</p>
+ <p>
+ Own Id: OTP-8926</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Kernel 2.14.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>In embedded mode, on_load handlers that called
+ <c>code:priv_dir/1</c> or other functions in <c>code</c>
+ would hang the system. Since the <c>crypto</c>
+ application now contains an on_loader handler that calls
+ <c>code:priv_dir/1</c>, including the <c>crypto</c>
+ application in the boot file would prevent the system
+ from starting.</p>
+ <p>Also extended the <c>-init_debug</c> option to print
+ information about on_load handlers being run to
+ facilitate debugging.</p>
+ <p>
+ Own Id: OTP-8902 Aux Id: seq11703 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Kernel 2.14.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index ec256d5806..feb5131aad 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -213,19 +213,20 @@ unstick_mod(Mod) when is_atom(Mod) -> call({unstick_mod,Mod}).
-spec is_sticky(Module :: atom()) -> boolean().
is_sticky(Mod) when is_atom(Mod) -> call({is_sticky,Mod}).
--spec set_path(Directories :: [file:filename()]) -> 'true' | {'error', term()}.
+-spec set_path(Directories :: [file:filename()]) ->
+ 'true' | {'error', 'bad_directory' | 'bad_path'}.
set_path(PathList) when is_list(PathList) -> call({set_path,PathList}).
-spec get_path() -> [file:filename()].
get_path() -> call(get_path).
--spec add_path(Directory :: file:filename()) -> 'true' | {'error', term()}.
+-spec add_path(Directory :: file:filename()) -> 'true' | {'error', 'bad_directory'}.
add_path(Dir) when is_list(Dir) -> call({add_path,last,Dir}).
--spec add_pathz(Directory :: file:filename()) -> 'true' | {'error', term()}.
+-spec add_pathz(Directory :: file:filename()) -> 'true' | {'error', 'bad_directory'}.
add_pathz(Dir) when is_list(Dir) -> call({add_path,last,Dir}).
--spec add_patha(Directory :: file:filename()) -> 'true' | {'error', term()}.
+-spec add_patha(Directory :: file:filename()) -> 'true' | {'error', 'bad_directory'}.
add_patha(Dir) when is_list(Dir) -> call({add_path,first,Dir}).
-spec add_paths(Directories :: [file:filename()]) -> 'ok'.
@@ -237,7 +238,6 @@ add_pathsz(Dirs) when is_list(Dirs) -> call({add_paths,last,Dirs}).
-spec add_pathsa(Directories :: [file:filename()]) -> 'ok'.
add_pathsa(Dirs) when is_list(Dirs) -> call({add_paths,first,Dirs}).
-%% XXX Contract's input argument differs from add_path/1 -- why?
-spec del_path(Name :: file:filename() | atom()) -> boolean() | {'error', 'bad_name'}.
del_path(Name) when is_list(Name) ; is_atom(Name) -> call({del_path,Name}).
@@ -286,6 +286,8 @@ do_start(Flags) ->
ets:module_info(module),
os:module_info(module),
+ binary:module_info(module),
+ unicode:module_info(module),
filename:module_info(module),
lists:module_info(module),
diff --git a/lib/kernel/src/error_handler.erl b/lib/kernel/src/error_handler.erl
index 17dd02acd4..885eeb2b0f 100644
--- a/lib/kernel/src/error_handler.erl
+++ b/lib/kernel/src/error_handler.erl
@@ -17,6 +17,11 @@
%% %CopyrightEnd%
%%
-module(error_handler).
+%% FIXME: remove no_native directive after HiPE has been changed to make
+%% remote calls link to the target's Export* like BEAM does.
+%% For a detailed explanation see the commit titled
+%% "error_handler: add no_native compiler directive"
+-compile(no_native).
%% A simple error handler.
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index cffe4e3db5..3aca9b4b0d 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -75,25 +75,34 @@
-define(RAM_FILE, ram_file). % Module
%% data types
--type filename() :: string().
+-type filename() :: string() | binary().
-type file_info() :: #file_info{}.
-type fd() :: #file_descriptor{}.
-type io_device() :: pid() | fd().
-type location() :: integer() | {'bof', integer()} | {'cur', integer()}
| {'eof', integer()} | 'bof' | 'cur' | 'eof'.
--type mode() :: 'read' | 'write' | 'append' | 'raw' | 'binary' |
- {'delayed_write', non_neg_integer(), non_neg_integer()} |
- 'delayed_write' | {'read_ahead', pos_integer()} |
- 'read_ahead' | 'compressed' | 'exclusive'.
--type name() :: string() | atom() | [name()].
--type posix() :: atom().
+-type mode() :: 'read' | 'write' | 'append'
+ | 'exclusive' | 'raw' | 'binary'
+ | {'delayed_write', non_neg_integer(), non_neg_integer()}
+ | 'delayed_write' | {'read_ahead', pos_integer()}
+ | 'read_ahead' | 'compressed'
+ | {'encoding', unicode:encoding()}.
+-type name() :: string() | atom() | [name()] | binary().
+-type posix() :: 'eacces' | 'eagain' | 'ebadf' | 'ebusy' | 'edquot'
+ | 'eexist' | 'efault' | 'efbig' | 'eintr' | 'einval'
+ | 'eio' | 'eisdir' | 'eloop' | 'emfile' | 'emlink'
+ | 'enametoolong'
+ | 'enfile' | 'enodev' | 'enoent' | 'enomem' | 'enospc'
+ | 'enotblk' | 'enotdir' | 'enotsup' | 'enxio' | 'eperm'
+ | 'epipe' | 'erofs' | 'espipe' | 'esrch' | 'estale'
+ | 'exdev'.
-type bindings() :: any().
-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'.
+-type posix_file_advise() :: 'normal' | 'sequential' | 'random'
+ | 'no_reuse' | 'will_need' | 'dont_need'.
%%%-----------------------------------------------------------------
%%% General functions
@@ -174,7 +183,7 @@ make_dir(Name) ->
del_dir(Name) ->
check_and_call(del_dir, [file_name(Name)]).
--spec read_file_info(Name :: name()) -> {'ok', #file_info{}} | {'error', posix()}.
+-spec read_file_info(Name :: name()) -> {'ok', file_info()} | {'error', posix()}.
read_file_info(Name) ->
check_and_call(read_file_info, [file_name(Name)]).
@@ -184,7 +193,7 @@ read_file_info(Name) ->
altname(Name) ->
check_and_call(altname, [file_name(Name)]).
--spec read_link_info(Name :: name()) -> {'ok', #file_info{}} | {'error', posix()}.
+-spec read_link_info(Name :: name()) -> {'ok', file_info()} | {'error', posix()}.
read_link_info(Name) ->
check_and_call(read_link_info, [file_name(Name)]).
@@ -194,7 +203,7 @@ read_link_info(Name) ->
read_link(Name) ->
check_and_call(read_link, [file_name(Name)]).
--spec write_file_info(Name :: name(), Info :: #file_info{}) ->
+-spec write_file_info(Name :: name(), Info :: file_info()) ->
'ok' | {'error', posix()}.
write_file_info(Name, Info = #file_info{}) ->
@@ -205,7 +214,8 @@ write_file_info(Name, Info = #file_info{}) ->
list_dir(Name) ->
check_and_call(list_dir, [file_name(Name)]).
--spec read_file(Name :: name()) -> {'ok', binary()} | {'error', posix()}.
+-spec read_file(Name :: name()) ->
+ {'ok', binary()} | {'error', posix() | 'terminated' | 'system_limit'}.
read_file(Name) ->
check_and_call(read_file, [file_name(Name)]).
@@ -220,17 +230,17 @@ make_link(Old, New) ->
make_symlink(Old, New) ->
check_and_call(make_symlink, [file_name(Old), file_name(New)]).
--spec write_file(Name :: name(), Bin :: binary()) -> 'ok' | {'error', posix()}.
+-spec write_file(Name :: name(), Bin :: iodata()) ->
+ 'ok' | {'error', posix() | 'terminated' | 'system_limit'}.
write_file(Name, Bin) ->
check_and_call(write_file, [file_name(Name), make_binary(Bin)]).
%% This whole operation should be moved to the file_server and prim_file
%% when it is time to change file server protocol again.
-%% Meanwhile, it is implemented here, slihtly less efficient.
-%%
+%% Meanwhile, it is implemented here, slightly less efficient.
--spec write_file(Name :: name(), Bin :: binary(), Modes :: [mode()]) ->
+-spec write_file(Name :: name(), Bin :: iodata(), Modes :: [mode()]) ->
'ok' | {'error', posix()}.
write_file(Name, Bin, ModeList) when is_list(ModeList) ->
@@ -286,7 +296,7 @@ raw_write_file_info(Name, #file_info{} = Info) ->
%% Contemporary mode specification - list of options
-spec open(Name :: name(), Modes :: [mode()]) ->
- {'ok', io_device()} | {'error', posix()}.
+ {'ok', io_device()} | {'error', posix() | 'system_limit'}.
open(Item, ModeList) when is_list(ModeList) ->
case lists:member(raw, ModeList) of
@@ -339,7 +349,7 @@ open(Item, Mode) ->
%%% The File argument must be either a Pid or a handle
%%% returned from ?PRIM_FILE:open.
--spec close(File :: io_device()) -> 'ok' | {'error', posix()}.
+-spec close(File :: io_device()) -> 'ok' | {'error', posix() | 'terminated'}.
close(File) when is_pid(File) ->
R = file_request(File, close),
@@ -358,7 +368,7 @@ close(_) ->
{error, badarg}.
-spec advise(File :: io_device(), Offset :: integer(),
- Length :: integer(), Advise :: posix_file_advise()) ->
+ Length :: integer(), Advise :: posix_file_advise()) ->
'ok' | {'error', posix()}.
advise(File, Offset, Length, Advise) when is_pid(File) ->
@@ -440,7 +450,7 @@ pread(_, _, _) ->
{error, badarg}.
-spec write(File :: io_device() | atom(), Byte :: iodata()) ->
- 'ok' | {'error', posix()}.
+ 'ok' | {'error', posix() | 'terminated'}.
write(File, Bytes) when (is_pid(File) orelse is_atom(File)) ->
case make_binary(Bytes) of
@@ -1024,22 +1034,26 @@ path_open_first([], _Name, _Mode, LastError) ->
%% Generates a flat file name from a deep list of atoms and
%% characters (integers).
+file_name(N) when is_binary(N) ->
+ N;
file_name(N) ->
try
- file_name_1(N)
+ file_name_1(N,file:native_name_encoding())
catch Reason ->
{error, Reason}
end.
-file_name_1([C|T]) when is_integer(C), C > 0, C =< 255 ->
- [C|file_name_1(T)];
-file_name_1([H|T]) ->
- file_name_1(H) ++ file_name_1(T);
-file_name_1([]) ->
+file_name_1([C|T],latin1) when is_integer(C), C < 256->
+ [C|file_name_1(T,latin1)];
+file_name_1([C|T],utf8) when is_integer(C) ->
+ [C|file_name_1(T,utf8)];
+file_name_1([H|T],E) ->
+ file_name_1(H,E) ++ file_name_1(T,E);
+file_name_1([],_) ->
[];
-file_name_1(N) when is_atom(N) ->
+file_name_1(N,_) when is_atom(N) ->
atom_to_list(N);
-file_name_1(_) ->
+file_name_1(_,_) ->
throw(badarg).
make_binary(Bin) when is_binary(Bin) ->
diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl
index 39dc32bb79..14da9c1a55 100644
--- a/lib/kernel/src/file_io_server.erl
+++ b/lib/kernel/src/file_io_server.erl
@@ -44,11 +44,11 @@ format_error(ErrorId) ->
erl_posix_msg:message(ErrorId).
start(Owner, FileName, ModeList)
- when is_pid(Owner), is_list(FileName), is_list(ModeList) ->
+ when is_pid(Owner), (is_list(FileName) orelse is_binary(FileName)), is_list(ModeList) ->
do_start(spawn, Owner, FileName, ModeList).
start_link(Owner, FileName, ModeList)
- when is_pid(Owner), is_list(FileName), is_list(ModeList) ->
+ when is_pid(Owner), (is_list(FileName) orelse is_binary(FileName)), is_list(ModeList) ->
do_start(spawn_link, Owner, FileName, ModeList).
%%%-----------------------------------------------------------------
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index 93d75321ba..327e0f93f1 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -25,6 +25,7 @@
%% socket
-export([peername/1, sockname/1, port/1, send/2,
setopts/2, getopts/2,
+ getifaddrs/0, getifaddrs/1,
getif/1, getif/0, getiflist/0, getiflist/1,
ifget/3, ifget/2, ifset/3, ifset/2,
getstat/1, getstat/2,
@@ -265,6 +266,17 @@ setopts(Socket, Opts) ->
getopts(Socket, Opts) ->
prim_inet:getopts(Socket, Opts).
+-spec getifaddrs(Socket :: socket()) ->
+ {'ok', [string()]} | {'error', posix()}.
+
+getifaddrs(Socket) ->
+ prim_inet:getifaddrs(Socket).
+
+-spec getifaddrs() -> {'ok', [string()]} | {'error', posix()}.
+
+getifaddrs() ->
+ withsocket(fun(S) -> prim_inet:getifaddrs(S) end).
+
-spec getiflist(Socket :: socket()) ->
{'ok', [string()]} | {'error', posix()}.
diff --git a/lib/kernel/src/inet6_tcp_dist.erl b/lib/kernel/src/inet6_tcp_dist.erl
index fab00bbb9f..b9c4fa607c 100644
--- a/lib/kernel/src/inet6_tcp_dist.erl
+++ b/lib/kernel/src/inet6_tcp_dist.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -162,8 +162,8 @@ do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
inet:getll(S)
end,
f_address = fun get_remote_id/2,
- mf_tick = {?MODULE, tick},
- mf_getstat = {?MODULE,getstat}
+ mf_tick = fun ?MODULE:tick/1,
+ mf_getstat = fun ?MODULE:getstat/1
},
dist_util:handshake_other_started(HSData);
{false,IP} ->
diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl
index cf357b7fba..6f1688c6a2 100644
--- a/lib/kernel/src/inet_int.hrl
+++ b/lib/kernel/src/inet_int.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -82,6 +82,7 @@
-define(INET_REQ_IFGET, 22).
-define(INET_REQ_IFSET, 23).
-define(INET_REQ_SUBSCRIBE, 24).
+-define(INET_REQ_GETIFADDRS, 25).
%% TCP requests
-define(TCP_REQ_ACCEPT, 40).
-define(TCP_REQ_LISTEN, 41).
diff --git a/lib/kernel/src/kernel.erl b/lib/kernel/src/kernel.erl
index 92ee7b441a..1e07620a3e 100644
--- a/lib/kernel/src/kernel.erl
+++ b/lib/kernel/src/kernel.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -143,6 +143,13 @@ init(safe) ->
Boot = start_boot_server(),
DiskLog = start_disk_log(),
Pg2 = start_pg2(),
+
+ %% Run the on_load handlers for all modules that have been
+ %% loaded so far. Running them at this point means that
+ %% on_load handlers can safely call kernel processes
+ %% (and in particular call code:priv_dir/1 or code:lib_dir/1).
+ init:run_on_load_handlers(),
+
{ok, {SupFlags, Boot ++ DiskLog ++ Pg2}}.
get_code_args() ->
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index f5e2820bbe..23db85e1f4 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -322,24 +322,19 @@ init({Name, LongOrShortNames, TickT}) ->
process_flag(priority, max),
Ticktime = to_integer(TickT),
Ticker = spawn_link(net_kernel, ticker, [self(), Ticktime]),
- case auth:get_cookie(Node) of
- Cookie when is_atom(Cookie) ->
- {ok, #state{name = Name,
- node = Node,
- type = LongOrShortNames,
- tick = #tick{ticker = Ticker, time = Ticktime},
- connecttime = connecttime(),
- connections =
- ets:new(sys_dist,[named_table,
- protected,
- {keypos, 2}]),
- listen = Listeners,
- allowed = [],
- verbose = 0
- }};
- _ELSE ->
- {stop, {error,{bad_cookie, Node}}}
- end;
+ {ok, #state{name = Name,
+ node = Node,
+ type = LongOrShortNames,
+ tick = #tick{ticker = Ticker, time = Ticktime},
+ connecttime = connecttime(),
+ connections =
+ ets:new(sys_dist,[named_table,
+ protected,
+ {keypos, 2}]),
+ listen = Listeners,
+ allowed = [],
+ verbose = 0
+ }};
Error ->
{stop, Error}
end.
diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl
index 75a11a8afd..95a2f71ec0 100644
--- a/lib/kernel/src/os.erl
+++ b/lib/kernel/src/os.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -82,8 +82,9 @@ verify_executable(Name0, [Ext|Rest], OrigExtensions) ->
end;
_ ->
case file:read_file_info(Name1) of
- {ok, #file_info{mode=Mode}} when Mode band 8#111 =/= 0 ->
- %% XXX This test for execution permission is not full-proof
+ {ok, #file_info{type=regular,mode=Mode}}
+ when Mode band 8#111 =/= 0 ->
+ %% XXX This test for execution permission is not fool-proof
%% on Unix, since we test if any execution bit is set.
{ok, Name1};
_ ->
@@ -230,9 +231,13 @@ start_port_srv(Request) ->
catch
error:_ -> false
end,
- start_port_srv_loop(Request, StayAlive).
+ start_port_srv_handle(Request),
+ case StayAlive of
+ true -> start_port_srv_loop();
+ false -> exiting
+ end.
-start_port_srv_loop({Ref,Client}, StayAlive) ->
+start_port_srv_handle({Ref,Client}) ->
Reply = try open_port({spawn, ?SHELL},[stream]) of
Port when is_port(Port) ->
(catch port_connect(Port, Client)),
@@ -242,20 +247,18 @@ start_port_srv_loop({Ref,Client}, StayAlive) ->
error:Reason ->
{Reason,erlang:get_stacktrace()}
end,
- Client ! {Ref,Reply},
- case StayAlive of
- true -> start_port_srv_loop(get_open_port_request(), true);
- false -> exiting
- end.
+ Client ! {Ref,Reply}.
-get_open_port_request() ->
+
+start_port_srv_loop() ->
receive
{Ref, Client} = Request when is_reference(Ref),
is_pid(Client) ->
- Request;
+ start_port_srv_handle(Request);
_Junk ->
- get_open_port_request()
- end.
+ ignore
+ end,
+ start_port_srv_loop().
%%
%% unix_get_data(Port) -> Result
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index 293c368e2a..5f8f3a6bf6 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -51,6 +51,7 @@ MODULES= \
error_logger_SUITE \
error_logger_warn_SUITE \
file_SUITE \
+ file_name_SUITE \
prim_file_SUITE \
ram_file_SUITE \
gen_tcp_api_SUITE \
@@ -141,7 +142,7 @@ release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(APP_FILES) $(RELSYSDIR)
- $(INSTALL_DATA) kernel.dynspec $(EMAKEFILE)\
+ $(INSTALL_DATA) kernel.spec $(EMAKEFILE)\
$(COVERFILE) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/kernel/test/appinc1.erl b/lib/kernel/test/appinc1.erl
index 8456b0eac2..343fefb25c 100644
--- a/lib/kernel/test/appinc1.erl
+++ b/lib/kernel/test/appinc1.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/appinc1x.erl b/lib/kernel/test/appinc1x.erl
index 2e177727f2..8c144676ac 100644
--- a/lib/kernel/test/appinc1x.erl
+++ b/lib/kernel/test/appinc1x.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/appinc2.erl b/lib/kernel/test/appinc2.erl
index e41d58bb71..d2e0305109 100644
--- a/lib/kernel/test/appinc2.erl
+++ b/lib/kernel/test/appinc2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/appinc2A.erl b/lib/kernel/test/appinc2A.erl
index b51a1f5035..604e31e3d3 100644
--- a/lib/kernel/test/appinc2A.erl
+++ b/lib/kernel/test/appinc2A.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/appinc2B.erl b/lib/kernel/test/appinc2B.erl
index cafb061ae3..abb60010aa 100644
--- a/lib/kernel/test/appinc2B.erl
+++ b/lib/kernel/test/appinc2B.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/appinc2top.erl b/lib/kernel/test/appinc2top.erl
index 5bd19a59e7..5a8d0d6687 100644
--- a/lib/kernel/test/appinc2top.erl
+++ b/lib/kernel/test/appinc2top.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl
index 313b50f976..2912735368 100644
--- a/lib/kernel/test/application_SUITE.erl
+++ b/lib/kernel/test/application_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,9 +18,11 @@
%%
-module(application_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1, failover/1, failover_comp/1, permissions/1, load/1, reported_bugs/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ failover/1, failover_comp/1, permissions/1, load/1,
load_use_cache/1,
otp_1586/1, otp_2078/1, otp_2012/1, otp_2718/1, otp_2973/1,
otp_3002/1, otp_3184/1, otp_4066/1, otp_4227/1, otp_5363/1,
@@ -30,23 +32,46 @@
nodedown_start/1, init2973/0, loop2973/0, loop5606/1]).
-export([config_change/1,
- distr_changed/1, distr_changed_tc1/1, distr_changed_tc2/1,
+ distr_changed_tc1/1, distr_changed_tc2/1,
shutdown_func/1, do_shutdown/1]).
-define(TESTCASE, testcase_name).
-define(testcase, ?config(?TESTCASE, Config)).
--export([init_per_testcase/2, fin_per_testcase/2, start_type/0,
+-export([init_per_testcase/2, end_per_testcase/2, start_type/0,
start_phase/0, conf_change/0]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(2)).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[failover, failover_comp, permissions, load,
- load_use_cache, reported_bugs,
- start_phases, script_start, nodedown_start,
- permit_false_start_local, permit_false_start_dist,
- get_key, distr_changed, config_change, shutdown_func].
+ load_use_cache, {group, reported_bugs}, start_phases,
+ script_start, nodedown_start, permit_false_start_local,
+ permit_false_start_dist, get_key,
+ {group, distr_changed}, config_change, shutdown_func].
+
+groups() ->
+ [{reported_bugs, [],
+ [otp_1586, otp_2078, otp_2012, otp_2718, otp_2973,
+ otp_3002, otp_3184, otp_4066, otp_4227, otp_5363,
+ otp_5606]},
+ {distr_changed, [],
+ [distr_changed_tc1, distr_changed_tc2]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(otp_2973=Case, Config) ->
@@ -57,12 +82,12 @@ init_per_testcase(Case, Config) ->
?line Dog = test_server:timetrap(?default_timeout),
[{?TESTCASE, Case}, {watchdog, Dog}|Config].
-fin_per_testcase(otp_2973, Config) ->
+end_per_testcase(otp_2973, Config) ->
code:del_path(?config(data_dir,Config)),
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok;
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -932,9 +957,6 @@ nodedown_start(Conf) when is_list(Conf) ->
%%%-----------------------------------------------------------------
%%% Testing of reported bugs and other tickets.
%%%-----------------------------------------------------------------
-reported_bugs(suite) -> [otp_1586, otp_2078, otp_2012, otp_2718,
- otp_2973, otp_3002, otp_3184, otp_4066,
- otp_4227, otp_5363, otp_5606].
%%-----------------------------------------------------------------
%% Ticket: OTP-1586
@@ -1589,7 +1611,6 @@ get_key(Conf) when is_list(Conf) ->
%%%-----------------------------------------------------------------
%%% Testing of change of distributed parameter.
%%%-----------------------------------------------------------------
-distr_changed(suite) -> [distr_changed_tc1, distr_changed_tc2].
distr_changed_tc1(suite) -> [];
distr_changed_tc1(doc) -> ["Test change of distributed parameter."];
diff --git a/lib/kernel/test/bif_SUITE.erl b/lib/kernel/test/bif_SUITE.erl
index ae2a3a08ff..173051b693 100644
--- a/lib/kernel/test/bif_SUITE.erl
+++ b/lib/kernel/test/bif_SUITE.erl
@@ -17,15 +17,16 @@
%% %CopyrightEnd%
%%
-module(bif_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
--export([spawn_tests/1,
+-export([
spawn1/1, spawn2/1, spawn3/1, spawn4/1,
- spawn_link_tests/1,
+
spawn_link1/1, spawn_link2/1, spawn_link3/1, spawn_link4/1,
- spawn_opt_tests/1,
+
spawn_opt2/1, spawn_opt3/1, spawn_opt4/1, spawn_opt5/1,
spawn_failures/1,
@@ -33,9 +34,9 @@
run_fun/1,
wilderness/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -43,25 +44,36 @@
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [spawn_tests, spawn_link_tests, spawn_opt_tests, spawn_failures, wilderness].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-spawn_tests(doc) -> ["Test spawn"];
-spawn_tests(suite) ->
- [spawn1, spawn2, spawn3, spawn4].
+all() ->
+ [{group, spawn_tests}, {group, spawn_link_tests},
+ {group, spawn_opt_tests}, spawn_failures, wilderness].
-spawn_link_tests(doc) -> ["Test spawn_link"];
-spawn_link_tests(suite) ->
- [spawn_link1, spawn_link2, spawn_link3, spawn_link4].
+groups() ->
+ [{spawn_tests, [], [spawn1, spawn2, spawn3, spawn4]},
+ {spawn_link_tests, [],
+ [spawn_link1, spawn_link2, spawn_link3, spawn_link4]},
+ {spawn_opt_tests, [],
+ [spawn_opt2, spawn_opt3, spawn_opt4, spawn_opt5]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-spawn_opt_tests(doc) -> ["Test spawn_opt"];
-spawn_opt_tests(suite) ->
- [spawn_opt2, spawn_opt3, spawn_opt4, spawn_opt5].
spawn1(doc) -> ["Test spawn/1"];
spawn1(suite) ->
diff --git a/lib/kernel/test/ch.erl b/lib/kernel/test/ch.erl
index 25d1b4354c..25d6f6d200 100644
--- a/lib/kernel/test/ch.erl
+++ b/lib/kernel/test/ch.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/ch_sup.erl b/lib/kernel/test/ch_sup.erl
index 9d03628839..4c923b2909 100644
--- a/lib/kernel/test/ch_sup.erl
+++ b/lib/kernel/test/ch_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/cleanup.erl b/lib/kernel/test/cleanup.erl
index 831ceba8f5..01db1e9124 100644
--- a/lib/kernel/test/cleanup.erl
+++ b/lib/kernel/test/cleanup.erl
@@ -18,11 +18,22 @@
%%
-module(cleanup).
--export([all/1, cleanup/1]).
+-export([all/0,groups/0,init_per_group/2,end_per_group/2, cleanup/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+all() ->
+ [cleanup].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> {req, [kernel], [cleanup]}.
cleanup(suite) -> [];
cleanup(_) ->
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index c9437df258..7b1e4fc522 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -18,9 +18,9 @@
%%
-module(code_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([set_path/1, get_path/1, add_path/1, add_paths/1, del_path/1,
replace_path/1, load_file/1, load_abs/1, ensure_loaded/1,
delete/1, purge/1, soft_purge/1, is_loaded/1, all_loaded/1,
@@ -31,9 +31,10 @@
where_is_file_cached/1, where_is_file_no_cache/1,
purge_stacktrace/1, mult_lib_roots/1, bad_erl_libs/1,
code_archive/1, code_archive2/1, on_load/1,
+ big_boot_embedded/1,
on_load_embedded/1, on_load_errors/1, native_early_modules/1]).
--export([init_per_testcase/2, fin_per_testcase/2,
+-export([init_per_testcase/2, end_per_testcase/2,
init_per_suite/1, end_per_suite/1,
sticky_compiler/1]).
@@ -42,18 +43,29 @@
handle_event/2, handle_call/2, handle_info/2,
terminate/2]).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[set_path, get_path, add_path, add_paths, del_path,
replace_path, load_file, load_abs, ensure_loaded,
delete, purge, soft_purge, is_loaded, all_loaded,
load_binary, dir_req, object_code, set_path_file,
- pa_pz_option, add_del_path,
- dir_disappeared, ext_mod_dep, clash,
- load_cached, start_node_with_cache, add_and_rehash,
- where_is_file_no_cache, where_is_file_cached,
- purge_stacktrace, mult_lib_roots, bad_erl_libs,
- code_archive, code_archive2, on_load, on_load_embedded,
- on_load_errors, native_early_modules].
+ pa_pz_option, add_del_path, dir_disappeared,
+ ext_mod_dep, clash, load_cached, start_node_with_cache,
+ add_and_rehash, where_is_file_no_cache,
+ where_is_file_cached, purge_stacktrace, mult_lib_roots,
+ bad_erl_libs, code_archive, code_archive2, on_load,
+ on_load_embedded, big_boot_embedded, on_load_errors,
+ native_early_modules].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
init_per_suite(Config) ->
%% The compiler will no longer create a Beam file if
@@ -74,7 +86,18 @@ init_per_testcase(_Func, Config) ->
P=code:get_path(),
P=code:get_path(),
[{watchdog, Dog}, {code_path, P}|Config].
-fin_per_testcase(_Func, Config) ->
+
+end_per_testcase(TC, Config) when TC == mult_lib_roots;
+ TC == big_boot_embedded ->
+ {ok, HostName} = inet:gethostname(),
+ NodeName = list_to_atom(atom_to_list(TC)++"@"++HostName),
+ ?t:stop_node(NodeName),
+ end_per_testcase(Config);
+end_per_testcase(_Func, Config) ->
+ end_per_testcase(Config).
+
+end_per_testcase(Config) ->
+ code:purge(code_b_test),
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog),
P=?config(code_path, Config),
@@ -584,13 +607,21 @@ clash(Config) when is_list(Config) ->
TmpEzFile = Priv++"foobar-0.tmp.ez",
?line {ok, _} = file:copy(DDir++"foobar-0.1.ez", TmpEzFile),
?line true = code:add_path(TmpEzFile++"/foobar-0.1/ebin"),
- ?line ok = file:delete(TmpEzFile),
+ case os:type() of
+ {win32,_} ->
+ %% The file wont be deleted on windows until it's closed, why we
+ %% need to rename instead.
+ ?line ok = file:rename(TmpEzFile,TmpEzFile++".moved");
+ _ ->
+ ?line ok = file:delete(TmpEzFile)
+ end,
test_server:capture_start(),
?line ok = code:clash(),
test_server:capture_stop(),
?line [BadPathMsg|_] = test_server:capture_get(),
?line true = lists:prefix("** Bad path can't read", BadPathMsg),
?line true = code:set_path(P),
+ file:delete(TmpEzFile++".moved"), %% Only effect on windows
ok.
ext_mod_dep(suite) ->
@@ -635,7 +666,7 @@ analyse([], [This={M,F,A}|Path], Visited, ErrCnt0) ->
%% These modules should be loaded by code.erl before
%% the code_server is started.
OK = [erlang, os, prim_file, erl_prim_loader, init, ets,
- code_server, lists, lists_sort, filename, packages,
+ code_server, lists, lists_sort, unicode, binary, filename, packages,
gb_sets, gb_trees, hipe_unified_loader, hipe_bifs,
prim_zip, zlib],
ErrCnt1 =
@@ -664,6 +695,22 @@ analyse2(MFA={_,_,_}, Path, Visited0) ->
%%%% We need to check these manually...
% fun's are ok as long as they are defined locally.
check_funs({'$M_EXPR','$F_EXPR',_},
+ [{unicode,characters_to_binary_int,3},
+ {unicode,characters_to_binary,3},
+ {filename,filename_string_to_binary,1}|_]) -> 0;
+check_funs({'$M_EXPR','$F_EXPR',_},
+ [{unicode,ml_map,3},
+ {unicode,characters_to_binary_int,3},
+ {unicode,characters_to_binary,3},
+ {filename,filename_string_to_binary,1}|_]) -> 0;
+check_funs({'$M_EXPR','$F_EXPR',_},
+ [{unicode,do_o_binary2,2},
+ {unicode,do_o_binary,2},
+ {unicode,o_trans,1},
+ {unicode,characters_to_binary_int,3},
+ {unicode,characters_to_binary,3},
+ {filename,filename_string_to_binary,1}|_]) -> 0;
+check_funs({'$M_EXPR','$F_EXPR',_},
[{code_server,load_native_code,4},
{code_server,load_native_code_1,2},
{code_server,load_native_code,2},
@@ -880,6 +927,8 @@ add_and_rehash(Config) when is_list(Config) ->
?line true = rpc:call(Node, code, add_path, [OkDir]),
?line {error,_} = rpc:call(Node, code, add_path, [BadDir]),
?line ok = rpc:call(Node, code, rehash, []),
+
+ ?t:stop_node(Node),
ok.
where_is_file_no_cache(suite) ->
@@ -981,9 +1030,9 @@ mult_lib_roots(Config) when is_list(Config) ->
?t:start_node(mult_lib_roots, slave,
[{args,"-env ERL_LIBS "++ErlLibs}]),
- ?line {ok,Cwd} = file:get_cwd(),
+ ?line TSPath = filename:dirname(code:which(test_server)),
?line Path0 = rpc:call(Node, code, get_path, []),
- ?line [Cwd,"."|Path1] = Path0,
+ ?line [TSPath,"."|Path1] = Path0,
?line [Kernel|Path2] = Path1,
?line [Stdlib|Path3] = Path2,
?line mult_lib_verify_lib(Kernel, "kernel"),
@@ -1002,7 +1051,6 @@ mult_lib_roots(Config) when is_list(Config) ->
?line true = rpc:call(Node, code_SUITE_mult_root_module, works_fine, []),
- ?line ?t:stop_node(Node),
ok.
mult_lib_compile(Root, Last) ->
@@ -1145,6 +1193,22 @@ compile_files([File | Files], SrcDir, OutDir) ->
compile_files([], _, _) ->
ok.
+big_boot_embedded(suite) ->
+ [];
+big_boot_embedded(doc) ->
+ ["Test that a boot file with (almost) all of OTP can be used to start an"
+ " embeddedd system."];
+big_boot_embedded(Config) when is_list(Config) ->
+ ?line {BootArg,AppsInBoot} = create_big_boot(Config),
+ ?line {ok, Node} =
+ ?t:start_node(big_boot_embedded, slave,
+ [{args,"-boot "++BootArg++" -mode embedded"}]),
+ ?line RemoteNodeApps =
+ [ {X,Y} || {X,_,Y} <-
+ rpc:call(Node,application,loaded_applications,[]) ],
+ ?line true = lists:sort(AppsInBoot) =:= lists:sort(RemoteNodeApps),
+ ok.
+
on_load(Config) when is_list(Config) ->
Master = on_load_test_case_process,
@@ -1226,7 +1290,8 @@ on_load_embedded_1(Config) ->
?line LibRoot = code:lib_dir(),
?line LinkName = filename:join(LibRoot, "on_load_app-1.0"),
?line OnLoadApp = filename:join(DataDir, "on_load_app-1.0"),
- ?line file:delete(LinkName),
+ ?line del_link(LinkName),
+ io:format("LinkName :~p, OnLoadApp: ~p~n",[LinkName,OnLoadApp]),
case file:make_symlink(OnLoadApp, LinkName) of
{error,enotsup} ->
throw({skip,"Support for symlinks required"});
@@ -1255,7 +1320,15 @@ on_load_embedded_1(Config) ->
%% Clean up.
?line stop_node(Node),
- ?line ok = file:delete(LinkName).
+ ?line ok = del_link(LinkName).
+
+del_link(LinkName) ->
+ case file:delete(LinkName) of
+ {error,eperm} ->
+ file:del_dir(LinkName);
+ Other ->
+ Other
+ end.
create_boot(Config, Options) ->
?line {ok, OldDir} = file:get_cwd(),
@@ -1281,6 +1354,73 @@ create_script(Config) ->
?line file:close(Fd),
{filename:dirname(Name),filename:basename(Name)}.
+create_big_boot(Config) ->
+ ?line {ok, OldDir} = file:get_cwd(),
+ ?line {Options,Local} = case is_source_dir() of
+ true -> {[no_module_tests,local],true};
+ _ -> {[no_module_tests],false}
+ end,
+ ?line {LatestDir,LatestName,Apps} = create_big_script(Config,Local),
+ ?line ok = file:set_cwd(LatestDir),
+ ?line ok = systools:make_script(LatestName, Options),
+ ?line ok = file:set_cwd(OldDir),
+ {filename:join(LatestDir, LatestName),Apps}.
+
+% The following apps cannot be loaded
+% hipe .app references (or can reference) files that have no
+% corresponding beam file (if hipe is not enabled)
+filter_app("hipe",_) ->
+ false;
+% Dialyzer and typer depends on hipe
+filter_app("dialyzer",_) ->
+ false;
+filter_app("typer",_) ->
+ false;
+% Orber requires explicit configuration
+filter_app("orber",_) ->
+ false;
+% cos* depends on orber
+filter_app("cos"++_,_) ->
+ false;
+% ic has a mod instruction in the app file but no corresponding start function
+filter_app("ic",_) ->
+ false;
+% Netconf has some dependency that I really do not understand (maybe like orber)
+filter_app("netconf",_) ->
+ false;
+% Safe has the same kind of error in the .app file as ic
+filter_app("safe",_) ->
+ false;
+% OS_mon does not find it's port program when running cerl
+filter_app("os_mon",true) ->
+ false;
+% Other apps should be OK.
+filter_app(_,_) ->
+ true.
+create_big_script(Config,Local) ->
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Name = filename:join(PrivDir,"full_script_test"),
+ ?line InitialApplications=application:loaded_applications(),
+ %% Applications left loaded by the application suite, unload them!
+ ?line UnloadFix=[app0,app1,app2,group_leader,app_start_error],
+ ?line [application:unload(Leftover) ||
+ Leftover <- UnloadFix,
+ lists:keymember(Leftover,1,InitialApplications) ],
+ %% Now we should have only "real" applications...
+ ?line [application:load(list_to_atom(Y)) || {match,[Y]} <- [ re:run(X,code:lib_dir()++"/"++"([^/-]*).*/ebin",[{capture,[1],list}]) || X <- code:get_path()],filter_app(Y,Local)],
+ ?line Apps = [ {N,V} || {N,_,V} <- application:loaded_applications()],
+ ?line {ok,Fd} = file:open(Name ++ ".rel", write),
+ ?line io:format(Fd,
+ "{release, {\"Test release 3\", \"P2A\"}, \n"
+ " {erts, \"9.42\"}, \n"
+ " ~p}.\n",
+ [Apps]),
+ ?line file:close(Fd),
+ ?line NewlyLoaded =
+ application:loaded_applications() -- InitialApplications,
+ ?line [ application:unload(N) || {N,_,_} <- NewlyLoaded],
+ {filename:dirname(Name),filename:basename(Name),Apps}.
+
is_source_dir() ->
filename:basename(code:lib_dir(kernel)) =:= "kernel" andalso
filename:basename(code:lib_dir(stdlib)) =:= "stdlib".
diff --git a/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl b/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl
index a39332f81d..646921026d 100644
--- a/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl
+++ b/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl
@@ -3,6 +3,15 @@
-on_load(run_me/0).
run_me() ->
+ %% An onload handler typically calls code:priv_dir/1
+ %% or code:lib_dir/1, so make sure that it works.
+ LibDir = code:lib_dir(on_load_app),
+ PrivDir = code:priv_dir(on_load_app),
+ LibDir = filename:dirname(PrivDir),
+ ModPath = filename:join(filename:split(code:which(?MODULE))),
+ LibDir = filename:dirname(filename:dirname(ModPath)),
+
+ %% Start a process to remember that the on_load was called.
spawn(fun() ->
register(everything_is_fine, self()),
receive Any ->
diff --git a/lib/kernel/test/code_a_test.erl b/lib/kernel/test/code_a_test.erl
index 745bbf032c..22830fff53 100644
--- a/lib/kernel/test/code_a_test.erl
+++ b/lib/kernel/test/code_a_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/code_b_test.erl b/lib/kernel/test/code_b_test.erl
index 0f0107a2b4..a8ff570e2e 100644
--- a/lib/kernel/test/code_b_test.erl
+++ b/lib/kernel/test/code_b_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/disk_log_SUITE.erl b/lib/kernel/test/disk_log_SUITE.erl
index 1bfe76f5ea..389a911d0b 100644
--- a/lib/kernel/test/disk_log_SUITE.erl
+++ b/lib/kernel/test/disk_log_SUITE.erl
@@ -28,46 +28,47 @@
-define(config(X,Y), foo).
-define(t,test_server).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(format(S, A), ok).
-define(privdir(Conf), ?config(priv_dir, Conf)).
-define(datadir(Conf), ?config(data_dir, Conf)).
-endif.
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
- halt_int/1, halt_int_inf/1, halt_int_sz/1,
+ halt_int_inf/1,
halt_int_sz_1/1, halt_int_sz_2/1,
- read_mode/1, halt_int_ro/1, halt_ext_ro/1, wrap_int_ro/1,
+ halt_int_ro/1, halt_ext_ro/1, wrap_int_ro/1,
wrap_ext_ro/1, halt_trunc/1, halt_misc/1, halt_ro_alog/1,
halt_ro_balog/1, halt_ro_crash/1,
- wrap_int/1, wrap_int_1/1, wrap_int_2/1, inc_wrap_file/1,
+ wrap_int_1/1, wrap_int_2/1, inc_wrap_file/1,
- halt_ext/1, halt_ext_inf/1,
+ halt_ext_inf/1,
- halt_ext_sz/1, halt_ext_sz_1/1, halt_ext_sz_2/1,
+ halt_ext_sz_1/1, halt_ext_sz_2/1,
- wrap_ext/1, wrap_ext_1/1, wrap_ext_2/1,
+ wrap_ext_1/1, wrap_ext_2/1,
- head/1, head_func/1, plain_head/1, one_header/1,
+ head_func/1, plain_head/1, one_header/1,
- notif/1, wrap_notif/1, full_notif/1, trunc_notif/1, blocked_notif/1,
+ wrap_notif/1, full_notif/1, trunc_notif/1, blocked_notif/1,
new_idx_vsn/1,
reopen/1,
- block/1, block_blocked/1, block_queue/1, block_queue2/1,
+ block_blocked/1, block_queue/1, block_queue2/1,
unblock/1,
- open/1, open_overwrite/1, open_size/1, open_truncate/1, open_error/1,
+ open_overwrite/1, open_size/1, open_truncate/1, open_error/1,
- close/1, close_race/1, close_block/1, close_deadlock/1,
+ close_race/1, close_block/1, close_deadlock/1,
- error/1, error_repair/1, error_log/1, error_index/1,
+ error_repair/1, error_log/1, error_index/1,
chunk/1,
@@ -75,15 +76,15 @@
many_users/1,
- info/1, info_current/1,
+ info_current/1,
- change_size/1, change_size_before/1, change_size_during/1,
+ change_size_before/1, change_size_during/1,
change_size_after/1, default_size/1, change_size2/1,
change_size_truncate/1,
change_attribute/1,
- distribution/1, dist_open/1, dist_error_open/1, dist_notify/1,
+ dist_open/1, dist_error_open/1, dist_notify/1,
dist_terminate/1, dist_accessible/1, dist_deadlock/1,
dist_open2/1, other_groups/1,
@@ -94,7 +95,7 @@
-export([head_fun/1, hf/0, lserv/1,
measure/0, init_m/1, xx/0, head_exit/0, slow_header/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([try_unblock/1]).
@@ -142,8 +143,59 @@
change_size_after, default_size]).
-all(suite) ->
- ?ALL_TESTS.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, halt_int}, {group, wrap_int},
+ {group, halt_ext}, {group, wrap_ext},
+ {group, read_mode}, {group, head}, {group, notif},
+ new_idx_vsn, reopen, {group, block}, unblock,
+ {group, open}, {group, close}, {group, error}, chunk,
+ truncate, many_users, {group, info},
+ {group, change_size}, change_attribute,
+ {group, distribution}, evil, otp_6278].
+
+groups() ->
+ [{halt_int, [], [halt_int_inf, {group, halt_int_sz}]},
+ {halt_int_sz, [], [halt_int_sz_1, halt_int_sz_2]},
+ {read_mode, [],
+ [halt_int_ro, halt_ext_ro, wrap_int_ro, wrap_ext_ro,
+ halt_trunc, halt_misc, halt_ro_alog, halt_ro_balog,
+ halt_ro_crash]},
+ {wrap_int, [], [wrap_int_1, wrap_int_2, inc_wrap_file]},
+ {halt_ext, [], [halt_ext_inf, {group, halt_ext_sz}]},
+ {halt_ext_sz, [], [halt_ext_sz_1, halt_ext_sz_2]},
+ {wrap_ext, [], [wrap_ext_1, wrap_ext_2]},
+ {head, [], [head_func, plain_head, one_header]},
+ {notif, [],
+ [wrap_notif, full_notif, trunc_notif, blocked_notif]},
+ {block, [], [block_blocked, block_queue, block_queue2]},
+ {open, [],
+ [open_overwrite, open_size, open_truncate, open_error]},
+ {close, [], [close_race, close_block, close_deadlock]},
+ {error, [], [error_repair, error_log, error_index]},
+ {info, [], [info_current]},
+ {change_size, [],
+ [change_size_before, change_size_during,
+ change_size_after, default_size, change_size2,
+ change_size_truncate]},
+ {distribution, [],
+ [dist_open, dist_error_open, dist_notify,
+ dist_terminate, dist_accessible, dist_deadlock,
+ dist_open2, other_groups]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Case, Config) ->
@@ -167,12 +219,11 @@ init_per_testcase(Case, Config) ->
[{watchdog, Dog}|Config]
end.
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-halt_int(suite) -> [halt_int_inf, halt_int_sz].
halt_int_inf(suite) -> [];
halt_int_inf(doc) -> ["Test simple halt disk log, size infinity"];
@@ -187,7 +238,6 @@ halt_int_inf(Conf) when is_list(Conf) ->
?line ok = disk_log:close(a),
?line ok = file:delete(File).
-halt_int_sz(suite) -> [halt_int_sz_1, halt_int_sz_2].
halt_int_sz_1(suite) -> [];
halt_int_sz_1(doc) -> ["Test simple halt disk log, size defined"];
@@ -275,10 +325,6 @@ halt_int_sz_2(Conf) when is_list(Conf) ->
?line ok = file:delete(File3),
ok.
-read_mode(suite) -> [halt_int_ro, halt_ext_ro,
- wrap_int_ro, wrap_ext_ro,
- halt_trunc, halt_misc, halt_ro_alog, halt_ro_balog,
- halt_ro_crash].
halt_int_ro(suite) -> [];
halt_int_ro(doc) -> ["Test simple halt disk log, read only, internal"];
@@ -480,7 +526,6 @@ halt_ro_crash(Conf) when is_list(Conf) ->
-wrap_int(suite) -> [wrap_int_1, wrap_int_2, inc_wrap_file].
wrap_int_1(suite) -> [];
wrap_int_1(doc) -> ["Test wrap disk log, internal"];
@@ -628,7 +673,6 @@ inc_wrap_file(Conf) when is_list(Conf) ->
-halt_ext(suite) -> [halt_ext_inf, halt_ext_sz].
halt_ext_inf(suite) -> [];
halt_ext_inf(doc) -> ["Test halt disk log, external, infinity"];
@@ -642,7 +686,6 @@ halt_ext_inf(Conf) when is_list(Conf) ->
?line ok = disk_log:close(a),
?line ok = file:delete(File).
-halt_ext_sz(suite) -> [halt_ext_sz_1, halt_ext_sz_2].
halt_ext_sz_1(suite) -> [];
halt_ext_sz_1(doc) -> ["Test halt disk log, external, size defined"];
@@ -734,7 +777,6 @@ halt_ext_sz_2(Conf) when is_list(Conf) ->
?line ok = file:delete(File3),
ok.
-wrap_ext(suite) -> [wrap_ext_1, wrap_ext_2].
wrap_ext_1(suite) -> [];
wrap_ext_1(doc) -> ["Test wrap disk log, external, size defined"];
@@ -1147,7 +1189,6 @@ end_times({T1,W1}) ->
{W2, _} = statistics(wall_clock),
{T2-T1, W2-W1}.
-head(suite) -> [head_func, plain_head, one_header].
head_func(suite) -> [];
head_func(doc) -> ["Test head parameter"];
@@ -1327,8 +1368,6 @@ one_header(Conf) when is_list(Conf) ->
ok.
-notif(suite) -> [wrap_notif, full_notif, trunc_notif,
- blocked_notif].
wrap_notif(suite) -> [];
wrap_notif(doc) -> ["Test notify parameter, wrap"];
@@ -1553,7 +1592,6 @@ reopen(Conf) when is_list(Conf) ->
?line Q = qlen(),
ok.
-block(suite) -> [block_blocked, block_queue, block_queue2].
block_blocked(suite) -> [];
block_blocked(doc) ->
@@ -1826,8 +1864,6 @@ try_unblock(Log) ->
?line Error = {error, {not_blocked_by_pid, n}} = disk_log:unblock(Log),
?line "The disk log" ++ _ = format_error(Error).
-open(suite) -> [open_overwrite, open_size,
- open_truncate, open_error].
open_overwrite(suite) -> [];
open_overwrite(doc) ->
@@ -2075,7 +2111,6 @@ open_error(Conf) when is_list(Conf) ->
?line del(File, No).
-close(suite) -> [close_race, close_block, close_deadlock].
close_race(suite) -> [];
close_race(doc) ->
@@ -2497,7 +2532,6 @@ lserv(Log) ->
end,
lserv(Log).
-error(suite) -> [error_repair, error_log, error_index].
error_repair(suite) -> [];
error_repair(doc) ->
@@ -3215,7 +3249,6 @@ del_files(_Size, File) ->
-info(suite) -> [info_current].
info_current(suite) -> [];
info_current(doc) ->
@@ -3420,11 +3453,6 @@ info_current(Conf) when is_list(Conf) ->
ok.
-change_size(suite) -> [change_size_before,
- change_size_during,
- change_size_after,
- default_size, change_size2,
- change_size_truncate].
change_size_before(suite) -> [];
change_size_before(doc) ->
@@ -4094,13 +4122,6 @@ change_attribute(Conf) when is_list(Conf) ->
?line Q = qlen(),
?line del(File, No).
-distribution(suite) -> [dist_open, dist_error_open,
- dist_notify,
- dist_terminate,
- dist_accessible,
- dist_deadlock,
- dist_open2,
- other_groups].
dist_open(suite) -> [];
dist_open(doc) ->
diff --git a/lib/kernel/test/erl_boot_server_SUITE.erl b/lib/kernel/test/erl_boot_server_SUITE.erl
index 241d68fef4..8399e8072f 100644
--- a/lib/kernel/test/erl_boot_server_SUITE.erl
+++ b/lib/kernel/test/erl_boot_server_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,9 +18,9 @@
%%
-module(erl_boot_server_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2]).
-export([start/1, start_link/1, stop/1, add/1, delete/1, responses/1]).
@@ -33,9 +33,27 @@
%% Changed for the new erl_boot_server for R3A by Bjorn Gustavsson.
%%-----------------------------------------------------------------
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[start, start_link, stop, add, delete, responses].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
-define(all_ones, {255, 255, 255, 255}).
start(doc) -> "Tests the erl_boot_server:start/1 function.";
diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index 21a96f804a..9cccdab76b 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,13 +19,14 @@
-module(erl_distribution_SUITE).
%-define(line_trace, 1).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([tick/1, tick_change/1, illegal_nodenames/1, hidden_node/1,
table_waste/1, net_setuptime/1,
- monitor_nodes/1,
+
monitor_nodes_nodedown_reason/1,
monitor_nodes_complex_nodedown_reason/1,
monitor_nodes_node_type/1,
@@ -41,7 +42,7 @@
tick_serv_test/2, tick_serv_test1/1,
keep_conn/1, time_ping/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([start_node/2]).
@@ -57,16 +58,39 @@
%% erl -sname master -rsh ctrsh
%%-----------------------------------------------------------------
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[tick, tick_change, illegal_nodenames, hidden_node,
- table_waste, net_setuptime,
- monitor_nodes].
+ table_waste, net_setuptime, {group, monitor_nodes}].
+
+groups() ->
+ [{monitor_nodes, [],
+ [monitor_nodes_nodedown_reason,
+ monitor_nodes_complex_nodedown_reason,
+ monitor_nodes_node_type, monitor_nodes_misc,
+ monitor_nodes_otp_6481, monitor_nodes_errors,
+ monitor_nodes_combinations, monitor_nodes_cleanup,
+ monitor_nodes_many]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(4)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
@@ -530,18 +554,6 @@ check_monitor_nodes_res(Pid, Node) ->
end.
-monitor_nodes(doc) ->
- [];
-monitor_nodes(suite) ->
- [monitor_nodes_nodedown_reason,
- monitor_nodes_complex_nodedown_reason,
- monitor_nodes_node_type,
- monitor_nodes_misc,
- monitor_nodes_otp_6481,
- monitor_nodes_errors,
- monitor_nodes_combinations,
- monitor_nodes_cleanup,
- monitor_nodes_many].
%%
%% Testcase:
@@ -845,13 +857,16 @@ monitor_nodes_otp_6481_test(Config, TestType) when is_list(Config) ->
?line {ok, Node} = start_node(Name, "", this),
?line receive {nodeup, Node} -> ok end,
- ?line spawn(Node,
+ ?line RemotePid = spawn(Node,
fun () ->
- receive after 1000 -> ok end,
- lists:foreach(fun (No) ->
- Me ! {NodeMsg, No}
- end,
- Seq),
+ receive after 1500 -> ok end,
+ % infinit loop of msgs
+ % we want an endless stream of messages and the kill
+ % the node mercilessly.
+ % We then want to ensure that the nodedown message arrives
+ % last ... without garbage after it.
+ _ = spawn(fun() -> node_loop_send(Me, NodeMsg, 1) end),
+ receive {Me, kill_it} -> ok end,
halt()
end),
@@ -860,9 +875,11 @@ monitor_nodes_otp_6481_test(Config, TestType) when is_list(Config) ->
%% Verify that '{nodeup, Node}' comes before '{NodeMsg, 1}' (the message
%% bringing up the connection).
- %%?line no_msgs(500), % Why wait? It fails test sometimes /sverker
+ ?line no_msgs(500),
?line {nodeup, Node} = receive Msg1 -> Msg1 end,
- ?line {NodeMsg, 1} = receive Msg2 -> Msg2 end,
+ ?line {NodeMsg, 1} = receive Msg2 -> Msg2 end,
+ % msg stream has begun, kill the node
+ ?line RemotePid ! {self(), kill_it},
%% Verify that '{nodedown, Node}' comes after the last '{NodeMsg, N}'
%% message.
@@ -883,6 +900,10 @@ flush_node_msgs(NodeMsg, No) ->
OtherMsg -> OtherMsg
end.
+node_loop_send(Pid, Msg, No) ->
+ Pid ! {Msg, No},
+ node_loop_send(Pid, Msg, No + 1).
+
monitor_nodes_errors(doc) ->
[];
monitor_nodes_errors(suite) ->
diff --git a/lib/kernel/test/erl_distribution_wb_SUITE.erl b/lib/kernel/test/erl_distribution_wb_SUITE.erl
index 627fed1fdd..f712cdea46 100644
--- a/lib/kernel/test/erl_distribution_wb_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_wb_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,12 +18,13 @@
%%
-module(erl_distribution_wb_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/inet.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
--export([init_per_testcase/2, fin_per_testcase/2, whitebox/1,
+-export([init_per_testcase/2, end_per_testcase/2, whitebox/1,
switch_options/1, missing_compulsory_dflags/1]).
%% 1)
@@ -77,14 +78,32 @@
-define(u32(X3,X2,X1,X0),
(((X3) bsl 24) bor ((X2) bsl 16) bor ((X1) bsl 8) bor (X0))).
-all(suite) ->
- [whitebox,switch_options,missing_compulsory_dflags].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [whitebox, switch_options, missing_compulsory_dflags].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(1)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl
index 19c84ab34c..b990e76064 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE.erl
@@ -19,9 +19,10 @@
-module(erl_prim_loader_SUITE).
-include_lib("kernel/include/file.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([get_path/1, set_path/1, get_file/1,
inet_existing/1, inet_coming_up/1, inet_disconnects/1,
@@ -29,27 +30,41 @@
local_archive/1, remote_archive/1,
primary_archive/1, virtual_dir_in_archive/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%%-----------------------------------------------------------------
%% Test suite for erl_prim_loader. (Most code is run during system start/stop.)
%%-----------------------------------------------------------------
-all(suite) ->
- [
- get_path, set_path, get_file,
- inet_existing, inet_coming_up,
- inet_disconnects, multiple_slaves,
- file_requests, local_archive,
- remote_archive, primary_archive,
- virtual_dir_in_archive
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [get_path, set_path, get_file, inet_existing,
+ inet_coming_up, inet_disconnects, multiple_slaves,
+ file_requests, local_archive, remote_archive,
+ primary_archive, virtual_dir_in_archive].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(3)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
@@ -291,7 +306,6 @@ wait_and_shutdown([], _) ->
ok.
-file_requests(suite) -> {req, [{local_slave_nodes, 1}, {time, 10}]};
file_requests(doc) -> ["Start a node using the 'inet' loading method, ",
"verify that the boot server responds to file requests."];
file_requests(Config) when is_list(Config) ->
@@ -300,9 +314,11 @@ file_requests(Config) when is_list(Config) ->
%% compare with results from file server calls (the
%% boot server uses the same file sys and cwd)
{ok,Files} = file:list_dir("."),
+ io:format("Files: ~p~n",[Files]),
?line {ok,Files} = rpc:call(Node, erl_prim_loader, list_dir, ["."]),
- {ok,Info} = file:read_file_info("test_server.beam"),
- ?line {ok,Info} = rpc:call(Node, erl_prim_loader, read_file_info, ["test_server.beam"]),
+ {ok,Info} = file:read_file_info(code:which(test_server)),
+ ?line {ok,Info} = rpc:call(Node, erl_prim_loader, read_file_info,
+ [code:which(test_server)]),
{ok,Cwd} = file:get_cwd(),
?line {ok,Cwd} = rpc:call(Node, erl_prim_loader, get_cwd, []),
case file:get_cwd("C:") of
diff --git a/lib/kernel/test/error_logger_SUITE.erl b/lib/kernel/test/error_logger_SUITE.erl
index eda86861d5..dca073cea0 100644
--- a/lib/kernel/test/error_logger_SUITE.erl
+++ b/lib/kernel/test/error_logger_SUITE.erl
@@ -18,7 +18,7 @@
%%
-module(error_logger_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%%-----------------------------------------------------------------
%% We don't have to test the normal behaviour here, i.e. the tty
@@ -27,7 +27,9 @@
%% error_logger deliver the expected events.
%%-----------------------------------------------------------------
--export([all/1, error_report/1, info_report/1, error/1, info/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ error_report/1, info_report/1, error/1, info/1,
emulator/1, tty/1, logfile/1, add/1, delete/1]).
-export([generate_error/0]).
@@ -37,9 +39,27 @@
terminate/2]).
-all(suite) ->
- [error_report, info_report, error, info,
- emulator, tty, logfile, add, delete].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [error_report, info_report, error, info, emulator, tty,
+ logfile, add, delete].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%-----------------------------------------------------------------
diff --git a/lib/kernel/test/error_logger_warn_SUITE.erl b/lib/kernel/test/error_logger_warn_SUITE.erl
index 6629eca1ad..5b8f0eb049 100644
--- a/lib/kernel/test/error_logger_warn_SUITE.erl
+++ b/lib/kernel/test/error_logger_warn_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,7 +18,9 @@
%%
-module(error_logger_warn_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
basic/1,warnings_info/1,warnings_warnings/1,
rb_basic/1,rb_warnings_info/1,rb_warnings_warnings/1,
rb_trunc/1,rb_utc/1,file_utc/1]).
@@ -26,7 +28,7 @@
%% Internal exports.
-export([init/1,handle_event/2,handle_info/2,handle_call/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(EXPECT(Pattern),
(fun() ->
@@ -43,15 +45,33 @@
-define(default_timeout, ?t:minutes(1)).
-all(suite) ->
- [basic, warnings_info, warnings_warnings,
- rb_basic, rb_warnings_info, rb_warnings_warnings,
- rb_trunc,rb_utc, file_utc].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic, warnings_info, warnings_warnings, rb_basic,
+ rb_warnings_info, rb_warnings_warnings, rb_trunc,
+ rb_utc, file_utc].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index 17c47f871d..d218589028 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -40,29 +40,29 @@
-module(?FILE_SUITE).
--export([all/1,
- init/1, fini/1,
- init_per_testcase/2, fin_per_testcase/2,
- read_write_file/1, dirs/1, files/1, names/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
+ read_write_file/1, names/1]).
-export([cur_dir_0/1, cur_dir_1/1, make_del_dir/1,
- pos/1, pos1/1, pos2/1]).
--export([close/1, consult/1, consult1/1, path_consult/1, delete/1]).
--export([eval/1, eval1/1, path_eval/1, script/1, script1/1, path_script/1,
- open/1, open1/1,
+ pos1/1, pos2/1]).
+-export([close/1, consult1/1, path_consult/1, delete/1]).
+-export([ eval1/1, path_eval/1, script1/1, path_script/1,
+ open1/1,
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,
+-export([ 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, datasync/1, sync/1,
read_write/1, pread_write/1, append/1, exclusive/1]).
--export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).
+-export([ e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).
-export([otp_5814/1]).
--export([compression/1, read_not_really_compressed/1,
+-export([ read_not_really_compressed/1,
read_compressed_cooked/1, read_compressed_cooked_binary/1,
read_cooked_tar_problem/1,
write_compressed/1, compress_errors/1, catenated_gzips/1]).
--export([links/1, make_link/1, read_link_info_for_non_link/1, symlinks/1]).
+-export([ make_link/1, read_link_info_for_non_link/1, symlinks/1]).
-export([copy/1]).
@@ -93,23 +93,56 @@
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
-all(suite) ->
- {conf, init,
- [altname, read_write_file, dirs, files,
- delete, rename, names, errors,
- 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,
- standard_io],
- fini}.
-
-init(Config) when is_list(Config) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [altname, read_write_file, {group, dirs},
+ {group, files}, delete, rename, names, {group, errors},
+ {group, compression}, {group, 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, standard_io].
+
+groups() ->
+ [{dirs, [], [make_del_dir, cur_dir_0, cur_dir_1]},
+ {files, [],
+ [{group, open}, {group, pos}, {group, file_info},
+ {group, consult}, {group, eval}, {group, script},
+ truncate, sync, datasync, advise]},
+ {open, [],
+ [open1, old_modes, new_modes, path_open, close, access,
+ read_write, pread_write, append, open_errors,
+ exclusive]},
+ {pos, [], [pos1, pos2]},
+ {file_info, [],
+ [file_info_basic_file, file_info_basic_directory,
+ file_info_bad, file_info_times, file_write_file_info]},
+ {consult, [], [consult1, path_consult]},
+ {eval, [], [eval1, path_eval]},
+ {script, [], [script1, path_script]},
+ {errors, [],
+ [e_delete, e_rename, e_make_dir, e_del_dir]},
+ {compression, [],
+ [read_compressed_cooked, read_compressed_cooked_binary,
+ read_cooked_tar_problem, read_not_really_compressed,
+ write_compressed, compress_errors, catenated_gzips]},
+ {links, [],
+ [make_link, read_link_info_for_non_link, symlinks]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
Priv = ?config(priv_dir, Config),
@@ -126,7 +159,7 @@ init(Config) when is_list(Config) ->
?FILE_INIT(Config)
end.
-fini(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
os:cmd("subst z: /d");
@@ -139,7 +172,7 @@ init_per_testcase(_Func, Config) ->
%%error_logger:info_msg("~p:~p *****~n", [?MODULE, _Func]),
?FILE_INIT_PER_TESTCASE(Config).
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
%% error_logger:info_msg("~p:~p END *****~n", [?MODULE, _Func]),
?FILE_FIN_PER_TESTCASE(Config).
@@ -314,7 +347,6 @@ read_write_file(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-dirs(suite) -> [make_del_dir, cur_dir_0, cur_dir_1].
make_del_dir(suite) -> [];
make_del_dir(doc) -> [];
@@ -461,12 +493,7 @@ win_cur_dir_1(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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,exclusive].
open1(suite) -> [];
open1(doc) -> [];
@@ -858,7 +885,6 @@ exclusive(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-pos(suite) -> [pos1,pos2].
pos1(suite) -> [];
pos1(doc) -> [];
@@ -950,8 +976,6 @@ pos2(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
-file_info(suite) -> [file_info_basic_file, file_info_basic_directory,
- file_info_bad, file_info_times, file_write_file_info].
file_info_basic_file(suite) -> [];
file_info_basic_file(doc) -> [];
@@ -1217,7 +1241,6 @@ file_write_file_info(Config) when is_list(Config) ->
get_good_directory(Config) ->
?line ?config(priv_dir, Config).
-consult(suite) -> [consult1, path_consult].
consult1(suite) -> [];
consult1(doc) -> [];
@@ -1278,7 +1301,6 @@ path_consult(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
-eval(suite) -> [eval1,path_eval].
eval1(suite) -> [];
eval1(doc) -> [];
@@ -1351,7 +1373,6 @@ path_eval(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
-script(suite) -> [script1,path_script].
script1(suite) -> [];
script1(doc) -> "";
@@ -1702,7 +1723,6 @@ names(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-errors(suite) -> [e_delete, e_rename, e_make_dir, e_del_dir].
e_delete(suite) -> [];
e_delete(doc) -> [];
@@ -1959,12 +1979,6 @@ e_del_dir(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-compression(suite) ->
- [read_compressed_cooked, read_compressed_cooked_binary,
- read_cooked_tar_problem,
- read_not_really_compressed,
- write_compressed, compress_errors,
- catenated_gzips].
%% Trying reading and positioning from a compressed file.
@@ -2258,8 +2272,6 @@ altname(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
Result.
-links(doc) -> "Test the link functions.";
-links(suite) -> [make_link, read_link_info_for_non_link, symlinks].
make_link(doc) -> "Test creating a hard link.";
make_link(suite) -> [];
@@ -3268,7 +3280,7 @@ large_file(Config) when is_list(Config) ->
{{unix,sunos},{A,B,C}}
when A == 5, B == 5, C >= 1; A == 5, B >= 6; A >= 6 ->
do_large_file(Config);
- {{unix,Unix},_} when Unix =:= linux; Unix =:= darwin ->
+ {{unix,Unix},_} when Unix =/= sunos ->
N = unix_free(Config),
io:format("Free: ~w KByte~n", [N]),
if N < 5 * (1 bsl 20) ->
@@ -3278,7 +3290,7 @@ large_file(Config) when is_list(Config) ->
do_large_file(Config)
end;
_ ->
- {skipped,"Only supported on Win32, Linux, or SunOS >= 5.5.1"}
+ {skipped,"Only supported on Win32, Unix or SunOS >= 5.5.1"}
end.
unix_free(Config) ->
@@ -3290,7 +3302,7 @@ unix_free(Config) ->
N.
do_large_file(Config) ->
- ?line Watchdog = ?t:timetrap(?t:minutes(4)),
+ ?line Watchdog = ?t:timetrap(?t:minutes(5)),
%%
?line Name = filename:join(?config(priv_dir, Config),
?MODULE_STRING ++ "_large_file"),
@@ -3329,6 +3341,17 @@ do_large_file(Config) ->
?line {ok,P} = ?FILE_MODULE:position(F, {eof,-L}),
?line {ok,Rs} = ?FILE_MODULE:read(F, L+1),
?line ok = ?FILE_MODULE:close(F),
+ %% Reopen the file with 'append'; used to fail on Windows causing
+ %% writes to go to the beginning of the file for files > 4GB.
+ ?line PL = P + L,
+ ?line PLL = PL + L,
+ ?line {ok,F1} = ?FILE_MODULE:open(Name, [raw,read,write,append]),
+ ?line ok = ?FILE_MODULE:write(F1, R),
+ ?line {ok,PLL} = ?FILE_MODULE:position(F1, {cur,0}),
+ ?line {ok,Rs} = ?FILE_MODULE:pread(F1, P, L),
+ ?line {ok,PL} = ?FILE_MODULE:position(F1, {eof,-L}),
+ ?line {ok,R} = ?FILE_MODULE:read(F1, L+1),
+ ?line ok = ?FILE_MODULE:close(F1),
%%
?line Mref = erlang:monitor(process, Deleter),
?line Deleter ! {Tester,done},
diff --git a/lib/kernel/test/file_name_SUITE.erl b/lib/kernel/test/file_name_SUITE.erl
new file mode 100644
index 0000000000..33c8e5bbe4
--- /dev/null
+++ b/lib/kernel/test/file_name_SUITE.erl
@@ -0,0 +1,1756 @@
+-module(file_name_SUITE).
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("kernel/include/file.hrl").
+
+%%
+%% File operations that take filenames as parameters (* not prim_file operation) (** a drive):
+%% altname
+%% copy (*)
+%% del_dir
+%% delete
+%% get_cwd (**)
+%% list_dir
+%% make_dir
+%% make_link
+%% make_symlink
+%% open
+%% read_file
+%% read_file_info
+%% read_link
+%% read_link_info
+%% rename
+%% set_cwd
+%% write_file
+%% write_file_info
+%%
+%% File operations that opens/uses separate driver port (not connected to file)
+%% altname
+%% del_dir
+%% delete
+%% get_cwd
+%% list_dir
+%% make_dir
+%% make_link
+%% make_symlink
+%% read_file_info
+%% read_link
+%% read_link_info
+%% rename
+%% set_cwd
+%% write_file_info
+%%
+%% Operations that use ?FD_DRV in prim_file
+%% open
+%% read_file
+%% write_file
+%%
+%%
+%% Operations that return a filename/path
+%% altname
+%% get_cwd
+%% list_dir
+%% read_link
+
+-export([all/0,groups/0,suite/0,
+ init_per_suite/1,end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
+-export([normal/1,icky/1,very_icky/1,normalize/1]).
+
+
+init_per_testcase(_Func, Config) ->
+ Dog = test_server:timetrap(test_server:seconds(60)),
+ [{watchdog,Dog}|Config].
+
+end_per_testcase(_Func, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [normal, icky, very_icky, normalize].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+normalize(suite) ->
+ [];
+normalize(doc) ->
+ ["Check that filename normalization works"];
+normalize(Config) when is_list(Config) ->
+ random:seed({1290,431421,830412}),
+ try
+ ?line UniMode = file:native_name_encoding() =/= latin1,
+ if
+ not UniMode ->
+ throw(need_unicode_mode);
+ true ->
+ ok
+ end,
+ ?line Pairs = [rand_comp_decomp(200) || _ <- lists:seq(1,1000)],
+ case os:type() of
+ {unix,darwin} ->
+ ?line [ true = (A =:= prim_file:internal_native2name(B)) ||
+ {A,B} <- Pairs ];
+ _ ->
+ ok
+ end,
+ ?line [ true = (A =:= prim_file:internal_normalize_utf8(B)) ||
+ {A,B} <- Pairs ]
+
+ catch
+ throw:need_unicode_mode ->
+ io:format("Sorry, can only run in unicode mode.~n"),
+ {skipped,"VM needs to be started in Unicode filename mode"}
+ end.
+
+normal(suite) ->
+ [];
+normal(doc) ->
+ "Check file operations on normal file names regardless of unicode mode";
+normal(Config) when is_list(Config) ->
+ {ok,Dir} = file:get_cwd(),
+ try
+ Priv = ?config(priv_dir, Config),
+ file:set_cwd(Priv),
+ put(file_module,prim_file),
+ ok = check_normal(prim_file),
+ put(file_module,file),
+ ok = check_normal(file)
+ after
+ file:set_cwd(Dir)
+ end.
+
+
+icky(suite) ->
+ [];
+icky(doc) ->
+ "Check file operations on normal file names regardless of unicode mode";
+icky(Config) when is_list(Config) ->
+ case hopeless_darwin() of
+ true ->
+ {skipped,"This version of darwin does not support icky names at all."};
+ false ->
+ {ok,Dir} = file:get_cwd(),
+ try
+ Priv = ?config(priv_dir, Config),
+ file:set_cwd(Priv),
+ put(file_module,prim_file),
+ ok = check_icky(prim_file),
+ put(file_module,file),
+ ok = check_icky(file)
+ after
+ file:set_cwd(Dir)
+ end
+ end.
+very_icky(suite) ->
+ [];
+very_icky(doc) ->
+ "Check file operations on normal file names regardless of unicode mode";
+very_icky(Config) when is_list(Config) ->
+ case hopeless_darwin() of
+ true ->
+ {skipped,"This version of darwin does not support icky names at all."};
+ false ->
+ {ok,Dir} = file:get_cwd(),
+ try
+ Priv = ?config(priv_dir, Config),
+ file:set_cwd(Priv),
+ put(file_module,prim_file),
+ case check_very_icky(prim_file) of
+ need_unicode_mode ->
+ {skipped,"VM needs to be started in Unicode filename mode"};
+ ok ->
+ put(file_module,file),
+ ok = check_very_icky(file)
+ end
+ after
+ file:set_cwd(Dir)
+ end
+ end.
+
+
+check_normal(Mod) ->
+ {ok,Dir} = Mod:get_cwd(),
+ try
+ ?line make_normal_dir(Mod),
+ ?line {ok, L0} = Mod:list_dir("."),
+ ?line L1 = lists:sort(L0),
+ %erlang:display(L1),
+ ?line L1 = lists:sort(list(normal_dir())),
+ ?line {ok,D2} = Mod:get_cwd(),
+ ?line true = is_list(D2),
+ ?line case Mod:altname("fil1") of
+ {error,enotsup} ->
+ ok;
+ {ok,LLL} when is_list(LLL) ->
+ ok
+ end,
+ ?line [ true = is_list(El) || El <- L1],
+ ?line Syms = [ {S,Targ,list_to_binary(get_data(Targ,normal_dir()))}
+ || {T,S,Targ} <- normal_dir(), T =:= symlink ],
+ ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ],
+ ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ],
+ ?line chk_cre_dir(Mod,[{directory,"temp_dir",normal_dir()}]),
+ ?line {ok,BeginAt} = Mod:get_cwd(),
+ ?line true = is_list(BeginAt),
+ ?line {error,enoent} = Mod:set_cwd("tmp_dir"),
+ ?line ok = Mod:set_cwd("temp_dir"),
+ ?line {ok, NowAt} = Mod:get_cwd(),
+ ?line true = BeginAt =/= NowAt,
+ ?line ok = Mod:set_cwd(".."),
+ ?line {ok,BeginAt} = Mod:get_cwd(),
+ ?line rm_r(Mod,"temp_dir"),
+ ?line true = is_list(Dir),
+ ?line [ true = is_list(FN) || FN <- L0 ],
+ case has_links() of
+ true ->
+ ?line ok = Mod:make_link("fil1","nisse"),
+ ?line {ok, <<"fil1">>} = Mod:read_file("nisse"),
+ ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisse"),
+ ?line ok = Mod:delete("nisse"),
+ ?line {ok, <<"fil1">>} = Mod:read_file("fil1"),
+ ?line {error,enoent} = Mod:read_file("nisse"),
+ ?line {error,enoent} = Mod:read_link_info("nisse");
+ false ->
+ ok
+ end,
+ ?line [ begin
+ ?line {ok, FD} = Mod:open(Name,[read]),
+ ?line {ok, Content} = Mod:read(FD,1024),
+ ?line ok = file:close(FD)
+ end || {regular,Name,Content} <- normal_dir() ],
+ ?line [ begin
+ ?line {ok, FD} = Mod:open(Name,[read,binary]),
+ ?line BC = list_to_binary(Content),
+ ?line {ok, BC} = Mod:read(FD,1024),
+ ?line ok = file:close(FD)
+ end || {regular,Name,Content} <- normal_dir() ],
+ ?line Mod:rename("fil1","tmp_fil1"),
+ ?line {ok, <<"fil1">>} = Mod:read_file("tmp_fil1"),
+ ?line {error,enoent} = Mod:read_file("fil1"),
+ ?line Mod:rename("tmp_fil1","fil1"),
+ ?line {ok, <<"fil1">>} = Mod:read_file("fil1"),
+ ?line {error,enoent} = Mod:read_file("tmp_fil1"),
+ ?line {ok,FI} = Mod:read_file_info("fil1"),
+ ?line NewMode = FI#file_info.mode band (bnot 8#333),
+ ?line NewMode2 = NewMode bor 8#222,
+ ?line true = NewMode2 =/= NewMode,
+ ?line ok = Mod:write_file_info("fil1",FI#file_info{mode = NewMode}),
+ ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info("fil1"),
+ ?line ok = Mod:write_file_info("fil1",FI#file_info{mode = NewMode2}),
+ ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info("fil1"),
+ ok
+ after
+ case Mod:read_file_info("fil1") of
+ {ok,FII} ->
+ NewModeI = FII#file_info.mode bor 8#777,
+ Mod:write_file_info("fil1",FII#file_info{mode = NewModeI});
+ _ ->
+ ok
+ end,
+ Mod:set_cwd(Dir),
+ io:format("Wd now: ~s~n",[Dir])
+ end.
+
+check_icky(Mod) ->
+ {ok,Dir} = Mod:get_cwd(),
+ try
+ ?line true=(length("���") =:= 3),
+ ?line UniMode = file:native_name_encoding() =/= latin1,
+ ?line make_icky_dir(Mod),
+ ?line {ok, L0} = Mod:list_dir("."),
+ ?line L1 = lists:sort(L0),
+ io:format("~p ~p~n",[L1,list(icky_dir())]),
+ ?line L1 = lists:sort(convlist(list(icky_dir()))),
+ ?line {ok,D2} = Mod:get_cwd(),
+ ?line true = is_list(D2),
+%% Altname only on windows, and there are no non native filenames there
+%% ?line case Mod:altname("fil1") of
+%% {error,enotsup} ->
+%% ok;
+%% {ok,LLL} when is_list(LLL) ->
+%% ok
+%% end,
+ ?line [ true = ((is_list(El) or (UniMode and is_binary(El)))) || El <- L1],
+ ?line Syms = [ {S,conv(Targ),list_to_binary(get_data(Targ,icky_dir()))}
+ || {T,S,Targ} <- icky_dir(), T =:= symlink ],
+ ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ],
+ ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ],
+ ?line chk_cre_dir(Mod,[{directory,"���_dir",icky_dir()}]),
+ ?line {ok,BeginAt} = Mod:get_cwd(),
+ ?line true = is_list(BeginAt),
+ ?line {error,enoent} = Mod:set_cwd("��_dir"),
+ ?line ok = Mod:set_cwd("���_dir"),
+ ?line {ok, NowAt} = Mod:get_cwd(),
+ ?line true = is_list(NowAt),
+ ?line true = BeginAt =/= NowAt,
+ ?line ok = Mod:set_cwd(".."),
+ ?line {ok,BeginAt} = Mod:get_cwd(),
+ ?line rm_r2(Mod,"���_dir"),
+ {OS,TYPE} = os:type(),
+ % Check that treat_icky really converts to the same as the OS
+ case UniMode of
+ true ->
+ ?line chk_cre_dir(Mod,[{directory,"���_dir",[]}]),
+ ?line ok = Mod:set_cwd("���_dir"),
+ ?line ok = Mod:write_file(<<"���">>,<<"hello">>),
+ ?line Treated = treat_icky(<<"���">>),
+ ?line {ok,[Treated]} = Mod:list_dir("."),
+ ?line ok = Mod:delete(<<"���">>),
+ ?line {ok,[]} = Mod:list_dir("."),
+ ?line ok = Mod:set_cwd(".."),
+ ?line rm_r2(Mod,"���_dir");
+ false ->
+ ok
+ end,
+
+ ?line chk_cre_dir(Mod,[{directory,treat_icky(<<"���_dir">>),icky_dir()}]),
+ if
+ UniMode and (OS =/= win32) ->
+ ?line {error,enoent} = Mod:set_cwd("���_dir");
+ true ->
+ ok
+ end,
+ ?line ok = Mod:set_cwd(treat_icky(<<"���_dir">>)),
+ ?line {ok, NowAt2} = Mod:get_cwd(),
+ io:format("~p~n",[NowAt2]),
+ % Cannot create raw unicode-breaking filenames on windows or macos
+ ?line true = ((((not UniMode) or (OS =:= win32) or (TYPE=:=darwin)) and is_list(NowAt2)) orelse ((UniMode) and is_binary(NowAt2))),
+ ?line true = BeginAt =/= NowAt2,
+ ?line ok = Mod:set_cwd(".."),
+ ?line {ok,BeginAt} = Mod:get_cwd(),
+ ?line rm_r2(Mod,conv(treat_icky(<<"���_dir">>))),
+ case has_links() of
+ true ->
+ ?line ok = Mod:make_link("fil1","nisse�"),
+ ?line {ok, <<"fil1">>} = Mod:read_file("nisse�"),
+ ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisse�"),
+ ?line ok = Mod:delete("nisse�"),
+ ?line ok = Mod:make_link("fil1",treat_icky(<<"nisse�">>)),
+ ?line {ok, <<"fil1">>} = Mod:read_file(treat_icky(<<"nisse�">>)),
+ ?line {ok, #file_info{type = regular}} = Mod:read_link_info(treat_icky(<<"nisse�">>)),
+ ?line ok = Mod:delete(treat_icky(<<"nisse�">>)),
+ ?line {ok, <<"fil1">>} = Mod:read_file("fil1"),
+ ?line {error,enoent} = Mod:read_file("nisse�"),
+ ?line {error,enoent} = Mod:read_link_info("nisse�"),
+ ?line {error,enoent} = Mod:read_file(treat_icky(<<"nisse�">>)),
+ ?line {error,enoent} = Mod:read_link_info(treat_icky(<<"nisse�">>));
+ false ->
+ ok
+ end,
+ ?line [ begin
+ ?line {ok, FD} = Mod:open(Name,[read]),
+ ?line {ok, Content} = Mod:read(FD,1024),
+ ?line ok = file:close(FD)
+ end || {regular,Name,Content} <- icky_dir() ],
+ ?line [ begin
+ ?line {ok, FD} = Mod:open(Name,[read,binary]),
+ ?line BC = list_to_binary([Content]),
+ ?line {ok, BC} = Mod:read(FD,1024),
+ ?line ok = file:close(FD)
+ end || {regular,Name,Content} <- icky_dir() ],
+ ?line Mod:rename("���2","���_fil1"),
+ ?line {ok, <<"���2">>} = Mod:read_file("���_fil1"),
+ ?line {error,enoent} = Mod:read_file("���2"),
+ ?line Mod:rename("���_fil1","���2"),
+ ?line {ok, <<"���2">>} = Mod:read_file("���2"),
+ ?line {error,enoent} = Mod:read_file("���_fil1"),
+
+ ?line Mod:rename("���2",treat_icky(<<"���_fil1">>)),
+ ?line {ok, <<"���2">>} = Mod:read_file(treat_icky(<<"���_fil1">>)),
+ if
+ UniMode and (OS =/= win32) ->
+ {error,enoent} = Mod:read_file("���_fil1");
+ true ->
+ ok
+ end,
+ ?line {error,enoent} = Mod:read_file("���2"),
+ ?line Mod:rename(treat_icky(<<"���_fil1">>),"���2"),
+ ?line {ok, <<"���2">>} = Mod:read_file("���2"),
+ ?line {error,enoent} = Mod:read_file("���_fil1"),
+ ?line {error,enoent} = Mod:read_file(treat_icky(<<"���_fil1">>)),
+
+ ?line {ok,FI} = Mod:read_file_info("���2"),
+ ?line NewMode = FI#file_info.mode band (bnot 8#333),
+ ?line NewMode2 = NewMode bor 8#222,
+ ?line true = NewMode2 =/= NewMode,
+ ?line ok = Mod:write_file_info("���2",FI#file_info{mode = NewMode}),
+ ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info("���2"),
+ ?line ok = Mod:write_file_info("���2",FI#file_info{mode = NewMode2}),
+ ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info("���2"),
+
+ ?line {ok,FII} = Mod:read_file_info(treat_icky(<<"���5">>)),
+ ?line true = NewMode2 =/= NewMode,
+ ?line ok = Mod:write_file_info(treat_icky(<<"���5">>),FII#file_info{mode = NewMode}),
+ ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info(treat_icky(<<"���5">>)),
+ ?line ok = Mod:write_file_info(<<"���5">>,FII#file_info{mode = NewMode2}),
+ ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info(treat_icky(<<"���5">>)),
+ ok
+ after
+ Mod:set_cwd(Dir),
+ io:format("Wd now: ~s~n",[Dir])
+ end.
+
+check_very_icky(Mod) ->
+ {ok,Dir} = Mod:get_cwd(),
+ try
+ ?line true=(length("���") =:= 3),
+ ?line UniMode = file:native_name_encoding() =/= latin1,
+ if
+ not UniMode ->
+ throw(need_unicode_mode);
+ true ->
+ ok
+ end,
+ ?line make_very_icky_dir(Mod),
+ ?line {ok, L0} = Mod:list_dir("."),
+ ?line L1 = lists:sort(L0),
+ ?line L1 = lists:sort(convlist(list(very_icky_dir()))),
+ ?line {ok,D2} = Mod:get_cwd(),
+ ?line true = is_list(D2),
+ ?line [ true = ((is_list(El) or is_binary(El))) || El <- L1],
+ ?line Syms = [ {S,conv(Targ),list_to_binary(get_data(Targ,very_icky_dir()))}
+ || {T,S,Targ} <- very_icky_dir(), T =:= symlink ],
+ ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ],
+ ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ],
+ ?line chk_cre_dir(Mod,[{directory,[1088,1079,1091]++"_dir",very_icky_dir()}]),
+ ?line {ok,BeginAt} = Mod:get_cwd(),
+ ?line true = is_list(BeginAt),
+ ?line {error,enoent} = Mod:set_cwd("��_dir"),
+ ?line ok = Mod:set_cwd([1088,1079,1091]++"_dir"),
+ ?line {ok, NowAt} = Mod:get_cwd(),
+ ?line true = is_list(NowAt),
+ ?line true = BeginAt =/= NowAt,
+ ?line ok = Mod:set_cwd(".."),
+ ?line {ok,BeginAt} = Mod:get_cwd(),
+ ?line rm_r2(Mod,[1088,1079,1091]++"_dir"),
+
+ case has_links() of
+ true ->
+ ?line ok = Mod:make_link("fil1","nisse"++[1088,1079,1091]),
+ ?line {ok, <<"fil1">>} =
+ Mod:read_file("nisse"++[1088,1079,1091]),
+ ?line {ok, #file_info{type = regular}} =
+ Mod:read_link_info("nisse"++[1088,1079,1091]),
+ ?line ok = Mod:delete("nisse"++[1088,1079,1091]),
+ ?line ok = Mod:make_link("fil1",<<"nisse�">>),
+ ?line {ok, <<"fil1">>} = Mod:read_file(<<"nisse�">>),
+ ?line {ok, #file_info{type = regular}} =
+ Mod:read_link_info(<<"nisse�">>),
+ ?line ok = Mod:delete(<<"nisse�">>),
+ ?line {ok, <<"fil1">>} = Mod:read_file("fil1"),
+ ?line {error,enoent} = Mod:read_file("nisse"++[1088,1079,1091]),
+ ?line {error,enoent} = Mod:read_link_info("nisse"++[1088,1079,1091]),
+ ?line {error,enoent} = Mod:read_file(<<"nisse�">>),
+ ?line {error,enoent} = Mod:read_link_info(<<"nisse�">>);
+ false ->
+ ok
+ end,
+ ?line [ begin
+ ?line {ok, FD} = Mod:open(Name,[read]),
+ ?line {ok, Content} = Mod:read(FD,1024),
+ ?line ok = file:close(FD)
+ end || {regular,Name,Content} <- very_icky_dir() ],
+ ?line [ begin
+ ?line {ok, FD} = Mod:open(Name,[read,binary]),
+ ?line BC = list_to_binary([Content]),
+ ?line {ok, BC} = Mod:read(FD,1024),
+ ?line ok = file:close(FD)
+ end || {regular,Name,Content} <- very_icky_dir() ],
+ ?line Mod:rename([956,965,963,954,959,49],
+ [956,965,963,954,959]++"_fil1"),
+ ?line {ok, <<"���2">>} = Mod:read_file([956,965,963,954,959]++"_fil1"),
+ ?line {error,enoent} = Mod:read_file([956,965,963,954,959,49]),
+ ?line Mod:rename([956,965,963,954,959]++"_fil1",[956,965,963,954,959,49]),
+ ?line {ok, <<"���2">>} = Mod:read_file([956,965,963,954,959,49]),
+ ?line {error,enoent} = Mod:read_file([956,965,963,954,959]++"_fil1"),
+
+ ?line {ok,FI} = Mod:read_file_info([956,965,963,954,959,49]),
+ ?line NewMode = FI#file_info.mode band (bnot 8#333),
+ ?line NewMode2 = NewMode bor 8#222,
+ ?line true = NewMode2 =/= NewMode,
+ ?line ok = Mod:write_file_info([956,965,963,954,959,49],
+ FI#file_info{mode = NewMode}),
+ ?line {ok,#file_info{mode = NewMode}} =
+ Mod:read_file_info([956,965,963,954,959,49]),
+ ?line ok = Mod:write_file_info([956,965,963,954,959,49],
+ FI#file_info{mode = NewMode2}),
+ ?line {ok,#file_info{mode = NewMode2}} =
+ Mod:read_file_info([956,965,963,954,959,49]),
+ ?line NumOK0 = case has_links() of
+ true -> 5;
+ false -> 3
+ end,
+ ?line NumNOK0 = case has_links() of
+ true -> 4;
+ false -> 3
+ end,
+ ?line {NumOK,NumNOK} = case is_binary(treat_icky(<<"foo">>)) of
+ false ->
+ {NumOK0+NumNOK0,0};
+ true ->
+ {NumOK0,NumNOK0}
+ end,
+ ?line {NumOK,NumNOK} = filelib:fold_files(".",".*",true,fun(_F,{N,M}) when is_list(_F) -> io:format("~ts~n",[_F]),{N+1,M}; (_F,{N,M}) -> io:format("~p~n",[_F]),{N,M+1} end,{0,0}),
+ ?line ok = filelib:fold_files(".",[1076,1089,1072,124,46,42],true,fun(_F,_) -> ok end,false),
+ ?line SF3 = unicode:characters_to_binary("���subfil3",
+ file:native_name_encoding()),
+ ?line SF2 = case treat_icky(<<"���subfil2">>) of
+ LF2 when is_list(LF2) ->
+ unicode:characters_to_binary(LF2,
+ file:native_name_encoding());
+ BF2 ->
+ BF2
+ end,
+ ?line Sorted = lists:sort([SF3,SF2]),
+ ?line Sorted = lists:sort(filelib:wildcard("*",<<"���subdir2">>)),
+ ok
+ catch
+ throw:need_unicode_mode ->
+ io:format("Sorry, can only run in unicode mode.~n"),
+ need_unicode_mode
+ after
+ Mod:set_cwd(Dir),
+ io:format("Wd now: ~s~n",[Dir])
+ end.
+
+%%
+%% Utilities
+%%
+
+
+rm_rf(Mod,Dir) ->
+ case Mod:read_link_info(Dir) of
+ {ok, #file_info{type = directory}} ->
+ {ok, Content} = Mod:list_dir(Dir),
+ [ rm_rf(Mod,filename:join(Dir,C)) || C <- Content ],
+ Mod:del_dir(Dir),
+ ok;
+ {ok, #file_info{}} ->
+ Mod:delete(Dir);
+ _ ->
+ ok
+ end.
+
+rm_r(Mod,Dir) ->
+ %erlang:display({rm_r,Dir}),
+ case Mod:read_link_info(Dir) of
+ {ok, #file_info{type = directory}} ->
+ {ok,#file_info{type = directory}} = Mod:read_file_info(Dir),
+ {ok, Content} = Mod:list_dir(Dir),
+ [ true = is_list(Part) || Part <- Content ],
+ [ true = is_list(filename:join(Dir,Part)) || Part <- Content ],
+ [ rm_r(Mod,filename:join(Dir,C)) || C <- Content ],
+ ok = Mod:del_dir(Dir),
+ ok;
+ {ok, #file_info{type = regular}} ->
+ {ok,#file_info{type = regular}} = Mod:read_file_info(Dir),
+ ok = Mod:delete(Dir);
+ {ok, #file_info{type = symlink}} ->
+ ok = Mod:delete(Dir)
+ end.
+%% For icky test, allow binaries sometimes
+rm_r2(Mod,Dir) ->
+ %erlang:display({rm_r2,Dir}),
+ case Mod:read_link_info(Dir) of
+ {ok, #file_info{type = directory}} ->
+ {ok,#file_info{type = directory}} = Mod:read_file_info(Dir),
+ {ok, Content} = Mod:list_dir(Dir),
+ UniMode = file:native_name_encoding() =/= latin1,
+ [ true = (is_list(Part) orelse UniMode) || Part <- Content ],
+ [ true = (is_list(filename:join(Dir,Part)) orelse UniMode) || Part <- Content ],
+ [ rm_r2(Mod,filename:join(Dir,C)) || C <- Content ],
+ ok = Mod:del_dir(Dir),
+ ok;
+ {ok, #file_info{type = regular}} ->
+ {ok,#file_info{type = regular}} = Mod:read_file_info(Dir),
+ ok = Mod:delete(Dir);
+ {ok, #file_info{type = symlink}} ->
+ ok = Mod:delete(Dir)
+ end.
+chk_cre_dir(_,[]) ->
+ ok;
+chk_cre_dir(Mod,[{regular,Name,Content}|T]) ->
+ %io:format("~p~n",[Name]),
+ ok = Mod:write_file(Name,Content),
+ chk_cre_dir(Mod,T);
+chk_cre_dir(Mod,[{link,Name,Target}|T]) ->
+ ok = Mod:make_link(Target,Name),
+ chk_cre_dir(Mod,T);
+chk_cre_dir(Mod,[{symlink,Name,Target}|T]) ->
+ ok = Mod:make_symlink(Target,Name),
+ chk_cre_dir(Mod,T);
+chk_cre_dir(Mod,[{directory,Name,Content}|T]) ->
+ ok = Mod:make_dir(Name),
+ %io:format("Content = ~p~n",[Content]),
+ Content2 = [{Ty,filename:join(Name,N),case Ty of link -> filename:join(Name,C); _ -> C end} || {Ty,N,C} <- Content ],
+ %io:format("Content2 = ~p~n",[Content2]),
+ chk_cre_dir(Mod,Content2),
+ chk_cre_dir(Mod,T).
+
+has_links() ->
+ case os:type() of
+ {win32,_} ->
+ case os:version() of
+ {N,NN,_} when (N > 5) andalso (NN >= 1) ->
+ true;
+ _ ->
+ false
+ end;
+ _ ->
+ true
+ end.
+
+make_normal_dir(Mod) ->
+ rm_rf(Mod,"normal_dir"),
+ Mod:make_dir("normal_dir"),
+ Mod:set_cwd("normal_dir"),
+ Mod:write_file("fil1","fil1"),
+ Mod:write_file("fil2","fil2"),
+ case has_links() of
+ true ->
+ Mod:make_link("fil2","fil3"),
+ Mod:make_symlink("fil2","fil4");
+ _ ->
+ ok
+ end,
+ Mod:make_dir("subdir"),
+ Mod:write_file(filename:join("subdir","subfil1"),"subfil1"),
+ ok.
+
+normal_dir() ->
+ [{regular,"fil1","fil1"},
+ {regular,"fil2","fil2"}] ++
+ case has_links() of
+ true ->
+ [{regular,"fil3","fil2"},
+ {symlink,"fil4","fil2"}];
+ false ->
+ []
+ end ++
+ [{directory,"subdir",
+ [{regular,"subfil1","subfil1"}]}].
+
+make_icky_dir(Mod) ->
+ rm_rf(Mod,"icky_dir"),
+ Icky=icky_dir(),
+ chk_cre_dir(Mod,[{directory,"icky_dir",linkify([],Icky)}]),
+ Mod:set_cwd("icky_dir"),
+ ok.
+
+linkify(_Passed,[]) ->
+ [];
+linkify(Passed,[{regular,Name,Content}|T]) ->
+ Regulars = [ {N,C} || {regular,N,C} <- Passed, N =/= Name ],
+ case lists:keysearch(Content,2,Regulars) of
+ {value, {Linkto, Content}} ->
+ [{link,Name,Linkto} | linkify(Passed,T)];
+ _ ->
+ [{regular,Name,Content} | linkify([{regular,Name,Content}|Passed],T)]
+ end;
+linkify(Passed,[{directory, Name, Content}|T]) ->
+ [{directory,Name, linkify(Content,Content)}|linkify(Passed,T)];
+linkify(Passed,[H|T]) ->
+ [H|linkify([H|Passed],T)].
+
+hopeless_darwin() ->
+ case {os:type(),os:version()} of
+ {{unix,darwin},{Major,_,_}} when Major < 9 ->
+ true;
+ _ ->
+ false
+ end.
+
+icky_dir() ->
+ [{regular,"fil1","fil1"},
+ {regular,"���2","���2"}] ++
+ case has_links() of
+ true ->
+ [{regular,"���3","���2"},
+ {symlink,"���4","���2"}];
+ false ->
+ []
+ end ++
+ [{regular,treat_icky(<<"���5">>),"���5"}] ++
+ case has_links() of
+ true ->
+ [{symlink,treat_icky(<<"���6">>),treat_icky(<<"���5">>)}];
+ false ->
+ []
+ end ++
+ [{directory,treat_icky(<<"���subdir2">>),
+ [{regular,treat_icky(<<"���subfil2">>),"���subfil12"},
+ {regular,"���subfil3","���subfil13"}]},
+ {directory,"���subdir",
+ [{regular,"���subfil1","���subfil1"}]}].
+
+make_very_icky_dir(Mod) ->
+ rm_rf(Mod,"very_icky_dir"),
+ Icky=very_icky_dir(),
+ chk_cre_dir(Mod,[{directory,"very_icky_dir",linkify([],Icky)}]),
+ Mod:set_cwd("very_icky_dir"),
+ ok.
+
+very_icky_dir() ->
+ [{regular,"fil1","fil1"},
+ {regular,[956,965,963,954,959,49],"���2"}] ++
+ case has_links() of
+ true ->
+ [{regular,[956,965,963,954,959,50],"���2"},
+ {symlink,[956,965,963,954,959,51],[956,965,963,954,959,49]}];
+ false ->
+ []
+ end ++
+ [{regular,treat_icky(<<"���5">>),"���5"}] ++
+ case has_links() of
+ true ->
+ [{symlink,treat_icky(<<"���6">>),treat_icky(<<"���5">>)}];
+ false ->
+ []
+ end ++
+ [{directory,treat_icky(<<"���subdir2">>),
+ [{regular,treat_icky(<<"���subfil2">>),"���subfil12"},
+ {regular,"���subfil3","���subfil13"}]},
+ {directory,[956,965,963,954,959]++"subdir1",
+ [{regular,[956,965,963,954,959]++"subfil1","���subfil1"}]}].
+
+%% Some OS'es simply do not allow non UTF8 filenames
+treat_icky(Bin) ->
+ case os:type() of
+ {unix,darwin} ->
+ binary_to_list(procentify(Bin));
+ {win32,_} ->
+ binary_to_list(Bin);
+ _ ->
+ Bin
+ end.
+
+% Handle windows having absolute soft link targets.
+fixlink({ok,Link}) ->
+ case os:type() of
+ {win32,_} ->
+ {ok,filename:basename(Link)};
+ _ ->
+ {ok,Link}
+ end;
+fixlink(X) ->
+ X.
+
+procentify(<<>>) ->
+ <<>>;
+procentify(<<X:8,Rst/binary>>) when X > 127 ->
+ T=procentify(Rst),
+ Y = list_to_binary([$%
+ | io_lib:format("~2.16B",[X])]),
+ <<Y/binary,T/binary>>;
+procentify(<<X:8,Rst/binary>>) ->
+ T=procentify(Rst),
+ <<X:8,T/binary>>.
+
+
+list([]) ->
+ [];
+list([{_,Name,_} | T]) ->
+ [Name | list(T)].
+
+
+get_data(FN,List) ->
+ case lists:keysearch(FN,2,List) of
+ {value,{regular,FN,C}} ->
+ C;
+ {value,{symlink,FN,NewFN}} ->
+ get_data(NewFN,List);
+ _->
+ []
+ end.
+
+
+convlist(L) ->
+ convlist(file:native_name_encoding(),L).
+convlist(latin1,[Bin|T]) when is_binary(Bin) ->
+ %erlang:display('Convert...'),
+ [binary_to_list(Bin)| convlist(latin1,T)];
+convlist(Any,[H|T]) ->
+ [H|convlist(Any,T)];
+convlist(_,[]) ->
+ [].
+
+conv(L) ->
+ NoUniMode = file:native_name_encoding() =:= latin1,
+ if
+ NoUniMode, is_binary(L) ->
+ binary_to_list(L);
+ true ->
+ L
+ end.
+
+
+rand_comp_decomp(Max) ->
+ N = random:uniform(Max),
+ L = [ rand_decomp() || _ <- lists:seq(1,N) ],
+ LC = [ A || {A,_} <- L],
+ LD = lists:flatten([B || {_,B} <- L]),
+ LB = unicode:characters_to_binary(LD,unicode,utf8),
+ {LC,LB}.
+
+rand_decomp() ->
+ BT = bigtup(),
+ SZ = tuple_size(BT),
+ element(random:uniform(SZ),BT).
+bigtup() ->
+ {{192,[65,768]},
+ {200,[69,768]},
+ {204,[73,768]},
+ {210,[79,768]},
+ {217,[85,768]},
+ {7808,[87,768]},
+ {7922,[89,768]},
+ {224,[97,768]},
+ {232,[101,768]},
+ {236,[105,768]},
+ {242,[111,768]},
+ {249,[117,768]},
+ {7809,[119,768]},
+ {7923,[121,768]},
+ {8173,[168,768]},
+ {7846,[65,770,768]},
+ {7872,[69,770,768]},
+ {7890,[79,770,768]},
+ {7847,[97,770,768]},
+ {7873,[101,770,768]},
+ {7891,[111,770,768]},
+ {7700,[69,772,768]},
+ {7760,[79,772,768]},
+ {7701,[101,772,768]},
+ {7761,[111,772,768]},
+ {7856,[65,774,768]},
+ {7857,[97,774,768]},
+ {475,[85,776,768]},
+ {476,[117,776,768]},
+ {8146,[953,776,768]},
+ {8162,[965,776,768]},
+ {8074,[913,837,787,768]},
+ {8090,[919,837,787,768]},
+ {8106,[937,837,787,768]},
+ {8066,[945,837,787,768]},
+ {8082,[951,837,787,768]},
+ {8098,[969,837,787,768]},
+ {7946,[913,787,768]},
+ {7962,[917,787,768]},
+ {7978,[919,787,768]},
+ {7994,[921,787,768]},
+ {8010,[927,787,768]},
+ {8042,[937,787,768]},
+ {7938,[945,787,768]},
+ {7954,[949,787,768]},
+ {7970,[951,787,768]},
+ {7986,[953,787,768]},
+ {8002,[959,787,768]},
+ {8018,[965,787,768]},
+ {8034,[969,787,768]},
+ {8075,[913,837,788,768]},
+ {8091,[919,837,788,768]},
+ {8107,[937,837,788,768]},
+ {8067,[945,837,788,768]},
+ {8083,[951,837,788,768]},
+ {8099,[969,837,788,768]},
+ {7947,[913,788,768]},
+ {7963,[917,788,768]},
+ {7979,[919,788,768]},
+ {7995,[921,788,768]},
+ {8011,[927,788,768]},
+ {8027,[933,788,768]},
+ {8043,[937,788,768]},
+ {7939,[945,788,768]},
+ {7955,[949,788,768]},
+ {7971,[951,788,768]},
+ {7987,[953,788,768]},
+ {8003,[959,788,768]},
+ {8019,[965,788,768]},
+ {8035,[969,788,768]},
+ {7900,[79,795,768]},
+ {7914,[85,795,768]},
+ {7901,[111,795,768]},
+ {7915,[117,795,768]},
+ {8114,[945,837,768]},
+ {8130,[951,837,768]},
+ {8178,[969,837,768]},
+ {8122,[913,768]},
+ {8136,[917,768]},
+ {8138,[919,768]},
+ {8154,[921,768]},
+ {8184,[927,768]},
+ {8170,[933,768]},
+ {8186,[937,768]},
+ {8048,[945,768]},
+ {8050,[949,768]},
+ {8052,[951,768]},
+ {8054,[953,768]},
+ {8056,[959,768]},
+ {8058,[965,768]},
+ {8060,[969,768]},
+ {8141,[8127,768]},
+ {8157,[8190,768]},
+ {193,[65,769]},
+ {262,[67,769]},
+ {201,[69,769]},
+ {500,[71,769]},
+ {205,[73,769]},
+ {7728,[75,769]},
+ {313,[76,769]},
+ {7742,[77,769]},
+ {323,[78,769]},
+ {211,[79,769]},
+ {7764,[80,769]},
+ {340,[82,769]},
+ {346,[83,769]},
+ {218,[85,769]},
+ {7810,[87,769]},
+ {221,[89,769]},
+ {377,[90,769]},
+ {225,[97,769]},
+ {263,[99,769]},
+ {233,[101,769]},
+ {501,[103,769]},
+ {237,[105,769]},
+ {7729,[107,769]},
+ {314,[108,769]},
+ {7743,[109,769]},
+ {324,[110,769]},
+ {243,[111,769]},
+ {7765,[112,769]},
+ {341,[114,769]},
+ {347,[115,769]},
+ {250,[117,769]},
+ {7811,[119,769]},
+ {253,[121,769]},
+ {378,[122,769]},
+ {8174,[168,769]},
+ {508,[198,769]},
+ {510,[216,769]},
+ {509,[230,769]},
+ {511,[248,769]},
+ {7844,[65,770,769]},
+ {7870,[69,770,769]},
+ {7888,[79,770,769]},
+ {7845,[97,770,769]},
+ {7871,[101,770,769]},
+ {7889,[111,770,769]},
+ {7756,[79,771,769]},
+ {7800,[85,771,769]},
+ {7757,[111,771,769]},
+ {7801,[117,771,769]},
+ {7702,[69,772,769]},
+ {7762,[79,772,769]},
+ {7703,[101,772,769]},
+ {7763,[111,772,769]},
+ {7854,[65,774,769]},
+ {7855,[97,774,769]},
+ {7726,[73,776,769]},
+ {471,[85,776,769]},
+ {7727,[105,776,769]},
+ {472,[117,776,769]},
+ {8147,[953,776,769]},
+ {8163,[965,776,769]},
+ {506,[65,778,769]},
+ {507,[97,778,769]},
+ {8076,[913,837,787,769]},
+ {8092,[919,837,787,769]},
+ {8108,[937,837,787,769]},
+ {8068,[945,837,787,769]},
+ {8084,[951,837,787,769]},
+ {8100,[969,837,787,769]},
+ {7948,[913,787,769]},
+ {7964,[917,787,769]},
+ {7980,[919,787,769]},
+ {7996,[921,787,769]},
+ {8012,[927,787,769]},
+ {8044,[937,787,769]},
+ {7940,[945,787,769]},
+ {7956,[949,787,769]},
+ {7972,[951,787,769]},
+ {7988,[953,787,769]},
+ {8004,[959,787,769]},
+ {8020,[965,787,769]},
+ {8036,[969,787,769]},
+ {8077,[913,837,788,769]},
+ {8093,[919,837,788,769]},
+ {8109,[937,837,788,769]},
+ {8069,[945,837,788,769]},
+ {8085,[951,837,788,769]},
+ {8101,[969,837,788,769]},
+ {7949,[913,788,769]},
+ {7965,[917,788,769]},
+ {7981,[919,788,769]},
+ {7997,[921,788,769]},
+ {8013,[927,788,769]},
+ {8029,[933,788,769]},
+ {8045,[937,788,769]},
+ {7941,[945,788,769]},
+ {7957,[949,788,769]},
+ {7973,[951,788,769]},
+ {7989,[953,788,769]},
+ {8005,[959,788,769]},
+ {8021,[965,788,769]},
+ {8037,[969,788,769]},
+ {7898,[79,795,769]},
+ {7912,[85,795,769]},
+ {7899,[111,795,769]},
+ {7913,[117,795,769]},
+ {7688,[67,807,769]},
+ {7689,[99,807,769]},
+ {8116,[945,837,769]},
+ {8132,[951,837,769]},
+ {8180,[959,837,769]},
+ {8123,[913,769]},
+ {8137,[917,769]},
+ {8139,[919,769]},
+ {8155,[921,769]},
+ {8185,[927,769]},
+ {8171,[933,769]},
+ {8187,[937,769]},
+ {8049,[945,769]},
+ {8051,[949,769]},
+ {8053,[951,769]},
+ {8055,[953,769]},
+ {8057,[959,769]},
+ {8059,[965,769]},
+ {8061,[969,769]},
+ {1027,[1043,769]},
+ {1036,[1050,769]},
+ {1107,[1075,769]},
+ {1116,[1082,769]},
+ {8142,[8127,769]},
+ {8158,[8190,769]},
+ {194,[65,770]},
+ {264,[67,770]},
+ {202,[69,770]},
+ {284,[71,770]},
+ {292,[72,770]},
+ {206,[73,770]},
+ {308,[74,770]},
+ {212,[79,770]},
+ {348,[83,770]},
+ {219,[85,770]},
+ {372,[87,770]},
+ {374,[89,770]},
+ {7824,[90,770]},
+ {226,[97,770]},
+ {265,[99,770]},
+ {234,[101,770]},
+ {285,[103,770]},
+ {293,[104,770]},
+ {238,[105,770]},
+ {309,[106,770]},
+ {244,[111,770]},
+ {349,[115,770]},
+ {251,[117,770]},
+ {373,[119,770]},
+ {375,[121,770]},
+ {7825,[122,770]},
+ {7852,[65,803,770]},
+ {7878,[69,803,770]},
+ {7896,[79,803,770]},
+ {7853,[97,803,770]},
+ {7879,[101,803,770]},
+ {7897,[111,803,770]},
+ {195,[65,771]},
+ {7868,[69,771]},
+ {296,[73,771]},
+ {209,[78,771]},
+ {213,[79,771]},
+ {360,[85,771]},
+ {7804,[86,771]},
+ {7928,[89,771]},
+ {227,[97,771]},
+ {7869,[101,771]},
+ {297,[105,771]},
+ {241,[110,771]},
+ {245,[111,771]},
+ {361,[117,771]},
+ {7805,[118,771]},
+ {7929,[121,771]},
+ {7850,[65,770,771]},
+ {7876,[69,770,771]},
+ {7894,[79,770,771]},
+ {7851,[97,770,771]},
+ {7877,[101,770,771]},
+ {7895,[111,770,771]},
+ {7860,[65,774,771]},
+ {7861,[97,774,771]},
+ {7904,[79,795,771]},
+ {7918,[85,795,771]},
+ {7905,[111,795,771]},
+ {7919,[117,795,771]},
+ {256,[65,772]},
+ {274,[69,772]},
+ {7712,[71,772]},
+ {298,[73,772]},
+ {332,[79,772]},
+ {362,[85,772]},
+ {257,[97,772]},
+ {275,[101,772]},
+ {7713,[103,772]},
+ {299,[105,772]},
+ {333,[111,772]},
+ {363,[117,772]},
+ {482,[198,772]},
+ {483,[230,772]},
+ {480,[65,775,772]},
+ {481,[97,775,772]},
+ {478,[65,776,772]},
+ {469,[85,776,772]},
+ {479,[97,776,772]},
+ {470,[117,776,772]},
+ {7736,[76,803,772]},
+ {7772,[82,803,772]},
+ {7737,[108,803,772]},
+ {7773,[114,803,772]},
+ {492,[79,808,772]},
+ {493,[111,808,772]},
+ {8121,[913,772]},
+ {8153,[921,772]},
+ {8169,[933,772]},
+ {8113,[945,772]},
+ {8145,[953,772]},
+ {8161,[965,772]},
+ {1250,[1048,772]},
+ {1262,[1059,772]},
+ {1251,[1080,772]},
+ {1263,[1091,772]},
+ {258,[65,774]},
+ {276,[69,774]},
+ {286,[71,774]},
+ {300,[73,774]},
+ {334,[79,774]},
+ {364,[85,774]},
+ {259,[97,774]},
+ {277,[101,774]},
+ {287,[103,774]},
+ {301,[105,774]},
+ {335,[111,774]},
+ {365,[117,774]},
+ {7862,[65,803,774]},
+ {7863,[97,803,774]},
+ {7708,[69,807,774]},
+ {7709,[101,807,774]},
+ {8120,[913,774]},
+ {8152,[921,774]},
+ {8168,[933,774]},
+ {8112,[945,774]},
+ {8144,[953,774]},
+ {8160,[965,774]},
+ {1232,[1040,774]},
+ {1238,[1045,774]},
+ {1217,[1046,774]},
+ {1049,[1048,774]},
+ {1038,[1059,774]},
+ {1233,[1072,774]},
+ {1239,[1077,774]},
+ {1218,[1078,774]},
+ {1081,[1080,774]},
+ {1118,[1091,774]},
+ {7682,[66,775]},
+ {266,[67,775]},
+ {7690,[68,775]},
+ {278,[69,775]},
+ {7710,[70,775]},
+ {288,[71,775]},
+ {7714,[72,775]},
+ {304,[73,775]},
+ {7744,[77,775]},
+ {7748,[78,775]},
+ {7766,[80,775]},
+ {7768,[82,775]},
+ {7776,[83,775]},
+ {7786,[84,775]},
+ {7814,[87,775]},
+ {7818,[88,775]},
+ {7822,[89,775]},
+ {379,[90,775]},
+ {7683,[98,775]},
+ {267,[99,775]},
+ {7691,[100,775]},
+ {279,[101,775]},
+ {7711,[102,775]},
+ {289,[103,775]},
+ {7715,[104,775]},
+ {7745,[109,775]},
+ {7749,[110,775]},
+ {7767,[112,775]},
+ {7769,[114,775]},
+ {7777,[115,775]},
+ {7787,[116,775]},
+ {7815,[119,775]},
+ {7819,[120,775]},
+ {7823,[121,775]},
+ {380,[122,775]},
+ {7835,[383,775]},
+ {7780,[83,769,775]},
+ {7781,[115,769,775]},
+ {784,[774,775]},
+ {7782,[83,780,775]},
+ {7783,[115,780,775]},
+ {7784,[83,803,775]},
+ {7785,[115,803,775]},
+ {196,[65,776]},
+ {203,[69,776]},
+ {7718,[72,776]},
+ {207,[73,776]},
+ {214,[79,776]},
+ {220,[85,776]},
+ {7812,[87,776]},
+ {7820,[88,776]},
+ {376,[89,776]},
+ {228,[97,776]},
+ {235,[101,776]},
+ {7719,[104,776]},
+ {239,[105,776]},
+ {246,[111,776]},
+ {7831,[116,776]},
+ {252,[117,776]},
+ {7813,[119,776]},
+ {7821,[120,776]},
+ {255,[121,776]},
+ {1242,[399,776]},
+ {1258,[415,776]},
+ {1243,[601,776]},
+ {1259,[629,776]},
+ {7758,[79,771,776]},
+ {7759,[111,771,776]},
+ {7802,[85,772,776]},
+ {7803,[117,772,776]},
+ {938,[921,776]},
+ {939,[933,776]},
+ {970,[953,776]},
+ {971,[965,776]},
+ {980,[978,776]},
+ {1031,[1030,776]},
+ {1234,[1040,776]},
+ {1025,[1045,776]},
+ {1244,[1046,776]},
+ {1246,[1047,776]},
+ {1252,[1048,776]},
+ {1254,[1054,776]},
+ {1264,[1059,776]},
+ {1268,[1063,776]},
+ {1272,[1067,776]},
+ {1235,[1072,776]},
+ {1105,[1077,776]},
+ {1245,[1078,776]},
+ {1247,[1079,776]},
+ {1253,[1080,776]},
+ {1255,[1086,776]},
+ {1265,[1091,776]},
+ {1269,[1095,776]},
+ {1273,[1099,776]},
+ {1111,[1110,776]},
+ {7842,[65,777]},
+ {7866,[69,777]},
+ {7880,[73,777]},
+ {7886,[79,777]},
+ {7910,[85,777]},
+ {7926,[89,777]},
+ {7843,[97,777]},
+ {7867,[101,777]},
+ {7881,[105,777]},
+ {7887,[111,777]},
+ {7911,[117,777]},
+ {7927,[121,777]},
+ {7848,[65,770,777]},
+ {7874,[69,770,777]},
+ {7892,[79,770,777]},
+ {7849,[97,770,777]},
+ {7875,[101,770,777]},
+ {7893,[111,770,777]},
+ {7858,[65,774,777]},
+ {7859,[97,774,777]},
+ {7902,[79,795,777]},
+ {7916,[85,795,777]},
+ {7903,[111,795,777]},
+ {7917,[117,795,777]},
+ {197,[65,778]},
+ {366,[85,778]},
+ {229,[97,778]},
+ {367,[117,778]},
+ {7832,[119,778]},
+ {7833,[121,778]},
+ {336,[79,779]},
+ {368,[85,779]},
+ {337,[111,779]},
+ {369,[117,779]},
+ {1266,[1059,779]},
+ {1267,[1091,779]},
+ {461,[65,780]},
+ {268,[67,780]},
+ {270,[68,780]},
+ {282,[69,780]},
+ {486,[71,780]},
+ {463,[73,780]},
+ {488,[75,780]},
+ {317,[76,780]},
+ {327,[78,780]},
+ {465,[79,780]},
+ {344,[82,780]},
+ {352,[83,780]},
+ {356,[84,780]},
+ {467,[85,780]},
+ {381,[90,780]},
+ {462,[97,780]},
+ {269,[99,780]},
+ {271,[100,780]},
+ {283,[101,780]},
+ {487,[103,780]},
+ {464,[105,780]},
+ {496,[106,780]},
+ {489,[107,780]},
+ {318,[108,780]},
+ {328,[110,780]},
+ {466,[111,780]},
+ {345,[114,780]},
+ {353,[115,780]},
+ {357,[116,780]},
+ {468,[117,780]},
+ {382,[122,780]},
+ {494,[439,780]},
+ {495,[658,780]},
+ {473,[85,776,780]},
+ {474,[117,776,780]},
+ {901,[168,781]},
+ {912,[953,776,781]},
+ {944,[965,776,781]},
+ {902,[913,781]},
+ {904,[917,781]},
+ {905,[919,781]},
+ {906,[921,781]},
+ {908,[927,781]},
+ {910,[933,781]},
+ {911,[937,781]},
+ {940,[945,781]},
+ {941,[949,781]},
+ {942,[951,781]},
+ {943,[953,781]},
+ {972,[959,781]},
+ {973,[965,781]},
+ {974,[969,781]},
+ {979,[978,781]},
+ {512,[65,783]},
+ {516,[69,783]},
+ {520,[73,783]},
+ {524,[79,783]},
+ {528,[82,783]},
+ {532,[85,783]},
+ {513,[97,783]},
+ {517,[101,783]},
+ {521,[105,783]},
+ {525,[111,783]},
+ {529,[114,783]},
+ {533,[117,783]},
+ {1142,[1140,783]},
+ {1143,[1141,783]},
+ {514,[65,785]},
+ {518,[69,785]},
+ {522,[73,785]},
+ {526,[79,785]},
+ {530,[82,785]},
+ {534,[85,785]},
+ {515,[97,785]},
+ {519,[101,785]},
+ {523,[105,785]},
+ {527,[111,785]},
+ {531,[114,785]},
+ {535,[117,785]},
+ {8072,[913,837,787]},
+ {8088,[919,837,787]},
+ {8104,[937,837,787]},
+ {8064,[945,837,787]},
+ {8080,[951,837,787]},
+ {8096,[969,837,787]},
+ {7944,[913,787]},
+ {7960,[917,787]},
+ {7976,[919,787]},
+ {7992,[921,787]},
+ {8008,[927,787]},
+ {8040,[937,787]},
+ {7936,[945,787]},
+ {7952,[949,787]},
+ {7968,[951,787]},
+ {7984,[953,787]},
+ {8000,[959,787]},
+ {8164,[961,787]},
+ {8016,[965,787]},
+ {8032,[969,787]},
+ {8073,[913,837,788]},
+ {8089,[919,837,788]},
+ {8105,[937,837,788]},
+ {8065,[945,837,788]},
+ {8081,[951,837,788]},
+ {8097,[969,837,788]},
+ {7945,[913,788]},
+ {7961,[917,788]},
+ {7977,[919,788]},
+ {7993,[921,788]},
+ {8009,[927,788]},
+ {8172,[929,788]},
+ {8025,[933,788]},
+ {8041,[937,788]},
+ {7937,[945,788]},
+ {7953,[949,788]},
+ {7969,[951,788]},
+ {7985,[953,788]},
+ {8001,[959,788]},
+ {8165,[961,788]},
+ {8017,[965,788]},
+ {8033,[969,788]},
+ {416,[79,795]},
+ {431,[85,795]},
+ {417,[111,795]},
+ {432,[117,795]},
+ {7840,[65,803]},
+ {7684,[66,803]},
+ {7692,[68,803]},
+ {7864,[69,803]},
+ {7716,[72,803]},
+ {7882,[73,803]},
+ {7730,[75,803]},
+ {7734,[76,803]},
+ {7746,[77,803]},
+ {7750,[78,803]},
+ {7884,[79,803]},
+ {7770,[82,803]},
+ {7778,[83,803]},
+ {7788,[84,803]},
+ {7908,[85,803]},
+ {7806,[86,803]},
+ {7816,[87,803]},
+ {7924,[89,803]},
+ {7826,[90,803]},
+ {7841,[97,803]},
+ {7685,[98,803]},
+ {7693,[100,803]},
+ {7865,[101,803]},
+ {7717,[104,803]},
+ {7883,[105,803]},
+ {7731,[107,803]},
+ {7735,[108,803]},
+ {7747,[109,803]},
+ {7751,[110,803]},
+ {7885,[111,803]},
+ {7771,[114,803]},
+ {7779,[115,803]},
+ {7789,[116,803]},
+ {7909,[117,803]},
+ {7807,[118,803]},
+ {7817,[119,803]},
+ {7925,[121,803]},
+ {7827,[122,803]},
+ {7906,[79,795,803]},
+ {7920,[85,795,803]},
+ {7907,[111,795,803]},
+ {7921,[117,795,803]},
+ {7794,[85,804]},
+ {7795,[117,804]},
+ {7680,[65,805]},
+ {7681,[97,805]},
+ {199,[67,807]},
+ {7696,[68,807]},
+ {290,[71,807]},
+ {7720,[72,807]},
+ {310,[75,807]},
+ {315,[76,807]},
+ {325,[78,807]},
+ {342,[82,807]},
+ {350,[83,807]},
+ {354,[84,807]},
+ {231,[99,807]},
+ {7697,[100,807]},
+ {291,[103,807]},
+ {7721,[104,807]},
+ {311,[107,807]},
+ {316,[108,807]},
+ {326,[110,807]},
+ {343,[114,807]},
+ {351,[115,807]},
+ {355,[116,807]},
+ {260,[65,808]},
+ {280,[69,808]},
+ {302,[73,808]},
+ {490,[79,808]},
+ {370,[85,808]},
+ {261,[97,808]},
+ {281,[101,808]},
+ {303,[105,808]},
+ {491,[111,808]},
+ {371,[117,808]},
+ {7698,[68,813]},
+ {7704,[69,813]},
+ {7740,[76,813]},
+ {7754,[78,813]},
+ {7792,[84,813]},
+ {7798,[85,813]},
+ {7699,[100,813]},
+ {7705,[101,813]},
+ {7741,[108,813]},
+ {7755,[110,813]},
+ {7793,[116,813]},
+ {7799,[117,813]},
+ {7722,[72,814]},
+ {7723,[104,814]},
+ {7706,[69,816]},
+ {7724,[73,816]},
+ {7796,[85,816]},
+ {7707,[101,816]},
+ {7725,[105,816]},
+ {7797,[117,816]},
+ {7686,[66,817]},
+ {7694,[68,817]},
+ {7732,[75,817]},
+ {7738,[76,817]},
+ {7752,[78,817]},
+ {7774,[82,817]},
+ {7790,[84,817]},
+ {7828,[90,817]},
+ {7687,[98,817]},
+ {7695,[100,817]},
+ {7830,[104,817]},
+ {7733,[107,817]},
+ {7739,[108,817]},
+ {7753,[110,817]},
+ {7775,[114,817]},
+ {7791,[116,817]},
+ {7829,[122,817]},
+ {8129,[168,834]},
+ {8151,[953,776,834]},
+ {8167,[965,776,834]},
+ {8078,[913,837,787,834]},
+ {8094,[919,837,787,834]},
+ {8110,[937,837,787,834]},
+ {8070,[945,837,787,834]},
+ {8086,[951,837,787,834]},
+ {8102,[969,837,787,834]},
+ {7950,[913,787,834]},
+ {7982,[919,787,834]},
+ {7998,[921,787,834]},
+ {8046,[937,787,834]},
+ {7942,[945,787,834]},
+ {7974,[951,787,834]},
+ {7990,[953,787,834]},
+ {8022,[965,787,834]},
+ {8038,[969,787,834]},
+ {8079,[913,837,788,834]},
+ {8095,[919,837,788,834]},
+ {8111,[937,837,788,834]},
+ {8071,[945,837,788,834]},
+ {8087,[951,837,788,834]},
+ {8103,[969,837,788,834]},
+ {7951,[913,788,834]},
+ {7983,[919,788,834]},
+ {7999,[921,788,834]},
+ {8031,[933,788,834]},
+ {8047,[937,788,834]},
+ {7943,[945,788,834]},
+ {7975,[951,788,834]},
+ {7991,[953,788,834]},
+ {8023,[965,788,834]},
+ {8039,[969,788,834]},
+ {8119,[945,837,834]},
+ {8135,[951,837,834]},
+ {8183,[969,837,834]},
+ {8118,[945,834]},
+ {8134,[951,834]},
+ {8150,[953,834]},
+ {8166,[965,834]},
+ {8182,[969,834]},
+ {8143,[8127,834]},
+ {8159,[8190,834]},
+ {8124,[913,837]},
+ {8140,[919,837]},
+ {8188,[937,837]},
+ {8115,[945,837]},
+ {8131,[951,837]},
+ {8179,[969,837]},
+ {64302,[1488,1463]},
+ {64287,[1522,1463]},
+ {64303,[1488,1464]},
+ {64331,[1493,1465]},
+ {64304,[1488,1468]},
+ {64305,[1489,1468]},
+ {64306,[1490,1468]},
+ {64307,[1491,1468]},
+ {64308,[1492,1468]},
+ {64309,[1493,1468]},
+ {64310,[1494,1468]},
+ {64312,[1496,1468]},
+ {64313,[1497,1468]},
+ {64314,[1498,1468]},
+ {64315,[1499,1468]},
+ {64316,[1500,1468]},
+ {64318,[1502,1468]},
+ {64320,[1504,1468]},
+ {64321,[1505,1468]},
+ {64323,[1507,1468]},
+ {64324,[1508,1468]},
+ {64326,[1510,1468]},
+ {64327,[1511,1468]},
+ {64328,[1512,1468]},
+ {64329,[1513,1468]},
+ {64330,[1514,1468]},
+ {64332,[1489,1471]},
+ {64333,[1499,1471]},
+ {64334,[1508,1471]},
+ {64300,[1513,1468,1473]},
+ {64298,[1513,1473]},
+ {64301,[1513,1468,1474]},
+ {64299,[1513,1474]},
+ {2392,[2325,2364]},
+ {2393,[2326,2364]},
+ {2394,[2327,2364]},
+ {2395,[2332,2364]},
+ {2396,[2337,2364]},
+ {2397,[2338,2364]},
+ {2345,[2344,2364]},
+ {2398,[2347,2364]},
+ {2399,[2351,2364]},
+ {2353,[2352,2364]},
+ {2356,[2355,2364]},
+ {2524,[2465,2492]},
+ {2525,[2466,2492]},
+ {2480,[2476,2492]},
+ {2527,[2479,2492]},
+ {2507,[2503,2494]},
+ {2508,[2503,2519]},
+ {2649,[2582,2620]},
+ {2650,[2583,2620]},
+ {2651,[2588,2620]},
+ {2652,[2593,2620]},
+ {2654,[2603,2620]},
+ {2908,[2849,2876]},
+ {2909,[2850,2876]},
+ {2911,[2863,2876]},
+ {2891,[2887,2878]},
+ {2888,[2887,2902]},
+ {2892,[2887,2903]},
+ {3018,[3014,3006]},
+ {3019,[3015,3006]},
+ {2964,[2962,3031]},
+ {3020,[3014,3031]},
+ {3144,[3142,3158]},
+ {3274,[3270,3266]},
+ {3264,[3263,3285]},
+ {3275,[3270,3266,3285]},
+ {3271,[3270,3285]},
+ {3272,[3270,3286]},
+ {3402,[3398,3390]},
+ {3403,[3399,3390]},
+ {3404,[3398,3415]},
+ {3635,[3661,3634]},
+ {3763,[3789,3762]},
+ {3955,[3954,3953]},
+ {3957,[3956,3953]},
+ {3959,[4018,3968,3953]},
+ {3961,[4019,3968,3953]},
+ {3958,[4018,3968]},
+ {3960,[4019,3968]},
+ {3945,[3904,4021]},
+ {4025,[3984,4021]},
+ {3907,[3906,4023]},
+ {3917,[3916,4023]},
+ {3922,[3921,4023]},
+ {3927,[3926,4023]},
+ {3932,[3931,4023]},
+ {3987,[3986,4023]},
+ {3997,[3996,4023]},
+ {4002,[4001,4023]},
+ {4007,[4006,4023]},
+ {4012,[4011,4023]},
+ {12436,[12358,12441]},
+ {12364,[12363,12441]},
+ {12366,[12365,12441]},
+ {12368,[12367,12441]},
+ {12370,[12369,12441]},
+ {12372,[12371,12441]},
+ {12374,[12373,12441]},
+ {12376,[12375,12441]},
+ {12378,[12377,12441]},
+ {12380,[12379,12441]},
+ {12382,[12381,12441]},
+ {12384,[12383,12441]},
+ {12386,[12385,12441]},
+ {12389,[12388,12441]},
+ {12391,[12390,12441]},
+ {12393,[12392,12441]},
+ {12400,[12399,12441]},
+ {12403,[12402,12441]},
+ {12406,[12405,12441]},
+ {12409,[12408,12441]},
+ {12412,[12411,12441]},
+ {12446,[12445,12441]},
+ {12532,[12454,12441]},
+ {12460,[12459,12441]},
+ {12462,[12461,12441]},
+ {12464,[12463,12441]},
+ {12466,[12465,12441]},
+ {12468,[12467,12441]},
+ {12470,[12469,12441]},
+ {12472,[12471,12441]},
+ {12474,[12473,12441]},
+ {12476,[12475,12441]},
+ {12478,[12477,12441]},
+ {12480,[12479,12441]},
+ {12482,[12481,12441]},
+ {12485,[12484,12441]},
+ {12487,[12486,12441]},
+ {12489,[12488,12441]},
+ {12496,[12495,12441]},
+ {12499,[12498,12441]},
+ {12502,[12501,12441]},
+ {12505,[12504,12441]},
+ {12508,[12507,12441]},
+ {12535,[12527,12441]},
+ {12536,[12528,12441]},
+ {12537,[12529,12441]},
+ {12538,[12530,12441]},
+ {12542,[12541,12441]},
+ {12401,[12399,12442]},
+ {12404,[12402,12442]},
+ {12407,[12405,12442]},
+ {12410,[12408,12442]},
+ {12413,[12411,12442]},
+ {12497,[12495,12442]},
+ {12500,[12498,12442]},
+ {12503,[12501,12442]},
+ {12506,[12504,12442]},
+ {12509,[12507,12442]}}.
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index 9aa94a0868..d3aa62d7ec 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -18,26 +18,58 @@
%%
-module(gen_sctp_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/inet_sctp.hrl").
%%-compile(export_all).
--export([all/1,init_per_testcase/2,fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,
+ init_per_suite/1,end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
-export(
[basic/1,
api_open_close/1,api_listen/1,api_connect_init/1,api_opts/1,
xfer_min/1,xfer_active/1,def_sndrcvinfo/1,implicit_inet6/1]).
-all(suite) ->
- [basic,
- api_open_close,api_listen,api_connect_init,api_opts,
- xfer_min,xfer_active,def_sndrcvinfo,implicit_inet6].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic, api_open_close, api_listen, api_connect_init,
+ api_opts, xfer_min, xfer_active, def_sndrcvinfo,
+ implicit_inet6].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ try gen_sctp:open() of
+ {ok,Socket} ->
+ gen_sctp:close(Socket),
+ [];
+ _ ->
+ []
+ catch
+ error:badarg ->
+ {skip,"SCTP not supported on this machine"};
+ _:_ ->
+ Config
+ end.
+
+end_per_suite(_Conifig) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Func, Config) ->
Dog = test_server:timetrap(test_server:seconds(15)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
diff --git a/lib/kernel/test/gen_tcp_api_SUITE.erl b/lib/kernel/test/gen_tcp_api_SUITE.erl
index 94637290a1..c8fe602ac2 100644
--- a/lib/kernel/test/gen_tcp_api_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_api_SUITE.erl
@@ -22,30 +22,52 @@
%% are not tested here, because they are tested indirectly in this and
%% and other test suites.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/inet.hrl").
--export([all/1, init_per_testcase/2, fin_per_testcase/2,
- t_accept/1, t_connect_timeout/1, t_accept_timeout/1,
- t_connect/1, t_connect_bad/1,
- t_recv/1, t_recv_timeout/1, t_recv_eof/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
+ t_connect_timeout/1, t_accept_timeout/1,
+ t_connect_bad/1,
+ t_recv_timeout/1, t_recv_eof/1,
t_shutdown_write/1, t_shutdown_both/1, t_shutdown_error/1,
t_fdopen/1, t_implicit_inet6/1]).
-all(suite) -> [t_accept, t_connect, t_recv, t_shutdown_write,
- t_shutdown_both, t_shutdown_error, t_fdopen,
- t_implicit_inet6].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, t_accept}, {group, t_connect}, {group, t_recv},
+ t_shutdown_write, t_shutdown_both, t_shutdown_error,
+ t_fdopen, t_implicit_inet6].
+
+groups() ->
+ [{t_accept, [], [t_accept_timeout]},
+ {t_connect, [], [t_connect_timeout, t_connect_bad]},
+ {t_recv, [], [t_recv_timeout, t_recv_eof]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Func, Config) ->
Dog = test_server:timetrap(test_server:seconds(60)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
%%% gen_tcp:accept/1,2
-t_accept(suite) -> [t_accept_timeout].
t_accept_timeout(doc) -> "Test that gen_tcp:accept/2 (with timeout) works.";
t_accept_timeout(suite) -> [];
@@ -55,7 +77,6 @@ t_accept_timeout(Config) when is_list(Config) ->
%%% gen_tcp:connect/X
-t_connect(suite) -> [t_connect_timeout, t_connect_bad].
t_connect_timeout(doc) -> "Test that gen_tcp:connect/4 (with timeout) works.";
t_connect_timeout(Config) when is_list(Config) ->
@@ -84,7 +105,6 @@ t_connect_bad(Config) when is_list(Config) ->
%%% gen_tcp:recv/X
-t_recv(suite) -> [t_recv_timeout, t_recv_eof].
t_recv_timeout(doc) -> "Test that gen_tcp:recv/3 (with timeout works).";
t_recv_timeout(suite) -> [];
diff --git a/lib/kernel/test/gen_tcp_echo_SUITE.erl b/lib/kernel/test/gen_tcp_echo_SUITE.erl
index a2e09877af..830e2d9c39 100644
--- a/lib/kernel/test/gen_tcp_echo_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_echo_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-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
@@ -18,11 +18,13 @@
%%
-module(gen_tcp_echo_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%%-compile(export_all).
--export([all/1, init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
active_echo/1, passive_echo/1, active_once_echo/1,
slow_active_echo/1, slow_passive_echo/1,
limit_active_echo/1, limit_passive_echo/1,
@@ -31,16 +33,34 @@
-define(TPKT_VRSN, 3).
-define(LINE_LENGTH, 1023). % (default value of gen_tcp option 'recbuf') - 1
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[active_echo, passive_echo, active_once_echo,
- slow_active_echo, slow_passive_echo,
- limit_active_echo, limit_passive_echo,
- large_limit_active_echo, large_limit_passive_echo].
+ slow_active_echo, slow_passive_echo, limit_active_echo,
+ limit_passive_echo, large_limit_active_echo,
+ large_limit_passive_echo].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Func, Config) ->
Dog = test_server:timetrap(test_server:minutes(5)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl
index d73c5fab56..c3ce6497bb 100644
--- a/lib/kernel/test/gen_tcp_misc_SUITE.erl
+++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl
@@ -18,14 +18,16 @@
%%
-module(gen_tcp_misc_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%-compile(export_all).
--export([all/1, controlling_process/1, no_accept/1, close_with_pending_output/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ controlling_process/1, no_accept/1, close_with_pending_output/1,
data_before_close/1, iter_max_socks/1, get_status/1,
passive_sockets/1, accept_closed_by_other_process/1,
- init_per_testcase/2, fin_per_testcase/2,
+ init_per_testcase/2, end_per_testcase/2,
otp_3924/1, otp_3924_sender/4, closed_socket/1,
shutdown_active/1, shutdown_passive/1, shutdown_pending/1,
default_options/1, http_bad_packet/1,
@@ -34,39 +36,60 @@
partial_recv_and_close_2/1,partial_recv_and_close_3/1,so_priority/1,
% Accept tests
primitive_accept/1,multi_accept_close_listen/1,accept_timeout/1,
- accept_timeouts_in_order/1,accept_timeouts_in_order2/1,accept_timeouts_in_order3/1,
- accept_timeouts_mixed/1,
+ accept_timeouts_in_order/1,accept_timeouts_in_order2/1,
+ accept_timeouts_in_order3/1,accept_timeouts_mixed/1,
killing_acceptor/1,killing_multi_acceptors/1,killing_multi_acceptors2/1,
- several_accepts_in_one_go/1,active_once_closed/1, send_timeout/1, otp_7731/1,
- zombie_sockets/1, otp_7816/1, otp_8102/1]).
+ several_accepts_in_one_go/1,active_once_closed/1, send_timeout/1,
+ otp_7731/1, zombie_sockets/1, otp_7816/1, otp_8102/1]).
%% Internal exports.
--export([sender/3, not_owner/1, passive_sockets_server/2, priority_server/1, otp_7731_server/1, zombie_server/2]).
+-export([sender/3, not_owner/1, passive_sockets_server/2, priority_server/1,
+ otp_7731_server/1, zombie_server/2]).
init_per_testcase(_Func, Config) when is_list(Config) ->
Dog = test_server:timetrap(test_server:seconds(240)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[controlling_process, no_accept,
- close_with_pending_output,
- data_before_close, iter_max_socks, passive_sockets,
+ close_with_pending_output, data_before_close,
+ iter_max_socks, passive_sockets,
accept_closed_by_other_process, otp_3924, closed_socket,
shutdown_active, shutdown_passive, shutdown_pending,
- default_options, http_bad_packet,
- busy_send, busy_disconnect_passive, busy_disconnect_active,
- fill_sendq, partial_recv_and_close,
- partial_recv_and_close_2, partial_recv_and_close_3, so_priority,
- primitive_accept,multi_accept_close_listen,accept_timeout,
- accept_timeouts_in_order,accept_timeouts_in_order2,accept_timeouts_in_order3,
- accept_timeouts_mixed,
- killing_acceptor,killing_multi_acceptors,killing_multi_acceptors2,
- several_accepts_in_one_go, active_once_closed, send_timeout, otp_7731,
+ default_options, http_bad_packet, busy_send,
+ busy_disconnect_passive, busy_disconnect_active,
+ fill_sendq, partial_recv_and_close,
+ partial_recv_and_close_2, partial_recv_and_close_3,
+ so_priority, primitive_accept,
+ multi_accept_close_listen, accept_timeout,
+ accept_timeouts_in_order, accept_timeouts_in_order2,
+ accept_timeouts_in_order3, accept_timeouts_mixed,
+ killing_acceptor, killing_multi_acceptors,
+ killing_multi_acceptors2, several_accepts_in_one_go,
+ active_once_closed, send_timeout, otp_7731,
zombie_sockets, otp_7816, otp_8102].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
default_options(doc) ->
["Tests kernel application variables inet_default_listen_options and "
diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl
index bbdfbd3cb0..ee9288bc75 100644
--- a/lib/kernel/test/gen_udp_SUITE.erl
+++ b/lib/kernel/test/gen_udp_SUITE.erl
@@ -21,7 +21,7 @@
% because udp is not deterministic.
%
-module(gen_udp_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(default_timeout, ?t:minutes(1)).
@@ -29,23 +29,42 @@
% XXX - we should pick a port that we _know_ is closed. That's pretty hard.
-define(CLOSED_PORT, 6666).
--export([all/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([send_to_closed/1,
buffer_size/1, binary_passive_recv/1, bad_address/1,
read_packets/1, open_fd/1, connect/1, implicit_inet6/1]).
-all(suite) ->
- [send_to_closed,
- buffer_size, binary_passive_recv, bad_address, read_packets,
- open_fd, connect, implicit_inet6].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [send_to_closed, buffer_size, binary_passive_recv,
+ bad_address, read_packets, open_fd, connect,
+ implicit_inet6].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -423,7 +442,11 @@ connect(Config) when is_list(Config) ->
?line ok = gen_udp:close(S1),
?line ok = gen_udp:connect(S2, Addr, P1),
?line ok = gen_udp:send(S2, <<16#deadbeef:32>>),
- ?line {error,econnrefused} = gen_udp:recv(S2, 0, 5),
+ ?line ok = case gen_udp:recv(S2, 0, 5) of
+ {error,econnrefused} -> ok;
+ {error,econnreset} -> ok;
+ Other -> Other
+ end,
ok.
implicit_inet6(Config) when is_list(Config) ->
diff --git a/lib/kernel/test/global_SUITE.erl b/lib/kernel/test/global_SUITE.erl
index 7a84ad5e75..c88e0f60bb 100644
--- a/lib/kernel/test/global_SUITE.erl
+++ b/lib/kernel/test/global_SUITE.erl
@@ -20,7 +20,8 @@
%-define(line_trace, 1).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
names/1, names_hidden/1, locks/1, locks_hidden/1,
bad_input/1, names_and_locks/1, lock_die/1, name_die/1,
basic_partition/1, basic_name_partition/1,
@@ -42,14 +43,14 @@
-export([global_load/3, lock_global/2, lock_global2/2]).
--export([ttt/1]).
+-export([]).
-export([mass_spawn/1]).
-export([start_tracer/0, stop_tracer/0, get_trace/0]).
-compile(export_all).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(NODES, [node()|nodes()]).
@@ -58,41 +59,62 @@
%% The resource used by the global module.
-define(GLOBAL_LOCK, global).
-ttt(suite) ->
- [
-%% 5&6: succeeds
-%% 4&5&6: succeeds
-%% 3&4&5&6: succeeds
-%% 1&2&3&6: fails
-%% 1&2&6: succeeds
-%% 3&6: succeeds
- names, names_hidden, locks, locks_hidden,
- bad_input,
- names_and_locks, lock_die, name_die, basic_partition,
-% advanced_partition, basic_name_partition,
-% stress_partition, simple_ring, simple_line,
- ring].
-
-all(suite) ->
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
case init:get_argument(ring_line) of
- {ok, _} ->
- [ring_line];
+ {ok, _} -> [ring_line];
_ ->
- [names, names_hidden, locks, locks_hidden,
- bad_input,
+ [names, names_hidden, locks, locks_hidden, bad_input,
names_and_locks, lock_die, name_die, basic_partition,
advanced_partition, basic_name_partition,
- stress_partition, simple_ring, simple_line,
- ring, line, global_lost_nodes, otp_1849,
- otp_3162, otp_5640, otp_5737, otp_6931,
- simple_disconnect, simple_resolve, simple_resolve2,
- simple_resolve3,
- leftover_name, re_register_name, name_exit,
- external_nodes, many_nodes, sync_0, global_groups_change,
- register_1, both_known_1, lost_unregister,
- mass_death, garbage_messages]
+ stress_partition, simple_ring, simple_line, ring, line,
+ global_lost_nodes, otp_1849, otp_3162, otp_5640,
+ otp_5737, otp_6931, simple_disconnect, simple_resolve,
+ simple_resolve2, simple_resolve3, leftover_name,
+ re_register_name, name_exit, external_nodes, many_nodes,
+ sync_0, global_groups_change, register_1, both_known_1,
+ lost_unregister, mass_death, garbage_messages]
end.
+groups() ->
+ [{ttt, [],
+ [names, names_hidden, locks, locks_hidden, bad_input,
+ names_and_locks, lock_die, name_die, basic_partition,
+ ring]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_suite(Config) ->
+
+ %% Copied from test_server_ctrl ln 647, we have to do this here as
+ %% the test_server only does this when run without common_test
+ global:sync(),
+ case global:whereis_name(test_server) of
+ undefined ->
+ io:format(user, "Registering test_server globally!~n",[]),
+ global:register_name(test_server, whereis(test_server_ctrl));
+ Pid ->
+ case node() of
+ N when N == node(Pid) ->
+ io:format(user, "Warning: test_server already running!\n", []),
+ global:re_register_name(test_server,self());
+ _ ->
+ ok
+ end
+ end,
+ Config.
+
+end_per_suite(_Config) ->
+ global:unregister_name(test_server),
+ ok.
+
+
-define(TESTCASE, testcase_name).
-define(testcase, ?config(?TESTCASE, Config)).
-define(nodes_tag, '$global_nodes').
@@ -100,9 +122,16 @@ all(suite) ->
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
ok = gen_server:call(global_name_server, high_level_trace_start,infinity),
+
+ %% Make sure that everything is dead and done. Otherwise there are problems
+ %% on platforms on which it takes a long time to shut down a node.
+ stop_nodes(nodes()),
+ timer:sleep(1000),
+
[{?TESTCASE, Case}, {registered, registered()} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
+ ct:log("Calling end_per_testcase!",[]),
?line write_high_level_trace(Config),
?line _ =
gen_server:call(global_name_server, high_level_trace_stop, infinity),
@@ -114,6 +143,7 @@ fin_per_testcase(_Case, Config) ->
{What, N} <- [{"Added", Registered -- InitRegistered},
{"Removed", InitRegistered -- Registered}],
N =/= []],
+
ok.
%%% General comments:
diff --git a/lib/kernel/test/global_group_SUITE.erl b/lib/kernel/test/global_group_SUITE.erl
index 430cc61267..c113bbc0cb 100644
--- a/lib/kernel/test/global_group_SUITE.erl
+++ b/lib/kernel/test/global_group_SUITE.erl
@@ -19,25 +19,61 @@
-module(global_group_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1]).
-export([start_gg_proc/1, no_gg_proc/1, no_gg_proc_sync/1, compatible/1,
one_grp/1, one_grp_x/1, two_grp/1, hidden_groups/1, test_exit/1]).
-export([init/1, init/2, init2/2, start_proc/1, start_proc_rereg/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%-compile(export_all).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(NODES, [node()|nodes()]).
-define(UNTIL(Seq), loop_until_true(fun() -> Seq end)).
-all(suite) ->
- [start_gg_proc, no_gg_proc, no_gg_proc_sync,
- compatible, one_grp, one_grp_x, two_grp, test_exit,
- hidden_groups].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [start_gg_proc, no_gg_proc, no_gg_proc_sync, compatible,
+ one_grp, one_grp_x, two_grp, test_exit, hidden_groups].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(Config) ->
+
+ %% Copied from test_server_ctrl ln 647, we have to do this here as
+ %% the test_server only does this when run without common_test
+ global:sync(),
+ case global:whereis_name(test_server) of
+ undefined ->
+ io:format(user, "Registering test_server globally!~n",[]),
+ global:register_name(test_server, whereis(test_server_ctrl));
+ Pid ->
+ case node() of
+ N when N == node(Pid) ->
+ io:format(user, "Warning: test_server already running!\n", []),
+ global:re_register_name(test_server,self());
+ _ ->
+ ok
+ end
+ end,
+ Config.
+
+end_per_suite(_Config) ->
+ global:unregister_name(test_server),
+ ok.
-define(TESTCASE, testcase_name).
-define(testcase, ?config(?TESTCASE, Config)).
@@ -46,7 +82,7 @@ init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(5)),
[{?TESTCASE, Case}, {watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
@@ -164,8 +200,8 @@ no_gg_proc(Config) when is_list(Config) ->
?line Own_nodes_should = [node(), Cp1nn, Cp2nn, Cp3nn,
Cpxnn, Cpynn, Cpznn],
?line Own_nodes = rpc:call(Cp3, global_group, own_nodes, []),
- ?line true = (Own_nodes -- Own_nodes_should) =:= [],
- ?line true = (Own_nodes_should -- Own_nodes) =:= [],
+ ?line [] = (Own_nodes -- Own_nodes_should),
+ ?line [] = (Own_nodes_should -- Own_nodes),
?line Pid2 = rpc:call(Cp1, global_group, send, [test2, {ping, self()}]),
?line receive
@@ -339,8 +375,8 @@ no_gg_proc_sync(Config) when is_list(Config) ->
?line Own_nodes_should = [node(), Cp1nn, Cp2nn, Cp3nn,
Cpxnn, Cpynn, Cpznn],
?line Own_nodes = rpc:call(Cp3, global_group, own_nodes, []),
- ?line true = (Own_nodes -- Own_nodes_should) =:= [],
- ?line true = (Own_nodes_should -- Own_nodes) =:= [],
+ ?line [] = (Own_nodes -- Own_nodes_should),
+ ?line [] = (Own_nodes_should -- Own_nodes),
?line Pid2 = rpc:call(Cp1, global_group, send, [test2, {ping, self()}]),
?line receive
@@ -513,8 +549,8 @@ compatible(Config) when is_list(Config) ->
?line Own_nodes_should = [node(), Cp1nn, Cp2nn, Cp3nn,
Cpxnn, Cpynn, Cpznn],
?line Own_nodes = rpc:call(Cp3, global_group, own_nodes, []),
- ?line true = (Own_nodes -- Own_nodes_should) =:= [],
- ?line true = (Own_nodes_should -- Own_nodes) =:= [],
+ ?line [] = (Own_nodes -- Own_nodes_should),
+ ?line [] = (Own_nodes_should -- Own_nodes),
?line Pid2 = rpc:call(Cp1, global_group, send, [test2, {ping, self()}]),
?line receive
diff --git a/lib/kernel/test/heart_SUITE.erl b/lib/kernel/test/heart_SUITE.erl
index 0d0296238b..e82eabe530 100644
--- a/lib/kernel/test/heart_SUITE.erl
+++ b/lib/kernel/test/heart_SUITE.erl
@@ -18,12 +18,14 @@
%%
-module(heart_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1, ostype/1, start/1, restart/1, reboot/1, set_cmd/1, clear_cmd/1,
- dont_drop/1, kill_pid/1, fini/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, start/1, restart/1,
+ reboot/1, set_cmd/1, clear_cmd/1,
+ dont_drop/1, kill_pid/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([start_heart_stress/1, mangle/1, suicide_by_heart/0]).
@@ -33,7 +35,7 @@ init_per_testcase(_Func, Config) ->
Dog=test_server:timetrap(test_server:seconds(?DEFAULT_TIMEOUT_SECS)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Nodes = nodes(),
lists:foreach(fun(X) ->
NNam = list_to_atom(hd(string:tokens(atom_to_list(X),"@"))),
@@ -53,18 +55,29 @@ fin_per_testcase(_Func, Config) ->
%% Should be started in a CC view with:
%% erl -sname master -rsh ctrsh
%%-----------------------------------------------------------------
-all(suite) ->
- [{conf, ostype, [start, restart, reboot,
- set_cmd, clear_cmd, kill_pid], fini}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-ostype(Config) when is_list(Config) ->
+all() ->
+ [start, restart, reboot, set_cmd, clear_cmd, kill_pid].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(Config) when is_list(Config) ->
case os:type() of
{win32, windows} ->
{skipped, "No use to run on Windows 95/98"};
_ ->
Config
end.
-fini(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
Config.
start_check(Type, Name) ->
diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl
index f4f27933a5..523e5c63ce 100644
--- a/lib/kernel/test/inet_SUITE.erl
+++ b/lib/kernel/test/inet_SUITE.erl
@@ -18,29 +18,72 @@
%%
-module(inet_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/inet.hrl").
-include_lib("kernel/src/inet_dns.hrl").
--export([all/1, t_gethostbyaddr/1, t_getaddr/1, t_gethostbyname/1,
- t_gethostbyaddr_v6/1, t_getaddr_v6/1, t_gethostbyname_v6/1,
- ipv4_to_ipv6/1, host_and_addr/1, parse/1, t_gethostnative/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ t_gethostbyaddr/0, t_gethostbyaddr/1,
+ t_getaddr/0, t_getaddr/1,
+ t_gethostbyname/0, t_gethostbyname/1,
+ t_gethostbyaddr_v6/0, t_gethostbyaddr_v6/1,
+ t_getaddr_v6/0, t_getaddr_v6/1,
+ t_gethostbyname_v6/0, t_gethostbyname_v6/1,
+ ipv4_to_ipv6/0, ipv4_to_ipv6/1,
+ host_and_addr/0, host_and_addr/1,
+ t_gethostnative/1,
gethostnative_parallell/1, cname_loop/1,
- gethostnative_soft_restart/1,gethostnative_debug_level/1,getif/1,
- getif_ifr_name_overflow/1,getservbyname_overflow/1]).
+ gethostnative_soft_restart/0, gethostnative_soft_restart/1,
+ gethostnative_debug_level/0, gethostnative_debug_level/1,
+ getif/1,
+ getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1]).
-export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1,
kill_gethost/0, parallell_gethost/0]).
-export([init_per_testcase/2, end_per_testcase/2]).
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [t_gethostbyaddr, t_gethostbyname, t_getaddr,
+ t_gethostbyaddr_v6, t_gethostbyname_v6, t_getaddr_v6,
+ ipv4_to_ipv6, host_and_addr, {group, parse},
+ t_gethostnative, gethostnative_parallell, cname_loop,
+ gethostnative_debug_level, gethostnative_soft_restart,
+ getif, getif_ifr_name_overflow, getservbyname_overflow,
+ getifaddrs].
+
+groups() ->
+ [{parse, [], [parse_hosts, parse_address]}].
+
+%% Required configuaration
+required(v4) ->
+ [{require, test_host_ipv4_only},
+ {require, test_dummy_host}];
+required(v6) ->
+ [{require, test_host_ipv6_only},
+ {require, test_dummy_ipv6_host}];
+required(hosts) ->
+ case os:type() of
+ {OS, _} when OS =:= win32; OS =:= vxworks ->
+ [{require, hardcoded_hosts},
+ {require, hardcoded_ipv6_hosts}];
+ _Else ->
+ [{require, test_hosts}]
+ end.
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [t_gethostbyaddr, t_gethostbyname, t_getaddr,
- t_gethostbyaddr_v6, t_gethostbyname_v6, t_getaddr_v6,
- ipv4_to_ipv6, host_and_addr, parse,t_gethostnative,
- gethostnative_parallell, cname_loop,
- gethostnative_debug_level,gethostnative_soft_restart,
- getif,getif_ifr_name_overflow,getservbyname_overflow].
+end_per_group(_GroupName, Config) ->
+ Config.
init_per_testcase(_Func, Config) ->
Dog = test_server:timetrap(test_server:seconds(60)),
@@ -50,10 +93,12 @@ end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
-
+t_gethostbyaddr() ->
+ required(v4).
t_gethostbyaddr(doc) -> "Test the inet:gethostbyaddr/1 function.";
t_gethostbyaddr(Config) when is_list(Config) ->
- ?line {Name,FullName,IPStr,IP,Aliases,_,_} = ?config(test_host_ipv4_only, Config),
+ ?line {Name,FullName,IPStr,IP,Aliases,_,_} =
+ ct:get_config(test_host_ipv4_only),
?line {ok,HEnt} = inet:gethostbyaddr(IPStr),
?line {ok,HEnt} = inet:gethostbyaddr(IP),
?line {error,Error} = inet:gethostbyaddr(Name),
@@ -75,15 +120,16 @@ t_gethostbyaddr(Config) when is_list(Config) ->
end,
?line {_DName, _DFullName, DIPStr, DIP, _, _, _} =
- ?config(test_dummy_host, Config),
+ ct:get_config(test_dummy_host),
?line {error,nxdomain} = inet:gethostbyaddr(DIPStr),
?line {error,nxdomain} = inet:gethostbyaddr(DIP),
ok.
+t_gethostbyaddr_v6() -> required(v6).
t_gethostbyaddr_v6(doc) -> "Test the inet:gethostbyaddr/1 inet6 function.";
t_gethostbyaddr_v6(Config) when is_list(Config) ->
?line {Name6, FullName6, IPStr6, IP6, Aliases6} =
- ?config(test_host_ipv6_only, Config),
+ ct:get_config(test_host_ipv6_only),
?line case inet:gethostbyaddr(IPStr6) of
%% Even if IPv6 is not supported, the native resolver may succeed
@@ -103,27 +149,28 @@ t_gethostbyaddr_v6(Config) when is_list(Config) ->
{HEnt6#hostent.h_aliases,[[],Aliases6]}]),
?line {_DName6, _DFullName6, DIPStr6, DIP6, _} =
- ?config(test_dummy_ipv6_host, Config),
+ ct:get_config(test_dummy_ipv6_host),
?line {error,nxdomain} = inet:gethostbyaddr(DIPStr6),
?line {error,nxdomain} = inet:gethostbyaddr(DIP6),
ok
end.
+t_gethostbyname() -> required(v4).
t_gethostbyname(doc) -> "Test the inet:gethostbyname/1 function.";
t_gethostbyname(suite) -> [];
t_gethostbyname(Config) when is_list(Config) ->
?line {Name,FullName,IPStr,IP,Aliases,IP_46_Str,_} =
- ?config(test_host_ipv4_only, Config),
+ ct:get_config(test_host_ipv4_only),
?line {ok,_} = inet:gethostbyname(IPStr),
?line {ok,HEnt} = inet:gethostbyname(Name),
?line {ok,HEnt} = inet:gethostbyname(list_to_atom(Name)),
?line HEnt_ = HEnt#hostent{h_addrtype = inet,
h_length = 4,
h_addr_list = [IP]},
+
?line HEnt_ = HEnt,
?line check_elems([{HEnt#hostent.h_name,[Name,FullName]},
{HEnt#hostent.h_aliases,[[],Aliases]}]),
-
?line {ok,HEntF} = inet:gethostbyname(FullName),
?line HEntF_ = HEntF#hostent{h_name = FullName,
h_addrtype = inet,
@@ -133,15 +180,16 @@ t_gethostbyname(Config) when is_list(Config) ->
?line check_elems([{HEnt#hostent.h_aliases,[[],Aliases]}]),
?line {DName, _DFullName, _DIPStr, _DIP, _, _, _} =
- ?config(test_dummy_host, Config),
+ ct:get_config(test_dummy_host),
?line {error,nxdomain} = inet:gethostbyname(DName),
?line {error,nxdomain} = inet:gethostbyname(IP_46_Str).
+t_gethostbyname_v6() -> required(v6).
t_gethostbyname_v6(doc) -> "Test the inet:gethostbyname/1 inet6 function.";
t_gethostbyname_v6(suite) -> [];
t_gethostbyname_v6(Config) when is_list(Config) ->
?line {Name, _, _, _,Aliases,IP_46_Str,IP_46} =
- ?config(test_host_ipv4_only, Config),
+ ct:get_config(test_host_ipv4_only),
case {inet:gethostbyname(IP_46_Str, inet6),
inet:gethostbyname(Name, inet6)} of
@@ -154,7 +202,7 @@ t_gethostbyname_v6(Config) when is_list(Config) ->
?line check_elems([{HEnt46#hostent.h_aliases,[[],Aliases]}]),
?line {Name6, FullName6, IPStr6, IP6, Aliases6} =
- ?config(test_host_ipv6_only, Config),
+ ct:get_config(test_host_ipv6_only),
?line {ok,_} = inet:gethostbyname(IPStr6, inet6),
?line {ok,HEnt6} = inet:gethostbyname(Name6, inet6),
?line {ok,HEnt6} = inet:gethostbyname(list_to_atom(Name6), inet6),
@@ -200,7 +248,7 @@ t_gethostbyname_v6(Config) when is_list(Config) ->
end,
?line {DName6, _DFullName6, _DIPStr6, _DIP6, _} =
- ?config(test_dummy_ipv6_host, Config),
+ ct:get_config(test_dummy_ipv6_host),
?line {error,nxdomain} = inet:gethostbyname(DName6, inet6),
ok;
{_,_} ->
@@ -219,11 +267,12 @@ check_elem(Val, [], Tests0) ->
?t:fail({no_match,Val,Tests0}).
+t_getaddr() -> required(v4).
t_getaddr(doc) -> "Test the inet:getaddr/2 function.";
t_getaddr(suite) -> [];
t_getaddr(Config) when is_list(Config) ->
?line {Name,FullName,IPStr,IP,_,IP_46_Str,IP46} =
- ?config(test_host_ipv4_only, Config),
+ ct:get_config(test_host_ipv4_only),
?line {ok,IP} = inet:getaddr(list_to_atom(Name), inet),
?line {ok,IP} = inet:getaddr(Name, inet),
?line {ok,IP} = inet:getaddr(FullName, inet),
@@ -232,17 +281,18 @@ t_getaddr(Config) when is_list(Config) ->
?line {error,nxdomain} = inet:getaddr(IP_46_Str, inet),
?line {error,eafnosupport} = inet:getaddr(IP46, inet),
- ?line {DName, DFullName, DIPStr, DIP, _, _, _} = ?config(test_dummy_host, Config),
+ ?line {DName, DFullName, DIPStr, DIP, _, _, _} = ct:get_config(test_dummy_host),
?line {error,nxdomain} = inet:getaddr(DName, inet),
?line {error,nxdomain} = inet:getaddr(DFullName, inet),
?line {ok,DIP} = inet:getaddr(DIPStr, inet),
?line {ok,DIP} = inet:getaddr(DIP, inet).
+t_getaddr_v6() -> required(v4) ++ required(v6).
t_getaddr_v6(doc) -> "Test the inet:getaddr/2 function.";
t_getaddr_v6(suite) -> [];
t_getaddr_v6(Config) when is_list(Config) ->
?line {Name,FullName,IPStr,_IP,_,IP_46_Str,IP46} =
- ?config(test_host_ipv4_only, Config),
+ ct:get_config(test_host_ipv4_only),
case {inet:getaddr(IP_46_Str, inet6),inet:getaddr(Name, inet6)} of
{{ok,IP46},{ok,_}} ->
%% Since we suceeded in parsing an IPv6 address string and
@@ -261,7 +311,7 @@ t_getaddr_v6(Config) when is_list(Config) ->
%% inet_db:res_option(lookup))
%% end,
?line {Name6, FullName6, IPStr6, IP6, _} =
- ?config(test_host_ipv6_only, Config),
+ ct:get_config(test_host_ipv6_only),
?line {ok,_} = inet:getaddr(list_to_atom(Name6), inet6),
?line {ok,_} = inet:getaddr(Name6, inet6),
?line {ok,_} = inet:getaddr(FullName6, inet6),
@@ -269,7 +319,7 @@ t_getaddr_v6(Config) when is_list(Config) ->
?line {ok,IP6} = inet:getaddr(IPStr6, inet6),
?line {DName6, DFullName6, DIPStr6, DIP6, _} =
- ?config(test_dummy_ipv6_host, Config),
+ ct:get_config(test_dummy_ipv6_host),
?line {error,nxdomain} = inet:getaddr(DName6, inet6),
?line {error,nxdomain} = inet:getaddr(DFullName6, inet6),
?line {ok,DIP6} = inet:getaddr(DIPStr6, inet6),
@@ -279,6 +329,7 @@ t_getaddr_v6(Config) when is_list(Config) ->
{skip, "IPv6 is not supported on this host"}
end.
+ipv4_to_ipv6() -> required(v4).
ipv4_to_ipv6(doc) -> "Test if IPv4 address is converted to IPv6 address.";
ipv4_to_ipv6(suite) -> [];
ipv4_to_ipv6(Config) when is_list(Config) ->
@@ -287,7 +338,7 @@ ipv4_to_ipv6(Config) when is_list(Config) ->
%% address should be returned. If no IPv6 support on this host, an
%% error should beturned.
?line {_Name,_FullName,IPStr,_IP,Aliases,IP_46_Str,IP_46} =
- ?config(test_host_ipv4_only, Config),
+ ct:get_config(test_host_ipv4_only),
?line IP4to6Res =
case inet:getaddr(IPStr, inet6) of
{ok,IP_46} ->
@@ -314,6 +365,7 @@ ipv4_to_ipv6(Config) when is_list(Config) ->
end,
ok.
+host_and_addr() -> required(hosts).
host_and_addr(doc) -> ["Test looking up hosts and addresses. Use 'ypcat hosts' ",
"or the local eqivalent to find all hosts."];
host_and_addr(suite) -> [];
@@ -334,30 +386,30 @@ try_host({Ip0, Host}) ->
%% Get all hosts from the system using 'ypcat hosts' or the local
%% equvivalent.
-get_hosts(Config) ->
+get_hosts(_Config) ->
case os:type() of
{unix, _} ->
List = lists:map(fun(X) ->
atom_to_list(X)++" "
- end, ?config(test_hosts, Config)),
+ end, ct:get_config(test_hosts)),
Cmd = "ypmatch "++List++" hosts.byname",
HostFile = os:cmd(Cmd),
get_hosts(HostFile, [], [], []);
_ ->
- ?config(hardcoded_hosts, Config)
+ ct:get_config(hardcoded_hosts)
end.
-get_ipv6_hosts(Config) ->
+get_ipv6_hosts(_Config) ->
case os:type() of
{unix, _} ->
List = lists:map(fun(X) ->
atom_to_list(X)++" "
- end, ?config(test_hosts, Config)),
+ end, ct:get_config(ipv6_hosts)),
Cmd = "ypmatch "++List++" ipnodes.byname",
HostFile = os:cmd(Cmd),
get_hosts(HostFile, [], [], []);
_ ->
- ?config(hardcoded_ipv6_hosts, Config)
+ ct:get_config(hardcoded_ipv6_hosts)
end.
get_hosts([$\t|Rest], Cur, Ip, Result) when Ip /= [] ->
@@ -376,9 +428,6 @@ get_hosts([C|Rest], Cur, Ip, Result) ->
get_hosts([], _, _, Result) ->
Result.
-parse(suite) -> [parse_hosts, parse_address];
-parse(doc) -> ["Test that parsing of the hosts file or equivalent works,",
- "and that erroneous lines are skipped"].
parse_hosts(Config) when is_list(Config) ->
?line DataDir = ?config(data_dir,Config),
@@ -730,6 +779,7 @@ cname_loop(Config) when is_list(Config) ->
lookup_count=300,
lookup_processes=20}).
+gethostnative_soft_restart() -> required(hosts).
gethostnative_soft_restart(suite) ->
[];
gethostnative_soft_restart(doc) ->
@@ -740,6 +790,8 @@ gethostnative_soft_restart(Config) when is_list(Config) ->
#gethostnative_control{
control_seq=[soft_restart]}).
+
+gethostnative_debug_level() -> required(hosts).
gethostnative_debug_level(suite) ->
[];
gethostnative_debug_level(doc) ->
@@ -873,6 +925,14 @@ getif(suite) ->
getif(doc) ->
["Tests basic functionality of getiflist, getif, and ifget"];
getif(Config) when is_list(Config) ->
+ ?line case os:type() of
+ {unix,Osname} ->
+ ?line do_getif(Osname);
+ {_,_} ->
+ {skip,"inet:getif/0 probably not supported"}
+ end.
+
+do_getif(Osname) ->
?line {ok,Hostname} = inet:gethostname(),
?line {ok,Address} = inet:getaddr(Hostname, inet),
?line {ok,Loopback} = inet:getaddr("localhost", inet),
@@ -887,7 +947,8 @@ getif(Config) when is_list(Config) ->
end
end, [], Interfaces)),
?line io:format("HWAs = ~p~n", [HWAs]),
- ?line length(HWAs) > 0 orelse ?t:fail(no_HWAs),
+ ?line (Osname =/= sunos)
+ andalso ((length(HWAs) > 0) orelse (?t:fail(no_HWAs))),
?line Addresses =
lists:sort(
lists:foldl(
@@ -906,6 +967,14 @@ getif(Config) when is_list(Config) ->
getif_ifr_name_overflow(doc) ->
"Test long interface names do not overrun buffer";
getif_ifr_name_overflow(Config) when is_list(Config) ->
+ ?line case os:type() of
+ {unix,Osname} ->
+ ?line do_getif_ifr_name_overflow(Osname);
+ {_,_} ->
+ {skip,"inet:ifget/2 probably not supported"}
+ end.
+
+do_getif_ifr_name_overflow(_) ->
%% emulator should not crash
?line {ok,[]} = inet:ifget(lists:duplicate(128, "x"), [addr]),
ok.
@@ -917,6 +986,112 @@ getservbyname_overflow(Config) when is_list(Config) ->
?line {error,einval} = inet:getservbyname(list_to_atom(lists:flatten(lists:duplicate(128, "x"))), tcp),
ok.
+getifaddrs(doc) ->
+ "Test inet:gifaddrs/0";
+getifaddrs(Config) when is_list (Config) ->
+ ?line {ok,IfAddrs} = inet:getifaddrs(),
+ ?line ?t:format("IfAddrs = ~p.~n", [IfAddrs]),
+ ?line
+ case
+ {os:type(),
+ [If ||
+ {If,Opts} <- IfAddrs,
+ lists:keymember(hwaddr, 1, Opts)]} of
+ {{unix,sunos},[]} -> ok;
+ {OT,[]} ->
+ ?t:fail({should_have_hwaddr,OT});
+ _ -> ok
+ end,
+ ?line Addrs =
+ [element(1, A) || A <- ifaddrs(IfAddrs)],
+ ?line ?t:format("Addrs = ~p.~n", [Addrs]),
+ ?line [check_addr(Addr) || Addr <- Addrs],
+ ok.
+
+check_addr(Addr)
+ when tuple_size(Addr) =:= 8,
+ element(1, Addr) band 16#FFC0 =:= 16#FE80 ->
+ ?line ?t:format("Addr: ~p link local; SKIPPED!~n", [Addr]),
+ ok;
+check_addr(Addr) ->
+ ?line ?t:format("Addr: ~p.~n", [Addr]),
+ ?line Ping = "ping",
+ ?line Pong = "pong",
+ ?line {ok,L} = gen_tcp:listen(0, [{ip,Addr},{active,false}]),
+ ?line {ok,P} = inet:port(L),
+ ?line {ok,S1} = gen_tcp:connect(Addr, P, [{active,false}]),
+ ?line {ok,S2} = gen_tcp:accept(L),
+ ?line ok = gen_tcp:send(S2, Ping),
+ ?line {ok,Ping} = gen_tcp:recv(S1, length(Ping)),
+ ?line ok = gen_tcp:send(S1, Pong),
+ ?line ok = gen_tcp:close(S1),
+ ?line {ok,Pong} = gen_tcp:recv(S2, length(Pong)),
+ ?line ok = gen_tcp:close(S2),
+ ?line ok = gen_tcp:close(L),
+ ok.
+
+-record(ifopts, {name,flags,addrs=[],hwaddr}).
+
+ifaddrs([]) -> [];
+ifaddrs([{If,Opts}|IOs]) ->
+ ?line #ifopts{flags=Flags} = Ifopts =
+ check_ifopts(Opts, #ifopts{name=If}),
+ ?line case Flags =/= undefined andalso lists:member(up, Flags) of
+ true ->
+ Ifopts#ifopts.addrs;
+ false ->
+ []
+ end++ifaddrs(IOs).
+
+check_ifopts([], #ifopts{name=If,flags=Flags,addrs=Raddrs}=Ifopts) ->
+ Addrs = lists:reverse(Raddrs),
+ R = Ifopts#ifopts{addrs=Addrs},
+ ?t:format("~p.~n", [R]),
+ %% See how we did...
+ if is_list(Flags) -> ok;
+ true ->
+ ?t:fail({flags_undefined,If})
+ end,
+ case lists:member(broadcast, Flags) of
+ true ->
+ [case A of
+ {_,_,_} -> A;
+ {T,_} when tuple_size(T) =:= 8 -> A;
+ _ ->
+ ?t:fail({broaddr_missing,If,A})
+ end || A <- Addrs];
+ false ->
+ [case A of {_,_} -> A;
+ _ ->
+ ?t:fail({should_have_netmask,If,A})
+ end || A <- Addrs]
+ end,
+ R;
+check_ifopts([{flags,Flags}|Opts], #ifopts{flags=undefined}=Ifopts) ->
+ check_ifopts(Opts, Ifopts#ifopts{flags=Flags});
+check_ifopts([{flags,Fs}|Opts], #ifopts{flags=Flags}=Ifopts) ->
+ case Fs of
+ Flags ->
+ check_ifopts(Opts, Ifopts#ifopts{});
+ _ ->
+ ?t:fail({multiple_flags,Fs,Ifopts})
+ end;
+check_ifopts(
+ [{addr,Addr},{netmask,Netmask},{broadaddr,Broadaddr}|Opts],
+ #ifopts{addrs=Addrs}=Ifopts) ->
+ check_ifopts(Opts, Ifopts#ifopts{addrs=[{Addr,Netmask,Broadaddr}|Addrs]});
+check_ifopts(
+ [{addr,Addr},{netmask,Netmask}|Opts],
+ #ifopts{addrs=Addrs}=Ifopts) ->
+ check_ifopts(Opts, Ifopts#ifopts{addrs=[{Addr,Netmask}|Addrs]});
+check_ifopts([{addr,Addr}|Opts], #ifopts{addrs=Addrs}=Ifopts) ->
+ check_ifopts(Opts, Ifopts#ifopts{addrs=[{Addr}|Addrs]});
+check_ifopts([{hwaddr,Hwaddr}|Opts], #ifopts{hwaddr=undefined}=Ifopts)
+ when is_list(Hwaddr) ->
+ check_ifopts(Opts, Ifopts#ifopts{hwaddr=Hwaddr});
+check_ifopts([{hwaddr,HwAddr}|_], #ifopts{}=Ifopts) ->
+ ?t:fail({multiple_hwaddrs,HwAddr,Ifopts}).
+
%% Works just like lists:member/2, except that any {127,_,_,_} tuple
%% matches any other {127,_,_,_}. We do this to handle Linux systems
%% that use (for instance) 127.0.1.1 as the IP address for the hostname.
diff --git a/lib/kernel/test/inet_res_SUITE.erl b/lib/kernel/test/inet_res_SUITE.erl
index cc32d1f8f9..0c3c7c950c 100644
--- a/lib/kernel/test/inet_res_SUITE.erl
+++ b/lib/kernel/test/inet_res_SUITE.erl
@@ -18,24 +18,51 @@
%%
-module(inet_res_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
-include_lib("kernel/include/inet.hrl").
-include_lib("kernel/src/inet_dns.hrl").
--export([all/1, init_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
-export([basic/1, resolve/1, edns0/1, txt_record/1, files_monitor/1]).
--export([gethostbyaddr/1, gethostbyaddr_v6/1,
- gethostbyname/1, gethostbyname_v6/1,
- getaddr/1, getaddr_v6/1, ipv4_to_ipv6/1, host_and_addr/1]).
+-export([
+ gethostbyaddr/0, gethostbyaddr/1,
+ gethostbyaddr_v6/0, gethostbyaddr_v6/1,
+ gethostbyname/0, gethostbyname/1,
+ gethostbyname_v6/0, gethostbyname_v6/1,
+ getaddr/0, getaddr/1,
+ getaddr_v6/0, getaddr_v6/1,
+ ipv4_to_ipv6/0, ipv4_to_ipv6/1,
+ host_and_addr/0, host_and_addr/1
+ ]).
-define(RUN_NAMED, "run-named").
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[basic, resolve, edns0, txt_record, files_monitor,
- gethostbyaddr, gethostbyaddr_v6, gethostbyname, gethostbyname_v6,
- getaddr, getaddr_v6, ipv4_to_ipv6, host_and_addr].
+ gethostbyaddr, gethostbyaddr_v6, gethostbyname,
+ gethostbyname_v6, getaddr, getaddr_v6, ipv4_to_ipv6,
+ host_and_addr].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
zone_dir(basic) ->
otptest;
@@ -450,11 +477,19 @@ do_files_monitor(Config) ->
%% Compatibility tests. Call the inet_SUITE tests, but with
%% lookup = [file,dns] instead of [native]
+gethostbyaddr() -> inet_SUITE:t_gethostbyaddr().
gethostbyaddr(Config) -> inet_SUITE:t_gethostbyaddr(Config).
+gethostbyaddr_v6() -> inet_SUITE:t_gethostbyaddr_v6().
gethostbyaddr_v6(Config) -> inet_SUITE:t_gethostbyaddr_v6(Config).
+gethostbyname() -> inet_SUITE:t_gethostbyname().
gethostbyname(Config) -> inet_SUITE:t_gethostbyname(Config).
+gethostbyname_v6() -> inet_SUITE:t_gethostbyname_v6().
gethostbyname_v6(Config) -> inet_SUITE:t_gethostbyname_v6(Config).
+getaddr() -> inet_SUITE:t_getaddr().
getaddr(Config) -> inet_SUITE:t_getaddr(Config).
+getaddr_v6() -> inet_SUITE:t_getaddr_v6().
getaddr_v6(Config) -> inet_SUITE:t_getaddr_v6(Config).
+ipv4_to_ipv6() -> inet_SUITE:ipv4_to_ipv6().
ipv4_to_ipv6(Config) -> inet_SUITE:ipv4_to_ipv6(Config).
+host_and_addr() -> inet_SUITE:host_and_addr().
host_and_addr(Config) -> inet_SUITE:host_and_addr(Config).
diff --git a/lib/kernel/test/inet_sockopt_SUITE.erl b/lib/kernel/test/inet_sockopt_SUITE.erl
index 0fa0226ccf..1ef182ca18 100644
--- a/lib/kernel/test/inet_sockopt_SUITE.erl
+++ b/lib/kernel/test/inet_sockopt_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -18,7 +18,7 @@
%%
-module(inet_sockopt_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(C_GET_IPPROTO_TCP,1).
@@ -48,7 +48,9 @@
-define(C_QUIT,99).
--export([all/1, simple/1, loop_all/1, simple_raw/1, simple_raw_getbin/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ simple/1, loop_all/1, simple_raw/1, simple_raw_getbin/1,
doc_examples_raw/1,doc_examples_raw_getbin/1,
large_raw/1,large_raw_getbin/1,combined/1,combined_getbin/1,
type_errors/1]).
@@ -56,10 +58,29 @@
-export([init_per_testcase/2, end_per_testcase/2]).
-all(suite) ->
- [simple,loop_all,simple_raw,simple_raw_getbin,
- doc_examples_raw, doc_examples_raw_getbin,
- large_raw,large_raw_getbin,combined,combined_getbin,type_errors].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [simple, loop_all, simple_raw, simple_raw_getbin,
+ doc_examples_raw, doc_examples_raw_getbin, large_raw,
+ large_raw_getbin, combined, combined_getbin,
+ type_errors].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Func, Config) ->
Dog = test_server:timetrap(test_server:seconds(60)),
diff --git a/lib/kernel/test/init_SUITE.erl b/lib/kernel/test/init_SUITE.erl
index bbd8261197..18bb5c7087 100644
--- a/lib/kernel/test/init_SUITE.erl
+++ b/lib/kernel/test/init_SUITE.erl
@@ -18,16 +18,17 @@
%%
-module(init_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([get_arguments/1, get_argument/1, boot_var/1, restart/1,
get_plain_arguments/1,
- reboot/1, stop/1, get_status/1, script_id/1, boot/1]).
+ reboot/1, stop/1, get_status/1, script_id/1]).
-export([boot1/1, boot2/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([init/1, fini/1]).
@@ -38,17 +39,34 @@
%% Should be started in a CC view with:
%% erl -sname master -rsh ctrsh
%%-----------------------------------------------------------------
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[get_arguments, get_argument, boot_var,
- get_plain_arguments,
- restart,
- get_status, script_id, boot].
+ get_plain_arguments, restart, get_status, script_id,
+ {group, boot}].
+
+groups() ->
+ [{boot, [], [boot1, boot2]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:seconds(?DEFAULT_TIMEOUT_SEC)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog).
@@ -488,7 +506,6 @@ script_id(Config) when is_list(Config) ->
%% ------------------------------------------------
%% Start the slave system with -boot flag.
%% ------------------------------------------------
-boot(suite) -> [boot1, boot2].
boot1(doc) -> [];
boot1(suite) -> {req, [distribution, {local_slave_nodes, 1}, {time, 35}]};
diff --git a/lib/kernel/test/interactive_shell_SUITE.erl b/lib/kernel/test/interactive_shell_SUITE.erl
index c0db292ba5..66a01b1849 100644
--- a/lib/kernel/test/interactive_shell_SUITE.erl
+++ b/lib/kernel/test/interactive_shell_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -17,8 +17,10 @@
%% %CopyrightEnd%
%%
-module(interactive_shell_SUITE).
--include("test_server.hrl").
--export([all/1, get_columns_and_rows/1, exit_initial/1, job_control_local/1,
+-include_lib("test_server/include/test_server.hrl").
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ get_columns_and_rows/1, exit_initial/1, job_control_local/1,
job_control_remote/1,
job_control_remote_noshell/1]).
@@ -44,10 +46,28 @@ end_per_testcase(_Func, Config) ->
test_server:timetrap_cancel(Dog).
-all(suite) ->
- [get_columns_and_rows, exit_initial, job_control_local,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [get_columns_and_rows, exit_initial, job_control_local,
job_control_remote, job_control_remote_noshell].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%-define(DEBUG,1).
-ifdef(DEBUG).
-define(dbg(Data),erlang:display(Data)).
diff --git a/lib/kernel/test/kernel.cover b/lib/kernel/test/kernel.cover
index 228dafc565..f6967ca651 100644
--- a/lib/kernel/test/kernel.cover
+++ b/lib/kernel/test/kernel.cover
@@ -1,4 +1,3 @@
%% -*- erlang -*-
-{exclude,all}.
-{include,[gen_udp,inet6_udp,inet_res,inet_dns]}.
+{incl_mods,[gen_udp,inet6_udp,inet_res,inet_dns]}.
diff --git a/lib/kernel/test/kernel.dynspec b/lib/kernel/test/kernel.dynspec
deleted file mode 100644
index 297a7c71ea..0000000000
--- a/lib/kernel/test/kernel.dynspec
+++ /dev/null
@@ -1,57 +0,0 @@
-%% -*- erlang -*-
-%% You can test this file using this command.
-%% file:script("kernel.dynspec", [{'Os',"Unix"}]).
-
-case Os of
- "VxWorks" ->
- FsCantHandle = "VxWorks filesystem can't handle this",
- FsOverload = "VxWorks filesystem would overload",
- CantHandle = "VxWorks can't handle this",
- SlaveMisadaption = "Test not adopted to slaves on different machine",
- [{skip,{application_SUITE,
- "VxWorks: requires manual testing "++
- "(requires multiple nodes (OTP-1774))"}},
- {skip,{bif_SUITE, spawn_link_race1, "Known bug."}},
- {skip,{erl_distribution_SUITE, "VxWorks: More vx nodes needed"}},
- {skip,{file_SUITE,read_write_file,FsCantHandle}},
- {skip,{file_SUITE,cur_dir_0,FsCantHandle}},
- {skip,{file_SUITE,open1,FsCantHandle}},
- {skip,{file_SUITE,file_info_times,FsCantHandle}},
- {skip,{file_SUITE,file_write_file_info,FsCantHandle}},
- {skip,{file_SUITE,truncate,FsCantHandle}},
- {skip,{file_SUITE,rename,FsCantHandle}},
- {skip,{file_SUITE,e_delete,FsCantHandle}},
- {skip,{file_SUITE,e_rename,FsCantHandle}},
- {skip,{file_SUITE,delayed_write,FsCantHandle}},
- {skip,{file_SUITE,read_ahead,FsCantHandle}},
- {skip,{file_SUITE,segment_write,FsOverload}},
- {skip,{file_SUITE,segment_read,FsOverload}},
- {skip,{file_SUITE,compress_errors,FsCantHandle}},
- {skip,{global_SUITE,
- "To heavy on slavenodes for VxWorks (and more)."}},
- {skip,{global_group_SUITE, "To heavy on slavenodes for VxWorks."}},
- {skip,{heart_SUITE, "Not for VxWorks heart, it's special"}},
- {skip,{init_SUITE,restart,"Uses peer nodes"}},
- {skip,{kernel_config_SUITE, "VxWorks does not support slave nodes"}},
- {skip,{os_SUITE,space_in_cwd,CantHandle}},
- {skip,{os_SUITE,space_in_name,CantHandle}},
- {skip,{os_SUITE,quoting,CantHandle}},
- {skip,{prim_file_SUITE,open1,FsCantHandle}},
- {skip,{prim_file_SUITE,compress_errors,FsCantHandle}},
- {skip,{seq_trace_SUITE,distributed_recv,SlaveMisadaption}},
- {skip,{seq_trace_SUITE,distributed_exit,SlaveMisadaption}}];
- _ ->
- []
-end ++
-try gen_sctp:open() of
- {ok,Socket} ->
- gen_sctp:close(Socket),
- [];
- _ ->
- []
-catch
- error:badarg ->
- [{skip,{gen_sctp_SUITE,"SCTP not supported on this machine"}}];
- _:_ ->
- []
-end.
diff --git a/lib/kernel/test/kernel.spec b/lib/kernel/test/kernel.spec
new file mode 100644
index 0000000000..62afc9f97b
--- /dev/null
+++ b/lib/kernel/test/kernel.spec
@@ -0,0 +1,4 @@
+{config, "../test_server/ts.config"}.
+{config, "../test_server/ts.unix.config"}.
+
+{suites,"../kernel_test", all}.
diff --git a/lib/kernel/test/kernel.spec.wxworks b/lib/kernel/test/kernel.spec.wxworks
new file mode 100644
index 0000000000..370e474e64
--- /dev/null
+++ b/lib/kernel/test/kernel.spec.wxworks
@@ -0,0 +1,63 @@
+%% -*- erlang -*-
+{suites,"kernel_test",all}.
+{skip_cases,"kernel_test",bif_SUITE,[spawn_link_race1],"Known bug."}.
+{skip_cases,"kernel_test",file_SUITE,
+ [read_write_file],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [cur_dir_0],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [open1],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [file_info_times],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [file_write_file_info],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [truncate],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [rename],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [e_delete],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [e_rename],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [delayed_write],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [read_ahead],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [segment_write],
+ "VxWorks filesystem would overload"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [segment_read],
+ "VxWorks filesystem would overload"}.
+{skip_cases,"kernel_test",file_SUITE,
+ [compress_errors],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",init_SUITE,[restart],"Uses peer nodes"}.
+{skip_cases,"kernel_test",os_SUITE,[space_in_cwd],"VxWorks can't handle this"}.
+{skip_cases,"kernel_test",os_SUITE,
+ [space_in_name],
+ "VxWorks can't handle this"}.
+{skip_cases,"kernel_test",os_SUITE,[quoting],"VxWorks can't handle this"}.
+{skip_cases,"kernel_test",prim_file_SUITE,
+ [open1],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",prim_file_SUITE,
+ [compress_errors],
+ "VxWorks filesystem can't handle this"}.
+{skip_cases,"kernel_test",seq_trace_SUITE,
+ [distributed_recv],
+ "Test not adopted to slaves on different machine"}.
+{skip_cases,"kernel_test",seq_trace_SUITE,
+ [distributed_exit],
+ "Test not adopted to slaves on different machine"}.
diff --git a/lib/kernel/test/kernel_SUITE.erl b/lib/kernel/test/kernel_SUITE.erl
index bb1d905de3..02b6edf0bd 100644
--- a/lib/kernel/test/kernel_SUITE.erl
+++ b/lib/kernel/test/kernel_SUITE.erl
@@ -20,15 +20,16 @@
%%% Kernel application test suite.
%%%-----------------------------------------------------------------
-module(kernel_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
% Test server specific exports
--export([all/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
% Test cases must be exported.
-export([app_test/1]).
@@ -36,15 +37,31 @@
%%
%% all/1
%%
-all(doc) ->
- [];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[app_test].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/kernel/test/kernel_config_SUITE.erl b/lib/kernel/test/kernel_config_SUITE.erl
index c72fc3f02d..deef248956 100644
--- a/lib/kernel/test/kernel_config_SUITE.erl
+++ b/lib/kernel/test/kernel_config_SUITE.erl
@@ -18,23 +18,35 @@
%%
-module(kernel_config_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1, sync/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, sync/1]).
--export([init/1, fini/1]).
+-export([init_per_suite/1, end_per_suite/1]).
-all(suite) ->
- [{conf, init, [sync], fini}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-init(doc) -> [];
-init(suite) -> [];
-init(Config) when is_list(Config) ->
+all() ->
+ [sync].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(doc) -> [];
+init_per_suite(suite) -> [];
+init_per_suite(Config) when is_list(Config) ->
Config.
-fini(doc) -> [];
-fini(suite) -> [];
-fini(Config) when is_list(Config) ->
+end_per_suite(doc) -> [];
+end_per_suite(suite) -> [];
+end_per_suite(Config) when is_list(Config) ->
stop_node(init_test),
Config.
diff --git a/lib/kernel/test/myApp.erl b/lib/kernel/test/myApp.erl
index 2b92046141..26dc74f91b 100644
--- a/lib/kernel/test/myApp.erl
+++ b/lib/kernel/test/myApp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl
index ace9501d18..b08b12c978 100644
--- a/lib/kernel/test/os_SUITE.erl
+++ b/lib/kernel/test/os_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,15 +18,34 @@
%%
-module(os_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([space_in_cwd/1, quoting/1, space_in_name/1, bad_command/1,
find_executable/1, unix_comment_in_command/1, evil/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [space_in_cwd, quoting, space_in_name, bad_command,
+ find_executable, unix_comment_in_command, evil].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [space_in_cwd, quoting, space_in_name, bad_command, find_executable,
- unix_comment_in_command, evil].
space_in_cwd(doc) ->
"Test that executing a command in a current working directory "
@@ -156,6 +175,21 @@ find_executable(Config) when is_list(Config) ->
?line find_exe(Current, "my_batch", ".bat", Path),
ok;
{unix, _} ->
+ DataDir = ?config(data_dir, Config),
+
+ %% Smoke test.
+ case lib:progname() of
+ erl ->
+ ?line ErlPath = os:find_executable("erl"),
+ ?line true = is_list(ErlPath),
+ ?line true = filelib:is_regular(ErlPath);
+ _ ->
+ %% Don't bother -- the progname could include options.
+ ok
+ end,
+
+ %% Never return a directory name.
+ ?line false = os:find_executable("unix", [DataDir]),
ok;
vxworks ->
ok
@@ -204,8 +238,9 @@ evil(Config) when is_list(Config) ->
evil_loop(Parent, ?EVIL_LOOPS,N)
end)
end, lists:seq(1, ?EVIL_PROCS)),
- Devil = spawn(fun () -> devil(hd(Ps), hd(lists:reverse(Ps))) end),
+ Devil = spawn_link(fun () -> devil(hd(Ps), hd(lists:reverse(Ps))) end),
lists:foreach(fun (P) -> receive {P, done} -> ok end end, Ps),
+ unlink(Devil),
exit(Devil, kill),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/kernel/test/pdict_SUITE.erl b/lib/kernel/test/pdict_SUITE.erl
index 87ee951a0c..d41ad41350 100644
--- a/lib/kernel/test/pdict_SUITE.erl
+++ b/lib/kernel/test/pdict_SUITE.erl
@@ -20,7 +20,7 @@
%% NB: The ?line macro cannot be used when testing the dictionary.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(M(A,B),m(A,B,?MODULE,?LINE)).
-ifdef(DEBUG).
@@ -29,22 +29,41 @@
-define(DEBUGF(A,B), noop).
-endif.
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
simple/1, complicated/1, heavy/1, info/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([other_process/2]).
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(test_server:minutes(10)),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[simple, complicated, heavy, info].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
simple(doc) ->
["Tests simple functionality in process dictionary."];
simple(suite) ->
diff --git a/lib/kernel/test/pg2_SUITE.erl b/lib/kernel/test/pg2_SUITE.erl
index df28dcf447..5dc32440a0 100644
--- a/lib/kernel/test/pg2_SUITE.erl
+++ b/lib/kernel/test/pg2_SUITE.erl
@@ -20,14 +20,16 @@
%%-----------------------------------------------------------------
-module(pg2_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(datadir, ?config(data_dir, Config)).
-define(privdir, ?config(priv_dir, Config)).
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
--export([tickets/1,
- otp_7277/1, otp_8259/1, otp_8653/1,
+-export([
+ otp_7277/1, otp_8259/1, otp_8653/1,
compat/1, basic/1]).
% Default timetrap timeout (set in init_per_testcase).
@@ -44,16 +46,33 @@ init_per_testcase(Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{?TESTCASE, Case}, {watchdog, Dog} | Config].
-fin_per_testcase(_Case, _Config) ->
+end_per_testcase(_Case, _Config) ->
Dog = ?config(watchdog, _Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [tickets].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, tickets}].
+
+groups() ->
+ [{tickets, [],
+ [otp_7277, otp_8259, otp_8653, compat, basic]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-tickets(suite) ->
- [otp_7277, otp_8259, otp_8653, compat, basic].
otp_7277(doc) ->
"OTP-7277. Bugfix leave().";
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 1688ec45ca..3013af70f6 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -17,40 +17,40 @@
%% %CopyrightEnd%
%%
-module(prim_file_SUITE).
--export([all/1,
- init/1, fini/1,
- read_write_file/1, dirs/1, files/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ read_write_file/1]).
-export([cur_dir_0a/1, cur_dir_0b/1,
cur_dir_1a/1, cur_dir_1b/1,
make_del_dir_a/1, make_del_dir_b/1,
- pos/1, pos1/1, pos2/1]).
+ pos1/1, pos2/1]).
-export([close/1,
delete_a/1, delete_b/1]).
--export([open/1, open1/1, modes/1]).
--export([file_info/1,
- file_info_basic_file_a/1, file_info_basic_file_b/1,
- file_info_basic_directory_a/1, file_info_basic_directory_b/1,
- file_info_bad_a/1, file_info_bad_b/1,
- file_info_times_a/1, file_info_times_b/1,
- file_write_file_info_a/1, file_write_file_info_b/1]).
+-export([ open1/1, modes/1]).
+-export([
+ file_info_basic_file_a/1, file_info_basic_file_b/1,
+ file_info_basic_directory_a/1, file_info_basic_directory_b/1,
+ file_info_bad_a/1, file_info_bad_b/1,
+ 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, datasync/1, sync/1,
read_write/1, pread_write/1, append/1, exclusive/1]).
--export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).
+-export([ e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).
--export([compression/1, read_not_really_compressed/1,
- read_compressed/1, write_compressed/1,
- compress_errors/1]).
+-export([ read_not_really_compressed/1,
+ read_compressed/1, write_compressed/1,
+ compress_errors/1]).
--export([links/1,
- make_link_a/1, make_link_b/1,
- read_link_info_for_non_link/1,
- symlinks_a/1, symlinks_b/1,
- list_dir_limit/1]).
+-export([
+ make_link_a/1, make_link_b/1,
+ read_link_info_for_non_link/1,
+ symlinks_a/1, symlinks_b/1,
+ list_dir_limit/1]).
-export([advise/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
-define(PRIM_FILE, prim_file).
@@ -67,14 +67,47 @@
_ -> apply(?PRIM_FILE, F, [H | A])
end).
-all(suite) -> {req, [kernel],
- {conf, init,
- [read_write_file, dirs, files,
- delete_a, delete_b, rename_a, rename_b, errors,
- compression, links, list_dir_limit],
- fini}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [read_write_file, {group, dirs}, {group, files},
+ delete_a, delete_b, rename_a, rename_b, {group, errors},
+ {group, compression}, {group, links}, list_dir_limit].
+
+groups() ->
+ [{dirs, [],
+ [make_del_dir_a, make_del_dir_b, cur_dir_0a, cur_dir_0b,
+ cur_dir_1a, cur_dir_1b]},
+ {files, [],
+ [{group, open}, {group, pos}, {group, file_info},
+ truncate, sync, datasync, advise]},
+ {open, [],
+ [open1, modes, close, access, read_write, pread_write,
+ append, exclusive]},
+ {pos, [], [pos1, pos2]},
+ {file_info, [],
+ [file_info_basic_file_a, file_info_basic_file_b,
+ file_info_basic_directory_a,
+ file_info_basic_directory_b, file_info_bad_a,
+ file_info_bad_b, file_info_times_a, file_info_times_b,
+ file_write_file_info_a, file_write_file_info_b]},
+ {errors, [],
+ [e_delete, e_rename, e_make_dir, e_del_dir]},
+ {compression, [],
+ [read_compressed, read_not_really_compressed,
+ write_compressed, compress_errors]},
+ {links, [],
+ [make_link_a, make_link_b, read_link_info_for_non_link,
+ symlinks_a, symlinks_b]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-init(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
Priv = ?config(priv_dir, Config),
@@ -91,7 +124,7 @@ init(Config) when is_list(Config) ->
Config
end.
-fini(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
os:cmd("subst z: /d");
@@ -190,9 +223,6 @@ read_write_file(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-dirs(suite) -> [make_del_dir_a, make_del_dir_b,
- cur_dir_0a, cur_dir_0b,
- cur_dir_1a, cur_dir_1b].
make_del_dir_a(suite) -> [];
make_del_dir_a(doc) -> [];
@@ -382,10 +412,7 @@ win_cur_dir_1(_Config, Handle) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-files(suite) -> [open,pos,file_info,truncate,sync,datasync,advise].
-open(suite) -> [open1,modes,close,access,read_write,
- pread_write,append,exclusive].
open1(suite) -> [];
open1(doc) -> [];
@@ -628,7 +655,6 @@ exclusive(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-pos(suite) -> [pos1,pos2].
pos1(suite) -> [];
pos1(doc) -> [];
@@ -716,12 +742,6 @@ pos2(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
-file_info(suite) -> [file_info_basic_file_a, file_info_basic_file_b,
- file_info_basic_directory_a,
- file_info_basic_directory_b,
- file_info_bad_a, file_info_bad_b,
- file_info_times_a, file_info_times_b,
- file_write_file_info_a, file_write_file_info_b].
file_info_basic_file_a(suite) -> [];
file_info_basic_file_a(doc) -> [];
@@ -1298,7 +1318,6 @@ rename(Config, Handle, Suffix) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-errors(suite) -> [e_delete, e_rename, e_make_dir, e_del_dir].
e_delete(suite) -> [];
e_delete(doc) -> [];
@@ -1550,8 +1569,6 @@ e_del_dir(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
-compression(suite) -> [read_compressed, read_not_really_compressed,
- write_compressed, compress_errors].
%% Trying reading and positioning from a compressed file.
@@ -1704,11 +1721,6 @@ compress_errors(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
-links(doc) -> "Test the link functions.";
-links(suite) ->
- [make_link_a, make_link_b,
- read_link_info_for_non_link,
- symlinks_a, symlinks_b].
make_link_a(doc) -> "Test creating a hard link.";
make_link_a(suite) -> [];
diff --git a/lib/kernel/test/ram_file_SUITE.erl b/lib/kernel/test/ram_file_SUITE.erl
index 798a37d3dc..5f9ccaa34f 100644
--- a/lib/kernel/test/ram_file_SUITE.erl
+++ b/lib/kernel/test/ram_file_SUITE.erl
@@ -19,14 +19,15 @@
-module(ram_file_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
%% init/1, fini/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
-export([open_modes/1, open_old_modes/1, pread_pwrite/1, position/1,
truncate/1, sync/1, get_set_file/1, compress/1, uuencode/1,
large_file_errors/1, large_file_light/1, large_file_heavy/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
-define(FILE_MODULE, file). % Name of module to test
@@ -34,11 +35,29 @@
%%--------------------------------------------------------------------------
-all(suite) ->
- [open_modes, open_old_modes, pread_pwrite, position,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [open_modes, open_old_modes, pread_pwrite, position,
truncate, sync, get_set_file, compress, uuencode,
large_file_errors, large_file_light, large_file_heavy].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Time =
case Func of
@@ -51,7 +70,7 @@ init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
%% error_logger:info_msg("~p:~p *****~n", [?MODULE, Func]),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
%% error_logger:info_msg("~p:~p END *****~n", [?MODULE, Func]),
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog).
diff --git a/lib/kernel/test/rpc_SUITE.erl b/lib/kernel/test/rpc_SUITE.erl
index 2b7de40797..895441251a 100644
--- a/lib/kernel/test/rpc_SUITE.erl
+++ b/lib/kernel/test/rpc_SUITE.erl
@@ -18,7 +18,8 @@
%%
-module(rpc_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([call/1, block_call/1, multicall/1, multicall_timeout/1,
multicall_dies/1, multicall_node_dies/1,
called_dies/1, called_node_dies/1,
@@ -26,13 +27,31 @@
-export([suicide/2, suicide/3, f/0, f2/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [call, block_call, multicall, multicall_timeout,
+ multicall_dies, multicall_node_dies, called_dies,
+ called_node_dies, called_throws, call_benchmark,
+ async_call].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [call, block_call, multicall, multicall_timeout,
- multicall_dies, multicall_node_dies,
- called_dies, called_node_dies,
- called_throws, call_benchmark, async_call].
call(doc) -> "Test different rpc calls";
diff --git a/lib/kernel/test/seq_trace_SUITE.erl b/lib/kernel/test/seq_trace_SUITE.erl
index b557c7fb1e..9637e18959 100644
--- a/lib/kernel/test/seq_trace_SUITE.erl
+++ b/lib/kernel/test/seq_trace_SUITE.erl
@@ -18,7 +18,9 @@
%%
-module(seq_trace_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2]).
-export([token_set_get/1, tracer_set_get/1, print/1,
send/1, distributed_send/1, recv/1, distributed_recv/1,
trace_exit/1, distributed_exit/1, call/1, port/1,
@@ -29,21 +31,40 @@
start_tracer/0, stop_tracer/1,
do_match_set_seq_token/1, do_gc_seq_token/1, countdown_start/2]).
-%-define(line_trace, 1).
--include("test_server.hrl").
+ %-define(line_trace, 1).
+-include_lib("test_server/include/test_server.hrl").
-define(default_timeout, ?t:minutes(1)).
-all(suite) -> [token_set_get, tracer_set_get, print,
- send, distributed_send, recv, distributed_recv,
- trace_exit, distributed_exit, call, port,
- match_set_seq_token, gc_seq_token].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [token_set_get, tracer_set_get, print, send,
+ distributed_send, recv, distributed_recv, trace_exit,
+ distributed_exit, call, port, match_set_seq_token,
+ gc_seq_token].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog = test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/kernel/test/topApp.erl b/lib/kernel/test/topApp.erl
index acf98e6da0..f44e99f738 100644
--- a/lib/kernel/test/topApp.erl
+++ b/lib/kernel/test/topApp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/topApp2.erl b/lib/kernel/test/topApp2.erl
index 4587910ff3..b791d4a914 100644
--- a/lib/kernel/test/topApp2.erl
+++ b/lib/kernel/test/topApp2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/topApp3.erl b/lib/kernel/test/topApp3.erl
index 1bb6f2f31a..456ef5b2fb 100644
--- a/lib/kernel/test/topApp3.erl
+++ b/lib/kernel/test/topApp3.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/wrap_log_reader_SUITE.erl b/lib/kernel/test/wrap_log_reader_SUITE.erl
index ceac593e44..b4a9b578eb 100644
--- a/lib/kernel/test/wrap_log_reader_SUITE.erl
+++ b/lib/kernel/test/wrap_log_reader_SUITE.erl
@@ -28,31 +28,53 @@
-define(config(X,Y), foo).
-define(t,test_server).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(format(S, A), ok).
-define(privdir(Conf), ?config(priv_dir, Conf)).
-endif.
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
no_file/1,
- one/1, one_empty/1, one_filled/1,
- two/1, two_filled/1,
- four/1, four_filled/1,
- wrap/1, wrap_filled/1,
+ one_empty/1, one_filled/1,
+ two_filled/1,
+ four_filled/1,
+ wrap_filled/1,
wrapping/1,
external/1,
error/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [no_file, {group, one}, {group, two}, {group, four},
+ {group, wrap}, wrapping, external, error].
+
+groups() ->
+ [{one, [], [one_empty, one_filled]},
+ {two, [], [two_filled]}, {four, [], [four_filled]},
+ {wrap, [], [wrap_filled]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [no_file, one, two, four, wrap, wrapping, external, error].
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
Dog=?t:timetrap(?t:seconds(60)),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Func, _Config) ->
+end_per_testcase(_Func, _Config) ->
Dog=?config(watchdog, _Config),
?t:timetrap_cancel(Dog).
@@ -76,8 +98,6 @@ no_file(Conf) when is_list(Conf) ->
delete_files(File),
ok.
-one(suite) -> [one_empty, one_filled];
-one(doc) -> ["One index file"].
one_empty(suite) -> [];
one_empty(doc) -> ["One empty index file"];
@@ -139,8 +159,6 @@ test_one(File) ->
{chunk, 1, ["first round, two"]}, eof], wlt, ?LINE),
ok.
-two(suite) -> [two_filled];
-two(doc) -> ["Two index files"].
two_filled(suite) -> [];
two_filled(doc) -> ["Two filled index files"];
@@ -181,8 +199,6 @@ test_two(File) ->
{chunk, 2, ["first round, 12"]}, eof], wlt, ?LINE),
ok.
-four(suite) -> [four_filled];
-four(doc) -> ["Four index files"].
four_filled(suite) -> [];
four_filled(doc) -> ["Four filled index files"];
@@ -226,8 +242,6 @@ test_four(File) ->
{chunk, 2, ["first round, 42"]}, eof], wlt, ?LINE),
ok.
-wrap(suite) -> [wrap_filled];
-wrap(doc) -> ["Wrap index file, first wrapping"].
wrap_filled(suite) -> [];
wrap_filled(doc) -> ["First wrap, open, filled index file"];
diff --git a/lib/kernel/test/zlib_SUITE.erl b/lib/kernel/test/zlib_SUITE.erl
index f20c9a176b..170f685390 100644
--- a/lib/kernel/test/zlib_SUITE.erl
+++ b/lib/kernel/test/zlib_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -19,7 +19,7 @@
-module(zlib_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-compile(export_all).
@@ -48,7 +48,7 @@
init_per_testcase(_Func, Config) ->
Dog = test_server:timetrap(test_server:seconds(60)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
@@ -69,33 +69,40 @@ error(Format, Args, File, Line) ->
%% end,
%% log("<>ERROR<>~n" ++ Format, Args, File, Line).
-all(suite) ->
- [api, examples, func, smp, otp_7359].
-
-api(doc) -> "Basic the api tests";
-api(suite) ->
- [api_open_close,
- api_deflateInit,
- api_deflateSetDictionary,
- api_deflateReset,
- api_deflateParams,
- api_deflate,
- api_deflateEnd,
- api_inflateInit,
- api_inflateSetDictionary,
- api_inflateSync,
- api_inflateReset,
- api_inflate,
- api_inflateEnd,
- api_setBufsz,
- api_getBufsz,
- api_crc32,
- api_adler32,
- api_getQSize,
- api_un_compress,
- api_un_zip,
-% api_g_un_zip_file,
- api_g_un_zip].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, api}, {group, examples}, {group, func}, smp,
+ otp_7359].
+
+groups() ->
+ [{api, [],
+ [api_open_close, api_deflateInit,
+ api_deflateSetDictionary, api_deflateReset,
+ api_deflateParams, api_deflate, api_deflateEnd,
+ api_inflateInit, api_inflateSetDictionary,
+ api_inflateSync, api_inflateReset, api_inflate,
+ api_inflateEnd, api_setBufsz, api_getBufsz, api_crc32,
+ api_adler32, api_getQSize, api_un_compress, api_un_zip,
+ api_g_un_zip]},
+ {examples, [], [intro]},
+ {func, [],
+ [zip_usage, gz_usage, gz_usage2, compress_usage,
+ dictionary_usage, large_deflate, crc, adler]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
api_open_close(doc) -> "Test open/0 and close/1";
api_open_close(suite) -> [];
@@ -517,11 +524,6 @@ bad_len_data() ->
%% zlib:zip(<<42>>), one byte changed.
<<31,139,8,0,0,0,0,0,0,3,211,2,0,91,38,185,9,2,0,0,0>>.
-examples(doc) -> "Test the doc examples";
-examples(suite) ->
- [
- intro
- ].
intro(suite) -> [];
intro(doc) -> "";
@@ -551,15 +553,6 @@ intro(Config) when is_list(Config) ->
Orig = list_to_binary(lists:duplicate(5, D)),
?m(Orig, zlib:uncompress(Res)).
-func(doc) -> "Test the functionality";
-func(suite) ->
- [zip_usage, gz_usage, gz_usage2, compress_usage,
- dictionary_usage,
- large_deflate,
- %% inflateSync,
- crc,
- adler
- ].
large_deflate(doc) -> "Test deflate large file, which had a bug reported on erlang-bugs";
large_deflate(suite) -> [];
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index 03fe63e385..e33b90a274 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 2.14.2
+KERNEL_VSN = 2.14.3
diff --git a/lib/megaco/Makefile b/lib/megaco/Makefile
index d4698eb558..10efaf667f 100644
--- a/lib/megaco/Makefile
+++ b/lib/megaco/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
+# Copyright Ericsson AB 1999-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -97,12 +97,19 @@ endif
CONFIGURE_OPTS = $(FLEX_SCANNER_LINENO_ENABLER) $(FLEX_SCANNER_REENTRANT_ENABLER)
+MEGACO_DIA_PLT = ./priv/megaco.plt
+MEGACO_DIA_PLT_LOG = $(basename $(MEGACO_DIA_PLT)).dialyzer_plt_log
+MEGACO_DIA_LOG = $(basename $(MEGACO_DIA_PLT)).dialyzer_log
+
# ----------------------------------------------------
# Default Subdir Targets
# ----------------------------------------------------
include $(ERL_TOP)/make/otp_subdir.mk
+.PHONY: reconf conf dconf econf configure setup info version \
+ app_install dialyzer
+
reconf:
(cd $(ERL_TOP) && \
./otp_build autoconf && \
@@ -132,6 +139,10 @@ info:
@echo "APP_TAR_FILE: $(APP_TAR_FILE)"
@echo "OTP_INSTALL_DIR: $(OTP_INSTALL_DIR)"
@echo "APP_INSTALL_DIR: $(APP_INSTALL_DIR)"
+ @echo ""
+ @echo "MEGACO_PLT = $(MEGACO_PLT)"
+ @echo "MEGACO_DIA_LOG = $(MEGACO_DIA_LOG)"
+ @echo ""
version:
@echo "$(VSN)"
@@ -190,9 +201,18 @@ tar: $(APP_TAR_FILE)
$(APP_TAR_FILE): $(APP_DIR)
(cd $(APP_RELEASE_DIR); gtar zcf $(APP_TAR_FILE) $(DIR_NAME))
-dialyzer:
- (cd ./ebin; \
- dialyzer --build_plt \
- --output_plt ../priv/megaco.plt \
- -r ../../megaco/ebin \
- --verbose)
+dialyzer_plt: $(MEGACO_DIA_PLT)
+
+$(MEGACO_DIA_PLT):
+ @echo "Building megaco plt file"
+ @dialyzer --build_plt \
+ --output_plt $@ \
+ -r ../megaco/ebin \
+ -o $(MEGACO_DIA_PLT_LOG) \
+ --verbose
+
+dialyzer: $(MEGACO_DIA_PLT)
+ (dialyzer --plt $< \
+ -o $(MEGACO_DIA_LOG) \
+ ../megaco/ebin \
+ && (shell cat $(MEGACO_DIA_LOG)))
diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml
index 81c9305542..4f678a2a1b 100644
--- a/lib/megaco/doc/src/notes.xml
+++ b/lib/megaco/doc/src/notes.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
- <year>2000</year><year>2010</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -35,22 +35,90 @@
thus constitutes one section in this document. The title of each
section is the version number of Megaco.</p>
+
+ <section><title>Megaco 3.15.1</title>
+
+ <p>Version 3.15.1 supports code replacement in runtime from/to
+ version 3.15, 3.14.1.1, 3.14.1 and 3.14.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+
+ <p>-</p>
+
+<!--
+ <list type="bulleted">
+ <item>
+ <p>Updated the
+ <seealso marker="megaco_performance">performance</seealso>
+ chapter. </p>
+ <p>Own Id: OTP-8696</p>
+ </item>
+
+ </list>
+-->
+
+ </section>
+
+ <section>
+ <title>Fixed bugs and malfunctions</title>
+
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>Fixing miscellaneous things detected by dialyzer. </p>
+ <p>Own Id: OTP-9075</p>
+ <!-- <p>Aux Id: Seq 11579</p> -->
+ </item>
+
+ </list>
+
+ </section>
+
+ </section> <!-- 3.15.1 -->
+
+
<section><title>Megaco 3.15</title>
<section><title>Improvements and New Features</title>
- <list>
+
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>Fixing auto-import issues.</p>
+ <p>Own Id: OTP-8842</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Fixed bugs and malfunctions</title>
+ <p>-</p>
+
+<!--
+ <list type="bulleted">
<item>
- <p>
- Fixing auto-import issues.</p>
- <p>
- Own Id: OTP-8842</p>
+ <p>Eliminated a possible race condition while creating
+ pending counters. </p>
+ <p>Own Id: OTP-8634</p>
+ <p>Aux Id: Seq 11579</p>
</item>
+
</list>
+-->
+
</section>
-</section>
+ </section> <!-- 3.15 -->
-<section>
+
+ <section>
<title>Megaco 3.14.1.1</title>
<p>Version 3.14.1.1 supports code replacement in runtime from/to
diff --git a/lib/megaco/src/app/megaco.app.src b/lib/megaco/src/app/megaco.app.src
index 503fcd7176..c0d8218ac8 100644
--- a/lib/megaco/src/app/megaco.app.src
+++ b/lib/megaco/src/app/megaco.app.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -67,6 +67,7 @@
megaco_compact_text_encoder_prev3c,
megaco_compact_text_encoder_v3,
megaco_config,
+ megaco_config_misc,
megaco_digit_map,
megaco_encoder,
megaco_edist_compress,
diff --git a/lib/megaco/src/app/megaco.appup.src b/lib/megaco/src/app/megaco.appup.src
index 66068f650f..01b070d79f 100644
--- a/lib/megaco/src/app/megaco.appup.src
+++ b/lib/megaco/src/app/megaco.appup.src
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -133,50 +133,34 @@
%% |
%% v
%% 3.15
+%% |
+%% v
+%% 3.15.1
%%
%%
{"%VSN%",
[
- {"3.14.1.1",
+ {"3.15",
[
- {load_module, megaco_binary_transformer_prev3a, soft_purge, soft_purge, []},
- {load_module, megaco_binary_transformer_prev3b, soft_purge, soft_purge, []},
- {load_module, megaco_binary_transformer_prev3c, soft_purge, soft_purge, []},
+ {load_module, megaco_flex_scanner, soft_purge, soft_purge, []},
{load_module, megaco_sdp, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_v1, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_v1, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_v2, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_v2, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_prev3a, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_prev3a, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_prev3b, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_prev3b, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_prev3c, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_prev3c, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_v3, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_v3, soft_purge, soft_purge, []}
+ {load_module, megaco_filter, soft_purge, soft_purge, []},
+ {load_module, megaco_timer, soft_purge, soft_purge, [megaco_config_misc]},
+ {update, megaco_config, soft, soft_purge, soft_purge,
+ [megaco_timer, megaco_config_misc]},
+ {add_module, megaco_config_misc}
]
}
],
[
- {"3.14.1.1",
+ {"3.15",
[
- {load_module, megaco_binary_transformer_prev3a, soft_purge, soft_purge, []},
- {load_module, megaco_binary_transformer_prev3b, soft_purge, soft_purge, []},
- {load_module, megaco_binary_transformer_prev3c, soft_purge, soft_purge, []},
+ {load_module, megaco_flex_scanner, soft_purge, soft_purge, []},
{load_module, megaco_sdp, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_v1, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_v1, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_v2, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_v2, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_prev3a, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_prev3a, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_prev3b, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_prev3b, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_prev3c, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_prev3c, soft_purge, soft_purge, []},
- {load_module, megaco_compact_text_encoder_v3, soft_purge, soft_purge, []},
- {load_module, megaco_pretty_text_encoder_v3, soft_purge, soft_purge, []}
+ {load_module, megaco_filter, soft_purge, soft_purge, []},
+ {load_module, megaco_timer, soft_purge, soft_purge, [megaco_config]},
+ {update, megaco_config, soft, soft_purge, soft_purge, []},
+ {remove, {megaco_config_misc, soft_purge, brutal_purge}}
]
}
]
diff --git a/lib/megaco/src/binary/megaco_binary_encoder_lib.erl b/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
index 842d6b70d1..967ee93935 100644
--- a/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
+++ b/lib/megaco/src/binary/megaco_binary_encoder_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -134,6 +134,12 @@ encode_transaction(EC, {Tag, _} = Trans, AsnMod, TransMod, Type)
encode_transaction(_EC, T, _AsnMod, _TransMod, _Type) ->
{error, {no_megaco_transaction, T}}.
+-spec do_encode_transaction(EC :: list(),
+ Trans :: tuple(),
+ AnsMod :: atom(),
+ TransMod :: atom(),
+ Type :: atom()) ->
+ {'ok', binary()} | {'error', any()}.
do_encode_transaction([native], _Trans, _AsnMod, _TransMod, binary) ->
%% asn1rt:encode(AsnMod, element(1, T), T);
{error, not_implemented};
@@ -160,6 +166,12 @@ do_encode_transaction(EC, _Trans, _AsnMod, _TransMod, _Type) ->
%% Convert a list of ActionRequest record's into a binary
%% Return {ok, DeepIoList} | {error, Reason}
%%----------------------------------------------------------------------
+-spec encode_action_requests(EC :: list(),
+ ARs :: list(),
+ AnsMod :: atom(),
+ TransMod :: atom(),
+ Type :: atom()) ->
+ {'ok', binary()} | {'error', any()}.
encode_action_requests([native], _ARs, _AsnMod, _TransMod, binary) ->
%% asn1rt:encode(AsnMod, element(1, T), T);
{error, not_implemented};
@@ -183,13 +195,20 @@ encode_action_requests(EC, _ARs, _AsnMod, _TransMod, _Type) ->
%% Convert a ActionRequest record into a binary
%% Return {ok, DeepIoList} | {error, Reason}
%%----------------------------------------------------------------------
-encode_action_request([native], _ARs, _AsnMod, _TransMod, binary) ->
+
+-spec encode_action_request(EC :: list(),
+ AR :: tuple(),
+ AnsMod :: atom(),
+ TransMod :: atom(),
+ Type :: atom()) ->
+ {'ok', binary()} | {'error', any()}.
+encode_action_request([native], _AR, _AsnMod, _TransMod, binary) ->
%% asn1rt:encode(AsnMod, element(1, T), T);
{error, not_implemented};
-encode_action_request(_EC, _ARs0, _AsnMod, _TransMod, binary) ->
+encode_action_request(_EC, _AR, _AsnMod, _TransMod, binary) ->
{error, not_implemented};
-encode_action_request(EC, ARs, AsnMod, TransMod, io_list) ->
- case encode_action_request(EC, ARs, AsnMod, TransMod, binary) of
+encode_action_request(EC, AR, AsnMod, TransMod, io_list) ->
+ case encode_action_request(EC, AR, AsnMod, TransMod, binary) of
{ok, Bin} when is_binary(Bin) ->
{ok, Bin};
{ok, DeepIoList} ->
@@ -198,7 +217,7 @@ encode_action_request(EC, ARs, AsnMod, TransMod, io_list) ->
{error, Reason} ->
{error, Reason}
end;
-encode_action_request(EC, _ARs, _AsnMod, _TransMod, _Type) ->
+encode_action_request(EC, _AR, _AsnMod, _TransMod, _Type) ->
{error, {bad_encoding_config, EC}}.
diff --git a/lib/megaco/src/engine/depend.mk b/lib/megaco/src/engine/depend.mk
index 8d8c83e923..935eb813e5 100644
--- a/lib/megaco/src/engine/depend.mk
+++ b/lib/megaco/src/engine/depend.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2003-2009. All Rights Reserved.
+# Copyright Ericsson AB 2003-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -17,6 +17,8 @@
#
# %CopyrightEnd%
+$(EBIN)/megaco_config_misc.$(EMULATOR): megaco_config_misc.erl
+
$(EBIN)/megaco_config.$(EMULATOR): megaco_config.erl \
../../include/megaco.hrl \
../app/megaco_internal.hrl
diff --git a/lib/megaco/src/engine/megaco_config.erl b/lib/megaco/src/engine/megaco_config.erl
index 6805db790d..b65ddbe232 100644
--- a/lib/megaco/src/engine/megaco_config.erl
+++ b/lib/megaco/src/engine/megaco_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -46,10 +46,10 @@
%% Verification functions
verify_val/2,
- verify_strict_uint/1,
- verify_strict_int/1, verify_strict_int/2,
- verify_uint/1,
- verify_int/1, verify_int/2,
+%% verify_strict_uint/1,
+%% verify_strict_int/1, verify_strict_int/2,
+%% verify_uint/1,
+%% verify_int/1, verify_int/2,
%% Reply limit counter
@@ -1501,28 +1501,37 @@ verify_val(Item, Val) ->
mid -> true;
local_mid -> true;
remote_mid -> true;
- min_trans_id -> verify_strict_uint(Val, 4294967295); % uint32
- max_trans_id -> verify_uint(Val, 4294967295); % uint32
+ min_trans_id ->
+ megaco_config_misc:verify_strict_uint(Val, 4294967295); % uint32
+ max_trans_id ->
+ megaco_config_misc:verify_uint(Val, 4294967295); % uint32
request_timer -> verify_timer(Val);
long_request_timer -> verify_timer(Val);
- auto_ack -> verify_bool(Val);
+ auto_ack ->
+ megaco_config_misc:verify_bool(Val);
- trans_ack -> verify_bool(Val);
- trans_ack_maxcount -> verify_uint(Val);
+ trans_ack ->
+ megaco_config_misc:verify_bool(Val);
+ trans_ack_maxcount ->
+ megaco_config_misc:verify_uint(Val);
- trans_req -> verify_bool(Val);
- trans_req_maxcount -> verify_uint(Val);
- trans_req_maxsize -> verify_uint(Val);
+ trans_req ->
+ megaco_config_misc:verify_bool(Val);
+ trans_req_maxcount ->
+ megaco_config_misc:verify_uint(Val);
+ trans_req_maxsize ->
+ megaco_config_misc:verify_uint(Val);
- trans_timer -> verify_timer(Val) and (Val >= 0);
- trans_sender when Val == undefined -> true;
+ trans_timer ->
+ verify_timer(Val) and (Val >= 0);
+ trans_sender when Val =:= undefined -> true;
pending_timer -> verify_timer(Val);
- sent_pending_limit -> verify_uint(Val) andalso
- (Val > 0);
- recv_pending_limit -> verify_uint(Val) andalso
- (Val > 0);
+ sent_pending_limit ->
+ megaco_config_misc:verify_uint(Val) andalso (Val > 0);
+ recv_pending_limit ->
+ megaco_config_misc:verify_uint(Val) andalso (Val > 0);
reply_timer -> verify_timer(Val);
control_pid when is_pid(Val) -> true;
monitor_ref -> true; % Internal usage only
@@ -1530,110 +1539,43 @@ verify_val(Item, Val) ->
send_handle -> true;
encoding_mod when is_atom(Val) -> true;
encoding_config when is_list(Val) -> true;
- protocol_version -> verify_strict_uint(Val);
+ protocol_version ->
+ megaco_config_misc:verify_strict_uint(Val);
auth_data -> true;
user_mod when is_atom(Val) -> true;
user_args when is_list(Val) -> true;
reply_data -> true;
- threaded -> verify_bool(Val);
- strict_version -> verify_bool(Val);
- long_request_resend -> verify_bool(Val);
- call_proxy_gc_timeout -> verify_strict_uint(Val);
- cancel -> verify_bool(Val);
+ threaded ->
+ megaco_config_misc:verify_bool(Val);
+ strict_version ->
+ megaco_config_misc:verify_bool(Val);
+ long_request_resend ->
+ megaco_config_misc:verify_bool(Val);
+ call_proxy_gc_timeout ->
+ megaco_config_misc:verify_strict_uint(Val);
+ cancel ->
+ megaco_config_misc:verify_bool(Val);
resend_indication -> verify_resend_indication(Val);
- segment_reply_ind -> verify_bool(Val);
- segment_recv_acc -> verify_bool(Val);
+ segment_reply_ind ->
+ megaco_config_misc:verify_bool(Val);
+ segment_recv_acc ->
+ megaco_config_misc:verify_bool(Val);
segment_recv_timer -> verify_timer(Val);
segment_send -> verify_segmentation_window(Val);
segment_send_timer -> verify_timer(Val);
- max_pdu_size -> verify_int(Val) andalso (Val > 0);
+ max_pdu_size ->
+ megaco_config_misc:verify_int(Val) andalso (Val > 0);
request_keep_alive_timeout ->
- (verify_uint(Val) orelse (Val =:= plain));
+ (megaco_config_misc:verify_uint(Val) orelse (Val =:= plain));
_ -> false
end.
-verify_bool(true) -> true;
-verify_bool(false) -> true;
-verify_bool(_) -> false.
-
verify_resend_indication(flag) -> true;
-verify_resend_indication(Val) -> verify_bool(Val).
-
--spec verify_strict_int(Int :: integer()) -> boolean().
-verify_strict_int(Int) when is_integer(Int) -> true;
-verify_strict_int(_) -> false.
-
--spec verify_strict_int(Int :: integer(),
- Max :: integer() | 'infinity') -> boolean().
-verify_strict_int(Int, infinity) ->
- verify_strict_int(Int);
-verify_strict_int(Int, Max) ->
- verify_strict_int(Int) andalso verify_strict_int(Max) andalso (Int =< Max).
-
--spec verify_strict_uint(Int :: non_neg_integer()) -> boolean().
-verify_strict_uint(Int) when is_integer(Int) andalso (Int >= 0) -> true;
-verify_strict_uint(_) -> false.
-
--spec verify_strict_uint(Int :: non_neg_integer(),
- Max :: non_neg_integer() | 'infinity') -> boolean().
-verify_strict_uint(Int, infinity) ->
- verify_strict_uint(Int);
-verify_strict_uint(Int, Max) ->
- verify_strict_int(Int, 0, Max).
-
--spec verify_uint(Val :: non_neg_integer() | 'infinity') -> boolean().
-verify_uint(infinity) -> true;
-verify_uint(Val) -> verify_strict_uint(Val).
-
--spec verify_int(Val :: integer() | 'infinity') -> boolean().
-verify_int(infinity) -> true;
-verify_int(Val) -> verify_strict_int(Val).
-
--spec verify_int(Int :: integer() | 'infinity',
- Max :: integer() | 'infinity') -> boolean().
-verify_int(Int, infinity) ->
- verify_int(Int);
-verify_int(infinity, _Max) ->
- true;
-verify_int(Int, Max) ->
- verify_strict_int(Int) andalso verify_strict_int(Max) andalso (Int =< Max).
-
--spec verify_uint(Int :: non_neg_integer() | 'infinity',
- Max :: non_neg_integer() | 'infinity') -> boolean().
-verify_uint(Int, infinity) ->
- verify_uint(Int);
-verify_uint(infinity, _Max) ->
- true;
-verify_uint(Int, Max) ->
- verify_strict_int(Int, 0, Max).
-
--spec verify_strict_int(Int :: integer(),
- Min :: integer(),
- Max :: integer()) -> boolean().
-verify_strict_int(Val, Min, Max)
- when (is_integer(Val) andalso
- is_integer(Min) andalso
- is_integer(Max) andalso
- (Val >= Min) andalso
- (Val =< Max)) ->
- true;
-verify_strict_int(_Val, _Min, _Max) ->
- false.
-
--spec verify_int(Val :: integer() | 'infinity',
- Min :: integer(),
- Max :: integer() | 'infinity') -> boolean().
-verify_int(infinity, Min, infinity) ->
- verify_strict_int(Min);
-verify_int(Val, Min, infinity) ->
- verify_strict_int(Val) andalso
- verify_strict_int(Min) andalso (Val >= Min);
-verify_int(Int, Min, Max) ->
- verify_strict_int(Int, Min, Max).
+verify_resend_indication(Val) -> megaco_config_misc:verify_bool(Val).
verify_timer(Timer) ->
megaco_timer:verify(Timer).
@@ -1641,7 +1583,7 @@ verify_timer(Timer) ->
verify_segmentation_window(none) ->
true;
verify_segmentation_window(K) ->
- verify_int(K, 1, infinity).
+ megaco_config_misc:verify_int(K, 1, infinity).
handle_stop_user(UserMid) ->
case catch user_info(UserMid, mid) of
diff --git a/lib/megaco/src/engine/megaco_config_misc.erl b/lib/megaco/src/engine/megaco_config_misc.erl
new file mode 100644
index 0000000000..0a1601c766
--- /dev/null
+++ b/lib/megaco/src/engine/megaco_config_misc.erl
@@ -0,0 +1,113 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2011-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Utility module for megaco_config
+%%----------------------------------------------------------------------
+%%
+
+-module(megaco_config_misc).
+
+%% Application internal exports
+-export([
+ verify_bool/1,
+
+ verify_int/1, verify_int/2, verify_int/3,
+ verify_strict_int/1, verify_strict_int/2, verify_strict_int/3,
+
+ verify_uint/1, verify_uint/2,
+ verify_strict_uint/1, verify_strict_uint/2
+ ]).
+
+
+%%%----------------------------------------------------------------------
+%%% API
+%%%----------------------------------------------------------------------
+
+verify_bool(true) -> true;
+verify_bool(false) -> true;
+verify_bool(_) -> false.
+
+
+%% verify_int(Val) -> boolean()
+verify_int(infinity) -> true;
+verify_int(Val) -> verify_strict_int(Val).
+
+%% verify_int(Val, Max) -> boolean()
+verify_int(Int, infinity) ->
+ verify_int(Int);
+verify_int(infinity, _Max) ->
+ true;
+verify_int(Int, Max) ->
+ verify_strict_int(Int) andalso verify_strict_int(Max) andalso (Int =< Max).
+
+%% verify_int(Val, Min, Max) -> boolean()
+verify_int(infinity, Min, infinity) ->
+ verify_strict_int(Min);
+verify_int(Val, Min, infinity) ->
+ verify_strict_int(Val) andalso
+ verify_strict_int(Min) andalso (Val >= Min);
+verify_int(Int, Min, Max) ->
+ verify_strict_int(Int, Min, Max).
+
+%% verify_strict_int(Val) -> boolean()
+verify_strict_int(Int) when is_integer(Int) -> true;
+verify_strict_int(_) -> false.
+
+%% verify_strict_int(Val, Max) -> boolean()
+verify_strict_int(Int, infinity) ->
+ verify_strict_int(Int);
+verify_strict_int(Int, Max) ->
+ verify_strict_int(Int) andalso verify_strict_int(Max) andalso (Int =< Max).
+
+%% verify_strict_int(Val, Min, Max) -> boolean()
+verify_strict_int(Val, Min, Max)
+ when (is_integer(Val) andalso
+ is_integer(Min) andalso
+ is_integer(Max) andalso
+ (Val >= Min) andalso
+ (Val =< Max)) ->
+ true;
+verify_strict_int(_Val, _Min, _Max) ->
+ false.
+
+
+%% verify_uint(Val) -> boolean()
+verify_uint(infinity) -> true;
+verify_uint(Val) -> verify_strict_uint(Val).
+
+%% verify_uint(Val, Max) -> boolean()
+verify_uint(Int, infinity) ->
+ verify_uint(Int);
+verify_uint(infinity, _Max) ->
+ true;
+verify_uint(Int, Max) ->
+ verify_strict_int(Int, 0, Max).
+
+%% verify_strict_uint(Val) -> boolean()
+verify_strict_uint(Int) when is_integer(Int) andalso (Int >= 0) -> true;
+verify_strict_uint(_) -> false.
+
+%% verify_strict_uint(Val, Max) -> boolean()
+verify_strict_uint(Int, infinity) ->
+ verify_strict_uint(Int);
+verify_strict_uint(Int, Max) ->
+ verify_strict_int(Int, 0, Max).
+
diff --git a/lib/megaco/src/engine/megaco_filter.erl b/lib/megaco/src/engine/megaco_filter.erl
index 9df752789c..fb0c700a82 100644
--- a/lib/megaco/src/engine/megaco_filter.erl
+++ b/lib/megaco/src/engine/megaco_filter.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,6 +21,7 @@
%%----------------------------------------------------------------------
%% Purpose : Megaco/H.248 customization of the Event Tracer tool
%%----------------------------------------------------------------------
+%%
-module(megaco_filter).
@@ -33,6 +34,7 @@
-include_lib("megaco/src/app/megaco_internal.hrl").
-include_lib("et/include/et.hrl").
+
%%----------------------------------------------------------------------
%% BUGBUG: There are some opportunities for improvements:
%%
@@ -43,7 +45,8 @@
%% records that already are defined in megaco_message_{v1,v2,v3}.hrl.
%% * The records megaco_udp and megaco_tcp are copied from the files
%% megaco_udp.hrl and megaco_tcp.hrl respectively, as we cannot include
-%% both header files. They both defines the macros HEAP_SIZE and GC_MSG_LIMIT.
+%% both header files.
+%% They both defines the macros HEAP_SIZE and GC_MSG_LIMIT.
%%-include("megaco_message_internal.hrl").
-record('megaco_transaction_reply',
@@ -76,6 +79,8 @@
module = megaco,
serialize = false % false: Spawn a new process for each message
}).
+
+
%%----------------------------------------------------------------------
start() ->
@@ -360,28 +365,24 @@ pretty(_ConnData, MegaMsg) when is_record(MegaMsg, 'MegacoMessage') ->
{ok, Bin} = megaco_pretty_text_encoder:encode_message([], MegaMsg),
term_to_string(Bin);
pretty(_ConnData, CmdReq) when is_record(CmdReq, 'CommandRequest') ->
- {ok, IoList} = megaco_pretty_text_encoder:encode_command_request(CmdReq),
- term_to_string(lists:flatten(IoList));
+ {ok, Bin} = megaco_pretty_text_encoder:encode_command_request(CmdReq),
+ term_to_string(Bin);
pretty(_ConnData, {complete_success, ContextId, RepList}) ->
ActRep = #'ActionReply'{contextId = ContextId,
commandReply = RepList},
- {ok, IoList} = megaco_pretty_text_encoder:encode_action_reply(ActRep),
- term_to_string(lists:flatten(IoList));
+ {ok, Bin} = megaco_pretty_text_encoder:encode_action_reply(ActRep),
+ term_to_string(Bin);
pretty(_ConnData, AR) when is_record(AR, 'ActionReply') ->
- {ok, IoList} = megaco_pretty_text_encoder:encode_action_reply(AR),
- term_to_string(lists:flatten(IoList));
+ {ok, Bin} = megaco_pretty_text_encoder:encode_action_reply(AR),
+ term_to_string(Bin);
pretty(_ConnData, {partial_failure, ContextId, RepList}) ->
ActRep = #'ActionReply'{contextId = ContextId,
commandReply = RepList},
- {ok, IoList} = megaco_pretty_text_encoder:encode_action_reply(ActRep),
- term_to_string(lists:flatten(IoList));
+ {ok, Bin} = megaco_pretty_text_encoder:encode_action_reply(ActRep),
+ term_to_string(Bin);
pretty(_ConnData, {trans, Trans}) ->
- case megaco_pretty_text_encoder:encode_transaction(Trans) of
- {ok, Bin} when is_binary(Bin) ->
- term_to_string(binary_to_list(Bin));
- {ok, IoList} ->
- term_to_string(lists:flatten(IoList))
- end;
+ {ok, Bin} = megaco_pretty_text_encoder:encode_transaction(Trans),
+ term_to_string(Bin);
pretty(__ConnData, Other) ->
term_to_string(Other).
diff --git a/lib/megaco/src/engine/megaco_sdp.erl b/lib/megaco/src/engine/megaco_sdp.erl
index 37f28cac59..96732584fb 100644
--- a/lib/megaco/src/engine/megaco_sdp.erl
+++ b/lib/megaco/src/engine/megaco_sdp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -877,9 +877,7 @@ decode_bandwidth_bwt("CT") ->
decode_bandwidth_bwt("AS") ->
as;
decode_bandwidth_bwt(BwType) when is_list(BwType) ->
- BwType;
-decode_bandwidth_bwt(BadBwType) ->
- error({invalid_bandwidth_bwtype, BadBwType}).
+ BwType.
encode_bandwidth_bwt(ct) ->
"CT";
diff --git a/lib/megaco/src/engine/megaco_timer.erl b/lib/megaco/src/engine/megaco_timer.erl
index 9f524523a8..1336be0b5b 100644
--- a/lib/megaco/src/engine/megaco_timer.erl
+++ b/lib/megaco/src/engine/megaco_timer.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -42,7 +42,7 @@
%% NewTimer = megaco_timer()
%% TimeoutTime = infinity | integer()
%%
-init(SingleWaitFor) when SingleWaitFor == infinity ->
+init(SingleWaitFor) when SingleWaitFor =:= infinity ->
{SingleWaitFor, timeout};
init(SingleWaitFor) when is_integer(SingleWaitFor) and (SingleWaitFor >= 0) ->
{SingleWaitFor, timeout};
@@ -76,17 +76,17 @@ verify(#megaco_incr_timer{wait_for = WaitFor,
factor = Factor,
incr = Incr,
max_retries = MaxRetries}) ->
- (megaco_config:verify_strict_uint(WaitFor) and
- megaco_config:verify_strict_uint(Factor) and
- megaco_config:verify_strict_int(Incr) and
+ (megaco_config_misc:verify_strict_uint(WaitFor) and
+ megaco_config_misc:verify_strict_uint(Factor) and
+ megaco_config_misc:verify_strict_int(Incr) and
verify_max_retries(MaxRetries));
verify(Timer) ->
- megaco_config:verify_uint(Timer).
+ megaco_config_misc:verify_uint(Timer).
verify_max_retries(infinity_restartable) ->
true;
verify_max_retries(Val) ->
- megaco_config:verify_uint(Val).
+ megaco_config_misc:verify_uint(Val).
%%-----------------------------------------------------------------
diff --git a/lib/megaco/src/engine/modules.mk b/lib/megaco/src/engine/modules.mk
index 44bcadc37b..4bc57cd63e 100644
--- a/lib/megaco/src/engine/modules.mk
+++ b/lib/megaco/src/engine/modules.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+# Copyright Ericsson AB 2001-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -24,6 +24,7 @@ BEHAVIOUR_MODULES = \
MODULES = \
$(BEHAVIOUR_MODULES) \
+ megaco_config_misc \
megaco_config \
megaco_digit_map \
megaco_erl_dist_encoder \
diff --git a/lib/megaco/src/flex/megaco_flex_scanner.erl b/lib/megaco/src/flex/megaco_flex_scanner.erl
index e471412c13..508f8905e7 100644
--- a/lib/megaco/src/flex/megaco_flex_scanner.erl
+++ b/lib/megaco/src/flex/megaco_flex_scanner.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -30,21 +30,11 @@
-define(SCHED_ID(), erlang:system_info(scheduler_id)).
-define(SMP_SUPPORT_DEFAULT(), erlang:system_info(smp_support)).
-is_enabled() ->
- case ?ENABLE_MEGACO_FLEX_SCANNER of
- true ->
- true;
- _ ->
- false
- end.
+is_enabled() ->
+ (true =:= ?ENABLE_MEGACO_FLEX_SCANNER).
is_reentrant_enabled() ->
- case ?MEGACO_REENTRANT_FLEX_SCANNER of
- true ->
- true;
- _ ->
- false
- end.
+ (true =:= ?MEGACO_REENTRANT_FLEX_SCANNER).
is_scanner_port(Port, Port) when is_port(Port) ->
true;
diff --git a/lib/megaco/test/megaco.cover b/lib/megaco/test/megaco.cover
index e7764017d4..be21216c24 100644
--- a/lib/megaco/test/megaco.cover
+++ b/lib/megaco/test/megaco.cover
@@ -1,5 +1,7 @@
+{incl_app,megaco,details}.
+
%% -*- erlang -*-
-{exclude,
+{excl_mods, megaco,
[megaco_encoder,
megaco_edist_compress,
megaco_filter,
diff --git a/lib/megaco/test/megaco.spec b/lib/megaco/test/megaco.spec
index 7493bd5df8..cab8499835 100644
--- a/lib/megaco/test/megaco.spec
+++ b/lib/megaco/test/megaco.spec
@@ -1,5 +1,2 @@
-{topcase, {dir, "../megaco_test"}}.
-{require_nodenames, 1}.
-%{skip, {megaco_digit_map_test, all, "Not yet implemented"}}.
-{skip, {megaco_measure_test, all, "Not yet implemented"}}.
-%{skip, {M, F, "Not yet implemented"}}.
+{suites,"../megaco_test",all}.
+{skip_cases,"../megaco_test",megaco_measure_test,[all],"Not yet implemented"}.
diff --git a/lib/megaco/test/megaco_SUITE.erl b/lib/megaco/test/megaco_SUITE.erl
index 1bb3a570a4..007677ba4d 100644
--- a/lib/megaco/test/megaco_SUITE.erl
+++ b/lib/megaco/test/megaco_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -36,8 +36,8 @@ t(Case) -> megaco_test_lib:t({?MODULE, Case}).
init_per_testcase(Case, Config) ->
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
init() ->
process_flag(trap_exit, true),
@@ -46,97 +46,86 @@ init() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- app_test,
- appup_test,
- config,
- flex,
- udp,
- tcp,
- examples,
- %% call_flow,
- digit_map,
- mess,
- measure,
- binary_term_id,
- codec,
- sdp,
- mib,
- trans,
- actions,
- load,
- pending_limit,
- segmented,
- timer
- ].
+suite() -> [{ct_hooks, [{ts_install_cth, [{nodenames,1}]}]}].
+
+all() ->
+ [{group, app_test},
+ {group, appup_test},
+ {group, config},
+ {group, flex},
+ {group, udp},
+ {group, tcp},
+ {group, examples},
+ {group, digit_map},
+ {group, mess},
+ {group, measure},
+ {group, binary_term_id},
+ {group, codec},
+ {group, sdp},
+ {group, mib},
+ {group, trans},
+ {group, actions},
+ {group, load},
+ {group, pending_limit},
+ {group, segmented},
+ {group, timer}].
+
+groups() ->
+ [{tickets, [], [{group, mess}, {group, codec}]},
+ {app_test, [], [{megaco_app_test, all}]},
+ {appup_test, [], [{megaco_appup_test, all}]},
+ {config, [], [{megaco_config_test, all}]},
+ {call_flow, [], [{megaco_call_flow_test, all}]},
+ {digit_map, [], [{megaco_digit_map_test, all}]},
+ {mess, [], [{megaco_mess_test, all}]},
+ {udp, [], [{megaco_udp_test, all}]},
+ {tcp, [], [{megaco_tcp_test, all}]},
+ {examples, [], [{megaco_examples_test, all}]},
+ {measure, [], [{megaco_measure_test, all}]},
+ {binary_term_id, [], [{megaco_binary_term_id_test, all}]},
+ {codec, [], [{megaco_codec_test, all}]},
+ {sdp, [], [{megaco_sdp_test, all}]},
+ {mib, [], [{megaco_mib_test, all}]},
+ {trans, [], [{megaco_trans_test, all}]},
+ {actions, [], [{megaco_actions_test, all}]},
+ {load, [], [{megaco_load_test, all}]},
+ {pending_limit, [], [{megaco_pending_limit_test, all}]},
+ {segmented, [], [{megaco_segment_test, all}]},
+ {timer, [], [{megaco_timer_test, all}]},
+ {flex, [], [{megaco_flex_test, all}]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-tickets(suite) ->
- [
- mess,
- codec
- ].
-app_test(suite) ->
- [{megaco_app_test, all}].
-appup_test(suite) ->
- [{megaco_appup_test, all}].
-config(suite) ->
- [{megaco_config_test, all}].
-call_flow(suite) ->
- [{megaco_call_flow_test, all}].
-digit_map(suite) ->
- [{megaco_digit_map_test, all}].
-mess(suite) ->
- [{megaco_mess_test, all}].
-udp(suite) ->
- [{megaco_udp_test, all}].
-tcp(suite) ->
- [{megaco_tcp_test, all}].
-examples(suite) ->
- [{megaco_examples_test, all}].
-measure(suite) ->
- [{megaco_measure_test, all}].
-binary_term_id(suite) ->
- [{megaco_binary_term_id_test, all}].
-codec(suite) ->
- [{megaco_codec_test, all}].
-sdp(suite) ->
- [{megaco_sdp_test, all}].
-mib(suite) ->
- [{megaco_mib_test, all}].
-trans(suite) ->
- [{megaco_trans_test, all}].
-actions(suite) ->
- [{megaco_actions_test, all}].
-load(suite) ->
- [{megaco_load_test, all}].
-pending_limit(suite) ->
- [{megaco_pending_limit_test, all}].
-segmented(suite) ->
- [{megaco_segment_test, all}].
-timer(suite) ->
- [{megaco_timer_test, all}].
-flex(suite) ->
- [{megaco_flex_test, all}].
diff --git a/lib/megaco/test/megaco_actions_test.erl b/lib/megaco/test/megaco_actions_test.erl
index d493022ca1..2efb6e834a 100644
--- a/lib/megaco/test/megaco_actions_test.erl
+++ b/lib/megaco/test/megaco_actions_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-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
@@ -72,28 +72,25 @@ init_per_testcase(Case, Config) ->
process_flag(trap_exit, true),
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
process_flag(trap_exit, false),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- pretty_text,
- flex_pretty_text,
- compact_text,
- flex_compact_text,
- erl_dist,
- erl_dist_mc,
- ber_bin,
- ber_bin_drv,
- ber_bin_native,
- ber_bin_drv_native
- ],
- Cases.
+all() ->
+ [pretty_text, flex_pretty_text, compact_text,
+ flex_compact_text, erl_dist, erl_dist_mc, ber_bin,
+ ber_bin_drv, ber_bin_native, ber_bin_drv_native].
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_app_test.erl b/lib/megaco/test/megaco_app_test.erl
index 597ec26338..00f7b7fb68 100644
--- a/lib/megaco/test/megaco_app_test.erl
+++ b/lib/megaco/test/megaco_app_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -39,28 +39,36 @@ init_per_testcase(undef_funcs = Case, Config) ->
init_per_testcase(Case, Config) ->
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- fields,
- modules,
- exportall,
- app_depend,
- undef_funcs
- ],
- {req, [], {conf, app_init, Cases, app_fin}}.
+all() ->
+ [
+ fields,
+ modules,
+ exportall,
+ app_depend,
+ undef_funcs
+ ].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-app_init(suite) -> [];
-app_init(doc) -> [];
-app_init(Config) when is_list(Config) ->
+init_per_suite(suite) -> [];
+init_per_suite(doc) -> [];
+init_per_suite(Config) when is_list(Config) ->
case is_app(megaco) of
{ok, AppFile} ->
io:format("AppFile: ~n~p~n", [AppFile]),
@@ -96,9 +104,9 @@ is_app(App) ->
end.
-app_fin(suite) -> [];
-app_fin(doc) -> [];
-app_fin(Config) when is_list(Config) ->
+end_per_suite(suite) -> [];
+end_per_suite(doc) -> [];
+end_per_suite(Config) when is_list(Config) ->
Config.
@@ -110,7 +118,7 @@ fields(doc) ->
[];
fields(Config) when is_list(Config) ->
AppFile = key1search(app_file, Config),
- Fields = [vsn, description, modules, registered, applications],
+ Fields = [vsn, description, modules, registered, applications],
case check_fields(Fields, AppFile, []) of
[] ->
ok;
diff --git a/lib/megaco/test/megaco_appup_mg.erl b/lib/megaco/test/megaco_appup_mg.erl
index f6060e406b..bb8b098f5d 100644
--- a/lib/megaco/test/megaco_appup_mg.erl
+++ b/lib/megaco/test/megaco_appup_mg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/megaco/test/megaco_appup_mgc.erl b/lib/megaco/test/megaco_appup_mgc.erl
index b6e53655f8..49c5f24852 100644
--- a/lib/megaco/test/megaco_appup_mgc.erl
+++ b/lib/megaco/test/megaco_appup_mgc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/megaco/test/megaco_appup_test.erl b/lib/megaco/test/megaco_appup_test.erl
index 09732c6a4d..40eebcae86 100644
--- a/lib/megaco/test/megaco_appup_test.erl
+++ b/lib/megaco/test/megaco_appup_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -24,6 +24,7 @@
-module(megaco_appup_test).
-compile(export_all).
+-compile({no_auto_import,[error/1]}).
-include("megaco_test_lib.hrl").
@@ -37,25 +38,31 @@ t(Case) -> megaco_test_lib:t({?MODULE, Case}).
init_per_testcase(Case, Config) ->
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- appup
- ],
- {req, [], {conf, appup_init, Cases, appup_fin}}.
+all() ->
+ [appup].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-appup_init(suite) -> [];
-appup_init(doc) -> [];
-appup_init(Config) when is_list(Config) ->
+init_per_suite(suite) -> [];
+init_per_suite(doc) -> [];
+init_per_suite(Config) when is_list(Config) ->
AppFile = file_name(?APPLICATION, ".app"),
AppupFile = file_name(?APPLICATION, ".appup"),
[{app_file, AppFile}, {appup_file, AppupFile}|Config].
@@ -66,9 +73,9 @@ file_name(App, Ext) ->
filename:join([LibDir, "ebin", atom_to_list(App) ++ Ext]).
-appup_fin(suite) -> [];
-appup_fin(doc) -> [];
-appup_fin(Config) when is_list(Config) ->
+end_per_suite(suite) -> [];
+end_per_suite(doc) -> [];
+end_per_suite(Config) when is_list(Config) ->
Config.
diff --git a/lib/megaco/test/megaco_binary_term_id_test.erl b/lib/megaco/test/megaco_binary_term_id_test.erl
index da4e69c617..47a7a76c1c 100644
--- a/lib/megaco/test/megaco_binary_term_id_test.erl
+++ b/lib/megaco/test/megaco_binary_term_id_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -37,8 +37,8 @@
-export([t/0]).
%% Test suite exports
--export([all/1, encode_first/1, decode_first/1,
- init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
%%----------------------------------------------------------------------
@@ -57,25 +57,25 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- encode_first,
- decode_first
- ].
+all() ->
+ [{group, encode_first}, {group, decode_first}].
-encode_first(suite) ->
- encode_first_cases().
+groups() ->
+ [{encode_first, [], encode_first_cases()},
+ {decode_first, [], decode_first_cases()}].
-decode_first(suite) ->
- decode_first_cases().
+init_per_group(_GroupName, Config) ->
+ Config.
+end_per_group(_GroupName, Config) ->
+ Config.
%% Test server callbacks
init_per_testcase(Case, Config) ->
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
%%======================================================================
@@ -89,11 +89,12 @@ t() ->
cases() -> encode_first_cases() ++ decode_first_cases().
-encode_first_cases() -> [te01,te02,te03,te04,te05,
- te06,te07,te08,te09,te10,
- te11,te12,te13,te14,te15,
- te16,te17,te18,te19].
-decode_first_cases() -> [td01,td02,td03,td04,td05,td06].
+encode_first_cases() ->
+[te01, te02, te03, te04, te05, te06, te07, te08, te09,
+ te10, te11, te12, te13, te14, te15, te16, te17, te18,
+ te19].
+decode_first_cases() ->
+[td01, td02, td03, td04, td05, td06].
do(Case) ->
case doc(Case) of
diff --git a/lib/megaco/test/megaco_call_flow_test.erl b/lib/megaco/test/megaco_call_flow_test.erl
index a25a7924e8..b9d64ca8b2 100644
--- a/lib/megaco/test/megaco_call_flow_test.erl
+++ b/lib/megaco/test/megaco_call_flow_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-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
@@ -50,37 +50,25 @@ t(Case) -> megaco_test_lib:t({?MODULE, Case}).
init_per_testcase(Case, Config) ->
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- text,
- binary
- ].
+all() ->
+ [{group, text}, {group, binary}].
-text(suite) ->
- [
- pretty,
- compact
- ].
+groups() ->
+ [{text, [], [pretty, compact]},
+ {flex, [], [pretty_flex, compact_flex]},
+ {binary, [], [bin, ber, ber_bin, per]}].
-flex(suite) ->
- [
- pretty_flex,
- compact_flex
- ].
+init_per_group(_GroupName, Config) ->
+ Config.
-binary(suite) ->
- [
- bin,
- ber,
- ber_bin,
- per
- ].
+end_per_group(_GroupName, Config) ->
+ Config.
pretty(suite) ->
[];
diff --git a/lib/megaco/test/megaco_codec_flex_lib.erl b/lib/megaco/test/megaco_codec_flex_lib.erl
index de76956711..93bc5d4bbc 100644
--- a/lib/megaco/test/megaco_codec_flex_lib.erl
+++ b/lib/megaco/test/megaco_codec_flex_lib.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/megaco/test/megaco_codec_mini_test.erl b/lib/megaco/test/megaco_codec_mini_test.erl
index e509739bb1..ff0c154c7c 100644
--- a/lib/megaco/test/megaco_codec_mini_test.erl
+++ b/lib/megaco/test/megaco_codec_mini_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -34,14 +34,14 @@
-export([t/0, t/1]).
--export([all/1,
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
tickets/0,
- tickets/1,
+
otp7672_msg01/1,
otp7672_msg02/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
%% ----
@@ -49,31 +49,6 @@
-define(SET_DBG(S,D), begin put(severity, S), put(dbg, D) end).
-define(RESET_DBG(), begin erase(severity), erase(dbg) end).
-
-%% ----
-
-tickets() ->
- Flag = process_flag(trap_exit, true),
- Cases = expand(tickets),
- Fun = fun(Case) ->
- C = init_per_testcase(Case, [{tc_timeout,
- timer:minutes(10)}]),
- io:format("Eval ~w~n", [Case]),
- Result =
- case (catch apply(?MODULE, Case, [C])) of
- {'EXIT', Reason} ->
- io:format("~n~p exited:~n ~p~n",
- [Case, Reason]),
- {error, {Case, Reason}};
- Res ->
- Res
- end,
- fin_per_testcase(Case, C),
- Result
- end,
- process_flag(trap_exit, Flag),
- lists:map(Fun, Cases).
-
expand(RootCase) ->
expand([RootCase], []).
@@ -106,24 +81,51 @@ init_per_testcase(Case, Config) ->
end,
megaco_test_lib:init_per_testcase(Case, C).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
erase(verbosity),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- tickets
- ].
+all() ->
+ [{group, tickets}].
+
+groups() ->
+ [{tickets, [], [otp7672_msg01, otp7672_msg02]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
-tickets(suite) ->
- [
- otp7672_msg01,
- otp7672_msg02
- ].
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+
+%% ----
+
+tickets() ->
+ Flag = process_flag(trap_exit, true),
+ Cases = expand(tickets),
+ Fun = fun(Case) ->
+ C = init_per_testcase(Case, [{tc_timeout,
+ timer:minutes(10)}]),
+ io:format("Eval ~w~n", [Case]),
+ Result =
+ case (catch apply(?MODULE, Case, [C])) of
+ {'EXIT', Reason} ->
+ io:format("~n~p exited:~n ~p~n",
+ [Case, Reason]),
+ {error, {Case, Reason}};
+ Res ->
+ Res
+ end,
+ end_per_testcase(Case, C),
+ Result
+ end,
+ process_flag(trap_exit, Flag),
+ lists:map(Fun, Cases).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_codec_prev3a_test.erl b/lib/megaco/test/megaco_codec_prev3a_test.erl
index 696a72343c..d50e72aef1 100644
--- a/lib/megaco/test/megaco_codec_prev3a_test.erl
+++ b/lib/megaco/test/megaco_codec_prev3a_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -36,22 +36,16 @@
-export([t/0, t/1]).
--export([all/1,
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
- text/1,
-
- pretty/1,
pretty_test_msgs/1,
-
- compact/1,
+
compact_test_msgs/1,
-
- flex_pretty/1,
+
flex_pretty_init/1,
flex_pretty_finish/1,
flex_pretty_test_msgs/1,
-
- flex_compact/1,
+
flex_compact_init/1,
flex_compact_finish/1,
flex_compact_test_msgs/1,
@@ -64,32 +58,21 @@
flex_compact_dm_timers6/1,
flex_compact_dm_timers7/1,
flex_compact_dm_timers8/1,
-
- binary/1,
- bin/1,
bin_test_msgs/1,
-
- ber/1,
+
ber_test_msgs/1,
-
- ber_bin/1,
+
ber_bin_test_msgs/1,
-
- per/1,
+
per_test_msgs/1,
-
- per_bin/1,
+
per_bin_test_msgs/1,
-
- erl_dist/1,
- erl_dist_m/1,
+
erl_dist_m_test_msgs/1,
tickets/0,
- tickets/1,
-
- compact_tickets/1,
+
compact_otp4011_msg1/1,
compact_otp4011_msg2/1,
compact_otp4011_msg3/1,
@@ -132,8 +115,7 @@
compact_otp6017_msg01/1,
compact_otp6017_msg02/1,
compact_otp6017_msg03/1,
-
- flex_compact_tickets/1,
+
flex_compact_otp7431_msg01/1,
flex_compact_otp7431_msg02/1,
flex_compact_otp7431_msg03/1,
@@ -141,8 +123,7 @@
flex_compact_otp7431_msg05/1,
flex_compact_otp7431_msg06/1,
flex_compact_otp7431_msg07/1,
-
- pretty_tickets/1,
+
pretty_otp4632_msg1/1,
pretty_otp4632_msg2/1,
pretty_otp4632_msg3/1,
@@ -185,8 +166,7 @@
pretty_otp7671_msg04/1,
pretty_otp7671_msg05/1,
pretty_otp8114_msg01/1,
-
- flex_pretty_tickets/1,
+
flex_pretty_otp5042_msg1/1,
flex_pretty_otp5085_msg1/1,
flex_pretty_otp5085_msg2/1,
@@ -208,7 +188,7 @@
flex_pretty_otp7431_msg06/1,
flex_pretty_otp7431_msg07/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
-export([display_text_messages/0]).
@@ -263,30 +243,7 @@ expand([Case|Cases], Acc) ->
expand(Cases, [Case|Acc])
end.
-
-%% ----
-
-tickets() ->
- Flag = process_flag(trap_exit, true),
- Cases = expand(tickets),
- Fun = fun(Case) ->
- C = init_per_testcase(Case, [{tc_timeout,
- timer:minutes(10)}]),
- io:format("Eval ~w~n", [Case]),
- Result =
- case (catch apply(?MODULE, Case, [C])) of
- {'EXIT', Reason} ->
- io:format("~n~p exited:~n ~p~n",
- [Case, Reason]),
- {error, {Case, Reason}};
- Res ->
- Res
- end,
- fin_per_testcase(Case, C),
- Result
- end,
- process_flag(trap_exit, Flag),
- lists:map(Fun, Cases).
+
%% ----
@@ -306,268 +263,166 @@ init_per_testcase(Case, Config) ->
end,
megaco_test_lib:init_per_testcase(Case, C).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
erase(verbosity),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- text,
- binary,
- erl_dist,
- tickets
- ].
-
-text(suite) ->
- [
- pretty,
- flex_pretty,
- compact,
- flex_compact
- ].
-
-binary(suite) ->
- [
- bin,
- ber,
- ber_bin,
- per,
- per_bin
- ].
-
-erl_dist(suite) ->
- [
- erl_dist_m
- ].
-
-pretty(suite) ->
- [
- pretty_test_msgs
- ].
-
-
-compact(suite) ->
- [
- compact_test_msgs
- ].
-
-
-flex_pretty(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_cases(), flex_pretty_finish}}.
-
-flex_pretty_cases() ->
- [
- flex_pretty_test_msgs
- ].
-
-flex_compact(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_cases(), flex_compact_finish}}.
-
-flex_compact_cases() ->
- [
- flex_compact_test_msgs,
- flex_compact_dm_timers1,
- flex_compact_dm_timers2,
- flex_compact_dm_timers3,
- flex_compact_dm_timers4,
- flex_compact_dm_timers5,
- flex_compact_dm_timers6,
- flex_compact_dm_timers7,
- flex_compact_dm_timers8
- ].
-
-
-bin(suite) ->
- [
- bin_test_msgs
- ].
-
-
-ber(suite) ->
- [
- ber_test_msgs
- ].
-
-
-ber_bin(suite) ->
- [
- ber_bin_test_msgs
- ].
-
-
-per(suite) ->
- [
- per_test_msgs
- ].
-
+all() ->
+ [{group, text}, {group, binary}, {group, erl_dist},
+ {group, tickets}].
+
+groups() ->
+ [{text, [],
+ [{group, pretty}, {group, flex_pretty},
+ {group, compact}, {group, flex_compact}]},
+ {binary, [],
+ [{group, bin}, {group, ber}, {group, ber_bin},
+ {group, per}, {group, per_bin}]},
+ {erl_dist, [], [{group, erl_dist_m}]},
+ {pretty, [], [pretty_test_msgs]},
+ {compact, [], [compact_test_msgs]},
+ {flex_pretty, [], flex_pretty_cases()},
+ {flex_compact, [], flex_compact_cases()},
+ {bin, [], [bin_test_msgs]}, {ber, [], [ber_test_msgs]},
+ {ber_bin, [], [ber_bin_test_msgs]},
+ {per, [], [per_test_msgs]},
+ {per_bin, [], [per_bin_test_msgs]},
+ {erl_dist_m, [], [erl_dist_m_test_msgs]},
+ {tickets, [],
+ [{group, compact_tickets},
+ {group, flex_compact_tickets}, {group, pretty_tickets},
+ {group, flex_pretty_tickets}]},
+ {compact_tickets, [],
+ [compact_otp4011_msg1, compact_otp4011_msg2,
+ compact_otp4011_msg3, compact_otp4013_msg1,
+ compact_otp4085_msg1, compact_otp4085_msg2,
+ compact_otp4280_msg1, compact_otp4299_msg1,
+ compact_otp4299_msg2, compact_otp4359_msg1,
+ compact_otp4920_msg0, compact_otp4920_msg1,
+ compact_otp4920_msg2, compact_otp4920_msg3,
+ compact_otp4920_msg4, compact_otp4920_msg5,
+ compact_otp4920_msg6, compact_otp4920_msg7,
+ compact_otp4920_msg8, compact_otp4920_msg9,
+ compact_otp4920_msg10, compact_otp4920_msg11,
+ compact_otp4920_msg12, compact_otp4920_msg20,
+ compact_otp4920_msg21, compact_otp4920_msg22,
+ compact_otp4920_msg23, compact_otp4920_msg24,
+ compact_otp4920_msg25, compact_otp5186_msg01,
+ compact_otp5186_msg02, compact_otp5186_msg03,
+ compact_otp5186_msg04, compact_otp5186_msg05,
+ compact_otp5186_msg06, compact_otp5793_msg01,
+ compact_otp5993_msg01, compact_otp5993_msg02,
+ compact_otp5993_msg03, compact_otp6017_msg01,
+ compact_otp6017_msg02, compact_otp6017_msg03]},
+ {flex_compact_tickets, [],
+ flex_compact_tickets_cases()},
+ {pretty_tickets, [],
+ [pretty_otp4632_msg1, pretty_otp4632_msg2,
+ pretty_otp4632_msg3, pretty_otp4632_msg4,
+ pretty_otp4710_msg1, pretty_otp4710_msg2,
+ pretty_otp4945_msg1, pretty_otp4945_msg2,
+ pretty_otp4945_msg3, pretty_otp4945_msg4,
+ pretty_otp4945_msg5, pretty_otp4945_msg6,
+ pretty_otp4949_msg1, pretty_otp4949_msg2,
+ pretty_otp4949_msg3, pretty_otp5042_msg1,
+ pretty_otp5068_msg1, pretty_otp5085_msg1,
+ pretty_otp5085_msg2, pretty_otp5085_msg3,
+ pretty_otp5085_msg4, pretty_otp5085_msg5,
+ pretty_otp5085_msg6, pretty_otp5085_msg7,
+ pretty_otp5085_msg8, pretty_otp5600_msg1,
+ pretty_otp5600_msg2, pretty_otp5601_msg1,
+ pretty_otp5793_msg01, pretty_otp5882_msg01,
+ pretty_otp6490_msg01, pretty_otp6490_msg02,
+ pretty_otp6490_msg03, pretty_otp6490_msg04,
+ pretty_otp6490_msg05, pretty_otp6490_msg06,
+ pretty_otp7671_msg01, pretty_otp7671_msg02,
+ pretty_otp7671_msg03, pretty_otp7671_msg04,
+ pretty_otp7671_msg05, pretty_otp8114_msg01]},
+ {flex_pretty_tickets, [], flex_pretty_tickets_cases()}].
+
+init_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_init(Config);
+init_per_group(flex_compact_tickets, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_compact, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_pretty, Config) ->
+ flex_pretty_init(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(flex_compact_tickets, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_compact, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_pretty, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
+flex_pretty_cases() ->
+ [flex_pretty_test_msgs].
+
+
+flex_compact_cases() ->
+ [flex_compact_test_msgs, flex_compact_dm_timers1,
+ flex_compact_dm_timers2, flex_compact_dm_timers3,
+ flex_compact_dm_timers4, flex_compact_dm_timers5,
+ flex_compact_dm_timers6, flex_compact_dm_timers7,
+ flex_compact_dm_timers8].
%% Support for per_bin was added to ASN.1 as of version
%% 1.3.2 (R8). And later merged into 1.3.1.3 (R7). These
%% releases are identical (as far as I know).
%%
-per_bin(suite) ->
- [
- per_bin_test_msgs
- ].
-
-
-erl_dist_m(suite) ->
- [
- erl_dist_m_test_msgs
- ].
-
-tickets(suite) ->
- [
- compact_tickets,
- flex_compact_tickets,
- pretty_tickets,
- flex_pretty_tickets
- ].
-
-compact_tickets(suite) ->
- [
- compact_otp4011_msg1,
- compact_otp4011_msg2,
- compact_otp4011_msg3,
- compact_otp4013_msg1,
- compact_otp4085_msg1,
- compact_otp4085_msg2,
- compact_otp4280_msg1,
- compact_otp4299_msg1,
- compact_otp4299_msg2,
- compact_otp4359_msg1,
- compact_otp4920_msg0,
- compact_otp4920_msg1,
- compact_otp4920_msg2,
- compact_otp4920_msg3,
- compact_otp4920_msg4,
- compact_otp4920_msg5,
- compact_otp4920_msg6,
- compact_otp4920_msg7,
- compact_otp4920_msg8,
- compact_otp4920_msg9,
- compact_otp4920_msg10,
- compact_otp4920_msg11,
- compact_otp4920_msg12,
- compact_otp4920_msg20,
- compact_otp4920_msg21,
- compact_otp4920_msg22,
- compact_otp4920_msg23,
- compact_otp4920_msg24,
- compact_otp4920_msg25,
- compact_otp5186_msg01,
- compact_otp5186_msg02,
- compact_otp5186_msg03,
- compact_otp5186_msg04,
- compact_otp5186_msg05,
- compact_otp5186_msg06,
- compact_otp5793_msg01,
- compact_otp5993_msg01,
- compact_otp5993_msg02,
- compact_otp5993_msg03,
- compact_otp6017_msg01,
- compact_otp6017_msg02,
- compact_otp6017_msg03
- ].
-
-flex_compact_tickets(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_tickets_cases(),
- flex_compact_finish}}.
+flex_compact_tickets_cases() ->
+ [flex_compact_otp7431_msg01, flex_compact_otp7431_msg02,
+ flex_compact_otp7431_msg03, flex_compact_otp7431_msg04,
+ flex_compact_otp7431_msg05, flex_compact_otp7431_msg06,
+ flex_compact_otp7431_msg07].
+
+flex_pretty_tickets_cases() ->
+ [flex_pretty_otp5042_msg1, flex_pretty_otp5085_msg1,
+ flex_pretty_otp5085_msg2, flex_pretty_otp5085_msg3,
+ flex_pretty_otp5085_msg4, flex_pretty_otp5085_msg5,
+ flex_pretty_otp5085_msg6, flex_pretty_otp5085_msg7,
+ flex_pretty_otp5085_msg8, flex_pretty_otp5600_msg1,
+ flex_pretty_otp5600_msg2, flex_pretty_otp5601_msg1,
+ flex_pretty_otp5793_msg01, flex_pretty_otp7431_msg01,
+ flex_pretty_otp7431_msg02, flex_pretty_otp7431_msg03,
+ flex_pretty_otp7431_msg04, flex_pretty_otp7431_msg05,
+ flex_pretty_otp7431_msg06, flex_pretty_otp7431_msg07].
-flex_compact_tickets_cases() ->
- [
- flex_compact_otp7431_msg01,
- flex_compact_otp7431_msg02,
- flex_compact_otp7431_msg03,
- flex_compact_otp7431_msg04,
- flex_compact_otp7431_msg05,
- flex_compact_otp7431_msg06,
- flex_compact_otp7431_msg07
- ].
-
-
-pretty_tickets(suite) ->
- [
- pretty_otp4632_msg1,
- pretty_otp4632_msg2,
- pretty_otp4632_msg3,
- pretty_otp4632_msg4,
- pretty_otp4710_msg1,
- pretty_otp4710_msg2,
- pretty_otp4945_msg1,
- pretty_otp4945_msg2,
- pretty_otp4945_msg3,
- pretty_otp4945_msg4,
- pretty_otp4945_msg5,
- pretty_otp4945_msg6,
- pretty_otp4949_msg1,
- pretty_otp4949_msg2,
- pretty_otp4949_msg3,
- pretty_otp5042_msg1,
- pretty_otp5068_msg1,
- pretty_otp5085_msg1,
- pretty_otp5085_msg2,
- pretty_otp5085_msg3,
- pretty_otp5085_msg4,
- pretty_otp5085_msg5,
- pretty_otp5085_msg6,
- pretty_otp5085_msg7,
- pretty_otp5085_msg8,
- pretty_otp5600_msg1,
- pretty_otp5600_msg2,
- pretty_otp5601_msg1,
- pretty_otp5793_msg01,
- pretty_otp5882_msg01,
- pretty_otp6490_msg01,
- pretty_otp6490_msg02,
- pretty_otp6490_msg03,
- pretty_otp6490_msg04,
- pretty_otp6490_msg05,
- pretty_otp6490_msg06,
- pretty_otp7671_msg01,
- pretty_otp7671_msg02,
- pretty_otp7671_msg03,
- pretty_otp7671_msg04,
- pretty_otp7671_msg05,
- pretty_otp8114_msg01
- ].
+%% ----
-flex_pretty_tickets(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_tickets_cases(),
- flex_pretty_finish}}.
-
-flex_pretty_tickets_cases() ->
- [
- flex_pretty_otp5042_msg1,
- flex_pretty_otp5085_msg1,
- flex_pretty_otp5085_msg2,
- flex_pretty_otp5085_msg3,
- flex_pretty_otp5085_msg4,
- flex_pretty_otp5085_msg5,
- flex_pretty_otp5085_msg6,
- flex_pretty_otp5085_msg7,
- flex_pretty_otp5085_msg8,
- flex_pretty_otp5600_msg1,
- flex_pretty_otp5600_msg2,
- flex_pretty_otp5601_msg1,
- flex_pretty_otp5793_msg01,
- flex_pretty_otp7431_msg01,
- flex_pretty_otp7431_msg02,
- flex_pretty_otp7431_msg03,
- flex_pretty_otp7431_msg04,
- flex_pretty_otp7431_msg05,
- flex_pretty_otp7431_msg06,
- flex_pretty_otp7431_msg07
- ].
+tickets() ->
+ Flag = process_flag(trap_exit, true),
+ Cases = expand(tickets),
+ Fun = fun(Case) ->
+ C = init_per_testcase(Case, [{tc_timeout,
+ timer:minutes(10)}]),
+ io:format("Eval ~w~n", [Case]),
+ Result =
+ case (catch apply(?MODULE, Case, [C])) of
+ {'EXIT', Reason} ->
+ io:format("~n~p exited:~n ~p~n",
+ [Case, Reason]),
+ {error, {Case, Reason}};
+ Res ->
+ Res
+ end,
+ end_per_testcase(Case, C),
+ Result
+ end,
+ process_flag(trap_exit, Flag),
+ lists:map(Fun, Cases).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_codec_prev3b_test.erl b/lib/megaco/test/megaco_codec_prev3b_test.erl
index b5fe4d2038..eaab8f37c1 100644
--- a/lib/megaco/test/megaco_codec_prev3b_test.erl
+++ b/lib/megaco/test/megaco_codec_prev3b_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -36,22 +36,16 @@
-export([t/0, t/1]).
--export([all/1,
-
- text/1,
-
- pretty/1,
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
+
pretty_test_msgs/1,
-
- compact/1,
+
compact_test_msgs/1,
- flex_pretty/1,
flex_pretty_init/1,
flex_pretty_finish/1,
flex_pretty_test_msgs/1,
-
- flex_compact/1,
+
flex_compact_init/1,
flex_compact_finish/1,
flex_compact_test_msgs/1,
@@ -64,32 +58,21 @@
flex_compact_dm_timers6/1,
flex_compact_dm_timers7/1,
flex_compact_dm_timers8/1,
-
- binary/1,
- bin/1,
bin_test_msgs/1,
-
- ber/1,
+
ber_test_msgs/1,
-
- ber_bin/1,
+
ber_bin_test_msgs/1,
-
- per/1,
+
per_test_msgs/1,
-
- per_bin/1,
+
per_bin_test_msgs/1,
-
- erl_dist/1,
- erl_dist_m/1,
+
erl_dist_m_test_msgs/1,
tickets/0,
- tickets/1,
-
- compact_tickets/1,
+
compact_otp4011_msg1/1,
compact_otp4011_msg2/1,
compact_otp4011_msg3/1,
@@ -133,8 +116,7 @@
compact_otp6017_msg01/1,
compact_otp6017_msg02/1,
compact_otp6017_msg03/1,
-
- flex_compact_tickets/1,
+
flex_compact_otp7431_msg01/1,
flex_compact_otp7431_msg02/1,
flex_compact_otp7431_msg03/1,
@@ -142,8 +124,7 @@
flex_compact_otp7431_msg05/1,
flex_compact_otp7431_msg06/1,
flex_compact_otp7431_msg07/1,
-
- pretty_tickets/1,
+
pretty_otp4632_msg1/1,
pretty_otp4632_msg2/1,
pretty_otp4632_msg3/1,
@@ -190,8 +171,7 @@
pretty_otp7671_msg04/1,
pretty_otp7671_msg05/1,
pretty_otp8114_msg01/1,
-
- flex_pretty_tickets/1,
+
flex_pretty_otp5042_msg1/1,
flex_pretty_otp5085_msg1/1,
flex_pretty_otp5085_msg2/1,
@@ -217,7 +197,7 @@
flex_pretty_otp7431_msg06/1,
flex_pretty_otp7431_msg07/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
-export([display_text_messages/0, generate_text_messages/0]).
@@ -281,31 +261,6 @@ expand([Case|Cases], Acc) ->
expand(Cases, [Case|Acc])
end.
-
-%% ----
-
-tickets() ->
- Flag = process_flag(trap_exit, true),
- Cases = expand(tickets),
- Fun = fun(Case) ->
- C = init_per_testcase(Case, [{tc_timeout,
- timer:minutes(10)}]),
- io:format("Eval ~w~n", [Case]),
- Result =
- case (catch apply(?MODULE, Case, [C])) of
- {'EXIT', Reason} ->
- io:format("~n~p exited:~n ~p~n",
- [Case, Reason]),
- {error, {Case, Reason}};
- Res ->
- Res
- end,
- fin_per_testcase(Case, C),
- Result
- end,
- process_flag(trap_exit, Flag),
- lists:map(Fun, Cases).
-
%% ----
@@ -324,276 +279,170 @@ init_per_testcase(Case, Config) ->
end,
megaco_test_lib:init_per_testcase(Case, C).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
erase(verbosity),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- text,
- binary,
- erl_dist,
- tickets
- ].
-
-text(suite) ->
- [
- pretty,
- flex_pretty,
- compact,
- flex_compact
- ].
-
-binary(suite) ->
- [
- bin,
- ber,
- ber_bin,
- per,
- per_bin
- ].
-
-erl_dist(suite) ->
- [
- erl_dist_m
- ].
-
-pretty(suite) ->
- [
- pretty_test_msgs
- ].
-
-
-compact(suite) ->
- [
- compact_test_msgs
- ].
-
-
-flex_pretty(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_cases(), flex_pretty_finish}}.
-
-flex_pretty_cases() ->
- [
- flex_pretty_test_msgs
- ].
-
-flex_compact(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_cases(), flex_compact_finish}}.
-
-flex_compact_cases() ->
- [
- flex_compact_test_msgs,
- flex_compact_dm_timers1,
- flex_compact_dm_timers2,
- flex_compact_dm_timers3,
- flex_compact_dm_timers4,
- flex_compact_dm_timers5,
- flex_compact_dm_timers6,
- flex_compact_dm_timers7,
- flex_compact_dm_timers8
- ].
-
-
-bin(suite) ->
- [
- bin_test_msgs
- ].
-
-
-ber(suite) ->
- [
- ber_test_msgs
- ].
-
-
-ber_bin(suite) ->
- [
- ber_bin_test_msgs
- ].
-
-
-per(suite) ->
- [
- per_test_msgs
- ].
-
+all() ->
+ [{group, text}, {group, binary}, {group, erl_dist},
+ {group, tickets}].
+
+groups() ->
+ [{text, [],
+ [{group, pretty}, {group, flex_pretty},
+ {group, compact}, {group, flex_compact}]},
+ {binary, [],
+ [{group, bin}, {group, ber}, {group, ber_bin},
+ {group, per}, {group, per_bin}]},
+ {erl_dist, [], [{group, erl_dist_m}]},
+ {pretty, [], [pretty_test_msgs]},
+ {compact, [], [compact_test_msgs]},
+ {flex_pretty, [], flex_pretty_cases()},
+ {flex_compact, [], flex_compact_cases()},
+ {bin, [], [bin_test_msgs]}, {ber, [], [ber_test_msgs]},
+ {ber_bin, [], [ber_bin_test_msgs]},
+ {per, [], [per_test_msgs]},
+ {per_bin, [], [per_bin_test_msgs]},
+ {erl_dist_m, [], [erl_dist_m_test_msgs]},
+ {tickets, [],
+ [{group, compact_tickets},
+ {group, flex_compact_tickets}, {group, pretty_tickets},
+ {group, flex_pretty_tickets}]},
+ {compact_tickets, [],
+ [compact_otp4011_msg1, compact_otp4011_msg2,
+ compact_otp4011_msg3, compact_otp4013_msg1,
+ compact_otp4085_msg1, compact_otp4085_msg2,
+ compact_otp4280_msg1, compact_otp4299_msg1,
+ compact_otp4299_msg2, compact_otp4359_msg1,
+ compact_otp4920_msg0, compact_otp4920_msg1,
+ compact_otp4920_msg2, compact_otp4920_msg3,
+ compact_otp4920_msg4, compact_otp4920_msg5,
+ compact_otp4920_msg6, compact_otp4920_msg7,
+ compact_otp4920_msg8, compact_otp4920_msg9,
+ compact_otp4920_msg10, compact_otp4920_msg11,
+ compact_otp4920_msg12, compact_otp4920_msg20,
+ compact_otp4920_msg21, compact_otp4920_msg22,
+ compact_otp4920_msg23, compact_otp4920_msg24,
+ compact_otp4920_msg25, compact_otp5186_msg01,
+ compact_otp5186_msg02, compact_otp5186_msg03,
+ compact_otp5186_msg04, compact_otp5186_msg05,
+ compact_otp5186_msg06, compact_otp5793_msg01,
+ compact_otp5836_msg01, compact_otp5993_msg01,
+ compact_otp5993_msg02, compact_otp5993_msg03,
+ compact_otp6017_msg01, compact_otp6017_msg02,
+ compact_otp6017_msg03]},
+ {flex_compact_tickets, [],
+ flex_compact_tickets_cases()},
+ {pretty_tickets, [],
+ [pretty_otp4632_msg1, pretty_otp4632_msg2,
+ pretty_otp4632_msg3, pretty_otp4632_msg4,
+ pretty_otp4710_msg1, pretty_otp4710_msg2,
+ pretty_otp4945_msg1, pretty_otp4945_msg2,
+ pretty_otp4945_msg3, pretty_otp4945_msg4,
+ pretty_otp4945_msg5, pretty_otp4945_msg6,
+ pretty_otp4949_msg1, pretty_otp4949_msg2,
+ pretty_otp4949_msg3, pretty_otp5042_msg1,
+ pretty_otp5068_msg1, pretty_otp5085_msg1,
+ pretty_otp5085_msg2, pretty_otp5085_msg3,
+ pretty_otp5085_msg4, pretty_otp5085_msg5,
+ pretty_otp5085_msg6, pretty_otp5085_msg7,
+ pretty_otp5085_msg8, pretty_otp5600_msg1,
+ pretty_otp5600_msg2, pretty_otp5601_msg1,
+ pretty_otp5793_msg01, pretty_otp5803_msg01,
+ pretty_otp5803_msg02, pretty_otp5805_msg01,
+ pretty_otp5836_msg01, pretty_otp5882_msg01,
+ pretty_otp6490_msg01, pretty_otp6490_msg02,
+ pretty_otp6490_msg03, pretty_otp6490_msg04,
+ pretty_otp6490_msg05, pretty_otp6490_msg06,
+ pretty_otp7671_msg01, pretty_otp7671_msg02,
+ pretty_otp7671_msg03, pretty_otp7671_msg04,
+ pretty_otp7671_msg05, pretty_otp8114_msg01]},
+ {flex_pretty_tickets, [], flex_pretty_tickets_cases()}].
+
+init_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_init(Config);
+init_per_group(flex_compact_tickets, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_compact, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_pretty, Config) ->
+ flex_pretty_init(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(flex_compact_tickets, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_compact, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_pretty, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
+flex_pretty_cases() ->
+ [flex_pretty_test_msgs].
+
+flex_compact_cases() ->
+ [flex_compact_test_msgs, flex_compact_dm_timers1,
+ flex_compact_dm_timers2, flex_compact_dm_timers3,
+ flex_compact_dm_timers4, flex_compact_dm_timers5,
+ flex_compact_dm_timers6, flex_compact_dm_timers7,
+ flex_compact_dm_timers8].
%% Support for per_bin was added to ASN.1 as of version
%% 1.3.2 (R8). And later merged into 1.3.1.3 (R7). These
%% releases are identical (as far as I know).
%%
-per_bin(suite) ->
- [
- per_bin_test_msgs
- ].
-
-
-erl_dist_m(suite) ->
- [
- erl_dist_m_test_msgs
- ].
-
-tickets(suite) ->
- [
- compact_tickets,
- flex_compact_tickets,
- pretty_tickets,
- flex_pretty_tickets
- ].
+flex_compact_tickets_cases() ->
+ [flex_compact_otp7431_msg01, flex_compact_otp7431_msg02,
+ flex_compact_otp7431_msg03, flex_compact_otp7431_msg04,
+ flex_compact_otp7431_msg05, flex_compact_otp7431_msg06,
+ flex_compact_otp7431_msg07].
+
+flex_pretty_tickets_cases() ->
+ [flex_pretty_otp5042_msg1, flex_pretty_otp5085_msg1,
+ flex_pretty_otp5085_msg2, flex_pretty_otp5085_msg3,
+ flex_pretty_otp5085_msg4, flex_pretty_otp5085_msg5,
+ flex_pretty_otp5085_msg6, flex_pretty_otp5085_msg7,
+ flex_pretty_otp5085_msg8, flex_pretty_otp5600_msg1,
+ flex_pretty_otp5600_msg2, flex_pretty_otp5601_msg1,
+ flex_pretty_otp5793_msg01, flex_pretty_otp5803_msg01,
+ flex_pretty_otp5803_msg02, flex_pretty_otp5805_msg01,
+ flex_pretty_otp5836_msg01, flex_pretty_otp7431_msg01,
+ flex_pretty_otp7431_msg02, flex_pretty_otp7431_msg03,
+ flex_pretty_otp7431_msg04, flex_pretty_otp7431_msg05,
+ flex_pretty_otp7431_msg06, flex_pretty_otp7431_msg07].
-compact_tickets(suite) ->
- [
- compact_otp4011_msg1,
- compact_otp4011_msg2,
- compact_otp4011_msg3,
- compact_otp4013_msg1,
- compact_otp4085_msg1,
- compact_otp4085_msg2,
- compact_otp4280_msg1,
- compact_otp4299_msg1,
- compact_otp4299_msg2,
- compact_otp4359_msg1,
- compact_otp4920_msg0,
- compact_otp4920_msg1,
- compact_otp4920_msg2,
- compact_otp4920_msg3,
- compact_otp4920_msg4,
- compact_otp4920_msg5,
- compact_otp4920_msg6,
- compact_otp4920_msg7,
- compact_otp4920_msg8,
- compact_otp4920_msg9,
- compact_otp4920_msg10,
- compact_otp4920_msg11,
- compact_otp4920_msg12,
- compact_otp4920_msg20,
- compact_otp4920_msg21,
- compact_otp4920_msg22,
- compact_otp4920_msg23,
- compact_otp4920_msg24,
- compact_otp4920_msg25,
- compact_otp5186_msg01,
- compact_otp5186_msg02,
- compact_otp5186_msg03,
- compact_otp5186_msg04,
- compact_otp5186_msg05,
- compact_otp5186_msg06,
- compact_otp5793_msg01,
- compact_otp5836_msg01,
- compact_otp5993_msg01,
- compact_otp5993_msg02,
- compact_otp5993_msg03,
- compact_otp6017_msg01,
- compact_otp6017_msg02,
- compact_otp6017_msg03
- ].
-
-flex_compact_tickets(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_tickets_cases(),
- flex_compact_finish}}.
-
-flex_compact_tickets_cases() ->
- [
- flex_compact_otp7431_msg01,
- flex_compact_otp7431_msg02,
- flex_compact_otp7431_msg03,
- flex_compact_otp7431_msg04,
- flex_compact_otp7431_msg05,
- flex_compact_otp7431_msg06,
- flex_compact_otp7431_msg07
- ].
-
-pretty_tickets(suite) ->
- [
- pretty_otp4632_msg1,
- pretty_otp4632_msg2,
- pretty_otp4632_msg3,
- pretty_otp4632_msg4,
- pretty_otp4710_msg1,
- pretty_otp4710_msg2,
- pretty_otp4945_msg1,
- pretty_otp4945_msg2,
- pretty_otp4945_msg3,
- pretty_otp4945_msg4,
- pretty_otp4945_msg5,
- pretty_otp4945_msg6,
- pretty_otp4949_msg1,
- pretty_otp4949_msg2,
- pretty_otp4949_msg3,
- pretty_otp5042_msg1,
- pretty_otp5068_msg1,
- pretty_otp5085_msg1,
- pretty_otp5085_msg2,
- pretty_otp5085_msg3,
- pretty_otp5085_msg4,
- pretty_otp5085_msg5,
- pretty_otp5085_msg6,
- pretty_otp5085_msg7,
- pretty_otp5085_msg8,
- pretty_otp5600_msg1,
- pretty_otp5600_msg2,
- pretty_otp5601_msg1,
- pretty_otp5793_msg01,
- pretty_otp5803_msg01,
- pretty_otp5803_msg02,
- pretty_otp5805_msg01,
- pretty_otp5836_msg01,
- pretty_otp5882_msg01,
- pretty_otp6490_msg01,
- pretty_otp6490_msg02,
- pretty_otp6490_msg03,
- pretty_otp6490_msg04,
- pretty_otp6490_msg05,
- pretty_otp6490_msg06,
- pretty_otp7671_msg01,
- pretty_otp7671_msg02,
- pretty_otp7671_msg03,
- pretty_otp7671_msg04,
- pretty_otp7671_msg05,
- pretty_otp8114_msg01
- ].
+%% ----
-flex_pretty_tickets(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_tickets_cases(),
- flex_pretty_finish}}.
-
-flex_pretty_tickets_cases() ->
- [
- flex_pretty_otp5042_msg1,
- flex_pretty_otp5085_msg1,
- flex_pretty_otp5085_msg2,
- flex_pretty_otp5085_msg3,
- flex_pretty_otp5085_msg4,
- flex_pretty_otp5085_msg5,
- flex_pretty_otp5085_msg6,
- flex_pretty_otp5085_msg7,
- flex_pretty_otp5085_msg8,
- flex_pretty_otp5600_msg1,
- flex_pretty_otp5600_msg2,
- flex_pretty_otp5601_msg1,
- flex_pretty_otp5793_msg01,
- flex_pretty_otp5803_msg01,
- flex_pretty_otp5803_msg02,
- flex_pretty_otp5805_msg01,
- flex_pretty_otp5836_msg01,
- flex_pretty_otp7431_msg01,
- flex_pretty_otp7431_msg02,
- flex_pretty_otp7431_msg03,
- flex_pretty_otp7431_msg04,
- flex_pretty_otp7431_msg05,
- flex_pretty_otp7431_msg06,
- flex_pretty_otp7431_msg07
- ].
+tickets() ->
+ Flag = process_flag(trap_exit, true),
+ Cases = expand(tickets),
+ Fun = fun(Case) ->
+ C = init_per_testcase(Case, [{tc_timeout,
+ timer:minutes(10)}]),
+ io:format("Eval ~w~n", [Case]),
+ Result =
+ case (catch apply(?MODULE, Case, [C])) of
+ {'EXIT', Reason} ->
+ io:format("~n~p exited:~n ~p~n",
+ [Case, Reason]),
+ {error, {Case, Reason}};
+ Res ->
+ Res
+ end,
+ end_per_testcase(Case, C),
+ Result
+ end,
+ process_flag(trap_exit, Flag),
+ lists:map(Fun, Cases).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_codec_prev3c_test.erl b/lib/megaco/test/megaco_codec_prev3c_test.erl
index 813d0cf57d..7f9c0fe4e7 100644
--- a/lib/megaco/test/megaco_codec_prev3c_test.erl
+++ b/lib/megaco/test/megaco_codec_prev3c_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -37,22 +37,17 @@
-export([t/0, t/1]).
--export([all/1,
-
- text/1,
-
- pretty/1,
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
+
pretty_test_msgs/1,
-
- compact/1,
+
compact_test_msgs/1,
-
- flex_pretty/1,
+
flex_pretty_init/1,
flex_pretty_finish/1,
flex_pretty_test_msgs/1,
- flex_compact/1,
+
flex_compact_init/1,
flex_compact_finish/1,
flex_compact_test_msgs/1,
@@ -65,32 +60,21 @@
flex_compact_dm_timers6/1,
flex_compact_dm_timers7/1,
flex_compact_dm_timers8/1,
-
- binary/1,
- bin/1,
bin_test_msgs/1,
-
- ber/1,
+
ber_test_msgs/1,
-
- ber_bin/1,
+
ber_bin_test_msgs/1,
-
- per/1,
+
per_test_msgs/1,
-
- per_bin/1,
+
per_bin_test_msgs/1,
-
- erl_dist/1,
- erl_dist_m/1,
+
erl_dist_m_test_msgs/1,
tickets/0,
- tickets/1,
-
- compact_tickets/1,
+
compact_otp4011_msg1/1,
compact_otp4011_msg2/1,
compact_otp4011_msg3/1,
@@ -133,8 +117,7 @@
compact_otp6017_msg01/1,
compact_otp6017_msg02/1,
compact_otp6017_msg03/1,
-
- flex_compact_tickets/1,
+
flex_compact_otp4299_msg1/1,
flex_compact_otp7431_msg01/1,
flex_compact_otp7431_msg02/1,
@@ -143,8 +126,7 @@
flex_compact_otp7431_msg05/1,
flex_compact_otp7431_msg06/1,
flex_compact_otp7431_msg07/1,
-
- pretty_tickets/1,
+
pretty_otp4632_msg1/1,
pretty_otp4632_msg2/1,
pretty_otp4632_msg3/1,
@@ -191,8 +173,7 @@
pretty_otp7671_msg04/1,
pretty_otp7671_msg05/1,
pretty_otp8114_msg01/1,
-
- flex_pretty_tickets/1,
+
flex_pretty_otp5042_msg1/1,
flex_pretty_otp5085_msg1/1,
flex_pretty_otp5085_msg2/1,
@@ -218,7 +199,7 @@
flex_pretty_otp7431_msg06/1,
flex_pretty_otp7431_msg07/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
-export([display_text_messages/0, generate_text_messages/0]).
@@ -286,32 +267,6 @@ expand([Case|Cases], Acc) ->
expand(Cases, [Case|Acc])
end.
-
-%% ----
-
-tickets() ->
- Flag = process_flag(trap_exit, true),
- Cases = expand(tickets),
- Fun = fun(Case) ->
- C = init_per_testcase(Case, [{tc_timeout,
- timer:minutes(10)}]),
- io:format("Eval ~w~n", [Case]),
- Result =
- case (catch apply(?MODULE, Case, [C])) of
- {'EXIT', Reason} ->
- io:format("~n~p exited:~n ~p~n",
- [Case, Reason]),
- {error, {Case, Reason}};
- Res ->
- Res
- end,
- fin_per_testcase(Case, C),
- Result
- end,
- process_flag(trap_exit, Flag),
- lists:map(Fun, Cases).
-
-
%% ----
t() -> megaco_test_lib:t(?MODULE).
@@ -329,279 +284,169 @@ init_per_testcase(Case, Config) ->
end,
megaco_test_lib:init_per_testcase(Case, C).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
erase(verbosity),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- text,
- binary,
- erl_dist,
- tickets
- ].
-
-text(suite) ->
- [
- pretty,
- flex_pretty,
- compact,
- flex_compact
- ].
-
-binary(suite) ->
- [
- bin,
- ber,
- ber_bin,
- per,
- per_bin
- ].
-
-erl_dist(suite) ->
- [
- erl_dist_m
- ].
-
-pretty(suite) ->
- [
- pretty_test_msgs
- ].
-
-
-compact(suite) ->
- [
- compact_test_msgs
- ].
-
-
-flex_pretty(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_cases(), flex_pretty_finish}}.
-
-flex_pretty_cases() ->
- [
- flex_pretty_test_msgs
- ].
-
-flex_compact(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_cases(), flex_compact_finish}}.
-
-flex_compact_cases() ->
- [
- flex_compact_test_msgs,
- flex_compact_dm_timers1,
- flex_compact_dm_timers2,
- flex_compact_dm_timers3,
- flex_compact_dm_timers4,
- flex_compact_dm_timers5,
- flex_compact_dm_timers6,
- flex_compact_dm_timers7,
- flex_compact_dm_timers8
- ].
-
-
-bin(suite) ->
- [
- bin_test_msgs
- ].
-
-
-ber(suite) ->
- [
- ber_test_msgs
- ].
-
-
-ber_bin(suite) ->
- [
- ber_bin_test_msgs
- ].
-
-
-per(suite) ->
- [
- per_test_msgs
- ].
-
+all() ->
+ [{group, text}, {group, binary}, {group, erl_dist},
+ {group, tickets}].
+
+groups() ->
+ [{text, [],
+ [{group, pretty}, {group, flex_pretty},
+ {group, compact}, {group, flex_compact}]},
+ {binary, [],
+ [{group, bin}, {group, ber}, {group, ber_bin},
+ {group, per}, {group, per_bin}]},
+ {erl_dist, [], [{group, erl_dist_m}]},
+ {pretty, [], [pretty_test_msgs]},
+ {compact, [], [compact_test_msgs]},
+ {flex_pretty, [], flex_pretty_cases()},
+ {flex_compact, [], flex_compact_cases()},
+ {bin, [], [bin_test_msgs]}, {ber, [], [ber_test_msgs]},
+ {ber_bin, [], [ber_bin_test_msgs]},
+ {per, [], [per_test_msgs]},
+ {per_bin, [], [per_bin_test_msgs]},
+ {erl_dist_m, [], [erl_dist_m_test_msgs]},
+ {tickets, [],
+ [{group, compact_tickets},
+ {group, flex_compact_tickets}, {group, pretty_tickets},
+ {group, flex_pretty_tickets}]},
+ {compact_tickets, [],
+ [compact_otp4011_msg1, compact_otp4011_msg2,
+ compact_otp4011_msg3, compact_otp4013_msg1,
+ compact_otp4085_msg1, compact_otp4085_msg2,
+ compact_otp4280_msg1, compact_otp4299_msg1,
+ compact_otp4359_msg1, compact_otp4920_msg0,
+ compact_otp4920_msg1, compact_otp4920_msg2,
+ compact_otp4920_msg3, compact_otp4920_msg4,
+ compact_otp4920_msg5, compact_otp4920_msg6,
+ compact_otp4920_msg7, compact_otp4920_msg8,
+ compact_otp4920_msg9, compact_otp4920_msg10,
+ compact_otp4920_msg11, compact_otp4920_msg12,
+ compact_otp4920_msg20, compact_otp4920_msg21,
+ compact_otp4920_msg22, compact_otp4920_msg23,
+ compact_otp4920_msg24, compact_otp4920_msg25,
+ compact_otp5186_msg01, compact_otp5186_msg02,
+ compact_otp5186_msg03, compact_otp5186_msg04,
+ compact_otp5186_msg05, compact_otp5186_msg06,
+ compact_otp5793_msg01, compact_otp5836_msg01,
+ compact_otp5993_msg01, compact_otp5993_msg02,
+ compact_otp5993_msg03, compact_otp6017_msg01,
+ compact_otp6017_msg02, compact_otp6017_msg03]},
+ {flex_compact_tickets, [],
+ flex_compact_tickets_cases()},
+ {pretty_tickets, [],
+ [pretty_otp4632_msg1, pretty_otp4632_msg2,
+ pretty_otp4632_msg3, pretty_otp4632_msg4,
+ pretty_otp4710_msg1, pretty_otp4710_msg2,
+ pretty_otp4945_msg1, pretty_otp4945_msg2,
+ pretty_otp4945_msg3, pretty_otp4945_msg4,
+ pretty_otp4945_msg5, pretty_otp4945_msg6,
+ pretty_otp4949_msg1, pretty_otp4949_msg2,
+ pretty_otp4949_msg3, pretty_otp5042_msg1,
+ pretty_otp5068_msg1, pretty_otp5085_msg1,
+ pretty_otp5085_msg2, pretty_otp5085_msg3,
+ pretty_otp5085_msg4, pretty_otp5085_msg5,
+ pretty_otp5085_msg6, pretty_otp5085_msg7,
+ pretty_otp5085_msg8, pretty_otp5600_msg1,
+ pretty_otp5600_msg2, pretty_otp5601_msg1,
+ pretty_otp5793_msg01, pretty_otp5803_msg01,
+ pretty_otp5803_msg02, pretty_otp5805_msg01,
+ pretty_otp5836_msg01, pretty_otp5882_msg01,
+ pretty_otp6490_msg01, pretty_otp6490_msg02,
+ pretty_otp6490_msg03, pretty_otp6490_msg04,
+ pretty_otp6490_msg05, pretty_otp6490_msg06,
+ pretty_otp7671_msg01, pretty_otp7671_msg02,
+ pretty_otp7671_msg03, pretty_otp7671_msg04,
+ pretty_otp7671_msg05, pretty_otp8114_msg01]},
+ {flex_pretty_tickets, [], flex_pretty_tickets_cases()}].
+
+init_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_init(Config);
+init_per_group(flex_compact_tickets, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_compact, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_pretty, Config) ->
+ flex_pretty_init(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(flex_compact_tickets, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_compact, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_pretty, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
+flex_pretty_cases() ->
+ [flex_pretty_test_msgs].
+
+flex_compact_cases() ->
+ [flex_compact_test_msgs, flex_compact_dm_timers1,
+ flex_compact_dm_timers2, flex_compact_dm_timers3,
+ flex_compact_dm_timers4, flex_compact_dm_timers5,
+ flex_compact_dm_timers6, flex_compact_dm_timers7,
+ flex_compact_dm_timers8].
%% Support for per_bin was added to ASN.1 as of version
%% 1.3.2 (R8). And later merged into 1.3.1.3 (R7). These
%% releases are identical (as far as I know).
%%
-per_bin(suite) ->
- [
- per_bin_test_msgs
- ].
-
-
-erl_dist_m(suite) ->
- [
- erl_dist_m_test_msgs
- ].
-
-tickets(suite) ->
- [
- compact_tickets,
- flex_compact_tickets,
- pretty_tickets,
- flex_pretty_tickets
- ].
-
-
-compact_tickets(suite) ->
- [
- compact_otp4011_msg1,
- compact_otp4011_msg2,
- compact_otp4011_msg3,
- compact_otp4013_msg1,
- compact_otp4085_msg1,
- compact_otp4085_msg2,
- compact_otp4280_msg1,
- compact_otp4299_msg1,
- compact_otp4359_msg1,
- compact_otp4920_msg0,
- compact_otp4920_msg1,
- compact_otp4920_msg2,
- compact_otp4920_msg3,
- compact_otp4920_msg4,
- compact_otp4920_msg5,
- compact_otp4920_msg6,
- compact_otp4920_msg7,
- compact_otp4920_msg8,
- compact_otp4920_msg9,
- compact_otp4920_msg10,
- compact_otp4920_msg11,
- compact_otp4920_msg12,
- compact_otp4920_msg20,
- compact_otp4920_msg21,
- compact_otp4920_msg22,
- compact_otp4920_msg23,
- compact_otp4920_msg24,
- compact_otp4920_msg25,
- compact_otp5186_msg01,
- compact_otp5186_msg02,
- compact_otp5186_msg03,
- compact_otp5186_msg04,
- compact_otp5186_msg05,
- compact_otp5186_msg06,
- compact_otp5793_msg01,
- compact_otp5836_msg01,
- compact_otp5993_msg01,
- compact_otp5993_msg02,
- compact_otp5993_msg03,
- compact_otp6017_msg01,
- compact_otp6017_msg02,
- compact_otp6017_msg03
- ].
-
-
-flex_compact_tickets(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_tickets_cases(),
- flex_compact_finish}}.
-flex_compact_tickets_cases() ->
- [
- flex_compact_otp4299_msg1,
- flex_compact_otp7431_msg01,
- flex_compact_otp7431_msg02,
- flex_compact_otp7431_msg03,
- flex_compact_otp7431_msg04,
- flex_compact_otp7431_msg05,
- flex_compact_otp7431_msg06,
- flex_compact_otp7431_msg07
- ].
-
-
-pretty_tickets(suite) ->
- [
- pretty_otp4632_msg1,
- pretty_otp4632_msg2,
- pretty_otp4632_msg3,
- pretty_otp4632_msg4,
- pretty_otp4710_msg1,
- pretty_otp4710_msg2,
- pretty_otp4945_msg1,
- pretty_otp4945_msg2,
- pretty_otp4945_msg3,
- pretty_otp4945_msg4,
- pretty_otp4945_msg5,
- pretty_otp4945_msg6,
- pretty_otp4949_msg1,
- pretty_otp4949_msg2,
- pretty_otp4949_msg3,
- pretty_otp5042_msg1,
- pretty_otp5068_msg1,
- pretty_otp5085_msg1,
- pretty_otp5085_msg2,
- pretty_otp5085_msg3,
- pretty_otp5085_msg4,
- pretty_otp5085_msg5,
- pretty_otp5085_msg6,
- pretty_otp5085_msg7,
- pretty_otp5085_msg8,
- pretty_otp5600_msg1,
- pretty_otp5600_msg2,
- pretty_otp5601_msg1,
- pretty_otp5793_msg01,
- pretty_otp5803_msg01,
- pretty_otp5803_msg02,
- pretty_otp5805_msg01,
- pretty_otp5836_msg01,
- pretty_otp5882_msg01,
- pretty_otp6490_msg01,
- pretty_otp6490_msg02,
- pretty_otp6490_msg03,
- pretty_otp6490_msg04,
- pretty_otp6490_msg05,
- pretty_otp6490_msg06,
- pretty_otp7671_msg01,
- pretty_otp7671_msg02,
- pretty_otp7671_msg03,
- pretty_otp7671_msg04,
- pretty_otp7671_msg05,
- pretty_otp8114_msg01
- ].
+flex_compact_tickets_cases() ->
+ [flex_compact_otp4299_msg1, flex_compact_otp7431_msg01,
+ flex_compact_otp7431_msg02, flex_compact_otp7431_msg03,
+ flex_compact_otp7431_msg04, flex_compact_otp7431_msg05,
+ flex_compact_otp7431_msg06, flex_compact_otp7431_msg07].
+
+flex_pretty_tickets_cases() ->
+ [flex_pretty_otp5042_msg1, flex_pretty_otp5085_msg1,
+ flex_pretty_otp5085_msg2, flex_pretty_otp5085_msg3,
+ flex_pretty_otp5085_msg4, flex_pretty_otp5085_msg5,
+ flex_pretty_otp5085_msg6, flex_pretty_otp5085_msg7,
+ flex_pretty_otp5085_msg8, flex_pretty_otp5600_msg1,
+ flex_pretty_otp5600_msg2, flex_pretty_otp5601_msg1,
+ flex_pretty_otp5793_msg01, flex_pretty_otp5803_msg01,
+ flex_pretty_otp5803_msg02, flex_pretty_otp5805_msg01,
+ flex_pretty_otp5836_msg01, flex_pretty_otp7431_msg01,
+ flex_pretty_otp7431_msg02, flex_pretty_otp7431_msg03,
+ flex_pretty_otp7431_msg04, flex_pretty_otp7431_msg05,
+ flex_pretty_otp7431_msg06, flex_pretty_otp7431_msg07].
+%% ----
-flex_pretty_tickets(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_tickets_cases(),
- flex_pretty_finish}}.
-
-flex_pretty_tickets_cases() ->
- [
- flex_pretty_otp5042_msg1,
- flex_pretty_otp5085_msg1,
- flex_pretty_otp5085_msg2,
- flex_pretty_otp5085_msg3,
- flex_pretty_otp5085_msg4,
- flex_pretty_otp5085_msg5,
- flex_pretty_otp5085_msg6,
- flex_pretty_otp5085_msg7,
- flex_pretty_otp5085_msg8,
- flex_pretty_otp5600_msg1,
- flex_pretty_otp5600_msg2,
- flex_pretty_otp5601_msg1,
- flex_pretty_otp5793_msg01,
- flex_pretty_otp5803_msg01,
- flex_pretty_otp5803_msg02,
- flex_pretty_otp5805_msg01,
- flex_pretty_otp5836_msg01,
- flex_pretty_otp7431_msg01,
- flex_pretty_otp7431_msg02,
- flex_pretty_otp7431_msg03,
- flex_pretty_otp7431_msg04,
- flex_pretty_otp7431_msg05,
- flex_pretty_otp7431_msg06,
- flex_pretty_otp7431_msg07
- ].
+tickets() ->
+ Flag = process_flag(trap_exit, true),
+ Cases = expand(tickets),
+ Fun = fun(Case) ->
+ C = init_per_testcase(Case, [{tc_timeout,
+ timer:minutes(10)}]),
+ io:format("Eval ~w~n", [Case]),
+ Result =
+ case (catch apply(?MODULE, Case, [C])) of
+ {'EXIT', Reason} ->
+ io:format("~n~p exited:~n ~p~n",
+ [Case, Reason]),
+ {error, {Case, Reason}};
+ Res ->
+ Res
+ end,
+ end_per_testcase(Case, C),
+ Result
+ end,
+ process_flag(trap_exit, Flag),
+ lists:map(Fun, Cases).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_codec_test.erl b/lib/megaco/test/megaco_codec_test.erl
index d247959cc5..8391024c3f 100644
--- a/lib/megaco/test/megaco_codec_test.erl
+++ b/lib/megaco/test/megaco_codec_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -36,8 +36,8 @@ t(Case) -> megaco_test_lib:t({?MODULE, Case}).
init_per_testcase(Case, Config) ->
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
init() ->
process_flag(trap_exit, true),
@@ -47,17 +47,24 @@ init() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- codec
- ].
-
-codec(suite) ->
- [{megaco_codec_mini_test, all},
- {megaco_codec_v1_test, all},
- {megaco_codec_v2_test, all},
- {megaco_codec_prev3a_test, all},
- {megaco_codec_prev3b_test, all},
- {megaco_codec_prev3c_test, all},
- {megaco_codec_v3_test, all}].
+all() ->
+ [{group, codec}].
+
+groups() ->
+ [{codec, [],
+ [{megaco_codec_mini_test, all},
+ {megaco_codec_v1_test, all},
+ {megaco_codec_v2_test, all},
+ {megaco_codec_prev3a_test, all},
+ {megaco_codec_prev3b_test, all},
+ {megaco_codec_prev3c_test, all},
+ {megaco_codec_v3_test, all}]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
diff --git a/lib/megaco/test/megaco_codec_test_lib.erl b/lib/megaco/test/megaco_codec_test_lib.erl
index 66e8a52a24..0a903f5617 100644
--- a/lib/megaco/test/megaco_codec_test_lib.erl
+++ b/lib/megaco/test/megaco_codec_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/megaco/test/megaco_codec_v1_test.erl b/lib/megaco/test/megaco_codec_v1_test.erl
index 7f2af37282..3a548c4d9e 100644
--- a/lib/megaco/test/megaco_codec_v1_test.erl
+++ b/lib/megaco/test/megaco_codec_v1_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,6 +26,10 @@
%% ----
+-compile({no_auto_import,[error/1]}).
+
+%% ----
+
-include_lib("megaco/include/megaco.hrl").
-include_lib("megaco/include/megaco_message_v1.hrl").
-include("megaco_test_lib.hrl").
@@ -38,22 +42,16 @@
-export([t/0, t/1]).
--export([all/1,
-
- text/1,
-
- pretty/1,
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
+
pretty_test_msgs/1,
-
- compact/1,
+
compact_test_msgs/1,
-
- flex_pretty/1,
+
flex_pretty_init/1,
flex_pretty_finish/1,
flex_pretty_test_msgs/1,
-
- flex_compact/1,
+
flex_compact_init/1,
flex_compact_finish/1,
flex_compact_test_msgs/1,
@@ -63,32 +61,21 @@
flex_compact_dm_timers4/1,
flex_compact_dm_timers5/1,
flex_compact_dm_timers6/1,
-
- binary/1,
- bin/1,
bin_test_msgs/1,
-
- ber/1,
+
ber_test_msgs/1,
-
- ber_bin/1,
+
ber_bin_test_msgs/1,
-
- per/1,
+
per_test_msgs/1,
-
- per_bin/1,
+
per_bin_test_msgs/1,
-
- erl_dist/1,
- erl_dist_m/1,
+
erl_dist_m_test_msgs/1,
tickets/0,
- tickets/1,
-
- compact_tickets/1,
+
compact_otp4011_msg1/1,
compact_otp4011_msg2/1,
compact_otp4011_msg3/1,
@@ -131,8 +118,7 @@
compact_otp6017_msg01/1,
compact_otp6017_msg02/1,
compact_otp6017_msg03/1,
-
- flex_compact_tickets/1,
+
flex_compact_otp7431_msg01a/1,
flex_compact_otp7431_msg01b/1,
flex_compact_otp7431_msg02/1,
@@ -141,8 +127,7 @@
flex_compact_otp7431_msg05/1,
flex_compact_otp7431_msg06/1,
flex_compact_otp7431_msg07/1,
-
- pretty_tickets/1,
+
pretty_otp4632_msg1/1,
pretty_otp4632_msg2/1,
pretty_otp4632_msg3/1,
@@ -184,7 +169,6 @@
pretty_otp7671_msg04/1,
pretty_otp7671_msg05/1,
- flex_pretty_tickets/1,
flex_pretty_otp5042_msg1/1,
flex_pretty_otp5085_msg1/1,
flex_pretty_otp5085_msg2/1,
@@ -205,7 +189,7 @@
flex_pretty_otp7431_msg06/1,
flex_pretty_otp7431_msg07/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
-export([display_text_messages/0, generate_text_messages/0]).
@@ -451,31 +435,6 @@ expand([Case|Cases], Acc) ->
expand(Cases, [Case|Acc])
end.
-
-%% ----
-
-tickets() ->
- Flag = process_flag(trap_exit, true),
- Cases = expand(tickets),
- Fun = fun(Case) ->
- C = init_per_testcase(Case, [{tc_timeout,
- timer:minutes(10)}]),
- io:format("Eval ~w~n", [Case]),
- Result =
- case (catch apply(?MODULE, Case, [C])) of
- {'EXIT', Reason} ->
- io:format("~n~p exited:~n ~p~n",
- [Case, Reason]),
- {error, {Case, Reason}};
- Res ->
- Res
- end,
- fin_per_testcase(Case, C),
- Result
- end,
- process_flag(trap_exit, Flag),
- lists:map(Fun, Cases).
-
%% ----
@@ -494,265 +453,210 @@ init_per_testcase(Case, Config) ->
end,
megaco_test_lib:init_per_testcase(Case, C).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
erase(verbosity),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- text,
- binary,
- erl_dist,
- tickets
- ].
-
-text(suite) ->
- [
- pretty,
- flex_pretty,
- compact,
- flex_compact
- ].
-
-binary(suite) ->
- [
- bin,
- ber,
- ber_bin,
- per,
- per_bin
- ].
-
-erl_dist(suite) ->
- [
- erl_dist_m
- ].
-
-pretty(suite) ->
- [
- pretty_test_msgs
- ].
-
-
-compact(suite) ->
- [
- compact_test_msgs
- ].
-
-
-flex_pretty(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_cases(), flex_pretty_finish}}.
-
-flex_pretty_cases() ->
- [
- flex_pretty_test_msgs
- ].
-
-
-flex_compact(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_cases(), flex_compact_finish}}.
-
-flex_compact_cases() ->
- [
- flex_compact_test_msgs,
-
- flex_compact_dm_timers1,
- flex_compact_dm_timers2,
- flex_compact_dm_timers3,
- flex_compact_dm_timers4,
- flex_compact_dm_timers5,
- flex_compact_dm_timers6
- ].
-
-
-bin(suite) ->
- [
- bin_test_msgs
- ].
-
-
-ber(suite) ->
+all() ->
[
- ber_test_msgs
- ].
-
-
-ber_bin(suite) ->
- [
- ber_bin_test_msgs
- ].
-
-
-per(suite) ->
- [
- per_test_msgs
+ {group, text},
+ {group, binary},
+ {group, erl_dist},
+ {group, tickets}
].
+groups() ->
+ [{text, [], [{group, pretty},
+ {group, flex_pretty},
+ {group, compact},
+ {group, flex_compact}]},
+ {binary, [], [{group, bin},
+ {group, ber},
+ {group, ber_bin},
+ {group, per},
+ {group, per_bin}]},
+ {erl_dist, [], [{group, erl_dist_m}]},
+ {pretty, [], [pretty_test_msgs]},
+ {compact, [], [compact_test_msgs]},
+ {flex_pretty, [], flex_pretty_cases()},
+ {flex_compact, [], flex_compact_cases()},
+ {bin, [], [bin_test_msgs]},
+ {ber, [], [ber_test_msgs]},
+ {ber_bin, [], [ber_bin_test_msgs]},
+ {per, [], [per_test_msgs]},
+ {per_bin, [], [per_bin_test_msgs]},
+ {erl_dist_m, [], [erl_dist_m_test_msgs]},
+ {tickets, [], [{group, compact_tickets},
+ {group, pretty_tickets},
+ {group, flex_compact_tickets},
+ {group, flex_pretty_tickets}]},
+ {compact_tickets, [], [compact_otp4011_msg1,
+ compact_otp4011_msg2,
+ compact_otp4011_msg3,
+ compact_otp4013_msg1,
+ compact_otp4085_msg1,
+ compact_otp4085_msg2,
+ compact_otp4280_msg1,
+ compact_otp4299_msg1,
+ compact_otp4299_msg2,
+ compact_otp4359_msg1,
+ compact_otp4920_msg0,
+ compact_otp4920_msg1,
+ compact_otp4920_msg2,
+ compact_otp4920_msg3,
+ compact_otp4920_msg4,
+ compact_otp4920_msg5,
+ compact_otp4920_msg6,
+ compact_otp4920_msg7,
+ compact_otp4920_msg8,
+ compact_otp4920_msg9,
+ compact_otp4920_msg10,
+ compact_otp4920_msg11,
+ compact_otp4920_msg12,
+ compact_otp4920_msg20,
+ compact_otp4920_msg21,
+ compact_otp4920_msg22,
+ compact_otp4920_msg23,
+ compact_otp4920_msg24,
+ compact_otp4920_msg25,
+ compact_otp5186_msg01,
+ compact_otp5186_msg02,
+ compact_otp5186_msg03,
+ compact_otp5186_msg04,
+ compact_otp5186_msg05,
+ compact_otp5186_msg06,
+ compact_otp5793_msg01,
+ compact_otp5993_msg01,
+ compact_otp5993_msg02,
+ compact_otp5993_msg03,
+ compact_otp6017_msg01,
+ compact_otp6017_msg02,
+ compact_otp6017_msg03]},
+ {flex_compact_tickets, [], flex_compact_tickets_cases()},
+ {pretty_tickets, [], [pretty_otp4632_msg1,
+ pretty_otp4632_msg2,
+ pretty_otp4632_msg3,
+ pretty_otp4632_msg4,
+ pretty_otp4710_msg1,
+ pretty_otp4710_msg2,
+ pretty_otp4945_msg1,
+ pretty_otp4945_msg2,
+ pretty_otp4945_msg3,
+ pretty_otp4945_msg4,
+ pretty_otp4945_msg5,
+ pretty_otp4945_msg6,
+ pretty_otp4949_msg1,
+ pretty_otp4949_msg2,
+ pretty_otp4949_msg3,
+ pretty_otp5042_msg1,
+ pretty_otp5068_msg1,
+ pretty_otp5085_msg1,
+ pretty_otp5085_msg2,
+ pretty_otp5085_msg3,
+ pretty_otp5085_msg4,
+ pretty_otp5085_msg5,
+ pretty_otp5085_msg6,
+ pretty_otp5085_msg7,
+ pretty_otp5600_msg1,
+ pretty_otp5600_msg2,
+ pretty_otp5601_msg1,
+ pretty_otp5793_msg01,
+ pretty_otp5882_msg01,
+ pretty_otp6490_msg01,
+ pretty_otp6490_msg02,
+ pretty_otp6490_msg03,
+ pretty_otp6490_msg04,
+ pretty_otp6490_msg05,
+ pretty_otp6490_msg06,
+ pretty_otp7671_msg01,
+ pretty_otp7671_msg02,
+ pretty_otp7671_msg03,
+ pretty_otp7671_msg04,
+ pretty_otp7671_msg05]},
+ {flex_pretty_tickets, [], flex_pretty_tickets_cases()}].
+
+init_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_init(Config);
+init_per_group(flex_compact_tickets, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_compact, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_pretty, Config) ->
+ flex_pretty_init(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(flex_compact_tickets, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_compact, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_pretty, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
+flex_pretty_cases() ->
+ [flex_pretty_test_msgs].
+
+flex_compact_cases() ->
+ [flex_compact_test_msgs, flex_compact_dm_timers1,
+ flex_compact_dm_timers2, flex_compact_dm_timers3,
+ flex_compact_dm_timers4, flex_compact_dm_timers5,
+ flex_compact_dm_timers6].
%% Support for per_bin was added to ASN.1 as of version
%% 1.3.2 (R8). And later merged into 1.3.1.3 (R7). These
%% releases are identical (as far as I know).
%%
-per_bin(suite) ->
- [
- per_bin_test_msgs
- ].
-
-erl_dist_m(suite) ->
- [
- erl_dist_m_test_msgs
- ].
-tickets(suite) ->
- [
- compact_tickets,
- pretty_tickets,
- flex_compact_tickets,
- flex_pretty_tickets
- ].
+flex_compact_tickets_cases() ->
+ [flex_compact_otp7431_msg01a,
+ flex_compact_otp7431_msg01b, flex_compact_otp7431_msg02,
+ flex_compact_otp7431_msg03, flex_compact_otp7431_msg04,
+ flex_compact_otp7431_msg05, flex_compact_otp7431_msg06,
+ flex_compact_otp7431_msg07].
+
+flex_pretty_tickets_cases() ->
+ [flex_pretty_otp5042_msg1, flex_pretty_otp5085_msg1,
+ flex_pretty_otp5085_msg2, flex_pretty_otp5085_msg3,
+ flex_pretty_otp5085_msg4, flex_pretty_otp5085_msg5,
+ flex_pretty_otp5085_msg6, flex_pretty_otp5085_msg7,
+ flex_pretty_otp5600_msg1, flex_pretty_otp5600_msg2,
+ flex_pretty_otp5601_msg1, flex_pretty_otp5793_msg01,
+ flex_pretty_otp7431_msg01, flex_pretty_otp7431_msg02,
+ flex_pretty_otp7431_msg03, flex_pretty_otp7431_msg04,
+ flex_pretty_otp7431_msg05, flex_pretty_otp7431_msg06,
+ flex_pretty_otp7431_msg07].
+%% ----
-compact_tickets(suite) ->
- [
- compact_otp4011_msg1,
- compact_otp4011_msg2,
- compact_otp4011_msg3,
- compact_otp4013_msg1,
- compact_otp4085_msg1,
- compact_otp4085_msg2,
- compact_otp4280_msg1,
- compact_otp4299_msg1,
- compact_otp4299_msg2,
- compact_otp4359_msg1,
- compact_otp4920_msg0,
- compact_otp4920_msg1,
- compact_otp4920_msg2,
- compact_otp4920_msg3,
- compact_otp4920_msg4,
- compact_otp4920_msg5,
- compact_otp4920_msg6,
- compact_otp4920_msg7,
- compact_otp4920_msg8,
- compact_otp4920_msg9,
- compact_otp4920_msg10,
- compact_otp4920_msg11,
- compact_otp4920_msg12,
- compact_otp4920_msg20,
- compact_otp4920_msg21,
- compact_otp4920_msg22,
- compact_otp4920_msg23,
- compact_otp4920_msg24,
- compact_otp4920_msg25,
- compact_otp5186_msg01,
- compact_otp5186_msg02,
- compact_otp5186_msg03,
- compact_otp5186_msg04,
- compact_otp5186_msg05,
- compact_otp5186_msg06,
- compact_otp5793_msg01,
- compact_otp5993_msg01,
- compact_otp5993_msg02,
- compact_otp5993_msg03,
- compact_otp6017_msg01,
- compact_otp6017_msg02,
- compact_otp6017_msg03
- ].
-
-flex_compact_tickets(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_tickets_cases(),
- flex_compact_finish}}.
-
-flex_compact_tickets_cases() ->
- [
- flex_compact_otp7431_msg01a,
- flex_compact_otp7431_msg01b,
- flex_compact_otp7431_msg02,
- flex_compact_otp7431_msg03,
- flex_compact_otp7431_msg04,
- flex_compact_otp7431_msg05,
- flex_compact_otp7431_msg06,
- flex_compact_otp7431_msg07
- ].
-
-
-pretty_tickets(suite) ->
- [
- pretty_otp4632_msg1,
- pretty_otp4632_msg2,
- pretty_otp4632_msg3,
- pretty_otp4632_msg4,
- pretty_otp4710_msg1,
- pretty_otp4710_msg2,
- pretty_otp4945_msg1,
- pretty_otp4945_msg2,
- pretty_otp4945_msg3,
- pretty_otp4945_msg4,
- pretty_otp4945_msg5,
- pretty_otp4945_msg6,
- pretty_otp4949_msg1,
- pretty_otp4949_msg2,
- pretty_otp4949_msg3,
- pretty_otp5042_msg1,
- pretty_otp5068_msg1,
- pretty_otp5085_msg1,
- pretty_otp5085_msg2,
- pretty_otp5085_msg3,
- pretty_otp5085_msg4,
- pretty_otp5085_msg5,
- pretty_otp5085_msg6,
- pretty_otp5085_msg7,
- pretty_otp5600_msg1,
- pretty_otp5600_msg2,
- pretty_otp5601_msg1,
- pretty_otp5793_msg01,
- pretty_otp5882_msg01,
- pretty_otp6490_msg01,
- pretty_otp6490_msg02,
- pretty_otp6490_msg03,
- pretty_otp6490_msg04,
- pretty_otp6490_msg05,
- pretty_otp6490_msg06,
- pretty_otp7671_msg01,
- pretty_otp7671_msg02,
- pretty_otp7671_msg03,
- pretty_otp7671_msg04,
- pretty_otp7671_msg05
- ].
-
-flex_pretty_tickets(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_tickets_cases(),
- flex_pretty_finish}}.
-
-flex_pretty_tickets_cases() ->
- [
- flex_pretty_otp5042_msg1,
- flex_pretty_otp5085_msg1,
- flex_pretty_otp5085_msg2,
- flex_pretty_otp5085_msg3,
- flex_pretty_otp5085_msg4,
- flex_pretty_otp5085_msg5,
- flex_pretty_otp5085_msg6,
- flex_pretty_otp5085_msg7,
- flex_pretty_otp5600_msg1,
- flex_pretty_otp5600_msg2,
- flex_pretty_otp5601_msg1,
- flex_pretty_otp5793_msg01,
- flex_pretty_otp7431_msg01,
- flex_pretty_otp7431_msg02,
- flex_pretty_otp7431_msg03,
- flex_pretty_otp7431_msg04,
- flex_pretty_otp7431_msg05,
- flex_pretty_otp7431_msg06,
- flex_pretty_otp7431_msg07
- ].
+tickets() ->
+ Flag = process_flag(trap_exit, true),
+ Cases = expand(tickets),
+ Fun = fun(Case) ->
+ C = init_per_testcase(Case, [{tc_timeout,
+ timer:minutes(10)}]),
+ io:format("Eval ~w~n", [Case]),
+ Result =
+ case (catch apply(?MODULE, Case, [C])) of
+ {'EXIT', Reason} ->
+ io:format("~n~p exited:~n ~p~n",
+ [Case, Reason]),
+ {error, {Case, Reason}};
+ Res ->
+ Res
+ end,
+ end_per_testcase(Case, C),
+ Result
+ end,
+ process_flag(trap_exit, Flag),
+ lists:map(Fun, Cases).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_codec_v2_test.erl b/lib/megaco/test/megaco_codec_v2_test.erl
index 1df1c6c93b..c3a80febba 100644
--- a/lib/megaco/test/megaco_codec_v2_test.erl
+++ b/lib/megaco/test/megaco_codec_v2_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -37,22 +37,16 @@
-export([t/0, t/1]).
--export([all/1,
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
- text/1,
-
- pretty/1,
pretty_test_msgs/1,
- compact/1,
compact_test_msgs/1,
-
- flex_pretty/1,
+
flex_pretty_init/1,
flex_pretty_finish/1,
flex_pretty_test_msgs/1,
-
- flex_compact/1,
+
flex_compact_init/1,
flex_compact_finish/1,
flex_compact_test_msgs/1,
@@ -65,32 +59,21 @@
flex_compact_dm_timers6/1,
flex_compact_dm_timers7/1,
flex_compact_dm_timers8/1,
-
- binary/1,
- bin/1,
bin_test_msgs/1,
- ber/1,
ber_test_msgs/1,
-
- ber_bin/1,
+
ber_bin_test_msgs/1,
-
- per/1,
+
per_test_msgs/1,
-
- per_bin/1,
+
per_bin_test_msgs/1,
-
- erl_dist/1,
- erl_dist_m/1,
+
erl_dist_m_test_msgs/1,
tickets/0,
- tickets/1,
-
- compact_tickets/1,
+
compact_otp4011_msg1/1,
compact_otp4011_msg2/1,
compact_otp4011_msg3/1,
@@ -143,8 +126,7 @@
compact_otp7534_msg01/1,
compact_otp7576_msg01/1,
compact_otp7671_msg01/1,
-
- flex_compact_tickets/1,
+
flex_compact_otp7138_msg01/1,
flex_compact_otp7138_msg02/1,
flex_compact_otp7431_msg01/1,
@@ -160,8 +142,7 @@
flex_compact_otp7534_msg01/1,
flex_compact_otp7573_msg01/1,
flex_compact_otp7576_msg01/1,
-
- pretty_tickets/1,
+
pretty_otp4632_msg1/1,
pretty_otp4632_msg2/1,
pretty_otp4632_msg3/1,
@@ -204,7 +185,6 @@
pretty_otp7671_msg04/1,
pretty_otp7671_msg05/1,
- flex_pretty_tickets/1,
flex_pretty_otp5042_msg1/1,
flex_pretty_otp5085_msg1/1,
flex_pretty_otp5085_msg2/1,
@@ -225,7 +205,7 @@
flex_pretty_otp7431_msg06/1,
flex_pretty_otp7431_msg07/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
-export([display_text_messages/0, generate_text_messages/0]).
@@ -431,31 +411,7 @@ expand([Case|Cases], Acc) ->
expand(Cases, [Case|Acc])
end.
-
-%% ----
-
-tickets() ->
- Flag = process_flag(trap_exit, true),
- Cases = expand(tickets),
- Fun = fun(Case) ->
- C = init_per_testcase(Case, [{tc_timeout,
- timer:minutes(10)}]),
- io:format("Eval ~w~n", [Case]),
- Result =
- case (catch apply(?MODULE, Case, [C])) of
- {'EXIT', Reason} ->
- io:format("~n~p exited:~n ~p~n",
- [Case, Reason]),
- {error, {Case, Reason}};
- Res ->
- Res
- end,
- fin_per_testcase(Case, C),
- Result
- end,
- process_flag(trap_exit, Flag),
- lists:map(Fun, Cases).
-
+
%% ----
@@ -474,284 +430,202 @@ init_per_testcase(Case, Config) ->
end,
megaco_test_lib:init_per_testcase(Case, C).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
erase(verbosity),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- text,
- binary,
- erl_dist,
- tickets
- ].
-
-text(suite) ->
- [
- pretty,
- flex_pretty,
- compact,
- flex_compact
- ].
-
-binary(suite) ->
- [
- bin,
- ber,
- ber_bin,
- per,
- per_bin
- ].
-
-erl_dist(suite) ->
- [
- erl_dist_m
- ].
-
-pretty(suite) ->
- [
- pretty_test_msgs
- ].
-
-
-compact(suite) ->
- [
- compact_test_msgs
- ].
+all() ->
+[{group, text}, {group, binary}, {group, erl_dist},
+ {group, tickets}].
+
+groups() ->
+ [{text, [],
+ [{group, pretty}, {group, flex_pretty},
+ {group, compact}, {group, flex_compact}]},
+ {binary, [],
+ [{group, bin}, {group, ber}, {group, ber_bin},
+ {group, per}, {group, per_bin}]},
+ {erl_dist, [], [{group, erl_dist_m}]},
+ {pretty, [], [pretty_test_msgs]},
+ {compact, [], [compact_test_msgs]},
+ {flex_pretty, [], flex_pretty_cases()},
+ {flex_compact, [], flex_compact_cases()},
+ {bin, [], [bin_test_msgs]}, {ber, [], [ber_test_msgs]},
+ {ber_bin, [], [ber_bin_test_msgs]},
+ {per, [], [per_test_msgs]},
+ {per_bin, [], [per_bin_test_msgs]},
+ {erl_dist_m, [], [erl_dist_m_test_msgs]},
+ {tickets, [],
+ [{group, compact_tickets}, {group, pretty_tickets},
+ {group, flex_compact_tickets},
+ {group, flex_pretty_tickets}]},
+ {compact_tickets, [],
+ [compact_otp4011_msg1, compact_otp4011_msg2,
+ compact_otp4011_msg3, compact_otp4013_msg1,
+ compact_otp4085_msg1, compact_otp4085_msg2,
+ compact_otp4280_msg1, compact_otp4299_msg1,
+ compact_otp4299_msg2, compact_otp4359_msg1,
+ compact_otp4920_msg0, compact_otp4920_msg1,
+ compact_otp4920_msg2, compact_otp4920_msg3,
+ compact_otp4920_msg4, compact_otp4920_msg5,
+ compact_otp4920_msg6, compact_otp4920_msg7,
+ compact_otp4920_msg8, compact_otp4920_msg9,
+ compact_otp4920_msg10, compact_otp4920_msg11,
+ compact_otp4920_msg12, compact_otp4920_msg20,
+ compact_otp4920_msg21, compact_otp4920_msg22,
+ compact_otp4920_msg23, compact_otp4920_msg24,
+ compact_otp4920_msg25, compact_otp5186_msg01,
+ compact_otp5186_msg02, compact_otp5186_msg03,
+ compact_otp5186_msg04, compact_otp5186_msg05,
+ compact_otp5186_msg06, compact_otp5290_msg01,
+ compact_otp5290_msg02, compact_otp5793_msg01,
+ compact_otp5993_msg01, compact_otp5993_msg02,
+ compact_otp5993_msg03, compact_otp6017_msg01,
+ compact_otp6017_msg02, compact_otp6017_msg03,
+ compact_otp7138_msg01, compact_otp7138_msg02,
+ compact_otp7457_msg01, compact_otp7457_msg02,
+ compact_otp7457_msg03, compact_otp7534_msg01,
+ compact_otp7576_msg01, compact_otp7671_msg01]},
+ {flex_compact_tickets, [],
+ flex_compact_tickets_cases()},
+ {pretty_tickets, [],
+ [pretty_otp4632_msg1, pretty_otp4632_msg2,
+ pretty_otp4632_msg3, pretty_otp4632_msg4,
+ pretty_otp4710_msg1, pretty_otp4710_msg2,
+ pretty_otp4945_msg1, pretty_otp4945_msg2,
+ pretty_otp4945_msg3, pretty_otp4945_msg4,
+ pretty_otp4945_msg5, pretty_otp4945_msg6,
+ pretty_otp4949_msg1, pretty_otp4949_msg2,
+ pretty_otp4949_msg3, pretty_otp5042_msg1,
+ pretty_otp5068_msg1, pretty_otp5085_msg1,
+ pretty_otp5085_msg2, pretty_otp5085_msg3,
+ pretty_otp5085_msg4, pretty_otp5085_msg5,
+ pretty_otp5085_msg6, pretty_otp5085_msg7,
+ pretty_otp5600_msg1, pretty_otp5600_msg2,
+ pretty_otp5601_msg1, pretty_otp5793_msg01,
+ pretty_otp5882_msg01, pretty_otp6490_msg01,
+ pretty_otp6490_msg02, pretty_otp6490_msg03,
+ pretty_otp6490_msg04, pretty_otp6490_msg05,
+ pretty_otp6490_msg06, pretty_otp7249_msg01,
+ pretty_otp7671_msg01, pretty_otp7671_msg02,
+ pretty_otp7671_msg03, pretty_otp7671_msg04,
+ pretty_otp7671_msg05]},
+ {flex_pretty_tickets, [], flex_pretty_tickets_cases()}].
+
+init_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_init(Config);
+init_per_group(flex_compact_tickets, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_compact, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_pretty, Config) ->
+ flex_pretty_init(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(flex_compact_tickets, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_compact, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_pretty, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+
+
+
+
+
+
+
+
+flex_pretty_cases() ->
+[flex_pretty_test_msgs].
+
+
+flex_compact_cases() ->
+[flex_compact_test_msgs, flex_compact_dm_timers1,
+ flex_compact_dm_timers2, flex_compact_dm_timers3,
+ flex_compact_dm_timers4, flex_compact_dm_timers5,
+ flex_compact_dm_timers6, flex_compact_dm_timers7,
+ flex_compact_dm_timers8].
-flex_pretty(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_cases(), flex_pretty_finish}}.
-flex_pretty_cases() ->
- [
- flex_pretty_test_msgs
- ].
-flex_compact(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_cases(), flex_compact_finish}}.
-flex_compact_cases() ->
- [
- flex_compact_test_msgs,
- flex_compact_dm_timers1,
- flex_compact_dm_timers2,
- flex_compact_dm_timers3,
- flex_compact_dm_timers4,
- flex_compact_dm_timers5,
- flex_compact_dm_timers6,
- flex_compact_dm_timers7,
- flex_compact_dm_timers8
- ].
-bin(suite) ->
- [
- bin_test_msgs
- ].
-ber(suite) ->
- [
- ber_test_msgs
- ].
-
-
-ber_bin(suite) ->
- [
- ber_bin_test_msgs
- ].
-
-
-per(suite) ->
- [
- per_test_msgs
- ].
-
%% Support for per_bin was added to ASN.1 as of version
%% 1.3.2 (R8). And later merged into 1.3.1.3 (R7). These
%% releases are identical (as far as I know).
%%
-per_bin(suite) ->
- [
- per_bin_test_msgs
- ].
-erl_dist_m(suite) ->
- [
- erl_dist_m_test_msgs
- ].
-tickets(suite) ->
- [
- compact_tickets,
- pretty_tickets,
- flex_compact_tickets,
- flex_pretty_tickets
- ].
-compact_tickets(suite) ->
- [
- compact_otp4011_msg1,
- compact_otp4011_msg2,
- compact_otp4011_msg3,
- compact_otp4013_msg1,
- compact_otp4085_msg1,
- compact_otp4085_msg2,
- compact_otp4280_msg1,
- compact_otp4299_msg1,
- compact_otp4299_msg2,
- compact_otp4359_msg1,
- compact_otp4920_msg0,
- compact_otp4920_msg1,
- compact_otp4920_msg2,
- compact_otp4920_msg3,
- compact_otp4920_msg4,
- compact_otp4920_msg5,
- compact_otp4920_msg6,
- compact_otp4920_msg7,
- compact_otp4920_msg8,
- compact_otp4920_msg9,
- compact_otp4920_msg10,
- compact_otp4920_msg11,
- compact_otp4920_msg12,
- compact_otp4920_msg20,
- compact_otp4920_msg21,
- compact_otp4920_msg22,
- compact_otp4920_msg23,
- compact_otp4920_msg24,
- compact_otp4920_msg25,
- compact_otp5186_msg01,
- compact_otp5186_msg02,
- compact_otp5186_msg03,
- compact_otp5186_msg04,
- compact_otp5186_msg05,
- compact_otp5186_msg06,
- compact_otp5290_msg01,
- compact_otp5290_msg02,
- compact_otp5793_msg01,
- compact_otp5993_msg01,
- compact_otp5993_msg02,
- compact_otp5993_msg03,
- compact_otp6017_msg01,
- compact_otp6017_msg02,
- compact_otp6017_msg03,
- compact_otp7138_msg01,
- compact_otp7138_msg02,
- compact_otp7457_msg01,
- compact_otp7457_msg02,
- compact_otp7457_msg03,
- compact_otp7534_msg01,
- compact_otp7576_msg01,
- compact_otp7671_msg01
- ].
-flex_compact_tickets(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_tickets_cases(),
- flex_compact_finish}}.
-flex_compact_tickets_cases() ->
- [
- flex_compact_otp7138_msg01,
- flex_compact_otp7138_msg02,
- flex_compact_otp7431_msg01,
- flex_compact_otp7431_msg02,
- flex_compact_otp7431_msg03,
- flex_compact_otp7431_msg04,
- flex_compact_otp7431_msg05,
- flex_compact_otp7431_msg06,
- flex_compact_otp7431_msg07,
- flex_compact_otp7138_msg02,
- flex_compact_otp7457_msg01,
- flex_compact_otp7457_msg02,
- flex_compact_otp7457_msg03,
- flex_compact_otp7534_msg01,
- flex_compact_otp7573_msg01,
- flex_compact_otp7576_msg01
- ].
+flex_compact_tickets_cases() ->
+[flex_compact_otp7138_msg01, flex_compact_otp7138_msg02,
+ flex_compact_otp7431_msg01, flex_compact_otp7431_msg02,
+ flex_compact_otp7431_msg03, flex_compact_otp7431_msg04,
+ flex_compact_otp7431_msg05, flex_compact_otp7431_msg06,
+ flex_compact_otp7431_msg07, flex_compact_otp7138_msg02,
+ flex_compact_otp7457_msg01, flex_compact_otp7457_msg02,
+ flex_compact_otp7457_msg03, flex_compact_otp7534_msg01,
+ flex_compact_otp7573_msg01, flex_compact_otp7576_msg01].
-pretty_tickets(suite) ->
- [
- pretty_otp4632_msg1,
- pretty_otp4632_msg2,
- pretty_otp4632_msg3,
- pretty_otp4632_msg4,
- pretty_otp4710_msg1,
- pretty_otp4710_msg2,
- pretty_otp4945_msg1,
- pretty_otp4945_msg2,
- pretty_otp4945_msg3,
- pretty_otp4945_msg4,
- pretty_otp4945_msg5,
- pretty_otp4945_msg6,
- pretty_otp4949_msg1,
- pretty_otp4949_msg2,
- pretty_otp4949_msg3,
- pretty_otp5042_msg1,
- pretty_otp5068_msg1,
- pretty_otp5085_msg1,
- pretty_otp5085_msg2,
- pretty_otp5085_msg3,
- pretty_otp5085_msg4,
- pretty_otp5085_msg5,
- pretty_otp5085_msg6,
- pretty_otp5085_msg7,
- pretty_otp5600_msg1,
- pretty_otp5600_msg2,
- pretty_otp5601_msg1,
- pretty_otp5793_msg01,
- pretty_otp5882_msg01,
- pretty_otp6490_msg01,
- pretty_otp6490_msg02,
- pretty_otp6490_msg03,
- pretty_otp6490_msg04,
- pretty_otp6490_msg05,
- pretty_otp6490_msg06,
- pretty_otp7249_msg01,
- pretty_otp7671_msg01,
- pretty_otp7671_msg02,
- pretty_otp7671_msg03,
- pretty_otp7671_msg04,
- pretty_otp7671_msg05
- ].
-flex_pretty_tickets(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_tickets_cases(),
- flex_pretty_finish}}.
-flex_pretty_tickets_cases() ->
- [
- flex_pretty_otp5042_msg1,
- flex_pretty_otp5085_msg1,
- flex_pretty_otp5085_msg2,
- flex_pretty_otp5085_msg3,
- flex_pretty_otp5085_msg4,
- flex_pretty_otp5085_msg5,
- flex_pretty_otp5085_msg6,
- flex_pretty_otp5085_msg7,
- flex_pretty_otp5600_msg1,
- flex_pretty_otp5600_msg2,
- flex_pretty_otp5601_msg1,
- flex_pretty_otp5793_msg01,
- flex_pretty_otp7431_msg01,
- flex_pretty_otp7431_msg02,
- flex_pretty_otp7431_msg03,
- flex_pretty_otp7431_msg04,
- flex_pretty_otp7431_msg05,
- flex_pretty_otp7431_msg06,
- flex_pretty_otp7431_msg07
- ].
+flex_pretty_tickets_cases() ->
+[flex_pretty_otp5042_msg1, flex_pretty_otp5085_msg1,
+ flex_pretty_otp5085_msg2, flex_pretty_otp5085_msg3,
+ flex_pretty_otp5085_msg4, flex_pretty_otp5085_msg5,
+ flex_pretty_otp5085_msg6, flex_pretty_otp5085_msg7,
+ flex_pretty_otp5600_msg1, flex_pretty_otp5600_msg2,
+ flex_pretty_otp5601_msg1, flex_pretty_otp5793_msg01,
+ flex_pretty_otp7431_msg01, flex_pretty_otp7431_msg02,
+ flex_pretty_otp7431_msg03, flex_pretty_otp7431_msg04,
+ flex_pretty_otp7431_msg05, flex_pretty_otp7431_msg06,
+ flex_pretty_otp7431_msg07].
+
+%% ----
+
+tickets() ->
+ Flag = process_flag(trap_exit, true),
+ Cases = expand(tickets),
+ Fun = fun(Case) ->
+ C = init_per_testcase(Case, [{tc_timeout,
+ timer:minutes(10)}]),
+ io:format("Eval ~w~n", [Case]),
+ Result =
+ case (catch apply(?MODULE, Case, [C])) of
+ {'EXIT', Reason} ->
+ io:format("~n~p exited:~n ~p~n",
+ [Case, Reason]),
+ {error, {Case, Reason}};
+ Res ->
+ Res
+ end,
+ end_per_testcase(Case, C),
+ Result
+ end,
+ process_flag(trap_exit, Flag),
+ lists:map(Fun, Cases).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_codec_v3_test.erl b/lib/megaco/test/megaco_codec_v3_test.erl
index f49c3a677a..2c35ce13b3 100644
--- a/lib/megaco/test/megaco_codec_v3_test.erl
+++ b/lib/megaco/test/megaco_codec_v3_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -37,26 +37,15 @@
-export([t/0, t/1]).
--export([all/1,
-
- text/1,
-
- pretty/1,
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
pretty_test_msgs/1,
-
- compact/1,
compact_test_msgs/1,
-
- flex_pretty/1,
flex_pretty_init/1,
flex_pretty_finish/1,
flex_pretty_test_msgs/1,
-
- flex_compact/1,
flex_compact_init/1,
flex_compact_finish/1,
flex_compact_test_msgs/1,
-
flex_compact_dm_timers1/1,
flex_compact_dm_timers2/1,
flex_compact_dm_timers3/1,
@@ -65,32 +54,15 @@
flex_compact_dm_timers6/1,
flex_compact_dm_timers7/1,
flex_compact_dm_timers8/1,
-
- binary/1,
-
- bin/1,
bin_test_msgs/1,
-
- ber/1,
ber_test_msgs/1,
-
- ber_bin/1,
ber_bin_test_msgs/1,
-
- per/1,
per_test_msgs/1,
-
- per_bin/1,
per_bin_test_msgs/1,
-
- erl_dist/1,
- erl_dist_m/1,
erl_dist_m_test_msgs/1,
tickets/0,
- tickets/1,
-
- compact_tickets/1,
+
compact_otp4011_msg1/1,
compact_otp4011_msg2/1,
compact_otp4011_msg3/1,
@@ -133,8 +105,7 @@
compact_otp6017_msg01/1,
compact_otp6017_msg02/1,
compact_otp6017_msg03/1,
-
- flex_compact_tickets/1,
+
flex_compact_otp4299_msg1/1,
flex_compact_otp7431_msg01/1,
flex_compact_otp7431_msg02/1,
@@ -143,9 +114,7 @@
flex_compact_otp7431_msg05/1,
flex_compact_otp7431_msg06/1,
flex_compact_otp7431_msg07/1,
-
-
- pretty_tickets/1,
+
pretty_otp4632_msg1/1,
pretty_otp4632_msg2/1,
pretty_otp4632_msg3/1,
@@ -192,8 +161,7 @@
pretty_otp7671_msg04/1,
pretty_otp7671_msg05/1,
pretty_otp8114_msg01/1,
-
- flex_pretty_tickets/1,
+
flex_pretty_otp5042_msg1/1,
flex_pretty_otp5085_msg1/1,
flex_pretty_otp5085_msg2/1,
@@ -219,7 +187,7 @@
flex_pretty_otp7431_msg06/1,
flex_pretty_otp7431_msg07/1,
- init_per_testcase/2, fin_per_testcase/2]).
+ init_per_testcase/2, end_per_testcase/2]).
-export([display_text_messages/0, generate_text_messages/0]).
@@ -285,31 +253,6 @@ expand([Case|Cases], Acc) ->
expand(Cases, [Case|Acc])
end.
-
-%% ----
-
-tickets() ->
- Flag = process_flag(trap_exit, true),
- Cases = expand(tickets),
- Fun = fun(Case) ->
- C = init_per_testcase(Case, [{tc_timeout,
- timer:minutes(10)}]),
- io:format("Eval ~w~n", [Case]),
- Result =
- case (catch apply(?MODULE, Case, [C])) of
- {'EXIT', Reason} ->
- io:format("~n~p exited:~n ~p~n",
- [Case, Reason]),
- {error, {Case, Reason}};
- Res ->
- Res
- end,
- fin_per_testcase(Case, C),
- Result
- end,
- process_flag(trap_exit, Flag),
- lists:map(Fun, Cases).
-
%% ----
@@ -328,279 +271,174 @@ init_per_testcase(Case, Config) ->
end,
megaco_test_lib:init_per_testcase(Case, C).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
erase(verbosity),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- text,
- binary,
- erl_dist,
- tickets
- ].
-
-text(suite) ->
- [
- pretty,
- flex_pretty,
- compact,
- flex_compact
- ].
-
-binary(suite) ->
- [
- bin,
- ber,
- ber_bin,
- per,
- per_bin
- ].
-
-erl_dist(suite) ->
- [
- erl_dist_m
- ].
-
-pretty(suite) ->
- [
- pretty_test_msgs
- ].
-
-
-compact(suite) ->
- [
- compact_test_msgs
- ].
-
-
-flex_pretty(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_cases(), flex_pretty_finish}}.
+all() ->
+ [{group, text}, {group, binary}, {group, erl_dist},
+ {group, tickets}].
+
+groups() ->
+ [{text, [],
+ [{group, pretty}, {group, flex_pretty},
+ {group, compact}, {group, flex_compact}]},
+ {binary, [],
+ [{group, bin}, {group, ber}, {group, ber_bin},
+ {group, per}, {group, per_bin}]},
+ {erl_dist, [], [{group, erl_dist_m}]},
+ {pretty, [], [pretty_test_msgs]},
+ {compact, [], [compact_test_msgs]},
+ {flex_pretty, [], flex_pretty_cases()},
+ {flex_compact, [], flex_compact_cases()},
+ {bin, [], [bin_test_msgs]}, {ber, [], [ber_test_msgs]},
+ {ber_bin, [], [ber_bin_test_msgs]},
+ {per, [], [per_test_msgs]},
+ {per_bin, [], [per_bin_test_msgs]},
+ {erl_dist_m, [], [erl_dist_m_test_msgs]},
+ {tickets, [],
+ [{group, compact_tickets},
+ {group, flex_compact_tickets}, {group, pretty_tickets},
+ {group, flex_pretty_tickets}]},
+ {compact_tickets, [],
+ [compact_otp4011_msg1, compact_otp4011_msg2,
+ compact_otp4011_msg3, compact_otp4013_msg1,
+ compact_otp4085_msg1, compact_otp4085_msg2,
+ compact_otp4280_msg1, compact_otp4299_msg1,
+ compact_otp4359_msg1, compact_otp4920_msg0,
+ compact_otp4920_msg1, compact_otp4920_msg2,
+ compact_otp4920_msg3, compact_otp4920_msg4,
+ compact_otp4920_msg5, compact_otp4920_msg6,
+ compact_otp4920_msg7, compact_otp4920_msg8,
+ compact_otp4920_msg9, compact_otp4920_msg10,
+ compact_otp4920_msg11, compact_otp4920_msg12,
+ compact_otp4920_msg20, compact_otp4920_msg21,
+ compact_otp4920_msg22, compact_otp4920_msg23,
+ compact_otp4920_msg24, compact_otp4920_msg25,
+ compact_otp5186_msg01, compact_otp5186_msg02,
+ compact_otp5186_msg03, compact_otp5186_msg04,
+ compact_otp5186_msg05, compact_otp5186_msg06,
+ compact_otp5793_msg01, compact_otp5836_msg01,
+ compact_otp5993_msg01, compact_otp5993_msg02,
+ compact_otp5993_msg03, compact_otp6017_msg01,
+ compact_otp6017_msg02, compact_otp6017_msg03]},
+ {flex_compact_tickets, [],
+ flex_compact_tickets_cases()},
+ {pretty_tickets, [],
+ [pretty_otp4632_msg1, pretty_otp4632_msg2,
+ pretty_otp4632_msg3, pretty_otp4632_msg4,
+ pretty_otp4710_msg1, pretty_otp4710_msg2,
+ pretty_otp4945_msg1, pretty_otp4945_msg2,
+ pretty_otp4945_msg3, pretty_otp4945_msg4,
+ pretty_otp4945_msg5, pretty_otp4945_msg6,
+ pretty_otp4949_msg1, pretty_otp4949_msg2,
+ pretty_otp4949_msg3, pretty_otp5042_msg1,
+ pretty_otp5068_msg1, pretty_otp5085_msg1,
+ pretty_otp5085_msg2, pretty_otp5085_msg3,
+ pretty_otp5085_msg4, pretty_otp5085_msg5,
+ pretty_otp5085_msg6, pretty_otp5085_msg7,
+ pretty_otp5085_msg8, pretty_otp5600_msg1,
+ pretty_otp5600_msg2, pretty_otp5601_msg1,
+ pretty_otp5793_msg01, pretty_otp5803_msg01,
+ pretty_otp5803_msg02, pretty_otp5805_msg01,
+ pretty_otp5836_msg01, pretty_otp5882_msg01,
+ pretty_otp6490_msg01, pretty_otp6490_msg02,
+ pretty_otp6490_msg03, pretty_otp6490_msg04,
+ pretty_otp6490_msg05, pretty_otp6490_msg06,
+ pretty_otp7671_msg01, pretty_otp7671_msg02,
+ pretty_otp7671_msg03, pretty_otp7671_msg04,
+ pretty_otp7671_msg05, pretty_otp8114_msg01]},
+ {flex_pretty_tickets, [], flex_pretty_tickets_cases()}].
+
+init_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_init(Config);
+init_per_group(flex_compact_tickets, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_compact, Config) ->
+ flex_compact_init(Config);
+init_per_group(flex_pretty, Config) ->
+ flex_pretty_init(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(flex_pretty_tickets, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(flex_compact_tickets, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_compact, Config) ->
+ flex_compact_finish(Config);
+end_per_group(flex_pretty, Config) ->
+ flex_pretty_finish(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+flex_pretty_cases() ->
+ [flex_pretty_test_msgs].
+
+
+flex_compact_cases() ->
+ [flex_compact_test_msgs, flex_compact_dm_timers1,
+ flex_compact_dm_timers2, flex_compact_dm_timers3,
+ flex_compact_dm_timers4, flex_compact_dm_timers5,
+ flex_compact_dm_timers6, flex_compact_dm_timers7,
+ flex_compact_dm_timers8].
-flex_pretty_cases() ->
- [
- flex_pretty_test_msgs
- ].
-
-flex_compact(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_cases(), flex_compact_finish}}.
-
-flex_compact_cases() ->
- [
- flex_compact_test_msgs,
- flex_compact_dm_timers1,
- flex_compact_dm_timers2,
- flex_compact_dm_timers3,
- flex_compact_dm_timers4,
- flex_compact_dm_timers5,
- flex_compact_dm_timers6,
- flex_compact_dm_timers7,
- flex_compact_dm_timers8
- ].
-
-
-bin(suite) ->
- [
- bin_test_msgs
- ].
-
-
-ber(suite) ->
- [
- ber_test_msgs
- ].
-
-
-ber_bin(suite) ->
- [
- ber_bin_test_msgs
- ].
-
-
-per(suite) ->
- [
- per_test_msgs
- ].
%% Support for per_bin was added to ASN.1 as of version
%% 1.3.2 (R8). And later merged into 1.3.1.3 (R7). These
%% releases are identical (as far as I know).
%%
-per_bin(suite) ->
- [
- per_bin_test_msgs
- ].
-
-
-erl_dist_m(suite) ->
- [
- erl_dist_m_test_msgs
- ].
-
-tickets(suite) ->
- [
- compact_tickets,
- flex_compact_tickets,
- pretty_tickets,
- flex_pretty_tickets
- ].
-
-
-compact_tickets(suite) ->
- [
- compact_otp4011_msg1,
- compact_otp4011_msg2,
- compact_otp4011_msg3,
- compact_otp4013_msg1,
- compact_otp4085_msg1,
- compact_otp4085_msg2,
- compact_otp4280_msg1,
- compact_otp4299_msg1,
- compact_otp4359_msg1,
- compact_otp4920_msg0,
- compact_otp4920_msg1,
- compact_otp4920_msg2,
- compact_otp4920_msg3,
- compact_otp4920_msg4,
- compact_otp4920_msg5,
- compact_otp4920_msg6,
- compact_otp4920_msg7,
- compact_otp4920_msg8,
- compact_otp4920_msg9,
- compact_otp4920_msg10,
- compact_otp4920_msg11,
- compact_otp4920_msg12,
- compact_otp4920_msg20,
- compact_otp4920_msg21,
- compact_otp4920_msg22,
- compact_otp4920_msg23,
- compact_otp4920_msg24,
- compact_otp4920_msg25,
- compact_otp5186_msg01,
- compact_otp5186_msg02,
- compact_otp5186_msg03,
- compact_otp5186_msg04,
- compact_otp5186_msg05,
- compact_otp5186_msg06,
- compact_otp5793_msg01,
- compact_otp5836_msg01,
- compact_otp5993_msg01,
- compact_otp5993_msg02,
- compact_otp5993_msg03,
- compact_otp6017_msg01,
- compact_otp6017_msg02,
- compact_otp6017_msg03
- ].
-flex_compact_tickets(suite) ->
- {req, [],
- {conf, flex_compact_init, flex_compact_tickets_cases(),
- flex_compact_finish}}.
-
-flex_compact_tickets_cases() ->
- [
- flex_compact_otp4299_msg1,
- flex_compact_otp7431_msg01,
- flex_compact_otp7431_msg02,
- flex_compact_otp7431_msg03,
- flex_compact_otp7431_msg04,
- flex_compact_otp7431_msg05,
- flex_compact_otp7431_msg06,
- flex_compact_otp7431_msg07
- ].
-
-
-pretty_tickets(suite) ->
- [
- pretty_otp4632_msg1,
- pretty_otp4632_msg2,
- pretty_otp4632_msg3,
- pretty_otp4632_msg4,
- pretty_otp4710_msg1,
- pretty_otp4710_msg2,
- pretty_otp4945_msg1,
- pretty_otp4945_msg2,
- pretty_otp4945_msg3,
- pretty_otp4945_msg4,
- pretty_otp4945_msg5,
- pretty_otp4945_msg6,
- pretty_otp4949_msg1,
- pretty_otp4949_msg2,
- pretty_otp4949_msg3,
- pretty_otp5042_msg1,
- pretty_otp5068_msg1,
- pretty_otp5085_msg1,
- pretty_otp5085_msg2,
- pretty_otp5085_msg3,
- pretty_otp5085_msg4,
- pretty_otp5085_msg5,
- pretty_otp5085_msg6,
- pretty_otp5085_msg7,
- pretty_otp5085_msg8,
- pretty_otp5600_msg1,
- pretty_otp5600_msg2,
- pretty_otp5601_msg1,
- pretty_otp5793_msg01,
- pretty_otp5803_msg01,
- pretty_otp5803_msg02,
- pretty_otp5805_msg01,
- pretty_otp5836_msg01,
- pretty_otp5882_msg01,
- pretty_otp6490_msg01,
- pretty_otp6490_msg02,
- pretty_otp6490_msg03,
- pretty_otp6490_msg04,
- pretty_otp6490_msg05,
- pretty_otp6490_msg06,
- pretty_otp7671_msg01,
- pretty_otp7671_msg02,
- pretty_otp7671_msg03,
- pretty_otp7671_msg04,
- pretty_otp7671_msg05,
- pretty_otp8114_msg01
- ].
+flex_compact_tickets_cases() ->
+ [flex_compact_otp4299_msg1, flex_compact_otp7431_msg01,
+ flex_compact_otp7431_msg02, flex_compact_otp7431_msg03,
+ flex_compact_otp7431_msg04, flex_compact_otp7431_msg05,
+ flex_compact_otp7431_msg06, flex_compact_otp7431_msg07].
+
+flex_pretty_tickets_cases() ->
+ [flex_pretty_otp5042_msg1, flex_pretty_otp5085_msg1,
+ flex_pretty_otp5085_msg2, flex_pretty_otp5085_msg3,
+ flex_pretty_otp5085_msg4, flex_pretty_otp5085_msg5,
+ flex_pretty_otp5085_msg6, flex_pretty_otp5085_msg7,
+ flex_pretty_otp5085_msg8, flex_pretty_otp5600_msg1,
+ flex_pretty_otp5600_msg2, flex_pretty_otp5601_msg1,
+ flex_pretty_otp5793_msg01, flex_pretty_otp5803_msg01,
+ flex_pretty_otp5803_msg02, flex_pretty_otp5805_msg01,
+ flex_pretty_otp5836_msg01, flex_pretty_otp7431_msg01,
+ flex_pretty_otp7431_msg02, flex_pretty_otp7431_msg03,
+ flex_pretty_otp7431_msg04, flex_pretty_otp7431_msg05,
+ flex_pretty_otp7431_msg06, flex_pretty_otp7431_msg07].
+%% ----
-flex_pretty_tickets(suite) ->
- {req, [],
- {conf, flex_pretty_init, flex_pretty_tickets_cases(),
- flex_pretty_finish}}.
-
-flex_pretty_tickets_cases() ->
- [
- flex_pretty_otp5042_msg1,
- flex_pretty_otp5085_msg1,
- flex_pretty_otp5085_msg2,
- flex_pretty_otp5085_msg3,
- flex_pretty_otp5085_msg4,
- flex_pretty_otp5085_msg5,
- flex_pretty_otp5085_msg6,
- flex_pretty_otp5085_msg7,
- flex_pretty_otp5085_msg8,
- flex_pretty_otp5600_msg1,
- flex_pretty_otp5600_msg2,
- flex_pretty_otp5601_msg1,
- flex_pretty_otp5793_msg01,
- flex_pretty_otp5803_msg01,
- flex_pretty_otp5803_msg02,
- flex_pretty_otp5805_msg01,
- flex_pretty_otp5836_msg01,
- flex_pretty_otp7431_msg01,
- flex_pretty_otp7431_msg02,
- flex_pretty_otp7431_msg03,
- flex_pretty_otp7431_msg04,
- flex_pretty_otp7431_msg05,
- flex_pretty_otp7431_msg06,
- flex_pretty_otp7431_msg07
- ].
+tickets() ->
+ Flag = process_flag(trap_exit, true),
+ Cases = expand(tickets),
+ Fun = fun(Case) ->
+ C = init_per_testcase(Case, [{tc_timeout,
+ timer:minutes(10)}]),
+ io:format("Eval ~w~n", [Case]),
+ Result =
+ case (catch apply(?MODULE, Case, [C])) of
+ {'EXIT', Reason} ->
+ io:format("~n~p exited:~n ~p~n",
+ [Case, Reason]),
+ {error, {Case, Reason}};
+ Res ->
+ Res
+ end,
+ end_per_testcase(Case, C),
+ Result
+ end,
+ process_flag(trap_exit, Flag),
+ lists:map(Fun, Cases).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_config_test.erl b/lib/megaco/test/megaco_config_test.erl
index 9ab1a7d90d..1fc4d09d3b 100644
--- a/lib/megaco/test/megaco_config_test.erl
+++ b/lib/megaco/test/megaco_config_test.erl
@@ -44,9 +44,9 @@ do_init_per_testcase(Case, Config) ->
process_flag(trap_exit, true),
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
process_flag(trap_exit, false),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
-record(command, {id, desc, cmd, verify}).
@@ -58,25 +58,21 @@ fin_per_testcase(Case, Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(suite) ->
- [
- config,
- transaction_id_counter,
- tickets
- ].
-
-transaction_id_counter(suite) ->
- [
- transaction_id_counter_mg,
- transaction_id_counter_mgc
- ].
-
-tickets(suite) ->
- [
- otp_7216,
- otp_8167,
- otp_8183
- ].
+all() ->
+ [config, {group, transaction_id_counter},
+ {group, tickets}].
+
+groups() ->
+ [{transaction_id_counter, [],
+ [transaction_id_counter_mg,
+ transaction_id_counter_mgc]},
+ {tickets, [], [otp_7216, otp_8167, otp_8183]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_digit_map_test.erl b/lib/megaco/test/megaco_digit_map_test.erl
index 22e115278f..d16fb679ae 100644
--- a/lib/megaco/test/megaco_digit_map_test.erl
+++ b/lib/megaco/test/megaco_digit_map_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -36,54 +36,39 @@ t(Case) -> megaco_test_lib:t({?MODULE, Case}).
init_per_testcase(Case, Config) ->
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- tickets
- ],
- Cases.
+all() ->
+ [{group, tickets}].
+
+groups() ->
+ [{tickets, [],
+ [{group, otp_5750}, {group, otp_5799},
+ {group, otp_5826}, {group, otp_7449}]},
+ {otp_5750, [], [otp_5750_01, otp_5750_02]},
+ {otp_5799, [], [otp_5799_01]},
+ {otp_5826, [], [otp_5826_01, otp_5826_02, otp_5826_03]},
+ {otp_7449, [], [otp_7449_1, otp_7449_2]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-tickets(suite) ->
- [
- otp_5750,
- otp_5799,
- otp_5826,
- otp_7449
- ].
-
-
-otp_5750(suite) ->
- [
- otp_5750_01,
- otp_5750_02
- ].
-
-otp_5799(suite) ->
- [
- otp_5799_01
- ].
-
-otp_5826(suite) ->
- [
- otp_5826_01,
- otp_5826_02,
- otp_5826_03
- ].
-
-otp_7449(suite) ->
- [
- otp_7449_1,
- otp_7449_2
- ].
+
+
+
+
+
diff --git a/lib/megaco/test/megaco_examples_test.erl b/lib/megaco/test/megaco_examples_test.erl
index ef15cb1bde..528b61c2af 100644
--- a/lib/megaco/test/megaco_examples_test.erl
+++ b/lib/megaco/test/megaco_examples_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -41,11 +41,11 @@ init_per_testcase(Case, Config) ->
megaco:enable_trace(max, io),
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
purge_examples(),
erase(dbg),
megaco:disable_trace(),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
example_modules() ->
[megaco_simple_mg, megaco_simple_mgc].
@@ -70,13 +70,18 @@ purge_examples() ->
%% Top test case
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Run all examples mentioned in the documentation",
- "Are really all examples covered?"];
-all(suite) ->
- [
- simple
- ].
+all() ->
+ [simple].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
simple(suite) ->
[];
diff --git a/lib/megaco/test/megaco_flex_test.erl b/lib/megaco/test/megaco_flex_test.erl
index 3dbcf53e7a..d7fc8eacb5 100644
--- a/lib/megaco/test/megaco_flex_test.erl
+++ b/lib/megaco/test/megaco_flex_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -32,10 +32,10 @@
-export([
t/0, t/1,
- init_per_testcase/2, fin_per_testcase/2,
+ init_per_testcase/2, end_per_testcase/2,
- all/1,
- flex_init/1, flex_fin/1,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
plain/1,
port_exit/1,
@@ -55,26 +55,31 @@ t(Case) -> megaco_test_lib:t({?MODULE, Case}).
init_per_testcase(Case, Config) ->
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- plain,
- port_exit,
- garbage_in
- ],
- {req, [], {conf, flex_init, Cases, flex_fin}}.
+all() ->
+ [plain, port_exit, garbage_in].
-flex_init(suite) ->
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(suite) ->
[];
-flex_init(doc) ->
+init_per_suite(doc) ->
[];
-flex_init(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
case megaco_flex_scanner:is_enabled() of
true ->
Config;
@@ -82,9 +87,9 @@ flex_init(Config) when is_list(Config) ->
?SKIP(flex_scanner_not_enabled)
end.
-flex_fin(suite) -> [];
-flex_fin(doc) -> [];
-flex_fin(Config) when is_list(Config) ->
+end_per_suite(suite) -> [];
+end_per_suite(doc) -> [];
+end_per_suite(Config) when is_list(Config) ->
Config.
diff --git a/lib/megaco/test/megaco_load_test.erl b/lib/megaco/test/megaco_load_test.erl
index 5a22b7b4ee..5519ca15c6 100644
--- a/lib/megaco/test/megaco_load_test.erl
+++ b/lib/megaco/test/megaco_load_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -99,26 +99,29 @@ do_init_per_testcase(Case, Config) ->
process_flag(trap_exit, true),
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
process_flag(trap_exit, false),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- single_user_light_load,
- single_user_medium_load,
- single_user_heavy_load,
- single_user_extreme_load,
- multi_user_light_load,
- multi_user_medium_load,
- multi_user_heavy_load,
- multi_user_extreme_load
- ],
- Cases.
+all() ->
+ [single_user_light_load,
+ single_user_medium_load, single_user_heavy_load,
+ single_user_extreme_load, multi_user_light_load,
+ multi_user_medium_load, multi_user_heavy_load,
+ multi_user_extreme_load].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_mess_otp8212_test.erl b/lib/megaco/test/megaco_mess_otp8212_test.erl
index 109886ebc4..e074e2f0b3 100644
--- a/lib/megaco/test/megaco_mess_otp8212_test.erl
+++ b/lib/megaco/test/megaco_mess_otp8212_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% 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
diff --git a/lib/megaco/test/megaco_mess_test.erl b/lib/megaco/test/megaco_mess_test.erl
index 368800fa54..ded1506271 100644
--- a/lib/megaco/test/megaco_mess_test.erl
+++ b/lib/megaco/test/megaco_mess_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -34,13 +34,13 @@
%% -compile(export_all).
-export([
- all/1,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
+ end_per_testcase/2,
connect/1,
- request_and_reply/1,
+
request_and_reply_plain/1,
request_and_no_reply/1,
request_and_reply_pending_ack_no_pending/1,
@@ -52,13 +52,13 @@
request_and_reply_and_late_ack/1,
trans_req_and_reply_and_req/1,
- pending_ack/1,
+
pending_ack_plain/1,
request_and_pending_and_late_reply/1,
dist/1,
- tickets/1,
+
otp_4359/1,
otp_4836/1,
otp_5805/1,
@@ -67,18 +67,18 @@
otp_6253/1,
otp_6275/1,
otp_6276/1,
- otp_6442/1,
+
otp_6442_resend_request1/1,
otp_6442_resend_request2/1,
otp_6442_resend_reply1/1,
otp_6442_resend_reply2/1,
- otp_6865/1,
+
otp_6865_request_and_reply_plain_extra1/1,
otp_6865_request_and_reply_plain_extra2/1,
otp_7189/1,
otp_7259/1,
otp_7713/1,
- otp_8183/1,
+
otp_8183_request1/1,
otp_8212/1
]).
@@ -337,83 +337,50 @@ init_per_testcase(Case, Config) ->
C = lists:keydelete(tc_timeout, 1, Config),
megaco_test_lib:init_per_testcase(Case, [{tc_timeout, min(1)} |C]).
-% fin_per_testcase(pending_ack = Case, Config) ->
+% end_per_testcase(pending_ack = Case, Config) ->
% erase(dbg),
-% megaco_test_lib:fin_per_testcase(Case, Config);
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+% megaco_test_lib:end_per_testcase(Case, Config);
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- [
- connect,
- request_and_reply,
- pending_ack,
- dist,
-
- %% Tickets last
- tickets
- ].
-
-request_and_reply(suite) ->
- [
- request_and_reply_plain,
- request_and_no_reply,
- request_and_reply_pending_ack_no_pending,
- request_and_reply_pending_ack_one_pending,
- single_trans_req_and_reply,
- single_trans_req_and_reply_sendopts,
- request_and_reply_and_ack,
- request_and_reply_and_no_ack,
- request_and_reply_and_late_ack,
- trans_req_and_reply_and_req
- ].
-
-pending_ack(suite) ->
- [
- pending_ack_plain,
- request_and_pending_and_late_reply
- ].
-
-tickets(suite) ->
- [
- otp_4359,
- otp_4836,
- otp_5805,
- otp_5881,
- otp_5887,
- otp_6253,
- otp_6275,
- otp_6276,
- otp_6442,
- otp_6865,
- otp_7189,
- otp_7259,
- otp_7713,
- otp_8183,
- otp_8212
- ].
-
-otp_6442(suite) ->
- [
- otp_6442_resend_request1,
- otp_6442_resend_request2,
- otp_6442_resend_reply1,
- otp_6442_resend_reply2
- ].
-
-otp_6865(suite) ->
- [
- otp_6865_request_and_reply_plain_extra1,
- otp_6865_request_and_reply_plain_extra2
- ].
-
-otp_8183(suite) ->
- [
- otp_8183_request1
- ].
+all() ->
+ [connect, {group, request_and_reply},
+ {group, pending_ack}, dist, {group, tickets}].
+
+groups() ->
+ [{request_and_reply, [],
+ [request_and_reply_plain, request_and_no_reply,
+ request_and_reply_pending_ack_no_pending,
+ request_and_reply_pending_ack_one_pending,
+ single_trans_req_and_reply,
+ single_trans_req_and_reply_sendopts,
+ request_and_reply_and_ack, request_and_reply_and_no_ack,
+ request_and_reply_and_late_ack,
+ trans_req_and_reply_and_req]},
+ {pending_ack, [],
+ [pending_ack_plain,
+ request_and_pending_and_late_reply]},
+ {tickets, [],
+ [otp_4359, otp_4836, otp_5805, otp_5881, otp_5887,
+ otp_6253, otp_6275, otp_6276, {group, otp_6442},
+ {group, otp_6865}, otp_7189, otp_7259, otp_7713,
+ {group, otp_8183}, otp_8212]},
+ {otp_6442, [],
+ [otp_6442_resend_request1, otp_6442_resend_request2,
+ otp_6442_resend_reply1, otp_6442_resend_reply2]},
+ {otp_6865, [],
+ [otp_6865_request_and_reply_plain_extra1,
+ otp_6865_request_and_reply_plain_extra2]},
+ {otp_8183, [], [otp_8183_request1]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_mess_user_test.erl b/lib/megaco/test/megaco_mess_user_test.erl
index 50284be549..ce682c167b 100644
--- a/lib/megaco/test/megaco_mess_user_test.erl
+++ b/lib/megaco/test/megaco_mess_user_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/megaco/test/megaco_mib_test.erl b/lib/megaco/test/megaco_mib_test.erl
index 2da6aa3bf3..52d99d1442 100644
--- a/lib/megaco/test/megaco_mib_test.erl
+++ b/lib/megaco/test/megaco_mib_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-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
@@ -63,21 +63,25 @@ init_per_testcase(Case, Config) ->
megaco_test_lib:init_per_testcase(Case, Config)
end.
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
process_flag(trap_exit, false),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- plain,
- connect,
- traffic
- ],
- Cases.
+all() ->
+ [plain, connect, traffic].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_mreq_test.erl b/lib/megaco/test/megaco_mreq_test.erl
index 676acd8a12..1d3f38d50d 100644
--- a/lib/megaco/test/megaco_mreq_test.erl
+++ b/lib/megaco/test/megaco_mreq_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -69,20 +69,24 @@ init_per_testcase(Case, Config) ->
process_flag(trap_exit, true),
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
process_flag(trap_exit, false),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- req_and_rep,
- req_and_pending,
- req_and_cancel
- ],
- Cases.
+all() ->
+ [req_and_rep, req_and_pending, req_and_cancel].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_pending_limit_test.erl b/lib/megaco/test/megaco_pending_limit_test.erl
index 1ca29c195c..233c22f4d2 100644
--- a/lib/megaco/test/megaco_pending_limit_test.erl
+++ b/lib/megaco/test/megaco_pending_limit_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,22 +26,16 @@
-module(megaco_pending_limit_test).
-export([t/0, t/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
--export([all/1,
-
- sent/1,
+-export([init_per_testcase/2, end_per_testcase/2]).
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
sent_timer_late_reply/1,
sent_timer_exceeded/1,
sent_timer_exceeded_long/1,
sent_resend_late_reply/1,
sent_resend_exceeded/1,
sent_resend_exceeded_long/1,
-
- recv/1,
recv_limit_exceeded1/1,
recv_limit_exceeded2/1,
-
- tickets/1,
otp_4956/1,
otp_5310/1,
otp_5619/1
@@ -139,45 +133,29 @@ init_per_testcase(Case, Config) ->
process_flag(trap_exit, true),
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
process_flag(trap_exit, false),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- [
- sent,
- recv,
-
- %% Tickets last
- tickets
- ].
-
-sent(suite) ->
- [
- sent_timer_late_reply,
- sent_timer_exceeded,
- sent_timer_exceeded_long,
- sent_resend_late_reply,
- sent_resend_exceeded,
- sent_resend_exceeded_long
-
- ].
+all() ->
+ [{group, sent}, {group, recv}, {group, tickets}].
-recv(suite) ->
- [
- recv_limit_exceeded1,
- recv_limit_exceeded2
- ].
+groups() ->
+ [{sent, [],
+ [sent_timer_late_reply, sent_timer_exceeded,
+ sent_timer_exceeded_long, sent_resend_late_reply,
+ sent_resend_exceeded, sent_resend_exceeded_long]},
+ {recv, [],
+ [recv_limit_exceeded1, recv_limit_exceeded2]},
+ {tickets, [], [otp_4956, otp_5310, otp_5619]}].
-tickets(suite) ->
- [
- otp_4956,
- otp_5310,
- otp_5619
- ].
+init_per_group(_GroupName, Config) ->
+ Config.
+end_per_group(_GroupName, Config) ->
+ Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% %%%
diff --git a/lib/megaco/test/megaco_profile.erl b/lib/megaco/test/megaco_profile.erl
index 01fa0b5a14..d0b62610e1 100644
--- a/lib/megaco/test/megaco_profile.erl
+++ b/lib/megaco/test/megaco_profile.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/megaco/test/megaco_sdp_test.erl b/lib/megaco/test/megaco_sdp_test.erl
index e9bd550518..796a956f23 100644
--- a/lib/megaco/test/megaco_sdp_test.erl
+++ b/lib/megaco/test/megaco_sdp_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -24,13 +24,12 @@
-module(megaco_sdp_test).
--export([all/1,
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
decode_encode/1,
- tickets/1,
otp8123/1,
- init_per_testcase/2, fin_per_testcase/2,
+ init_per_testcase/2, end_per_testcase/2,
t/0, t/1]).
@@ -46,8 +45,8 @@ t(Case) -> megaco_test_lib:t({?MODULE, Case}).
init_per_testcase(Case, Config) ->
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -55,16 +54,19 @@ fin_per_testcase(Case, Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- [
- decode_encode,
- tickets
- ].
+all() ->
+ [decode_encode, {group, tickets}].
+
+groups() ->
+ [{tickets, [], [otp8123]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-tickets(suite) ->
- [
- otp8123
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_segment_test.erl b/lib/megaco/test/megaco_segment_test.erl
index ef07ee54b1..e4b568119d 100644
--- a/lib/megaco/test/megaco_segment_test.erl
+++ b/lib/megaco/test/megaco_segment_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -24,10 +24,10 @@
-module(megaco_segment_test).
-export([t/0, t/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
--export([all/1,
+-export([init_per_testcase/2, end_per_testcase/2]).
+-export([all/0,groups/0,init_per_group/2,end_per_group/2,
- send/1,
+
send_segmented_msg_plain1/1,
send_segmented_msg_plain2/1,
send_segmented_msg_plain3/1,
@@ -36,13 +36,11 @@
send_segmented_msg_missing_seg_reply1/1,
send_segmented_msg_missing_seg_reply2/1,
- recv/1,
+
recv_segmented_msg_plain/1,
recv_segmented_msg_ooo_seg/1,
recv_segmented_msg_missing_seg1/1,
- recv_segmented_msg_missing_seg2/1,
-
- tickets/1
+ recv_segmented_msg_missing_seg2/1
]).
@@ -66,45 +64,33 @@ init_per_testcase(Case, Config) ->
process_flag(trap_exit, true),
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
process_flag(trap_exit, false),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- [
- send,
- recv
-
- %% Tickets last
- %% tickets
- ].
-
-send(suite) ->
- [
- send_segmented_msg_plain1,
- send_segmented_msg_plain2,
- send_segmented_msg_plain3,
- send_segmented_msg_plain4,
- send_segmented_msg_ooo1,
- send_segmented_msg_missing_seg_reply1,
- send_segmented_msg_missing_seg_reply2
- ].
-
-recv(suite) ->
- [
- recv_segmented_msg_plain,
- recv_segmented_msg_ooo_seg,
- recv_segmented_msg_missing_seg1,
- recv_segmented_msg_missing_seg2
- ].
-
-tickets(suite) ->
- [
- ].
-
+all() ->
+ [{group, send}, {group, recv}].
+
+groups() ->
+ [{send, [],
+ [send_segmented_msg_plain1, send_segmented_msg_plain2,
+ send_segmented_msg_plain3, send_segmented_msg_plain4,
+ send_segmented_msg_ooo1,
+ send_segmented_msg_missing_seg_reply1,
+ send_segmented_msg_missing_seg_reply2]},
+ {recv, [],
+ [recv_segmented_msg_plain, recv_segmented_msg_ooo_seg,
+ recv_segmented_msg_missing_seg1,
+ recv_segmented_msg_missing_seg2]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_tc_controller.erl b/lib/megaco/test/megaco_tc_controller.erl
index dedf45e321..458bff55e8 100644
--- a/lib/megaco/test/megaco_tc_controller.erl
+++ b/lib/megaco/test/megaco_tc_controller.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/megaco/test/megaco_tcp_test.erl b/lib/megaco/test/megaco_tcp_test.erl
index 31c88489fe..013096c385 100644
--- a/lib/megaco/test/megaco_tcp_test.erl
+++ b/lib/megaco/test/megaco_tcp_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -36,25 +36,19 @@
%% External exports
%%----------------------------------------------------------------------
-export([
- all/1,
-
- start/1,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
start_normal/1,
start_invalid_opt/1,
start_and_stop/1,
-
- sending/1,
sendreceive/1,
block_unblock/1,
-
- errors/1,
socket_failure/1,
accept_process/1,
accept_supervisor/1,
connection_supervisor/1,
tcp_server/1,
- init_per_testcase/2, fin_per_testcase/2,
+ init_per_testcase/2, end_per_testcase/2,
t/0, t/1
]).
@@ -111,44 +105,32 @@ init_per_testcase(Case, Config) ->
%%----------------------------------------------------------------------
-%% Function: fin_per_testcase/2
+%% Function: end_per_testcase/2
%% Description:
%%----------------------------------------------------------------------
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
%%======================================================================
%% Test case definitions
%%======================================================================
-all(suite) ->
- [
- start,
- sending,
- errors
- ].
-
-start(suite) ->
- [
- start_normal,
- start_invalid_opt,
- start_and_stop
- ].
-
-sending(suite) ->
- [
- sendreceive,
- block_unblock
- ].
-
-errors(suite) ->
- [
- socket_failure,
- accept_process,
- accept_supervisor,
- connection_supervisor,
- tcp_server
- ].
+all() ->
+ [{group, start}, {group, sending}, {group, errors}].
+
+groups() ->
+ [{start, [],
+ [start_normal, start_invalid_opt, start_and_stop]},
+ {sending, [], [sendreceive, block_unblock]},
+ {errors, [],
+ [socket_failure, accept_process, accept_supervisor,
+ connection_supervisor, tcp_server]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%% ------------------ start ------------------------
diff --git a/lib/megaco/test/megaco_test_deliver.erl b/lib/megaco/test/megaco_test_deliver.erl
index 2d0f0c1cbe..ece0a48015 100644
--- a/lib/megaco/test/megaco_test_deliver.erl
+++ b/lib/megaco/test/megaco_test_deliver.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/megaco/test/megaco_test_generator.erl b/lib/megaco/test/megaco_test_generator.erl
index 8bbc60e6cd..4fbc86262e 100644
--- a/lib/megaco/test/megaco_test_generator.erl
+++ b/lib/megaco/test/megaco_test_generator.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,6 +26,10 @@
-behaviour(gen_server).
+-compile({no_auto_import,[error/2]}).
+
+%% ----
+
-export([
start_link/3,
start_link/4,
diff --git a/lib/megaco/test/megaco_test_generator_lib.erl b/lib/megaco/test/megaco_test_generator_lib.erl
index cf0dcaf722..1584605913 100644
--- a/lib/megaco/test/megaco_test_generator_lib.erl
+++ b/lib/megaco/test/megaco_test_generator_lib.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/megaco/test/megaco_test_generic_transport.erl b/lib/megaco/test/megaco_test_generic_transport.erl
index 10afa45baa..7a3dbc5317 100644
--- a/lib/megaco/test/megaco_test_generic_transport.erl
+++ b/lib/megaco/test/megaco_test_generic_transport.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/megaco/test/megaco_test_lib.erl b/lib/megaco/test/megaco_test_lib.erl
index 03c04831e8..41f6c2c4cb 100644
--- a/lib/megaco/test/megaco_test_lib.erl
+++ b/lib/megaco/test/megaco_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -146,28 +146,28 @@ tickets(Mod, Func, Config) ->
end,
lists:map(Map, Cases);
- {req, _, {conf, Init, Cases, Finish}} ->
- case (catch Mod:Init(Config)) of
- Conf when is_list(Conf) ->
- io:format("Expand: ~p:~p ...~n", [Mod, Func]),
- Map = fun({M,_}) when is_atom(M) ->
- tickets(M, tickets, Config);
- (F) when is_atom(F) ->
- tickets(Mod, F, Config);
- (Case) -> Case
- end,
- Res = lists:map(Map, Cases),
- (catch Mod:Finish(Conf)),
- Res;
+%% {req, _, {conf, Init, Cases, Finish}} ->
+%% case (catch Mod:Init(Config)) of
+%% Conf when is_list(Conf) ->
+%% io:format("Expand: ~p:~p ...~n", [Mod, Func]),
+%% Map = fun({M,_}) when is_atom(M) ->
+%% tickets(M, tickets, Config);
+%% (F) when is_atom(F) ->
+%% tickets(Mod, F, Config);
+%% (Case) -> Case
+%% end,
+%% Res = lists:map(Map, Cases),
+%% (catch Mod:Finish(Conf)),
+%% Res;
- {'EXIT', {skipped, Reason}} ->
- io:format(" => skipping: ~p~n", [Reason]),
- [{skipped, {Mod, Func}, Reason}];
+%% {'EXIT', {skipped, Reason}} ->
+%% io:format(" => skipping: ~p~n", [Reason]),
+%% [{skipped, {Mod, Func}, Reason}];
- Error ->
- io:format(" => init failed: ~p~n", [Error]),
- [{failed, {Mod, Func}, Error}]
- end;
+%% Error ->
+%% io:format(" => init failed: ~p~n", [Error]),
+%% [{failed, {Mod, Func}, Error}]
+%% end;
{'EXIT', {undef, _}} ->
io:format("Undefined: ~p~n", [{Mod, Func}]),
@@ -252,6 +252,8 @@ alloc_instance_mem_info(Key, InstanceInfo) ->
end.
+t([Case]) when is_atom(Case) ->
+ t(Case);
t(Case) ->
process_flag(trap_exit, true),
MEM = fun() -> case (catch erlang:memory()) of
@@ -266,11 +268,65 @@ t(Case) ->
Res = lists:flatten(t(Case, default_config())),
Alloc2 = alloc_info(),
Mem2 = MEM(),
- %% io:format("Res: ~p~n", [Res]),
display_result(Res, Alloc1, Mem1, Alloc2, Mem2),
Res.
-t({Mod, Fun}, Config) when is_atom(Mod) andalso is_atom(Fun) ->
+
+groups(Mod) when is_atom(Mod) ->
+ try Mod:groups() of
+ Groups when is_list(Groups) ->
+ Groups;
+ BadGroups ->
+ exit({bad_groups, Mod, BadGroups})
+ catch
+ _:_ ->
+ []
+ end.
+
+init_suite(Mod, Config) ->
+ Mod:init_per_suite(Config).
+
+end_suite(Mod, Config) ->
+ Mod:end_per_suite(Config).
+
+init_group(Mod, Group, Config) ->
+ Mod:init_per_group(Group, Config).
+
+end_group(Mod, Group, Config) ->
+ Mod:init_per_group(Group, Config).
+
+%% This is for sub-SUITEs
+t({_Mod, {NewMod, all}, _Groups}, _Config) when is_atom(NewMod) ->
+ t(NewMod);
+t({Mod, {group, Name} = Group, Groups}, Config)
+ when is_atom(Mod) andalso is_atom(Name) andalso is_list(Groups) ->
+ case lists:keysearch(Name, 1, Groups) of
+ {value, {Name, _Props, GroupsAndCases}} ->
+ try init_group(Mod, Name, Config) of
+ Config2 when is_list(Config2) ->
+ Res = [t({Mod, Case, Groups}, Config2) ||
+ Case <- GroupsAndCases],
+ (catch end_group(Mod, Name, Config2)),
+ Res;
+ Error ->
+ io:format(" => group (~w) init failed: ~p~n",
+ [Name, Error]),
+ [{failed, {Mod, Group}, Error}]
+ catch
+ exit:{skipped, SkipReason} ->
+ io:format(" => skipping group: ~p~n", [SkipReason]),
+ [{skipped, {Mod, Group}, SkipReason, 0}];
+ exit:{undef, _} ->
+ [t({Mod, Case, Groups}, Config) ||
+ Case <- GroupsAndCases];
+ T:E ->
+ [{failed, {Mod, Group}, {T,E}, 0}]
+ end;
+ false ->
+ exit({unknown_group, Mod, Name, Groups})
+ end;
+t({Mod, Fun, _}, Config)
+ when is_atom(Mod) andalso is_atom(Fun) ->
case catch apply(Mod, Fun, [suite]) of
[] ->
io:format("Eval: ~p:", [{Mod, Fun}]),
@@ -286,26 +342,6 @@ t({Mod, Fun}, Config) when is_atom(Mod) andalso is_atom(Fun) ->
end,
t(lists:map(Map, Cases), Config);
- {req, _, {conf, Init, Cases, Finish}} ->
- case (catch apply(Mod, Init, [Config])) of
- Conf when is_list(Conf) ->
- io:format("Expand: ~p ...~n", [{Mod, Fun}]),
- Map = fun(Case) when is_atom(Case) -> {Mod, Case};
- (Case) -> Case
- end,
- Res = t(lists:map(Map, Cases), Conf),
- (catch apply(Mod, Finish, [Conf])),
- Res;
-
- {'EXIT', {skipped, Reason}} ->
- io:format(" => skipping: ~p~n", [Reason]),
- [{skipped, {Mod, Fun}, Reason, 0}];
-
- Error ->
- io:format(" => failed: ~p~n", [Error]),
- [{failed, {Mod, Fun}, Error, 0}]
- end;
-
{'EXIT', {undef, _}} ->
io:format("Undefined: ~p~n", [{Mod, Fun}]),
[{nyi, {Mod, Fun}, ok, 0}];
@@ -315,10 +351,38 @@ t({Mod, Fun}, Config) when is_atom(Mod) andalso is_atom(Fun) ->
[{failed, {Mod, Fun}, Error, 0}]
end;
t(Mod, Config) when is_atom(Mod) ->
- Res = t({Mod, all}, Config),
- Res;
-t(Cases, Config) when is_list(Cases) ->
- [t(Case, Config) || Case <- Cases];
+ %% This is assumed to be a test suite, so we start by calling
+ %% the top test suite function(s) (all/0 and groups/0).
+ case (catch Mod:all()) of
+ Cases when is_list(Cases) ->
+ %% The list may contain atoms (actual test cases) and
+ %% group-tuples (a tuple naming a group of test cases).
+ %% A group is defined by the (optional) groups/0 function.
+ Groups = groups(Mod),
+ try init_suite(Mod, Config) of
+ Config2 when is_list(Config2) ->
+ Res = [t({Mod, Case, Groups}, Config2) || Case <- Cases],
+ (catch end_suite(Mod, Config2)),
+ Res;
+ Error ->
+ io:format(" => suite init failed: ~p~n", [Error]),
+ [{failed, {Mod, init_per_suite}, Error}]
+ catch
+ exit:{skipped, SkipReason} ->
+ io:format(" => skipping suite: ~p~n", [SkipReason]),
+ [{skipped, {Mod, init_per_suite}, SkipReason, 0}];
+ exit:{undef, _} ->
+ [t({Mod, Case, Groups}, Config) || Case <- Cases];
+ T:E ->
+ [{failed, {Mod, init_per_suite}, {T,E}, 0}]
+ end;
+ {'EXIT', {undef, _}} ->
+ io:format("Undefined: ~p~n", [{Mod, all}]),
+ [{nyi, {Mod, all}, ok, 0}];
+
+ Crap ->
+ Crap
+ end;
t(Bad, _Config) ->
[{badarg, Bad, ok, 0}].
@@ -333,7 +397,7 @@ eval(Mod, Fun, Config) ->
Config2 = Mod:init_per_testcase(Fun, Config),
Pid = spawn_link(?MODULE, do_eval, [self(), Mod, Fun, Config2]),
R = wait_for_evaluator(Pid, Mod, Fun, Config2, []),
- Mod:fin_per_testcase(Fun, Config2),
+ Mod:end_per_testcase(Fun, Config2),
erase(megaco_test_server),
global:unregister_name(megaco_test_case_sup),
process_flag(trap_exit, Flag),
@@ -495,28 +559,56 @@ do_display_memory([{Key, Mem1}|MemInfo1], MemInfo2) ->
display_result([]) ->
io:format("OK~n", []);
display_result(Res) when is_list(Res) ->
- Ok = [{MF, Time} || {ok, MF, _, Time} <- Res],
- Nyi = [MF || {nyi, MF, _, _Time} <- Res],
- Skipped = [{MF, Reason} || {skipped, MF, Reason, _Time} <- Res],
- Failed = [{MF, Reason} || {failed, MF, Reason, _Time} <- Res],
- Crashed = [{MF, Reason} || {crashed, MF, Reason, _Time} <- Res],
- display_summery(Ok, Nyi, Skipped, Failed, Crashed),
+ Ok = [{MF, Time} || {ok, MF, _, Time} <- Res],
+ Nyi = [MF || {nyi, MF, _, _Time} <- Res],
+ SkippedGrps = [{{M,G}, Reason} ||
+ {skipped, {M, {group, G}}, Reason, _Time} <- Res],
+ SkippedCases = [{MF, Reason} ||
+ {skipped, {_M, F} = MF, Reason, _Time} <- Res,
+ is_atom(F)],
+ FailedGrps = [{{M,G}, Reason} ||
+ {failed, {M, {group, G}}, Reason, _Time} <- Res],
+ FailedCases = [{MF, Reason} ||
+ {failed, {_M, F} = MF, Reason, _Time} <- Res,
+ is_atom(F)],
+ Crashed = [{MF, Reason} || {crashed, MF, Reason, _Time} <- Res],
+ display_summery(Ok, Nyi,
+ SkippedGrps, SkippedCases,
+ FailedGrps, FailedCases,
+ Crashed),
display_ok(Ok),
- display_skipped(Skipped),
- display_failed(Failed),
+ display_skipped("groups", SkippedGrps),
+ display_skipped("test cases", SkippedCases),
+ display_failed("groups", FailedGrps),
+ display_failed("test cases", FailedCases),
display_crashed(Crashed).
-display_summery(Ok, Nyi, Skipped, Failed, Crashed) ->
+display_summery(Ok, Nyi,
+ SkippedGrps, SkippedCases,
+ FailedGrps, FailedCases,
+ Crashed) ->
io:format("~nTest case summery:~n", []),
- display_summery(Ok, "successfull"),
- display_summery(Nyi, "not yet implemented"),
- display_summery(Skipped, "skipped"),
- display_summery(Failed, "failed"),
- display_summery(Crashed, "crashed"),
+ display_summery(Ok, "test case", "successfull"),
+ display_summery(Nyi, "test case", "not yet implemented"),
+ display_summery(SkippedGrps, "group", "skipped"),
+ display_summery(SkippedCases, "test case", "skipped"),
+ display_summery(FailedGrps, "group", "failed"),
+ display_summery(FailedCases, "test case", "failed"),
+ display_summery(Crashed, "test case", "crashed"),
io:format("~n", []).
-display_summery(Res, Info) ->
- io:format(" ~w test cases ~s~n", [length(Res), Info]).
+
+display_summery(Res, Kind, Info) ->
+ Len = length(Res),
+ if
+ Len =:= 1 ->
+ display_summery(Len, Kind ++ " " ++ Info);
+ true ->
+ display_summery(Len, Kind ++ "s " ++ Info)
+ end.
+
+display_summery(Len, Info) ->
+ io:format(" ~w ~s~n", [Len, Info]).
display_ok([]) ->
ok;
@@ -528,20 +620,20 @@ display_ok(Ok) ->
lists:foreach(F, Ok),
io:format("~n", []).
-display_skipped([]) ->
+display_skipped(_, []) ->
ok;
-display_skipped(Skipped) ->
- io:format("Skipped test cases:~n", []),
- F = fun({MF, Reason}) -> io:format(" ~p => ~p~n", [MF, Reason]) end,
+display_skipped(Pre, Skipped) ->
+ io:format("Skipped ~s:~n", [Pre]),
+ F = fun({X, Reason}) -> io:format(" ~p => ~p~n", [X, Reason]) end,
lists:foreach(F, Skipped),
io:format("~n", []).
-display_failed([]) ->
+display_failed(_, []) ->
ok;
-display_failed(Failed) ->
- io:format("Failed test cases:~n", []),
- F = fun({MF, Reason}) -> io:format(" ~p => ~p~n", [MF, Reason]) end,
+display_failed(Pre, Failed) ->
+ io:format("Failed ~s:~n", [Pre]),
+ F = fun({X, Reason}) -> io:format(" ~p => ~p~n", [X, Reason]) end,
lists:foreach(F, Failed),
io:format("~n", []).
@@ -677,11 +769,11 @@ init_per_testcase(_Case, Config) ->
end,
set_kill_timer(Config).
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Name = megaco_global_logger,
case global:whereis_name(Name) of
undefined ->
- io:format("~w:fin_per_testcase -> already un-registered~n",
+ io:format("~w:end_per_testcase -> already un-registered~n",
[?MODULE]),
ok;
Pid when is_pid(Pid) ->
@@ -837,5 +929,5 @@ start_nodes([Node | Nodes], File, Line) ->
start_nodes([], _File, _Line) ->
ok.
-p(F,A) ->
- io:format("~p" ++ F ++ "~n", [self()|A]).
+p(F, A) ->
+ io:format("~p~w:" ++ F ++ "~n", [self(), ?MODULE |A]).
diff --git a/lib/megaco/test/megaco_test_megaco_generator.erl b/lib/megaco/test/megaco_test_megaco_generator.erl
index 5ff7162223..f0c723d2cf 100644
--- a/lib/megaco/test/megaco_test_megaco_generator.erl
+++ b/lib/megaco/test/megaco_test_megaco_generator.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,6 +26,8 @@
-behaviour(megaco_test_generator).
+-compile({no_auto_import,[error/1]}).
+
%% API
-export([
start_link/1, start_link/2,
diff --git a/lib/megaco/test/megaco_test_mg.erl b/lib/megaco/test/megaco_test_mg.erl
index 22b65a1ac6..ecb3cedc83 100644
--- a/lib/megaco/test/megaco_test_mg.erl
+++ b/lib/megaco/test/megaco_test_mg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/megaco/test/megaco_test_mgc.erl b/lib/megaco/test/megaco_test_mgc.erl
index 05c482f1af..13c1cebe56 100644
--- a/lib/megaco/test/megaco_test_mgc.erl
+++ b/lib/megaco/test/megaco_test_mgc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/megaco/test/megaco_test_msg_prev3a_lib.erl b/lib/megaco/test/megaco_test_msg_prev3a_lib.erl
index 5ce2ec302b..fad7f29831 100644
--- a/lib/megaco/test/megaco_test_msg_prev3a_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_prev3a_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,6 +26,10 @@
%% ----
+-compile({no_auto_import,[error/1]}).
+
+%% ----
+
-include_lib("megaco/include/megaco_message_prev3a.hrl").
-include_lib("megaco/include/megaco.hrl").
diff --git a/lib/megaco/test/megaco_test_msg_prev3b_lib.erl b/lib/megaco/test/megaco_test_msg_prev3b_lib.erl
index be87dc9a41..2f1a093728 100644
--- a/lib/megaco/test/megaco_test_msg_prev3b_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_prev3b_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,6 +26,10 @@
%% ----
+-compile({no_auto_import,[error/1]}).
+
+%% ----
+
-include_lib("megaco/include/megaco_message_prev3b.hrl").
-include_lib("megaco/include/megaco.hrl").
diff --git a/lib/megaco/test/megaco_test_msg_prev3c_lib.erl b/lib/megaco/test/megaco_test_msg_prev3c_lib.erl
index 74a05060d0..884e2f2bad 100644
--- a/lib/megaco/test/megaco_test_msg_prev3c_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_prev3c_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,6 +26,10 @@
%% ----
+-compile({no_auto_import,[error/1]}).
+
+%% ----
+
-include_lib("megaco/include/megaco_message_prev3c.hrl").
-include_lib("megaco/include/megaco.hrl").
diff --git a/lib/megaco/test/megaco_test_msg_v1_lib.erl b/lib/megaco/test/megaco_test_msg_v1_lib.erl
index 638215e8c1..76665cb575 100644
--- a/lib/megaco/test/megaco_test_msg_v1_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_v1_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,6 +28,10 @@
%% ----
+-compile({no_auto_import,[error/1]}).
+
+%% ----
+
-include_lib("megaco/include/megaco_message_v1.hrl").
-include_lib("megaco/include/megaco.hrl").
diff --git a/lib/megaco/test/megaco_test_msg_v2_lib.erl b/lib/megaco/test/megaco_test_msg_v2_lib.erl
index b680bc869a..66e423284a 100644
--- a/lib/megaco/test/megaco_test_msg_v2_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_v2_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,6 +26,10 @@
%% ----
+-compile({no_auto_import,[error/1]}).
+
+%% ----
+
-include_lib("megaco/include/megaco_message_v2.hrl").
-include_lib("megaco/include/megaco.hrl").
diff --git a/lib/megaco/test/megaco_test_msg_v3_lib.erl b/lib/megaco/test/megaco_test_msg_v3_lib.erl
index 7b0d4f7d37..24492167ff 100644
--- a/lib/megaco/test/megaco_test_msg_v3_lib.erl
+++ b/lib/megaco/test/megaco_test_msg_v3_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,6 +26,10 @@
%% ----
+-compile({no_auto_import,[error/1]}).
+
+%% ----
+
-include_lib("megaco/include/megaco_message_v3.hrl").
-include_lib("megaco/include/megaco.hrl").
diff --git a/lib/megaco/test/megaco_test_tcp_generator.erl b/lib/megaco/test/megaco_test_tcp_generator.erl
index e4f27f32f5..3ed4c49bab 100644
--- a/lib/megaco/test/megaco_test_tcp_generator.erl
+++ b/lib/megaco/test/megaco_test_tcp_generator.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,6 +26,8 @@
-behaviour(megaco_test_generator).
+-compile({no_auto_import,[error/1]}).
+
%% API
-export([
start_link/1, start_link/2,
diff --git a/lib/megaco/test/megaco_timer_test.erl b/lib/megaco/test/megaco_timer_test.erl
index 8bcfc5a907..9b9103c40b 100644
--- a/lib/megaco/test/megaco_timer_test.erl
+++ b/lib/megaco/test/megaco_timer_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,22 +23,17 @@
%%----------------------------------------------------------------------
-module(megaco_timer_test).
+-compile({no_auto_import,[error/1]}).
+
-export([
t/0, t/1,
- init_per_testcase/2, fin_per_testcase/2,
-
- all/1,
-
- simple/1,
+ init_per_testcase/2, end_per_testcase/2,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
simple_init/1,
simple_usage/1,
-
- integer_timer/1,
integer_timer_start_and_expire/1,
integer_timer_start_and_stop/1%% ,
-
%% incr_timer/1
-
]).
-export([
@@ -71,49 +66,39 @@ do_init_per_testcase(Case, Config) ->
{ok, _Pid} = megaco_monitor:start_link(),
megaco_test_lib:init_per_testcase(Case, [{monitor_running, true}|Config]).
-fin_per_testcase(Case, Config) ->
- io:format("fin_per_testcase -> entry with"
+end_per_testcase(Case, Config) ->
+ io:format("end_per_testcase -> entry with"
"~n Case: ~p"
"~n Config: ~p"
"~n", [Case, Config]),
process_flag(trap_exit, false),
case lists:keydelete(monitor_running, 1, Config) of
Config ->
- megaco_test_lib:fin_per_testcase(Case, Config);
+ megaco_test_lib:end_per_testcase(Case, Config);
Config2 ->
megaco_monitor:stop(),
- megaco_test_lib:fin_per_testcase(Case, Config2)
+ megaco_test_lib:end_per_testcase(Case, Config2)
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- simple,
- integer_timer%% ,
-%% incr_timer
- ],
- Cases.
-
-
-simple(suite) ->
- Cases =
- [
- simple_init,
- simple_usage
- ],
- Cases.
-
-
-integer_timer(suite) ->
- Cases =
- [
- integer_timer_start_and_expire,
- integer_timer_start_and_stop
- ],
- Cases.
+all() ->
+ [{group, simple}, {group, integer_timer}].
+
+groups() ->
+ [{simple, [],
+ [simple_init, simple_usage]},
+%, incr_timer
+ {integer_timer, [],
+ [integer_timer_start_and_expire,
+ integer_timer_start_and_stop]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%% incr_timer(suite) ->
diff --git a/lib/megaco/test/megaco_trans_test.erl b/lib/megaco/test/megaco_trans_test.erl
index 44d4b3fff7..5f564e3bf6 100644
--- a/lib/megaco/test/megaco_trans_test.erl
+++ b/lib/megaco/test/megaco_trans_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -95,78 +95,49 @@ init_per_testcase(Case, Config) ->
process_flag(trap_exit, true),
megaco_test_lib:init_per_testcase(Case, Config).
-fin_per_testcase(Case, Config) ->
+end_per_testcase(Case, Config) ->
process_flag(trap_exit, false),
- megaco_test_lib:fin_per_testcase(Case, Config).
+ megaco_test_lib:end_per_testcase(Case, Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- [
- ack,
- trans_req,
- trans_req_and_ack,
- pending,
- reply,
-
- tickets
- ].
-
-ack(suite) ->
- [
- single_ack,
- multi_ack_timeout,
- multi_ack_maxcount
- ].
-
-trans_req(suite) ->
- [
- single_trans_req,
- multi_trans_req_timeout,
- multi_trans_req_maxcount1,
- multi_trans_req_maxcount2,
- multi_trans_req_maxsize1,
- multi_trans_req_maxsize2
- ].
-
-trans_req_and_ack(suite) ->
- [
- single_trans_req_and_ack,
- multi_trans_req_and_ack_timeout,
- multi_trans_req_and_ack_ackmaxcount,
- multi_trans_req_and_ack_reqmaxcount,
- multi_trans_req_and_ack_maxsize1,
- multi_trans_req_and_ack_maxsize2
- ].
-
-pending(suite) ->
- [
- single_trans_req_and_pending,
- multi_trans_req_and_pending,
- multi_trans_req_and_ack_and_pending,
- multi_ack_and_pending
- ].
-
-reply(suite) ->
- [
- multi_trans_req_and_reply,
- multi_trans_req_and_ack_and_reply,
- multi_ack_and_reply
- ].
-
-tickets(suite) ->
- [
- otp_7192
- ].
-
-otp_7192(suite) ->
- [
- otp_7192_1,
- otp_7192_2,
- otp_7192_3
- ].
-
+all() ->
+ [{group, ack}, {group, trans_req},
+ {group, trans_req_and_ack}, {group, pending},
+ {group, reply}, {group, tickets}].
+
+groups() ->
+ [{ack, [],
+ [single_ack, multi_ack_timeout, multi_ack_maxcount]},
+ {trans_req, [],
+ [single_trans_req, multi_trans_req_timeout,
+ multi_trans_req_maxcount1, multi_trans_req_maxcount2,
+ multi_trans_req_maxsize1, multi_trans_req_maxsize2]},
+ {trans_req_and_ack, [],
+ [single_trans_req_and_ack,
+ multi_trans_req_and_ack_timeout,
+ multi_trans_req_and_ack_ackmaxcount,
+ multi_trans_req_and_ack_reqmaxcount,
+ multi_trans_req_and_ack_maxsize1,
+ multi_trans_req_and_ack_maxsize2]},
+ {pending, [],
+ [single_trans_req_and_pending,
+ multi_trans_req_and_pending,
+ multi_trans_req_and_ack_and_pending,
+ multi_ack_and_pending]},
+ {reply, [],
+ [multi_trans_req_and_reply,
+ multi_trans_req_and_ack_and_reply,
+ multi_ack_and_reply]},
+ {tickets, [], [{group, otp_7192}]},
+ {otp_7192, [], [otp_7192_1, otp_7192_2, otp_7192_3]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/megaco/test/megaco_udp_test.erl b/lib/megaco/test/megaco_udp_test.erl
index 2e2f5465dd..ffbff9b762 100644
--- a/lib/megaco/test/megaco_udp_test.erl
+++ b/lib/megaco/test/megaco_udp_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -34,22 +34,14 @@
%% External exports
%%----------------------------------------------------------------------
-export([
- all/1,
-
- start/1,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
start_normal/1,
start_invalid_opt/1,
start_and_stop/1,
-
- sending/1,
sendreceive/1,
block_unblock/1,
-
- errors/1,
socket_failure/1,
-
- init_per_testcase/2, fin_per_testcase/2,
-
+ init_per_testcase/2, end_per_testcase/2,
t/0, t/1
]).
@@ -104,42 +96,31 @@ init_per_testcase(Case, Config) ->
%%----------------------------------------------------------------------
-%% Function: fin_per_testcase/2
+%% Function: end_per_testcase/2
%% Description:
%%----------------------------------------------------------------------
-fin_per_testcase(Case, Config) ->
- megaco_test_lib:fin_per_testcase(Case, Config).
+end_per_testcase(Case, Config) ->
+ megaco_test_lib:end_per_testcase(Case, Config).
%%======================================================================
%% Test case definitions
%%======================================================================
-all(suite) ->
- [
- start,
- sending,
- errors
- ].
-
-start(suite) ->
- [
- start_normal,
- start_invalid_opt,
- start_and_stop
- ].
+all() ->
+ [{group, start}, {group, sending}, {group, errors}].
-sending(suite) ->
- [
- sendreceive,
- block_unblock
+groups() ->
+ [{start, [],
+ [start_normal, start_invalid_opt, start_and_stop]},
+ {sending, [], [sendreceive, block_unblock]},
+ {errors, [], [socket_failure]}].
- ].
+init_per_group(_GroupName, Config) ->
+ Config.
-errors(suite) ->
- [
- socket_failure
- ].
+end_per_group(_GroupName, Config) ->
+ Config.
%% =================================================
diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk
index 9fc0e0f2fa..5f71712360 100644
--- a/lib/megaco/vsn.mk
+++ b/lib/megaco/vsn.mk
@@ -1,4 +1,23 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
APPLICATION = megaco
-MEGACO_VSN = 3.15
-PRE_VSN =
-APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)"
+MEGACO_VSN = 3.15.1
+PRE_VSN =
+APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)"
diff --git a/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc
index 0714c7b645..2e2cc386b7 100644
--- a/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc
@@ -235,9 +235,7 @@
<seealso marker="Mnesia_chap3#start_mnesia">Starting Mnesia</seealso>.
</item>
</list>
- <p>Continuing the dialogue with the Erlang shell will produce the following
- the following:
- </p>
+ <p>Continuing the dialogue with the Erlang shell will produce the following:</p>
<pre><![CDATA[
3> company:init().
{atomic,ok}
@@ -418,7 +416,7 @@ In_proj</tcaption>
interchangeably throughout this book.
</p>
<p>A Mnesia table is populated by Mnesia records. For example,
- the tuple <c>{boss, klacke, bjarne}</c> is an record. The
+ the tuple <c>{boss, klacke, bjarne}</c> is a record. The
second element in this tuple is the key. In order to uniquely
identify a table row both the key and the table name is
needed. The term <em>object identifier</em>,
@@ -553,7 +551,7 @@ In_proj</tcaption>
stored in the database:
</p>
<pre>
-\011 mnesia:select(employee, [{#employee{sex = female, name = '$1', _ = '_'},[], ['$1']}]).
+mnesia:select(employee, [{#employee{sex = female, name = '$1', _ = '_'},[], ['$1']}]).
</pre>
<p>Select must always run within an activity such as a
transaction. To be able to call from the shell we might
@@ -587,8 +585,8 @@ In_proj</tcaption>
</p>
<pre>
Q = qlc:q([E#employee.name || E <![CDATA[<-]]> mnesia:table(employee),
-\011 E#employee.sex == female]),
-\011 qlc:e(Q),
+ E#employee.sex == female]),
+ qlc:e(Q),
</pre>
<p>Accessing mnesia tables from a QLC list comprehension must
always be done within a transaction. Consider the following
diff --git a/lib/mnesia/doc/src/Mnesia_chap3.xml b/lib/mnesia/doc/src/Mnesia_chap3.xml
index 9a382bcb5a..2db9af9cf7 100644
--- a/lib/mnesia/doc/src/Mnesia_chap3.xml
+++ b/lib/mnesia/doc/src/Mnesia_chap3.xml
@@ -132,7 +132,7 @@
function changes the format on all records in table
<c>Tab</c>. It applies the argument <c>Fun</c> to all
records in the table. <c>Fun</c> shall be a function which
- takes an record of the old type, and returns the record of the new
+ takes a record of the old type, and returns the record of the new
type. The table key may not be changed.</p>
<code type="none">
-record(old, {key, val}).
@@ -418,8 +418,8 @@ skeppet %<input>erl -sname b -mnesia dir '"/ldisc/scratch/Mnesia.company"'</inpu
type <c>set</c> and <c>bag</c>: </p>
<pre>
f() -> F = fun() ->
-\011 mnesia:write({foo, 1, 2}), mnesia:write({foo, 1, 3}),
-\011 mnesia:read({foo, 1}) end, mnesia:transaction(F). </pre>
+ mnesia:write({foo, 1, 2}), mnesia:write({foo, 1, 3}),
+ mnesia:read({foo, 1}) end, mnesia:transaction(F). </pre>
<p>This transaction will return the list <c>[{foo,1,3}]</c> if
the <c>foo</c> table is of type <c>set</c>. However, list
<c>[{foo,1,2}, {foo,1,3}]</c> will return if the table is
diff --git a/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc
index 7d89c1b0dd..6e8055326b 100644
--- a/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc
@@ -514,13 +514,13 @@ The behavior is undefined if any process perform a write
of the table itself. This is an implementation detail, but remember
the dirty functions are low level functions.
</item>
- <item><c>mnesia:dirty_last(Tab)</c> This function works exactly as
+ <item><c>mnesia:dirty_last(Tab)</c> This function works exactly like
<c>mnesia:dirty_first/1</c> but returns the last object in
Erlang term order for the <c>ordered_set</c> table type. For
all other table types, <c>mnesia:dirty_first/1</c> and
<c>mnesia:dirty_last/1</c> are synonyms.
</item>
- <item><c>mnesia:dirty_prev(Tab, Key)</c> This function works exactly as
+ <item><c>mnesia:dirty_prev(Tab, Key)</c> This function works exactly like
<c>mnesia:dirty_next/2</c> but returns the previous object in
Erlang term order for the ordered_set table type. For
all other table types, <c>mnesia:dirty_next/2</c> and
diff --git a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
index 1c7e3662e1..30a8991465 100644
--- a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc
@@ -335,7 +335,7 @@ ok
explicitly be set at table creation. The default is
<c>0</c>, but if <c>n_disc_copies</c> and
<c>n_disc_only_copies</c> also are <c>0</c>,
- <c>n_ram_copies</c>\011will default be set to <c>1</c>.
+ <c>n_ram_copies</c> will default be set to <c>1</c>.
</p>
</item>
<tag><c>{n_disc_copies, Int}</c></tag>
@@ -408,7 +408,7 @@ ok
(a@sam)4> SecProps = [{foreign_key, {prim_dict, sec_val}}].
[{foreign_key,{prim_dict,sec_val}}]
(a@sam)5> mnesia:create_table(sec_dict,
-\011 [{frag_properties, SecProps},
+ [{frag_properties, SecProps},
(a@sam)5> {attributes, [sec_key, sec_val]}]).
{atomic,ok}
(a@sam)6> Write = fun(Rec) -> mnesia:write(Rec) end.
@@ -418,23 +418,23 @@ ok
(a@sam)8> SecKey = 42.
42
(a@sam)9> mnesia:activity(sync_dirty, Write,
-\011\011 [{prim_dict, PrimKey, -11}], mnesia_frag).
+ [{prim_dict, PrimKey, -11}], mnesia_frag).
ok
(a@sam)10> mnesia:activity(sync_dirty, Write,
-\011\011 [{sec_dict, SecKey, PrimKey}], mnesia_frag).
+ [{sec_dict, SecKey, PrimKey}], mnesia_frag).
ok
(a@sam)11> mnesia:change_table_frag(prim_dict, {add_frag, [node()]}).
{atomic,ok}
(a@sam)12> SecRead = fun(PrimKey, SecKey) ->
-\011\011 mnesia:read({sec_dict, PrimKey}, SecKey, read) end.
+ mnesia:read({sec_dict, PrimKey}, SecKey, read) end.
#Fun<erl_eval>
(a@sam)13> mnesia:activity(transaction, SecRead,
-\011\011 [PrimKey, SecKey], mnesia_frag).
+ [PrimKey, SecKey], mnesia_frag).
[{sec_dict,42,11}]
(a@sam)14> Info = fun(Tab, Item) -> mnesia:table_info(Tab, Item) end.
#Fun<erl_eval>
(a@sam)15> mnesia:activity(sync_dirty, Info,
-\011\011 [prim_dict, frag_size], mnesia_frag).
+ [prim_dict, frag_size], mnesia_frag).
[{prim_dict,0},
{prim_dict_frag2,0},
{prim_dict_frag3,0},
@@ -444,7 +444,7 @@ ok
{prim_dict_frag7,0},
{prim_dict_frag8,0}]
(a@sam)16> mnesia:activity(sync_dirty, Info,
-\011\011 [sec_dict, frag_size], mnesia_frag).
+ [sec_dict, frag_size], mnesia_frag).
[{sec_dict,0},
{sec_dict_frag2,0},
{sec_dict_frag3,0},
@@ -1051,7 +1051,7 @@ ok
ActivityID will be received. Note that this event may still be received even
if no table events with a corresponding ActivityID were received, depending on
the tables to which the receiving process is subscribed.</p>
- <p>Dirty operations always only contain one update and thus no activity event is sent.</p>
+ <p>Dirty operations always only contain one update and thus no activity event is sent.</p>
</item>
</taglist>
</section>
diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml
index 5d3bcf830e..16e78ea0af 100644
--- a/lib/mnesia/doc/src/mnesia.xml
+++ b/lib/mnesia/doc/src/mnesia.xml
@@ -799,7 +799,7 @@ mnesia:change_table_copy_type(person, node(), disc_copies)
</item>
<item>
<p><c>{local_content, Bool}</c>, where <c>Bool</c> must be
- either <c>true</c> or <c>false</c>. The default value is <c>false</c>.\011 </p>
+ either <c>true</c> or <c>false</c>. The default value is <c>false</c>.</p>
</item>
</list>
<p>For example, the following call creates the <c>person</c> table
@@ -1022,7 +1022,7 @@ mnesia:create_table(person,
<name>dirty_last(Tab) -> Key | exit({aborted, Reason}) </name>
<fsummary>Return the key for the last record in a table.</fsummary>
<desc>
- <p>This function works exactly
+ <p>This function works exactly like
<c>mnesia:dirty_first/1</c> but returns the last object in
Erlang term order for the <c>ordered_set</c> table type. For
all other table types, <c>mnesia:dirty_first/1</c> and
@@ -1063,11 +1063,11 @@ mnesia:create_table(person,
<name>dirty_prev(Tab, Key) -> Key | exit({aborted, Reason}) </name>
<fsummary>Return the previous key in a table. </fsummary>
<desc>
- <p>This function works exactly
+ <p>This function works exactly like
<c>mnesia:dirty_next/2</c> but returns the previous object in
Erlang term order for the ordered_set table type. For
all other table types, <c>mnesia:dirty_next/2</c> and
- <c>mnesia:dirty_prev/2</c> are synonyms.\011 </p>
+ <c>mnesia:dirty_prev/2</c> are synonyms.</p>
</desc>
</func>
<func>
@@ -1334,7 +1334,7 @@ mnesia:create_table(person,
<name>foldr(Function, Acc, Table) -> NewAcc | transaction abort </name>
<fsummary>Call Function for each record in Table </fsummary>
<desc>
- <p>This function works exactly as
+ <p>This function works exactly like
<c>foldl/3</c> but iterates the table in the opposite order
for the <c>ordered_set</c> table type. For
all other table types, <c>foldr/3</c> and
@@ -1512,14 +1512,14 @@ mnesia:create_table(person,
<fsummary>Check if code is running in a transaction.</fsummary>
<desc>
<p>When this function is executed inside a transaction context
- it returns <c>true</c>, otherwise <c>false</c>.</p>
+ it returns <c>true</c>, otherwise <c>false</c>.</p>
</desc>
</func>
<func>
<name>last(Tab) -> Key | transaction abort </name>
<fsummary>Return the key for the last record in a table.</fsummary>
<desc>
- <p>This function works exactly
+ <p>This function works exactly like
<c>mnesia:first/1</c> but returns the last object in
Erlang term order for the <c>ordered_set</c> table type. For
all other table types, <c>mnesia:first/1</c> and
@@ -1698,11 +1698,11 @@ mnesia:create_table(person,
<name>prev(Tab, Key) -> Key | transaction abort </name>
<fsummary>Return the previous key in a table. </fsummary>
<desc>
- <p>This function works exactly
+ <p>This function works exactly like
<c>mnesia:next/2</c> but returns the previous object in
Erlang term order for the ordered_set table type. For
all other table types, <c>mnesia:next/2</c> and
- <c>mnesia:prev/2</c> are synonyms.\011 </p>
+ <c>mnesia:prev/2</c> are synonyms.</p>
</desc>
</func>
<func>
@@ -1891,10 +1891,10 @@ mnesia:create_table(person,
<p>For example to find the names of all male persons with an age over 30 in table
Tab do:</p>
<code type="none">
-\011 MatchHead = #person{name='$1', sex=male, age='$2', _='_'},
-\011 Guard = {'>', '$2', 30},
-\011 Result = '$1',
-\011 mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),
+MatchHead = #person{name='$1', sex=male, age='$2', _='_'},
+Guard = {'>', '$2', 30},
+Result = '$1',
+mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]),
</code>
</desc>
</func>
@@ -2835,7 +2835,7 @@ raise(Name, Amount) ->
</func>
<func>
<name>write(Tab, Record, LockKind) -> transaction abort | ok </name>
- <fsummary>Write an record into the database.</fsummary>
+ <fsummary>Write a record into the database.</fsummary>
<desc>
<p>Writes the record <c>Record</c> to the table <c>Tab</c>.
</p>
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index 2352f11b93..5a6de05c8b 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -38,7 +38,36 @@
thus constitutes one section in this document. The title of each
section is the version number of Mnesia.</p>
- <section><title>Mnesia 4.4.15</title>
+ <section><title>Mnesia 4.4.16</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Sometimes a 'log_header' record was added to tables when
+ invoking mnesia:restore/2 with the option
+ 'recreate_tables'. Thanks Vance Shipley.</p>
+ <p>
+ Own Id: OTP-8960</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Compiler warnings were eliminated.</p>
+ <p>
+ Own Id: OTP-8855</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.4.15</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/mnesia/src/mnesia.appup.src b/lib/mnesia/src/mnesia.appup.src
index 47c9bf9979..22ef5178a7 100644
--- a/lib/mnesia/src/mnesia.appup.src
+++ b/lib/mnesia/src/mnesia.appup.src
@@ -1,7 +1,13 @@
%% -*- erlang -*-
{"%VSN%",
[
+ {"4.4.15",[
+ {update, mnesia_dumper, soft, soft_purge, soft_purge, []}
+ ]}
],
[
+ {"4.4.15",[
+ {update, mnesia_dumper, soft, soft_purge, soft_purge, []}
+ ]}
]
}.
diff --git a/lib/mnesia/src/mnesia_dumper.erl b/lib/mnesia/src/mnesia_dumper.erl
index f669d009c6..644133cf5d 100644
--- a/lib/mnesia/src/mnesia_dumper.erl
+++ b/lib/mnesia/src/mnesia_dumper.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -643,7 +643,7 @@ insert_op(Tid, _, {op, create_table, TabDef}, InPlace, InitBy) ->
true -> ignore;
false ->
mnesia_log:open_log(temp,
- mnesia_log:dcl_log_header(),
+ mnesia_log:dcd_log_header(),
Dcd,
false,
false,
diff --git a/lib/mnesia/test/Makefile b/lib/mnesia/test/Makefile
index 4f98efaed1..bce2467a5f 100644
--- a/lib/mnesia/test/Makefile
+++ b/lib/mnesia/test/Makefile
@@ -108,7 +108,7 @@ release_spec: opt
release_tests_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) mnesia.spec mnesia.spec.vxworks $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) mnesia.spec mnesia.cover $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
$(INSTALL_SCRIPT) mt $(INSTALL_PROGS) $(RELSYSDIR)
# chmod -f -R u+w $(RELSYSDIR)
# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/mnesia/test/mnesia.cover b/lib/mnesia/test/mnesia.cover
new file mode 100644
index 0000000000..66ffc06e89
--- /dev/null
+++ b/lib/mnesia/test/mnesia.cover
@@ -0,0 +1,2 @@
+{incl_app,mnesia,details}.
+
diff --git a/lib/mnesia/test/mnesia.spec b/lib/mnesia/test/mnesia.spec
index 596f8b917d..204d1519cb 100644
--- a/lib/mnesia/test/mnesia.spec
+++ b/lib/mnesia/test/mnesia.spec
@@ -1,23 +1,76 @@
-{topcase, {dir, "../mnesia_test"}}.
-{require_nodenames, 2}.
-{skip, {mnesia_measure_test, ram_meter, "Takes to long time"}}.
-{skip, {mnesia_measure_test, disc_meter, "Takes to long time"}}.
-{skip, {mnesia_measure_test, disc_only_meter, "Takes to long time"}}.
-{skip, {mnesia_measure_test, cost, "Takes to long time"}}.
-{skip, {mnesia_measure_test, dbn_meters, "Takes to long time"}}.
-{skip, {mnesia_measure_test, tpcb, "Takes to long time"}}.
-{skip, {mnesia_measure_test, prediction, "Not yet implemented"}}.
-{skip, {mnesia_measure_test, consumption, "Not yet implemented"}}.
-{skip, {mnesia_measure_test, scalability, "Not yet implemented"}}.
-{skip, {mnesia_measure_test, tpcb, "Takes too much time and memory"}}.
-{skip, {mnesia_measure_test, measure_all_api_functions, "Not yet implemented"}}.
-{skip, {mnesia_measure_test, mnemosyne_vs_mnesia_kernel, "Not yet implemented"}}.
-{skip, {mnesia_examples_test, company, "Not yet implemented"}}.
-{skip, {mnesia_config_test, ignore_fallback_at_startup, "Not yet implemented"}}.
-{skip, {mnesia_evil_backup, local_backup_checkpoint, "Not yet implemented"}}.
-{skip, {mnesia_config_test, max_wait_for_decision, "Not yet implemented"}}.
-{skip, {mnesia_recovery_test, after_full_disc_partition, "Not yet implemented"}}.
-{skip, {mnesia_recovery_test, system_upgrade, "Not yet implemented"}}.
-{skip, {mnesia_consistency_test, consistency_after_change_table_copy_type, "Not yet implemented"}}.
-{skip, {mnesia_consistency_test, consistency_after_transform_table, "Not yet implemented"}}.
-{skip, {mnesia_consistency_test, consistency_after_rename_of_node, "Not yet implemented"}}.
+{suites,"../mnesia_test",all}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [ram_meter],
+ "Takes to long time"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [disc_meter],
+ "Takes to long time"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [disc_only_meter],
+ "Takes to long time"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,[cost],"Takes to long time"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [dbn_meters],
+ "Takes to long time"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [ram_tpcb,disc_tpcb,disc_only_tpcb],
+ "Takes to long time"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [reader_disturbed_by_node_down,writer_disturbed_by_node_down,
+ reader_disturbed_by_node_up,writer_disturbed_by_node_up,
+ reader_disturbed_by_schema_ops,writer_disturbed_by_schema_ops,
+ reader_disturbed_by_checkpoint,writer_disturbed_by_checkpoint,
+ reader_disturbed_by_dump_log,writer_disturbed_by_dump_log,
+ reader_disturbed_by_backup,writer_disturbed_by_backup,
+ reader_disturbed_by_restore,writer_disturbed_by_restore,
+ reader_competing_with_reader,reader_competing_with_writer,
+ writer_competing_with_reader,writer_competing_with_writer],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [measure_resource_consumption,determine_resource_leakage],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [determine_system_limits,performance_at_min_config,
+ performance_at_max_config,performance_at_full_load,
+ resource_consumption_at_min_config,
+ resource_consumption_at_max_config,
+ resource_consumption_at_full_load],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [ram_tpcb,disc_tpcb,disc_only_tpcb],
+ "Takes too much time and memory"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [measure_all_api_functions],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_measure_test,
+ [mnemosyne_vs_mnesia_kernel],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_examples_test,
+ [company],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_config_test,
+ [ignore_fallback_at_startup],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_evil_backup,
+ [local_backup_checkpoint],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_config_test,
+ [max_wait_for_decision],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_recovery_test,
+ [after_full_disc_partition],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_recovery_test,
+ [system_upgrade],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_consistency_test,
+ [consistency_after_change_table_copy_type],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_consistency_test,
+ [consistency_after_transform_table_ram,
+ consistency_after_transform_table_disc,
+ consistency_after_transform_table_disc_only],
+ "Not yet implemented"}.
+{skip_cases,"../mnesia_test",mnesia_consistency_test,
+ [consistency_after_rename_of_node],
+ "Not yet implemented"}.
diff --git a/lib/mnesia/test/mnesia_SUITE.erl b/lib/mnesia/test/mnesia_SUITE.erl
index b28deaf330..fe7d366eb3 100644
--- a/lib/mnesia/test/mnesia_SUITE.erl
+++ b/lib/mnesia/test/mnesia_SUITE.erl
@@ -26,135 +26,122 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Verify that Mnesia really is a distributed real-time DBMS",
- "This is the test suite of the Mnesia DBMS. The test suite",
- "covers many aspects of usage and is indended to be developed",
- "incrementally. The test suite is divided into a hierarchy of test",
- "suites where the leafs actually implements the test cases.",
- "The intention of each test case and sub test suite can be",
- "read in comments where they are implemented or in worst cases",
- "from their long mnemonic names. ",
- "",
- "The most simple test case of them all is called 'silly'",
- "and is useful to run now and then, e.g. when some new fatal",
- "bug has been introduced. It may be run even if Mnesia is in",
- "such a bad shape that the test machinery cannot be used.",
- "NB! Invoke the function directly with mnesia_SUITE:silly()",
- "and do not involve the normal test machinery."];
-all(suite) ->
- [
- light,
- medium,
- heavy,
- clean_up_suite
- ].
+suite() -> [{ct_hooks,[{ts_install_cth,[{nodenames,1}]}]}].
+
+
+%% Verify that Mnesia really is a distributed real-time DBMS.
+%% This is the test suite of the Mnesia DBMS. The test suite
+%% covers many aspects of usage and is indended to be developed
+%% incrementally. The test suite is divided into a hierarchy of test
+%% suites where the leafs actually implements the test cases.
+%% The intention of each test case and sub test suite can be
+%% read in comments where they are implemented or in worst cases
+%% from their long mnemonic names.
+%%
+%% The most simple test case of them all is called 'silly'
+%% and is useful to run now and then, e.g. when some new fatal
+%% bug has been introduced. It may be run even if Mnesia is in
+%% such a bad shape that the test machinery cannot be used.
+%% NB! Invoke the function directly with mnesia_SUITE:silly()
+%% and do not involve the normal test machinery.
+
+all() ->
+ [{group, light}, {group, medium}, {group, heavy},
+ clean_up_suite].
+
+groups() ->
+ %% The 'light' test suite runs a selected set of test suites and is
+ %% intended to be the smallest test suite that is meaningful
+ %% to run. It starts with an installation test (which in essence is the
+ %% 'silly' test case) and then it covers all functions in the API in
+ %% various depths. All configuration parameters and examples are also
+ %% covered.
+ [{light, [],
+ [{group, install}, {group, nice}, {group, evil},
+ {group, mnesia_frag_test, light}, {group, qlc},
+ {group, registry}, {group, config}, {group, examples}]},
+ {install, [], [{mnesia_install_test, all}]},
+ {nice, [], [{mnesia_nice_coverage_test, all}]},
+ {evil, [], [{mnesia_evil_coverage_test, all}]},
+ {qlc, [], [{mnesia_qlc_test, all}]},
+ {registry, [], [{mnesia_registry_test, all}]},
+ {config, [], [{mnesia_config_test, all}]},
+ {examples, [], [{mnesia_examples_test, all}]},
+ %% The 'medium' test suite verfies the ACID (atomicity, consistency
+ %% isolation and durability) properties and various recovery scenarios
+ %% These tests may take quite while to run.
+ {medium, [],
+ [{group, install}, {group, atomicity},
+ {group, isolation}, {group, durability},
+ {group, recovery}, {group, consistency},
+ {group, mnesia_frag_test, medium}]},
+ {atomicity, [], [{mnesia_atomicity_test, all}]},
+ {isolation, [], [{mnesia_isolation_test, all}]},
+ {durability, [], [{mnesia_durability_test, all}]},
+ {recovery, [], [{mnesia_recovery_test, all}]},
+ {consistency, [], [{mnesia_consistency_test, all}]},
+ %% The 'heavy' test suite runs some resource consuming tests and
+ %% benchmarks
+ {heavy, [], [{group, measure}]},
+ {measure, [], [{mnesia_measure_test, all}]},
+ {prediction, [],
+ [{group, mnesia_measure_test, prediction}]},
+ {fairness, [],
+ [{group, mnesia_measure_test, fairness}]},
+ {benchmarks, [],
+ [{group, mnesia_measure_test, benchmarks}]},
+ {consumption, [],
+ [{group, mnesia_measure_test, consumption}]},
+ {scalability, [],
+ [{group, mnesia_measure_test, scalability}]},
+ %% This test suite is an extract of the grand Mnesia suite
+ %% it contains OTP R4B specific test cases
+ {otp_r4b, [],
+ [{mnesia_config_test, access_module},
+ {mnesia_config_test, dump_log_load_regulation},
+ {mnesia_config_test, embedded_mnemosyne},
+ {mnesia_config_test, ignore_fallback_at_startup},
+ {mnesia_config_test, max_wait_for_decision},
+ {mnesia_consistency_test, consistency_after_restore},
+ {mnesia_evil_backup, restore},
+ {mnesia_evil_coverage_test, offline_set_master_nodes},
+ {mnesia_evil_coverage_test, record_name},
+ {mnesia_evil_coverage_test, user_properties},
+ {mnesia_registry_test, all}, {group, otp_2363}]},
+ %% Index on disc only tables
+ {otp_2363, [],
+ [{mnesia_dirty_access_test,
+ dirty_index_match_object_disc_only},
+ {mnesia_dirty_access_test, dirty_index_read_disc_only},
+ {mnesia_dirty_access_test,
+ dirty_index_update_bag_disc_only},
+ {mnesia_dirty_access_test,
+ dirty_index_update_set_disc_only},
+ {mnesia_evil_coverage_test,
+ create_live_table_index_disc_only}]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
silly() ->
mnesia_install_test:silly().
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-light(doc) ->
- ["The 'light' test suite runs a selected set of test suites and is",
- "intended to be the smallest test suite that is meaningful",
- "to run. It starts with an installation test (which in essence is the",
- "'silly' test case) and then it covers all functions in the API in",
- "various depths. All configuration parameters and examples are also",
- "covered."];
-light(suite) ->
- [
- install,
- nice,
- evil,
- {mnesia_frag_test, light},
- qlc,
- registry,
- config,
- examples
- ].
-
-install(suite) ->
- [{mnesia_install_test, all}].
-
-nice(suite) ->
- [{mnesia_nice_coverage_test, all}].
-
-evil(suite) ->
- [{mnesia_evil_coverage_test, all}].
-
-qlc(suite) ->
- [{mnesia_qlc_test, all}].
-
-registry(suite) ->
- [{mnesia_registry_test, all}].
-
-config(suite) ->
- [{mnesia_config_test, all}].
-
-examples(suite) ->
- [{mnesia_examples_test, all}].
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-medium(doc) ->
- ["The 'medium' test suite verfies the ACID (atomicity, consistency",
- "isolation and durability) properties and various recovery scenarios",
- "These tests may take quite while to run."];
-medium(suite) ->
- [
- install,
- atomicity,
- isolation,
- durability,
- recovery,
- consistency,
- {mnesia_frag_test, medium}
- ].
-
-atomicity(suite) ->
- [{mnesia_atomicity_test, all}].
-
-isolation(suite) ->
- [{mnesia_isolation_test, all}].
-
-durability(suite) ->
- [{mnesia_durability_test, all}].
-
-recovery(suite) ->
- [{mnesia_recovery_test, all}].
-
-consistency(suite) ->
- [{mnesia_consistency_test, all}].
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-heavy(doc) ->
- ["The 'heavy' test suite runs some resource consuming tests and",
- "benchmarks"];
-heavy(suite) ->
- [measure].
-
-measure(suite) ->
- [{mnesia_measure_test, all}].
-
-prediction(suite) ->
- [{mnesia_measure_test, prediction}].
-
-fairness(suite) ->
- [{mnesia_measure_test, fairness}].
-
-benchmarks(suite) ->
- [{mnesia_measure_test, benchmarks}].
-
-consumption(suite) ->
- [{mnesia_measure_test, consumption}].
-
-scalability(suite) ->
- [{mnesia_measure_test, scalability}].
-
clean_up_suite(doc) -> ["Not a test case only kills mnesia and nodes, that where"
"started during the tests"];
@@ -169,35 +156,7 @@ clean_up_suite(Config) when is_list(Config)->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-otp_r4b(doc) ->
- ["This test suite is an extract of the grand Mnesia suite",
- "it contains OTP R4B specific test cases"];
-otp_r4b(suite) ->
- [
- {mnesia_config_test, access_module},
- {mnesia_config_test, dump_log_load_regulation},
- {mnesia_config_test, embedded_mnemosyne},
- {mnesia_config_test, ignore_fallback_at_startup},
- {mnesia_config_test, max_wait_for_decision},
- {mnesia_consistency_test, consistency_after_restore},
- {mnesia_evil_backup, restore},
- {mnesia_evil_coverage_test, offline_set_master_nodes},
- {mnesia_evil_coverage_test, record_name},
- {mnesia_evil_coverage_test, user_properties},
- {mnesia_registry_test, all},
- otp_2363
- ].
-
-otp_2363(doc) ->
- ["Index on disc only tables"];
-otp_2363(suite) ->
- [
- {mnesia_dirty_access_test, dirty_index_match_object_disc_only},
- {mnesia_dirty_access_test,dirty_index_read_disc_only},
- {mnesia_dirty_access_test,dirty_index_update_bag_disc_only},
- {mnesia_dirty_access_test,dirty_index_update_set_disc_only},
- {mnesia_evil_coverage_test, create_live_table_index_disc_only}
- ].
+
diff --git a/lib/mnesia/test/mnesia_atomicity_test.erl b/lib/mnesia/test/mnesia_atomicity_test.erl
index 645c203a91..cf878fc820 100644
--- a/lib/mnesia/test/mnesia_atomicity_test.erl
+++ b/lib/mnesia/test/mnesia_atomicity_test.erl
@@ -27,24 +27,46 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Verify atomicity of transactions",
- "Verify that transactions are atomic, i.e. either all operations",
- "in a transaction will be performed or none of them. It must be",
- "assured that no partitially completed operations leaves any",
- "effects in the database."];
-all(suite) ->
- [
- explicit_abort_in_middle_of_trans,
+all() ->
+ [explicit_abort_in_middle_of_trans,
runtime_error_in_middle_of_trans,
- kill_self_in_middle_of_trans,
- throw_in_middle_of_trans,
- mnesia_down_in_middle_of_trans
- ].
+ kill_self_in_middle_of_trans, throw_in_middle_of_trans,
+ {group, mnesia_down_in_middle_of_trans}].
+
+groups() ->
+ [{mnesia_down_in_middle_of_trans, [],
+ [mnesia_down_during_infinite_trans,
+ {group, lock_waiter}, {group, restart_check}]},
+ {lock_waiter, [],
+ [lock_waiter_sw_r, lock_waiter_sw_rt, lock_waiter_sw_wt,
+ lock_waiter_wr_r, lock_waiter_srw_r, lock_waiter_sw_sw,
+ lock_waiter_sw_w, lock_waiter_sw_wr, lock_waiter_sw_srw,
+ lock_waiter_wr_wt, lock_waiter_srw_wt,
+ lock_waiter_wr_sw, lock_waiter_srw_sw, lock_waiter_wr_w,
+ lock_waiter_srw_w, lock_waiter_r_sw, lock_waiter_r_w,
+ lock_waiter_r_wt, lock_waiter_rt_sw, lock_waiter_rt_w,
+ lock_waiter_rt_wt, lock_waiter_wr_wr,
+ lock_waiter_srw_srw, lock_waiter_wt_r, lock_waiter_wt_w,
+ lock_waiter_wt_rt, lock_waiter_wt_wt, lock_waiter_wt_wr,
+ lock_waiter_wt_srw, lock_waiter_wt_sw, lock_waiter_w_wr,
+ lock_waiter_w_srw, lock_waiter_w_sw, lock_waiter_w_r,
+ lock_waiter_w_w, lock_waiter_w_rt, lock_waiter_w_wt]},
+ {restart_check, [],
+ [restart_r_one, restart_w_one, restart_rt_one,
+ restart_wt_one, restart_wr_one, restart_sw_one,
+ restart_r_two, restart_w_two, restart_rt_two,
+ restart_wt_two, restart_wr_two, restart_sw_two]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
explicit_abort_in_middle_of_trans(suite) -> [];
@@ -259,12 +281,6 @@ throw_in_middle_of_trans(Config) when is_list(Config) ->
?verify_mnesia(Nodes, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-mnesia_down_in_middle_of_trans(suite) ->
- [
- mnesia_down_during_infinite_trans,
- lock_waiter,
- restart_check
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
mnesia_down_during_infinite_trans(suite) -> [];
@@ -304,56 +320,6 @@ mnesia_down_during_infinite_trans(Config) when is_list(Config) ->
?verify_mnesia([Node2], [Node1]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-lock_waiter(doc) ->
- ["The purpose of this test case is to test the following situation:",
- "process B locks an object, process A accesses that object as",
- "well, but A has to wait for the lock to be released. Then",
- "mnesia of B goes down. Question: will A get the lock ?",
- "important: the transaction of A is the oldest one !!! (= a little tricky)",
- "",
- "several different access operations shall be tested",
- "rt = read_lock_table, wt = write_lock_table, r = read,",
- "sw = s_write, w = write, wr = wread"];
-lock_waiter(suite) ->
- [
- lock_waiter_sw_r,
- lock_waiter_sw_rt,
- lock_waiter_sw_wt,
- lock_waiter_wr_r,
- lock_waiter_srw_r,
- lock_waiter_sw_sw,
- lock_waiter_sw_w,
- lock_waiter_sw_wr,
- lock_waiter_sw_srw,
- lock_waiter_wr_wt,
- lock_waiter_srw_wt,
- lock_waiter_wr_sw,
- lock_waiter_srw_sw,
- lock_waiter_wr_w,
- lock_waiter_srw_w,
- lock_waiter_r_sw,
- lock_waiter_r_w,
- lock_waiter_r_wt,
- lock_waiter_rt_sw,
- lock_waiter_rt_w,
- lock_waiter_rt_wt,
- lock_waiter_wr_wr,
- lock_waiter_srw_srw,
- lock_waiter_wt_r,
- lock_waiter_wt_w,
- lock_waiter_wt_rt,
- lock_waiter_wt_wt,
- lock_waiter_wt_wr,
- lock_waiter_wt_srw,
- lock_waiter_wt_sw,
- lock_waiter_w_wr,
- lock_waiter_w_srw,
- lock_waiter_w_sw,
- lock_waiter_w_r,
- lock_waiter_w_w,
- lock_waiter_w_rt,
- lock_waiter_w_wt
- ].
lock_waiter_sw_r(suite) -> [];
lock_waiter_sw_r(Config) when is_list(Config) ->
@@ -649,29 +615,6 @@ wait(Mseconds) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-restart_check (doc) ->
- [
- "test case:'A' performs a transaction on a table which",
- "is only replicated on node B. During that transaction",
- "mnesia on node B is killed. The transaction of A should",
- "be stopped, since there is no further replica",
- "rt = read_lock_table, wt = write_lock_table, r = read,",
- "sw = s_write, w = write, wr = wread,"];
-restart_check(suite) ->
- [
- restart_r_one,
- restart_w_one,
- restart_rt_one,
- restart_wt_one,
- restart_wr_one,
- restart_sw_one,
- restart_r_two,
- restart_w_two,
- restart_rt_two,
- restart_wt_two,
- restart_wr_two,
- restart_sw_two
- ].
restart_r_one(suite) -> [];
restart_r_one(Config) when is_list(Config) ->
diff --git a/lib/mnesia/test/mnesia_config_backup.erl b/lib/mnesia/test/mnesia_config_backup.erl
index a33ec6ac5c..0916e255e2 100644
--- a/lib/mnesia/test/mnesia_config_backup.erl
+++ b/lib/mnesia/test/mnesia_config_backup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/mnesia/test/mnesia_config_event.erl b/lib/mnesia/test/mnesia_config_event.erl
index 6c1dea7ed5..832bf94eb9 100644
--- a/lib/mnesia/test/mnesia_config_event.erl
+++ b/lib/mnesia/test/mnesia_config_event.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/mnesia/test/mnesia_config_test.erl b/lib/mnesia/test/mnesia_config_test.erl
index 7b62c63a62..93510d539c 100644
--- a/lib/mnesia/test/mnesia_config_test.erl
+++ b/lib/mnesia/test/mnesia_config_test.erl
@@ -27,14 +27,14 @@
-record(test_table2,{i, b}).
-export([
- all/1,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
access_module/1,
auto_repair/1,
backup_module/1,
debug/1,
dir/1,
dump_log_load_regulation/1,
- dump_log_thresholds/1,
+
dump_log_update_in_place/1,
embedded_mnemosyne/1,
event_module/1,
@@ -44,7 +44,7 @@
send_compressed/1,
app_test/1,
- schema_config/1,
+
schema_merge/1,
unknown_config/1,
@@ -56,13 +56,13 @@
start_first_one_disc_less_then_two_more_disc_less/1,
schema_location_and_extra_db_nodes_combinations/1,
table_load_to_disc_less_nodes/1,
- dynamic_connect/1,
+
dynamic_basic/1,
dynamic_ext/1,
dynamic_bad/1,
init_per_testcase/2,
- fin_per_testcase/2,
+ end_per_testcase/2,
c_nodes/0
]).
@@ -95,46 +95,40 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- [
- "Test all configuration parameters",
- "Perform an exhaustive test of all the various parameters that",
- "may be used to configure the Mnesia application.",
- "",
- "Hint: Check out the unofficial function mnesia:start/1.",
- " But be careful to cleanup all configuration parameters",
- " afterwards since the rest of the test suite may rely on",
- " these default configurations. Perhaps it is best to run",
- " these tests in a separate node which is dropped afterwards.",
- "Are really all configuration parameters covered?"];
-
-all(suite) ->
- [
- access_module,
- auto_repair,
- backup_module,
- debug,
- dir,
- dump_log_load_regulation,
- dump_log_thresholds,
- dump_log_update_in_place,
- embedded_mnemosyne,
- event_module,
- ignore_fallback_at_startup,
- inconsistent_database,
- max_wait_for_decision,
- send_compressed,
-
- app_test,
- schema_config,
- unknown_config
- ].
+all() ->
+ [access_module, auto_repair, backup_module, debug, dir,
+ dump_log_load_regulation, {group, dump_log_thresholds},
+ dump_log_update_in_place, embedded_mnemosyne,
+ event_module, ignore_fallback_at_startup,
+ inconsistent_database, max_wait_for_decision,
+ send_compressed, app_test, {group, schema_config},
+ unknown_config].
+
+groups() ->
+ [{dump_log_thresholds, [],
+ [dump_log_time_threshold, dump_log_write_threshold]},
+ {schema_config, [],
+ [start_one_disc_full_then_one_disc_less,
+ start_first_one_disc_less_then_one_disc_full,
+ start_first_one_disc_less_then_two_more_disc_less,
+ schema_location_and_extra_db_nodes_combinations,
+ table_load_to_disc_less_nodes, schema_merge,
+ {group, dynamic_connect}]},
+ {dynamic_connect, [],
+ [dynamic_basic, dynamic_ext, dynamic_bad]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -445,21 +439,6 @@ dump_log_update_in_place(Config) when is_list(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-dump_log_thresholds(doc) ->
- ["Elaborate with various values of the dump log thresholds and how",
- "they affects each others. Both the dump_log_time_threshold and the",
- "dump_log_write_threshold must be covered. Do also check that both",
- "kinds of overload events are generated as expected.",
- "",
- "Logs are checked by first doing whatever has to be done to trigger ",
- "a dump, and then stopping Mnesia and then look in the ",
- "data files and see that the correct amount of transactions ",
- "have been done."];
-dump_log_thresholds(suite) ->
- [
- dump_log_time_threshold,
- dump_log_write_threshold
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
dump_log_write_threshold(doc)->
@@ -783,22 +762,6 @@ event_module(Config) when is_list(Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-schema_config(doc) ->
- ["Try many configurations with various schema_location's with and",
- "without explicit extra_db_nodes. Do also provoke various schema merge",
- "situations. Most of the other test suites focusses on tests where the",
- "schema is residing on disc. Now it is time to perform an exhaustive",
- "elaboration with various disc less configurations."];
-schema_config(suite) ->
- [
- start_one_disc_full_then_one_disc_less,
- start_first_one_disc_less_then_one_disc_full,
- start_first_one_disc_less_then_two_more_disc_less,
- schema_location_and_extra_db_nodes_combinations,
- table_load_to_disc_less_nodes,
- schema_merge,
- dynamic_connect
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
start_one_disc_full_then_one_disc_less(doc)->
["Start a disk node and then a disk less one. Distribute some",
@@ -1160,15 +1123,6 @@ sort(NS) when is_list(NS) ->
lists:sort(NS).
-dynamic_connect(doc) ->
- ["Test the new functionality where we start mnesia first and then "
- "connect to the other mnesia nodes"];
-dynamic_connect(suite) ->
- [
- dynamic_basic,
- dynamic_ext,
- dynamic_bad
- ].
dynamic_basic(suite) -> [];
diff --git a/lib/mnesia/test/mnesia_consistency_test.erl b/lib/mnesia/test/mnesia_consistency_test.erl
index ffe8ab7ac3..f38e13f3a2 100644
--- a/lib/mnesia/test/mnesia_consistency_test.erl
+++ b/lib/mnesia/test/mnesia_consistency_test.erl
@@ -27,33 +27,121 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Verify transaction consistency",
- "Consistency is the property of the application that requires any",
- "execution of the transaction to take the database from one",
- "consistent state to another. Verify that the database is",
- "consistent at any point in time.",
- "Verify for various configurations.",
- " Verify for both set and bag"];
-all(suite) ->
- [
- consistency_after_restart,
- consistency_after_dump_tables,
- consistency_after_add_replica,
- consistency_after_del_replica,
- consistency_after_move_replica,
- consistency_after_transform_table,
+all() ->
+ [{group, consistency_after_restart},
+ {group, consistency_after_dump_tables},
+ {group, consistency_after_add_replica},
+ {group, consistency_after_del_replica},
+ {group, consistency_after_move_replica},
+ {group, consistency_after_transform_table},
consistency_after_change_table_copy_type,
- consistency_after_fallback,
- consistency_after_restore,
+ {group, consistency_after_fallback},
+ {group, consistency_after_restore},
consistency_after_rename_of_node,
- checkpoint_retainer_consistency,
- backup_consistency
- ].
+ {group, checkpoint_retainer_consistency},
+ {group, backup_consistency}].
+
+groups() ->
+ [{consistency_after_restart, [],
+ [consistency_after_restart_1_ram,
+ consistency_after_restart_1_disc,
+ consistency_after_restart_1_disc_only,
+ consistency_after_restart_2_ram,
+ consistency_after_restart_2_disc,
+ consistency_after_restart_2_disc_only]},
+ {consistency_after_dump_tables, [],
+ [consistency_after_dump_tables_1_ram,
+ consistency_after_dump_tables_2_ram]},
+ {consistency_after_add_replica, [],
+ [consistency_after_add_replica_2_ram,
+ consistency_after_add_replica_2_disc,
+ consistency_after_add_replica_2_disc_only,
+ consistency_after_add_replica_3_ram,
+ consistency_after_add_replica_3_disc,
+ consistency_after_add_replica_3_disc_only]},
+ {consistency_after_del_replica, [],
+ [consistency_after_del_replica_2_ram,
+ consistency_after_del_replica_2_disc,
+ consistency_after_del_replica_2_disc_only,
+ consistency_after_del_replica_3_ram,
+ consistency_after_del_replica_3_disc,
+ consistency_after_del_replica_3_disc_only]},
+ {consistency_after_move_replica, [],
+ [consistency_after_move_replica_2_ram,
+ consistency_after_move_replica_2_disc,
+ consistency_after_move_replica_2_disc_only,
+ consistency_after_move_replica_3_ram,
+ consistency_after_move_replica_3_disc,
+ consistency_after_move_replica_3_disc_only]},
+ {consistency_after_transform_table, [],
+ [consistency_after_transform_table_ram,
+ consistency_after_transform_table_disc,
+ consistency_after_transform_table_disc_only]},
+ {consistency_after_fallback, [],
+ [consistency_after_fallback_2_ram,
+ consistency_after_fallback_2_disc,
+ consistency_after_fallback_2_disc_only,
+ consistency_after_fallback_3_ram,
+ consistency_after_fallback_3_disc,
+ consistency_after_fallback_3_disc_only]},
+ {consistency_after_restore, [],
+ [consistency_after_restore_clear_ram,
+ consistency_after_restore_clear_disc,
+ consistency_after_restore_clear_disc_only,
+ consistency_after_restore_recreate_ram,
+ consistency_after_restore_recreate_disc,
+ consistency_after_restore_recreate_disc_only]},
+ {checkpoint_retainer_consistency, [],
+ [{group, updates_during_checkpoint_activation},
+ {group, updates_during_checkpoint_iteration},
+ {group, load_table_with_activated_checkpoint},
+ {group,
+ add_table_copy_to_table_with_activated_checkpoint}]},
+ {updates_during_checkpoint_activation, [],
+ [updates_during_checkpoint_activation_2_ram,
+ updates_during_checkpoint_activation_2_disc,
+ updates_during_checkpoint_activation_2_disc_only,
+ updates_during_checkpoint_activation_3_ram,
+ updates_during_checkpoint_activation_3_disc,
+ updates_during_checkpoint_activation_3_disc_only]},
+ {updates_during_checkpoint_iteration, [],
+ [updates_during_checkpoint_iteration_2_ram,
+ updates_during_checkpoint_iteration_2_disc,
+ updates_during_checkpoint_iteration_2_disc_only]},
+ {load_table_with_activated_checkpoint, [],
+ [load_table_with_activated_checkpoint_ram,
+ load_table_with_activated_checkpoint_disc,
+ load_table_with_activated_checkpoint_disc_only]},
+ {add_table_copy_to_table_with_activated_checkpoint, [],
+ [add_table_copy_to_table_with_activated_checkpoint_ram,
+ add_table_copy_to_table_with_activated_checkpoint_disc,
+ add_table_copy_to_table_with_activated_checkpoint_disc_only]},
+ {backup_consistency, [],
+ [{group, interupted_install_fallback},
+ {group, interupted_uninstall_fallback},
+ {group, mnesia_down_during_backup_causes_switch},
+ {group, mnesia_down_during_backup_causes_abort},
+ {group, schema_transactions_during_backup}]},
+ {interupted_install_fallback, [],
+ [inst_fallback_process_dies, fatal_when_inconsistency]},
+ {interupted_uninstall_fallback, [], [after_delete]},
+ {mnesia_down_during_backup_causes_switch, [],
+ [cause_switch_before, cause_switch_after]},
+ {mnesia_down_during_backup_causes_abort, [],
+ [cause_abort_before, cause_abort_after]},
+ {schema_transactions_during_backup, [],
+ [change_schema_before, change_schema_after]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
@@ -185,15 +273,6 @@ receive_messages(ListOfMsgs) ->
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-consistency_after_restart(suite) ->
- [
- consistency_after_restart_1_ram,
- consistency_after_restart_1_disc,
- consistency_after_restart_1_disc_only,
- consistency_after_restart_2_ram,
- consistency_after_restart_2_disc,
- consistency_after_restart_2_disc_only
- ].
consistency_after_restart_1_ram(suite) -> [];
consistency_after_restart_1_ram(Config) when is_list(Config) ->
@@ -237,11 +316,6 @@ consistency_after_restart(ReplicaType, NodeConfig, Config) ->
?verify_mnesia(Nodes, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-consistency_after_dump_tables(suite) ->
- [
- consistency_after_dump_tables_1_ram,
- consistency_after_dump_tables_2_ram
- ].
consistency_after_dump_tables_1_ram(suite) -> [];
consistency_after_dump_tables_1_ram(Config) when is_list(Config) ->
@@ -274,15 +348,6 @@ consistency_after_dump_tables(ReplicaType, NodeConfig, Config) ->
?verify_mnesia(Nodes, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-consistency_after_add_replica(suite) ->
- [
- consistency_after_add_replica_2_ram,
- consistency_after_add_replica_2_disc,
- consistency_after_add_replica_2_disc_only,
- consistency_after_add_replica_3_ram,
- consistency_after_add_replica_3_disc,
- consistency_after_add_replica_3_disc_only
- ].
consistency_after_add_replica_2_ram(suite) -> [];
consistency_after_add_replica_2_ram(Config) when is_list(Config) ->
@@ -326,15 +391,6 @@ consistency_after_add_replica(ReplicaType, NodeConfig, Config) ->
?verify_mnesia(Nodes0, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-consistency_after_del_replica(suite) ->
- [
- consistency_after_del_replica_2_ram,
- consistency_after_del_replica_2_disc,
- consistency_after_del_replica_2_disc_only,
- consistency_after_del_replica_3_ram,
- consistency_after_del_replica_3_disc,
- consistency_after_del_replica_3_disc_only
- ].
consistency_after_del_replica_2_ram(suite) -> [];
consistency_after_del_replica_2_ram(Config) when is_list(Config) ->
@@ -377,15 +433,6 @@ consistency_after_del_replica(ReplicaType, NodeConfig, Config) ->
?verify_mnesia(Nodes, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-consistency_after_move_replica(suite) ->
- [
- consistency_after_move_replica_2_ram,
- consistency_after_move_replica_2_disc,
- consistency_after_move_replica_2_disc_only,
- consistency_after_move_replica_3_ram,
- consistency_after_move_replica_3_disc,
- consistency_after_move_replica_3_disc_only
- ].
consistency_after_move_replica_2_ram(suite) -> [];
consistency_after_move_replica_2_ram(Config) when is_list(Config) ->
@@ -430,16 +477,6 @@ consistency_after_move_replica(ReplicaType, NodeConfig, Config) ->
?verify_mnesia(Nodes, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-consistency_after_transform_table(doc) ->
- ["Check that the database is consistent after transform_table.",
- " While applications are updating the involved tables. "];
-
-consistency_after_transform_table(suite) ->
- [
- consistency_after_transform_table_ram,
- consistency_after_transform_table_disc,
- consistency_after_transform_table_disc_only
- ].
consistency_after_transform_table_ram(suite) -> [];
@@ -498,20 +535,6 @@ consistency_after_change_table_copy_type(doc) ->
" While applications are updating the involved tables. "].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-consistency_after_fallback(doc) ->
- ["Check that installed fallbacks are consistent. Check this by starting ",
- "some nodes, run tpcb on them, take a backup at any time, install it ",
- "as a fallback, kill all nodes, start mnesia again and check for ",
- "any inconsistencies"];
-consistency_after_fallback(suite) ->
- [
- consistency_after_fallback_2_ram,
- consistency_after_fallback_2_disc,
- consistency_after_fallback_2_disc_only,
- consistency_after_fallback_3_ram,
- consistency_after_fallback_3_disc
- , consistency_after_fallback_3_disc_only
- ].
consistency_after_fallback_2_ram(suite) -> [];
consistency_after_fallback_2_ram(Config) when is_list(Config) ->
@@ -583,18 +606,6 @@ consistency_after_fallback(ReplicaType, NodeConfig, Config) ->
?verify_mnesia(Nodes, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-consistency_after_restore(doc) ->
- ["Verify consistency after restore operations."];
-
-consistency_after_restore(suite) ->
- [
- consistency_after_restore_clear_ram,
- consistency_after_restore_clear_disc,
- consistency_after_restore_clear_disc_only,
- consistency_after_restore_recreate_ram,
- consistency_after_restore_recreate_disc,
- consistency_after_restore_recreate_disc_only
- ].
consistency_after_restore_clear_ram(suite) -> [];
consistency_after_restore_clear_ram(Config) when is_list(Config) ->
@@ -716,32 +727,8 @@ consistency_after_rename_of_node(doc) ->
["Skipped because it is an unimportant case."].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-checkpoint_retainer_consistency(doc) ->
- ["Verify that the contents of a checkpoint retainer has the expected",
- "contents in various situations."];
-checkpoint_retainer_consistency(suite) ->
- [
- updates_during_checkpoint_activation,
- updates_during_checkpoint_iteration,
- load_table_with_activated_checkpoint,
- add_table_copy_to_table_with_activated_checkpoint
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-updates_during_checkpoint_activation(doc) ->
- ["Perform updates while the checkpoint getting activated",
- "and verify that all checkpoint retainers associated with",
- "different replicas of the same table really has the same",
- "contents."];
-updates_during_checkpoint_activation(suite) ->
- [
- updates_during_checkpoint_activation_2_ram,
- updates_during_checkpoint_activation_2_disc,
- updates_during_checkpoint_activation_2_disc_only,
- updates_during_checkpoint_activation_3_ram,
- updates_during_checkpoint_activation_3_disc
- , updates_during_checkpoint_activation_3_disc_only
- ].
updates_during_checkpoint_activation_2_ram(suite) -> [];
updates_during_checkpoint_activation_2_ram(Config) when is_list(Config) ->
@@ -808,17 +795,6 @@ updates_during_checkpoint_activation(ReplicaType,NodeConfig,Config) ->
?verify_mnesia(Nodes, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-updates_during_checkpoint_iteration(doc) ->
- ["Perform updates while someone is iterating over a checkpoint",
- "and verify that the iterator really finds the expected data",
- "regardless of ongoing upates."];
-
-updates_during_checkpoint_iteration(suite) ->
- [
- updates_during_checkpoint_iteration_2_ram,
- updates_during_checkpoint_iteration_2_disc
- , updates_during_checkpoint_iteration_2_disc_only
- ].
updates_during_checkpoint_iteration_2_ram(suite) -> [];
updates_during_checkpoint_iteration_2_ram(Config) when is_list(Config) ->
@@ -890,17 +866,6 @@ loop_accounts(N_br, N_acc) when N_acc >= 1 ->
loop_accounts(_,_) -> done.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-load_table_with_activated_checkpoint(doc) ->
- ["Load a table with a checkpoint attached to it and verify that the",
- "newly loaded replica also gets a checkpoint retainer attached to it",
- "and that it is consistent with the original retainer."];
-
-load_table_with_activated_checkpoint(suite) ->
- [
- load_table_with_activated_checkpoint_ram,
- load_table_with_activated_checkpoint_disc,
- load_table_with_activated_checkpoint_disc_only
- ].
load_table_with_activated_checkpoint_ram(suite) -> [];
load_table_with_activated_checkpoint_ram(Config) when is_list(Config) ->
@@ -986,18 +951,6 @@ view(Source, Mod) ->
lists:sort(TabList).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-add_table_copy_to_table_with_activated_checkpoint(doc) ->
- ["Add a replica to a table with a checkpoint attached to it",
- "and verify that the new replica also gets a checkpoint",
- "retainer attached to it and that it is consistent with the",
- "original retainer."];
-
-add_table_copy_to_table_with_activated_checkpoint(suite) ->
- [
- add_table_copy_to_table_with_activated_checkpoint_ram,
- add_table_copy_to_table_with_activated_checkpoint_disc,
- add_table_copy_to_table_with_activated_checkpoint_disc_only
- ].
add_table_copy_to_table_with_activated_checkpoint_ram(suite) -> [];
add_table_copy_to_table_with_activated_checkpoint_ram(Config) when is_list(Config) ->
@@ -1070,25 +1023,8 @@ add_table_copy_to_table_with_activated_checkpoint(Type,Config) ->
?verify_mnesia(Nodes, []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-backup_consistency(suite) ->
- [
- interupted_install_fallback,
- interupted_uninstall_fallback,
- mnesia_down_during_backup_causes_switch,
- mnesia_down_during_backup_causes_abort,
- schema_transactions_during_backup
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-interupted_install_fallback(doc) ->
- ["Verify that a interrupted install_fallback really",
- "is performed on all nodes or none"];
-
-interupted_install_fallback(suite) ->
- [
- inst_fallback_process_dies,
- fatal_when_inconsistency
- ].
inst_fallback_process_dies(suite) ->
[];
@@ -1232,13 +1168,6 @@ is_running(Node, Shouldbe) ->
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-interupted_uninstall_fallback(doc) ->
- ["Verify that a interrupted uninstall_fallback really",
- "is performed on all nodes or none"];
-interupted_uninstall_fallback(suite) ->
- [
- after_delete
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1371,17 +1300,6 @@ do_uninstall(Config,DebugPoint) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-mnesia_down_during_backup_causes_switch(doc) ->
- ["Verify that an ongoing backup is not disturbed",
- "even if the node hosting the replica that currently",
- "is being backup'ed is stopped. The backup utility",
- "is expected to switch over to another replica and",
- "fulfill the backup."];
-mnesia_down_during_backup_causes_switch(suite) ->
- [
- cause_switch_before,
- cause_switch_after
- ].
%%%%%%%%%%%%%%%
@@ -1401,16 +1319,6 @@ cause_switch_after(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-mnesia_down_during_backup_causes_abort(doc) ->
- ["Verify that an ongoing backup is aborted nicely",
- "without leaving any backup file if the last replica",
- "of a table becomes unavailable due to a node down",
- "or some crash."];
-mnesia_down_during_backup_causes_abort(suite) ->
- [
- cause_abort_before,
- cause_abort_after
- ].
%%%%%%%%%%%%%%%%%%
@@ -1432,14 +1340,6 @@ cause_abort_after(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-schema_transactions_during_backup(doc) ->
- ["Verify that an schema transactions does not",
- "affect an ongoing backup."];
-schema_transactions_during_backup(suite) ->
- [
- change_schema_before,
- change_schema_after
- ].
%%%%%%%%%%%%%
diff --git a/lib/mnesia/test/mnesia_cost.erl b/lib/mnesia/test/mnesia_cost.erl
index 54cb2b3064..3221f46f61 100644
--- a/lib/mnesia/test/mnesia_cost.erl
+++ b/lib/mnesia/test/mnesia_cost.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/mnesia/test/mnesia_dirty_access_test.erl b/lib/mnesia/test/mnesia_dirty_access_test.erl
index 5f9f2a9733..abbdab48c0 100644
--- a/lib/mnesia/test/mnesia_dirty_access_test.erl
+++ b/lib/mnesia/test/mnesia_dirty_access_test.erl
@@ -26,37 +26,72 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Evil dirty access, regardless of transaction scope.",
- "Invoke all functions in the API and try to cover all legal uses",
- "cases as well the illegal dito. This is a complement to the",
- "other more explicit test cases."];
-all(suite) ->
- [
- dirty_write,
- dirty_read,
- dirty_update_counter,
- dirty_delete,
- dirty_delete_object,
- dirty_match_object,
- dirty_index,
- dirty_iter,
- admin_tests
- ].
+all() ->
+ [{group, dirty_write}, {group, dirty_read},
+ {group, dirty_update_counter}, {group, dirty_delete},
+ {group, dirty_delete_object},
+ {group, dirty_match_object}, {group, dirty_index},
+ {group, dirty_iter}, {group, admin_tests}].
+
+groups() ->
+ [{dirty_write, [],
+ [dirty_write_ram, dirty_write_disc,
+ dirty_write_disc_only]},
+ {dirty_read, [],
+ [dirty_read_ram, dirty_read_disc,
+ dirty_read_disc_only]},
+ {dirty_update_counter, [],
+ [dirty_update_counter_ram, dirty_update_counter_disc,
+ dirty_update_counter_disc_only]},
+ {dirty_delete, [],
+ [dirty_delete_ram, dirty_delete_disc,
+ dirty_delete_disc_only]},
+ {dirty_delete_object, [],
+ [dirty_delete_object_ram, dirty_delete_object_disc,
+ dirty_delete_object_disc_only]},
+ {dirty_match_object, [],
+ [dirty_match_object_ram, dirty_match_object_disc,
+ dirty_match_object_disc_only]},
+ {dirty_index, [],
+ [{group, dirty_index_match_object},
+ {group, dirty_index_read},
+ {group, dirty_index_update}]},
+ {dirty_index_match_object, [],
+ [dirty_index_match_object_ram,
+ dirty_index_match_object_disc,
+ dirty_index_match_object_disc_only]},
+ {dirty_index_read, [],
+ [dirty_index_read_ram, dirty_index_read_disc,
+ dirty_index_read_disc_only]},
+ {dirty_index_update, [],
+ [dirty_index_update_set_ram,
+ dirty_index_update_set_disc,
+ dirty_index_update_set_disc_only,
+ dirty_index_update_bag_ram, dirty_index_update_bag_disc,
+ dirty_index_update_bag_disc_only]},
+ {dirty_iter, [],
+ [dirty_iter_ram, dirty_iter_disc,
+ dirty_iter_disc_only]},
+ {admin_tests, [],
+ [del_table_copy_1, del_table_copy_2, del_table_copy_3,
+ add_table_copy_1, add_table_copy_2, add_table_copy_3,
+ add_table_copy_4, move_table_copy_1, move_table_copy_2,
+ move_table_copy_3, move_table_copy_4]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Write records dirty
-dirty_write(suite) ->
- [
- dirty_write_ram,
- dirty_write_disc,
- dirty_write_disc_only
- ].
dirty_write_ram(suite) -> [];
dirty_write_ram(Config) when is_list(Config) ->
@@ -88,12 +123,6 @@ dirty_write(Config, Storage) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Read records dirty
-dirty_read(suite) ->
- [
- dirty_read_ram,
- dirty_read_disc,
- dirty_read_disc_only
- ].
dirty_read_ram(suite) -> [];
dirty_read_ram(Config) when is_list(Config) ->
@@ -137,12 +166,6 @@ dirty_read(Config, Storage) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Update counter record dirty
-dirty_update_counter(suite) ->
- [
- dirty_update_counter_ram,
- dirty_update_counter_disc,
- dirty_update_counter_disc_only
- ].
dirty_update_counter_ram(suite) -> [];
dirty_update_counter_ram(Config) when is_list(Config) ->
@@ -180,12 +203,6 @@ dirty_update_counter(Config, Storage) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Delete record dirty
-dirty_delete(suite) ->
- [
- dirty_delete_ram,
- dirty_delete_disc,
- dirty_delete_disc_only
- ].
dirty_delete_ram(suite) -> [];
dirty_delete_ram(Config) when is_list(Config) ->
@@ -223,12 +240,6 @@ dirty_delete(Config, Storage) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Delete matching record dirty
-dirty_delete_object(suite) ->
- [
- dirty_delete_object_ram,
- dirty_delete_object_disc,
- dirty_delete_object_disc_only
- ].
dirty_delete_object_ram(suite) -> [];
dirty_delete_object_ram(Config) when is_list(Config) ->
@@ -272,12 +283,6 @@ dirty_delete_object(Config, Storage) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Read matching records dirty
-dirty_match_object(suite) ->
- [
- dirty_match_object_ram,
- dirty_match_object_disc,
- dirty_match_object_disc_only
- ].
dirty_match_object_ram(suite) -> [];
dirty_match_object_ram(Config) when is_list(Config) ->
@@ -311,22 +316,10 @@ dirty_match_object(Config, Storage) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-dirty_index(suite) ->
- [
- dirty_index_match_object,
- dirty_index_read,
- dirty_index_update
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Dirty read matching records by using an index
-dirty_index_match_object(suite) ->
- [
- dirty_index_match_object_ram,
- dirty_index_match_object_disc,
- dirty_index_match_object_disc_only
- ].
dirty_index_match_object_ram(suite) -> [];
dirty_index_match_object_ram(Config) when is_list(Config) ->
@@ -364,12 +357,6 @@ dirty_index_match_object(Config, Storage) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Read records by using an index
-dirty_index_read(suite) ->
- [
- dirty_index_read_ram,
- dirty_index_read_disc,
- dirty_index_read_disc_only
- ].
dirty_index_read_ram(suite) -> [];
dirty_index_read_ram(Config) when is_list(Config) ->
@@ -413,19 +400,6 @@ dirty_index_read(Config, Storage) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-dirty_index_update(suite) ->
- [
- dirty_index_update_set_ram,
- dirty_index_update_set_disc,
- dirty_index_update_set_disc_only,
- dirty_index_update_bag_ram,
- dirty_index_update_bag_disc,
- dirty_index_update_bag_disc_only
- ];
-dirty_index_update(doc) ->
- ["See Ticket OTP-2083, verifies that a table with a index is "
- "update in the correct way i.e. the index finds the correct "
- "records after a update"].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
dirty_index_update_set_ram(suite) -> [];
@@ -631,12 +605,6 @@ dirty_index_update_bag(Config, Storage) ->
%% Dirty iteration
%% dirty_slot, dirty_first, dirty_next
-dirty_iter(suite) ->
- [
- dirty_iter_ram,
- dirty_iter_disc,
- dirty_iter_disc_only
- ].
dirty_iter_ram(suite) -> [];
dirty_iter_ram(Config) when is_list(Config) ->
@@ -700,21 +668,6 @@ all_nexts(Tab, PrevKey) ->
[PrevKey] ++ all_nexts(Tab, Key).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-admin_tests(doc) ->
- ["Verifies that dirty operations work during schema operations"];
-
-admin_tests(suite) ->
- [del_table_copy_1,
- del_table_copy_2,
- del_table_copy_3,
- add_table_copy_1,
- add_table_copy_2,
- add_table_copy_3,
- add_table_copy_4,
- move_table_copy_1,
- move_table_copy_2,
- move_table_copy_3,
- move_table_copy_4].
update_trans(Tab, Key, Acc) ->
Update =
diff --git a/lib/mnesia/test/mnesia_durability_test.erl b/lib/mnesia/test/mnesia_durability_test.erl
index b917b0ca40..55205d1222 100644
--- a/lib/mnesia/test/mnesia_durability_test.erl
+++ b/lib/mnesia/test/mnesia_durability_test.erl
@@ -28,47 +28,54 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
-record(test_rec,{key,val}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Verify durability",
- "Verify that the effects of committed transactions are durable.",
- "The content of the tables tables must be restored at startup."];
-all(suite) ->
- [
- load_tables,
- durability_of_dump_tables,
+all() ->
+ [{group, load_tables},
+ {group, durability_of_dump_tables},
durability_of_disc_copies,
- durability_of_disc_only_copies
- ].
+ durability_of_disc_only_copies].
+
+groups() ->
+ [{load_tables, [],
+ [load_latest_data, load_local_contents_directly,
+ load_directly_when_all_are_ram_copiesA,
+ load_directly_when_all_are_ram_copiesB,
+ {group, late_load_when_all_are_ram_copies_on_ram_nodes},
+ load_when_last_replica_becomes_available,
+ load_when_we_have_down_from_all_other_replica_nodes,
+ late_load_transforms_into_disc_load,
+ late_load_leads_to_hanging,
+ force_load_when_nobody_intents_to_load,
+ force_load_when_someone_has_decided_to_load,
+ force_load_when_someone_else_already_has_loaded,
+ force_load_when_we_has_loaded,
+ force_load_on_a_non_local_table,
+ force_load_when_the_table_does_not_exist,
+ {group, load_tables_with_master_tables}]},
+ {late_load_when_all_are_ram_copies_on_ram_nodes, [],
+ [late_load_when_all_are_ram_copies_on_ram_nodes1,
+ late_load_when_all_are_ram_copies_on_ram_nodes2]},
+ {load_tables_with_master_tables, [],
+ [master_nodes, starting_master_nodes,
+ master_on_non_local_tables,
+ remote_force_load_with_local_master_node]},
+ {durability_of_dump_tables, [],
+ [dump_ram_copies, dump_disc_copies, dump_disc_only]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-load_tables(doc) ->
- ["Try to provoke all kinds of table load scenarios."];
-load_tables(suite) ->
- [
- load_latest_data,
- load_local_contents_directly,
- load_directly_when_all_are_ram_copiesA,
- load_directly_when_all_are_ram_copiesB,
- late_load_when_all_are_ram_copies_on_ram_nodes,
- load_when_last_replica_becomes_available,
- load_when_we_have_down_from_all_other_replica_nodes,
- late_load_transforms_into_disc_load,
- late_load_leads_to_hanging,
- force_load_when_nobody_intents_to_load,
- force_load_when_someone_has_decided_to_load,
- force_load_when_someone_else_already_has_loaded,
- force_load_when_we_has_loaded,
- force_load_on_a_non_local_table,
- force_load_when_the_table_does_not_exist,
- load_tables_with_master_tables
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
load_latest_data(doc) ->
@@ -284,13 +291,6 @@ load_directly_when_all_are_ram_copiesB(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-late_load_when_all_are_ram_copies_on_ram_nodes(doc) ->
- ["Load of ram_copies tables when all replicas resides on disc less nodes"];
-late_load_when_all_are_ram_copies_on_ram_nodes(suite) ->
- [
- late_load_when_all_are_ram_copies_on_ram_nodes1,
- late_load_when_all_are_ram_copies_on_ram_nodes2
- ].
late_load_when_all_are_ram_copies_on_ram_nodes1(suite) -> [];
late_load_when_all_are_ram_copies_on_ram_nodes1(Config) when is_list(Config) ->
@@ -916,22 +916,6 @@ force_load_when_the_table_does_not_exist(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-load_tables_with_master_tables(doc) ->
- ["Verifies the semantics of different master nodes settings",
- "The semantics should be:",
- "1. Mnesia downs, Normally decides from where mnesia should load tables",
- "2. Master tables (overrides mnesia downs) ",
- "3. Force load (overrides Master tables) ",
- "--- 1st from active master nodes",
- "--- 2nd from active nodes",
- "--- 3rd get local copy (if ram create new one)"
- ];
-
-load_tables_with_master_tables(suite) ->
- [master_nodes,
- starting_master_nodes,
- master_on_non_local_tables,
- remote_force_load_with_local_master_node].
-define(SDwrite(Tup), fun() -> mnesia:write(Tup) end).
@@ -1156,13 +1140,6 @@ remote_force_load_with_local_master_node(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-durability_of_dump_tables(doc) ->
- [ "Verify that all tables contain the correct data when Mnesia",
- "is restarted and tables are loaded from disc to recover",
- " their previous contents. " ];
-durability_of_dump_tables(suite) -> [dump_ram_copies,
- dump_disc_copies,
- dump_disc_only].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/mnesia/test/mnesia_evil_backup.erl b/lib/mnesia/test/mnesia_evil_backup.erl
index bbbebeb02c..63f4146d98 100644
--- a/lib/mnesia/test/mnesia_evil_backup.erl
+++ b/lib/mnesia/test/mnesia_evil_backup.erl
@@ -35,31 +35,30 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Checking all the functionality regarding ",
- "to the backup and different ",
- "kinds of restore and fallback interface"];
-
-all(suite) ->
- [
- backup,
- bad_backup,
- global_backup_checkpoint,
- restore_tables,
- traverse_backup,
+all() ->
+ [backup, bad_backup, global_backup_checkpoint,
+ {group, restore_tables}, traverse_backup,
selective_backup_checkpoint,
- incremental_backup_checkpoint,
-%% local_backup_checkpoint,
- install_fallback,
- uninstall_fallback,
- local_fallback,
- sops_with_checkpoint
- ].
+ incremental_backup_checkpoint, install_fallback,
+ uninstall_fallback, local_fallback,
+ sops_with_checkpoint].
+
+groups() ->
+ [{restore_tables, [],
+ [restore_errors, restore_clear, restore_keep,
+ restore_recreate, restore_clear_ram]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
backup(doc) -> ["Checking the interface to the function backup",
"We don't check that the backups can be used here",
@@ -132,17 +131,6 @@ global_backup_checkpoint(Config) when is_list(Config) ->
?match(ok, file:delete(File2)),
?verify_mnesia(Nodes, []).
-restore_tables(doc) ->
- ["Tests the interface of restore"];
-
-restore_tables(suite) ->
- [
- restore_errors,
- restore_clear,
- restore_keep,
- restore_recreate,
- restore_clear_ram
- ].
restore_errors(suite) -> [];
restore_errors(Config) when is_list(Config) ->
diff --git a/lib/mnesia/test/mnesia_evil_coverage_test.erl b/lib/mnesia/test/mnesia_evil_coverage_test.erl
index 4fbf1b4003..668eba176f 100644
--- a/lib/mnesia/test/mnesia_evil_coverage_test.erl
+++ b/lib/mnesia/test/mnesia_evil_coverage_test.erl
@@ -30,45 +30,54 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Evil usage of the API.",
- "Invoke all functions in the API and try to cover all legal uses",
- "cases as well the illegal dito. This is a complement to the",
- "other more explicit test cases."];
-all(suite) ->
- [
- system_info,
- table_info,
- error_description,
- db_node_lifecycle,
- evil_delete_db_node,
- start_and_stop,
- checkpoint,
- table_lifecycle,
- add_copy_conflict,
- add_copy_when_going_down,
- replica_management,
- schema_availability,
- local_content,
- table_access_modifications,
- replica_location,
- table_sync,
- user_properties,
- unsupp_user_props,
- record_name,
- snmp_access,
- subscriptions,
- iteration,
- debug_support,
- sorted_ets,
+all() ->
+ [system_info, table_info, error_description,
+ db_node_lifecycle, evil_delete_db_node, start_and_stop,
+ checkpoint, table_lifecycle, add_copy_conflict,
+ add_copy_when_going_down, replica_management,
+ schema_availability, local_content,
+ {group, table_access_modifications}, replica_location,
+ {group, table_sync}, user_properties, unsupp_user_props,
+ {group, record_name}, {group, snmp_access},
+ {group, subscriptions}, {group, iteration},
+ {group, debug_support}, sorted_ets,
{mnesia_dirty_access_test, all},
{mnesia_trans_access_test, all},
- {mnesia_evil_backup, all}
- ].
+ {mnesia_evil_backup, all}].
+
+groups() ->
+ [{table_access_modifications, [],
+ [change_table_access_mode, change_table_load_order,
+ set_master_nodes, offline_set_master_nodes]},
+ {table_sync, [],
+ [dump_tables, dump_log, wait_for_tables,
+ force_load_table]},
+ {snmp_access, [],
+ [snmp_open_table, snmp_close_table, snmp_get_next_index,
+ snmp_get_row, snmp_get_mnesia_key, snmp_update_counter,
+ snmp_order]},
+ {subscriptions, [],
+ [subscribe_standard, subscribe_extended]},
+ {iteration, [], [foldl]},
+ {debug_support, [],
+ [info, schema_0, schema_1, view_0, view_1, view_2,
+ lkill, kill]},
+ {record_name, [], [{group, record_name_dirty_access}]},
+ {record_name_dirty_access, [],
+ [record_name_dirty_access_ram,
+ record_name_dirty_access_disc,
+ record_name_dirty_access_disc_only]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -910,13 +919,6 @@ local_content(Config) when is_list(Config) ->
?verify_mnesia(Nodes, []).
-table_access_modifications(suite) ->
- [
- change_table_access_mode,
- change_table_load_order,
- set_master_nodes,
- offline_set_master_nodes
- ].
change_table_access_mode(suite) -> [];
change_table_access_mode(Config) when is_list(Config) ->
@@ -1103,13 +1105,6 @@ offline_set_master_nodes(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Syncronize table with log or disc
%%
-table_sync(suite) ->
- [
- dump_tables,
- dump_log,
- wait_for_tables,
- force_load_table
- ].
%% Dump ram tables on disc
dump_tables(suite) -> [];
@@ -1359,19 +1354,6 @@ unsupp_user_props(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-snmp_access(doc) ->
- ["Make Mnesia table accessible via SNMP"];
-
-snmp_access(suite) ->
- [
- snmp_open_table,
- snmp_close_table,
- snmp_get_next_index,
- snmp_get_row,
- snmp_get_mnesia_key,
- snmp_update_counter,
- snmp_order
- ].
snmp_open_table(suite) -> [];
snmp_open_table(Config) when is_list(Config) ->
@@ -1779,11 +1761,6 @@ get_keys(Tab, Key) ->
-record(tab, {i, e1, e2}). % Simple test table
-subscriptions(doc) ->
- ["Test the event subscription mechanism"];
-subscriptions(suite) ->
- [subscribe_standard,
- subscribe_extended].
subscribe_extended(doc) ->
["Test the extended set of events, test with and without checkpoints. "];
@@ -2009,10 +1986,6 @@ recv_event() ->
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-iteration(doc) ->
- ["Verify that the iteration functions works as expected"];
-iteration(suite) ->
- [foldl].
foldl(suite) ->
@@ -2074,19 +2047,6 @@ sort_res(Else) ->
Else.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-debug_support(doc) ->
- ["Check that the debug support has not decayed."];
-debug_support(suite) ->
- [
- info,
- schema_0,
- schema_1,
- view_0,
- view_1,
- view_2,
- lkill,
- kill
- ].
info(suite) -> [];
info(Config) when is_list(Config) ->
@@ -2173,21 +2133,7 @@ kill(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-record_name(doc) ->
- ["Verify that record names may be differ from the name of ",
- "the hosting table. Check at least access, restore, "
- "registry, subscriptions and traveres_backup"];
-record_name(suite) ->
- [
- record_name_dirty_access
- ].
-
-record_name_dirty_access(suite) ->
- [
- record_name_dirty_access_ram,
- record_name_dirty_access_disc,
- record_name_dirty_access_disc_only
- ].
+
record_name_dirty_access_ram(suite) ->
[];
diff --git a/lib/mnesia/test/mnesia_examples_test.erl b/lib/mnesia/test/mnesia_examples_test.erl
index d1b1409c9d..373d47a05a 100644
--- a/lib/mnesia/test/mnesia_examples_test.erl
+++ b/lib/mnesia/test/mnesia_examples_test.erl
@@ -26,8 +26,8 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
-define(init(N, Config),
mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
@@ -61,16 +61,21 @@ opt_load(Mod) ->
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Run all examples mentioned in the documentation",
- "Are really all examples covered?"];
-all(suite) ->
- [
- bup,
- company,
- meter,
- tpcb
- ].
+all() ->
+ [bup, company, meter, {group, tpcb}].
+
+groups() ->
+ [{tpcb, [],
+ [replica_test, sticky_replica_test, dist_test,
+ conflict_test, frag_test, frag2_test, remote_test,
+ remote_frag2_test]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bup(doc) -> ["Run the backup examples in bup.erl"];
@@ -85,19 +90,6 @@ company(doc) ->
["Run the company examples in company.erl and company_o.erl"].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-tpcb(doc) ->
- ["Run the sample configurations of the stress tests in mnesia_tpcb.erl"];
-tpcb(suite) ->
- [
- replica_test,
- sticky_replica_test,
- dist_test,
- conflict_test,
- frag_test,
- frag2_test,
- remote_test,
- remote_frag2_test
- ].
replica_test(suite) -> [];
replica_test(Config) when is_list(Config) ->
diff --git a/lib/mnesia/test/mnesia_frag_test.erl b/lib/mnesia/test/mnesia_frag_test.erl
index 4add340254..d3f6762af7 100644
--- a/lib/mnesia/test/mnesia_frag_test.erl
+++ b/lib/mnesia/test/mnesia_frag_test.erl
@@ -27,8 +27,8 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
-define(match_dist(ExpectedRes, Expr),
case ?match(ExpectedRes, Expr) of
@@ -37,34 +37,29 @@ fin_per_testcase(Func, Conf) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Verify the functionality of fragmented tables"];
-all(suite) ->
- [
- light,
- medium
- ].
-
-light(suite) ->
- [
- nice,
- evil
- ].
-
-medium(suite) ->
- [
- consistency
- ].
+all() ->
+ [{group, light}, {group, medium}].
+
+groups() ->
+ [{light, [], [{group, nice}, {group, evil}]},
+ {medium, [], [consistency]},
+ {nice, [],
+ [nice_single, nice_multi, nice_access, iter_access]},
+ {evil, [],
+ [evil_create, evil_delete, evil_change, evil_combine,
+ evil_loop, evil_delete_db_node]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-nice(suite) ->
- [
- nice_single,
- nice_multi,
- nice_access,
- iter_access
- ].
nice_single(suite) -> [];
nice_single(Config) when is_list(Config) ->
@@ -503,17 +498,6 @@ consistency(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-evil(doc) ->
- ["Evil coverage of fragmentation API."];
-evil(suite) ->
- [
- evil_create,
- evil_delete,
- evil_change,
- evil_combine,
- evil_loop,
- evil_delete_db_node
- ].
evil_create(suite) -> [];
evil_create(Config) when is_list(Config) ->
diff --git a/lib/mnesia/test/mnesia_inconsistent_database_test.erl b/lib/mnesia/test/mnesia_inconsistent_database_test.erl
index b19cd8e01b..c4b6257d5b 100644
--- a/lib/mnesia/test/mnesia_inconsistent_database_test.erl
+++ b/lib/mnesia/test/mnesia_inconsistent_database_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/mnesia/test/mnesia_install_test.erl b/lib/mnesia/test/mnesia_install_test.erl
index 42a2a19f37..5d55fcac0e 100644
--- a/lib/mnesia/test/mnesia_install_test.erl
+++ b/lib/mnesia/test/mnesia_install_test.erl
@@ -27,29 +27,22 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Run some small but demanding test cases in order to verify",
- "that the basic functionality in Mnesia still works.",
- "",
- "Try some very simple things to begin with and increase the",
- "difficulty stepwise. This test suite should be run before",
- "all the others if you expect to find bugs.",
- "",
- "The function mnesia_install_test:silly() does not use the whole",
- "infra structure of the test suite. Invoke it on a single node to",
- "begin with. If that works, proceed with pong = net_adm:ping(SomeOtherNode)",
- "and rerun silly() in order to perform some distributed tests."];
-all(suite) ->
- [
- silly_durability,
- silly_move,
- silly_upgrade
- %,stress
- ].
+all() ->
+ [silly_durability, silly_move, silly_upgrade].
+
+groups() ->
+ [{stress, [], stress_cases()}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Stepwise of more and more advanced features
@@ -86,11 +79,11 @@ silly2(Config) when is_list(Config) ->
[schema])),
MoveRes = silly_move(Config),
UpgradeRes = silly_upgrade(Config),
- StressRes = [StressFun(F) || F <- stress(suite)],
+ StressRes = [StressFun(F) || F <- stress_cases()],
?verify_mnesia([Node2], []),
[Res, MoveRes, UpgradeRes] ++ StressRes;
_ ->
- StressRes = [StressFun(F) || F <- stress(suite)],
+ StressRes = [StressFun(F) || F <- stress_cases()],
?warning("Too few nodes. Perform net_adm:ping(OtherNode) "
"and rerun!!!~n", []),
[Res | StressRes]
@@ -286,13 +279,9 @@ transform_some_records(Tab1, _Tab2, Old) ->
lists:sort(lists:zf(Filter, Old)).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-stress(doc) ->
- ["Stress the system a little"];
-stress(suite) ->
- [
- conflict,
- dist
- ].
+
+stress_cases() ->
+[conflict, dist].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
dist(doc) ->
diff --git a/lib/mnesia/test/mnesia_isolation_test.erl b/lib/mnesia/test/mnesia_isolation_test.erl
index 4fc6e8fe58..3273bc4d40 100644
--- a/lib/mnesia/test/mnesia_isolation_test.erl
+++ b/lib/mnesia/test/mnesia_isolation_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -27,46 +27,53 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Verify the isolation property.",
- "Operations of concurrent transactions must yield results which",
- "are indistinguishable from the results which would be obtained by",
- "forcing each transaction to be serially executed to completion in",
- "some order. This means that repeated reads of the same records",
- "within any committed transaction must have returned identical",
- "data when run concurrently with any mix of arbitary transactions.",
- "Updates in one transaction must not be visible in any other",
- "transaction before the transaction has been committed."];
-all(suite) ->
- [
- locking,
- visibility
- ].
+all() ->
+ [{group, locking}, {group, visibility}].
+
+groups() ->
+ [{locking, [],
+ [no_conflict, simple_queue_conflict,
+ advanced_queue_conflict, simple_deadlock_conflict,
+ advanced_deadlock_conflict, lock_burst,
+ {group, sticky_locks}, {group, unbound_locking},
+ {group, admin_conflict}, nasty]},
+ {sticky_locks, [], [basic_sticky_functionality]},
+ {unbound_locking, [], [unbound1, unbound2]},
+ {admin_conflict, [],
+ [create_table, delete_table, move_table_copy,
+ add_table_index, del_table_index, transform_table,
+ snmp_open_table, snmp_close_table,
+ change_table_copy_type, change_table_access,
+ add_table_copy, del_table_copy, dump_tables,
+ {group, extra_admin_tests}]},
+ {extra_admin_tests, [],
+ [del_table_copy_1, del_table_copy_2, del_table_copy_3,
+ add_table_copy_1, add_table_copy_2, add_table_copy_3,
+ add_table_copy_4, move_table_copy_1, move_table_copy_2,
+ move_table_copy_3, move_table_copy_4]},
+ {visibility, [],
+ [dirty_updates_visible_direct,
+ dirty_reads_regardless_of_trans,
+ trans_update_invisibible_outside_trans,
+ trans_update_visible_inside_trans, write_shadows,
+ delete_shadows, write_delete_shadows_bag,
+ write_delete_shadows_bag2, {group, iteration},
+ shadow_search, snmp_shadows]},
+ {removed_resources, [], [rr_kill_copy]},
+ {iteration, [], [foldl, first_next]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-locking(doc) ->
- ["Verify locking semantics for various configurations",
- " NoLock = lock_funs(no_lock, any_granularity)",
- " SharedLock = lock_funs(shared_lock, any_granularity)",
- " ExclusiveLock = lock_funs(exclusive_lock, any_granularity)",
- " AnyLock = lock_funs(any_lock, any_granularity)"];
-locking(suite) ->
- [no_conflict,
- simple_queue_conflict,
- advanced_queue_conflict,
- simple_deadlock_conflict,
- advanced_deadlock_conflict,
- lock_burst,
- sticky_locks,
- unbound_locking,
- admin_conflict,
-%% removed_resources,
- nasty
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -431,14 +438,6 @@ burst_incr(Tab, Father) ->
Father ! burst_incr_done.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-sticky_locks(doc) ->
- ["Simple Tests of sticky locks"];
-
-sticky_locks(suite) ->
- [
- basic_sticky_functionality
- %% Needs to be expandand a little bit further
- ].
basic_sticky_functionality(suite) -> [];
basic_sticky_functionality(Config) when is_list(Config) ->
@@ -519,12 +518,6 @@ get_held() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-unbound_locking(suite) ->
- [unbound1, unbound2];
-
-unbound_locking(doc) ->
- ["Check that mnesia handles unbound key variables, GPRS bug."
- "Ticket id: OTP-3342"].
unbound1(suite) -> [];
unbound1(Config) when is_list(Config) ->
@@ -637,25 +630,6 @@ receiver() ->
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-admin_conflict(doc) ->
- ["Provoke lock conflicts with schema transactions and checkpoints."];
-admin_conflict(suite) ->
- [
- create_table,
- delete_table,
- move_table_copy,
- add_table_index,
- del_table_index,
- transform_table,
- snmp_open_table,
- snmp_close_table,
- change_table_copy_type,
- change_table_access,
- add_table_copy,
- del_table_copy,
- dump_tables,
- extra_admin_tests
- ].
create_table(suite) -> [];
create_table(Config) when is_list(Config) ->
@@ -1088,18 +1062,6 @@ insert(Tab, N) when N > 0 ->
ok = mnesia:sync_dirty(fun() -> mnesia:write({Tab, N, N, 0}) end),
insert(Tab, N-1).
-extra_admin_tests(suite) ->
- [del_table_copy_1,
- del_table_copy_2,
- del_table_copy_3,
- add_table_copy_1,
- add_table_copy_2,
- add_table_copy_3,
- add_table_copy_4,
- move_table_copy_1,
- move_table_copy_2,
- move_table_copy_3,
- move_table_copy_4].
update_own(Tab, Key, Acc) ->
Update =
@@ -1347,23 +1309,6 @@ move_table(CallFrom, FromNode, ToNode, [Node1, Node2, Node3], Def) ->
?verify_mnesia([Node1, Node2, Node3], []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-visibility(doc) ->
- ["Verify the visibility semantics for various configurations"];
-visibility(suite) ->
- [
- dirty_updates_visible_direct,
- dirty_reads_regardless_of_trans,
- trans_update_invisibible_outside_trans,
- trans_update_visible_inside_trans,
- write_shadows,
- delete_shadows,
-%% delete_shadows2,
- write_delete_shadows_bag,
- write_delete_shadows_bag2,
- iteration,
- shadow_search,
- snmp_shadows
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
dirty_updates_visible_direct(doc) ->
@@ -1969,10 +1914,6 @@ shadow_search(Config) when is_list(Config) ->
?verify_mnesia([Node1], []).
-removed_resources(suite) ->
- [rr_kill_copy];
-removed_resources(doc) ->
- ["Verify that the locking behave when resources are removed"].
rr_kill_copy(suite) -> [];
rr_kill_copy(Config) when is_list(Config) ->
@@ -2138,11 +2079,6 @@ get_exit(Pid) ->
?error("Timeout EXIT ~p~n", [Pid])
end.
-iteration(doc) ->
- ["Verify that the updates before/during iteration are visable "
- "and that the order is preserved for ordered_set tables"];
-iteration(suite) ->
- [foldl,first_next].
foldl(doc) ->
[""];
diff --git a/lib/mnesia/test/mnesia_measure_test.erl b/lib/mnesia/test/mnesia_measure_test.erl
index fbf804dbec..e63689d83a 100644
--- a/lib/mnesia/test/mnesia_measure_test.erl
+++ b/lib/mnesia/test/mnesia_measure_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-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
@@ -27,8 +27,8 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
-define(init(N, Config),
mnesia_test_lib:prepare_test_case([{init_test_case, [mnesia]},
@@ -37,101 +37,62 @@ fin_per_testcase(Func, Conf) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Measure various aspects of Mnesia",
- "Verify that Mnesia has predictable response times,",
- "that the transaction system has fair algoritms,",
- "resource consumption, scalabilitym system limits etc.",
- "Perform some benchmarks."];
-all(suite) ->
- [
- prediction,
- consumption,
- scalability,
- benchmarks
- ].
+all() ->
+ [{group, prediction}, {group, consumption},
+ {group, scalability}, {group, benchmarks}].
+
+groups() ->
+ [{prediction, [],
+ [reader_disturbed_by_node_down,
+ writer_disturbed_by_node_down,
+ reader_disturbed_by_node_up,
+ writer_disturbed_by_node_up,
+ reader_disturbed_by_schema_ops,
+ writer_disturbed_by_schema_ops,
+ reader_disturbed_by_checkpoint,
+ writer_disturbed_by_checkpoint,
+ reader_disturbed_by_dump_log,
+ writer_disturbed_by_dump_log,
+ reader_disturbed_by_backup, writer_disturbed_by_backup,
+ reader_disturbed_by_restore,
+ writer_disturbed_by_restore, {group, fairness}]},
+ {fairness, [],
+ [reader_competing_with_reader,
+ reader_competing_with_writer,
+ writer_competing_with_reader,
+ writer_competing_with_writer]},
+ {consumption, [],
+ [measure_resource_consumption,
+ determine_resource_leakage]},
+ {scalability, [],
+ [determine_system_limits, performance_at_min_config,
+ performance_at_max_config, performance_at_full_load,
+ resource_consumption_at_min_config,
+ resource_consumption_at_max_config,
+ resource_consumption_at_full_load]},
+ {benchmarks, [],
+ [{group, meter}, cost, dbn_meters,
+ measure_all_api_functions, {group, tpcb},
+ mnemosyne_vs_mnesia_kernel]},
+ {tpcb, [], [ram_tpcb, disc_tpcb, disc_only_tpcb]},
+ {meter, [], [ram_meter, disc_meter, disc_only_meter]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-prediction(doc) ->
- ["The system must have predictable response times.",
- "The maintenance of the system should not impact on the",
- "availability. Make sure that the response times does not vary too",
- "much from the undisturbed normal usage.",
- "Verify that deadlocks never occurs."];
-prediction(suite) ->
- [
- reader_disturbed_by_node_down,
- writer_disturbed_by_node_down,
- reader_disturbed_by_node_up,
- writer_disturbed_by_node_up,
- reader_disturbed_by_schema_ops,
- writer_disturbed_by_schema_ops,
- reader_disturbed_by_checkpoint,
- writer_disturbed_by_checkpoint,
- reader_disturbed_by_dump_log,
- writer_disturbed_by_dump_log,
- reader_disturbed_by_backup,
- writer_disturbed_by_backup,
- reader_disturbed_by_restore,
- writer_disturbed_by_restore,
- fairness
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-fairness(doc) ->
- ["Verify that the transaction system behaves fair, even under intense",
- "stress. Combine different access patterns (transaction profiles)",
- "in order to verify that concurrent applications gets a fair share",
- "of the database resource. Verify that starvation never may occur."];
-fairness(suite) ->
- [
- reader_competing_with_reader,
- reader_competing_with_writer,
- writer_competing_with_reader,
- writer_competing_with_writer
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-consumption(doc) ->
- ["Measure the resource consumption and publish the outcome. Make",
- "sure that resources are released after failures."];
-consumption(suite) ->
- [
- measure_resource_consumption,
- determine_resource_leakage
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-scalability(doc) ->
- ["Try out where the system limits are. We must at least meet the",
- "documented system limits.",
- "Redo the performance meters for various configurations and load,",
- "especially near system limits."];
-scalability(suite) ->
- [
- determine_system_limits,
- performance_at_min_config,
- performance_at_max_config,
- performance_at_full_load,
- resource_consumption_at_min_config,
- resource_consumption_at_max_config,
- resource_consumption_at_full_load
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-benchmarks(doc) ->
- ["Measure typical database operations and publish them. Try to",
- "verify that new releases of Mnesia always outperforms old",
- "releases, or at least that the meters does not get worse."];
-benchmarks(suite) ->
- [
- meter,
- cost,
- dbn_meters,
- measure_all_api_functions,
- tpcb,
- mnemosyne_vs_mnesia_kernel
- ].
dbn_meters(suite) -> [];
dbn_meters(Config) when is_list(Config) ->
@@ -139,12 +100,6 @@ dbn_meters(Config) when is_list(Config) ->
?match(ok, mnesia_dbn_meters:start()),
ok.
-tpcb(suite) ->
- [
- ram_tpcb,
- disc_tpcb,
- disc_only_tpcb
- ].
tpcb(ReplicaType, Config) ->
HarakiriDelay = {tc_timeout, timer:minutes(20)},
@@ -171,12 +126,6 @@ disc_only_tpcb(suite) -> [];
disc_only_tpcb(Config) when is_list(Config) ->
tpcb(disc_only_copies, Config).
-meter(suite) ->
- [
- ram_meter,
- disc_meter,
- disc_only_meter
- ].
ram_meter(suite) -> [];
ram_meter(Config) when is_list(Config) ->
diff --git a/lib/mnesia/test/mnesia_nice_coverage_test.erl b/lib/mnesia/test/mnesia_nice_coverage_test.erl
index aa9339f6b9..78eab67b11 100644
--- a/lib/mnesia/test/mnesia_nice_coverage_test.erl
+++ b/lib/mnesia/test/mnesia_nice_coverage_test.erl
@@ -28,16 +28,22 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Test nice usage of the entire API",
- "Invoke all functions in the API, at least once.",
- "Try to verify that all functions exists and that they perform",
- "reasonable things when used in the most simple way."];
-all(suite) -> [nice].
+all() ->
+ [nice].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
nice(doc) -> [""];
nice(suite) -> [];
diff --git a/lib/mnesia/test/mnesia_qlc_test.erl b/lib/mnesia/test/mnesia_qlc_test.erl
index 1e4f776c7d..141de71d01 100644
--- a/lib/mnesia/test/mnesia_qlc_test.erl
+++ b/lib/mnesia/test/mnesia_qlc_test.erl
@@ -22,7 +22,7 @@
-compile(export_all).
--export([all/1]).
+-export([all/0,groups/0,init_per_group/2,end_per_group/2]).
-include("mnesia_test_lib.hrl").
-include_lib("stdlib/include/qlc.hrl").
@@ -31,20 +31,34 @@ init_per_testcase(Func, Conf) ->
setup(Conf),
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
-all(doc) ->
- ["Test that the qlc mnesia interface works as expected."];
-all(suite) ->
+all() ->
case code:which(qlc) of
non_existing -> [];
- _ ->
- all_qlc()
+ _ -> all_qlc()
end.
-all_qlc() ->
- [dirty, trans, frag, info, mnesia_down].
+groups() ->
+ [{dirty, [],
+ [dirty_nice_ram_copies, dirty_nice_disc_copies,
+ dirty_nice_disc_only_copies]},
+ {trans, [],
+ [trans_nice_ram_copies, trans_nice_disc_copies,
+ trans_nice_disc_only_copies, {group, atomic}]},
+ {atomic, [], [atomic_eval]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+all_qlc() ->
+ [{group, dirty}, {group, trans}, frag, info,
+ mnesia_down].
init_testcases(Type,Config) ->
Nodes = [N1,N2] = ?acquire_nodes(2, Config),
@@ -59,10 +73,6 @@ init_testcases(Type,Config) ->
Nodes.
%% Test cases
-dirty(suite) ->
- [dirty_nice_ram_copies,
- dirty_nice_disc_copies,
- dirty_nice_disc_only_copies].
dirty_nice_ram_copies(Setup) -> dirty_nice(Setup,ram_copies).
dirty_nice_disc_copies(Setup) -> dirty_nice(Setup,disc_copies).
@@ -109,12 +119,6 @@ dirty_nice(Config, Type) when is_list(Config) ->
end,
?verify_mnesia(Ns, []).
-trans(suite) ->
- [trans_nice_ram_copies,
- trans_nice_disc_copies,
- trans_nice_disc_only_copies,
- atomic
- ].
trans_nice_ram_copies(Setup) -> trans_nice(Setup,ram_copies).
trans_nice_disc_copies(Setup) -> trans_nice(Setup,disc_copies).
@@ -182,9 +186,7 @@ recs() ->
"-record(b, {k,v}). "
"-record(k, {t,v}). "
>>.
-
-atomic(suite) -> [atomic_eval];
-atomic(doc) -> [].
+
atomic_eval(suite) -> [];
atomic_eval(doc) -> [];
diff --git a/lib/mnesia/test/mnesia_recovery_test.erl b/lib/mnesia/test/mnesia_recovery_test.erl
index f6ecf2ce2e..625e6e824c 100644
--- a/lib/mnesia/test/mnesia_recovery_test.erl
+++ b/lib/mnesia/test/mnesia_recovery_test.erl
@@ -28,8 +28,8 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
-define(receive_messages(Msgs), receive_messages(Msgs, ?FILE, ?LINE)).
@@ -42,34 +42,93 @@ fin_per_testcase(Func, Conf) ->
-endif.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Verify recoverability",
- "Verify that the effects of committed transactions are preserved",
- "after recovery from system failures. It must be possible to",
- "restore the tables to a consistent state on a node, from (any kind",
- "of) replica on other nodes as well as from local disk on the failed",
- "node. The system must also recover from instantaneous",
- "interruption causing disk files to not be completely synchronized."];
-
-all(suite) ->
- [
- mnesia_down,
- explicit_stop,
- coord_dies,
- schema_trans,
- async_dirty,
- sync_dirty,
- sym_trans,
- asym_trans,
- after_full_disc_partition,
- after_corrupt_files,
- disc_less,
- garb_decision,
- system_upgrade
- ].
-
-schema_trans(suite) ->
- [{mnesia_schema_recovery_test, all}].
+all() ->
+ [{group, mnesia_down}, {group, explicit_stop},
+ coord_dies, {group, schema_trans}, {group, async_dirty},
+ {group, sync_dirty}, {group, sym_trans},
+ {group, asym_trans}, after_full_disc_partition,
+ {group, after_corrupt_files}, disc_less, garb_decision,
+ system_upgrade].
+
+groups() ->
+ [{schema_trans, [],
+ [{mnesia_schema_recovery_test, all}]},
+ {mnesia_down, [],
+ [{group, mnesia_down_during_startup},
+ {group, master_node_tests}, {group, read_during_down},
+ {group, with_checkpoint}, delete_during_start]},
+ {master_node_tests, [],
+ [no_master_2, no_master_3, one_master_2, one_master_3,
+ two_master_2, two_master_3, all_master_2,
+ all_master_3]},
+ {read_during_down, [],
+ [dirty_read_during_down, trans_read_during_down]},
+ {mnesia_down_during_startup, [],
+ [mnesia_down_during_startup_disk_ram,
+ mnesia_down_during_startup_init_ram,
+ mnesia_down_during_startup_init_disc,
+ mnesia_down_during_startup_init_disc_only,
+ mnesia_down_during_startup_tm_ram,
+ mnesia_down_during_startup_tm_disc,
+ mnesia_down_during_startup_tm_disc_only]},
+ {with_checkpoint, [],
+ [with_checkpoint_same, with_checkpoint_other]},
+ {explicit_stop, [], [explicit_stop_during_snmp]},
+ {sym_trans, [],
+ [sym_trans_before_commit_kill_coord_node,
+ sym_trans_before_commit_kill_coord_pid,
+ sym_trans_before_commit_kill_part_after_ask,
+ sym_trans_before_commit_kill_part_before_ask,
+ sym_trans_after_commit_kill_coord_node,
+ sym_trans_after_commit_kill_coord_pid,
+ sym_trans_after_commit_kill_part_after_ask,
+ sym_trans_after_commit_kill_part_do_commit_pre,
+ sym_trans_after_commit_kill_part_do_commit_post]},
+ {sync_dirty, [],
+ [sync_dirty_pre_kill_part,
+ sync_dirty_pre_kill_coord_node,
+ sync_dirty_pre_kill_coord_pid,
+ sync_dirty_post_kill_part,
+ sync_dirty_post_kill_coord_node,
+ sync_dirty_post_kill_coord_pid]},
+ {async_dirty, [],
+ [async_dirty_pre_kill_part,
+ async_dirty_pre_kill_coord_node,
+ async_dirty_pre_kill_coord_pid,
+ async_dirty_post_kill_part,
+ async_dirty_post_kill_coord_node,
+ async_dirty_post_kill_coord_pid]},
+ {asym_trans, [],
+ [asym_trans_kill_part_ask,
+ asym_trans_kill_part_commit_vote,
+ asym_trans_kill_part_pre_commit,
+ asym_trans_kill_part_log_commit,
+ asym_trans_kill_part_do_commit,
+ asym_trans_kill_coord_got_votes,
+ asym_trans_kill_coord_pid_got_votes,
+ asym_trans_kill_coord_log_commit_rec,
+ asym_trans_kill_coord_pid_log_commit_rec,
+ asym_trans_kill_coord_log_commit_dec,
+ asym_trans_kill_coord_pid_log_commit_dec,
+ asym_trans_kill_coord_rec_acc_pre_commit_log_commit,
+ asym_trans_kill_coord_pid_rec_acc_pre_commit_log_commit,
+ asym_trans_kill_coord_rec_acc_pre_commit_done_commit,
+ asym_trans_kill_coord_pid_rec_acc_pre_commit_done_commit]},
+ {after_corrupt_files, [],
+ [after_corrupt_files_decision_log_head,
+ after_corrupt_files_decision_log_tail,
+ after_corrupt_files_latest_log_head,
+ after_corrupt_files_latest_log_tail,
+ after_corrupt_files_table_dat_head,
+ after_corrupt_files_table_dat_tail,
+ after_corrupt_files_schema_dat_head,
+ after_corrupt_files_schema_dat_tail]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
tpcb_config(ReplicaType, _NodeConfig, Nodes) ->
[{n_branches, 5},
@@ -83,30 +142,7 @@ tpcb_config(ReplicaType, _NodeConfig, Nodes) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-mnesia_down(doc) ->
- [" Various tests about recovery when mnesia goes down on one or several nodes."];
-mnesia_down(suite) ->
- [
- mnesia_down_during_startup,
- master_node_tests,
- read_during_down,
- with_checkpoint,
- delete_during_start
- ].
-
-master_node_tests(doc) ->
- ["Verify that mnesia loads the correct data after it has been down, regarding master node settings."];
-master_node_tests(suite) ->
- [
- no_master_2,
- no_master_3,
- one_master_2,
- one_master_3,
- two_master_2,
- two_master_3,
- all_master_2,
- all_master_3
- ].
+
no_master_2(suite) -> [];
no_master_2(Config) when is_list(Config) -> mnesia_down_2(no, Config).
@@ -251,13 +287,6 @@ mnesia_down_3(Masters, Config) ->
?verify_mnesia(Nodes, []).
-read_during_down(doc) ->
- ["Verify that read operation can continue to read when mnesia goes down"];
-read_during_down(suite) ->
- [
- dirty_read_during_down,
- trans_read_during_down
- ].
dirty_read_during_down(suite) ->
[];
@@ -325,20 +354,6 @@ loop_and_kill_mnesia(N, Node, Tabs) ->
timer:sleep(100),
loop_and_kill_mnesia(N-1, KN, Tabs).
-mnesia_down_during_startup(doc) ->
- ["Verify that mnesia can come back up again in a consistent state",
- "after it has gone down during startup (with different store and",
- "when it goes down in different situations"];
-mnesia_down_during_startup(suite) ->
- [
- mnesia_down_during_startup_disk_ram,
- mnesia_down_during_startup_init_ram,
- mnesia_down_during_startup_init_disc,
- mnesia_down_during_startup_init_disc_only,
- mnesia_down_during_startup_tm_ram,
- mnesia_down_during_startup_tm_disc,
- mnesia_down_during_startup_tm_disc_only
- ].
mnesia_down_during_startup_disk_ram(suite) -> [];
mnesia_down_during_startup_disk_ram(Config) when is_list(Config)->
@@ -433,10 +448,6 @@ mnesia_down_during_startup2(Config, ReplicaType, Debug_Point, _Father) ->
?verify_mnesia(Nodes, []).
-with_checkpoint(doc) ->
- ["Restart mnesia with checkpoint"];
-with_checkpoint(suite) ->
- [with_checkpoint_same, with_checkpoint_other].
with_checkpoint_same(suite) -> [];
with_checkpoint_same(Config) when is_list(Config) ->
@@ -581,10 +592,6 @@ verify_where2read([]) -> ok.
%%-------------------------------------------------------------------------------------------
-explicit_stop(doc) ->
- ["Stop Mnesia in different situations"];
-explicit_stop(suite) ->
- [explicit_stop_during_snmp].
%% This is a bad implementation, but at least gives a indication if something is wrong
explicit_stop_during_snmp(suite) -> [];
explicit_stop_during_snmp(Config) when is_list(Config) ->
@@ -700,21 +707,7 @@ coord_dies(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-sym_trans(doc) ->
- ["Recovery of symmetrical transactions in a couple of different",
- "situations; when coordinator or participant or node dies"];
-
-sym_trans(suite) ->
- [sym_trans_before_commit_kill_coord_node, %% coordinator node dies
- sym_trans_before_commit_kill_coord_pid, %% coordinator process dies
- sym_trans_before_commit_kill_part_after_ask, %% participating node dies
- sym_trans_before_commit_kill_part_before_ask,
- sym_trans_after_commit_kill_coord_node,
- sym_trans_after_commit_kill_coord_pid,
- sym_trans_after_commit_kill_part_after_ask,
- sym_trans_after_commit_kill_part_do_commit_pre,
- sym_trans_after_commit_kill_part_do_commit_post].
+
%kill_after_debug_point(Config, TestCase, {Debug_node, Debug_Point}, TransFun, Tab)
@@ -828,17 +821,6 @@ do_sym_trans([Tab], _Fahter) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-sync_dirty(doc) ->
- ["Verify recovery of synchronously operations in a couple of different",
- "situations"];
-sync_dirty(suite) ->
- [sync_dirty_pre_kill_part,
- sync_dirty_pre_kill_coord_node,
- sync_dirty_pre_kill_coord_pid,
- sync_dirty_post_kill_part,
- sync_dirty_post_kill_coord_node,
- sync_dirty_post_kill_coord_pid
- ].
sync_dirty_pre_kill_part(suite) -> [];
sync_dirty_pre_kill_part(Config) when is_list(Config) ->
@@ -916,16 +898,6 @@ do_sync_dirty([Tab], _Father) ->
?dl("SYNC_DIRTY done: ~p ", [Res]),
ok.
-async_dirty(doc) ->
- ["Verify recovery of asynchronously dirty operations in a couple of different",
- "situations"];
-async_dirty(suite) ->
- [async_dirty_pre_kill_part,
- async_dirty_pre_kill_coord_node,
- async_dirty_pre_kill_coord_pid,
- async_dirty_post_kill_part,
- async_dirty_post_kill_coord_node,
- async_dirty_post_kill_coord_pid].
async_dirty_pre_kill_part(suite) -> [];
async_dirty_pre_kill_part(Config) when is_list(Config) ->
@@ -1005,29 +977,6 @@ do_async_dirty([Tab], _Fahter) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-asym_trans(doc) ->
- ["Recovery of asymmetrical transactions in a couple of different",
- "situations, currently the error cases are not covered, i.e. ",
- "not tested are the situations when we kill mnesia or a process",
- "during a recovery"];
-asym_trans(suite) ->
- [
- asym_trans_kill_part_ask,
- asym_trans_kill_part_commit_vote,
- asym_trans_kill_part_pre_commit,
- asym_trans_kill_part_log_commit,
- asym_trans_kill_part_do_commit,
- asym_trans_kill_coord_got_votes,
- asym_trans_kill_coord_pid_got_votes,
- asym_trans_kill_coord_log_commit_rec,
- asym_trans_kill_coord_pid_log_commit_rec,
- asym_trans_kill_coord_log_commit_dec,
- asym_trans_kill_coord_pid_log_commit_dec,
- asym_trans_kill_coord_rec_acc_pre_commit_log_commit,
- asym_trans_kill_coord_pid_rec_acc_pre_commit_log_commit,
- asym_trans_kill_coord_rec_acc_pre_commit_done_commit,
- asym_trans_kill_coord_pid_rec_acc_pre_commit_done_commit
- ].
asym_trans_kill_part_ask(suite) -> [];
asym_trans_kill_part_ask(Config) when is_list(Config) ->
@@ -1435,18 +1384,6 @@ after_full_disc_partition(doc) ->
%% interrupted_fallback_start
%% is implemented in consistency interupted_install_fallback!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-after_corrupt_files(doc) ->
- ["Verify that mnesia (and dets) can handle corrupt files"];
-after_corrupt_files(suite) -> % cope with unsynced disks
- [after_corrupt_files_decision_log_head,
- after_corrupt_files_decision_log_tail,
- after_corrupt_files_latest_log_head,
- after_corrupt_files_latest_log_tail,
- after_corrupt_files_table_dat_head,
- after_corrupt_files_table_dat_tail,
- after_corrupt_files_schema_dat_head,
- after_corrupt_files_schema_dat_tail
- ].
after_corrupt_files_decision_log_head(suite) -> [];
after_corrupt_files_decision_log_head(Config) when is_list(Config) ->
diff --git a/lib/mnesia/test/mnesia_registry_test.erl b/lib/mnesia/test/mnesia_registry_test.erl
index 2305ef93b7..cf8da38632 100644
--- a/lib/mnesia/test/mnesia_registry_test.erl
+++ b/lib/mnesia/test/mnesia_registry_test.erl
@@ -26,17 +26,22 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Test the mnesia_registry module"];
-all(suite) ->
- [
- good_dump,
- bad_dump
- ].
+all() ->
+ [good_dump, bad_dump].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
good_dump(doc) ->
diff --git a/lib/mnesia/test/mnesia_schema_recovery_test.erl b/lib/mnesia/test/mnesia_schema_recovery_test.erl
index 387238ae6b..0fe26efd0b 100644
--- a/lib/mnesia/test/mnesia_schema_recovery_test.erl
+++ b/lib/mnesia/test/mnesia_schema_recovery_test.erl
@@ -26,8 +26,8 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
-define(receive_messages(Msgs), receive_messages(Msgs, ?FILE, ?LINE)).
@@ -41,92 +41,82 @@ fin_per_testcase(Func, Conf) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Verify recoverabiliy of schema transactions.",
- " Verify that a schema transaction",
- " can be completed when it has been logged correctly and Mnesia",
- " crashed before the log has been dumped. Then the transaction ",
- " should be handled during the log dump at startup"
- ];
-all(suite) ->
- [interrupted_before_log_dump,
- interrupted_after_log_dump].
-
-interrupted_before_log_dump(suite) ->
- [interrupted_before_create_ram,
- interrupted_before_create_disc,
- interrupted_before_create_disc_only,
- interrupted_before_create_nostore,
- interrupted_before_delete_ram,
- interrupted_before_delete_disc,
- interrupted_before_delete_disc_only,
- interrupted_before_add_ram,
- interrupted_before_add_disc,
- interrupted_before_add_disc_only,
- interrupted_before_add_kill_copier,
- interrupted_before_move_ram,
- interrupted_before_move_disc,
- interrupted_before_move_disc_only,
- interrupted_before_move_kill_copier,
- interrupted_before_delcopy_ram,
- interrupted_before_delcopy_disc,
- interrupted_before_delcopy_disc_only,
- interrupted_before_delcopy_kill_copier,
- interrupted_before_addindex_ram,
- interrupted_before_addindex_disc,
- interrupted_before_addindex_disc_only,
- interrupted_before_delindex_ram,
- interrupted_before_delindex_disc,
- interrupted_before_delindex_disc_only,
- interrupted_before_change_type_ram2disc,
- interrupted_before_change_type_ram2disc_only,
- interrupted_before_change_type_disc2ram,
- interrupted_before_change_type_disc2disc_only,
- interrupted_before_change_type_disc_only2ram,
- interrupted_before_change_type_disc_only2disc,
- interrupted_before_change_type_other_node,
- interrupted_before_change_schema_type %% Change schema table copy type!!
- ].
-
-interrupted_after_log_dump(suite) ->
- [interrupted_after_create_ram,
- interrupted_after_create_disc,
- interrupted_after_create_disc_only,
- interrupted_after_create_nostore,
- interrupted_after_delete_ram,
- interrupted_after_delete_disc,
- interrupted_after_delete_disc_only,
- interrupted_after_add_ram,
- interrupted_after_add_disc,
- interrupted_after_add_disc_only,
- interrupted_after_add_kill_copier,
- interrupted_after_move_ram,
- interrupted_after_move_disc,
- interrupted_after_move_disc_only,
- interrupted_after_move_kill_copier,
- interrupted_after_delcopy_ram,
- interrupted_after_delcopy_disc,
- interrupted_after_delcopy_disc_only,
- interrupted_after_delcopy_kill_copier,
- interrupted_after_addindex_ram,
- interrupted_after_addindex_disc,
- interrupted_after_addindex_disc_only,
- interrupted_after_delindex_ram,
- interrupted_after_delindex_disc,
- interrupted_after_delindex_disc_only,
- interrupted_after_change_type_ram2disc,
- interrupted_after_change_type_ram2disc_only,
- interrupted_after_change_type_disc2ram,
- interrupted_after_change_type_disc2disc_only,
- interrupted_after_change_type_disc_only2ram,
- interrupted_after_change_type_disc_only2disc,
- interrupted_after_change_type_other_node,
- interrupted_after_change_schema_type %% Change schema table copy type!!
-
-% interrupted_before_change_access_mode,
-% interrupted_before_transform,
-% interrupted_before_restore,
- ].
+all() ->
+ [{group, interrupted_before_log_dump},
+ {group, interrupted_after_log_dump}].
+
+groups() ->
+ [{interrupted_before_log_dump, [],
+ [interrupted_before_create_ram,
+ interrupted_before_create_disc,
+ interrupted_before_create_disc_only,
+ interrupted_before_create_nostore,
+ interrupted_before_delete_ram,
+ interrupted_before_delete_disc,
+ interrupted_before_delete_disc_only,
+ interrupted_before_add_ram, interrupted_before_add_disc,
+ interrupted_before_add_disc_only,
+ interrupted_before_add_kill_copier,
+ interrupted_before_move_ram,
+ interrupted_before_move_disc,
+ interrupted_before_move_disc_only,
+ interrupted_before_move_kill_copier,
+ interrupted_before_delcopy_ram,
+ interrupted_before_delcopy_disc,
+ interrupted_before_delcopy_disc_only,
+ interrupted_before_delcopy_kill_copier,
+ interrupted_before_addindex_ram,
+ interrupted_before_addindex_disc,
+ interrupted_before_addindex_disc_only,
+ interrupted_before_delindex_ram,
+ interrupted_before_delindex_disc,
+ interrupted_before_delindex_disc_only,
+ interrupted_before_change_type_ram2disc,
+ interrupted_before_change_type_ram2disc_only,
+ interrupted_before_change_type_disc2ram,
+ interrupted_before_change_type_disc2disc_only,
+ interrupted_before_change_type_disc_only2ram,
+ interrupted_before_change_type_disc_only2disc,
+ interrupted_before_change_type_other_node,
+ interrupted_before_change_schema_type]},
+ {interrupted_after_log_dump, [],
+ [interrupted_after_create_ram,
+ interrupted_after_create_disc,
+ interrupted_after_create_disc_only,
+ interrupted_after_create_nostore,
+ interrupted_after_delete_ram,
+ interrupted_after_delete_disc,
+ interrupted_after_delete_disc_only,
+ interrupted_after_add_ram, interrupted_after_add_disc,
+ interrupted_after_add_disc_only,
+ interrupted_after_add_kill_copier,
+ interrupted_after_move_ram, interrupted_after_move_disc,
+ interrupted_after_move_disc_only,
+ interrupted_after_move_kill_copier,
+ interrupted_after_delcopy_ram,
+ interrupted_after_delcopy_disc,
+ interrupted_after_delcopy_disc_only,
+ interrupted_after_delcopy_kill_copier,
+ interrupted_after_addindex_ram,
+ interrupted_after_addindex_disc,
+ interrupted_after_addindex_disc_only,
+ interrupted_after_delindex_ram,
+ interrupted_after_delindex_disc,
+ interrupted_after_delindex_disc_only,
+ interrupted_after_change_type_ram2disc,
+ interrupted_after_change_type_ram2disc_only,
+ interrupted_after_change_type_disc2ram,
+ interrupted_after_change_type_disc2disc_only,
+ interrupted_after_change_type_disc_only2ram,
+ interrupted_after_change_type_disc_only2disc,
+ interrupted_after_change_type_other_node,
+ interrupted_after_change_schema_type]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
interrupted_before_create_ram(suite) -> [];
interrupted_before_create_ram(Config) when is_list(Config) ->
diff --git a/lib/mnesia/test/mnesia_test_lib.erl b/lib/mnesia/test/mnesia_test_lib.erl
index 1e98f017f7..182c240084 100644
--- a/lib/mnesia/test/mnesia_test_lib.erl
+++ b/lib/mnesia/test/mnesia_test_lib.erl
@@ -130,7 +130,7 @@
doc/1,
struct/1,
init_per_testcase/2,
- fin_per_testcase/2,
+ end_per_testcase/2,
kill_tc/2
]).
@@ -144,7 +144,7 @@ init_per_testcase(_Func, Config) ->
global:register_name(mnesia_global_logger, group_leader()),
Config.
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
global:unregister_name(mnesia_global_logger),
%% Nodes = select_nodes(all, Config, ?FILE, ?LINE),
%% rpc:multicall(Nodes, mnesia, lkill, []),
@@ -492,19 +492,19 @@ wait_for_evaluator(Pid, Mod, Fun, Config) ->
{'EXIT', Pid, {skipped, Reason}} ->
log("<WARNING> Test case ~w skipped, because ~p~n",
[{Mod, Fun}, Reason]),
- Mod:fin_per_testcase(Fun, Config),
+ Mod:end_per_testcase(Fun, Config),
{skip, {Mod, Fun}, Reason};
{'EXIT', Pid, Reason} ->
log("<>ERROR<> Eval process ~w exited, because ~p~n",
[{Mod, Fun}, Reason]),
- Mod:fin_per_testcase(Fun, Config),
+ Mod:end_per_testcase(Fun, Config),
{crash, {Mod, Fun}, Reason}
end.
test_case_evaluator(Mod, Fun, [Config]) ->
NewConfig = Mod:init_per_testcase(Fun, Config),
R = apply(Mod, Fun, [NewConfig]),
- Mod:fin_per_testcase(Fun, NewConfig),
+ Mod:end_per_testcase(Fun, NewConfig),
exit({test_case_ok, R}).
activity_evaluator(Coordinator) ->
diff --git a/lib/mnesia/test/mnesia_tpcb.erl b/lib/mnesia/test/mnesia_tpcb.erl
index 903c53a21c..595412ff24 100644
--- a/lib/mnesia/test/mnesia_tpcb.erl
+++ b/lib/mnesia/test/mnesia_tpcb.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/mnesia/test/mnesia_trans_access_test.erl b/lib/mnesia/test/mnesia_trans_access_test.erl
index c67382e694..55ba4dd761 100644
--- a/lib/mnesia/test/mnesia_trans_access_test.erl
+++ b/lib/mnesia/test/mnesia_trans_access_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,8 +26,8 @@
init_per_testcase(Func, Conf) ->
mnesia_test_lib:init_per_testcase(Func, Conf).
-fin_per_testcase(Func, Conf) ->
- mnesia_test_lib:fin_per_testcase(Func, Conf).
+end_per_testcase(Func, Conf) ->
+ mnesia_test_lib:end_per_testcase(Func, Conf).
-define(receive_messages(Msgs), mnesia_recovery_test:receive_messages(Msgs, ?FILE, ?LINE)).
@@ -40,18 +40,41 @@ fin_per_testcase(Func, Conf) ->
-endif.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(doc) ->
- ["Evil access of records in the scope of transactions",
- "Invoke all functions in the API and try to cover all legal uses",
- "cases as well the illegal dito. This is a complement to the",
- "other more explicit test cases."];
-all(suite) ->
- [
- write, read, wread, delete, delete_object,
- match_object, select, select14, all_keys,
- transaction, nested_activities,
- index_tabs, index_lifecycle
- ].
+all() ->
+ [write, read, wread, delete, delete_object,
+ match_object, select, select14, all_keys, transaction,
+ {group, nested_activities}, {group, index_tabs},
+ {group, index_lifecycle}].
+
+groups() ->
+ [{nested_activities, [],
+ [basic_nested, {group, nested_transactions},
+ mix_of_nested_activities]},
+ {nested_transactions, [],
+ [nested_trans_both_ok, nested_trans_child_dies,
+ nested_trans_parent_dies, nested_trans_both_dies]},
+ {index_tabs, [],
+ [index_match_object, index_read, {group, index_update},
+ index_write]},
+ {index_update, [],
+ [index_update_set, index_update_bag]},
+ {index_lifecycle, [],
+ [add_table_index_ram, add_table_index_disc,
+ add_table_index_disc_only, create_live_table_index_ram,
+ create_live_table_index_disc,
+ create_live_table_index_disc_only, del_table_index_ram,
+ del_table_index_disc, del_table_index_disc_only,
+ {group, idx_schema_changes}]},
+ {idx_schema_changes, [],
+ [idx_schema_changes_ram, idx_schema_changes_disc,
+ idx_schema_changes_disc_only]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Write records
@@ -404,12 +427,6 @@ transaction(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-nested_activities(suite) ->
- [
- basic_nested,
- nested_transactions,
- mix_of_nested_activities
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -520,13 +537,6 @@ n_f4() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-nested_transactions(doc) ->
- ["Verify that nested_transactions are handled as expected"];
-nested_transactions(suite) ->
- [nested_trans_both_ok,
- nested_trans_child_dies,
- nested_trans_parent_dies,
- nested_trans_both_dies].
nested_trans_both_ok(suite) -> [];
nested_trans_both_ok(Config) when is_list(Config) ->
@@ -671,13 +681,6 @@ read_op(Oid) ->
Ops
end.
-index_tabs(suite) ->
- [
- index_match_object,
- index_read,
- index_update,
- index_write
- ].
%% Read matching records by using an index
@@ -767,10 +770,6 @@ index_read(Config) when is_list(Config) ->
?match({'EXIT', {aborted, no_transaction}}, mnesia:index_read(Tab, 2, ValPos)),
?verify_mnesia(Nodes, []).
-index_update(suite) -> [index_update_set, index_update_bag];
-index_update(doc) -> ["See Ticket OTP-2083, verifies that a table with a index is "
- "update in the correct way i.e. the index finds the correct "
- "records after a update"].
index_update_set(suite) -> [];
index_update_set(Config)when is_list(Config) ->
[Node1] = Nodes = ?acquire_nodes(1, Config),
@@ -1046,19 +1045,6 @@ index_write(Config)when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Add and drop indecies
-index_lifecycle(suite) ->
- [
- add_table_index_ram,
- add_table_index_disc,
- add_table_index_disc_only,
- create_live_table_index_ram,
- create_live_table_index_disc,
- create_live_table_index_disc_only,
- del_table_index_ram,
- del_table_index_disc,
- del_table_index_disc_only,
- idx_schema_changes
- ].
add_table_index_ram(suite) -> [];
add_table_index_ram(Config) when is_list(Config) ->
@@ -1171,13 +1157,6 @@ del_table_index(Config, Storage) ->
?match({atomic, ok}, mnesia:transaction(NestedFun)),
?verify_mnesia(Nodes, []).
-idx_schema_changes(suite) -> [idx_schema_changes_ram,
- idx_schema_changes_disc,
- idx_schema_changes_disc_only];
-idx_schema_changes(doc) ->
- ["Tests that index tables are handled correctly when schema changes.",
- "For example when a replica is deleted or inserted",
- "TICKET OTP-2XXX (ELVIRA)"].
idx_schema_changes_ram(suite) -> [];
idx_schema_changes_ram(Config) when is_list(Config) ->
diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk
index bce0f7b739..5b52bc6075 100644
--- a/lib/mnesia/vsn.mk
+++ b/lib/mnesia/vsn.mk
@@ -1 +1 @@
-MNESIA_VSN = 4.4.15
+MNESIA_VSN = 4.4.16
diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml
index 3d7c4fa269..76c13fb3ff 100644
--- a/lib/observer/doc/src/notes.xml
+++ b/lib/observer/doc/src/notes.xml
@@ -31,6 +31,23 @@
<p>This document describes the changes made to the Observer
application.</p>
+<section><title>Observer 0.9.8.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The multitrace.erl installation example file is now
+ installed in the examples directory. (Thanks to Peter
+ Lemenkov.)</p>
+ <p>
+ Own Id: OTP-8857</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Observer 0.9.8.3</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/observer/test/Makefile b/lib/observer/test/Makefile
index 6f1430b00a..e15bde7346 100644
--- a/lib/observer/test/Makefile
+++ b/lib/observer/test/Makefile
@@ -80,7 +80,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) observer.spec observer.dynspec $(EMAKEFILE) \
+ $(INSTALL_DATA) observer.spec $(EMAKEFILE) \
$(COVERFILE) $(ERL_FILES) \
$(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl
index fcf383dc2e..1a7e6f61fe 100644
--- a/lib/observer/test/crashdump_viewer_SUITE.erl
+++ b/lib/observer/test/crashdump_viewer_SUITE.erl
@@ -20,12 +20,13 @@
-module(crashdump_viewer_SUITE).
%% Test functions
--export([all/1,translate/1,start/1,fini/1,load_file/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ translate/1,start/1,fini/1,load_file/1,
non_existing/1,not_a_crashdump/1,old_crashdump/1]).
-export([init_per_suite/1, end_per_suite/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
-include_lib("kernel/include/file.hrl").
@@ -46,9 +47,21 @@ end_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [translate,{conf,start,[load_file,non_existing,not_a_crashdump,
- old_crashdump],fini}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [translate, load_file, non_existing, not_a_crashdump,
+ old_crashdump].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_suite(doc) ->
["Create a lot of crashdumps which can be used in the testcases below"];
diff --git a/lib/observer/test/etop_SUITE.erl b/lib/observer/test/etop_SUITE.erl
index 54f4a78e69..ab2a6f5d18 100644
--- a/lib/observer/test/etop_SUITE.erl
+++ b/lib/observer/test/etop_SUITE.erl
@@ -20,22 +20,42 @@
-module(etop_SUITE).
%% Test functions
--export([all/1,text/1,text_tracing_off/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,text/1,text_tracing_off/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(default_timeout, ?t:minutes(1)).
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(suite) -> [text,text_tracing_off].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [text, text_tracing_off].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
text(suite) ->
[];
diff --git a/lib/observer/test/observer.cover b/lib/observer/test/observer.cover
index 47770ba839..fafb718840 100644
--- a/lib/observer/test/observer.cover
+++ b/lib/observer/test/observer.cover
@@ -1,2 +1,4 @@
-{exclude,[multitrace]}.
-{include,[observer_backend]}.
+{incl_app,observer,details}.
+
+{excl_mods,observer,[multitrace]}.
+{incl_mods,observer,[observer_backend]}.
diff --git a/lib/observer/test/observer.spec b/lib/observer/test/observer.spec
index 801eb80607..3b4b5da28c 100644
--- a/lib/observer/test/observer.spec
+++ b/lib/observer/test/observer.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../observer_test"}}.
-
+{suites,"../observer_test",all}.
diff --git a/lib/observer/test/observer_SUITE.erl b/lib/observer/test/observer_SUITE.erl
index 3e9522c7a4..46d4612706 100644
--- a/lib/observer/test/observer_SUITE.erl
+++ b/lib/observer/test/observer_SUITE.erl
@@ -18,10 +18,11 @@
%%
-module(observer_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([init_per_testcase/2, end_per_testcase/2]).
%% Test cases
@@ -39,9 +40,27 @@ end_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[app_file].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
app_file(suite) ->
[];
app_file(doc) ->
diff --git a/lib/observer/test/ttb_SUITE.erl b/lib/observer/test/ttb_SUITE.erl
index 6da5e36b29..14bd1e9c33 100644
--- a/lib/observer/test/ttb_SUITE.erl
+++ b/lib/observer/test/ttb_SUITE.erl
@@ -21,14 +21,16 @@
-compile(export_all).
%% Test functions
--export([all/1,file/1,file_no_pi/1,file_fetch/1,wrap/1,wrap_merge/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ file/1,file_no_pi/1,file_fetch/1,wrap/1,wrap_merge/1,
wrap_merge_fetch_format/1,write_config1/1,write_config2/1,
write_config3/1,history/1,write_trace_info/1,seq_trace/1,
diskless/1,otp_4967_1/1,otp_4967_2/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([foo/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(default_timeout, ?t:minutes(1)).
@@ -36,15 +38,34 @@ init_per_testcase(_Case, Config) ->
ttb:stop(),
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(suite) -> [file,file_no_pi,file_fetch,wrap,wrap_merge,
- wrap_merge_fetch_format,write_config1,write_config2,
- write_config3,history,write_trace_info,seq_trace,diskless,
- otp_4967_1,otp_4967_2].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [file, file_no_pi, file_fetch, wrap, wrap_merge,
+ wrap_merge_fetch_format, write_config1, write_config2,
+ write_config3, history, write_trace_info, seq_trace,
+ diskless, otp_4967_1, otp_4967_2].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
file(suite) ->
[];
diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk
index 499cce6b97..1b72d30eab 100644
--- a/lib/observer/vsn.mk
+++ b/lib/observer/vsn.mk
@@ -1 +1 @@
-OBSERVER_VSN = 0.9.8.3
+OBSERVER_VSN = 0.9.8.4
diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
index c9627e9d05..077d78bfe5 100644
--- a/lib/odbc/c_src/odbcserver.c
+++ b/lib/odbc/c_src/odbcserver.c
@@ -108,8 +108,8 @@
#if defined WIN32
#include <winsock2.h>
-/* #include <ws2tcpip.h > When we can support a newer c-compiler*/
#include <windows.h>
+#include <ws2tcpip.h >
#include <fcntl.h>
#include <sql.h>
#include <sqlext.h>
@@ -1599,7 +1599,7 @@ static Boolean decode_params(db_state *state, byte *buffer, int *index, param_ar
break;
case SQL_C_TYPE_TIMESTAMP:
ts = (TIMESTAMP_STRUCT*) param->values.string;
- ei_decode_tuple_header(buffer, index, &val);
+ ei_decode_tuple_header(buffer, index, &size);
ei_decode_long(buffer, index, &val);
ts[j].year = (SQLUSMALLINT)val;
ei_decode_long(buffer, index, &val);
@@ -1727,74 +1727,48 @@ static byte * receive_erlang_port_msg(void)
}
/* ------------- Socket communication functions --------------------------*/
-#define USE_IPV4
-#ifdef UNIX
-#define SOCKET int
-#endif
-#if defined WIN32 || defined USE_IPV4
-/* Currently only an old windows compiler is supported so we do not have ipv6
- capabilities */
+#if defined(WIN32)
static SOCKET connect_to_erlang(const char *port)
-{
- SOCKET sock;
- struct sockaddr_in sin;
-
- sock = socket(AF_INET, SOCK_STREAM, 0);
-
- memset(&sin, 0, sizeof(sin));
- sin.sin_port = htons ((unsigned short)atoi(port));
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = inet_addr("127.0.0.1");
-
- if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
- close_socket(sock);
- DO_EXIT(EXIT_SOCKET_CONNECT);
- }
- return sock;
-}
#elif defined(UNIX)
static int connect_to_erlang(const char *port)
+#endif
{
- int sock;
-
- struct addrinfo hints;
- struct addrinfo *erlang_ai, *first;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
-
- if (getaddrinfo("localhost", port, &hints, &first) != 0) {
- DO_EXIT(EXIT_FAILURE);
- }
+#if defined(WIN32)
+ SOCKET sock;
+#elif defined(UNIX)
+ int sock;
+#endif
+ struct sockaddr_in sin;
+
+#if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_ADDR) && defined(AF_INET6)
+ struct sockaddr_in6 sin6;
+
+ sock = socket(AF_INET6, SOCK_STREAM, 0);
+
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_port = htons ((unsigned short)atoi(port));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_addr = in6addr_loopback;
- for (erlang_ai = first; erlang_ai; erlang_ai = erlang_ai->ai_next) {
+ if (connect(sock, (struct sockaddr*)&sin6, sizeof(sin6)) == 0) {
+ return sock;
+ }
+ close_socket(sock);
+#endif
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_port = htons ((unsigned short)atoi(port));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sock = socket(erlang_ai->ai_family, erlang_ai->ai_socktype,
- erlang_ai->ai_protocol);
- if (sock < 0)
- continue;
- if (connect(sock, (struct sockaddr*)erlang_ai->ai_addr,
- erlang_ai->ai_addrlen) < 0) {
- close(sock);
- sock = -1;
- continue;
- } else {
- break;
+ if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
+ close_socket(sock);
+ DO_EXIT(EXIT_SOCKET_CONNECT);
}
- }
- freeaddrinfo(first);
-
- if (sock < 0){
- close_socket(sock);
- DO_EXIT(EXIT_SOCKET_CONNECT);
- }
-
- return sock;
+ return sock;
}
-#endif
#ifdef WIN32
static void close_socket(SOCKET socket)
@@ -2177,9 +2151,9 @@ static void init_param_column(param_array *params, byte *buffer, int *index,
params->type.sql = SQL_TYPE_TIMESTAMP;
params->type.len = sizeof(TIMESTAMP_STRUCT);
params->type.c = SQL_C_TYPE_TIMESTAMP;
- params->type.col_size = (SQLUINTEGER)19;//;sizeof(TIMESTAMP_STRUCT);
+ params->type.col_size = (SQLUINTEGER)COL_SQL_TIMESTAMP;
params->values.string =
- (TIMESTAMP_STRUCT *)safe_malloc(num_param_values * params->type.len);
+ (byte *)safe_malloc(num_param_values * params->type.len);
break;
case USER_FLOAT:
params->type.sql = SQL_FLOAT;
diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h
index e6d8df1f58..3e2b22ab7d 100644
--- a/lib/odbc/c_src/odbcserver.h
+++ b/lib/odbc/c_src/odbcserver.h
@@ -98,6 +98,7 @@
#define COL_SQL_REAL 7
#define COL_SQL_DOUBLE 15
#define COL_SQL_TINYINT 4
+#define COL_SQL_TIMESTAMP 19
/* Types of parameters given to param_query*/
#define USER_SMALL_INT 1
diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in
index 94e8a214d4..2369e16813 100644
--- a/lib/odbc/configure.in
+++ b/lib/odbc/configure.in
@@ -118,11 +118,18 @@ AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"]))
dnl Checks for header files.
AC_HEADER_STDC
-AC_CHECK_HEADERS([fcntl.h netdb.h stdlib.h string.h sys/socket.h])
+AC_CHECK_HEADERS([fcntl.h netdb.h stdlib.h string.h sys/socket.h winsock2.h])
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
+AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_addr], [], [],
+ [#if HAVE_WINSOCK2_H
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+ #else
+ #include <netinet/in.h>
+ #endif])
dnl Checks for library functions.
AC_CHECK_FUNCS([memset socket])
diff --git a/lib/odbc/doc/src/notes.xml b/lib/odbc/doc/src/notes.xml
index 09d78c3248..7dece7c584 100644
--- a/lib/odbc/doc/src/notes.xml
+++ b/lib/odbc/doc/src/notes.xml
@@ -31,7 +31,31 @@
<p>This document describes the changes made to the odbc application.
</p>
- <section><title>ODBC 2.10.8</title>
+ <section><title>ODBC 2.10.9</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Ipv6 is now supported on Windows as well as on UNIX for
+ internal socket communication. (ODBC uses sockets instead
+ of the "Erlang port pipes" as some ODBC-drivers are known
+ to mess with stdin/stdout.) </p>
+ <p>
+ Loopback address constants are used when connecting the
+ c-side to the erlang-side over local socket API avoiding
+ getaddrinfo problems, and the {ip, loopback} option is
+ added as a listen option on the erlang-side. Also cleaned
+ up the TIME_STAMP contribution.</p>
+ <p>
+ Own Id: OTP-8917</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>ODBC 2.10.8</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/odbc/src/odbc.appup.src b/lib/odbc/src/odbc.appup.src
index e95e542ff5..f1a370d925 100644
--- a/lib/odbc/src/odbc.appup.src
+++ b/lib/odbc/src/odbc.appup.src
@@ -1 +1,8 @@
-{"%VSN%", [],[]}
+%% -*- erlang -*-
+{"%VSN%",
+ [
+ {"2.10.8", [{restart_application, ssl}]}
+ ],
+ [
+ {"2.10.8", [{restart_application, ssl}]}
+ ]}.
diff --git a/lib/odbc/src/odbc.erl b/lib/odbc/src/odbc.erl
index eb27a471ec..83d9f33102 100644
--- a/lib/odbc/src/odbc.erl
+++ b/lib/odbc/src/odbc.erl
@@ -441,10 +441,12 @@ init(Args) ->
{ok, ListenSocketSup} =
gen_tcp:listen(0, [Inet, binary, {packet, ?LENGTH_INDICATOR_SIZE},
- {active, false}, {nodelay, true}]),
+ {active, false}, {nodelay, true},
+ {ip, loopback}]),
{ok, ListenSocketOdbc} =
gen_tcp:listen(0, [Inet, binary, {packet, ?LENGTH_INDICATOR_SIZE},
- {active, false}, {nodelay, true}]),
+ {active, false}, {nodelay, true},
+ {ip, loopback}]),
%% Start the port program (a c program) that utilizes the odbc driver
case os:find_executable(?SERVERPROG, ?SERVERDIR) of
diff --git a/lib/odbc/test/Makefile b/lib/odbc/test/Makefile
index 935ecbf5a7..ab3cdea543 100644
--- a/lib/odbc/test/Makefile
+++ b/lib/odbc/test/Makefile
@@ -45,8 +45,8 @@ HRL_FILES= odbc_test.hrl\
TARGET_FILES= \
$(MODULES:%=$(EBIN)/%.$(EMULATOR))
-SPEC_FILES = odbc.spec odbc.dynspec \
- odbc.spec.win
+SPEC_FILES = odbc.spec
+COVER_FILE = odbc.cover
EMAKEFILE = Emakefile
MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
@@ -101,7 +101,7 @@ release_spec: opt
release_tests_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SPEC_FILES) $(COVER_FILE) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
release_docs_spec:
diff --git a/lib/odbc/test/odbc.cover b/lib/odbc/test/odbc.cover
new file mode 100644
index 0000000000..1acca281fb
--- /dev/null
+++ b/lib/odbc/test/odbc.cover
@@ -0,0 +1,2 @@
+{incl_app,odbc,details}.
+
diff --git a/lib/odbc/test/odbc.spec b/lib/odbc/test/odbc.spec
index acba9f8d98..edaf821c91 100644
--- a/lib/odbc/test/odbc.spec
+++ b/lib/odbc/test/odbc.spec
@@ -1,9 +1,25 @@
-{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
+{suites,"../odbc_test",all}.
+{skip_cases,"../odbc_test",odbc_data_type_SUITE,
+ [varchar_upper_limit],
+ "Known bug in database"}.
+{skip_cases,"../odbc_test",odbc_data_type_SUITE,
+ [text_upper_limit],
+ "Consumes too much resources"}.
+{skip_cases,"../odbc_test",odbc_data_type_SUITE,
+ [bit_true],
+ "Not supported by driver"}.
+{skip_cases,"../odbc_test",odbc_data_type_SUITE,
+ [bit_false],
+ "Not supported by driver"}.
+{skip_cases,"../odbc_test",odbc_query_SUITE,
+ [multiple_select_result_sets],
+ "Not supported by driver"}.
+{skip_cases,"../odbc_test",odbc_query_SUITE,
+ [multiple_mix_result_sets],
+ "Not supported by driver"}.
+{skip_cases,"../odbc_test",odbc_query_SUITE,
+ [multiple_result_sets_error],
+ "Not supported by driver"}.
+{skip_cases,"../odbc_test",odbc_query_SUITE,
+ [param_insert_tiny_int],
+ "Not supported by driver"}.
diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl
index 4d37a8f543..fd7693de3a 100644
--- a/lib/odbc/test/odbc_connect_SUITE.erl
+++ b/lib/odbc/test/odbc_connect_SUITE.erl
@@ -24,7 +24,7 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
-include("odbc_test.hrl").
@@ -40,20 +40,32 @@
%% 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) ->
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
case odbc_test_lib:odbc_check() of
- ok -> all();
+ ok ->
+ [not_exist_db, commit, rollback, not_explicit_commit,
+ no_c_node, port_dies, control_process_dies,
+ {group, client_dies}, connect_timeout, timeout,
+ many_timeouts, timeout_reset, disconnect_on_timeout,
+ connection_closed, disable_scrollable_cursors,
+ return_rows_as_lists, api_missuse];
Other -> {skip, Other}
- end.
+ end.
+
+groups() ->
+ [{client_dies, [],
+ [client_dies_normal, client_dies_timeout,
+ client_dies_error]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-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
@@ -66,7 +78,7 @@ all() ->
%%--------------------------------------------------------------------
init_per_suite(Config) ->
application:start(odbc),
- case odbc:connect(?RDBMS:connection_string(),
+ case catch odbc:connect(?RDBMS:connection_string(),
[{auto_commit, off}]) of
{ok, Ref} ->
odbc:disconnect(Ref),
@@ -283,11 +295,6 @@ control_process_dies(_Config) ->
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) ->
diff --git a/lib/odbc/test/odbc_data_type_SUITE.erl b/lib/odbc/test/odbc_data_type_SUITE.erl
index 7d4a0ca15f..83bb821e2b 100644
--- a/lib/odbc/test/odbc_data_type_SUITE.erl
+++ b/lib/odbc/test/odbc_data_type_SUITE.erl
@@ -24,7 +24,7 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-include("test_server_line.hrl").
-include("odbc_test.hrl").
@@ -39,16 +39,48 @@
%% 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) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
case odbc_test_lib:odbc_check() of
- ok -> all();
- Other -> {skip,Other}
- end.
+ ok ->
+ [{group, char}, {group, int}, {group, floats},
+ {group, dec_and_num}, timestamp];
+ Other -> {skip, Other}
+ end.
-all() ->
- [char, int, floats, dec_and_num, timestamp].
+groups() ->
+ [{char, [],
+ [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]},
+ {binary_char, [],
+ [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]},
+ {int, [],
+ [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]},
+ {floats, [],
+ [float_lower_limit, float_upper_limit, float_zero,
+ real_zero]},
+ {dec_and_num, [],
+ [dec_long, dec_double, dec_bignum, num_long, num_double,
+ num_bignum]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
@@ -124,14 +156,6 @@ end_per_testcase(_TestCase, Config) ->
%%-------------------------------------------------------------------------
%% 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."];
@@ -424,14 +448,6 @@ text_upper_limit(Config) when is_list(Config) ->
%% 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."];
@@ -726,13 +742,6 @@ binary_text_upper_limit(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-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].
%%-------------------------------------------------------------------------
@@ -1053,10 +1062,6 @@ bit_true(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-floats(doc) ->
- ["Test the datatype float."];
-floats(suite) ->
- [float_lower_limit, float_upper_limit, float_zero, real_zero].
%%-------------------------------------------------------------------------
float_lower_limit(doc) ->
@@ -1184,10 +1189,6 @@ real_zero(Config) when is_list(Config) ->
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) ->
[""];
diff --git a/lib/odbc/test/odbc_query_SUITE.erl b/lib/odbc/test/odbc_query_SUITE.erl
index 12b39be3b7..5c8126ace6 100644
--- a/lib/odbc/test/odbc_query_SUITE.erl
+++ b/lib/odbc/test/odbc_query_SUITE.erl
@@ -24,7 +24,7 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
-include("odbc_test.hrl").
@@ -38,22 +38,47 @@
%% 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) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
case odbc_test_lib:odbc_check() of
- ok -> all();
+ ok ->
+ [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,
+ {group, parameterized_queries}, {group, describe_table},
+ delete_nonexisting_row];
Other -> {skip, Other}
- end.
+ 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].
+groups() ->
+ [{parameterized_queries, [],
+ [{group, param_integers}, param_insert_decimal,
+ param_insert_numeric, {group, param_insert_string},
+ param_insert_float, param_insert_real,
+ param_insert_double, param_insert_mix, param_update,
+ param_delete, param_select]},
+ {param_integers, [],
+ [param_insert_tiny_int, param_insert_small_int,
+ param_insert_int, param_insert_integer]},
+ {param_insert_string, [],
+ [param_insert_char, param_insert_character,
+ param_insert_char_varying,
+ param_insert_character_varying]},
+ {describe_table, [],
+ [describe_integer, describe_string, describe_floating,
+ describe_dec_num, describe_no_such_table]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%--------------------------------------------------------------------
@@ -638,23 +663,8 @@ multiple_result_sets_error(Config) when is_list(Config) ->
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."];
@@ -891,11 +901,6 @@ param_insert_numeric(Config) when is_list(Config) ->
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)->
@@ -1320,11 +1325,6 @@ param_select(Config) when is_list(Config) ->
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) ->
diff --git a/lib/odbc/test/odbc_start_SUITE.erl b/lib/odbc/test/odbc_start_SUITE.erl
index 2cca8e4546..902e77d210 100644
--- a/lib/odbc/test/odbc_start_SUITE.erl
+++ b/lib/odbc/test/odbc_start_SUITE.erl
@@ -24,7 +24,7 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
-include("odbc_test.hrl").
@@ -98,17 +98,23 @@ end_per_testcase(_TestCase, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test start/stop of odbc"];
+suite() -> [{ct_hooks,[ts_install_cth]}].
-all(suite) ->
+all() ->
case odbc_test_lib:odbc_check() of
- ok -> all();
+ ok -> [start];
Other -> {skip, Other}
- end.
+ end.
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all() ->
- [start].
%% Test cases starts here.
diff --git a/lib/odbc/test/odbc_test_lib.erl b/lib/odbc/test/odbc_test_lib.erl
index 92e895eb87..012eb96e43 100644
--- a/lib/odbc/test/odbc_test_lib.erl
+++ b/lib/odbc/test/odbc_test_lib.erl
@@ -51,7 +51,7 @@ odbc_check() ->
[Other]))
end;
Other ->
- case test_server:os_type() of
+ case os:type() of
{unix, linux} ->
ok;
Platform ->
diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk
index fac3f06d4b..aacf3924db 100644
--- a/lib/odbc/vsn.mk
+++ b/lib/odbc/vsn.mk
@@ -1 +1 @@
-ODBC_VSN = 2.10.8
+ODBC_VSN = 2.10.9
diff --git a/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl b/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
index 7792839e22..768653c898 100644
--- a/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
+++ b/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -536,8 +536,15 @@ lookup(_, _Ctx) ->
receive_msg(Socket, Acc, Timeout) ->
receive
{tcp_closed, Socket} ->
- [_Header, Body] = re:split(Acc,"\r\n\r\n",[{return,list}]),
- Body;
+ case re:split(Acc,"\r\n\r\n",[{return,list}]) of
+ [_Header, Body] ->
+ Body;
+ What ->
+ orber:dbg("[~p] orber_cosnaming_utils:receive_msg();~n"
+ "HTTP server closed the connection before sending a complete reply: ~p.",
+ [?LINE, What], ?DEBUG_LEVEL),
+ corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO})
+ end;
{tcp, Socket, Response} ->
receive_msg(Socket, Acc ++ Response, Timeout);
{tcp_error, Socket, Reason} ->
diff --git a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
index a97ad65f0e..964ae3e92d 100644
--- a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
+++ b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -445,7 +445,19 @@ void op(in myEnum a);</cell>
<section>
<title>Struct Data Type</title>
<p>A <c>struct</c> may have Basic, Template, Scoped Names and Constructed
- types as members.</p>
+ types as members. By using forward declaration we can define a recursive struct:</p>
+ <code type="none"><![CDATA[
+struct myStruct; // Forward declaration
+typedef sequence<myStruct> myStructSeq;
+struct myStruct {
+ myStructSeq chain;
+};
+
+// Deprecated definition (anonymous) not supported by IC
+struct myStruct {
+ sequence<myStruct> chain;
+};
+ ]]></code>
</section>
<section>
@@ -510,6 +522,25 @@ union LongUnion2 switch(long) {
default: boolean DefaultValue;
};
</code>
+ <p>In the same way as structs, unions can be recursive if forward
+ declaration is used (anonymous types is deprecated and not supported):</p>
+ <code type="none"><![CDATA[
+// Forward declaration
+union myUnion;
+typedef sequence<myUnion>myUnionSeq;
+union myUnion switch (long) {
+ case 1 : myUnionSeq chain;
+ default: boolean DefaultValue;
+};
+ ]]></code>
+
+ <note>
+ <p>Recursive types (union and struct) require Light IFR. I.e. the
+ IC option {light_ifr, true} is used and that Orber is configured in such a way that
+ Light IFR is activated. Recursive TypeCode is currently not supported, which is
+ why these cannot be encapsulated in an any data type.</p>
+ </note>
+
</section>
<warning>
<p>Every field in, for example, a struct must be initiated. Otherwise
@@ -890,7 +921,7 @@ attribute long RWAttribute;
object internal state with its object reference. The object internal state is
an Erlang term which has a format defined by the user.</p>
<note>
- <p>It is is not always the case that the internal state will be the first parameter, as stubs can use their own object reference as the first parameter (see the IC documentation).</p>
+ <p>It is not always the case that the internal state will be the first parameter, as stubs can use their own object reference as the first parameter (see the IC documentation).</p>
</note>
<p>A function call will invoke an operation. The first
parameter of the function should be the object reference and then
diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml
index 17f7ac8270..589123ef73 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2010</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,23 +32,87 @@
<file>notes.xml</file>
</header>
- <section><title>Orber 3.6.17</title>
+ <section>
+ <title>Orber 3.6.20</title>
- <section><title>Improvements and New Features</title>
- <list>
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
<item>
<p>
- Eliminated warnings for auto-imported BIF clashes.</p>
+ Eliminated Dialyzer warnings when using exit or throw.</p>
<p>
- Own Id: OTP-8840</p>
+ Own Id: OTP-9050 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Orber 3.6.19</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Partial support for recursive structs and unions.
+ Only available for the erl_corba backend and requires
+ that Light IFR is used. I.e. the IC option {light_ifr, true}
+ and that Orber is configured in such a way that Light IFR
+ is activated. Recursive TypeCode is currently not supported.</p>
+ <p>
+ Own Id: OTP-8868 Aux Id: seq11633</p>
+ </item>
+ </list>
+ </section>
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The SSL option {ssl_imp, old} was not used if ssl_generation was
+ set to 2. Only R14B was affected by this.</p>
+ <p>Own Id: OTP-8994 Aux Id: seq11747</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Orber 3.6.18</title>
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>A corbaloc http string could return an EXIT message, instead
+ of a system exception, if the HTTP server closed the socket
+ without returning a complete message. I.e. header and a body
+ containing a stringified IOR.</p>
+ <p>Own Id: OTP-8900 Aux Id: seq11704</p>
</item>
</list>
</section>
+ </section>
-</section>
+ <section>
+ <title>Orber 3.6.17</title>
-<section>
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Eliminated warnings for auto-imported BIF clashes.</p>
+ <p>
+ Own Id: OTP-8840</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>Orber 3.6.16</title>
+
<section>
<title>Improvements and New Features</title>
<list type="bulleted">
@@ -56,16 +120,17 @@
<p>
Test suites published.</p>
<p>
- Own Id: OTP-8543 Aux Id:</p>
+ Own Id: OTP-8543O Aux Id:</p>
</item>
</list>
</section>
+
<section>
<title>Fixed Bugs and Malfunctions</title>
<list type="bulleted">
<item>
<p>Added missing trailing bracket to define in hrl-file.</p>
- <p>Own id: OTP-8489 Aux Id:</p>
+ <p>Own Id: OTP-8489 Aux Id:</p>
</item>
</list>
</section>
@@ -104,11 +169,11 @@
<list type="bulleted">
<item>
<p>Removed superfluous VT in the documentation.</p>
- <p>Own id: OTP-8353 Aux Id:</p>
+ <p>Own Id: OTP-8353 Aux Id:</p>
</item>
<item>
<p>Removed superfluous backslash in the documentation.</p>
- <p>Own id: OTP-8354 Aux Id:</p>
+ <p>Own Id: OTP-8354 Aux Id:</p>
</item>
</list>
</section>
@@ -140,7 +205,7 @@
<item>
<p>Obsolete guards, e.g. record vs is_record, has been changed
to avoid compiler warnings.</p>
- <p>Own id: OTP-7987</p>
+ <p>Own Id: OTP-7987</p>
</item>
</list>
</section>
@@ -158,7 +223,7 @@
Naming Service (INS) instead. INS is a part of the OMG
standard specification.</p>
<p>*** POTENTIAL INCOMPATIBILITY ***</p>
- <p>Own id: OTP-7906 Aux Id: seq11243</p>
+ <p>Own Id: OTP-7906 Aux Id: seq11243</p>
</item>
</list>
</section>
@@ -172,7 +237,7 @@
<list type="bulleted">
<item>
<p>Updated file headers.</p>
- <p>Own id: OTP-7837</p>
+ <p>Own Id: OTP-7837</p>
</item>
</list>
</section>
@@ -186,7 +251,7 @@
<list type="bulleted">
<item>
<p>Documentation source included in open source releases.</p>
- <p>Own id: OTP-7595</p>
+ <p>Own Id: OTP-7595</p>
</item>
</list>
</section>
@@ -200,11 +265,11 @@
<list type="bulleted">
<item>
<p>Updated file headers.</p>
- <p>Own id: OTP-7011</p>
+ <p>Own Id: OTP-7011</p>
</item>
<item>
<p>Now compliant with the new behavior of stdlib.</p>
- <p>Own id: OTP-7030 Aux Id: seq10827</p>
+ <p>Own Id: OTP-7030 Aux Id: seq10827</p>
</item>
</list>
</section>
diff --git a/lib/orber/include/ifr_types.hrl b/lib/orber/include/ifr_types.hrl
index 144ec7f8a1..324b32bd4f 100644
--- a/lib/orber/include/ifr_types.hrl
+++ b/lib/orber/include/ifr_types.hrl
@@ -1,9 +1,9 @@
%%--------------------------------------------------------------------
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
diff --git a/lib/orber/src/cdr_decode.erl b/lib/orber/src/cdr_decode.erl
index 9d30098940..36ef6ce02f 100644
--- a/lib/orber/src/cdr_decode.erl
+++ b/lib/orber/src/cdr_decode.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -898,9 +898,13 @@ dec_sequence_struct(Version, Message, N, TypeCodeList, Len, ByteOrder, Buff, C,
{Seq, Rest2, Len2, NewC2} = dec_sequence_struct(Version, Rest1, N - 1, TypeCodeList, Len1, ByteOrder,
Buff, NewC, Name),
{[list_to_tuple([Name |Struct]) | Seq], Rest2, Len2, NewC2}.
-dec_sequence_union(_, Message, 0, _DiscrTC, _Default, _ElementList, Len, _ByteOrder, _Buff, C, _Name) ->
+
+
+dec_sequence_union(_, Message, 0, _DiscrTC, _Default, _ElementList,
+ Len, _ByteOrder, _Buff, C, _Name) ->
{[], Message, Len, C};
-dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList, Len, ByteOrder, Buff, C, Name) ->
+dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList,
+ Len, ByteOrder, Buff, C, Name) when is_list(ElementList) ->
{Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Message, Len, ByteOrder, Buff, C),
Result = dec_union(Version, stringify_enum(DiscrTC, Label), ElementList, Default,
@@ -916,7 +920,20 @@ dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList, Len, Byte
DiscrTC, Default, ElementList,
Len2, ByteOrder,
Buff, NewC3, Name),
- {[{Name, Label, Value} | Seq], Rest3, Len3, NewC4}.
+ {[{Name, Label, Value} | Seq], Rest3, Len3, NewC4};
+dec_sequence_union(Version, Message, N, _DiscrTC, _Default, Module,
+ Len, ByteOrder, Buff, C, Name) when is_atom(Module) ->
+ case catch Module:tc() of
+ {tk_union, _, _, DiscrTC, Default, ElementList} ->
+ dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList,
+ Len, ByteOrder, Buff, C, Name);
+ What ->
+ orber:dbg("[~p] ~p:dec_sequence_union(~p). Union module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
+
+
%% A special case; when something is encapsulated (i.e. sent as octet-sequence)
%% we sometimes don not want the result to be converted to a list.
@@ -993,14 +1010,16 @@ dec_wstring(Version, Message, Len, ByteOrder, Buff, C) ->
%% Func: dec_union/9
%%-----------------------------------------------------------------
%% ## NEW IIOP 1.2 ##
-dec_union(Version, ?SYSTEM_TYPE, Name, DiscrTC, Default, ElementList, Bytes, Len, ByteOrder, Buff, C) ->
+dec_union(Version, ?SYSTEM_TYPE, Name, DiscrTC, Default, ElementList, Bytes,
+ Len, ByteOrder, Buff, C) ->
{Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Bytes, Len, ByteOrder, Buff, C),
{Value, Rest2, Len2, NewC3} = dec_union(Version, Label, ElementList, Default,
Rest1, Len1, ByteOrder, Buff, NewC),
{{Name, Label, Value}, Rest2, Len2, NewC3};
-dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len, ByteOrder, Buff, C) ->
+dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len,
+ ByteOrder, Buff, C) when is_list(ElementList) ->
{Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Bytes, Len, ByteOrder, Buff, C),
Result = dec_union(Version, stringify_enum(DiscrTC, Label), ElementList, Default,
Rest1, Len1, ByteOrder, Buff, NewC),
@@ -1012,7 +1031,20 @@ dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len, ByteOrde
X
end,
Name = ifrid_to_name(IFRId, ?IFR_UnionDef),
- {{Name, Label, Value}, Rest2, Len2, NewC3}.
+ {{Name, Label, Value}, Rest2, Len2, NewC3};
+dec_union(Version, IFRId, _, _DiscrTC, _Default, Module, Bytes, Len,
+ ByteOrder, Buff, C) when is_atom(Module) ->
+ case catch Module:tc() of
+ {tk_union, _, Name, DiscrTC, Default, ElementList} ->
+ dec_union(Version, IFRId, Name, DiscrTC, Default, ElementList, Bytes, Len,
+ ByteOrder, Buff, C);
+ What ->
+ orber:dbg("[~p] ~p:dec_union(~p). Union module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
+
+
dec_union(_, _, [], Default, Message, Len, _, _Buff, C) when Default < 0 ->
{undefined, Message, Len, C};
@@ -1047,7 +1079,16 @@ dec_struct1(_, [], Message, Len, _ByteOrder, _, C) ->
dec_struct1(Version, [{_ElemName, ElemType} | TypeCodeList], Message, Len, ByteOrder, Buff, C) ->
{Element, Rest, Len1, NewC} = dec_type(ElemType, Version, Message, Len, ByteOrder, Buff, C),
{Struct, Rest1, Len2, NewC2} = dec_struct1(Version, TypeCodeList, Rest, Len1, ByteOrder, Buff, NewC),
- {[Element |Struct], Rest1, Len2, NewC2}.
+ {[Element |Struct], Rest1, Len2, NewC2};
+dec_struct1(Version, Module, Message, Len, ByteOrder, Buff, C) ->
+ case catch Module:tc() of
+ {tk_struct, _, _, TypeCodeList} ->
+ dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C);
+ What ->
+ orber:dbg("[~p] ~p:dec_struct1(~p). Struct module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
ifrid_to_name([], Type) ->
orber:dbg("[~p] ~p:ifrid_to_name([], ~p). No Id supplied.",
@@ -1232,7 +1273,9 @@ get_user_exception_type(TypeId) ->
%%-----------------------------------------------------------------
dec_type_code(Version, Message, Len, ByteOrder, Buff, C) ->
{TypeNo, Message1, Len1, NewC} = dec_type('tk_ulong', Version, Message, Len, ByteOrder, Buff, C),
- dec_type_code(TypeNo, Version, Message1, Len1, ByteOrder, Buff, NewC).
+ TC = dec_type_code(TypeNo, Version, Message1, Len1, ByteOrder, Buff, NewC),
+ erase(orber_indirection),
+ TC.
%%-----------------------------------------------------------------
%% Func: dec_type_code/5
@@ -1441,13 +1484,22 @@ dec_type_code(33, Version, Message, Len, ByteOrder, Buff, C) ->
{"name", {'tk_string', 0}}]},
Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex),
{{'tk_local_interface', RepId, Name}, Message1, Len1, NewC};
-dec_type_code(16#ffffffff, Version, Message, Len, ByteOrder, Buff, C) -> %% placeholder
+dec_type_code(16#ffffffff, Version, Message, Len, ByteOrder, Buff, C) ->
{Indirection, Message1, Len1, NewC} =
dec_type('tk_long', Version, Message, Len, ByteOrder, Buff, C),
Position = C+Indirection,
- <<_:Position/binary, SubBuff/binary>> = Buff,
- {TC, _, _, _} = dec_type_code(Version, SubBuff, Position, ByteOrder, Buff, Position),
- {TC, Message1, Len1, NewC};
+ case put(orber_indirection, Position) of
+ Position ->
+%% {{'none', Indirection}, Message1, Len1, NewC};
+ %% Recursive TypeCode. Break the loop.
+ orber:dbg("[~p] cdr_decode:dec_type_code(~p); Recursive TC not supported.",
+ [?LINE,Position], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_NO});
+ _ ->
+ <<_:Position/binary, SubBuff/binary>> = Buff,
+ {TC, _, _, _} = dec_type_code(Version, SubBuff, Position, ByteOrder, Buff, Position),
+ {TC, Message1, Len1, NewC}
+ end;
dec_type_code(Type, _, _, _, _, _, _) ->
orber:dbg("[~p] cdr_decode:dec_type_code(~p); No match.",
[?LINE, Type], ?DEBUG_LEVEL),
diff --git a/lib/orber/src/cdr_encode.erl b/lib/orber/src/cdr_encode.erl
index 3ecb8833f5..eaf3c5b7dc 100644
--- a/lib/orber/src/cdr_encode.erl
+++ b/lib/orber/src/cdr_encode.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -815,11 +815,21 @@ enc_wstring(Env, String, MaxLength, Bytes, Len) ->
%%-----------------------------------------------------------------
%% Func: enc_union/5
%%-----------------------------------------------------------------
-enc_union(Env, {_, Label, Value}, DiscrTC, Default, TypeCodeList, Bytes, Len) ->
+enc_union(Env, {_, Label, Value}, DiscrTC, Default, TypeCodeList,
+ Bytes, Len) when is_list(TypeCodeList) ->
{ByteSequence, Len1} = enc_type(DiscrTC, Env, Label, Bytes, Len),
Label2 = stringify_enum(DiscrTC,Label),
enc_union2(Env, {Label2, Value},TypeCodeList, Default,
- ByteSequence, Len1, undefined).
+ ByteSequence, Len1, undefined);
+enc_union(Env, Value, _DiscrTC, _Default, Module, Bytes, Len) when is_atom(Module) ->
+ case catch Module:tc() of
+ {tk_union, _, _, DiscrTC, Default, ElementList} ->
+ enc_union(Env, Value, DiscrTC, Default, ElementList, Bytes, Len);
+ What ->
+ orber:dbg("[~p] ~p:enc_union(~p). Union module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
enc_union2(_Env, _What, [], Default, Bytes, Len, _) when Default < 0 ->
{Bytes, Len};
@@ -840,9 +850,19 @@ stringify_enum(_, Label) ->
%%-----------------------------------------------------------------
%% Func: enc_struct/4
%%-----------------------------------------------------------------
-enc_struct(Env, Struct, TypeCodeList, Bytes, Len) ->
+enc_struct(Env, Struct, TypeCodeList, Bytes, Len) when is_list(TypeCodeList) ->
[_Name | StructList] = tuple_to_list(Struct),
- enc_struct1(Env, StructList, TypeCodeList, Bytes, Len).
+ enc_struct1(Env, StructList, TypeCodeList, Bytes, Len);
+enc_struct(Env, Struct, Module, Bytes, Len) ->
+ [Module | StructList] = tuple_to_list(Struct),
+ case catch Module:tc() of
+ {tk_struct, _, _, TypeCodeList} ->
+ enc_struct1(Env, StructList, TypeCodeList, Bytes, Len);
+ What ->
+ orber:dbg("[~p] ~p:enc_struct([], ~p). Struct module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
enc_struct1(_Env, [], [], Bytes, Len) ->
{Bytes, Len};
diff --git a/lib/orber/src/corba.erl b/lib/orber/src/corba.erl
index ea1363742c..ecec768544 100644
--- a/lib/orber/src/corba.erl
+++ b/lib/orber/src/corba.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -620,6 +620,8 @@ get_pid(Objkey) ->
%% Returns : Throws the exception.
%% Description:
%%----------------------------------------------------------------------
+%% To avoid dialyzer warnings due to the use of exit/throw.
+-spec raise(term()) -> no_return().
raise(E) ->
throw({'EXCEPTION', E}).
@@ -629,6 +631,8 @@ raise(E) ->
%% Returns : Throws the exception.
%% Description:
%%----------------------------------------------------------------------
+%% To avoid dialyzer warnings due to the use of exit/throw.
+-spec raise_with_state(term(), term()) -> no_return().
raise_with_state(E, State) ->
throw({reply, {'EXCEPTION', E}, State}).
diff --git a/lib/orber/src/orber.app.src b/lib/orber/src/orber.app.src
index fe911d65a4..88df4162b6 100644
--- a/lib/orber/src/orber.app.src
+++ b/lib/orber/src/orber.app.src
@@ -101,7 +101,7 @@
orber_iiop_insup, orber_init, orber_reqno,
orber_objkeyserver, orber_iiop_socketsup,
orber_iiop_pm, orber_env]},
- {applications, [stdlib, kernel]},
+ {applications, [stdlib, kernel, mnesia]},
{env, []},
{mod, {orber, []}}
]}.
diff --git a/lib/orber/src/orber.erl b/lib/orber/src/orber.erl
index c3d37ad1fb..665b3cb383 100644
--- a/lib/orber/src/orber.erl
+++ b/lib/orber/src/orber.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1027,12 +1027,18 @@ remove_node(Node) when is_atom(Node) ->
remove_tables(Tables, Node) ->
- remove_tables(Tables, Node, []).
+ case remove_tables(Tables, Node, []) of
+ ok ->
+ ok;
+ {error, Node, Failed} ->
+ ?EFORMAT("orber:remove_node(~p) failed. Unable to remove table(s): ~p",
+ [Node, Failed])
+ end.
-remove_tables([], _, []) -> ok;
+remove_tables([], _, []) ->
+ ok;
remove_tables([], Node, Failed) ->
- ?EFORMAT("orber:remove_node(~p) failed. Unable to remove table(s): ~p",
- [Node, Failed]);
+ {error, Node, Failed};
remove_tables([T1|Trest], Node, Failed) ->
case mnesia:del_table_copy(T1, Node) of
{atomic, ok} ->
@@ -1041,8 +1047,6 @@ remove_tables([T1|Trest], Node, Failed) ->
remove_tables(Trest, Node, [{T1, Reason}|Failed])
end.
-
-
%%-----------------------------------------------------------------
%% Internal interface functions
%%-----------------------------------------------------------------
diff --git a/lib/orber/src/orber_socket.erl b/lib/orber/src/orber_socket.erl
index af6df01b7d..ec2cf8f42a 100644
--- a/lib/orber/src/orber_socket.erl
+++ b/lib/orber/src/orber_socket.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -37,7 +37,7 @@
%%-----------------------------------------------------------------
-export([start/0, connect/4, listen/3, listen/4, accept/2, accept/3, write/3,
controlling_process/3, close/2, peername/2, sockname/2,
- peerdata/2, peercert/2, peercert/3, sockdata/2, setopts/3,
+ peerdata/2, peercert/2, sockdata/2, setopts/3,
clear/2, shutdown/3, post_accept/2, post_accept/3]).
%%-----------------------------------------------------------------
@@ -366,14 +366,6 @@ peercert(Type, _Socket) ->
[?LINE, Type], ?DEBUG_LEVEL),
{error, ebadsocket}.
-peercert(ssl, Socket, Opts) ->
- ssl:peercert(Socket, Opts);
-peercert(Type, _Socket, Opts) ->
- orber:dbg("[~p] orber_socket:peercert(~p, ~p);~n"
- "Only available for SSL sockets.",
- [?LINE, Type, Opts], ?DEBUG_LEVEL),
- {error, ebadsocket}.
-
%%-----------------------------------------------------------------
%% Get peerdata
%%
@@ -496,27 +488,17 @@ check_port(Port, _, _) ->
%%-----------------------------------------------------------------
%% Check Options.
-%% We need this as a work-around since the SSL-app doesn't allow us
-%% to pass 'inet' as an option. Also needed for R9B :-(
check_options(normal, Options, _Generation) ->
- case orber:ip_version() of
- inet ->
- Options;
- inet6 ->
- %% Necessary for R9B. Should be [orber:ip_version()|Options];
- [inet6|Options]
- end;
+ [orber:ip_version()|Options];
check_options(ssl, Options, Generation) ->
case orber:ip_version() of
inet when Generation > 2 ->
[{ssl_imp, new}|Options];
inet ->
- Options;
+ [{ssl_imp, old}|Options];
inet6 when Generation > 2 ->
[{ssl_imp, new}, inet6|Options];
inet6 ->
- %% Will fail until SSL supports this option.
- %% Note, we want this happen!
- [inet6|Options]
+ [{ssl_imp, old}, inet6|Options]
end.
diff --git a/lib/orber/test/Makefile b/lib/orber/test/Makefile
index 4601e84d2c..4fad44dd7d 100644
--- a/lib/orber/test/Makefile
+++ b/lib/orber/test/Makefile
@@ -34,6 +34,7 @@ RELSYSDIR = $(RELEASE_PATH)/orber_test
# Target Specs
# ----------------------------------------------------
TEST_SPEC_FILE = orber.spec
+COVER_FILE = orber.cover
IDL_FILES = \
@@ -120,7 +121,11 @@ GEN_MOD_TEST_SERVER = \
orber_test_server_uni \
orber_test_server_uni_d \
orber_test_timeout_server \
- orber_parent_inherrit
+ orber_parent_inherrit \
+ orber_test_server_rec_struct \
+ orber_test_server_rec_struct_seq \
+ orber_test_server_rec_union \
+ orber_test_server_rec_union_seq
GEN_HRL_TEST_SERVER = \
oe_orber_test_server.hrl \
@@ -218,7 +223,7 @@ release_docs_spec:
release_tests_spec: tests
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \
+ $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) $(COVER_FILE) \
$(ERL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
diff --git a/lib/orber/test/cdrcoding_10_SUITE.erl b/lib/orber/test/cdrcoding_10_SUITE.erl
index d5d030538f..666f474e90 100644
--- a/lib/orber/test/cdrcoding_10_SUITE.erl
+++ b/lib/orber/test/cdrcoding_10_SUITE.erl
@@ -27,7 +27,7 @@
-include("idl_output/Module.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -36,12 +36,11 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -49,13 +48,28 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [types, reply, cancel_request, close_connection, message_error].
+all() ->
+ cases().
+
+groups() ->
+ [{types, [],
+ [do_register, null_type, void_type, principal_type,
+ objref_type, struct_type, union_type, string_type,
+ array_type, any_type, typecode_type, alias_type,
+ exception_type, do_unregister]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [{group, types}, reply, cancel_request,
+ close_connection, message_error].
%% request, locate_request, locate_reply].
%%-----------------------------------------------------------------
@@ -69,14 +83,14 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
orber:jump_start(0),
if
is_list(Config) ->
@@ -85,7 +99,7 @@ init_all(Config) when is_list(Config) ->
exit("Config not a list")
end.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
orber:jump_stop(),
Config.
@@ -94,11 +108,6 @@ finish_all(Config) when is_list(Config) ->
%% Description: Just testing the complex types, the others are
%% tested in the cdrlib SUITE.
%%-----------------------------------------------------------------
-types(doc) -> ["Description", "more description"];
-types(suite) -> [do_register, null_type, void_type, principal_type,
- objref_type, struct_type, union_type, string_type,
- array_type, any_type, typecode_type, alias_type,
- exception_type, do_unregister].
%types(Config) when list(Config) ->
% 'oe_orber_test':'oe_register'(),
% null_type(),
diff --git a/lib/orber/test/cdrcoding_11_SUITE.erl b/lib/orber/test/cdrcoding_11_SUITE.erl
index d62fe6eb3a..273c94a79e 100644
--- a/lib/orber/test/cdrcoding_11_SUITE.erl
+++ b/lib/orber/test/cdrcoding_11_SUITE.erl
@@ -27,7 +27,7 @@
-include("idl_output/Module.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -36,12 +36,11 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -49,13 +48,28 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [types, reply, cancel_request, close_connection, message_error].
+all() ->
+ cases().
+
+groups() ->
+ [{types, [],
+ [do_register, null_type, void_type, principal_type,
+ objref_type, struct_type, union_type, string_type,
+ array_type, any_type, typecode_type, alias_type,
+ exception_type, do_unregister]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [{group, types}, reply, cancel_request,
+ close_connection, message_error].
%% request, locate_request, locate_reply].
%%-----------------------------------------------------------------
@@ -69,14 +83,14 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
orber:jump_start(0),
if
is_list(Config) ->
@@ -85,7 +99,7 @@ init_all(Config) when is_list(Config) ->
exit("Config not a list")
end.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
orber:jump_stop(),
Config.
@@ -94,11 +108,6 @@ finish_all(Config) when is_list(Config) ->
%% Description: Just testing the complex types, the others are
%% tested in the cdrlib SUITE.
%%-----------------------------------------------------------------
-types(doc) -> ["Description", "more description"];
-types(suite) -> [do_register, null_type, void_type, principal_type,
- objref_type, struct_type, union_type, string_type,
- array_type, any_type, typecode_type, alias_type,
- exception_type, do_unregister].
%types(Config) when list(Config) ->
% 'oe_orber_test':'oe_register'(),
% null_type(),
diff --git a/lib/orber/test/cdrcoding_12_SUITE.erl b/lib/orber/test/cdrcoding_12_SUITE.erl
index 18e8eaa08a..3a2d995b99 100644
--- a/lib/orber/test/cdrcoding_12_SUITE.erl
+++ b/lib/orber/test/cdrcoding_12_SUITE.erl
@@ -28,7 +28,7 @@
-module(cdrcoding_12_SUITE).
-include("idl_output/Module.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -37,12 +37,11 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -50,13 +49,28 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
- [types, reply, cancel_request, close_connection, message_error].
+all() ->
+ cases().
+
+groups() ->
+ [{types, [],
+ [do_register, null_type, void_type, principal_type,
+ objref_type, struct_type, union_type, string_type,
+ array_type, any_type, typecode_type, alias_type,
+ exception_type, do_unregister]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [{group, types}, reply, cancel_request,
+ close_connection, message_error].
%% request, locate_request, locate_reply].
%%-----------------------------------------------------------------
@@ -70,14 +84,14 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
orber:jump_start(0),
if
is_list(Config) ->
@@ -86,7 +100,7 @@ init_all(Config) when is_list(Config) ->
exit("Config not a list")
end.
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
orber:jump_stop(),
Config.
@@ -95,11 +109,6 @@ finish_all(Config) when is_list(Config) ->
%% Description: Just testing the complex types, the others are
%% tested in the cdrlib SUITE.
%%-----------------------------------------------------------------
-types(doc) -> ["Description", "more description"];
-types(suite) -> [do_register, null_type, void_type, principal_type,
- objref_type, struct_type, union_type, string_type,
- array_type, any_type, typecode_type, alias_type,
- exception_type, do_unregister].
do_register(doc) -> [];
do_register(suite) -> [];
diff --git a/lib/orber/test/cdrlib_SUITE.erl b/lib/orber/test/cdrlib_SUITE.erl
index fa2d7f2a30..faf06904f0 100644
--- a/lib/orber/test/cdrlib_SUITE.erl
+++ b/lib/orber/test/cdrlib_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,19 +25,19 @@
%%-----------------------------------------------------------------
-module(cdrlib_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(default_timeout, ?t:minutes(3)).
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -45,10 +45,27 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) ->
- [short, ushort, long, ulong, longlong, ulonglong, boolean, character, octet,
- float, double, enum].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [short, ushort, long, ulong, longlong, ulonglong,
+ boolean, character, octet, float, double, enum].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
@@ -59,7 +76,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/orber/test/corba_SUITE.erl b/lib/orber/test/corba_SUITE.erl
index dae8fcbefc..1b28228375 100644
--- a/lib/orber/test/corba_SUITE.erl
+++ b/lib/orber/test/corba_SUITE.erl
@@ -25,7 +25,7 @@
%%-----------------------------------------------------------------
-module(corba_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -51,7 +51,7 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
@@ -64,18 +64,29 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for the CORBA/BOA/Object/orber interfaces", ""];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
-
-cases() ->
- [exception_info_api, corba_api, object_api, orber_api,
- orber_objectkeys_api, orber_pseudo_objects, callback_ok_api,
- callback_arity_api, callback_module_api, callback_function_api,
- callback_precond_api, callback_postcond_api, callback_exit_api,
- callback_badarith_api, callback_case_clause_api,
- callback_function_clause_api].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [exception_info_api, corba_api, object_api, orber_api,
+ orber_objectkeys_api, orber_pseudo_objects,
+ callback_ok_api, callback_arity_api,
+ callback_module_api, callback_function_api,
+ callback_precond_api, callback_postcond_api,
+ callback_exit_api, callback_badarith_api,
+ callback_case_clause_api, callback_function_clause_api].
%% boa_api, request, locate_request, locate_reply].
@@ -90,14 +101,14 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
corba:orb_init([{orber_debug_level, 10}, {giop_version, {1,2}},
{iiop_port, 0}]),
mnesia:delete_schema([node()]),
@@ -112,7 +123,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
application:stop(orber),
application:stop(mnesia),
mnesia:delete_schema([node()]),
diff --git a/lib/orber/test/csiv2_SUITE.erl b/lib/orber/test/csiv2_SUITE.erl
index 8103fd81ac..95cd8c56b3 100644
--- a/lib/orber/test/csiv2_SUITE.erl
+++ b/lib/orber/test/csiv2_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
-module(csiv2_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -272,8 +272,9 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1,
- init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2,
% code_CertificateChain_api/1,
% code_AttributeCertChain_api/1,
% code_VerifyingCertChain_api/1,
@@ -316,46 +317,26 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for multi orber interfaces using CSIv2"];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% NOTE - the fragment test cases must bu first since we explicitly set a request
%% id. Otherwise, the request-id counter would be increased and we cannot know
%% what it is.
-cases() ->
- [
-% code_CertificateChain_api,
-% code_AttributeCertChain_api,
-% code_VerifyingCertChain_api,
-% code_AttributeCertificate_api,
-% code_Certificate_api,
-% code_TBSCertificate_api,
-% code_CertificateSerialNumber_api,
-% code_Version_api,
-% code_AlgorithmIdentifier_api,
-% code_Name_api,
-% code_RDNSequence_api,
-% code_RelativeDistinguishedName_api,
-% code_AttributeTypeAndValue_api,
-% code_Attribute_api,
-% code_Validity_api,
-% code_SubjectPublicKeyInfo_api,
-% code_UniqueIdentifier_api,
-% code_Extensions_api,
-% code_Extension_api,
-% code_AttributeCertificateInfo_api,
-% code_AttCertVersion_api,
-% code_Holder_api,
-% code_AttCertIssuer_api,
-% code_AttCertValidityPeriod_api,
-% code_V2Form_api,
-% code_IssuerSerial_api,
-% code_ObjectDigestInfo_api,
-% code_OpenSSL509_api,
- ssl_server_peercert_api,
- ssl_client_peercert_api].
+cases() ->
+ [ssl_server_peercert_api, ssl_client_peercert_api].
%%-----------------------------------------------------------------
%% Init and cleanup functions.
@@ -370,7 +351,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
oe_orber_test_server:oe_unregister(),
orber:jump_stop(),
Path = code:which(?MODULE),
@@ -379,15 +360,15 @@ fin_per_testcase(_Case, Config) ->
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
- if
- is_list(Config) ->
- Config;
- true ->
- exit("Config not a list")
+init_per_suite(Config) ->
+ case orber_test_lib:ssl_version() of
+ no_ssl ->
+ {skip,"SSL is not installed!"};
+ _ ->
+ Config
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
Config.
%%-----------------------------------------------------------------
@@ -694,8 +675,8 @@ ssl_server_peercert_api(_Config) ->
{ok, Socket} =
?match({ok, _}, fake_client_ORB(ssl, ServerHost, ServerPort, SSLOptions)),
{ok, _PeerCert} = ?match({ok, _}, orber_socket:peercert(ssl, Socket)),
- ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])),
- ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])),
+%% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])),
+%% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])),
% ?match({ok, #'Certificate'{}},
% 'OrberCSIv2':decode('Certificate', PeerCert)),
destroy_fake_ORB(ssl, Socket),
@@ -734,8 +715,8 @@ ssl_client_peercert_api(_Config) ->
?match(ok, ssl:ssl_accept(Socket)),
{ok, _PeerCert} = ?match({ok, _}, orber_socket:peercert(ssl, Socket)),
- ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])),
- ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])),
+%% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [pkix, subject])),
+%% ?match({ok, {rdnSequence, _}}, orber_socket:peercert(ssl, Socket, [ssl, subject])),
% ?match({ok, #'Certificate'{}},
% 'OrberCSIv2':decode('Certificate', PeerCert)),
ssl:close(Socket),
diff --git a/lib/orber/test/data_types_SUITE.erl b/lib/orber/test/data_types_SUITE.erl
index 1feb0b3b58..45a8af9415 100644
--- a/lib/orber/test/data_types_SUITE.erl
+++ b/lib/orber/test/data_types_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
-module(data_types_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -48,12 +48,12 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -61,10 +61,27 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["This suite is for testing more or less complex data types"];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[fixed_type, any_type].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -75,7 +92,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
Dog = ?config(watchdog, Config),
diff --git a/lib/orber/test/generated_SUITE.erl b/lib/orber/test/generated_SUITE.erl
index 1cd1674fc4..29f0a54aed 100644
--- a/lib/orber/test/generated_SUITE.erl
+++ b/lib/orber/test/generated_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
-module(generated_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -71,7 +71,8 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
@@ -84,16 +85,37 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["This suite is for testing IC generated files"];
-all(suite) ->
- ['OrberApp_IFR',
- erlang_binary, erlang_pid, erlang_port, erlang_ref,
- 'CosNaming_Binding', 'CosNaming_BindingList', 'CosNaming_Name',
- 'CosNaming_NameComponent', 'CosNaming_NamingContextExt_InvalidAddress',
- 'CosNaming_NamingContext_AlreadyBound', 'CosNaming_NamingContext_CannotProceed',
- 'CosNaming_NamingContext_InvalidName', 'CosNaming_NamingContext_NotEmpty',
- 'CosNaming_NamingContext_NotFound', 'CosNaming_BindingIterator',
- 'CosNaming_NamingContext', 'CosNaming_NamingContextExt'].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ ['OrberApp_IFR', erlang_binary, erlang_pid, erlang_port,
+ erlang_ref, 'CosNaming_Binding',
+ 'CosNaming_BindingList', 'CosNaming_Name',
+ 'CosNaming_NameComponent',
+ 'CosNaming_NamingContextExt_InvalidAddress',
+ 'CosNaming_NamingContext_AlreadyBound',
+ 'CosNaming_NamingContext_CannotProceed',
+ 'CosNaming_NamingContext_InvalidName',
+ 'CosNaming_NamingContext_NotEmpty',
+ 'CosNaming_NamingContext_NotFound',
+ 'CosNaming_BindingIterator', 'CosNaming_NamingContext',
+ 'CosNaming_NamingContextExt'].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
@@ -103,7 +125,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/orber/test/iiop_module_do_test_impl.erl b/lib/orber/test/iiop_module_do_test_impl.erl
index bf171a3097..54fcd8239a 100644
--- a/lib/orber/test/iiop_module_do_test_impl.erl
+++ b/lib/orber/test/iiop_module_do_test_impl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/orber/test/iiop_module_test_impl.erl b/lib/orber/test/iiop_module_test_impl.erl
index fe334e1b26..2096c14a23 100644
--- a/lib/orber/test/iiop_module_test_impl.erl
+++ b/lib/orber/test/iiop_module_test_impl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/orber/test/iiop_test_impl.erl b/lib/orber/test/iiop_test_impl.erl
index fd92109c09..234f7c5f73 100644
--- a/lib/orber/test/iiop_test_impl.erl
+++ b/lib/orber/test/iiop_test_impl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/orber/test/interceptors_SUITE.erl b/lib/orber/test/interceptors_SUITE.erl
index 27e23a9433..487cfd0aec 100644
--- a/lib/orber/test/interceptors_SUITE.erl
+++ b/lib/orber/test/interceptors_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
-module(interceptors_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -65,7 +65,8 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
@@ -78,10 +79,27 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["This suite is for testing Orber Interceptors"];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[local_pseudo, local_default, local_local, local_global].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -96,7 +114,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
oe_orber_test_server:oe_unregister(),
orber:jump_stop(),
Path = code:which(?MODULE),
diff --git a/lib/orber/test/iop_ior_10_SUITE.erl b/lib/orber/test/iop_ior_10_SUITE.erl
index 1000c7f113..50d657ea4e 100644
--- a/lib/orber/test/iop_ior_10_SUITE.erl
+++ b/lib/orber/test/iop_ior_10_SUITE.erl
@@ -25,7 +25,7 @@
%%-----------------------------------------------------------------
-module(iop_ior_10_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/src/orber_iiop.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -33,7 +33,8 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
@@ -46,10 +47,27 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[encoding, create_and_get_ops].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -59,7 +77,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/orber/test/iop_ior_11_SUITE.erl b/lib/orber/test/iop_ior_11_SUITE.erl
index 35d01789ee..38112cc335 100644
--- a/lib/orber/test/iop_ior_11_SUITE.erl
+++ b/lib/orber/test/iop_ior_11_SUITE.erl
@@ -25,7 +25,7 @@
%%-----------------------------------------------------------------
-module(iop_ior_11_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/src/orber_iiop.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -33,7 +33,8 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
@@ -46,10 +47,27 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[encoding, create_and_get_ops].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -59,7 +77,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/orber/test/iop_ior_12_SUITE.erl b/lib/orber/test/iop_ior_12_SUITE.erl
index 42db130e54..3baea074c2 100644
--- a/lib/orber/test/iop_ior_12_SUITE.erl
+++ b/lib/orber/test/iop_ior_12_SUITE.erl
@@ -26,7 +26,7 @@
-module(iop_ior_12_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/src/orber_iiop.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -34,7 +34,8 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
@@ -47,10 +48,27 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[encoding, create_and_get_ops].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -60,7 +78,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/orber/test/lname_SUITE.erl b/lib/orber/test/lname_SUITE.erl
index d1f0e7cf0e..5e283d7bba 100644
--- a/lib/orber/test/lname_SUITE.erl
+++ b/lib/orber/test/lname_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
%%-----------------------------------------------------------------
-module(lname_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/COSS/CosNaming/lname.hrl").
@@ -34,7 +34,8 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
@@ -47,10 +48,27 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[lname_component, lname].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -60,7 +78,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/orber/test/multi_ORB_SUITE.erl b/lib/orber/test/multi_ORB_SUITE.erl
index d1931f5393..608fb23f3e 100644
--- a/lib/orber/test/multi_ORB_SUITE.erl
+++ b/lib/orber/test/multi_ORB_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
-module(multi_ORB_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -50,8 +50,9 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1, basic_PI_api/1, multi_orber_api/1,
- init_per_testcase/2, fin_per_testcase/2, multi_pseudo_orber_api/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1, basic_PI_api/1, multi_orber_api/1,
+ init_per_testcase/2, end_per_testcase/2, multi_pseudo_orber_api/1,
light_orber_api/1, light_orber2_api/1,
ssl_1_multi_orber_api/1, ssl_2_multi_orber_api/1, ssl_reconfigure_api/1,
iiop_timeout_api/1, iiop_timeout_added_api/1, setup_connection_timeout_api/1,
@@ -86,75 +87,93 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for multi orber interfaces",
- "This suite test intra-ORB communication. There are three scenarios:",
- "* No security at all (multi_orber_api)",
- "* Two secure orbs using ssl (ssl_multi_orb_api)",
- "* One secure and one orb with no security. (ssl_multi_orb_api)"];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% NOTE - the fragment test cases must be first since we explicitly set a request
%% id. Otherwise, the request-id counter would be increased and we cannot know
%% what it is.
-cases() ->
- [fragments_server_api,
- fragments_max_server_api,
- fragments_max_server_added_api,
- fragments_client_api,
- flags_added_api,
- bad_fragment_id_client_api,
- bad_giop_header_api,
- bad_id_cancel_request_api,
- implicit_context_api,
- pseudo_implicit_context_api,
+cases() ->
+ [fragments_server_api, fragments_max_server_api,
+ fragments_max_server_added_api, fragments_client_api,
+ flags_added_api, bad_fragment_id_client_api,
+ bad_giop_header_api, bad_id_cancel_request_api,
+ implicit_context_api, pseudo_implicit_context_api,
pseudo_two_implicit_context_api,
implicit_context_roundtrip_api,
- oneway_implicit_context_api,
+ oneway_implicit_context_api,
oneway_pseudo_implicit_context_api,
oneway_pseudo_two_implicit_context_api,
- proxy_interface_api,
- proxy_interface_ipv6_api,
- local_interface_api,
- local_interface_ctx_override_api,
- local_interface_acl_override_api,
- close_connections_api,
+ proxy_interface_api, proxy_interface_ipv6_api,
+ local_interface_api, local_interface_ctx_override_api,
+ local_interface_acl_override_api, close_connections_api,
close_connections_local_interface_api,
close_connections_local_interface_ctx_override_api,
close_connections_alt_iiop_addr_api,
close_connections_multiple_profiles_api,
- multiple_accept_api,
- max_requests_api,
- max_requests_added_api,
- max_connections_api,
- max_packet_size_exceeded_api,
- max_packet_size_ok_api,
- light_ifr_api,
- multi_pseudo_orber_api,
- multi_orber_api,
- light_orber_api,
- light_orber2_api,
- basic_PI_api,
- iiop_timeout_api,
- iiop_timeout_added_api,
- setup_connection_timeout_api,
- setup_multi_connection_timeout_api,
- setup_multi_connection_timeout_attempts_api,
- setup_multi_connection_timeout_random_api,
+ multiple_accept_api, max_requests_api,
+ max_requests_added_api, max_connections_api,
+ max_packet_size_exceeded_api, max_packet_size_ok_api,
+ light_ifr_api, multi_pseudo_orber_api, multi_orber_api,
+ light_orber_api, light_orber2_api, basic_PI_api,
+ iiop_timeout_api, iiop_timeout_added_api,
+ setup_connection_timeout_api,
+ setup_multi_connection_timeout_api,
+ setup_multi_connection_timeout_attempts_api,
+ setup_multi_connection_timeout_random_api,
ssl_1_multi_orber_api,
ssl_1_multi_orber_generation_3_api,
ssl_2_multi_orber_api,
ssl_2_multi_orber_generation_3_api,
- ssl_reconfigure_generation_3_api,
- ssl_reconfigure_api
- ].
+ ssl_reconfigure_generation_3_api, ssl_reconfigure_api].
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
-
+init_per_testcase(TC,Config)
+ when TC =:= ssl_1_multi_orber_api;
+ TC =:= ssl_2_multi_orber_api;
+ TC =:= ssl_reconfigure_api ->
+ init_ssl(Config);
+init_per_testcase(TC,Config)
+ when TC =:= ssl_1_multi_orber_generation_3_api;
+ TC =:= ssl_2_multi_orber_generation_3_api;
+ TC =:= ssl_reconfigure_generation_3_api ->
+ init_ssl_3(Config);
init_per_testcase(_Case, Config) ->
+ init_all(Config).
+
+init_ssl(Config) ->
+ case orber_test_lib:ssl_version() of
+ no_ssl ->
+ {skip,"SSL is not installed!"};
+ _ ->
+ init_all(Config)
+ end.
+
+init_ssl_3(Config) ->
+ case orber_test_lib:ssl_version() of
+ 3 ->
+ init_all(Config);
+ 2 ->
+ {skip,"Could not find the correct SSL version!"};
+ no_ssl ->
+ {skip,"SSL is not installed!"}
+ end.
+
+init_all(Config) ->
Path = code:which(?MODULE),
code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
Dog=test_server:timetrap(?default_timeout),
@@ -163,7 +182,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
oe_orber_test_server:oe_unregister(),
orber:jump_stop(),
Path = code:which(?MODULE),
@@ -172,7 +191,7 @@ fin_per_testcase(_Case, Config) ->
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
if
is_list(Config) ->
Config;
@@ -180,7 +199,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
Config.
%%-----------------------------------------------------------------
@@ -1372,7 +1391,7 @@ light_orber2_api(_Config) ->
LocalHost = net_adm:localhost(),
{ok, Node, _Host} =
?match({ok,_,_}, orber_test_lib:js_node([],
- {lightweigth, ["iiop://"++LocalHost++":"++integer_to_list(orber:iiop_port())]})),
+ {lightweight, ["iiop://"++LocalHost++":"++integer_to_list(orber:iiop_port())]})),
?match(ok, orber:info(io)),
?match([_], orber_test_lib:remote_apply(Node, orber_env, get_lightweight_nodes,[])),
@@ -1580,17 +1599,11 @@ ssl_1_multi_orber_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)",
"secure orbs which must raise a NO_PERMISSION exception."];
ssl_1_multi_orber_api(suite) -> [];
ssl_1_multi_orber_api(_Config) ->
- case os:type() of
- vxworks ->
- {skipped, "No SSL-support for VxWorks."};
- _ ->
- ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
- 1, [{iiop_ssl_port, 0}]),
- ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
- 1, [{iiop_ssl_port, 0}]),
- ssl_suite(ServerOptions, ClientOptions),
- ok
- end.
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 1, [{iiop_ssl_port, 0}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 1, [{iiop_ssl_port, 0}]),
+ ssl_suite(ServerOptions, ClientOptions).
ssl_1_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)",
"This case set up two secure orbs and test if they can",
@@ -1598,24 +1611,14 @@ ssl_1_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL dep
"secure orbs which must raise a NO_PERMISSION exception."];
ssl_1_multi_orber_generation_3_api(suite) -> [];
ssl_1_multi_orber_generation_3_api(_Config) ->
- case os:type() of
- vxworks ->
- {skipped, "No SSL-support for VxWorks."};
- _ ->
- case orber_test_lib:ssl_version() of
- 3 ->
- ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
- 1, [{ssl_generation, 3},
- {iiop_ssl_port, 0}]),
- ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
- 1, [{ssl_generation, 3},
- {iiop_ssl_port, 0}]),
- ssl_suite(ServerOptions, ClientOptions),
- ok;
- _ ->
- {skipped, "Required SSL generation not available"}
- end
- end.
+
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 1, [{ssl_generation, 3},
+ {iiop_ssl_port, 0}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 1, [{ssl_generation, 3},
+ {iiop_ssl_port, 0}]),
+ ssl_suite(ServerOptions, ClientOptions).
%%-----------------------------------------------------------------
@@ -1628,17 +1631,12 @@ ssl_2_multi_orber_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)",
"secure orbs which must raise a NO_PERMISSION exception."];
ssl_2_multi_orber_api(suite) -> [];
ssl_2_multi_orber_api(_Config) ->
- case os:type() of
- vxworks ->
- {skipped, "No SSL-support for VxWorks."};
- _ ->
- ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
- 2, [{iiop_ssl_port, 0}]),
- ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
- 2, [{iiop_ssl_port, 0}]),
- ssl_suite(ServerOptions, ClientOptions),
- ok
- end.
+
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 2, [{iiop_ssl_port, 0}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 2, [{iiop_ssl_port, 0}]),
+ ssl_suite(ServerOptions, ClientOptions).
ssl_2_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth 2)",
"This case set up two secure orbs and test if they can",
@@ -1646,24 +1644,14 @@ ssl_2_multi_orber_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL dep
"secure orbs which must raise a NO_PERMISSION exception."];
ssl_2_multi_orber_generation_3_api(suite) -> [];
ssl_2_multi_orber_generation_3_api(_Config) ->
- case os:type() of
- vxworks ->
- {skipped, "No SSL-support for VxWorks."};
- _ ->
- case orber_test_lib:ssl_version() of
- 3 ->
- ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
- 2, [{ssl_generation, 3},
- {iiop_ssl_port, 0}]),
- ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
- 2, [{ssl_generation, 3},
- {iiop_ssl_port, 0}]),
- ssl_suite(ServerOptions, ClientOptions),
- ok;
- _ ->
- {skipped, "Required SSL generation not available"}
- end
- end.
+
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 2, [{ssl_generation, 3},
+ {iiop_ssl_port, 0}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 2, [{ssl_generation, 3},
+ {iiop_ssl_port, 0}]),
+ ssl_suite(ServerOptions, ClientOptions).
%%-----------------------------------------------------------------
%% API tests for ORB to ORB, ssl security depth 2
%%-----------------------------------------------------------------
@@ -1682,69 +1670,57 @@ ssl_reconfigure_generation_3_api(doc) -> ["SECURE MULTI ORB API tests (SSL depth
"secure orbs which must raise a NO_PERMISSION exception."];
ssl_reconfigure_generation_3_api(suite) -> [];
ssl_reconfigure_generation_3_api(_Config) ->
- case orber_test_lib:ssl_version() of
- 3 ->
- ssl_reconfigure([{ssl_generation, 3}]);
-
- _ ->
- {skipped, "Required SSL generation not available"}
- end.
+ ssl_reconfigure([{ssl_generation, 3}]).
ssl_reconfigure(ExtraSSLOptions) ->
- case os:type() of
- vxworks ->
- {skipped, "No SSL-support for VxWorks."};
- _ ->
- IP = orber_test_lib:get_host(),
- Loopback = orber_test_lib:get_loopback_interface(),
- {ok, ServerNode, _ServerHost} =
- ?match({ok,_,_},
- orber_test_lib:js_node([{iiop_port, 0},
- {flags, ?ORB_ENV_LOCAL_INTERFACE},
- {ip_address, IP}|ExtraSSLOptions])),
- orber_test_lib:remote_apply(ServerNode, ssl, start, []),
- orber_test_lib:remote_apply(ServerNode, crypto, start, []),
- orber_test_lib:remote_apply(ServerNode, ssl, seed, ["testing"]),
- ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
- install_test_data,
- [ssl])),
- ?match({ok, _},
- orber_test_lib:remote_apply(ServerNode, orber,
- add_listen_interface,
- [Loopback, normal, [{iiop_port, 5648},
- {iiop_ssl_port, 5649},
- {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]])),
- ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
- 2, [{flags, ?ORB_ENV_LOCAL_INTERFACE},
- {iiop_port, 5648},
+
+ IP = orber_test_lib:get_host(),
+ Loopback = orber_test_lib:get_loopback_interface(),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_},
+ orber_test_lib:js_node([{iiop_port, 0},
+ {flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {ip_address, IP}|ExtraSSLOptions])),
+ orber_test_lib:remote_apply(ServerNode, ssl, start, []),
+ orber_test_lib:remote_apply(ServerNode, crypto, start, []),
+ orber_test_lib:remote_apply(ServerNode, ssl, seed, ["testing"]),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [ssl])),
+ ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [Loopback, normal, [{iiop_port, 5648},
{iiop_ssl_port, 5649},
- {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]),
- ?match({ok, _},
- orber_test_lib:remote_apply(ServerNode, orber,
- add_listen_interface,
- [Loopback, ssl, ServerOptions])),
-
- ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
- 2, [{iiop_ssl_port, 0}|ExtraSSLOptions]),
- {ok, ClientNode, _ClientHost} =
- ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)),
-
- ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib,
- install_test_data,
- [ssl])),
- orber_test_lib:remote_apply(ClientNode, ssl, start, []),
- orber_test_lib:remote_apply(ServerNode, crypto, start, []),
- orber_test_lib:remote_apply(ClientNode, ssl, seed, ["testing"]),
- Obj = ?match(#'IOP_IOR'{},
- orber_test_lib:remote_apply(ClientNode, corba,
- string_to_object, ["corbaname:iiop:1.1@"++Loopback++":5648/NameService#mamba",
- [{context, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
- context_data = {configuration, ClientOptions}}]}]])),
- ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_server,
- print, [Obj])),
-
- ok
- end.
+ {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]])),
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 2, [{flags, ?ORB_ENV_LOCAL_INTERFACE},
+ {iiop_port, 5648},
+ {iiop_ssl_port, 5649},
+ {interceptors, {native, [orber_iiop_tracer_silent]}}|ExtraSSLOptions]),
+ ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [Loopback, ssl, ServerOptions])),
+
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 2, [{iiop_ssl_port, 0}|ExtraSSLOptions]),
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)),
+
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_lib,
+ install_test_data,
+ [ssl])),
+ orber_test_lib:remote_apply(ClientNode, ssl, start, []),
+ orber_test_lib:remote_apply(ServerNode, crypto, start, []),
+ orber_test_lib:remote_apply(ClientNode, ssl, seed, ["testing"]),
+ Obj = ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba,
+ string_to_object, ["corbaname:iiop:1.1@"++Loopback++":5648/NameService#mamba",
+ [{context, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,
+ context_data = {configuration, ClientOptions}}]}]])),
+ ?match(ok, orber_test_lib:remote_apply(ClientNode, orber_test_server,
+ print, [Obj])).
diff --git a/lib/orber/test/naming_context_SUITE.erl b/lib/orber/test/naming_context_SUITE.erl
index 4406e01d5a..5250beacbe 100644
--- a/lib/orber/test/naming_context_SUITE.erl
+++ b/lib/orber/test/naming_context_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
%%-----------------------------------------------------------------
-module(naming_context_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/src/orber_iiop.hrl").
-include_lib("orber/include/corba.hrl").
@@ -35,7 +35,7 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
@@ -43,7 +43,8 @@
-export([name_context/1, check_list/1, name_context_ext/1]).
--export([init_all/1, finish_all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_suite/1, end_per_suite/1, init_per_testcase/2,
+ end_per_testcase/2]).
%%-----------------------------------------------------------------
@@ -75,12 +76,22 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-cases() ->
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
[name_context, check_list, name_context_ext].
%%-----------------------------------------------------------------
@@ -95,7 +106,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:del_path(filename:join(filename:dirname(Path), "idl_output")),
orber:jump_stop(),
@@ -103,10 +114,10 @@ fin_per_testcase(_Case, Config) ->
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
Config.
-finish_all(Config) ->
+end_per_suite(Config) ->
Config.
%%-----------------------------------------------------------------
diff --git a/lib/orber/test/orber.cover b/lib/orber/test/orber.cover
new file mode 100644
index 0000000000..807a7c2c6e
--- /dev/null
+++ b/lib/orber/test/orber.cover
@@ -0,0 +1,2 @@
+{incl_app,orber,details}.
+
diff --git a/lib/orber/test/orber.spec b/lib/orber/test/orber.spec
index 9d19ea7fc1..0dd30deade 100644
--- a/lib/orber/test/orber.spec
+++ b/lib/orber/test/orber.spec
@@ -1,19 +1 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-{topcase, {dir, "../orber_test"}}.
+{suites,"../orber_test",all}.
diff --git a/lib/orber/test/orber_SUITE.erl b/lib/orber/test/orber_SUITE.erl
index f54da02c0e..a55705e550 100644
--- a/lib/orber/test/orber_SUITE.erl
+++ b/lib/orber/test/orber_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,15 +18,16 @@
%%
%%
-module(orber_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(default_timeout, ?t:minutes(15)).
-define(application, orber).
% Test server specific exports
--export([all/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
% Test cases must be exported.
-export([app_test/1, undefined_functions/1, install_load_order/1,
@@ -35,17 +36,33 @@
%%
%% all/1
%%
-all(doc) ->
- [];
-all(suite) ->
- [app_test, undefined_functions,
- install_load_order, install_local_content].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [app_test, undefined_functions, install_load_order,
+ install_local_content].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/orber/test/orber_acl_SUITE.erl b/lib/orber/test/orber_acl_SUITE.erl
index 2c2a768af2..9e69457d6e 100644
--- a/lib/orber/test/orber_acl_SUITE.erl
+++ b/lib/orber/test/orber_acl_SUITE.erl
@@ -25,7 +25,7 @@
%%-----------------------------------------------------------------
-module(orber_acl_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(default_timeout, ?t:minutes(5)).
@@ -47,7 +47,7 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
@@ -59,15 +59,26 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Testing API for ACL (Access Control List)"];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[ipv4_verify, ipv4_range, ipv4_interfaces, ipv4_bm,
ipv6_verify, ipv6_range, ipv6_interfaces, ipv6_bm].
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
-init_all(Config) ->
+init_per_suite(Config) ->
if
list(Config) ->
Config;
@@ -75,7 +86,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
Config.
@@ -84,7 +95,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl b/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl
index 3ac0cb7921..e2c73c2fd0 100644
--- a/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl
+++ b/lib/orber/test/orber_firewall_ipv4_in_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
-module(orber_firewall_ipv4_in_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -49,8 +49,9 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1,
- init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2,
deny_port_api/1, deny_port_range_api/1, deny_host_api/1,
deny_peerhost_api/1, allow_port_range_api/1,
allow_host_api/1, allow_peerhost_api/1, check_address_api/1]).
@@ -60,17 +61,28 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for orber's firewall functionallity."];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% NOTE - the fragment test cases must bu first since we explicitly set a request
%% id. Otherwise, the request-id counter would be increased and we cannot know
%% what it is.
-cases() ->
- [deny_port_api, deny_port_range_api, deny_host_api, deny_peerhost_api,
- allow_port_range_api, allow_host_api, allow_peerhost_api, check_address_api].
+cases() ->
+ [deny_port_api, deny_port_range_api, deny_host_api,
+ deny_peerhost_api, allow_port_range_api, allow_host_api,
+ allow_peerhost_api, check_address_api].
init_per_testcase(_Case, Config) ->
@@ -78,12 +90,12 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
if
is_list(Config) ->
orber:jump_start([{iiop_port, 0},
@@ -93,7 +105,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
orber:jump_stop(),
Config.
diff --git a/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl b/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl
index 193fc72f7c..ac6c7327a1 100644
--- a/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl
+++ b/lib/orber/test/orber_firewall_ipv4_out_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
-module(orber_firewall_ipv4_out_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -49,8 +49,9 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1,
- init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2,
deny_port_api/1, deny_port_range_api/1, deny_host_api/1,
allow_port_api/1, allow_port_range_api/1, allow_host_api/1,
local_interface_api/1]).
@@ -60,15 +61,25 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for orber's firewall functionallity."];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% NOTE - the fragment test cases must bu first since we explicitly set a request
%% id. Otherwise, the request-id counter would be increased and we cannot know
%% what it is.
-cases() ->
+cases() ->
[deny_port_api, deny_port_range_api, deny_host_api,
allow_port_api, allow_port_range_api, allow_host_api,
local_interface_api].
@@ -79,12 +90,12 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
if
is_list(Config) ->
orber:jump_start([{iiop_port, 0},
@@ -94,7 +105,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
orber:jump_stop(),
Config.
diff --git a/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl b/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
index 83f48cba0c..2888565c54 100644
--- a/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
+++ b/lib/orber/test/orber_firewall_ipv6_in_SUITE.erl
@@ -20,7 +20,7 @@
-module(orber_firewall_ipv6_in_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -49,8 +49,9 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1,
- init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2,
deny_port_api/1, deny_port_range_api/1, deny_host_api/1,
deny_peerhost_api/1, allow_port_range_api/1,
allow_host_api/1, allow_peerhost_api/1, check_address_api/1]).
@@ -60,18 +61,28 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for orber's firewall functionallity."];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% NOTE - the fragment test cases must bu first since we explicitly set a request
%% id. Otherwise, the request-id counter would be increased and we cannot know
%% what it is.
-cases() ->
- [deny_port_api, deny_port_range_api, deny_host_api, deny_peerhost_api,
- allow_port_range_api, allow_host_api, allow_peerhost_api,
- check_address_api].
+cases() ->
+ [deny_port_api, deny_port_range_api, deny_host_api,
+ deny_peerhost_api, allow_port_range_api, allow_host_api,
+ allow_peerhost_api, check_address_api].
init_per_testcase(_Case, Config) ->
@@ -82,13 +93,13 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
orber:jump_stop(),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
case orber_test_lib:version_ok() of
true ->
if
@@ -101,7 +112,7 @@ init_all(Config) ->
Reason
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
Config.
diff --git a/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl b/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl
index e1856b9a47..f0a865adcb 100644
--- a/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl
+++ b/lib/orber/test/orber_firewall_ipv6_out_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
-module(orber_firewall_ipv6_out_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -49,8 +49,9 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1,
- init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2,
deny_port_api/1, deny_port_range_api/1, deny_host_api/1,
allow_port_api/1, allow_port_range_api/1, allow_host_api/1,
local_interface_api/1]).
@@ -60,15 +61,25 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for orber's firewall functionallity."];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% NOTE - the fragment test cases must bu first since we explicitly set a request
%% id. Otherwise, the request-id counter would be increased and we cannot know
%% what it is.
-cases() ->
+cases() ->
[deny_port_api, deny_port_range_api, deny_host_api,
allow_port_api, allow_port_range_api, allow_host_api,
local_interface_api].
@@ -82,13 +93,13 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
orber:jump_stop(),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
case orber_test_lib:version_ok() of
true ->
if
@@ -101,7 +112,7 @@ init_all(Config) ->
Reason
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
Config.
diff --git a/lib/orber/test/orber_nat_SUITE.erl b/lib/orber/test/orber_nat_SUITE.erl
index 5b295dd1aa..264a8ec523 100644
--- a/lib/orber/test/orber_nat_SUITE.erl
+++ b/lib/orber/test/orber_nat_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
-module(orber_nat_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/COSS/CosNaming/CosNaming.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -50,8 +50,9 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1, cases/0, init_all/1, finish_all/1,
- init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, cases/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2,
nat_ip_address/1, nat_ip_address_multiple/1,
nat_ip_address_local/1, nat_ip_address_local_local/1,
nat_iiop_port/1, nat_iiop_port_local/1,
@@ -68,32 +69,40 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["API tests for multi orber interfaces",
- "This suite test intra-ORB communication. There are three scenarios:",
- "* No security at all (multi_orber_api)",
- "* Two secure orbs using ssl (ssl_multi_orb_api)",
- "* One secure and one orb with no security. (ssl_multi_orb_api)"];
-all(suite) -> {req,
- [mnesia],
- {conf, init_all, cases(), finish_all}}.
-
-cases() ->
- [
- nat_ip_address,
- nat_ip_address_multiple,
- nat_ip_address_local,
- nat_iiop_port,
- nat_iiop_port_local,
- nat_ip_address_local_local,
- nat_iiop_port_local_local,
- nat_iiop_ssl_port,
- nat_iiop_ssl_port_local
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ cases().
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+cases() ->
+ [nat_ip_address, nat_ip_address_multiple,
+ nat_ip_address_local, nat_iiop_port,
+ nat_iiop_port_local, nat_ip_address_local_local,
+ nat_iiop_port_local_local, nat_iiop_ssl_port,
+ nat_iiop_ssl_port_local].
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
-
+init_per_testcase(TC, Config)
+ when TC =:= nat_iiop_ssl_port;
+ TC =:= nat_iiop_ssl_port_local ->
+ case orber_test_lib:ssl_version() of
+ no_ssl ->
+ {skip,"SSL not installed!"};
+ _ ->
+ init_per_testcase(dummy_tc, Config)
+ end;
init_per_testcase(_Case, Config) ->
Path = code:which(?MODULE),
code:add_pathz(filename:join(filename:dirname(Path), "idl_output")),
@@ -104,7 +113,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
oe_orber_test_server:oe_unregister(),
orber:jump_stop(),
Path = code:which(?MODULE),
@@ -113,7 +122,7 @@ fin_per_testcase(_Case, Config) ->
test_server:timetrap_cancel(Dog),
ok.
-init_all(Config) ->
+init_per_suite(Config) ->
if
is_list(Config) ->
Config;
@@ -121,7 +130,7 @@ init_all(Config) ->
exit("Config not a list")
end.
-finish_all(Config) ->
+end_per_suite(Config) ->
Config.
%%-----------------------------------------------------------------
@@ -266,107 +275,99 @@ nat_iiop_ssl_port(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)",
"Make sure NAT works for SSL"];
nat_iiop_ssl_port(suite) -> [];
nat_iiop_ssl_port(_Config) ->
- case os:type() of
- vxworks ->
- {skipped, "No SSL-support for VxWorks."};
- _ ->
- IP = orber_test_lib:get_host(),
- ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
- 1, [{iiop_ssl_port, 0},
- {flags, ?ORB_ENV_ENABLE_NAT},
- {ip_address, IP}]),
- ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
- 1, [{iiop_ssl_port, 0}]),
- {ok, ServerNode, _ServerHost} =
- ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)),
- ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
- SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []),
- NATSSLServerPort = SSLServerPort+1,
- {ok, Ref} = ?match({ok, _},
- orber_test_lib:remote_apply(ServerNode, orber,
- add_listen_interface,
- [IP, ssl, NATSSLServerPort])),
- orber_test_lib:remote_apply(ServerNode, orber_env, configure_override,
- [nat_iiop_ssl_port,
- {local, NATSSLServerPort, [{4001, 43}]}]),
-
- {ok, ClientNode, _ClientHost} =
- ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)),
- ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
- install_test_data,
- [ssl])),
-
- IOR1 = ?match(#'IOP_IOR'{},
- orber_test_lib:remote_apply(ClientNode, corba,
- string_to_object,
- ["corbaname::1.2@"++IP++":"++
- integer_to_list(ServerPort)++"/NameService#mamba"])),
-
- ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP,
- #host_data{protocol = ssl,
- ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}},
- iop_ior:get_key(IOR1)),
- ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
- uninstall_test_data,
- [ssl])),
- ?match(ok,
- orber_test_lib:remote_apply(ServerNode, orber,
- remove_listen_interface, [Ref])),
- ok
- end.
+
+ IP = orber_test_lib:get_host(),
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 1, [{iiop_ssl_port, 0},
+ {flags, ?ORB_ENV_ENABLE_NAT},
+ {ip_address, IP}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 1, [{iiop_ssl_port, 0}]),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []),
+ NATSSLServerPort = SSLServerPort+1,
+ {ok, Ref} = ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [IP, ssl, NATSSLServerPort])),
+ orber_test_lib:remote_apply(ServerNode, orber_env, configure_override,
+ [nat_iiop_ssl_port,
+ {local, NATSSLServerPort, [{4001, 43}]}]),
+
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [ssl])),
+
+ IOR1 = ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba,
+ string_to_object,
+ ["corbaname::1.2@"++IP++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba"])),
+
+ ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP,
+ #host_data{protocol = ssl,
+ ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}},
+ iop_ior:get_key(IOR1)),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ uninstall_test_data,
+ [ssl])),
+ ?match(ok,
+ orber_test_lib:remote_apply(ServerNode, orber,
+ remove_listen_interface, [Ref])),
+ ok.
nat_iiop_ssl_port_local(doc) -> ["SECURE MULTI ORB API tests (SSL depth 1)",
"Make sure NAT works for SSL"];
nat_iiop_ssl_port_local(suite) -> [];
nat_iiop_ssl_port_local(_Config) ->
- case os:type() of
- vxworks ->
- {skipped, "No SSL-support for VxWorks."};
- _ ->
- IP = orber_test_lib:get_host(),
- ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
- 1, [{iiop_ssl_port, 0},
- {flags,
- (?ORB_ENV_LOCAL_INTERFACE bor
- ?ORB_ENV_ENABLE_NAT)},
- {ip_address, IP}]),
- ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
- 1, [{iiop_ssl_port, 0}]),
- {ok, ServerNode, _ServerHost} =
- ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)),
- ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
- SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []),
- NATSSLServerPort = SSLServerPort+1,
- {ok, Ref} = ?match({ok, _},
- orber_test_lib:remote_apply(ServerNode, orber,
- add_listen_interface,
- [IP, ssl, NATSSLServerPort])),
- orber_test_lib:remote_apply(ServerNode, orber_env, configure_override,
- [nat_iiop_ssl_port,
- {local, NATSSLServerPort, [{NATSSLServerPort, NATSSLServerPort}]}]),
-
- {ok, ClientNode, _ClientHost} =
- ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)),
- ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
- install_test_data,
- [ssl])),
-
- IOR1 = ?match(#'IOP_IOR'{},
- orber_test_lib:remote_apply(ClientNode, corba,
- string_to_object,
- ["corbaname::1.2@"++IP++":"++
- integer_to_list(ServerPort)++"/NameService#mamba"])),
-
- ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP,
- #host_data{protocol = ssl,
- ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}},
- iop_ior:get_key(IOR1)),
- ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
- uninstall_test_data,
- [ssl])),
- ?match(ok,
- orber_test_lib:remote_apply(ServerNode, orber,
- remove_listen_interface, [Ref])),
- ok
- end.
+
+ IP = orber_test_lib:get_host(),
+ ServerOptions = orber_test_lib:get_options(iiop_ssl, server,
+ 1, [{iiop_ssl_port, 0},
+ {flags,
+ (?ORB_ENV_LOCAL_INTERFACE bor
+ ?ORB_ENV_ENABLE_NAT)},
+ {ip_address, IP}]),
+ ClientOptions = orber_test_lib:get_options(iiop_ssl, client,
+ 1, [{iiop_ssl_port, 0}]),
+ {ok, ServerNode, _ServerHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ServerOptions)),
+ ServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_port, []),
+ SSLServerPort = orber_test_lib:remote_apply(ServerNode, orber, iiop_ssl_port, []),
+ NATSSLServerPort = SSLServerPort+1,
+ {ok, Ref} = ?match({ok, _},
+ orber_test_lib:remote_apply(ServerNode, orber,
+ add_listen_interface,
+ [IP, ssl, NATSSLServerPort])),
+ orber_test_lib:remote_apply(ServerNode, orber_env, configure_override,
+ [nat_iiop_ssl_port,
+ {local, NATSSLServerPort, [{NATSSLServerPort, NATSSLServerPort}]}]),
+
+ {ok, ClientNode, _ClientHost} =
+ ?match({ok,_,_}, orber_test_lib:js_node(ClientOptions)),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ install_test_data,
+ [ssl])),
+
+ IOR1 = ?match(#'IOP_IOR'{},
+ orber_test_lib:remote_apply(ClientNode, corba,
+ string_to_object,
+ ["corbaname::1.2@"++IP++":"++
+ integer_to_list(ServerPort)++"/NameService#mamba"])),
+
+ ?match({'external', {_IP, _Port, _ObjectKey, _Counter, _TP,
+ #host_data{protocol = ssl,
+ ssl_data = #'SSLIOP_SSL'{port = NATSSLServerPort}}}},
+ iop_ior:get_key(IOR1)),
+ ?match(ok, orber_test_lib:remote_apply(ServerNode, orber_test_lib,
+ uninstall_test_data,
+ [ssl])),
+ ?match(ok,
+ orber_test_lib:remote_apply(ServerNode, orber,
+ remove_listen_interface, [Ref])),
+ ok.
diff --git a/lib/orber/test/orber_test_lib.erl b/lib/orber/test/orber_test_lib.erl
index a694dc58c4..ffc13d0e3c 100644
--- a/lib/orber/test/orber_test_lib.erl
+++ b/lib/orber/test/orber_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -95,16 +95,21 @@
%%
%%------------------------------------------------------------
ssl_version() ->
- case catch erlang:system_info(otp_release) of
- Version when is_list(Version) ->
- if
- "R12B" < Version ->
- 3;
- true ->
- 2
- end;
- _ ->
- 2
+ try
+ ssl:module_info(),
+ case catch erlang:system_info(otp_release) of
+ Version when is_list(Version) ->
+ if
+ "R12B" < Version ->
+ 3;
+ true ->
+ 2
+ end;
+ _ ->
+ 2
+ end
+ catch error:undef ->
+ no_ssl
end.
%%------------------------------------------------------------
@@ -126,13 +131,22 @@ version_ok() ->
_ ->
case gen_tcp:listen(0, [{reuseaddr, true}, inet6]) of
{ok, LSock} ->
- gen_tcp:close(LSock),
- true;
+ {ok, Port} = inet:port(LSock),
+ case gen_tcp:connect(Hostname, Port, [inet6]) of
+ {error, _} ->
+ gen_tcp:close(LSock),
+ {skipped, "Inet cannot handle IPv6"};
+ {ok, Socket} ->
+ gen_tcp:close(Socket),
+ gen_tcp:close(LSock),
+ true
+ end;
{error, _} ->
{skipped, "Inet cannot handle IPv6"}
end
end
end.
+
%%------------------------------------------------------------
%% function : get_host
%% Arguments: Family - inet | inet6
@@ -287,9 +301,11 @@ start_ssl(true, Node) ->
start_ssl(_, _) ->
ok.
-start_orber({lightweigth, Options}, Node) ->
+start_orber({lightweight, Options}, Node) ->
+ ok = rpc:call(Node, mnesia, start, []),
ok = rpc:call(Node, orber, start_lightweight, [Options]);
start_orber(lightweight, Node) ->
+ ok = rpc:call(Node, mnesia, start, []),
ok = rpc:call(Node, orber, start_lightweight, []);
start_orber(_, Node) ->
ok = rpc:call(Node, orber, jump_start, []).
@@ -1280,6 +1296,22 @@ test_coding(Obj, Local) ->
?match({'EXCEPTION',{'MARSHAL',_,_,_}},
orber_test_server:
testing_iiop_server_marshal(Obj, "string")),
+
+ RecS = #orber_test_server_rec_struct{chain = [#orber_test_server_rec_struct{chain = []}]},
+ ?match(RecS, orber_test_server:testing_iiop_rec_struct(Obj, RecS)),
+
+ RecU = #orber_test_server_rec_union{label = 'RecursiveType',
+ value = [#orber_test_server_rec_union{label = 'RecursiveType',
+ value = []}]},
+ ?match(RecU, orber_test_server:testing_iiop_rec_union(Obj, RecU)),
+
+%% RecA1 = #any{typecode = unsupported, value = RecS},
+%% RecA2 = #any{typecode = unsupported, value = RecU},
+%% ?match(RecA1,
+%% orber_test_server:testing_iiop_rec_any(Obj, RecA1)),
+%% ?match(RecA2,
+%% orber_test_server:testing_iiop_rec_any(Obj, RecA2)),
+
ok.
%%--------------- Testing Post- & Pre-cond -------------------
diff --git a/lib/orber/test/orber_test_server.idl b/lib/orber/test/orber_test_server.idl
index a88211c941..438c10e19b 100644
--- a/lib/orber/test/orber_test_server.idl
+++ b/lib/orber/test/orber_test_server.idl
@@ -28,7 +28,7 @@ module orber_parent {
};
module orber_test {
-
+
// interface server
interface server : orber_parent::inherrit {
typedef string array[2];
@@ -89,6 +89,23 @@ module orber_test {
const fixed52 fixed52negconst2 = -123.00d;
const fixed52 fixed52negconst3 = -023.00d;
+ struct rec_struct; // Forward declaration
+ typedef sequence<rec_struct> rec_struct_seq;
+ struct rec_struct {
+ rec_struct_seq chain;
+ };
+
+
+ union rec_union; // Forward declaration
+ typedef sequence<rec_union>rec_union_seq;
+
+ enum MyEnum {RecursiveType, NameType};
+
+ union rec_union switch (MyEnum) {
+ case RecursiveType : rec_union_seq chain;
+ case NameType : string aName;
+ };
+
void stop_normal();
void stop_brutal();
@@ -123,6 +140,12 @@ module orber_test {
void testing_iiop_context();
void testing_iiop_server_marshal(inout StrLength6 Str);
+ // Recursive types
+ any testing_iiop_rec_any(in any RecType);
+ rec_struct testing_iiop_rec_struct(in rec_struct RecS);
+ rec_union testing_iiop_rec_union(in rec_union RecU);
+
+
oneway void testing_iiop_oneway_delay(in long Time);
void testing_iiop_twoway_delay(in long Time);
diff --git a/lib/orber/test/orber_test_server_impl.erl b/lib/orber/test/orber_test_server_impl.erl
index 35296cb619..10a9caf242 100644
--- a/lib/orber/test/orber_test_server_impl.erl
+++ b/lib/orber/test/orber_test_server_impl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -55,6 +55,9 @@
testing_iiop_void/2,
testing_iiop_context/2,
testing_iiop_server_marshal/3,
+ testing_iiop_rec_any/3,
+ testing_iiop_rec_struct/3,
+ testing_iiop_rec_union/3,
relay_call/3,
relay_cast/3,
%% Testing pseudo calls.
@@ -197,6 +200,16 @@ testing_iiop_context(_Self, State) ->
testing_iiop_server_marshal(_Self, State, _String) ->
{reply, {ok, false}, State}.
+testing_iiop_rec_any(_Self, State, RAny) ->
+ {reply, RAny, State}.
+
+testing_iiop_rec_struct(_Self, State, RecS) ->
+ {reply, RecS, State}.
+
+testing_iiop_rec_union(_Self, State, RecU) ->
+ {reply, RecU, State}.
+
+
testing_iiop_oneway_delay(_Self, State, Time) ->
timer:sleep(Time),
{noreply, State}.
diff --git a/lib/orber/test/orber_test_timeout_server_impl.erl b/lib/orber/test/orber_test_timeout_server_impl.erl
index 138eb51d92..67ea897fdd 100644
--- a/lib/orber/test/orber_test_timeout_server_impl.erl
+++ b/lib/orber/test/orber_test_timeout_server_impl.erl
@@ -2,7 +2,7 @@
%%
%% %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
diff --git a/lib/orber/test/orber_web_SUITE.erl b/lib/orber/test/orber_web_SUITE.erl
index ffa7468853..ed5c0cbfa0 100644
--- a/lib/orber/test/orber_web_SUITE.erl
+++ b/lib/orber/test/orber_web_SUITE.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
-module(orber_web_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/include/corba.hrl").
-include_lib("orber/src/orber_iiop.hrl").
@@ -65,12 +65,12 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -78,10 +78,28 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["This suite is for testing the Orber Web API"];
-all(suite) ->
- [menu, configure, info, nameservice, ifr_select, ifr_data,
- create, delete_ctx, add_ctx, delete_obj, server].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [menu, configure, info, nameservice, ifr_select,
+ ifr_data, create, delete_ctx, add_ctx, delete_obj,
+ server].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
@@ -95,7 +113,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
oe_orber_test_server:oe_unregister(),
orber:jump_stop(),
Path = code:which(?MODULE),
diff --git a/lib/orber/test/tc_SUITE.erl b/lib/orber/test/tc_SUITE.erl
index 807a663219..9e6ee4eb90 100644
--- a/lib/orber/test/tc_SUITE.erl
+++ b/lib/orber/test/tc_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
%%-----------------------------------------------------------------
-module(tc_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("orber/src/orber_iiop.hrl").
-define(default_timeout, ?t:minutes(3)).
@@ -128,12 +128,12 @@
%%-----------------------------------------------------------------
%% External exports
%%-----------------------------------------------------------------
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%-----------------------------------------------------------------
%% Internal exports
%%-----------------------------------------------------------------
--export([]).
-compile(export_all).
%%-----------------------------------------------------------------
@@ -141,19 +141,32 @@
%% Args:
%% Returns:
%%-----------------------------------------------------------------
-all(doc) -> ["Description", "more description"];
-all(suite) ->
- [null, void,
- short, ushort,
- long, ulong,
- longlong, ulonglong,
- boolean, char, wchar, octet,
- float, double, longdouble,
- any, typecode, principal, object_reference,
- struct, union, enum, string, wstring, sequence, array,
- alias, exception, fixed, value, value_box, native,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [null, void, short, ushort, long, ulong, longlong,
+ ulonglong, boolean, char, wchar, octet, float, double,
+ longdouble, any, typecode, principal, object_reference,
+ struct, union, enum, string, wstring, sequence, array,
+ alias, exception, fixed, value, value_box, native,
abstract_interface, indirection, get_tc].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-----------------------------------------------------------------
%% Init and cleanup functions.
%%-----------------------------------------------------------------
@@ -163,7 +176,7 @@ init_per_testcase(_Case, Config) ->
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk
index 681b82b51b..5f17cda229 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -1 +1,3 @@
-ORBER_VSN = 3.6.17
+
+ORBER_VSN = 3.6.20
+
diff --git a/lib/os_mon/test/Makefile b/lib/os_mon/test/Makefile
index c87285e38b..f14a791806 100644
--- a/lib/os_mon/test/Makefile
+++ b/lib/os_mon/test/Makefile
@@ -85,7 +85,7 @@ release_spec:
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) os_mon.spec $(EMAKEFILE) $(SOURCE) $(RELSYSDIR)
+ $(INSTALL_DATA) os_mon.spec os_mon.cover $(EMAKEFILE) $(SOURCE) $(RELSYSDIR)
## tar chf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/os_mon/test/cpu_sup_SUITE.erl b/lib/os_mon/test/cpu_sup_SUITE.erl
index 45f9d981d1..174317527c 100644
--- a/lib/os_mon/test/cpu_sup_SUITE.erl
+++ b/lib/os_mon/test/cpu_sup_SUITE.erl
@@ -17,10 +17,10 @@
%% %CopyrightEnd%
%%
-module(cpu_sup_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([init_per_suite/1, end_per_suite/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -41,29 +41,43 @@ end_per_suite(Config) when is_list(Config) ->
?line ok = application:stop(os_mon),
Config.
+init_per_testcase(unavailable, Config) ->
+ terminate(Config),
+ init_per_testcase(dummy, Config);
init_per_testcase(_Case, Config) ->
Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
+end_per_testcase(unavailable, Config) ->
+ restart(Config),
+ end_per_testcase(dummy, Config);
end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- case ?t:os_type() of
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:os_type() of
{unix, sunos} ->
- [load_api, util_api, util_values, port,
- {conf, terminate, [unavailable], restart}];
+ [load_api, util_api, util_values, port, unavailable];
{unix, linux} ->
- [load_api, util_api, util_values, port,
- {conf, terminate, [unavailable], restart}];
- {unix, _OSname} ->
- [load_api];
- _OS ->
- [unavailable]
+ [load_api, util_api, util_values, port, unavailable];
+ {unix, _OSname} -> [load_api];
+ _OS -> [unavailable]
end.
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
load_api(suite) ->
[];
load_api(doc) ->
diff --git a/lib/os_mon/test/disksup_SUITE.erl b/lib/os_mon/test/disksup_SUITE.erl
index 987d631c36..6e015ef74a 100644
--- a/lib/os_mon/test/disksup_SUITE.erl
+++ b/lib/os_mon/test/disksup_SUITE.erl
@@ -17,10 +17,10 @@
%% %CopyrightEnd%
%%
-module(disksup_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([init_per_suite/1, end_per_suite/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -50,20 +50,28 @@ end_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
Bugs = [otp_5910],
- case ?t:os_type() of
+ case test_server:os_type() of
{unix, sunos} ->
- [api, config, alarm, port,
- {conf, terminate, [unavailable], restart}] ++ Bugs;
- {unix, _OSname} ->
- [api, alarm] ++ Bugs;
- {win32, _OSname} ->
- [api, alarm] ++ Bugs;
- _OS ->
- [unavailable]
+ [api, config, alarm, port, unavailable] ++ Bugs;
+ {unix, _OSname} -> [api, alarm] ++ Bugs;
+ {win32, _OSname} -> [api, alarm] ++ Bugs;
+ _OS -> [unavailable]
end.
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
api(suite) ->
[];
api(doc) ->
diff --git a/lib/os_mon/test/memsup_SUITE.erl b/lib/os_mon/test/memsup_SUITE.erl
index 01a7f6c7f2..afc14d1c83 100644
--- a/lib/os_mon/test/memsup_SUITE.erl
+++ b/lib/os_mon/test/memsup_SUITE.erl
@@ -17,10 +17,10 @@
%% %CopyrightEnd%
%%
-module(memsup_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([init_per_suite/1, end_per_suite/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -49,19 +49,30 @@ end_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
Config.
-all(suite) ->
- All = case ?t:os_type() of
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ All = case test_server:os_type() of
{unix, sunos} ->
- [api, alarm1, alarm2, process,
- config, timeout, unavailable, port];
+ [api, alarm1, alarm2, process, config, timeout,
+ unavailable, port];
{unix, linux} ->
[api, alarm1, alarm2, process, timeout];
- _OS ->
- [api, alarm1, alarm2, process]
+ _OS -> [api, alarm1, alarm2, process]
end,
Bugs = [otp_5910],
All ++ Bugs.
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
api(suite) ->
[];
api(doc) ->
diff --git a/lib/os_mon/test/os_mon.cover b/lib/os_mon/test/os_mon.cover
new file mode 100644
index 0000000000..aa07391351
--- /dev/null
+++ b/lib/os_mon/test/os_mon.cover
@@ -0,0 +1,2 @@
+{incl_app,os_mon,details}.
+
diff --git a/lib/os_mon/test/os_mon.spec b/lib/os_mon/test/os_mon.spec
index bdae523795..d292b258f3 100644
--- a/lib/os_mon/test/os_mon.spec
+++ b/lib/os_mon/test/os_mon.spec
@@ -1 +1 @@
-{topcase, {dir, "../os_mon_test"}}.
+{suites,"../os_mon_test",all}.
diff --git a/lib/os_mon/test/os_mon_SUITE.erl b/lib/os_mon/test/os_mon_SUITE.erl
index ce52271ff8..dd0ab0fbba 100644
--- a/lib/os_mon/test/os_mon_SUITE.erl
+++ b/lib/os_mon/test/os_mon_SUITE.erl
@@ -17,11 +17,12 @@
%% %CopyrightEnd%
%%
-module(os_mon_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%% Test cases
-export([app_file/1, config/1]).
@@ -33,17 +34,35 @@ init_per_testcase(_Case, Config) ->
Dog = test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- case ?t:os_type() of
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:os_type() of
{unix, sunos} -> [app_file, config];
_OS -> [app_file]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
app_file(suite) ->
[];
app_file(doc) ->
diff --git a/lib/os_mon/test/os_mon_mib_SUITE.erl b/lib/os_mon/test/os_mon_mib_SUITE.erl
index a1d463030a..01feb3a57c 100644
--- a/lib/os_mon/test/os_mon_mib_SUITE.erl
+++ b/lib/os_mon/test/os_mon_mib_SUITE.erl
@@ -24,13 +24,14 @@
-define(line,erlang:display({line,?LINE}),).
-define(config(A,B), config(A,B)).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("os_mon/include/OTP-OS-MON-MIB.hrl").
-include_lib("snmp/include/snmp_types.hrl").
-endif.
% Test server specific exports
--export([all/1, init_per_suite/1, end_per_suite/1,
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
init_per_testcase/2, end_per_testcase/2]).
@@ -38,8 +39,8 @@
-export([update_load_table/1]).
-export([get_mem_sys_mark/1, get_mem_proc_mark/1, get_disk_threshold/1,
- get_load_table/1, get_next_load_table/1, get_disk_table/1,
- get_next_disk_table/1, real_snmp_request/1, load_unload/1]).
+ get_load_table/1, get_disk_table/1,
+ real_snmp_request/1, load_unload/1]).
-export([sys_tot_mem/1, sys_used_mem/1, large_erl_process/1,
large_erl_process_mem/1, cpu_load/1, cpu_load5/1, cpu_load15/1,
@@ -47,7 +48,7 @@
large_erl_process_mem64/1, disk_descr/1, disk_kbytes/1,
disk_capacity/1]).
--export([tickets/1]).
+-export([]).
-export([otp_6351/1, otp_7441/1]).
-define(TRAP_UDP, 5000).
@@ -77,17 +78,32 @@ end_per_testcase(_Case, Config) when is_list(Config) ->
test_server:timetrap_cancel(Dog),
Config.
-all(doc) ->
- ["Test os_mon mibs and provided instrumentation functions."];
+suite() -> [{ct_hooks,[ts_install_cth]}].
-all(suite) ->
+all() ->
[load_unload, get_mem_sys_mark, get_mem_proc_mark,
- get_disk_threshold, get_load_table, get_next_load_table,
- get_disk_table, get_next_disk_table, real_snmp_request,
- update_load_table, tickets].
+ get_disk_threshold, get_load_table,
+ {group, get_next_load_table}, get_disk_table,
+ {group, get_next_disk_table}, real_snmp_request,
+ update_load_table, {group, tickets}].
+
+groups() ->
+ [{tickets, [], [otp_6351, otp_7441]},
+ {get_next_load_table, [],
+ [sys_tot_mem, sys_used_mem, large_erl_process,
+ large_erl_process_mem, cpu_load, cpu_load5, cpu_load15,
+ os_wordsize, sys_tot_mem64, sys_used_mem64,
+ large_erl_process_mem64]},
+ {get_next_disk_table, [],
+ [disk_descr, disk_kbytes, disk_capacity]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-tickets(suite) ->
- [otp_6351, otp_7441].
-endif.
%%---------------------------------------------------------------------
@@ -338,21 +354,6 @@ get_load_table(Config) when is_list(Config) ->
ok.
%%---------------------------------------------------------------------
-get_next_load_table(doc) ->
- ["Simulates get_next calls to test the instrumentation function "
- "for the loadTable"];
-get_next_load_table(suite) ->
- [ sys_tot_mem,
- sys_used_mem,
- large_erl_process,
- large_erl_process_mem,
- cpu_load,
- cpu_load5,
- cpu_load15,
- os_wordsize,
- sys_tot_mem64,
- sys_used_mem64,
- large_erl_process_mem64].
sys_tot_mem(doc) ->
[];
@@ -592,11 +593,6 @@ get_disk_table(Config) when is_list(Config) ->
ok.
%%---------------------------------------------------------------------
-get_next_disk_table(doc) ->
- ["Simulates get_next calls to test the instrumentation function "
- "for the diskTable."];
-get_next_disk_table(suite) ->
- [disk_descr, disk_kbytes, disk_capacity].
disk_descr(doc) ->
[];
diff --git a/lib/os_mon/test/os_sup_SUITE.erl b/lib/os_mon/test/os_sup_SUITE.erl
index 25041f968d..873db06317 100644
--- a/lib/os_mon/test/os_sup_SUITE.erl
+++ b/lib/os_mon/test/os_sup_SUITE.erl
@@ -17,10 +17,10 @@
%% %CopyrightEnd%
%%
-module(os_sup_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([init_per_suite/1, end_per_suite/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -63,17 +63,28 @@ end_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- case ?t:os_type() of
- {unix, sunos} ->
- [message, config, port];
- {win32, _OSname} ->
- [message];
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:os_type() of
+ {unix, sunos} -> [message, config, port];
+ {win32, _OSname} -> [message];
OS ->
- Str = io_lib:format("os_sup not available for ~p", [OS]),
+ Str = io_lib:format("os_sup not available for ~p",
+ [OS]),
{skip, lists:flatten(Str)}
end.
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
message(suite) ->
[];
message(doc) ->
diff --git a/lib/parsetools/doc/src/notes.xml b/lib/parsetools/doc/src/notes.xml
index 544850308e..77b3a1a657 100644
--- a/lib/parsetools/doc/src/notes.xml
+++ b/lib/parsetools/doc/src/notes.xml
@@ -30,6 +30,21 @@
</header>
<p>This document describes the changes made to the Parsetools application.</p>
+<section><title>Parsetools 2.0.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> The formating of Yecc's error messages has been
+ improved. (Thanks to Joe Armstrong.) </p>
+ <p>
+ Own Id: OTP-8919</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Parsetools 2.0.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/parsetools/include/yeccpre.hrl b/lib/parsetools/include/yeccpre.hrl
index 39dea0552d..80a3afbdb6 100644
--- a/lib/parsetools/include/yeccpre.hrl
+++ b/lib/parsetools/include/yeccpre.hrl
@@ -167,7 +167,7 @@ yecctoken2string({char,_,C}) -> io_lib:write_char(C);
yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]);
yecctoken2string({string,_,S}) -> io_lib:write_unicode_string(S);
yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A);
-yecctoken2string({_Cat, _, Val}) -> io_lib:write(Val);
+yecctoken2string({_Cat, _, Val}) -> io_lib:format("~p",[Val]);
yecctoken2string({dot, _}) -> "'.'";
yecctoken2string({'$end', _}) ->
[];
diff --git a/lib/parsetools/test/Makefile b/lib/parsetools/test/Makefile
index 19354b87b2..2d9d0a71e5 100644
--- a/lib/parsetools/test/Makefile
+++ b/lib/parsetools/test/Makefile
@@ -71,7 +71,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) parsetools.spec $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) parsetools.spec parsetools.cover $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl
index 069f780b5e..066d221ae7 100644
--- a/lib/parsetools/test/leex_SUITE.erl
+++ b/lib/parsetools/test/leex_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% 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
@@ -30,17 +30,19 @@
-define(privdir, "leex_SUITE_priv").
-define(t, test_server).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(datadir, ?config(data_dir, Config)).
-define(privdir, ?config(priv_dir, Config)).
-endif.
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
--export([checks/1,
- file/1, compile/1, syntax/1,
- examples/1,
- pt/1, man/1, ex/1, ex2/1, not_yet/1]).
+-export([
+ file/1, compile/1, syntax/1,
+
+ pt/1, man/1, ex/1, ex2/1, not_yet/1]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -49,15 +51,33 @@ init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) -> [checks, examples].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, checks}, {group, examples}].
+
+groups() ->
+ [{checks, [], [file, compile, syntax]},
+ {examples, [], [pt, man, ex, ex2, not_yet]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-checks(suite) ->
- [file, compile, syntax].
file(doc) ->
"Bad files and options.";
@@ -330,8 +350,6 @@ syntax(Config) when is_list(Config) ->
leex:file(Filename, Ret),
ok.
-examples(suite) ->
- [pt,man,ex,ex2,not_yet].
pt(doc) ->
"Pushing back characters.";
diff --git a/lib/parsetools/test/parsetools.cover b/lib/parsetools/test/parsetools.cover
new file mode 100644
index 0000000000..13f84e3ba6
--- /dev/null
+++ b/lib/parsetools/test/parsetools.cover
@@ -0,0 +1,2 @@
+{incl_app,parsetools,details}.
+
diff --git a/lib/parsetools/test/parsetools.spec b/lib/parsetools/test/parsetools.spec
index 5b34633378..870d57baf1 100644
--- a/lib/parsetools/test/parsetools.spec
+++ b/lib/parsetools/test/parsetools.spec
@@ -1 +1 @@
-{topcase, {dir, "../parsetools_test"}}.
+{suites,"../parsetools_test",all}.
diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl
index 93949a074a..8e27ddb13d 100644
--- a/lib/parsetools/test/yecc_SUITE.erl
+++ b/lib/parsetools/test/yecc_SUITE.erl
@@ -29,24 +29,26 @@
-define(privdir, "yecc_SUITE_priv").
-define(t, test_server).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(datadir, ?config(data_dir, Config)).
-define(privdir, ?config(priv_dir, Config)).
-endif.
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
-export([app_test/1,
- checks/1,
- file/1, syntax/1, compile/1, rules/1, expect/1,
- conflicts/1,
- examples/1,
- empty/1, prec/1, yeccpre/1, lalr/1, old_yecc/1,
- other_examples/1,
- bugs/1,
- otp_5369/1, otp_6362/1, otp_7945/1, otp_8483/1, otp_8486/1,
- improvements/1,
- otp_7292/1, otp_7969/1]).
+
+ file/1, syntax/1, compile/1, rules/1, expect/1,
+ conflicts/1,
+
+ empty/1, prec/1, yeccpre/1, lalr/1, old_yecc/1,
+ other_examples/1,
+
+ otp_5369/1, otp_6362/1, otp_7945/1, otp_8483/1, otp_8486/1,
+
+ otp_7292/1, otp_7969/1, otp_8919/1]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -55,12 +57,38 @@ init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) -> [app_test, checks, examples, bugs, improvements].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [app_test, {group, checks}, {group, examples},
+ {group, bugs}, {group, improvements}].
+
+groups() ->
+ [{checks, [],
+ [file, syntax, compile, rules, expect, conflicts]},
+ {examples, [],
+ [empty, prec, yeccpre, lalr, old_yecc, other_examples]},
+ {bugs, [],
+ [otp_5369, otp_6362, otp_7945, otp_8483, otp_8486]},
+ {improvements, [], [otp_7292, otp_7969, otp_8919]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
app_test(doc) ->
["Tests the applications consistency."];
@@ -70,8 +98,6 @@ app_test(Config) when is_list(Config) ->
?line ok=?t:app_test(parsetools),
ok.
-checks(suite) ->
- [file, syntax, compile, rules, expect, conflicts].
file(doc) ->
"Bad files and options.";
@@ -730,8 +756,6 @@ rules(Config) when is_list(Config) ->
?line run(Config, Ts),
ok.
-examples(suite) ->
- [empty, prec, yeccpre, lalr, old_yecc, other_examples].
expect(doc) ->
"Check of expect.";
@@ -1283,8 +1307,6 @@ other_examples(Config) when is_list(Config) ->
?line run(Config, Ts),
ok.
-bugs(suite) ->
- [otp_5369, otp_6362, otp_7945, otp_8483, otp_8486].
otp_5369(doc) ->
"OTP-5369. A bug in parse_and_scan reported on erlang questions.";
@@ -1540,9 +1562,6 @@ otp_8486(Config) when is_list(Config) ->
?line run(Config, Ts),
ok.
-improvements(suite) ->
- [otp_7292, otp_7969].
-
otp_7292(doc) ->
"OTP-7292. Header declarations for edoc.";
otp_7292(suite) -> [];
@@ -1773,6 +1792,14 @@ otp_7969(Config) when is_list(Config) ->
?line {error,{{1,11},erl_parse,_}} = erl_parse:parse_and_scan({F6, []}),
ok.
+otp_8919(doc) ->
+ "OTP-8919. Improve formating of Yecc error messages.";
+otp_8919(suite) -> [];
+otp_8919(Config) when is_list(Config) ->
+ {error,{1,Mod,Mess}} = erl_parse:parse([{cat,1,"hello"}]),
+ "syntax error before: \"hello\"" = lists:flatten(Mod:format_error(Mess)),
+ ok.
+
yeccpre_size() ->
yeccpre_size(default_yeccpre()).
diff --git a/lib/parsetools/vsn.mk b/lib/parsetools/vsn.mk
index 46915baed6..812bf21f03 100644
--- a/lib/parsetools/vsn.mk
+++ b/lib/parsetools/vsn.mk
@@ -1 +1 @@
-PARSETOOLS_VSN = 2.0.4
+PARSETOOLS_VSN = 2.0.5
diff --git a/lib/percept/src/egd.erl b/lib/percept/src/egd.erl
index 4fb5b6c46a..63e5c30572 100644
--- a/lib/percept/src/egd.erl
+++ b/lib/percept/src/egd.erl
@@ -42,6 +42,7 @@
%%==========================================================================
%% @type egd_image()
+%% @type font()
%% @type point() = {integer(), integer()}
%% @type color()
%% @type render_option() = {render_engine, opaque} | {render_engine, alpha}
diff --git a/lib/percept/src/percept.erl b/lib/percept/src/percept.erl
index f5e0f7e469..3a2d9f7601 100644
--- a/lib/percept/src/percept.erl
+++ b/lib/percept/src/percept.erl
@@ -185,10 +185,27 @@ stop_webserver() ->
undefined ->
{error, not_started};
Pid ->
- Pid ! {self(), get_port},
- receive Port -> ok end,
- Pid ! quit,
- stop_webserver(Port)
+ do_stop([], Pid)
+ end.
+
+do_stop([], Pid)->
+ Pid ! {self(), get_port},
+ Port = receive P -> P end,
+ do_stop(Port, Pid);
+do_stop(Port, [])->
+ case whereis(percept_httpd) of
+ undefined ->
+ {error, not_started};
+ Pid ->
+ do_stop(Port, Pid)
+ end;
+do_stop(Port, Pid)->
+ case find_service_pid_from_port(inets:services_info(), Port) of
+ undefined ->
+ {error, not_started};
+ Pid2 ->
+ Pid ! quit,
+ inets:stop(httpd, Pid2)
end.
%% @spec stop_webserver(integer()) -> ok | {error, not_started}
@@ -196,12 +213,7 @@ stop_webserver() ->
%% @hidden
stop_webserver(Port) ->
- case find_service_pid_from_port(inets:services_info(), Port) of
- undefined ->
- {error, not_started};
- Pid ->
- inets:stop(httpd, Pid)
- end.
+ do_stop(Port,[]).
%%==========================================================================
%%
diff --git a/lib/percept/src/percept_db.erl b/lib/percept/src/percept_db.erl
index edb0d79a29..52e9afb78f 100644
--- a/lib/percept/src/percept_db.erl
+++ b/lib/percept/src/percept_db.erl
@@ -33,7 +33,7 @@
]).
-include("percept.hrl").
-
+-define(STOP_TIMEOUT, 1000).
%%==========================================================================
%%
%% Type definitions
@@ -77,17 +77,32 @@
start() ->
case erlang:whereis(percept_db) of
undefined ->
- Pid = spawn( fun() -> init_percept_db() end),
- erlang:register(percept_db, Pid),
- {started, Pid};
+ {started, do_start()};
PerceptDB ->
- erlang:unregister(percept_db),
- PerceptDB ! {action, stop},
- Pid = spawn( fun() -> init_percept_db() end),
- erlang:register(percept_db, Pid),
- {restarted, Pid}
+ {restarted, restart(PerceptDB)}
end.
+%% @spec restart(pid()) -> pid()
+%% @private
+%% @doc restarts the percept database.
+
+-spec restart(pid())-> pid().
+
+restart(PerceptDB)->
+ stop_sync(PerceptDB),
+ do_start().
+
+%% @spec do_start(pid()) -> pid()
+%% @private
+%% @doc starts the percept database.
+
+-spec do_start()-> pid().
+
+do_start()->
+ Pid = spawn( fun() -> init_percept_db() end),
+ erlang:register(percept_db, Pid),
+ Pid.
+
%% @spec stop() -> not_started | {stopped, Pid}
%% Pid = pid()
%% @doc Stops the percept database.
@@ -103,6 +118,22 @@ stop() ->
{stopped, Pid}
end.
+%% @spec stop_sync(pid()) -> true
+%% @private
+%% @doc Stops the percept database, with a synchronous call.
+
+-spec stop_sync(pid())-> true.
+
+stop_sync(Pid)->
+ MonitorRef = erlang:monitor(process, Pid),
+ stop(),
+ receive
+ {'DOWN', MonitorRef, _Type, Pid, _Info}->
+ true
+ after ?STOP_TIMEOUT->
+ exit(Pid, kill)
+ end.
+
%% @spec insert(tuple()) -> ok
%% @doc Inserts a trace or profile message to the database.
diff --git a/lib/percept/test/Makefile b/lib/percept/test/Makefile
index 0984b02c81..0420ce40f2 100644
--- a/lib/percept/test/Makefile
+++ b/lib/percept/test/Makefile
@@ -82,7 +82,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) percept.spec $(EMAKEFILE) $(SOURCE) $(RELSYSDIR)
+ $(INSTALL_DATA) percept.spec percept.cover $(EMAKEFILE) $(SOURCE) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/percept/test/egd_SUITE.erl b/lib/percept/test/egd_SUITE.erl
index fde02b47d5..39d87efcf8 100644
--- a/lib/percept/test/egd_SUITE.erl
+++ b/lib/percept/test/egd_SUITE.erl
@@ -18,10 +18,10 @@
%%
-module(egd_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([init_per_suite/1, end_per_suite/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -54,16 +54,22 @@ end_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- % Test cases
- [
- image_create_and_destroy,
- image_shape,
- image_primitives,
- image_colors,
- image_font,
- image_png_compliant
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [image_create_and_destroy, image_shape,
+ image_primitives, image_colors, image_font,
+ image_png_compliant].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%----------------------------------------------------------------------
%% Tests
diff --git a/lib/percept/test/percept.cover b/lib/percept/test/percept.cover
new file mode 100644
index 0000000000..8a5ad0a55e
--- /dev/null
+++ b/lib/percept/test/percept.cover
@@ -0,0 +1,2 @@
+{incl_app,percept,details}.
+
diff --git a/lib/percept/test/percept.spec b/lib/percept/test/percept.spec
index 75aacc1fd6..f3ef76bd60 100644
--- a/lib/percept/test/percept.spec
+++ b/lib/percept/test/percept.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../percept_test"}}.
-
+{suites,"../percept_test",all}.
diff --git a/lib/percept/test/percept_SUITE.erl b/lib/percept/test/percept_SUITE.erl
index ff7cccdaa8..411fcd78f3 100644
--- a/lib/percept/test/percept_SUITE.erl
+++ b/lib/percept/test/percept_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -18,10 +18,10 @@
%%
-module(percept_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([init_per_suite/1, end_per_suite/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -51,12 +51,20 @@ end_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- % Test cases
- [ webserver,
- profile,
- analyze,
- analyze_dist].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [webserver, profile, analyze, analyze_dist].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%----------------------------------------------------------------------
%% Tests
@@ -70,6 +78,10 @@ webserver(Config) when is_list(Config) ->
% Explicit start inets?
?line {started, _, Port} = percept:start_webserver(),
?line ok = percept:stop_webserver(Port),
+ ?line {started, _, _} = percept:start_webserver(),
+ ?line ok = percept:stop_webserver(),
+ ?line {started, _, NewPort} = percept:start_webserver(),
+ ?line ok = percept:stop_webserver(NewPort),
?line application:stop(inets),
ok.
diff --git a/lib/percept/test/percept_db_SUITE.erl b/lib/percept/test/percept_db_SUITE.erl
new file mode 100644
index 0000000000..79be9714ba
--- /dev/null
+++ b/lib/percept/test/percept_db_SUITE.erl
@@ -0,0 +1,76 @@
+%%
+%% %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(percept_db_SUITE).
+-include("test_server.hrl").
+
+%% Test server specific exports
+-export([all/1]).
+-export([init_per_suite/1, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
+%% Test cases
+-export([
+ start/1
+ ]).
+
+%% Default timetrap timeout (set in init_per_testcase)
+-define(default_timeout, ?t:minutes(2)).
+-define(restarts, 10).
+-define(alive_timeout, 500).
+
+init_per_suite(Config) when is_list(Config) ->
+ Config.
+
+end_per_suite(Config) when is_list(Config) ->
+ Config.
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?default_timeout),
+ [{max_size, 300}, {watchdog,Dog} | Config].
+
+end_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+all(suite) ->
+ % Test cases
+ [start].
+
+%%----------------------------------------------------------------------
+%% Tests
+%%----------------------------------------------------------------------
+
+start(suite) ->
+ [];
+start(doc) ->
+ ["Percept_db start and restart test."];
+start(Config) when is_list(Config) ->
+ ok = restart(?restarts),
+ {stopped, _DB} = percept_db:stop(),
+ ok.
+
+restart(0)->
+ ok;
+restart(N)->
+ {_, DB} = percept_db:start(),
+ timer:sleep(?alive_timeout),
+ true = erlang:is_process_alive(DB),
+ restart(N-1).
diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml
index baa0e6c464..befbd3e586 100644
--- a/lib/public_key/doc/src/notes.xml
+++ b/lib/public_key/doc/src/notes.xml
@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
<year>2008</year>
- <year>2008</year>
+ <year>2010</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -34,6 +34,70 @@
<file>notes.xml</file>
</header>
+<section><title>Public_Key 0.10</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improved dialyzer specs.</p>
+ <p>
+ Own Id: OTP-8964</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Public_Key 0.9</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Updated ssl to ignore CA certs that violate the asn1-spec
+ for a certificate, and updated public key asn1 spec to
+ handle inherited DSS-params.</p>
+ <p>
+ Own Id: OTP-7884</p>
+ </item>
+ <item>
+ <p>
+ Changed ssl implementation to retain backwards
+ compatibility for old option {verify, 0} that shall be
+ equivalent to {verify, verify_none}, also separate the
+ cases unknown ca and selfsigned peer cert, and restored
+ return value of deprecated function
+ public_key:pem_to_der/1.</p>
+ <p>
+ Own Id: OTP-8858</p>
+ </item>
+ <item>
+ <p>
+ Better handling of v1 and v2 certificates. V1 and v2
+ certificates does not have any extensions so then
+ validate_extensions should just accept that there are
+ none and not end up in missing_basic_constraints clause.</p>
+ <p>
+ Own Id: OTP-8867</p>
+ </item>
+ <item>
+ <p>
+ Changed the verify fun so that it differentiate between
+ the peer certificate and CA certificates by using
+ valid_peer or valid as the second argument to the verify
+ fun. It may not always be trivial or even possible to
+ know when the peer certificate is reached otherwise.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8873</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Public_Key 0.8</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index c72719fac4..91e058f74e 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -64,8 +64,8 @@
<p><c>decrypt_der() = binary() </c></p>
- <p><c>pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'|
- 'DSAPrivateKey' | 'DHParameter'</c></p>
+ <p><c>pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| 'RSAPublicKey'
+ 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter' | 'SubjectPublicKeyInfo'</c></p>
<p><c>pem_entry () = {pki_asn1_type(), der_encoded() | decrypt_der(), not_encrypted |
{"DES-CBC" | "DES-EDE3-CBC", crypto:rand_bytes(8)}}.</c></p>
@@ -207,17 +207,24 @@
<v> Password = string() </v>
</type>
<desc>
- <p>Decodes a pem entry. pem_decode/1 returns a list of
- pem entries.</p>
+ <p>Decodes a pem entry. pem_decode/1 returns a list of pem
+ entries. Note that if the pem entry is of type
+ 'SubjectPublickeyInfo' it will be further decoded to an
+ rsa_public_key() or dsa_public_key().</p>
</desc>
</func>
<func>
<name>pem_entry_encode(Asn1Type, Entity [,{CipherInfo, Password}]) -> pem_entry()</name>
- <fsummary> Creates a pem entry that can be feed to pem_encode/1.</fsummary>
+ <fsummary> Creates a pem entry that can be fed to pem_encode/1.</fsummary>
<type>
- <v>Asn1Type = atom()</v>
- <v>Entity = term()</v>
+ <v>Asn1Type = pki_asn1_type()</v>
+ <v>Entity = term() - The Erlang representation of
+ <c>Asn1Type</c>. If <c>Asn1Type</c> is 'SubjectPublicKeyInfo'
+ then <c>Entity</c> must be either an rsa_public_key() or a
+ dsa_public_key() and this function will create the appropriate
+ 'SubjectPublicKeyInfo' entry.
+ </v>
<v>CipherInfo = {"DES-CBC" | "DES-EDE3-CBC", crypto:rand_bytes(8)}</v>
<v>Password = string()</v>
</type>
diff --git a/lib/public_key/include/public_key.hrl b/lib/public_key/include/public_key.hrl
index a16eb10fe6..f29ab859ed 100644
--- a/lib/public_key/include/public_key.hrl
+++ b/lib/public_key/include/public_key.hrl
@@ -34,6 +34,8 @@
(_,{extension, _}, UserState) ->
{unknown, UserState};
(_, valid, UserState) ->
+ {valid, UserState};
+ (_, valid_peer, UserState) ->
{valid, UserState}
end, []}).
@@ -71,8 +73,9 @@
-type der_encoded() :: binary().
-type decrypt_der() :: binary().
--type pki_asn1_type() :: 'Certificate' | 'RSAPrivateKey'
- | 'DSAPrivateKey' | 'DHParameter'.
+-type pki_asn1_type() :: 'Certificate' | 'RSAPrivateKey' | 'RSAPublicKey'
+ | 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter'
+ | 'SubjectPublicKeyInfo'.
-type pem_entry() :: {pki_asn1_type(), der_encoded() | decrypt_der(),
not_encrypted | {Cipher :: string(), Salt :: binary()}}.
-type asn1_type() :: atom(). %% see "OTP-PUB-KEY.hrl
diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl
index 2335a4e4b4..fadb993ed9 100644
--- a/lib/public_key/src/pubkey_cert.erl
+++ b/lib/public_key/src/pubkey_cert.erl
@@ -164,7 +164,7 @@ validate_signature(OtpCert, DerCert, Key, KeyParams,
verify_fun(OtpCert, {bad_cert, invalid_signature}, UserState, VerifyFun)
end.
%%--------------------------------------------------------------------
--spec validate_names(#'OTPCertificate'{}, list(), list(),
+-spec validate_names(#'OTPCertificate'{}, no_constraints | list(), list(),
term(), term(), fun())-> term().
%%
%% Description: Validate Subject Alternative Name.
@@ -223,10 +223,15 @@ validate_revoked_status(_OtpCert, UserState, _VerifyFun) ->
%%--------------------------------------------------------------------
validate_extensions(OtpCert, ValidationState, UserState, VerifyFun) ->
TBSCert = OtpCert#'OTPCertificate'.tbsCertificate,
- Extensions = TBSCert#'OTPTBSCertificate'.extensions,
- validate_extensions(OtpCert, Extensions, ValidationState, no_basic_constraint,
- is_self_signed(OtpCert), UserState, VerifyFun).
-
+ case TBSCert#'OTPTBSCertificate'.version of
+ N when N >= 3 ->
+ Extensions = TBSCert#'OTPTBSCertificate'.extensions,
+ validate_extensions(OtpCert, Extensions,
+ ValidationState, no_basic_constraint,
+ is_self_signed(OtpCert), UserState, VerifyFun);
+ _ -> %% Extensions not present in versions 1 & 2
+ {ValidationState, UserState}
+ end.
%%--------------------------------------------------------------------
-spec normalize_general_name({rdnSequence, term()}) -> {rdnSequence, term()}.
%%
@@ -291,7 +296,7 @@ is_fixed_dh_cert(#'OTPCertificate'{tbsCertificate =
%%--------------------------------------------------------------------
-spec verify_fun(#'OTPCertificate'{}, {bad_cert, atom()} | {extension, #'Extension'{}}|
- valid, term(), fun()) -> term().
+ valid | valid_peer, term(), fun()) -> term().
%%
%% Description: Gives the user application the opportunity handle path
%% validation errors and unknown extensions and optional do other
diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl
index 20b322b4a4..7a387e487c 100644
--- a/lib/public_key/src/pubkey_cert_records.erl
+++ b/lib/public_key/src/pubkey_cert_records.erl
@@ -23,7 +23,7 @@
-include("public_key.hrl").
--export([decode_cert/1, transform/2]).
+-export([decode_cert/1, transform/2, supportedPublicKeyAlgorithms/1]).
%%====================================================================
%% Internal application API
@@ -80,16 +80,24 @@ transform(Other,_) ->
Other.
%%--------------------------------------------------------------------
-%%% Internal functions
+-spec supportedPublicKeyAlgorithms(Oid::tuple()) -> asn1_type().
+%%
+%% Description: Returns the public key type for an algorithm
+%% identifier tuple as found in SubjectPublicKeyInfo.
+%%
%%--------------------------------------------------------------------
-
-%%% SubjectPublicKey
supportedPublicKeyAlgorithms(?'rsaEncryption') -> 'RSAPublicKey';
supportedPublicKeyAlgorithms(?'id-dsa') -> 'DSAPublicKey';
supportedPublicKeyAlgorithms(?'dhpublicnumber') -> 'DHPublicKey';
supportedPublicKeyAlgorithms(?'id-keyExchangeAlgorithm') -> 'KEA-PublicKey';
supportedPublicKeyAlgorithms(?'id-ecPublicKey') -> 'ECPoint'.
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+%%% SubjectPublicKey
+
decode_supportedPublicKey(#'OTPSubjectPublicKeyInfo'{algorithm= PA =
#'PublicKeyAlgorithm'{algorithm=Algo},
subjectPublicKey = {0,SPK0}}) ->
diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl
index 31d881973a..78870e5cd7 100644
--- a/lib/public_key/src/pubkey_pem.erl
+++ b/lib/public_key/src/pubkey_pem.erl
@@ -93,11 +93,11 @@ encode_pem_entries(Entries) ->
encode_pem_entry({Asn1Type, Der, not_encrypted}) ->
StartStr = pem_start(Asn1Type),
- [StartStr, "\n", b64encode_and_split(Der), pem_end(StartStr) ,"\n\n"];
+ [StartStr, "\n", b64encode_and_split(Der), "\n", pem_end(StartStr) ,"\n\n"];
encode_pem_entry({Asn1Type, Der, {Cipher, Salt}}) ->
StartStr = pem_start(Asn1Type),
[StartStr,"\n", pem_decrypt(),"\n", pem_decrypt_info(Cipher, Salt),"\n",
- b64encode_and_split(Der), pem_end(StartStr) ,"\n\n"].
+ b64encode_and_split(Der), "\n", pem_end(StartStr) ,"\n\n"].
decode_pem_entries([], Entries) ->
lists:reverse(Entries);
@@ -145,16 +145,22 @@ split_bin(N, Bin) ->
b64encode_and_split(Bin) ->
split_lines(base64:encode(Bin)).
+split_lines(<<Text:?ENCODED_LINE_LENGTH/binary>>) ->
+ [Text];
split_lines(<<Text:?ENCODED_LINE_LENGTH/binary, Rest/binary>>) ->
[Text, $\n | split_lines(Rest)];
split_lines(Bin) ->
- [Bin, $\n].
+ [Bin].
%% Ignore white space at end of line
join_entry([<<"-----END CERTIFICATE-----", _/binary>>| Lines], Entry) ->
{lists:reverse(Entry), Lines};
join_entry([<<"-----END RSA PRIVATE KEY-----", _/binary>>| Lines], Entry) ->
{lists:reverse(Entry), Lines};
+join_entry([<<"-----END PUBLIC KEY-----", _/binary>>| Lines], Entry) ->
+ {lists:reverse(Entry), Lines};
+join_entry([<<"-----END RSA PUBLIC KEY-----", _/binary>>| Lines], Entry) ->
+ {lists:reverse(Entry), Lines};
join_entry([<<"-----END DSA PRIVATE KEY-----", _/binary>>| Lines], Entry) ->
{lists:reverse(Entry), Lines};
join_entry([<<"-----END DH PARAMETERS-----", _/binary>>| Lines], Entry) ->
@@ -210,15 +216,22 @@ pem_start('Certificate') ->
<<"-----BEGIN CERTIFICATE-----">>;
pem_start('RSAPrivateKey') ->
<<"-----BEGIN RSA PRIVATE KEY-----">>;
+pem_start('RSAPublicKey') ->
+ <<"-----BEGIN RSA PUBLIC KEY-----">>;
+pem_start('SubjectPublicKeyInfo') ->
+ <<"-----BEGIN PUBLIC KEY-----">>;
pem_start('DSAPrivateKey') ->
<<"-----BEGIN DSA PRIVATE KEY-----">>;
pem_start('DHParameter') ->
<<"-----BEGIN DH PARAMETERS-----">>.
-
pem_end(<<"-----BEGIN CERTIFICATE-----">>) ->
<<"-----END CERTIFICATE-----">>;
pem_end(<<"-----BEGIN RSA PRIVATE KEY-----">>) ->
<<"-----END RSA PRIVATE KEY-----">>;
+pem_end(<<"-----BEGIN RSA PUBLIC KEY-----">>) ->
+ <<"-----END RSA PUBLIC KEY-----">>;
+pem_end(<<"-----BEGIN PUBLIC KEY-----">>) ->
+ <<"-----END PUBLIC KEY-----">>;
pem_end(<<"-----BEGIN DSA PRIVATE KEY-----">>) ->
<<"-----END DSA PRIVATE KEY-----">>;
pem_end(<<"-----BEGIN DH PARAMETERS-----">>) ->
@@ -230,6 +243,10 @@ asn1_type(<<"-----BEGIN CERTIFICATE-----">>) ->
'Certificate';
asn1_type(<<"-----BEGIN RSA PRIVATE KEY-----">>) ->
'RSAPrivateKey';
+asn1_type(<<"-----BEGIN RSA PUBLIC KEY-----">>) ->
+ 'RSAPublicKey';
+asn1_type(<<"-----BEGIN PUBLIC KEY-----">>) ->
+ 'SubjectPublicKeyInfo';
asn1_type(<<"-----BEGIN DSA PRIVATE KEY-----">>) ->
'DSAPrivateKey';
asn1_type(<<"-----BEGIN DH PARAMETERS-----">>) ->
diff --git a/lib/public_key/src/public_key.appup.src b/lib/public_key/src/public_key.appup.src
index c9d15b8747..6b6b76d0a5 100644
--- a/lib/public_key/src/public_key.appup.src
+++ b/lib/public_key/src/public_key.appup.src
@@ -1,29 +1,16 @@
%% -*- erlang -*-
{"%VSN%",
[
- {"0.7",
+ {"0.9",
[
- {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []},
- {update, public_key, soft, soft_purge, soft_purge, []},
- {update, pubkey_pem, soft, soft_purge, soft_purge, []},
- {update, pubkey_cert_records, soft, soft_purge, soft_purge, []}
- {update, pubkey_cert, soft, soft_purge, soft_purge, []}
- ]
- },
- {"0.6",
- [
- {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []},
{update, public_key, soft, soft_purge, soft_purge, []},
- {update, pubkey_pem, soft, soft_purge, soft_purge, []},
- {update, pubkey_cert_records, soft, soft_purge, soft_purge, []}
{update, pubkey_cert, soft, soft_purge, soft_purge, []}
]
},
- {"0.5",
+ {"0.8",
[
{update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []},
{update, public_key, soft, soft_purge, soft_purge, []},
- {update, pubkey_crypto, soft, soft_purge, soft_purge, []},
{update, pubkey_pem, soft, soft_purge, soft_purge, []},
{update, pubkey_cert_records, soft, soft_purge, soft_purge, []},
{update, pubkey_cert, soft, soft_purge, soft_purge, []}
@@ -31,32 +18,19 @@
}
],
[
- {"0.7",
- [
- {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []},
- {update, public_key, soft, soft_purge, soft_purge, []},
- {update, pubkey_pem, soft, soft_purge, soft_purge, []},
- {update, pubkey_cert_records, soft, soft_purge, soft_purge, []}
- {update, pubkey_cert, soft, soft_purge, soft_purge, []}
- ]
- },
- {"0.6",
- [
- {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []},
- {update, public_key, soft, soft_purge, soft_purge, []},
- {update, pubkey_pem, soft, soft_purge, soft_purge, []},
- {update, pubkey_cert_records, soft, soft_purge, soft_purge, []}
- {update, pubkey_cert, soft, soft_purge, soft_purge, []}
- ]
- },
- {"0.5",
+ {"0.9",
+ [
+ {update, public_key, soft, soft_purge, soft_purge, []},
+ {update, pubkey_cert, soft, soft_purge, soft_purge, []}
+ ]
+ },
+ {"0.8",
[
{update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []},
{update, public_key, soft, soft_purge, soft_purge, []},
- {update, pubkey_crypto, soft, soft_purge, soft_purge, []},
{update, pubkey_pem, soft, soft_purge, soft_purge, []},
{update, pubkey_cert_records, soft, soft_purge, soft_purge, []},
{update, pubkey_cert, soft, soft_purge, soft_purge, []}
]
- }
+ }
]}.
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 6de5f388dc..fad73e8e92 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -62,6 +62,7 @@
-type dss_digest_type() :: 'none' | 'sha'.
-define(UINT32(X), X:32/unsigned-big-integer).
+-define(DER_NULL, <<5, 0>>).
%%====================================================================
%% API
@@ -90,6 +91,17 @@ pem_encode(PemEntries) when is_list(PemEntries) ->
%% Description: Decodes a pem entry. pem_decode/1 returns a list of
%% pem entries.
%%--------------------------------------------------------------------
+pem_entry_decode({'SubjectPublicKeyInfo', Der, _}) ->
+ {_, {'AlgorithmIdentifier', AlgId, Params}, {0, Key0}}
+ = der_decode('SubjectPublicKeyInfo', Der),
+ KeyType = pubkey_cert_records:supportedPublicKeyAlgorithms(AlgId),
+ case KeyType of
+ 'RSAPublicKey' ->
+ der_decode(KeyType, Key0);
+ 'DSAPublicKey' ->
+ {params, DssParams} = der_decode('DSAParams', Params),
+ {der_decode(KeyType, Key0), DssParams}
+ end;
pem_entry_decode({Asn1Type, Der, not_encrypted}) when is_atom(Asn1Type),
is_binary(Der) ->
der_decode(Asn1Type, Der).
@@ -114,6 +126,18 @@ pem_entry_decode({Asn1Type, CryptDer, {Cipher, Salt}} = PemEntry,
%
%% Description: Creates a pem entry that can be feed to pem_encode/1.
%%--------------------------------------------------------------------
+pem_entry_encode('SubjectPublicKeyInfo', Entity=#'RSAPublicKey'{}) ->
+ Der = der_encode('RSAPublicKey', Entity),
+ Spki = {'SubjectPublicKeyInfo',
+ {'AlgorithmIdentifier', ?'rsaEncryption', ?DER_NULL}, {0, Der}},
+ pem_entry_encode('SubjectPublicKeyInfo', Spki);
+pem_entry_encode('SubjectPublicKeyInfo',
+ {DsaInt, Params=#'Dss-Parms'{}}) when is_integer(DsaInt) ->
+ KeyDer = der_encode('DSAPublicKey', DsaInt),
+ ParamDer = der_encode('DSAParams', {params, Params}),
+ Spki = {'SubjectPublicKeyInfo',
+ {'AlgorithmIdentifier', ?'id-dsa', ParamDer}, {0, KeyDer}},
+ pem_entry_encode('SubjectPublicKeyInfo', Spki);
pem_entry_encode(Asn1Type, Entity) when is_atom(Asn1Type) ->
Der = der_encode(Asn1Type, Entity),
{Asn1Type, Der, not_encrypted}.
@@ -213,10 +237,13 @@ decrypt_private(CipherText,
crypto:mpint(D)], Padding).
%%--------------------------------------------------------------------
--spec decrypt_public(CipherText :: binary(), rsa_public_key()) ->
+-spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key()) ->
PlainText :: binary().
--spec decrypt_public(CipherText :: binary(), rsa_public_key(),
+-spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key(),
public_crypt_options()) -> PlainText :: binary().
+%% NOTE: The rsa_private_key() is not part of the documented API it is
+%% here for testing purposes, in a real situation this is not a relevant
+%% thing to do.
%%
%% Description: Public key decryption using the public key.
%%--------------------------------------------------------------------
@@ -232,10 +259,14 @@ decrypt_public(CipherText,#'RSAPrivateKey'{modulus = N, publicExponent = E},
decrypt_public(CipherText, N,E, Options).
%%--------------------------------------------------------------------
--spec encrypt_public(PlainText :: binary(), rsa_public_key()) ->
+-spec encrypt_public(PlainText :: binary(), rsa_public_key() | rsa_private_key()) ->
CipherText :: binary().
--spec encrypt_public(PlainText :: binary(), rsa_public_key(),
+-spec encrypt_public(PlainText :: binary(), rsa_public_key() | rsa_private_key(),
public_crypt_options()) -> CipherText :: binary().
+
+%% NOTE: The rsa_private_key() is not part of the documented API it is
+%% here for testing purposes, in a real situation this is not a relevant
+%% thing to do.
%%
%% Description: Public key encryption using the public key.
%%--------------------------------------------------------------------
@@ -280,8 +311,8 @@ encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N,
sign(PlainText, DigestType, #'RSAPrivateKey'{modulus = N, publicExponent = E,
privateExponent = D})
when is_binary(PlainText),
- DigestType == md5;
- DigestType == sha ->
+ (DigestType == md5 orelse
+ DigestType == sha) ->
crypto:rsa_sign(DigestType, sized_binary(PlainText), [crypto:mpint(E),
crypto:mpint(N),
@@ -437,7 +468,7 @@ pkix_normalize_name(Issuer) ->
pubkey_cert:normalize_general_name(Issuer).
%%--------------------------------------------------------------------
--spec pkix_path_validation(der_encoded()| #'OTPCertificate'{} | unknown_ca,
+-spec pkix_path_validation(der_encoded()| #'OTPCertificate'{} | atom(),
CertChain :: [der_encoded()] ,
Options :: list()) ->
{ok, {PublicKeyInfo :: term(),
@@ -445,11 +476,11 @@ pkix_normalize_name(Issuer) ->
{error, {bad_cert, Reason :: term()}}.
%% Description: Performs a basic path validation according to RFC 5280.
%%--------------------------------------------------------------------
-pkix_path_validation(unknown_ca, [Cert | Chain], Options0) ->
+pkix_path_validation(PathErr, [Cert | Chain], Options0) when is_atom(PathErr)->
{VerifyFun, Userstat0} =
proplists:get_value(verify_fun, Options0, ?DEFAULT_VERIFYFUN),
Otpcert = pkix_decode_cert(Cert, otp),
- Reason = {bad_cert, unknown_ca},
+ Reason = {bad_cert, PathErr},
try VerifyFun(Otpcert, Reason, Userstat0) of
{valid, Userstate} ->
Options = proplists:delete(verify_fun, Options0),
@@ -556,26 +587,31 @@ validate(DerCert, #path_validation_state{working_issuer_name = Issuer,
%% We want the key_usage extension to be checked before we validate
%% the signature.
- UserState0 = pubkey_cert:validate_signature(OtpCert, DerCert,
+ UserState6 = pubkey_cert:validate_signature(OtpCert, DerCert,
Key, KeyParams, UserState5, VerifyFun),
- UserState = pubkey_cert:verify_fun(OtpCert, valid, UserState0, VerifyFun),
+ UserState = case Last of
+ false ->
+ pubkey_cert:verify_fun(OtpCert, valid, UserState6, VerifyFun);
+ true ->
+ pubkey_cert:verify_fun(OtpCert, valid_peer,
+ UserState6, VerifyFun)
+ end,
+
ValidationState =
ValidationState1#path_validation_state{user_state = UserState},
pubkey_cert:prepare_for_next_cert(OtpCert, ValidationState).
-sized_binary(Binary) when is_binary(Binary) ->
+sized_binary(Binary) ->
Size = size(Binary),
- <<?UINT32(Size), Binary/binary>>;
-sized_binary(List) ->
- sized_binary(list_to_binary(List)).
+ <<?UINT32(Size), Binary/binary>>.
%%--------------------------------------------------------------------
%%% Deprecated functions
%%--------------------------------------------------------------------
pem_to_der(CertSource) ->
{ok, Bin} = file:read_file(CertSource),
- pubkey_pem:decode(Bin).
+ {ok, pubkey_pem:decode(Bin)}.
decode_private_key(KeyInfo) ->
decode_private_key(KeyInfo, no_passwd).
diff --git a/lib/public_key/test/pkits_SUITE.erl b/lib/public_key/test/pkits_SUITE.erl
index 1d75e1aed2..fd976cb2f3 100644
--- a/lib/public_key/test/pkits_SUITE.erl
+++ b/lib/public_key/test/pkits_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,8 +25,8 @@
-compile(export_all).
-%%-include_lib("public_key/include/public_key.hrl").
--include("public_key.hrl").
+-include_lib("public_key/include/public_key.hrl").
+%%-include("public_key.hrl").
-define(error(Format,Args), error(Format,Args,?FILE,?LINE)).
-define(warning(Format,Args), warning(Format,Args,?FILE,?LINE)).
@@ -43,25 +43,24 @@
-define(NIST6, "2.16.840.1.101.3.2.1.48.6").
%%
-all(doc) ->
- ["PKITS tests for RFC3280 compliance"];
-all(suite) ->
- [signature_verification,
- validity_periods,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [signature_verification, validity_periods,
verifying_name_chaining,
- %% basic_certificate_revocation_tests,
verifying_paths_with_self_issued_certificates,
- verifying_basic_constraints,
- key_usage,
-%% certificate_policies,
-%% require_explicit_policy,
-%% policy_mappings,
-%% inhibit_policy_mapping,
-%% inhibit_any_policy,
- name_constraints,
-%% distribution_points,
-%% delta_crls,
- private_certificate_extensions].
+ verifying_basic_constraints, key_usage,
+ name_constraints, private_certificate_extensions].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
signature_verification(doc) -> [""];
signature_verification(suite) -> [];
@@ -129,7 +128,6 @@ private_certificate_extensions(Config) when is_list(Config) ->
run(private_certificate_extensions()).
run() ->
- catch crypto:start(),
Tests =
[signature_verification(),
validity_periods(),
@@ -581,17 +579,21 @@ init_per_testcase(_Func, Config) ->
put(datadir, Datadir),
Config.
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
%% Nodes = select_nodes(all, Config, ?FILE, ?LINE),
%% rpc:multicall(Nodes, mnesia, lkill, []),
Config.
init_per_suite(Config) ->
- crypto:start(),
- Config.
+ case application:start(crypto) of
+ ok ->
+ Config;
+ _ ->
+ {skip, "Crypto did not start"}
+ end.
end_per_suite(_Config) ->
- crypto:stop().
+ application:stop(crypto).
error(Format, Args, File0, Line) ->
File = filename:basename(File0),
diff --git a/lib/public_key/test/public_key.cover b/lib/public_key/test/public_key.cover
index 8477c76ef6..ec00814578 100644
--- a/lib/public_key/test/public_key.cover
+++ b/lib/public_key/test/public_key.cover
@@ -1,2 +1,4 @@
+{incl_app,public_key,details}.
-{exclude, ['OTP-PUB-KEY']}. \ No newline at end of file
+
+{excl_mods, public_key, ['OTP-PUB-KEY']}.
diff --git a/lib/public_key/test/public_key.spec b/lib/public_key/test/public_key.spec
index dee9ad44ed..1749822c2d 100644
--- a/lib/public_key/test/public_key.spec
+++ b/lib/public_key/test/public_key.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../public_key_test"}}.
-
+{suites,"../public_key_test",all}.
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index ea6a925139..d130196c15 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,10 +23,10 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include_lib("test_server/include/test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("test_server/include/test_server_line.hrl").
--include("public_key.hrl").
+-include_lib("public_key/include/public_key.hrl").
-define(TIMEOUT, 120000). % 2 min
@@ -41,9 +41,12 @@
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- crypto:start(),
- Config.
-
+ case application:start(crypto) of
+ ok ->
+ Config;
+ _ ->
+ {skip, "Crypto did not start"}
+ end.
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
%% Config - [tuple()]
@@ -51,7 +54,7 @@ init_per_suite(Config) ->
%% Description: Cleanup after the whole suite
%%--------------------------------------------------------------------
end_per_suite(_Config) ->
- crypto:stop().
+ application:stop(crypto).
%%--------------------------------------------------------------------
%% Function: init_per_testcase(TestCase, Config) -> Config
@@ -96,18 +99,21 @@ end_per_testcase(_TestCase, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test the public_key rsa functionality"];
-
-all(suite) ->
- [app,
- pk_decode_encode,
- encrypt_decrypt,
- sign_verify,
- pkix,
- pkix_path_validation,
- deprecated
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [app, pk_decode_encode, encrypt_decrypt, sign_verify,
+ pkix, pkix_path_validation, deprecated].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Test cases starts here.
%%--------------------------------------------------------------------
@@ -136,6 +142,15 @@ pk_decode_encode(Config) when is_list(Config) ->
DSAKey = public_key:der_decode('DSAPrivateKey', DerDSAKey),
DSAKey = public_key:pem_entry_decode(Entry0),
+
+ {ok, DSAPubPem} = file:read_file(filename:join(Datadir, "dsa_pub.pem")),
+ [{'SubjectPublicKeyInfo', _, _} = PubEntry0] =
+ public_key:pem_decode(DSAPubPem),
+ DSAPubKey = public_key:pem_entry_decode(PubEntry0),
+ true = check_entry_type(DSAPubKey, 'DSAPublicKey'),
+ PubEntry0 = public_key:pem_entry_encode('SubjectPublicKeyInfo', DSAPubKey),
+ DSAPubPemNoEndNewLines = strip_ending_newlines(DSAPubPem),
+ DSAPubPemEndNoNewLines = strip_ending_newlines(public_key:pem_encode([PubEntry0])),
[{'RSAPrivateKey', DerRSAKey, not_encrypted} = Entry1 ] =
erl_make_certs:pem_to_der(filename:join(Datadir, "client_key.pem")),
@@ -150,6 +165,22 @@ pk_decode_encode(Config) when is_list(Config) ->
true = check_entry_type(public_key:pem_entry_decode(Entry2, "abcd1234"),
'RSAPrivateKey'),
+ {ok, RSAPubPem} = file:read_file(filename:join(Datadir, "rsa_pub.pem")),
+ [{'SubjectPublicKeyInfo', _, _} = PubEntry1] =
+ public_key:pem_decode(RSAPubPem),
+ RSAPubKey = public_key:pem_entry_decode(PubEntry1),
+ true = check_entry_type(RSAPubKey, 'RSAPublicKey'),
+ PubEntry1 = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey),
+ RSAPubPemNoEndNewLines = strip_ending_newlines(RSAPubPem),
+ RSAPubPemNoEndNewLines = strip_ending_newlines(public_key:pem_encode([PubEntry1])),
+
+ {ok, RSARawPem} = file:read_file(filename:join(Datadir, "rsa_pub_key.pem")),
+ [{'RSAPublicKey', _, _} = PubEntry2] =
+ public_key:pem_decode(RSARawPem),
+ RSAPubKey = public_key:pem_entry_decode(PubEntry2),
+ RSARawPemNoEndNewLines = strip_ending_newlines(RSARawPem),
+ RSARawPemNoEndNewLines = strip_ending_newlines(public_key:pem_encode([PubEntry2])),
+
Salt0 = crypto:rand_bytes(8),
Entry3 = public_key:pem_entry_encode('RSAPrivateKey', RSAKey0,
{{"DES-EDE3-CBC", Salt0}, "1234abcd"}),
@@ -249,10 +280,8 @@ sign_verify(Config) when is_list(Config) ->
true = public_key:pkix_verify(Cert2, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}),
%% RSA sign
- Msg0 = lists:duplicate(5, "Foo bar 100"),
- Msg = list_to_binary(Msg0),
+ Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")),
- RSASign = public_key:sign(Msg0, sha, PrivateRSA),
RSASign = public_key:sign(Msg, sha, PrivateRSA),
true = public_key:verify(Msg, sha, RSASign, PublicRSA),
false = public_key:verify(<<1:8, Msg/binary>>, sha, RSASign, PublicRSA),
@@ -379,6 +408,8 @@ pkix_path_validation(Config) when is_list(Config) ->
(_,{extension, _}, UserState) ->
{unknown, UserState};
(_, valid, UserState) ->
+ {valid, UserState};
+ (_, valid_peer, UserState) ->
{valid, UserState}
end, []},
{ok, _} =
@@ -411,11 +442,11 @@ deprecated(suite) ->
[];
deprecated(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
- [DsaKey = {'DSAPrivateKey', _DsaKey, _}] =
+ {ok, [DsaKey = {'DSAPrivateKey', _DsaKey, _}]} =
public_key:pem_to_der(filename:join(Datadir, "dsa.pem")),
- [RsaKey = {'RSAPrivateKey', _RsaKey,_}] =
+ {ok, [RsaKey = {'RSAPrivateKey', _RsaKey,_}]} =
public_key:pem_to_der(filename:join(Datadir, "client_key.pem")),
- [ProtectedRsaKey = {'RSAPrivateKey', _ProtectedRsaKey,_}] =
+ {ok, [ProtectedRsaKey = {'RSAPrivateKey', _ProtectedRsaKey,_}]} =
public_key:pem_to_der(filename:join(Datadir, "rsa.pem")),
{ok, #'DSAPrivateKey'{}} = public_key:decode_private_key(DsaKey),
@@ -429,9 +460,16 @@ check_entry_type(#'DSAPrivateKey'{}, 'DSAPrivateKey') ->
true;
check_entry_type(#'RSAPrivateKey'{}, 'RSAPrivateKey') ->
true;
+check_entry_type(#'RSAPublicKey'{}, 'RSAPublicKey') ->
+ true;
+check_entry_type({_Int, #'Dss-Parms'{}}, 'DSAPublicKey') when is_integer(_Int) ->
+ true;
check_entry_type(#'DHParameter'{}, 'DHParameter') ->
true;
check_entry_type(#'Certificate'{}, 'Certificate') ->
true;
check_entry_type(_,_) ->
false.
+
+strip_ending_newlines(Bin) ->
+ string:strip(binary_to_list(Bin), right, 10).
diff --git a/lib/public_key/test/public_key_SUITE_data/dsa_pub.pem b/lib/public_key/test/public_key_SUITE_data/dsa_pub.pem
new file mode 100644
index 0000000000..d3635e5b20
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/dsa_pub.pem
@@ -0,0 +1,12 @@
+-----BEGIN PUBLIC KEY-----
+MIIBtzCCASwGByqGSM44BAEwggEfAoGBALez5tklY5CdFeTMos899pA6i4u4uCts
+zgBzrdBk6cl5FVqzdzWMGTQiynnTpGsrOESinzP06Ip+pG15We2OORwgvCxD/W95
+aCiN0/+MdiXqlsmboBARMzsa+SmBENN3gF/+tuuEAFzOXU1q2cmEywRLyfbM2KIB
+VE/TChWYw2eRAhUA1R64VvcQ90XA8SOKVDmMA0dBzukCgYEAlLMYP0pbgBlgHQVO
+3/avAHlWNrIq52Lxk7SdPJWgMvPjTK9Z6sv88kxsCcydtjvO439j1yqcwk50GQc+
+86ktBWWz93/HkIdnFyqafef4mmWvm2Uq6ClQKS+A0Asfaj8Mys+HUMiI+qsfdjRb
+yIpwb7MX1nsVdsKzALnZNMW27A0DgYQAAoGAfEIAb3mLjtFfiF/tsZb4/DGHdWSb
+6Ir0hFkoBUZ9ymBO70wlfZVSQGs240kZtOMpAOpJL1Dy8oH6PUQ+JyacwZIo8fdq
+19/Kwm6CPrpaEhzErmMvwT2CZJYZ+HOk55ljLkVCiyG7MzEj2+odLKym9yoQsbsJ
+olHzIRpkLk45y4c=
+-----END PUBLIC KEY-----
diff --git a/lib/public_key/test/public_key_SUITE_data/rsa_pub.pem b/lib/public_key/test/public_key_SUITE_data/rsa_pub.pem
new file mode 100644
index 0000000000..cbe81343f7
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/rsa_pub.pem
@@ -0,0 +1,4 @@
+-----BEGIN PUBLIC KEY-----
+MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANRiyZg0uci74Nc6mnqZ8AoDl88aT7x6
+JA0MfgHIHzteEj7Qg+lE5QxMGAafurVE5vqoHkDfwk4uzzsCAJuz91MCAwEAAQ==
+-----END PUBLIC KEY-----
diff --git a/lib/public_key/test/public_key_SUITE_data/rsa_pub_key.pem b/lib/public_key/test/public_key_SUITE_data/rsa_pub_key.pem
new file mode 100644
index 0000000000..3b9d7568ff
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/rsa_pub_key.pem
@@ -0,0 +1,4 @@
+-----BEGIN RSA PUBLIC KEY-----
+MEgCQQDUYsmYNLnIu+DXOpp6mfAKA5fPGk+8eiQNDH4ByB87XhI+0IPpROUMTBgG
+n7q1ROb6qB5A38JOLs87AgCbs/dTAgMBAAE=
+-----END RSA PUBLIC KEY-----
diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk
index f70209d891..334b9d792e 100644
--- a/lib/public_key/vsn.mk
+++ b/lib/public_key/vsn.mk
@@ -1 +1 @@
-PUBLIC_KEY_VSN = 0.8
+PUBLIC_KEY_VSN = 0.10
diff --git a/lib/reltool/test/Makefile b/lib/reltool/test/Makefile
index 5109058797..e4ab216298 100644
--- a/lib/reltool/test/Makefile
+++ b/lib/reltool/test/Makefile
@@ -73,7 +73,7 @@ release_spec: opt
release_tests_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) reltool.spec $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) reltool.spec reltool.cover $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
$(INSTALL_SCRIPT) rtt $(INSTALL_PROGS) $(RELSYSDIR)
$(INSTALL_DATA) $(INSTALL_PROGS) $(RELSYSDIR)
# chmod -f -R u+w $(RELSYSDIR)
diff --git a/lib/reltool/test/reltool.cover b/lib/reltool/test/reltool.cover
new file mode 100644
index 0000000000..ca425b9f98
--- /dev/null
+++ b/lib/reltool/test/reltool.cover
@@ -0,0 +1,2 @@
+{incl_app,reltool,details}.
+
diff --git a/lib/reltool/test/reltool.spec b/lib/reltool/test/reltool.spec
index 252232e09d..2995720105 100644
--- a/lib/reltool/test/reltool.spec
+++ b/lib/reltool/test/reltool.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../reltool_test"}}.
-
+{suites,"../reltool_test",all}.
diff --git a/lib/reltool/test/reltool_app_SUITE.erl b/lib/reltool/test/reltool_app_SUITE.erl
index f8433f73d0..537a06315a 100644
--- a/lib/reltool/test/reltool_app_SUITE.erl
+++ b/lib/reltool/test/reltool_app_SUITE.erl
@@ -58,22 +58,22 @@ init_per_testcase(Case, Config) ->
end_per_testcase(Func,Config) ->
reltool_test_lib:end_per_testcase(Func,Config).
-fin_per_testcase(Case, Config) ->
- reltool_test_lib:end_per_testcase(Case, Config).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all() ->
- all(suite).
-
-all(suite) ->
- [
- fields,
- modules,
- export_all,
- app_depend,
- undef_funcs
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [fields, modules, export_all, app_depend, undef_funcs].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl
index faf1bdbba2..b9b53b5a59 100644
--- a/lib/reltool/test/reltool_server_SUITE.erl
+++ b/lib/reltool/test/reltool_server_SUITE.erl
@@ -18,8 +18,9 @@
-module(reltool_server_SUITE).
--export([all/0, init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
-compile(export_all).
@@ -42,25 +43,26 @@ init_per_testcase(Func,Config) ->
reltool_test_lib:init_per_testcase(Func,Config).
end_per_testcase(Func,Config) ->
reltool_test_lib:end_per_testcase(Func,Config).
-fin_per_testcase(Func,Config) -> %% For test_server
- reltool_test_lib:end_per_testcase(Func,Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% SUITE specification
-all() ->
- all(suite).
-all(suite) ->
- [
- start_server,
- set_config,
- create_release,
- create_script,
- create_target,
- create_embedded,
- create_standalone,
- create_old_target
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [start_server, set_config, create_release,
+ create_script, create_target, create_embedded,
+ create_standalone, create_old_target].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% The test cases
diff --git a/lib/reltool/test/reltool_test_lib.erl b/lib/reltool/test/reltool_test_lib.erl
index 5390b0a75e..b8bcbcd009 100644
--- a/lib/reltool/test/reltool_test_lib.erl
+++ b/lib/reltool/test/reltool_test_lib.erl
@@ -97,7 +97,7 @@ wx_init_per_suite(Config) ->
exit({skipped, "Can not test on MacOSX"});
{unix, _} ->
io:format("DISPLAY ~s~n", [os:getenv("DISPLAY")]),
- case proplists:get_value(xserver, Config, none) of
+ case ct:get_config(xserver, none) of
none -> ignore;
Server -> os:putenv("DISPLAY", Server)
end;
@@ -295,7 +295,7 @@ eval_test_case(Mod, Fun, Config) ->
test_case_evaluator(Mod, Fun, [Config]) ->
NewConfig = Mod:init_per_testcase(Fun, Config),
R = apply(Mod, Fun, [NewConfig]),
- Mod:fin_per_testcase(Fun, NewConfig),
+ Mod:end_per_testcase(Fun, NewConfig),
exit({test_case_ok, R}).
wait_for_evaluator(Pid, Mod, Fun, Config) ->
@@ -311,12 +311,12 @@ wait_for_evaluator(Pid, Mod, Fun, Config) ->
{'EXIT', Pid, {skipped, Reason}} ->
log("<WARNING> Test case ~w skipped, because ~p~n",
[{Mod, Fun}, Reason]),
- Mod:fin_per_testcase(Fun, Config),
+ Mod:end_per_testcase(Fun, Config),
{skip, {Mod, Fun}, Reason};
{'EXIT', Pid, Reason} ->
log("<ERROR> Eval process ~w exited, because\n\t~p~n",
[{Mod, Fun}, Reason]),
- Mod:fin_per_testcase(Fun, Config),
+ Mod:end_per_testcase(Fun, Config),
{crash, {Mod, Fun}, Reason}
end.
diff --git a/lib/reltool/test/reltool_wx_SUITE.erl b/lib/reltool/test/reltool_wx_SUITE.erl
index 2e2b355e07..56b0a3ed4a 100644
--- a/lib/reltool/test/reltool_wx_SUITE.erl
+++ b/lib/reltool/test/reltool_wx_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -18,8 +18,9 @@
-module(reltool_wx_SUITE).
--export([all/0, init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
-compile(export_all).
@@ -36,16 +37,22 @@ init_per_testcase(Func,Config) ->
reltool_test_lib:init_per_testcase(Func,Config).
end_per_testcase(Func,Config) ->
reltool_test_lib:end_per_testcase(Func,Config).
-fin_per_testcase(Func,Config) -> %% For test_server
- reltool_test_lib:end_per_testcase(Func,Config).
%% SUITE specification
-all() ->
- all(suite).
-all(suite) ->
- [
- start_all_windows
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [start_all_windows].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% The test cases
diff --git a/lib/reltool/test/rtt.erl b/lib/reltool/test/rtt.erl
index 6755b8400f..437009e26a 100644
--- a/lib/reltool/test/rtt.erl
+++ b/lib/reltool/test/rtt.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% 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
diff --git a/lib/runtime_tools/test/Makefile b/lib/runtime_tools/test/Makefile
index 873d395277..7dc7a015e1 100644
--- a/lib/runtime_tools/test/Makefile
+++ b/lib/runtime_tools/test/Makefile
@@ -57,7 +57,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) runtime_tools.spec $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) runtime_tools.spec runtime_tools.cover $(ERL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(EMAKEFILE) runtime_tools.cover $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/runtime_tools/test/dbg_SUITE.erl b/lib/runtime_tools/test/dbg_SUITE.erl
index ff96af5e86..8e01e75aba 100644
--- a/lib/runtime_tools/test/dbg_SUITE.erl
+++ b/lib/runtime_tools/test/dbg_SUITE.erl
@@ -19,30 +19,51 @@
-module(dbg_SUITE).
%% Test functions
--export([all/1, big/1, tiny/1, simple/1, message/1, distributed/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ big/1, tiny/1, simple/1, message/1, distributed/1,
ip_port/1, file_port/1, file_port2/1, file_port_schedfix/1,
ip_port_busy/1, wrap_port/1, wrap_port_time/1,
with_seq_trace/1, dead_suspend/1, local_trace/1,
saved_patterns/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([tracee1/1, tracee2/1]).
-export([dummy/0, exported/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(default_timeout, ?t:minutes(1)).
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) -> [big, tiny, simple, message, distributed,
- ip_port, file_port, file_port2, file_port_schedfix,
- ip_port_busy, wrap_port, wrap_port_time,
- with_seq_trace, dead_suspend, local_trace, saved_patterns].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [big, tiny, simple, message, distributed, ip_port,
+ file_port, file_port2, file_port_schedfix, ip_port_busy,
+ wrap_port, wrap_port_time, with_seq_trace, dead_suspend,
+ local_trace, saved_patterns].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
big(suite) -> [];
big(doc) -> ["Rudimentary interface test"];
diff --git a/lib/runtime_tools/test/erts_alloc_config_SUITE.erl b/lib/runtime_tools/test/erts_alloc_config_SUITE.erl
index 32483dbe73..d4957c060e 100644
--- a/lib/runtime_tools/test/erts_alloc_config_SUITE.erl
+++ b/lib/runtime_tools/test/erts_alloc_config_SUITE.erl
@@ -21,10 +21,12 @@
%-define(line_trace, 1).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%-compile(export_all).
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
%% Testcases
-export([basic/1]).
@@ -34,15 +36,33 @@
-define(DEFAULT_TIMEOUT, ?t:minutes(2)).
-all(doc) -> [];
-all(suite) -> [basic].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(Case, Config) when is_list(Config) ->
[{testcase, Case},
{watchdog, ?t:timetrap(?DEFAULT_TIMEOUT)},
{erl_flags_env, save_env()} | Config].
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
?t:timetrap_cancel(?config(watchdog, Config)),
restore_env(?config(erl_flags_env, Config)),
ok.
diff --git a/lib/runtime_tools/test/inviso_SUITE.erl b/lib/runtime_tools/test/inviso_SUITE.erl
index 1c5c887b62..817ebfbbba 100644
--- a/lib/runtime_tools/test/inviso_SUITE.erl
+++ b/lib/runtime_tools/test/inviso_SUITE.erl
@@ -29,49 +29,40 @@
-module(inviso_SUITE).
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include_lib("kernel/include/file.hrl").
-define(l,?line).
-all(suite) ->
- [
- basic_dist_trace_1,
- basic_dist_trace_2,
- basic_dist_trace_3,
- basic_dist_trace_ti_1,
- basic_dist_trace_ti_2,
- basic_dist_trace_ti_3,
- suspend_dist_trace_ti_1,
- suspend_dist_trace_ti_2,
- meta_cleanfunc_dist_1,
- basic_handlerfun_dist_1,
- delete_log_dist_1,
- autostart_dist_1,
- autostart_dist_2,
- autostart_dist_3,
- running_alone_dist_1,
- running_alone_dist_2,
- running_alone_dist_3,
- running_alone_dist_4,
- running_alone_dist_5,
- overload_dist_1,
- overload_dist_2,
- overload_dist_3,
- overload_dist_4,
- overload_dist_5,
- subscribe_dist_1,
- lfm_trace_dist_1,
- lfm_trace_ti_dist_2,
- handle_logfile_sort_wrapset,
- fetch_log_dist_trace_1,
- fetch_log_dist_trace_2,
- fetch_log_dist_trace_3,
- fetch_log_dist_error_1,
- fetch_log_dist_error_2,
- expand_regexp_dist_1,
- only_loaded_dist_1
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic_dist_trace_1, basic_dist_trace_2,
+ basic_dist_trace_3, basic_dist_trace_ti_1,
+ basic_dist_trace_ti_2, basic_dist_trace_ti_3,
+ suspend_dist_trace_ti_1, suspend_dist_trace_ti_2,
+ meta_cleanfunc_dist_1, basic_handlerfun_dist_1,
+ delete_log_dist_1, autostart_dist_1, autostart_dist_2,
+ autostart_dist_3, running_alone_dist_1,
+ running_alone_dist_2, running_alone_dist_3,
+ running_alone_dist_4, running_alone_dist_5,
+ overload_dist_1, overload_dist_2, overload_dist_3,
+ overload_dist_4, overload_dist_5, subscribe_dist_1,
+ lfm_trace_dist_1, lfm_trace_ti_dist_2,
+ handle_logfile_sort_wrapset, fetch_log_dist_trace_1,
+ fetch_log_dist_trace_2, fetch_log_dist_trace_3,
+ fetch_log_dist_error_1, fetch_log_dist_error_2,
+ expand_regexp_dist_1, only_loaded_dist_1].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_suite(Config) ->
@@ -133,7 +124,7 @@ init_per_testcase(_Case,Config) ->
insert_timetraphandle_config(TH,NewConfig2).
%% -----------------------------------------------------------------------------
-fin_per_testcase(Case,Config) ->
+end_per_testcase(Case,Config) ->
?l test_server:stop_node(get_remotenode_config(inviso1,Config)),
?l test_server:stop_node(get_remotenode_config(inviso2,Config)),
@@ -142,14 +133,14 @@ fin_per_testcase(Case,Config) ->
true;
Pid when is_pid(Pid) -> % But if it exists...
exit(Pid,kill), % Remove it!
- io:format("Had to kill the control component in fin_per_testcase,~p.~n",[Case])
+ io:format("Had to kill the control component in end_per_testcase,~p.~n",[Case])
end,
case whereis(inviso_rt) of
undefined -> % Should not exist.
true;
Pid2 when is_pid(Pid2) -> % But if it exists...
exit(Pid2,kill), % Remove it!
- io:format("Had to kill local runtime component in fin_per_testcase,~p.~n",[Case])
+ io:format("Had to kill local runtime component in end_per_testcase,~p.~n",[Case])
end,
?l process_killer([inviso_test_proc,
inviso_tab_proc,
diff --git a/lib/runtime_tools/test/runtime_tools.cover b/lib/runtime_tools/test/runtime_tools.cover
index 2d62ebe6ac..ef850bc377 100644
--- a/lib/runtime_tools/test/runtime_tools.cover
+++ b/lib/runtime_tools/test/runtime_tools.cover
@@ -1 +1,3 @@
-{exclude,[observer_backend]}.
+{incl_app,runtime_tools,details}.
+
+{excl_mods, runtime_tools, [observer_backend]}.
diff --git a/lib/runtime_tools/test/runtime_tools.spec b/lib/runtime_tools/test/runtime_tools.spec
index a60a533ce2..0a24232be8 100644
--- a/lib/runtime_tools/test/runtime_tools.spec
+++ b/lib/runtime_tools/test/runtime_tools.spec
@@ -1 +1 @@
-{topcase, {dir, "../runtime_tools_test"}}.
+{suites,"../runtime_tools_test",all}.
diff --git a/lib/runtime_tools/test/runtime_tools_SUITE.erl b/lib/runtime_tools/test/runtime_tools_SUITE.erl
index 84e255e126..4d46d75b62 100644
--- a/lib/runtime_tools/test/runtime_tools_SUITE.erl
+++ b/lib/runtime_tools/test/runtime_tools_SUITE.erl
@@ -17,10 +17,11 @@
%% %CopyrightEnd%
%%
-module(runtime_tools_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([init_per_testcase/2, end_per_testcase/2]).
%% Test cases
@@ -38,9 +39,27 @@ end_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[app_file].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
app_file(suite) ->
[];
app_file(doc) ->
diff --git a/lib/snmp/doc/man1/.gitignore b/lib/snmp/doc/man1/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/snmp/doc/man1/.gitignore
diff --git a/lib/snmp/doc/src/Makefile b/lib/snmp/doc/src/Makefile
index e8d9efb148..70c2e1d09e 100644
--- a/lib/snmp/doc/src/Makefile
+++ b/lib/snmp/doc/src/Makefile
@@ -67,12 +67,15 @@ XML_OUTPUT = $(XML_FILES:%.xml=%.latex.xmls_output) \
INFO_FILE = ../../info
+#HTML_REF1_FILES = $(XML_REF1_FILES:%.xml=$(HTMLDIR)/%.html)
HTML_REF3_FILES = $(XML_REF3_FILES:%.xml=$(HTMLDIR)/%.html)
HTML_REF6_FILES = $(XML_REF6_FILES:%.xml=$(HTMLDIR)/%.html)
HTML_CHAP_FILES = $(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html)
-EXTRA_FILES = summary.html.src \
+EXTRA_FILES = \
+ summary.html.src \
$(DEFAULT_HTML_FILES) \
+ $(HTML_REF1_FILES) \
$(HTML_REF3_FILES) \
$(HTML_REF6_FILES) \
$(HTML_CHAP_FILES)
@@ -80,6 +83,7 @@ EXTRA_FILES = summary.html.src \
MAN7DIR = $(DOCDIR)/man7
+MAN1_FILES = $(MAN1DIR)/snmpc.1
MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
MAN6_FILES = $(XML_REF6_FILES:%_app.xml=$(MAN6DIR)/%.6)
MAN7_FILES = $(MIB_FILES:$(MIBSDIR)/%.mib=$(MAN7DIR)/%.7)
@@ -95,6 +99,7 @@ else
TEX_FILES_BOOK = \
$(BOOK_FILES:%.xml=%.tex)
TEX_FILES_REF_MAN = \
+ $(XML_REF1_FILES:%.xml=%.tex) \
$(XML_REF3_FILES:%.xml=%.tex) \
$(XML_REF6_FILES:%.xml=%.tex) \
$(XML_APPLICATION_FILES:%.xml=%.tex)
@@ -169,7 +174,7 @@ ps: $(TOP_PS_FILE)
html: $(HTML_FILES) $(TOP_HTML_FILES) gifs
-html2: gifs $(TOP_HTML_FILES) $(HTML_FILES) $(HTML_REF3_FILES) $(HTML_REF6_FILES) $(HTML_CHAP_FILES)
+html2: gifs $(TOP_HTML_FILES) $(HTML_FILES) $(HTML_REF1_FILES) $(HTML_REF3_FILES) $(HTML_REF6_FILES) $(HTML_CHAP_FILES)
clean: clean_tex clean_html clean_man clean_docs
@@ -195,7 +200,9 @@ endif
$(INDEX_TARGET): $(INDEX_SRC) ../../vsn.mk # Create top make file
sed -e 's;%VSN%;$(VSN);' $< > $@ # inserting version number
-man: man3 man6 man7
+man: man1 man3 man6 man7
+
+man1: $(MAN1_FILES)
man3: $(MAN3_FILES)
@@ -213,6 +220,7 @@ clean_pdf:
clean_man:
@echo "cleaning man:"
+ rm -f $(MAN1DIR)/*
rm -f $(MAN3DIR)/*
rm -f $(MAN6DIR)/*
rm -f $(MAN7DIR)/*
@@ -233,6 +241,11 @@ $(MAN7DIR)/%.7: $(MIBSDIR)/%.mib
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
+
+$(MAN1DIR)/snmpc.1: snmpc_cmd.xml
+ date=`date +"%B %e %Y"`; \
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+
include $(ERL_TOP)/make/otp_release_targets.mk
ifdef DOCSUPPORT
@@ -244,6 +257,8 @@ release_docs_spec: docs
$(INSTALL_DATA) $(HTMLDIR)/* \
$(RELSYSDIR)/doc/html
$(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man1
+ $(INSTALL_DATA) $(MAN1DIR)/* $(RELEASE_PATH)/man/man1
$(INSTALL_DIR) $(RELEASE_PATH)/man/man3
$(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3
$(INSTALL_DIR) $(RELEASE_PATH)/man/man6
@@ -269,7 +284,9 @@ release_docs_spec: docs
$(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \
$(RELSYSDIR)/doc/html
$(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
- $(INSTALL_DIR) $(RELEASE_PATH)/man/man3
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man1
+ $(INSTALL_DATA) $(MAN1_FILES) $(RELEASE_PATH)/man/man1
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man
$(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3
$(INSTALL_DIR) $(RELEASE_PATH)/man/man6
$(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6
@@ -286,6 +303,10 @@ release_spec:
ifdef DOCSUPPORT
info: info_xml info_man info_html
+ @echo "MAN1DIR: $(MAN1DIR)"
+ @echo "MAN3DIR: $(MAN3DIR)"
+ @echo "MAN6DIR: $(MAN6DIR)"
+ @echo "MAN7DIR: $(MAN7DIR)"
else
info: info_xml info_man info_html info_tex
@echo "DVI2PS = $(DVI2PS)"
@@ -297,6 +318,7 @@ endif
info_man:
@echo "man files:"
+ @echo "MAN1_FILES = $(MAN1_FILES)"
@echo "MAN3_FILES = $(MAN3_FILES)"
@echo "MAN6_FILES = $(MAN6_FILES)"
@echo "MAN7_FILES = $(MAN7_FILES)"
@@ -305,6 +327,7 @@ info_man:
info_xml:
@echo "xml files:"
+# @echo "XML_REF1_FILES = $(XML_REF1_FILES)"
@echo "XML_REF3_FILES = $(XML_REF3_FILES)"
@echo "XML_REF6_FILES = $(XML_REF6_FILES)"
@echo "XML_PART_FILES = $(XML_PART_FILES)"
@@ -333,6 +356,7 @@ info_html:
@echo ""
@echo "DEFAULT_HTML_FILES = $(DEFAULT_HTML_FILES)"
@echo ""
+# @echo "HTML_REF1_FILES = $(HTML_REF1_FILES)"
@echo "HTML_REF3_FILES = $(HTML_REF3_FILES)"
@echo "HTML_REF6_FILES = $(HTML_REF6_FILES)"
@echo "HTML_CHAP_FILES = $(HTML_CHAP_FILES)"
diff --git a/lib/snmp/doc/src/depend.mk b/lib/snmp/doc/src/depend.mk
index bf9833274d..4538f744de 100644
--- a/lib/snmp/doc/src/depend.mk
+++ b/lib/snmp/doc/src/depend.mk
@@ -48,6 +48,7 @@ $(HTMLDIR)/ref_man.html: \
snmp_app.xml \
snmp.xml \
snmpc.xml \
+ snmpc_cmd.xml \
snmpa.xml \
snmpa_conf.xml \
snmpa_discovery_handler.xml \
diff --git a/lib/snmp/doc/src/files.mk b/lib/snmp/doc/src/files.mk
index 293fb52ce0..f8462098be 100644
--- a/lib/snmp/doc/src/files.mk
+++ b/lib/snmp/doc/src/files.mk
@@ -23,6 +23,9 @@ XML_APPLICATION_FILES = \
XML_APP_REF3_FILES = \
snmp.xml
+XML_COMP_REF1_FILES = \
+ snmpc_cmd.xml
+
XML_COMP_REF3_FILES = \
snmpc.xml
@@ -98,12 +101,13 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
-XML_FILES = $(BOOK_FILES) \
- $(XML_CHAPTER_FILES) \
- $(XML_PART_FILES) \
- $(XML_REF6_FILES) \
- $(XML_REF3_FILES) \
- $(XML_APPLICATION_FILES)
+XML_FILES = $(BOOK_FILES) \
+ $(XML_CHAPTER_FILES) \
+ $(XML_PART_FILES) \
+ $(XML_REF1_FILES) \
+ $(XML_REF3_FILES) \
+ $(XML_REF6_FILES) \
+ $(XML_APPLICATION_FILES)
GIF_FILES = book.gif \
getnext1.gif \
diff --git a/lib/snmp/doc/src/make.dep b/lib/snmp/doc/src/make.dep
index ccd01b9d3a..6d741ec1b9 100644
--- a/lib/snmp/doc/src/make.dep
+++ b/lib/snmp/doc/src/make.dep
@@ -52,7 +52,7 @@ book.dvi: book.tex part.tex ref_man.tex snmp.tex snmp_advanced_agent.tex \
snmpa_notification_delivery_info_receiver.tex \
snmpa_notification_filter.tex \
snmpa_supervisor.tex \
- snmpc.tex snmpm.tex snmpm_conf.tex snmpm_mpd.tex \
+ snmpc.tex snmpc_cmd.tex snmpm.tex snmpm_conf.tex snmpm_mpd.tex \
snmpm_network_interface.tex snmpm_network_interface_filter.tex \
snmpm_user.tex
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 493e7aa092..2efeb8ae3f 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
- <year>1996</year><year>2010</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -32,23 +32,135 @@
<file>notes.xml</file>
</header>
- <section><title>SNMP 4.18</title>
+ <section>
+ <title>SNMP Development Toolkit 4.19</title>
+ <p>Version 4.19 supports code replacement in runtime from/to
+ version 4.18.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+<!--
+ <p>-</p>
+-->
+ <list type="bulleted">
+ <item>
+ <p>[compiler] Added support for textual convention
+ <c>AGENT-CAPABILITIES</c> and "full" support for textual
+ convention MODULE-COMPLIANCE, both defined by the SNMPv2-CONF
+ mib.</p>
+ <p>The <c>reference</c> and <c>modules</c> part(s) are
+ stored in the <c>assocList</c> of the mib-entry (<c>me</c>)
+ record.
+ Only handled <em>if</em> the option(s) <c>agent_capabilities</c>
+ and <c>module_compliance</c> (respectively) are provided to the
+ compiler. </p>
+ <p>See <seealso marker="snmpc#compile">compile/2</seealso>
+ for more info. </p>
+ <p>For backward compatibillity, the MIBs provided with
+ this application are <em>not</em> compiled with these
+ options. </p>
+ <p>Own Id: OTP-8966</p>
+ </item>
+
+ <item>
+ <p>[agent] Added a "complete" set of (snmp) table and variable
+ print functions, for each mib handled by the SNMP (agent)
+ application. This will be usefull when debugging a running agent.</p>
+ <p>See
+ <seealso marker="snmpa#print_mib_info">print_mib_info/0</seealso>,
+ <seealso marker="snmpa#print_mib_tables">print_mib_tables/0</seealso>
+ and
+ <seealso marker="snmpa#print_mib_variables">print_mib_variables/0</seealso>
+ for more info. </p>
+ <p>Own Id: OTP-8977</p>
+ </item>
+
+ <item>
+ <p>[compiler] Added a MIB compiler (frontend) escript,
+ <c>snmpc</c>. </p>
+ <p>Own Id: OTP-9004</p>
+ </item>
+
+ </list>
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+<!--
+ <p>-</p>
+-->
+ <list type="bulleted">
+ <item>
+ <p>[agent] For the table vacmAccessTable,
+ when performing the is_set_ok and set operation(s),
+ all values of the vacmAccessSecurityModel column was
+ incorrectly translated to <c>any</c>. </p>
+<!--
+that is when calling:
+snmp_view_basec_acm_mib:vacmAccessTable(set, RowIndex, Cols).
+-->
+ <p>Own Id: OTP-8980</p>
+ </item>
+
+ <item>
+ <p>[agent] When calling
+ <seealso marker="snmp_view_based_acm_mib#reconfigure">snmp_view_based_acm_mib:reconfigure/1</seealso>
+ on a running node, the table <c>vacmAccessTable</c> was not properly
+ cleaned.
+ This meant that if some entries in the vacm.conf file was removed
+ (compared to the <c>current</c> config),
+ while others where modified and/or added, the removed entrie(s)
+ would still exist in the <c>vacmAccessTable</c> table. </p>
+ <p>Own Id: OTP-8981</p>
+ <p>Aux Id: Seq 11750</p>
+ </item>
+
+ </list>
+ </section>
+
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+
+ </section> <!-- 4.19 -->
+
+ <section>
+ <title>SNMP Development Toolkit 4.18</title>
+ <p>Version 4.18 supports code replacement in runtime from/to
+ version 4.17.1 and 4.17.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <list type="bulleted">
+ <item>
+ <p>Prepared for R14B release.</p>
+ </item>
+ </list>
+ </section>
<section><title>Fixed Bugs and Malfunctions</title>
- <list>
+ <p>-</p>
+<!--
+ <list type="bulleted">
<item>
- <p>
- When the function FilterMod:accept_recv/2 returned false
- the SNMP agent stopped collecting messages from UDP.</p>
- <p>
- Own Id: OTP-8761</p>
+ <p>[agent] When the function FilterMod:accept_recv/2 returned false
+ the SNMP agent stopped collecting messages from UDP.</p>
+ <p>Own Id: OTP-8761</p>
</item>
</list>
+-->
</section>
-</section>
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+ </section> <!-- 4.18 -->
+
-<section>
+ <section>
<title>SNMP Development Toolkit 4.17.1</title>
<p>Version 4.17.1 supports code replacement in runtime from/to
version 4.17, 4.16.2, 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p>
@@ -63,7 +175,8 @@
<list type="bulleted">
<item>
<p>When the function FilterMod:accept_recv/2
- returned false the SNMP agent stopped collecting messages from UDP.</p>
+ returned false the SNMP agent stopped collecting
+ messages from UDP.</p>
<p>Own Id: OTP-8761</p>
</item>
</list>
diff --git a/lib/snmp/doc/src/ref_man.xml b/lib/snmp/doc/src/ref_man.xml
index 1ae5a8205b..815d21d33e 100644
--- a/lib/snmp/doc/src/ref_man.xml
+++ b/lib/snmp/doc/src/ref_man.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE application SYSTEM "application.dtd">
<application xmlns:xi="http://www.w3.org/2001/XInclude">
@@ -61,6 +61,7 @@
<xi:include href="snmp_user_based_sm_mib.xml"/>
<xi:include href="snmp_view_based_acm_mib.xml"/>
<xi:include href="snmpc.xml"/>
+ <xi:include href="snmpc_cmd.xml"/>
<xi:include href="snmpm.xml"/>
<xi:include href="snmpm_conf.xml"/>
<xi:include href="snmpm_mpd.xml"/>
diff --git a/lib/snmp/doc/src/snmp_agent_config_files.xml b/lib/snmp/doc/src/snmp_agent_config_files.xml
index 0bab563f87..b62269d506 100644
--- a/lib/snmp/doc/src/snmp_agent_config_files.xml
+++ b/lib/snmp/doc/src/snmp_agent_config_files.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -178,11 +178,12 @@
<c>community.conf</c>. It must be present if the agent is
configured for SNMPv1 or SNMPv2c.
</p>
+ <p>An SNMP <em>community</em> is a relationship between an SNMP
+ agent and a set of SNMP managers that defines authentication, access
+ control and proxy characteristics. </p>
<p>The corresponding table is <c>snmpCommunityTable</c> in the
- SNMP-COMMUNITY-MIB.
- </p>
- <p>Each entry is a term:
- </p>
+ SNMP-COMMUNITY-MIB. </p>
+ <p>Each entry is a term: </p>
<p><c>{CommunityIndex, CommunityName, SecurityName, ContextName, TransportTag}.</c></p>
<list type="bulleted">
<item><c>CommunityIndex</c> is a non-empty string.
diff --git a/lib/snmp/doc/src/snmp_config.xml b/lib/snmp/doc/src/snmp_config.xml
index 769b908adc..4e41cb5037 100644
--- a/lib/snmp/doc/src/snmp_config.xml
+++ b/lib/snmp/doc/src/snmp_config.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
@@ -1004,36 +1004,16 @@ ok
</taglist>
<p>Another usefull way to debug the agent is to pretty-print the content of
- some of the (MIB-) tables handled directly by the agent. This can be done
- for the following tables: </p>
- <taglist>
- <tag><c><![CDATA[snmpCommunityTable]]></c></tag>
- <item>
- <p><c><![CDATA[snmp_community_mib:snmpCommunityTable(print).]]></c></p>
- </item>
-
- <tag><c><![CDATA[snmpNotifyTable]]></c></tag>
- <item>
- <p><c><![CDATA[snmp_notification_mib:snmpNotifyTable(print).]]></c></p>
- </item>
-
- <tag><c><![CDATA[snmpTargetAddrTable]]></c></tag>
- <item>
- <p><c><![CDATA[snmp_target_mib:snmpTargetAddrTable(print).]]></c></p>
- </item>
-
- <tag><c><![CDATA[snmpTargetParamsTable]]></c></tag>
- <item>
- <p><c><![CDATA[snmp_target_mib:snmpTargetParamsTable(print).]]></c></p>
- </item>
-
- <tag><c><![CDATA[usmUserTable]]></c></tag>
- <item>
- <p><c><![CDATA[snmp_user_based_sm_mib:usmUserTable(print).]]></c></p>
- </item>
-
- </taglist>
-
+ all the tables and/or variables handled directly by the agent.
+ This can be done by simply calling: </p>
+ <p><c><![CDATA[snmpa:print_mib_info()]]></c></p>
+ <p>See
+ <seealso marker="snmpa#print_mib_info">print_mib_info/0</seealso>,
+ <seealso marker="snmpa#print_mib_tables">print_mib_tables/0</seealso>
+ or
+ <seealso marker="snmpa#print_mib_variables">print_mib_variables/0</seealso>
+ for more info. </p>
+
</section>
</chapter>
diff --git a/lib/snmp/doc/src/snmp_view_based_acm_mib.xml b/lib/snmp/doc/src/snmp_view_based_acm_mib.xml
index ffea256608..d595f6b93b 100644
--- a/lib/snmp/doc/src/snmp_view_based_acm_mib.xml
+++ b/lib/snmp/doc/src/snmp_view_based_acm_mib.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>
@@ -38,7 +38,10 @@
SNMP-VIEW-BASED-ACM-MIB, and functions for configuring the database.
</p>
<p>The configuration files are described in the SNMP User's Manual.</p>
+
+ <marker id="configure"></marker>
</description>
+
<funcs>
<func>
<name>configure(ConfDir) -> void()</name>
@@ -48,27 +51,24 @@
</type>
<desc>
<p>This function is called from the supervisor at system
- start-up.
- </p>
+ start-up. </p>
<p>Inserts all data in the configuration files into the
- database and destroys all old rows with StorageType
- <c>volatile</c>. The rows created from the configuration file
- will have StorageType <c>nonVolatile</c>.
- </p>
- <p>All <c>snmp</c> counters are set to zero.
- </p>
+ database and destroys all old rows with StorageType
+ <c>volatile</c>. The rows created from the configuration file
+ will have StorageType <c>nonVolatile</c>. </p>
+ <p>All <c>snmp</c> counters are set to zero. </p>
<p>If an error is found in the configuration file, it is
- reported using the function <c>config_err/2</c> of the error
- report module, and the function fails with the reason
- <c>configuration_error</c>.
- </p>
+ reported using the function <c>config_err/2</c> of the error
+ report module, and the function fails with the reason
+ <c>configuration_error</c>. </p>
<p><c>ConfDir</c> is a string which points to the directory
- where the configuration files are found.
- </p>
- <p>The configuration file read is: <c>vacm.conf</c>.
- </p>
+ where the configuration files are found. </p>
+ <p>The configuration file read is: <c>vacm.conf</c>. </p>
+
+ <marker id="reconfigure"></marker>
</desc>
</func>
+
<func>
<name>reconfigure(ConfDir) -> void()</name>
<fsummary>Configure the SNMP-VIEW-BASED-ACM-MIB</fsummary>
@@ -88,18 +88,20 @@
<p>All <c>snmp</c> counters are set to zero.
</p>
<p>If an error is found in the configuration file, it is
- reported using the function <c>config_err/2</c> of the error
- report module, and the function fails with the reason
+ reported using the function
+ <seealso marker="snmpa_error#config_err">config_err/2</seealso>
+ of the error report module, and the function fails with the reason
<c>configuration_error</c>.
</p>
<p><c>ConfDir</c> is a string which points to the directory
where the configuration files are found.
</p>
- <p>The configuration file read is: <c>vacm.conf</c>.
- <marker id="add_sec2group"></marker>
-</p>
+ <p>The configuration file read is: <c>vacm.conf</c>. </p>
+
+ <marker id="add_sec2group"></marker>
</desc>
</func>
+
<func>
<name>add_sec2group(SecModel, SecName, GroupName) -> Ret</name>
<fsummary>Add one security to group definition</fsummary>
@@ -113,10 +115,13 @@
</type>
<desc>
<p>Adds a security to group definition to the agent config.
- Equivalent to one vacmSecurityToGroup-line in the <c>vacm.conf</c> file.</p>
+ Equivalent to one vacmSecurityToGroup-line in the
+ <c>vacm.conf</c> file.</p>
+
<marker id="delete_sec2group"></marker>
</desc>
</func>
+
<func>
<name>delete_sec2group(Key) -> Ret</name>
<fsummary>Delete one security to group definition</fsummary>
@@ -127,9 +132,11 @@
</type>
<desc>
<p>Delete a security to group definition from the agent config.</p>
+
<marker id="add_access"></marker>
</desc>
</func>
+
<func>
<name>add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) -> Ret</name>
<fsummary>Add one access definition</fsummary>
@@ -148,10 +155,12 @@
</type>
<desc>
<p>Adds a access definition to the agent config.
- Equivalent to one vacmAccess-line in the <c>vacm.conf</c> file.</p>
- <marker id="delete_access"></marker>
+ Equivalent to one vacmAccess-line in the <c>vacm.conf</c> file.</p>
+
+ <marker id="delete_access"></marker>
</desc>
</func>
+
<func>
<name>delete_access(Key) -> Ret</name>
<fsummary>Delete one access definition</fsummary>
@@ -161,10 +170,12 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Delete a access definition from the agent config.</p>
- <marker id="add_view_tree_fam"></marker>
+ <p>Delete a access definition from the agent config.</p>
+
+ <marker id="add_view_tree_fam"></marker>
</desc>
</func>
+
<func>
<name>add_view_tree_fam(ViewIndex, SubTree, Status, Mask) -> Ret</name>
<fsummary>Add one view tree family definition</fsummary>
@@ -178,11 +189,14 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Adds a view tree family definition to the agent config.
- Equivalent to one vacmViewTreeFamily-line in the <c>vacm.conf</c> file.</p>
- <marker id="delete_view_tree_fam"></marker>
+ <p>Adds a view tree family definition to the agent config.
+ Equivalent to one vacmViewTreeFamily-line in the
+ <c>vacm.conf</c> file.</p>
+
+ <marker id="delete_view_tree_fam"></marker>
</desc>
</func>
+
<func>
<name>delete_view_tree_fam(Key) -> Ret</name>
<fsummary>Delete one view tree family definition</fsummary>
diff --git a/lib/snmp/doc/src/snmpa.xml b/lib/snmp/doc/src/snmpa.xml
index f546724a78..1d680e80f5 100644
--- a/lib/snmp/doc/src/snmpa.xml
+++ b/lib/snmp/doc/src/snmpa.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">
<erlref>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -1252,6 +1252,39 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2).
<p>This is a utility function, that can be useful when
e.g. debugging instrumentation functions.</p>
+ <marker id="print_mib_info"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>print_mib_info() -> void()</name>
+ <fsummary>Print mib info</fsummary>
+ <desc>
+ <p>Prints the content of all the (snmp) tables and variables
+ for all mibs handled by the snmp agent. </p>
+
+ <marker id="print_mib_tables"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>print_mib_tables() -> void()</name>
+ <fsummary>Print mib tables</fsummary>
+ <desc>
+ <p>Prints the content of all the (snmp) tables
+ for all mibs handled by the snmp agent. </p>
+
+ <marker id="print_mib_variables"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>print_mib_variables() -> void()</name>
+ <fsummary>Print mib variables</fsummary>
+ <desc>
+ <p>Prints the content of all the (snmp) variables
+ for all mibs handled by the snmp agent. </p>
+
<marker id="verbosity"></marker>
</desc>
</func>
diff --git a/lib/snmp/doc/src/snmpa_error.xml b/lib/snmp/doc/src/snmpa_error.xml
index a7312e8b24..4dbafdfbb7 100644
--- a/lib/snmp/doc/src/snmpa_error.xml
+++ b/lib/snmp/doc/src/snmpa_error.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -51,6 +51,8 @@
<c>error_report_mod</c>, see
<seealso marker="snmp_config#configuration_params">configuration parameters</seealso>.
</p>
+
+ <marker id="config_err"></marker>
</description>
<funcs>
<func>
@@ -67,8 +69,11 @@
</p>
<p><c>Format</c> and <c>Args</c> are as in
<c>io:format(Format, Args)</c>.</p>
+
+ <marker id="user_err"></marker>
</desc>
</func>
+
<func>
<name>user_err(Format, Args) -> void()</name>
<fsummary>Called if a user related error occurs</fsummary>
diff --git a/lib/snmp/doc/src/snmpc.xml b/lib/snmp/doc/src/snmpc.xml
index fbd0950c69..771629492d 100644
--- a/lib/snmp/doc/src/snmpc.xml
+++ b/lib/snmp/doc/src/snmpc.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">
<erlref>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -37,6 +37,7 @@
<p>The module <c>snmpc</c> contains interface functions to the
SNMP toolkit MIB compiler.</p>
+ <marker id="compile"></marker>
</description>
<funcs>
@@ -47,7 +48,7 @@
<type>
<v>File = string()</v>
<v>Options = [opt()]</v>
- <v>opt() = db() | relaxed_row_name_assign_check() | deprecated() | description() | reference() | group_check() | i() | il() | imports() | module() | module_identity() | outdir() | no_defs() | verbosity() | warnings()</v>
+ <v>opt() = db() | relaxed_row_name_assign_check() | deprecated() | description() | reference() | group_check() | i() | il() | imports() | module() | module_identity() | module_compliance() | agent_capabilities() | outdir() | no_defs() | verbosity() | warnings()</v>
<v>db() = {db, volatile|persistent|mnesia}</v>
<v>deprecated() = {deprecated, bool()}</v>
<v>relaxed_row_name_assign_check() = relaxed_row_name_assign_check</v>
@@ -59,6 +60,8 @@
<v>imports() = imports</v>
<v>module() = {module, atom()}</v>
<v>module_identity() = module_identity</v>
+ <v>module_compliance() = module_compliance</v>
+ <v>agent_capabilities() = agent_capabilities</v>
<v>no_defs() = no_defs</v>
<v>outdir() = {outdir, dir()}</v>
<v>verbosity() = {verbosity, silence|warning|info|log|debug|trace}</v>
@@ -77,6 +80,7 @@
be used for the default instrumentation. </p>
<p>Default is <c>volatile</c>. </p>
</item>
+
<item>
<p>The option <c>deprecated</c> specifies if a deprecated
definition should be kept or not. If the option is
@@ -84,6 +88,7 @@
definitions. </p>
<p>Default is <c>true</c>. </p>
</item>
+
<item>
<p>The option <c>relaxed_row_name_assign_check</c>, if present,
specifies that the row name assign check shall not be done
@@ -94,12 +99,14 @@
<p>By default it is not included, but if this option is present
it will be. </p>
</item>
+
<item>
<p>The option <c>description</c> specifies if the text
of the DESCRIPTION field will be included or not. </p>
<p>By default it is not included, but if this option is
present it will be. </p>
</item>
+
<item>
<p>The option <c>reference</c> specifies if the text
of the REFERENCE field, when found in a table definition,
@@ -108,18 +115,21 @@
it will be. The reference text will be placed in the allocList
field of the mib-entry record (#me{}) for the table. </p>
</item>
+
<item>
<p>The option <c>group_check</c> specifies whether the
mib compiler should check the OBJECT-GROUP macro and
the NOTIFICATION-GROUP macro for correctness or not. </p>
<p>Default is <c>true</c>. </p>
</item>
+
<item>
<p>The option <c>i</c> specifies the path to search for
imported (compiled) MIB files. The directories should be
strings with a trailing directory delimiter. </p>
<p>Default is <c>["./"]</c>. </p>
</item>
+
<item>
<p>The option <c>il</c> (include_lib) also specifies a
list of directories to search for imported MIBs. It
@@ -132,11 +142,13 @@
<c><![CDATA[<snmp-home>/priv/mibs/]]></c>
are always listed last in the include path. </p>
</item>
+
<item>
<p>The option <c>imports</c>, if present, specifies that
the IMPORT statement of the MIB shall be included in the
compiled mib. </p>
</item>
+
<item>
<p>The option <c>module</c>, if present, specifies the
name of a module which implements all instrumentation
@@ -145,11 +157,29 @@
functions must be the same as the corresponding managed
object it implements. </p>
</item>
+
<item>
<p>The option <c>module_identity</c>, if present, specifies
that the info part of the MODULE-IDENTITY statement of the MIB
shall be included in the compiled mib. </p>
</item>
+
+ <item>
+ <p>The option <c>module_compliance</c>, if present, specifies
+ that the MODULE-COMPLIANCE statement of the MIB shall be included
+ (with a mib-entry record) in the compiled mib. The mib-entry record
+ of the module-compliance will contain <c>reference</c> and <c>module</c>
+ part(s) this info in the <c>assocList</c> field). </p>
+ </item>
+
+ <item>
+ <p>The option <c>agent_capabilities</c>, if present, specifies
+ that the AGENT-CAPABILITIES statement of the MIB shall be included
+ (with a mib-entry record) in the compiled mib. The mib-entry record
+ of the agent-capabilitie will contain <c>reference</c> and <c>modules</c>
+ part(s) this info in the <c>assocList</c> field). </p>
+ </item>
+
<item>
<p>The option <c>no_defs</c>, if present, specifies
that if a managed object does not have an instrumentation
@@ -157,6 +187,7 @@
be used, instead this is reported as an error, and the
compilation aborts. </p>
</item>
+
<item>
<p>The option <c>verbosity</c> specifies the verbosity of
the SNMP mib compiler. I.e. if warning, info, log, debug
@@ -166,11 +197,13 @@
option <c>verbosity</c> is <c>silence</c>, warning messages will
still be shown. </p>
</item>
+
<item>
<p>The option <c>warnings</c> specifies whether warning
messages should be shown. </p>
<p>Default is <c>true</c>. </p>
</item>
+
</list>
<p>The MIB compiler understands both SMIv1 and SMIv2 MIBs. It
uses the <c>MODULE-IDENTITY</c> statement to determine if the MIB is
@@ -185,8 +218,11 @@
have to be specified to <c>erlc</c> using the syntax
<c>+term</c>. See <c>erlc(1)</c> for details.
</p>
+
+ <marker id="is_consistent"></marker>
</desc>
</func>
+
<func>
<name>is_consistent(Mibs) -> ok | {error, Reason}</name>
<fsummary>Check for OID conflicts between MIBs</fsummary>
@@ -198,8 +234,11 @@
<p>Checks for multiple usage of object identifiers and traps
between MIBs.
</p>
+
+ <marker id="mib_to_hrl"></marker>
</desc>
</func>
+
<func>
<name>mib_to_hrl(MibName) -> ok | {error, Reason}</name>
<fsummary>Generate constants for the objects in the MIB</fsummary>
diff --git a/lib/snmp/include/snmp_types.hrl b/lib/snmp/include/snmp_types.hrl
index 1fd6d153c9..4adb24361c 100644
--- a/lib/snmp/include/snmp_types.hrl
+++ b/lib/snmp/include/snmp_types.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -192,7 +192,7 @@
%%----------------------------------------------------------------------
-record(mib,
{misc = [],
- mib_format_version = "3.1",
+ mib_format_version = "3.2",
name = "",
module_identity, %% Not in SMIv1, and only with +module_identity
mes = [],
diff --git a/lib/snmp/mibs/Makefile.in b/lib/snmp/mibs/Makefile.in
index b85a8b0767..7aefb0ea34 100644
--- a/lib/snmp/mibs/Makefile.in
+++ b/lib/snmp/mibs/Makefile.in
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2009. All Rights Reserved.
+# Copyright Ericsson AB 1996-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -108,20 +108,28 @@ TARGET_FILES = \
# FLAGS
# ----------------------------------------------------
-SNMP_FLAGS += -pa ../ebin +version
+SNMP_FLAGS += -pa ../ebin +version
ifneq ($(MIBS_VERBOSITY),)
-SNMP_FLAGS += +'{verbosity,$(MIBS_VERBOSITY)}'
+SNMP_FLAGS += +'{verbosity, $(MIBS_VERBOSITY)}'
endif
-ifneq ($(MIBS_REFERENCE),)
+ifeq ($(MIBS_REFERENCE),true)
SNMP_FLAGS += +reference
endif
-ifneq ($(MIBS_OPTIONS),)
+ifeq ($(MIBS_OPTIONS),true)
SNMP_FLAGS += +options
endif
+ifeq ($(MIBS_MC),true)
+SNMP_FLAGS += +module_compliance
+endif
+
+ifeq ($(MIBS_AC),true)
+SNMP_FLAGS += +agent_capabilities
+endif
+
# ----------------------------------------------------
# Targets
@@ -148,6 +156,14 @@ conf:
cd ..; $(MAKE) conf
info:
+ @echo "MIBS_REFERENCE = $(MIBS_REFERENCE)"
+ @echo ""
+ @echo "MIBS_OPTIONS = $(MIBS_OPTIONS)"
+ @echo ""
+ @echo "MIBS_MC = $(MIBS_MC)"
+ @echo ""
+ @echo "MIBS_AC = $(MIBS_AC)"
+ @echo ""
@echo "SNMP_FLAGS = $(SNMP_FLAGS)"
@echo ""
@echo "MIBS = $(MIBS)"
diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl
index 8f0f4cad73..5644a43345 100644
--- a/lib/snmp/src/agent/snmp_community_mib.erl
+++ b/lib/snmp/src/agent/snmp_community_mib.erl
@@ -336,6 +336,8 @@ get_target_addr_ext_mms(TDomain, TAddress, Key) ->
get_target_addr_ext_mms(TDomain, TAddress, NextKey)
end
end.
+
+
%%-----------------------------------------------------------------
%% Instrumentation Functions
%%-----------------------------------------------------------------
@@ -347,7 +349,7 @@ snmpCommunityTable(print) ->
PrintRow =
fun(Prefix, Row) ->
lists:flatten(
- io_lib:format("~sIndex: ~p"
+ io_lib:format("~sIndex: ~p"
"~n~sName: ~p"
"~n~sSecurityName: ~p"
"~n~sContextEngineID: ~p"
diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl
index d9bf7e8551..0d7866d94d 100644
--- a/lib/snmp/src/agent/snmp_framework_mib.erl
+++ b/lib/snmp/src/agent/snmp_framework_mib.erl
@@ -373,15 +373,27 @@ intAgentUDPPort(Op) ->
intAgentIpAddress(Op) ->
snmp_generic:variable_func(Op, db(intAgentIpAddress)).
+snmpEngineID(print) ->
+ VarAndValue = [{snmpEngineID, snmpEngineID(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
snmpEngineID(Op) ->
snmp_generic:variable_func(Op, db(snmpEngineID)).
+snmpEngineMaxMessageSize(print) ->
+ VarAndValue = [{snmpEngineMaxMessageSize, snmpEngineMaxMessageSize(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
snmpEngineMaxMessageSize(Op) ->
snmp_generic:variable_func(Op, db(snmpEngineMaxMessageSize)).
+snmpEngineBoots(print) ->
+ VarAndValue = [{snmpEngineBoots, snmpEngineBoots(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
snmpEngineBoots(Op) ->
snmp_generic:variable_func(Op, db(snmpEngineBoots)).
+snmpEngineTime(print) ->
+ VarAndValue = [{snmpEngineTime, snmpEngineTime(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
snmpEngineTime(get) ->
{value, get_engine_time()}.
diff --git a/lib/snmp/src/agent/snmp_standard_mib.erl b/lib/snmp/src/agent/snmp_standard_mib.erl
index 639172401d..b6834d278c 100644
--- a/lib/snmp/src/agent/snmp_standard_mib.erl
+++ b/lib/snmp/src/agent/snmp_standard_mib.erl
@@ -40,6 +40,28 @@
sys_object_id/1, sys_object_id/2, sys_or_table/3,
variable_func/1, variable_func/2,
inc/1, inc/2]).
+-export([sysDescr/1, sysContact/1, sysName/1, sysLocation/1,
+ sysServices/1, sysUpTime/1, snmpEnableAuthenTraps/1,
+ sysObjectID/1,
+ snmpInPkts/1, snmpOutPkts/1,
+ snmpInBadVersions/1,
+ snmpInBadCommunityNames/1, snmpInBadCommunityUses/1,
+ snmpInASNParseErrs/1,
+ snmpInTooBigs/1,
+ snmpInNoSuchNames/1, snmpInBadValues/1,
+ snmpInReadOnlys/1, snmpInGenErrs/1,
+ snmpInTotalReqVars/1, snmpInTotalSetVars/1,
+ snmpInGetRequests/1, snmpInSetRequests/1,
+ snmpInGetNexts/1,
+ snmpInGetResponses/1, snmpInTraps/1,
+ snmpOutTooBigs/1,
+ snmpOutNoSuchNames/1,
+ snmpOutBadValues/1,
+ snmpOutGenErrs/1,
+ snmpOutGetRequests/1, snmpOutSetRequests/1,
+ snmpOutGetNexts/1,
+ snmpOutGetResponses/1,
+ snmpOutTraps/1]).
-export([dummy/1, snmp_set_serial_no/1, snmp_set_serial_no/2]).
-export([add_agent_caps/2, del_agent_caps/1, get_agent_caps/0]).
-export([check_standard/1]).
@@ -202,18 +224,257 @@ variable_func(get, Name) ->
inc(Name) -> inc(Name, 1).
inc(Name, N) -> ets:update_counter(snmp_agent_table, Name, N).
+
+sysDescr(print) ->
+ VarAndValue = [{sysDescr, sysDescr(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+sysDescr(get) ->
+ VarDB = db(sysDescr),
+ snmp_generic:variable_get(VarDB).
+
+
+sysContact(print) ->
+ VarAndValue = [{sysContact, sysContact(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+sysContact(get) ->
+ VarDB = db(sysContact),
+ snmp_generic:variable_get(VarDB).
+
+
+sysName(print) ->
+ VarAndValue = [{sysName, sysName(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+sysName(get) ->
+ VarDB = db(sysName),
+ snmp_generic:variable_get(VarDB).
+
+
+sysLocation(print) ->
+ VarAndValue = [{sysLocation, sysLocation(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+sysLocation(get) ->
+ VarDB = db(sysLocation),
+ snmp_generic:variable_get(VarDB).
+
+
+sysServices(print) ->
+ VarAndValue = [{sysServices, sysServices(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+sysServices(get) ->
+ VarDB = db(sysServices),
+ snmp_generic:variable_get(VarDB).
+
+
+snmpInPkts(print) ->
+ gen_counter(print, snmpInPkts);
+snmpInPkts(get) ->
+ gen_counter(get, snmpInPkts).
+
+
+snmpOutPkts(print) ->
+ gen_counter(print, snmpOutPkts);
+snmpOutPkts(get) ->
+ gen_counter(get, snmpOutPkts).
+
+
+snmpInASNParseErrs(print) ->
+ gen_counter(print, snmpInASNParseErrs);
+snmpInASNParseErrs(get) ->
+ gen_counter(get, snmpInASNParseErrs).
+
+
+snmpInBadCommunityNames(print) ->
+ gen_counter(print, snmpInBadCommunityNames);
+snmpInBadCommunityNames(get) ->
+ gen_counter(get, snmpInBadCommunityNames).
+
+
+snmpInBadCommunityUses(print) ->
+ gen_counter(print, snmpInBadCommunityUses);
+
+snmpInBadCommunityUses(get) ->
+ gen_counter(get, snmpInBadCommunityUses).
+
+
+snmpInBadVersions(print) ->
+ gen_counter(print, snmpInBadVersions);
+snmpInBadVersions(get) ->
+ gen_counter(get, snmpInBadVersions).
+
+
+snmpInTooBigs(print) ->
+ gen_counter(print, snmpInTooBigs);
+snmpInTooBigs(get) ->
+ gen_counter(get, snmpInTooBigs).
+
+
+snmpInNoSuchNames(print) ->
+ gen_counter(print, snmpInNoSuchNames);
+snmpInNoSuchNames(get) ->
+ gen_counter(get, snmpInNoSuchNames).
+
+
+snmpInBadValues(print) ->
+ gen_counter(print, snmpInBadValues);
+snmpInBadValues(get) ->
+ gen_counter(get, snmpInBadValues).
+
+
+snmpInReadOnlys(print) ->
+ gen_counter(print, snmpInReadOnlys);
+snmpInReadOnlys(get) ->
+ gen_counter(get, snmpInReadOnlys).
+
+
+snmpInGenErrs(print) ->
+ gen_counter(print, snmpInGenErrs);
+snmpInGenErrs(get) ->
+ gen_counter(get, snmpInGenErrs).
+
+
+snmpInTotalReqVars(print) ->
+ gen_counter(print, snmpInTotalReqVars);
+snmpInTotalReqVars(get) ->
+ gen_counter(get, snmpInTotalReqVars).
+
+
+snmpInTotalSetVars(print) ->
+ gen_counter(print, snmpInTotalSetVars);
+snmpInTotalSetVars(get) ->
+ gen_counter(get, snmpInTotalSetVars).
+
+
+snmpInGetRequests(print) ->
+ gen_counter(print, snmpInGetRequests);
+snmpInGetRequests(get) ->
+ gen_counter(get, snmpInGetRequests).
+
+
+snmpInSetRequests(print) ->
+ gen_counter(print, snmpInSetRequests);
+snmpInSetRequests(get) ->
+ gen_counter(get, snmpInSetRequests).
+
+
+snmpInGetNexts(print) ->
+ gen_counter(print, snmpInGetNexts);
+snmpInGetNexts(get) ->
+ gen_counter(get, snmpInGetNexts).
+
+
+snmpInGetResponses(print) ->
+ gen_counter(print, snmpInGetResponses);
+snmpInGetResponses(get) ->
+ gen_counter(get, snmpInGetResponses).
+
+
+snmpInTraps(print) ->
+ gen_counter(print, snmpInTraps);
+snmpInTraps(get) ->
+ gen_counter(get, snmpInTraps).
+
+
+snmpOutTooBigs(print) ->
+ gen_counter(print, snmpOutTooBigs);
+snmpOutTooBigs(get) ->
+ gen_counter(get, snmpOutTooBigs).
+
+
+snmpOutNoSuchNames(print) ->
+ gen_counter(print, snmpOutNoSuchNames);
+snmpOutNoSuchNames(get) ->
+ gen_counter(get, snmpOutNoSuchNames).
+
+
+snmpOutBadValues(print) ->
+ gen_counter(print, snmpOutBadValues);
+snmpOutBadValues(get) ->
+ gen_counter(get, snmpOutBadValues).
+
+
+snmpOutGenErrs(print) ->
+ gen_counter(print, snmpOutGenErrs);
+snmpOutGenErrs(get) ->
+ gen_counter(get, snmpOutGenErrs).
+
+
+snmpOutGetRequests(print) ->
+ gen_counter(print, snmpOutGetRequests);
+snmpOutGetRequests(get) ->
+ gen_counter(get, snmpOutGetRequests).
+
+
+snmpOutSetRequests(print) ->
+ gen_counter(print, snmpOutSetRequests);
+snmpOutSetRequests(get) ->
+ gen_counter(get, snmpOutSetRequests).
+
+
+snmpOutGetNexts(print) ->
+ gen_counter(print, snmpOutGetNexts);
+snmpOutGetNexts(get) ->
+ gen_counter(get, snmpOutGetNexts).
+
+
+snmpOutGetResponses(print) ->
+ gen_counter(print, snmpOutGetResponses);
+snmpOutGetResponses(get) ->
+ gen_counter(get, snmpOutGetResponses).
+
+
+snmpOutTraps(print) ->
+ gen_counter(print, snmpOutTraps);
+snmpOutTraps(get) ->
+ gen_counter(get, snmpOutTraps).
+
+
+gen_counter(print, Counter) ->
+ Val = gen_counter(get, Counter),
+ VarAndValue = [{Counter, Val}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+gen_counter(get, Counter) ->
+ variable_func(get, Counter).
+
+
%%-----------------------------------------------------------------
%% This is the instrumentation function for sysUpTime.
%%-----------------------------------------------------------------
+sysUpTime(print) ->
+ sys_up_time(print);
+sysUpTime(get) ->
+ sys_up_time(get).
+
sys_up_time() ->
snmpa:sys_up_time().
+sys_up_time(print) ->
+ VarAndValue = [{sysUpTime, sys_up_time(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
sys_up_time(get) ->
{value, snmpa:sys_up_time()}.
+
%%-----------------------------------------------------------------
%% This is the instrumentation function for snmpEnableAuthenTraps
%%-----------------------------------------------------------------
+
+snmpEnableAuthenTraps(print) ->
+ snmp_enable_authen_traps(print);
+snmpEnableAuthenTraps(get) ->
+ snmp_enable_authen_traps(get).
+
+
+snmp_enable_authen_traps(print) ->
+ VarAndValue = [{snmpEnableAuthenTraps, snmp_enable_authen_traps(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
snmp_enable_authen_traps(new) ->
snmp_generic:variable_func(new, db(snmpEnableAuthenTraps));
@@ -226,9 +487,19 @@ snmp_enable_authen_traps(get) ->
snmp_enable_authen_traps(set, NewVal) ->
snmp_generic:variable_func(set, NewVal, db(snmpEnableAuthenTraps)).
+
%%-----------------------------------------------------------------
-%% This is the instrumentation function for sysObjectId
+%% This is the instrumentation function for sysObjectID
%%-----------------------------------------------------------------
+sysObjectID(print) ->
+ sys_object_id(print);
+sysObjectID(get) ->
+ sys_object_id(get).
+
+sys_object_id(print) ->
+ VarAndValue = [{sysObjectID, sys_object_id(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
sys_object_id(new) ->
snmp_generic:variable_func(new, db(sysObjectID));
@@ -241,6 +512,7 @@ sys_object_id(get) ->
sys_object_id(set, NewVal) ->
snmp_generic:variable_func(set, NewVal, db(sysObjectID)).
+
%%-----------------------------------------------------------------
%% This is a dummy instrumentation function for objects like
%% snmpTrapOID, that is accessible-for-notify, with different
@@ -249,6 +521,7 @@ sys_object_id(set, NewVal) ->
%%-----------------------------------------------------------------
dummy(_Op) -> ok.
+
%%-----------------------------------------------------------------
%% This is the instrumentation function for snmpSetSerialNo.
%% It is always volatile.
diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl
index 3c32d1f59f..270a5fd5b6 100644
--- a/lib/snmp/src/agent/snmp_target_mib.erl
+++ b/lib/snmp/src/agent/snmp_target_mib.erl
@@ -511,6 +511,10 @@ set_target_engine_id(TargetAddrName, EngineId) ->
%%-----------------------------------------------------------------
%% Instrumentation Functions
%%-----------------------------------------------------------------
+snmpTargetSpinLock(print) ->
+ VarAndValue = [{snmpTargetSpinLock, snmpTargetSpinLock(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
snmpTargetSpinLock(new) ->
snmp_generic:variable_func(new, {snmpTargetSpinLock, volatile}),
{A1,A2,A3} = erlang:now(),
@@ -591,12 +595,9 @@ snmpTargetAddrTable(print) ->
?'snmpTargetAddrRowStatus_active' -> active;
_ -> undefined
end,
- Prefix,
- element(?snmpTargetAddrEngineId, Row),
- Prefix,
- element(?snmpTargetAddrTMask, Row),
- Prefix,
- element(?snmpTargetAddrMMS, Row)]))
+ Prefix, element(?snmpTargetAddrEngineId, Row),
+ Prefix, element(?snmpTargetAddrTMask, Row),
+ Prefix, element(?snmpTargetAddrMMS, Row)]))
end,
snmpa_mib_lib:print_table(Table, DB, FOI, PrintRow);
%% Op == new | delete
diff --git a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
index f40bb1a5b9..69cebc858b 100644
--- a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
+++ b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
@@ -26,6 +26,12 @@
table_next/2,
is_engine_id_known/1, get_user/2, get_user_from_security_name/2,
mk_key_change/3, mk_key_change/5, extract_new_key/3, mk_random/1]).
+-export([usmStatsUnsupportedSecLevels/1,
+ usmStatsNotInTimeWindows/1,
+ usmStatsUnknownUserNames/1,
+ usmStatsUnknownEngineIDs/1,
+ usmStatsWrongDigests/1,
+ usmStatsDecryptionErrors/1]).
-export([add_user/1, add_user/13, delete_user/1]).
%% Internal
@@ -303,6 +309,54 @@ gc_tabs() ->
%%-----------------------------------------------------------------
%% Counter functions
%%-----------------------------------------------------------------
+
+usmStatsUnsupportedSecLevels(print) ->
+ VarAndValue = [{usmStatsUnsupportedSecLevels,
+ usmStatsUnsupportedSecLevels(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsUnsupportedSecLevels(get) ->
+ get_counter(usmStatsUnsupportedSecLevels).
+
+usmStatsNotInTimeWindows(print) ->
+ VarAndValue = [{usmStatsNotInTimeWindows, usmStatsNotInTimeWindows(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsNotInTimeWindows(get) ->
+ get_counter(usmStatsNotInTimeWindows).
+
+usmStatsUnknownUserNames(print) ->
+ VarAndValue = [{usmStatsUnknownUserNames, usmStatsUnknownUserNames(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsUnknownUserNames(get) ->
+ get_counter(usmStatsUnknownUserNames).
+
+usmStatsUnknownEngineIDs(print) ->
+ VarAndValue = [{usmStatsUnknownEngineIDs, usmStatsUnknownEngineIDs(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsUnknownEngineIDs(get) ->
+ get_counter(usmStatsUnknownEngineIDs).
+
+usmStatsWrongDigests(print) ->
+ VarAndValue = [{usmStatsWrongDigests, usmStatsWrongDigests(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsWrongDigests(get) ->
+ get_counter(usmStatsWrongDigests).
+
+usmStatsDecryptionErrors(print) ->
+ VarAndValue = [{usmStatsDecryptionErrors, usmStatsDecryptionErrors(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsDecryptionErrors(get) ->
+ get_counter(usmStatsDecryptionErrors).
+
+
+get_counter(Name) ->
+ case (catch ets:lookup(snmp_agent_table, Name)) of
+ [{_, Val}] ->
+ {value, Val};
+ _ ->
+ genErr
+ end.
+
+
init_vars() -> lists:map(fun maybe_create_var/1, vars()).
maybe_create_var(Var) ->
@@ -323,6 +377,7 @@ vars() ->
usmStatsDecryptionErrors
].
+
%%-----------------------------------------------------------------
%% API functions
%%-----------------------------------------------------------------
@@ -374,6 +429,11 @@ get_user_from_security_name(EngineID, SecName) ->
%%-----------------------------------------------------------------
%% Instrumentation Functions
%%-----------------------------------------------------------------
+
+usmUserSpinLock(print) ->
+ VarAndValue = [{usmUserSpinLock, usmUserSpinLock(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
usmUserSpinLock(new) ->
snmp_generic:variable_func(new, {usmUserSpinLock, volatile}),
{A1,A2,A3} = erlang:now(),
diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
index 657207b36e..3e5091a555 100644
--- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
+++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
@@ -133,7 +133,6 @@ check_vacm({vacmSecurityToGroup, SecModel, SecName, GroupName}) ->
{ok, SecM} = snmp_conf:check_sec_model(SecModel, []),
snmp_conf:check_string(SecName),
snmp_conf:check_string(GroupName),
-
Vacm = {SecM, SecName, GroupName,
?'StorageType_nonVolatile', ?'RowStatus_active'},
{ok, {vacmSecurityToGroup, Vacm}};
@@ -181,15 +180,22 @@ init_tabs(Sec2Group, Access, View) ->
snmpa_local_db:table_delete(db(vacmSecurityToGroupTable)),
snmpa_local_db:table_create(db(vacmSecurityToGroupTable)),
init_sec2group_table(Sec2Group),
+
+ ?vdebug("create vacm access table",[]),
+ snmpa_vacm:cleanup(),
init_access_table(Access),
+
?vdebug("create vacm view-tree-family table",[]),
snmpa_local_db:table_delete(db(vacmViewTreeFamilyTable)),
snmpa_local_db:table_create(db(vacmViewTreeFamilyTable)),
- init_view_table(View).
+ init_view_table(View),
+
+ ?vdebug("table(s) initiated",[]),
+ ok.
init_sec2group_table([Row | T]) ->
-% ?vtrace("init security-to-group table: "
-% "~n Row: ~p",[Row]),
+%% ?vtrace("init security-to-group table: "
+%% "~n Row: ~p",[Row]),
Key1 = element(1, Row),
Key2 = element(2, Row),
Key = [Key1, length(Key2) | Key2],
@@ -198,12 +204,12 @@ init_sec2group_table([Row | T]) ->
init_sec2group_table([]) -> true.
init_access_table([{GN, Prefix, Model, Level, Row} | T]) ->
-% ?vtrace("init access table: "
-% "~n GN: ~p"
-% "~n Prefix: ~p"
-% "~n Model: ~p"
-% "~n Level: ~p"
-% "~n Row: ~p",[GN, Prefix, Model, Level, Row]),
+%% ?vtrace("init access table: "
+%% "~n GN: ~p"
+%% "~n Prefix: ~p"
+%% "~n Model: ~p"
+%% "~n Level: ~p"
+%% "~n Row: ~p",[GN, Prefix, Model, Level, Row]),
Key = [length(GN) | GN] ++ [length(Prefix) | Prefix] ++ [Model, Level],
snmpa_vacm:insert([{Key, Row}], false),
init_access_table(T);
@@ -211,8 +217,8 @@ init_access_table([]) ->
snmpa_vacm:dump_table().
init_view_table([Row | T]) ->
-% ?vtrace("init view table: "
-% "~n Row: ~p",[Row]),
+%% ?vtrace("init view table: "
+%% "~n Row: ~p",[Row]),
Key1 = element(1, Row),
Key2 = element(2, Row),
Key = [length(Key1) | Key1] ++ [length(Key2) | Key2],
@@ -348,6 +354,49 @@ vacmContextTable(Op, Arg1, Arg2) ->
snmp_framework_mib:intContextTable(Op, Arg1, Arg2).
+vacmSecurityToGroupTable(print) ->
+ Table = vacmSecurityToGroupTable,
+ DB = db(Table),
+ FOI = foi(Table),
+ PrintRow =
+ fun(Prefix, Row) ->
+ lists:flatten(
+ io_lib:format("~sSecurityModel: ~p (~w)"
+ "~n~sSecurityName: ~p"
+ "~n~sGroupName: ~p"
+ "~n~sStorageType: ~p (~w)"
+ "~n~sStatus: ~p (~w)",
+ [Prefix, element(?vacmSecurityModel, Row),
+ case element(?vacmSecurityModel, Row) of
+ ?SEC_ANY -> any;
+ ?SEC_V1 -> v1;
+ ?SEC_V2C -> v2c;
+ ?SEC_USM -> usm;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmSecurityName, Row),
+ Prefix, element(?vacmGroupName, Row),
+ Prefix, element(?vacmSecurityToGroupStorageType, Row),
+ case element(?vacmSecurityToGroupStorageType, Row) of
+ ?'vacmSecurityToGroupStorageType_readOnly' -> readOnly;
+ ?'vacmSecurityToGroupStorageType_permanent' -> permanent;
+ ?'vacmSecurityToGroupStorageType_nonVolatile' -> nonVolatile;
+ ?'vacmSecurityToGroupStorageType_volatile' -> volatile;
+ ?'vacmSecurityToGroupStorageType_other' -> other;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmSecurityToGroupStatus, Row),
+ case element(?vacmSecurityToGroupStatus, Row) of
+ ?'vacmSecurityToGroupStatus_destroy' -> destroy;
+ ?'vacmSecurityToGroupStatus_createAndWait' -> createAndWait;
+ ?'vacmSecurityToGroupStatus_createAndGo' -> createAndGo;
+ ?'vacmSecurityToGroupStatus_notReady' -> notReady;
+ ?'vacmSecurityToGroupStatus_notInService' -> notInService;
+ ?'vacmSecurityToGroupStatus_active' -> active;
+ _ -> undefined
+ end]))
+ end,
+ snmpa_mib_lib:print_table(Table, DB, FOI, PrintRow);
vacmSecurityToGroupTable(Op) ->
snmp_generic:table_func(Op, db(vacmSecurityToGroupTable)).
@@ -402,13 +451,13 @@ verify_vacmSecurityToGroupTable_cols([{Col, Val0}|Cols], Acc) ->
verify_vacmSecurityToGroupTable_col(?vacmSecurityModel, Model) ->
case Model of
any -> ?SEC_ANY;
- v1 -> ?SEC_ANY;
- v2c -> ?SEC_ANY;
- usm -> ?SEC_ANY;
+ v1 -> ?SEC_V1;
+ v2c -> ?SEC_V2C;
+ usm -> ?SEC_USM;
?SEC_ANY -> ?SEC_ANY;
- ?SEC_V1 -> ?SEC_ANY;
- ?SEC_V2C -> ?SEC_ANY;
- ?SEC_USM -> ?SEC_ANY;
+ ?SEC_V1 -> ?SEC_V1;
+ ?SEC_V2C -> ?SEC_V2C;
+ ?SEC_USM -> ?SEC_USM;
_ ->
?vlog("verification of vacmSecurityModel(~w) ~p failed",
[?vacmSecurityModel, Model]),
@@ -445,6 +494,49 @@ verify_vacmSecurityToGroupTable_col(_, Val) ->
%% {RowIndex, {Col4, Col5, ..., Col9}}
%%
%%-----------------------------------------------------------------
+vacmAccessTable(print) ->
+ %% M�ste jag g�ra om alla entrien till {RowIdx, Row}?
+ TableInfo = get_table(vacmAccessTable),
+ PrintRow =
+ fun(Prefix, Row) ->
+ lists:flatten(
+ io_lib:format("~sContextMatch: ~p (~w)"
+ "~n~sReadViewName: ~p"
+ "~n~sWriteViewName: ~p"
+ "~n~sNotifyViewName: ~p"
+ "~n~sStorageType: ~p (~w)"
+ "~n~sStatus: ~p (~w)",
+ [Prefix, element(?vacmAccessContextMatch-3, Row),
+ case element(?vacmAccessContextMatch-3, Row) of
+ ?vacmAccessContextMatch_exact -> exact;
+ ?vacmAccessContextMatch_prefix -> prefix;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmAccessReadViewName-3, Row),
+ Prefix, element(?vacmAccessWriteViewName-3, Row),
+ Prefix, element(?vacmAccessNotifyViewName-3, Row),
+ Prefix, element(?vacmAccessStorageType-3, Row),
+ case element(?vacmAccessStorageType-3, Row) of
+ ?vacmAccessStorageType_other -> other ;
+ ?vacmAccessStorageType_volatile -> volatile;
+ ?vacmAccessStorageType_nonVolatile -> nonVolatile;
+ ?vacmAccessStorageType_permanent -> permanent;
+ ?vacmAccessStorageType_readOnly -> readOnly;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmAccessStatus-3, Row),
+ case element(?vacmAccessStatus-3, Row) of
+ ?vacmAccessStatus_destroy -> destroy;
+ ?vacmAccessStatus_createAndWait -> createAndWait;
+ ?vacmAccessStatus_createAndGo -> createAndGo;
+ ?vacmAccessStatus_notReady -> notReady;
+ ?vacmAccessStatus_notInService -> notInService;
+ ?vacmAccessStatus_active -> active;
+ _ -> undefined
+ end
+ ]))
+ end,
+ snmpa_mib_lib:print_table(vacmAccessTable, {ok, TableInfo}, PrintRow);
vacmAccessTable(_Op) ->
ok.
vacmAccessTable(get, RowIndex, Cols) ->
@@ -540,24 +632,24 @@ verify_vacmAccessTable_col(?vacmAccessContextPrefix, Pref) ->
verify_vacmAccessTable_col(?vacmAccessSecurityModel, Model) ->
case Model of
any -> ?SEC_ANY;
- v1 -> ?SEC_ANY;
- v2c -> ?SEC_ANY;
- usm -> ?SEC_ANY;
+ v1 -> ?SEC_V1;
+ v2c -> ?SEC_V2C;
+ usm -> ?SEC_USM;
?SEC_ANY -> ?SEC_ANY;
- ?SEC_V1 -> ?SEC_ANY;
- ?SEC_V2C -> ?SEC_ANY;
- ?SEC_USM -> ?SEC_ANY;
+ ?SEC_V1 -> ?SEC_V1;
+ ?SEC_V2C -> ?SEC_V2C;
+ ?SEC_USM -> ?SEC_USM;
_ ->
wrongValue(?vacmAccessSecurityModel)
end;
verify_vacmAccessTable_col(?vacmAccessSecurityLevel, Level) ->
case Level of
- noAuthNoPriv -> 1;
- authNoPriv -> 2;
- authPriv -> 3;
- 1 -> 1;
- 2 -> 2;
- 3 -> 3;
+ noAuthNoPriv -> ?vacmAccessSecurityLevel_noAuthNoPriv;
+ authNoPriv -> ?vacmAccessSecurityLevel_authNoPriv;
+ authPriv -> ?vacmAccessSecurityLevel_authPriv;
+ ?vacmAccessSecurityLevel_noAuthNoPriv -> ?vacmAccessSecurityLevel_noAuthNoPriv;
+ ?vacmAccessSecurityLevel_authNoPriv -> ?vacmAccessSecurityLevel_authNoPriv;
+ ?vacmAccessSecurityLevel_authPriv -> ?vacmAccessSecurityLevel_authPriv;
_ -> wrongValue(?vacmAccessSecurityLevel)
end;
verify_vacmAccessTable_col(?vacmAccessContextMatch, Match) ->
@@ -664,6 +756,7 @@ do_get_next(RowIndex, Cols) ->
end
end.
+
%%-----------------------------------------------------------------
%% Functions to manipulate vacmAccessRows.
%%-----------------------------------------------------------------
@@ -696,29 +789,76 @@ split_cols([Col | Cols], PreCols) when Col =< 3 ->
split_cols(Cols, PreCols) ->
{PreCols, Cols}.
+vacmViewSpinLock(print) ->
+ VarAndValue = [{vacmViewSpinLock, vacmViewSpinLock(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
vacmViewSpinLock(new) ->
- snmp_generic:variable_func(new, {vacmViewSpinLock, volatile}),
+ snmp_generic:variable_func(new, volatile_db(vacmViewSpinLock)),
{A1,A2,A3} = erlang:now(),
random:seed(A1,A2,A3),
Val = random:uniform(2147483648) - 1,
- snmp_generic:variable_func(set, Val, {vacmViewSpinLock, volatile});
+ snmp_generic:variable_func(set, Val, volatile_db(vacmViewSpinLock));
vacmViewSpinLock(delete) ->
ok;
vacmViewSpinLock(get) ->
- snmp_generic:variable_func(get, {vacmViewSpinLock, volatile}).
+ snmp_generic:variable_func(get, volatile_db(vacmViewSpinLock)).
vacmViewSpinLock(is_set_ok, NewVal) ->
- case snmp_generic:variable_func(get, {vacmViewSpinLock, volatile}) of
+ case snmp_generic:variable_func(get, volatile_db(vacmViewSpinLock)) of
{value, NewVal} -> noError;
_ -> inconsistentValue
end;
vacmViewSpinLock(set, NewVal) ->
snmp_generic:variable_func(set, (NewVal + 1) rem 2147483648,
- {vacmViewSpinLock, volatile}).
-
-
+ volatile_db(vacmViewSpinLock)).
+
+
+vacmViewTreeFamilyTable(print) ->
+ Table = vacmViewTreeFamilyTable,
+ DB = db(Table),
+ FOI = foi(Table),
+ PrintRow =
+ fun(Prefix, Row) ->
+ lists:flatten(
+ io_lib:format("~sViewName: ~p"
+ "~n~sSubtree: ~p"
+ "~n~sMask: ~p"
+ "~n~sType: ~p (~w)"
+ "~n~sStorageType: ~p (~w)"
+ "~n~sStatus: ~p (~w)",
+ [Prefix, element(?vacmViewTreeFamilyViewName, Row),
+ Prefix, element(?vacmViewTreeFamilySubtree, Row),
+ Prefix, element(?vacmViewTreeFamilyMask, Row),
+ Prefix, element(?vacmViewTreeFamilyType, Row),
+ case element(?vacmViewTreeFamilyType, Row) of
+ ?vacmViewTreeFamilyType_included -> included;
+ ?vacmViewTreeFamilyType_excluded -> excluded;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmViewTreeFamilyStorageType, Row),
+ case element(?vacmViewTreeFamilyStorageType, Row) of
+ ?vacmViewTreeFamilyStorageType_readOnly -> readOnly;
+ ?vacmViewTreeFamilyStorageType_permanent -> permanent;
+ ?vacmViewTreeFamilyStorageType_nonVolatile -> nonVolatile;
+ ?vacmViewTreeFamilyStorageType_volatile -> volatile;
+ ?vacmViewTreeFamilyStorageType_other -> other;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmViewTreeFamilyStatus, Row),
+ case element(?vacmViewTreeFamilyStatus, Row) of
+ ?vacmViewTreeFamilyStatus_destroy -> destroy;
+ ?vacmViewTreeFamilyStatus_createAndWait -> createAndWait;
+ ?vacmViewTreeFamilyStatus_createAndGo -> createAndGo;
+ ?vacmViewTreeFamilyStatus_notReady -> notReady;
+ ?vacmViewTreeFamilyStatus_notInService -> notInService;
+ ?vacmViewTreeFamilyStatus_active -> active;
+ _ -> undefined
+ end]))
+ end,
+ snmpa_mib_lib:print_table(Table, DB, FOI, PrintRow);
vacmViewTreeFamilyTable(Op) ->
snmp_generic:table_func(Op, db(vacmViewTreeFamilyTable)).
vacmViewTreeFamilyTable(get_next, RowIndex, Cols) ->
@@ -795,7 +935,25 @@ table_next(Name, RestOid) ->
snmp_generic:table_next(db(Name), RestOid).
-db(X) -> snmpa_agent:db(X).
+get_table(vacmAccessTable) ->
+ do_get_vacmAccessTable([], []).
+
+do_get_vacmAccessTable(Key0, Acc) ->
+ case snmpa_vacm:get_next_row(Key0) of
+ {Key, _Row} = Entry ->
+ do_get_vacmAccessTable(Key, [Entry | Acc]);
+ false ->
+ lists:reverse(Acc)
+ end.
+
+
+%%-----------------------------------------------------------------
+%% Wrappers
+%%-----------------------------------------------------------------
+
+db(X) -> snmpa_agent:db(X).
+volatile_db(X) -> {X, volatile}.
+
fa(vacmSecurityToGroupTable) -> ?vacmGroupName;
fa(vacmViewTreeFamilyTable) -> ?vacmViewTreeFamilyMask.
diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl
index 87b191caed..22fbd33add 100644
--- a/lib/snmp/src/agent/snmpa.erl
+++ b/lib/snmp/src/agent/snmpa.erl
@@ -105,6 +105,8 @@
set_request_limit/1, set_request_limit/2
]).
+-export([print_mib_info/0, print_mib_tables/0, print_mib_variables/0]).
+
-include("snmpa_atl.hrl").
-define(EXTRA_INFO, undefined).
@@ -283,6 +285,186 @@ whereis_mib(Agent, Mib) when is_atom(Mib) ->
%% -
+mibs_info() ->
+ [
+ {snmp_standard_mib,
+ [],
+ [
+ sysDescr,
+ sysObjectID,
+ sysContact,
+ sysName,
+ sysLocation,
+ sysServices,
+ snmpEnableAuthenTraps,
+ sysUpTime,
+ snmpInPkts,
+ snmpOutPkts,
+ snmpInBadVersions,
+ snmpInBadCommunityNames,
+ snmpInBadCommunityUses,
+ snmpInASNParseErrs,
+ snmpInTooBigs,
+ snmpInNoSuchNames,
+ snmpInBadValues,
+ snmpInReadOnlys,
+ snmpInGenErrs,
+ snmpInTotalReqVars,
+ snmpInTotalSetVars,
+ snmpInGetRequests,
+ snmpInSetRequests,
+ snmpInGetNexts,
+ snmpInGetResponses,
+ snmpInTraps,
+ snmpOutTooBigs,
+ snmpOutNoSuchNames,
+ snmpOutBadValues,
+ snmpOutGenErrs,
+ snmpOutGetRequests,
+ snmpOutSetRequests,
+ snmpOutGetNexts,
+ snmpOutGetResponses,
+ snmpOutTraps
+ ]
+ },
+ {snmp_framework_mib,
+ [
+ ],
+ [
+ snmpEngineID,
+ snmpEngineBoots,
+ snmpEngineTime,
+ snmpEngineMaxMessageSize
+ ]
+ },
+ {snmp_view_based_acm_mib,
+ [
+ vacmAccessTable,
+ vacmSecurityToGroupTable,
+ vacmViewTreeFamilyTable
+ ],
+ [
+ vacmViewSpinLock
+ ]
+ },
+ {snmp_target_mib,
+ [
+ snmpTargetAddrTable,
+ snmpTargetParamsTable
+ ],
+ [
+ snmpTargetSpinLock
+ ]
+ },
+ {snmp_community_mib,
+ [
+ snmpCommunityTable
+ ],
+ []
+ },
+ {snmp_notification_mib,
+ [
+ snmpNotifyTable
+ ],
+ []},
+ {snmp_user_based_sm_mib,
+ [
+ usmUserTable
+ ],
+ [
+ usmUserSpinLock,
+ usmStatsUnsupportedSecLevels,
+ usmStatsNotInTimeWindows,
+ usmStatsUnknownUserNames,
+ usmStatsUnknownEngineIDs,
+ usmStatsWrongDigests,
+ usmStatsDecryptionErrors
+ ]
+ }
+ ].
+
+print_mib_info() ->
+ MibsInfo = mibs_info(),
+ print_mib_info(MibsInfo).
+
+print_mib_info([]) ->
+ io:format("~n", []),
+ ok;
+print_mib_info([{Mod, Tables, Variables} | MibsInfo]) ->
+ io:format("~n** ~s ** ~n~n", [make_pretty_mib(Mod)]),
+ print_mib_variables2(Mod, Variables),
+ print_mib_tables2(Mod, Tables),
+ io:format("~n", []),
+ print_mib_info(MibsInfo).
+
+
+print_mib_tables() ->
+ Tables = [{Mod, Tabs} || {Mod, Tabs, _Vars} <- mibs_info()],
+ print_mib_tables(Tables).
+
+print_mib_tables([]) ->
+ ok;
+print_mib_tables([{Mod, Tabs}|MibTabs])
+ when is_atom(Mod) andalso is_list(Tabs) ->
+ print_mib_tables(Mod, Tabs),
+ print_mib_tables(MibTabs);
+print_mib_tables([_|MibTabs]) ->
+ print_mib_tables(MibTabs).
+
+print_mib_tables(_Mod, [] = _Tables) ->
+ ok;
+print_mib_tables(Mod, Tables) ->
+ io:format("~n** ~s ** ~n~n", [make_pretty_mib(Mod)]),
+ print_mib_tables2(Mod, Tables),
+ io:format("~n", []).
+
+print_mib_tables2(Mod, Tables) ->
+ [(catch Mod:Table(print)) || Table <- Tables].
+
+
+print_mib_variables() ->
+ Variables = [{Mod, Vars} || {Mod, _Tabs, Vars} <- mibs_info()],
+ print_mib_variables(Variables).
+
+print_mib_variables([]) ->
+ ok;
+print_mib_variables([{Mod, Vars}|MibVars])
+ when is_atom(Mod) andalso is_list(Vars) ->
+ print_mib_variables(Mod, Vars),
+ print_mib_variables(MibVars);
+print_mib_variables([_|MibVars]) ->
+ print_mib_variables(MibVars).
+
+print_mib_variables(_Mod, [] = _Vars) ->
+ ok;
+print_mib_variables(Mod, Vars) ->
+ io:format("~n** ~s ** ~n~n", [make_pretty_mib(Mod)]),
+ print_mib_variables2(Mod, Vars),
+ io:format("~n", []).
+
+print_mib_variables2(Mod, Variables) ->
+ Vars = [{Var, (catch Mod:Var(get))} || Var <- Variables],
+ snmpa_mib_lib:print_variables(Vars).
+
+
+make_pretty_mib(snmp_view_based_acm_mib) ->
+ "SNMP-VIEW-BASED-ACM-MIB";
+make_pretty_mib(snmp_target_mib) ->
+ "SNMP-TARGET-MIB";
+make_pretty_mib(snmp_community_mib) ->
+ "SNMP-COMMUNITY-MIB";
+make_pretty_mib(snmp_notification_mib) ->
+ "SNMP-NOTIFICATION-MIB";
+make_pretty_mib(snmp_user_based_sm_mib) ->
+ "SNMP-USER-BASED-SM-MIB";
+make_pretty_mib(snmp_framework_mib) ->
+ "SNMP-FRAMEWORK-MIB";
+make_pretty_mib(Mod) ->
+ atom_to_list(Mod).
+
+
+%% -
+
mib_of(Oid) ->
snmpa_agent:mib_of(Oid).
diff --git a/lib/snmp/src/agent/snmpa_mib_lib.erl b/lib/snmp/src/agent/snmpa_mib_lib.erl
index 441228b9ee..cb96ff8056 100644
--- a/lib/snmp/src/agent/snmpa_mib_lib.erl
+++ b/lib/snmp/src/agent/snmpa_mib_lib.erl
@@ -19,7 +19,8 @@
-module(snmpa_mib_lib).
-export([table_cre_row/3, table_del_row/2]).
--export([get_table/2, print_table/3, print_table/4, print_tables/1]).
+-export([get_table/2]).
+-export([print_variables/1, print_table/3, print_table/4, print_tables/1]).
-export([gc_tab/3, gc_tab/5]).
-include("SNMPv2-TC.hrl").
@@ -81,31 +82,69 @@ get_table(NameDb, FOI, Oid, Acc) ->
end.
+print_variables(Variables) when is_list(Variables) ->
+ Variables2 = print_variables_prefixify(Variables),
+ lists:foreach(fun({Variable, ValueResult, Prefix}) ->
+ print_variable(Variable, ValueResult, Prefix)
+ end, Variables2),
+ ok.
+
+print_variable(Variable, {value, Val}, Prefix) when is_atom(Variable) ->
+ io:format("~w~s=> ~p~n", [Variable, Prefix, Val]);
+print_variable(Variable, Error, Prefix) when is_atom(Variable) ->
+ io:format("~w~s=> [e] ~p~n", [Variable, Prefix, Error]).
+
+print_variables_prefixify(Variables) ->
+ MaxVarLength = print_variables_maxlength(Variables),
+ print_variables_prefixify(Variables, MaxVarLength, []).
+
+print_variables_prefixify([], _MaxVarLength, Acc) ->
+ lists:reverse(Acc);
+print_variables_prefixify([{Var, Res}|Variables], MaxVarLength, Acc) ->
+ Prefix = make_variable_print_prefix(Var, MaxVarLength),
+ print_variables_prefixify(Variables, MaxVarLength,
+ [{Var, Res, Prefix}|Acc]).
+
+make_variable_print_prefix(Var, MaxVarLength) ->
+ lists:duplicate(MaxVarLength - length(atom_to_list(Var)) + 1, $ ).
+
+print_variables_maxlength(Variables) ->
+ print_variables_maxlength(Variables, 0).
+
+print_variables_maxlength([], MaxLength) ->
+ MaxLength;
+print_variables_maxlength([{Var, _}|Variables], MaxLength) when is_atom(Var) ->
+ VarLen = length(atom_to_list(Var)),
+ if
+ VarLen > MaxLength ->
+ print_variables_maxlength(Variables, VarLen);
+ true ->
+ print_variables_maxlength(Variables, MaxLength)
+ end.
+
+
print_tables(Tables) when is_list(Tables) ->
lists:foreach(fun({Table, DB, FOI, PrintRow}) ->
print_table(Table, DB, FOI, PrintRow)
end, Tables),
ok.
-%% print_table(Table, DB, FOI, PrintRow) ->
-%% TableInfo = get_table(DB(Table), FOI(Table)),
-%% print_table(Table, TableInfo, PrintRow),
-%% ok.
-
print_table(Table, DB, FOI, PrintRow) ->
TableInfo = get_table(DB, FOI),
print_table(Table, TableInfo, PrintRow).
print_table(Table, TableInfo, PrintRow) when is_function(PrintRow, 2) ->
- io:format("~w => ~n", [Table]),
+ io:format("~w =>", [Table]),
do_print_table(TableInfo, PrintRow).
+do_print_table({ok, [] = _TableInfo}, _PrintRow) ->
+ io:format(" -~n", []);
do_print_table({ok, TableInfo}, PrintRow) when is_function(PrintRow, 2) ->
+ io:format("~n", []),
lists:foreach(fun({RowIdx, Row}) ->
io:format(" ~w => ~n~s~n",
[RowIdx, PrintRow(" ", Row)])
- end, TableInfo),
- io:format("~n", []);
+ end, TableInfo);
do_print_table({error, {invalid_rowindex, BadRowIndex, []}}, _PrintRow) ->
io:format("Error: Bad rowindex ~w~n", [BadRowIndex]);
do_print_table({error, {invalid_rowindex, BadRowIndex, TableInfo}}, PrintRow) ->
diff --git a/lib/snmp/src/agent/snmpa_vacm.erl b/lib/snmp/src/agent/snmpa_vacm.erl
index 2eacea4301..892dc265f1 100644
--- a/lib/snmp/src/agent/snmpa_vacm.erl
+++ b/lib/snmp/src/agent/snmpa_vacm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,7 +21,7 @@
-export([get_mib_view/5]).
-export([init/1, init/2, backup/1]).
-export([delete/1, get_row/1, get_next_row/1, insert/1, insert/2,
- dump_table/0]).
+ cleanup/0, dump_table/0]).
-include("SNMPv2-TC.hrl").
-include("SNMP-VIEW-BASED-ACM-MIB.hrl").
@@ -256,6 +256,11 @@ delete(Key) ->
ets:delete(snmpa_vacm, Key),
dump_table().
+
+cleanup() ->
+ ets:delete_all_objects(snmpa_vacm),
+ dump_table().
+
dump_table(true) ->
dump_table();
dump_table(_) ->
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 2375e3df70..de0e5d6e14 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,43 +22,30 @@
%% ----- U p g r a d e -------------------------------------------------------
[
- {"4.17.1",
+ {"4.18",
[
- {load_module, snmp_community_mib, soft_purge, soft_purge, []},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, []},
- {load_module, snmp_generic, soft_purge, soft_purge, []},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, []},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, []},
- {load_module, snmp_target_mib, soft_purge, soft_purge, []},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
- {load_module, snmpa_conf, soft_purge, soft_purge, []},
- {update, snmpa_target_cache, soft, soft_purge, soft_purge, []},
- {load_module, snmpa_usm, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, []},
- {load_module, snmpm_conf, soft_purge, soft_purge, []},
- {update, snmpm_config, soft, soft_purge, soft_purge, []},
- {load_module, snmpm_usm, soft_purge, soft_purge, []}
- ]
- },
- {"4.17",
- [
- {load_module, snmp_community_mib, soft_purge, soft_purge, []},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, []},
- {load_module, snmp_generic, soft_purge, soft_purge, []},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, []},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, []},
- {load_module, snmp_target_mib, soft_purge, soft_purge, []},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
- {load_module, snmpa_conf, soft_purge, soft_purge, []},
- {update, snmpa_target_cache, soft, soft_purge, soft_purge, []},
- {load_module, snmpa_usm, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, []},
- {load_module, snmpm_conf, soft_purge, soft_purge, []},
- {update, snmpm_config, soft, soft_purge, soft_purge, []},
- {load_module, snmpm_usm, soft_purge, soft_purge, []},
- {load_module, snmpa_net_if, soft_purge, soft_purge, []}
+ {load_module, snmp_misc, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+ {load_module, snmpa, soft_purge, soft_purge,
+ [snmp_community_mib,
+ snmp_framework_mib,
+ snmp_standard_mib,
+ snmp_target_mib,
+ snmp_user_based_sm_mib,
+ snmp_view_based_acm_mib]},
+ {load_module, snmp_community_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib]},
+ {load_module, snmp_framework_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib]},
+ {load_module, snmp_standard_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib]},
+ {load_module, snmp_target_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib]},
+ {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib]},
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib, snmpa_vacm]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}
]
}
],
@@ -66,43 +53,30 @@
%% ------D o w n g r a d e ---------------------------------------------------
[
- {"4.17.1",
- [
- {load_module, snmp_community_mib, soft_purge, soft_purge, []},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, []},
- {load_module, snmp_generic, soft_purge, soft_purge, []},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, []},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, []},
- {load_module, snmp_target_mib, soft_purge, soft_purge, []},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
- {load_module, snmpa_conf, soft_purge, soft_purge, []},
- {update, snmpa_target_cache, soft, soft_purge, soft_purge, []},
- {load_module, snmpa_usm, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, []},
- {load_module, snmpm_conf, soft_purge, soft_purge, []},
- {update, snmpm_config, soft, soft_purge, soft_purge, []},
- {load_module, snmpm_usm, soft_purge, soft_purge, []}
- ]
- },
- {"4.17",
+ {"4.18",
[
- {load_module, snmp_community_mib, soft_purge, soft_purge, []},
- {load_module, snmp_framework_mib, soft_purge, soft_purge, []},
- {load_module, snmp_generic, soft_purge, soft_purge, []},
- {load_module, snmp_notification_mib, soft_purge, soft_purge, []},
- {load_module, snmp_standard_mib, soft_purge, soft_purge, []},
- {load_module, snmp_target_mib, soft_purge, soft_purge, []},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
- {load_module, snmpa_conf, soft_purge, soft_purge, []},
- {update, snmpa_target_cache, soft, soft_purge, soft_purge, []},
- {load_module, snmpa_usm, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, []},
- {load_module, snmpm_conf, soft_purge, soft_purge, []},
- {update, snmpm_config, soft, soft_purge, soft_purge, []},
- {load_module, snmpm_usm, soft_purge, soft_purge, []},
- {load_module, snmpa_net_if, soft_purge, soft_purge, []}
+ {load_module, snmp_misc, soft_purge, soft_purge, []},
+ {load_module, snmpa_vacm, soft_purge, soft_purge, []},
+ {load_module, snmpa, soft_purge, soft_purge,
+ [snmp_community_mib,
+ snmp_framework_mib,
+ snmp_standard_mib,
+ snmp_target_mib,
+ snmp_user_based_sm_mib,
+ snmp_view_based_acm_mib]},
+ {load_module, snmp_community_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib]},
+ {load_module, snmp_framework_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib]},
+ {load_module, snmp_standard_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib]},
+ {load_module, snmp_target_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib]},
+ {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib]},
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
+ [snmpa_mib_lib, snmpa_vacm]},
+ {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}
]
}
]
diff --git a/lib/snmp/src/compile/Makefile b/lib/snmp/src/compile/Makefile
index 4be60e1835..1f1086eae1 100644
--- a/lib/snmp/src/compile/Makefile
+++ b/lib/snmp/src/compile/Makefile
@@ -20,6 +20,7 @@
include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
+BIN = ../../bin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
@@ -44,9 +45,11 @@ RELSYSDIR = $(RELEASE_PATH)/lib/snmp-$(VSN)
include modules.mk
+ESCRIPT_BIN = $(ESCRIPT_SRC:%.src=$(BIN)/%)
+
ERL_FILES = $(MODULES:%=%.erl)
-TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(ESCRIPT_BIN)
GENERATED_PARSER = $(PARSER_MODULE:%=%.erl)
@@ -97,8 +100,12 @@ info:
@echo ""
@echo "EBIN: $(EBIN)"
@echo ""
+ @echo "ESCRIPT_SRC: $(ESCRIPT_SRC)"
+ @echo "ESCRIPT_BIN: $(ESCRIPT_BIN)"
+ @echo ""
@echo ""
+
# ----------------------------------------------------
# Special Build Targets
# ----------------------------------------------------
@@ -107,6 +114,7 @@ parser: $(PARSER_TARGET)
$(GENERATED_PARSER): $(PARSER_SRC)
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -115,9 +123,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)/src
$(INSTALL_DIR) $(RELSYSDIR)/src/compiler
- $(INSTALL_DATA) $(PARSER_SRC) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/compiler
+ $(INSTALL_DATA) $(ESCRIPT_SRC) $(PARSER_SRC) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/compiler
$(INSTALL_DIR) $(RELSYSDIR)/ebin
$(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
+ $(INSTALL_DIR) $(RELSYSDIR)/bin
+ $(INSTALL_SCRIPT) $(ESCRIPT_BIN) $(RELSYSDIR)/bin
release_docs_spec:
diff --git a/lib/snmp/src/compile/depend.mk b/lib/snmp/src/compile/depend.mk
index 75af1bf293..74eb6e0864 100644
--- a/lib/snmp/src/compile/depend.mk
+++ b/lib/snmp/src/compile/depend.mk
@@ -44,3 +44,6 @@ $(EBIN)/snmpc_mib_gram.$(EMULATOR): \
../../include/snmp_types.hrl \
snmpc_mib_gram.erl
+$(BIN)/snmpc: snmpc.src
+ $(PERL) -p -e 's?%VSN%?$(VSN)? ' < $< > $@
+ chmod 755 $@
diff --git a/lib/snmp/src/compile/modules.mk b/lib/snmp/src/compile/modules.mk
index 6365b0e694..ca78e2e6a9 100644
--- a/lib/snmp/src/compile/modules.mk
+++ b/lib/snmp/src/compile/modules.mk
@@ -21,6 +21,9 @@ PARSER_SRC = snmpc_mib_gram.yrl
PARSER_MODULE = $(PARSER_SRC:%.yrl=%)
+ESCRIPT_SRC = \
+ snmpc.src
+
MODULES = \
$(PARSER_MODULE) \
snmpc \
diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl
index a7f2cdc2bc..195c238184 100644
--- a/lib/snmp/src/compile/snmpc.erl
+++ b/lib/snmp/src/compile/snmpc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -112,6 +112,8 @@ compile(FileName) ->
%% description
%% reference
%% imports
+%% agent_capabilities
+%% module_compliance
%% module_identity
%% {module, string()}
%% no_defs
@@ -203,6 +205,10 @@ get_options([imports|Opts], Formats, Args) ->
get_options(Opts, ["~n imports"|Formats], Args);
get_options([module_identity|Opts], Formats, Args) ->
get_options(Opts, ["~n module_identity"|Formats], Args);
+get_options([module_compliance|Opts], Formats, Args) ->
+ get_options(Opts, ["~n module_compliance"|Formats], Args);
+get_options([agent_capabilities|Opts], Formats, Args) ->
+ get_options(Opts, ["~n agent_capabilities"|Formats], Args);
get_options([relaxed_row_name_assign_check|Opts], Formats, Args) ->
get_options(Opts, ["~n relaxed_row_name_assign_check"|Formats], Args);
get_options([_|Opts], Formats, Args) ->
@@ -288,6 +294,10 @@ check_options([imports| T]) ->
check_options(T);
check_options([module_identity| T]) ->
check_options(T);
+check_options([module_compliance| T]) ->
+ check_options(T);
+check_options([agent_capabilities| T]) ->
+ check_options(T);
check_options([relaxed_row_name_assign_check| T]) ->
check_options(T);
check_options([{module, M} | T]) when is_atom(M) ->
@@ -315,6 +325,12 @@ get_description(Options) ->
get_reference(Options) ->
get_bool_option(reference, Options).
+get_agent_capabilities(Options) ->
+ get_bool_option(agent_capabilities, Options).
+
+get_module_compliance(Options) ->
+ get_bool_option(module_compliance, Options).
+
get_relaxed_row_name_assign_check(Options) ->
lists:member(relaxed_row_name_assign_check, Options).
@@ -387,10 +403,12 @@ get_verbosity(Options) ->
init(From, MibFileName, Options) ->
{A,B,C} = now(),
random:seed(A,B,C),
- put(options, Options),
- put(verbosity, get_verbosity(Options)),
- put(description, get_description(Options)),
- put(reference, get_reference(Options)),
+ put(options, Options),
+ put(verbosity, get_verbosity(Options)),
+ put(description, get_description(Options)),
+ put(reference, get_reference(Options)),
+ put(agent_capabilities, get_agent_capabilities(Options)),
+ put(module_compliance, get_module_compliance(Options)),
File = filename:rootname(MibFileName, ".mib"),
put(filename, filename:basename(File ++ ".mib")),
R = case catch c_impl(File) of
@@ -876,12 +894,12 @@ definitions_loop([{#mc_object_type{name = NameOfEntry,
definitions_loop([{#mc_notification{name = TrapName,
status = deprecated}, Line}|T],
- false) ->
+ #dldata{deprecated = false} = Data) ->
?vinfo2("defloop -> notification ~w is deprecated => ignored",
[TrapName], Line),
update_status(TrapName, deprecated),
ensure_macro_imported('NOTIFICATION-TYPE', Line),
- definitions_loop(T, false);
+ definitions_loop(T, Data);
definitions_loop([{#mc_notification{name = TrapName,
status = obsolete}, Line}|T],
@@ -921,10 +939,96 @@ definitions_loop([{#mc_notification{name = TrapName,
snmpc_lib:add_cdata(#cdata.traps, [Notif]),
definitions_loop(T, Data);
-definitions_loop([{#mc_module_compliance{name = Name},Line}|T], Data) ->
- ?vlog2("defloop -> module_compliance:"
- "~n Name: ~p", [Name], Line),
+definitions_loop([{#mc_agent_capabilities{name = Name,
+ status = Status,
+ description = Desc,
+ reference = Ref,
+ modules = Mods,
+ name_assign = {Parent, SubIdx}},Line}|T], Data) ->
+ ?vlog2("defloop -> agent_capabilities ~p:"
+ "~n Status: ~p"
+ "~n Desc: ~p"
+ "~n Ref: ~p"
+ "~n Mods: ~p"
+ "~n Parent: ~p"
+ "~n SubIndex: ~p",
+ [Name, Status, Desc, Ref, Mods, Parent, SubIdx], Line),
+ ensure_macro_imported('AGENT-CAPABILITIES', Line),
+ case get(agent_capabilities) of
+ true ->
+ update_status(Name, Status),
+ snmpc_lib:register_oid(Line, Name, Parent, SubIdx),
+ NewME = snmpc_lib:makeInternalNode2(false, Name),
+ Description = make_description(Desc),
+ Reference =
+ case Ref of
+ undefined ->
+ [];
+ _ ->
+ [{reference, Ref}]
+ end,
+ Modules =
+ case Mods of
+ undefined ->
+ [];
+ [] ->
+ [];
+ _ ->
+ [{modules, Mods}]
+ end,
+ AssocList = Reference ++ Modules,
+ NewME2 = NewME#me{description = Description,
+ assocList = AssocList},
+ snmpc_lib:add_cdata(#cdata.mes, [NewME2]);
+ _ ->
+ ok
+ end,
+ definitions_loop(T, Data);
+
+definitions_loop([{#mc_module_compliance{name = Name,
+ status = Status,
+ description = Desc,
+ reference = Ref,
+ modules = Mods,
+ name_assign = {Parent, SubIdx}},Line}|T], Data) ->
+ ?vlog2("defloop -> module_compliance: ~p"
+ "~n Status: ~p"
+ "~n Desc: ~p"
+ "~n Ref: ~p"
+ "~n Mods: ~p"
+ "~n Parent: ~p"
+ "~n SubIndex: ~p",
+ [Name, Status, Desc, Ref, Mods, Parent, SubIdx], Line),
ensure_macro_imported('MODULE-COMPLIANCE', Line),
+ case get(module_compliance) of
+ true ->
+ update_status(Name, Status),
+ snmpc_lib:register_oid(Line, Name, Parent, SubIdx),
+ NewME = snmpc_lib:makeInternalNode2(false, Name),
+ Description = make_description(Desc),
+ Reference =
+ case Ref of
+ undefined ->
+ [];
+ _ ->
+ [{reference, Ref}]
+ end,
+ Modules =
+ case Mods of
+ undefined ->
+ [];
+ [] ->
+ [];
+ _ ->
+ [{modules, Mods}]
+ end,
+ AssocList = Reference ++ Modules,
+ NewME2 = NewME#me{description = Description,
+ assocList = AssocList},
+ snmpc_lib:add_cdata(#cdata.mes, [NewME2]);
+ _ ->
+ ok
+ end,
definitions_loop(T, Data);
definitions_loop([{#mc_object_group{name = Name,
@@ -1328,22 +1432,26 @@ save(Filename, MibName, Options) ->
parse(FileName) ->
+%% ?vtrace("parse -> start tokenizer for ~p", [FileName]),
case snmpc_tok:start_link(reserved_words(),
[{file, FileName ++ ".mib"},
{forget_stringdata, true}]) of
{error,ReasonStr} ->
snmpc_lib:error(lists:flatten(ReasonStr),[]);
{ok, TokPid} ->
+%% ?vtrace("parse -> tokenizer start, now get tokens", []),
Toks = snmpc_tok:get_all_tokens(TokPid),
+%% ?vtrace("parse -> tokens: ~p", [Toks]),
set_version(Toks),
- %% io:format("parse -> lexical analysis: ~n~p~n", [Toks]),
- %% t("parse -> lexical analysis: ~n~p", [Toks]),
+ %% ?vtrace("parse -> lexical analysis: ~n~p", [Toks]),
CDataArg =
case lists:keysearch(module, 1, get(options)) of
{value, {module, M}} -> {module, M};
_ -> {file, FileName ++ ".funcs"}
end,
put(cdata,snmpc_lib:make_cdata(CDataArg)),
+%% ?vtrace("parse -> stop tokenizer and then do the actual parse",
+%% []),
snmpc_tok:stop(TokPid),
Res = if
is_list(Toks) ->
@@ -1351,7 +1459,7 @@ parse(FileName) ->
true ->
Toks
end,
- %% t("parse -> parsed: ~n~p", [Res]),
+%% ?vtrace("parse -> parsed result: ~n~p", [Res]),
case Res of
{ok, PData} ->
{ok, PData};
@@ -1443,6 +1551,10 @@ reserved_words() ->
'NOTIFICATION-GROUP',
'NOTIFICATIONS',
'MODULE-COMPLIANCE',
+ 'AGENT-CAPABILITIES',
+ 'PRODUCT-RELEASE',
+ 'SUPPORTS',
+ 'INCLUDES',
'MODULE',
'MANDATORY-GROUPS',
'GROUP',
diff --git a/lib/snmp/src/compile/snmpc.hrl b/lib/snmp/src/compile/snmpc.hrl
index eb896cde6b..1c0808d065 100644
--- a/lib/snmp/src/compile/snmpc.hrl
+++ b/lib/snmp/src/compile/snmpc.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -103,16 +103,75 @@
).
+-record(mc_agent_capabilities,
+ {name,
+ product_release,
+ status,
+ description,
+ reference,
+ modules,
+ name_assign
+ }
+ ).
+
+-record(mc_ac_module,
+ {name,
+ groups,
+ variation
+ }
+ ).
+
+-record(mc_ac_object_variation,
+ {name,
+ syntax,
+ write_syntax,
+ access,
+ creation,
+ default_value,
+ description
+ }
+ ).
+
+-record(mc_ac_notification_variation,
+ {name,
+ access,
+ description
+ }
+ ).
+
+
-record(mc_module_compliance,
{name,
status,
description,
reference,
- module,
+ modules,
name_assign
}
).
+-record(mc_mc_compliance_group,
+ {name,
+ description
+ }
+ ).
+
+-record(mc_mc_object,
+ {name,
+ syntax,
+ write_syntax,
+ access,
+ description
+ }
+ ).
+
+-record(mc_mc_module,
+ {name,
+ mandatory,
+ compliance
+ }
+ ).
+
-record(mc_object_group,
{name,
diff --git a/lib/snmp/src/compile/snmpc.src b/lib/snmp/src/compile/snmpc.src
new file mode 100644
index 0000000000..e0734c056e
--- /dev/null
+++ b/lib/snmp/src/compile/snmpc.src
@@ -0,0 +1,381 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% SNMP MIB compiler frontend
+%%
+
+-mode(compile).
+
+-include_lib("kernel/include/file.hrl").
+-include_lib("snmp/include/snmp_types.hrl").
+
+
+-record(state,
+ {
+ version = "%VSN%",
+ mfv,
+ file, % .mib or .bin depending on which are compiled
+ outdir = "./",
+ db = volatile,
+ include_dirs = ["./"],
+ include_lib_dirs = [],
+ deprecated = false,
+ group_check = true,
+ description = false,
+ reference = false,
+ imports = false,
+ module_identity = false,
+ module_compliance = false,
+ agent_capabilities = false,
+ module,
+ no_defaults = false,
+ relaxed_row_name_assigne_check = false,
+ %% The default verbosity (silence) will be filled in
+ %% during argument processing.
+ verbosity,
+ warnings = false
+ }).
+
+
+%% ------------------------------------------------------------------------
+%% Valid arguments:
+%% --o Dir [defaults to "./"]
+%% --i Dir [defaults to "./"]
+%% --il Dir
+%% --sgc
+%% --db DB [defaults to volatile]
+%% --dep
+%% --desc
+%% --ref
+%% --imp
+%% --mi
+%% --mc
+%% --ac
+%% --mod Mod
+%% --nd
+%% --rrnac
+%% --version
+%% --verbosity V
+%% --warnings
+main(Args) when is_list(Args) ->
+ case (catch process_args(Args)) of
+ ok ->
+ usage();
+ {ok, State} when is_record(State, state) ->
+ compile(State);
+ {ok, Str} when is_list(Str) ->
+ io:format("~s~n~n", [Str]),
+ halt(1);
+ {error, ReasonStr} ->
+ usage(ReasonStr)
+ end;
+main(_) ->
+ usage().
+
+compile(State) ->
+ %% io:format("snmpc: ~p~n", [State]),
+ case mk_file(State) of
+ {mib, File} ->
+ Options = mk_mib_options(State),
+ case mib2bin(File, Options) of
+ {ok, _BinFileName} ->
+ ok;
+ {error, Reason} ->
+ io:format("ERROR: Failed compiling mib: "
+ "~n ~p~n", [Reason]),
+ halt(1)
+ end;
+ {bin, File} ->
+ Options = mk_hrl_options(State),
+ case bin2hrl(File, Options) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ io:format("ERROR: Failed generating hrl from mib: "
+ "~n ~p~n", [Reason]),
+ halt(1)
+ end
+ end.
+
+mib2bin(MibFileName, Options) ->
+ snmpc:compile(MibFileName, Options).
+
+bin2hrl(BinFileName, {OutDir, Verbosity}) ->
+ MibName = filename:basename(BinFileName),
+ BinFile = BinFileName ++ ".bin",
+ HrlFile = filename:join(OutDir, MibName) ++ ".hrl",
+ put(verbosity, Verbosity),
+ snmpc_mib_to_hrl:convert(BinFile, HrlFile, MibName).
+
+
+mk_file(#state{file = MIB}) ->
+ DirName = filename:dirname(MIB),
+ case filename:extension(MIB) of
+ ".mib" ->
+ BaseName = filename:basename(MIB, ".mib"),
+ {mib, filename:join(DirName, BaseName)};
+ ".bin" ->
+ BaseName = filename:basename(MIB, ".bin"),
+ {bin, filename:join(DirName, BaseName)};
+ BadExt ->
+ e(lists:flatten(io_lib:format("Unsupported file type: ~s", [BadExt])))
+ end.
+
+mk_mib_options(#state{outdir = OutDir,
+ db = DB,
+ include_dirs = IDs,
+ include_lib_dirs = ILDs,
+ deprecated = Dep,
+ group_check = GC,
+ description = Desc,
+ reference = Ref,
+ imports = Imp,
+ module_identity = MI,
+ module_compliance = MC,
+ agent_capabilities = AC,
+ module = Mod,
+ no_defaults = ND,
+ relaxed_row_name_assigne_check = RRNAC,
+ %% The default verbosity (silence) will be filled in
+ %% during argument processing.
+ verbosity = V,
+ warnings = W}) ->
+ [{outdir, OutDir},
+ {db, DB},
+ {i, IDs},
+ {il, ILDs},
+ {group_check, GC},
+ {verbosity, V},
+ {warnings, W},
+ {deprecated, Dep}] ++
+ if
+ (Mod =/= undefined) ->
+ [{module, Mod}];
+ true ->
+ []
+ end ++
+ maybe_option(ND, no_defs) ++
+ maybe_option(RRNAC, relaxed_row_name_assign_check) ++
+ maybe_option(Desc, description) ++
+ maybe_option(Ref, reference) ++
+ maybe_option(Imp, imports) ++
+ maybe_option(MI, module_identity) ++
+ maybe_option(MC, module_compliance) ++
+ maybe_option(AC, agent_capabilities).
+
+maybe_option(true, Opt) -> [Opt];
+maybe_option(_, _) -> [].
+
+
+mk_hrl_options(#state{outdir = OutDir,
+ verbosity = Verbosity}) ->
+ {OutDir, Verbosity}.
+
+
+process_args([]) ->
+ e("No input file");
+process_args(Args) ->
+ #mib{mib_format_version = MFV} = #mib{},
+ State = #state{},
+ process_args(Args, State#state{mfv = MFV}).
+
+process_args([], #state{verbosity = Verbosity0, file = MIB} = State) ->
+ if
+ (MIB =:= undefined) ->
+ e("No input file");
+ true ->
+ Verbosity =
+ case Verbosity0 of
+ undefined ->
+ silence;
+ _ ->
+ Verbosity0
+ end,
+ IPath = lists:reverse(State#state.include_dirs),
+ IlPath = lists:reverse(State#state.include_lib_dirs),
+ {ok, State#state{verbosity = Verbosity,
+ include_dirs = IPath,
+ include_lib_dirs = IlPath}}
+ end;
+process_args(["--help"|_Args], _State) ->
+ ok;
+process_args(["--version"|_Args], #state{version = Version, mfv = MFV} = _State) ->
+ {ok, lists:flatten(io_lib:format("snmpc ~s (~s)", [Version, MFV]))};
+process_args(["--verbosity", Verbosity0|Args], #state{verbosity = V} = State)
+ when (V =:= undefined) ->
+ Verbosity = list_to_atom(Verbosity0),
+ case lists:member(Verbosity, [trace,debug,log,info,silence]) of
+ true ->
+ process_args(Args, State#state{verbosity = Verbosity});
+ false ->
+ e(lists:flatten(io_lib:format("Unknown verbosity: ~s", [Verbosity0])))
+ end;
+process_args(["--verbosity"|_Args], #state{verbosity = V})
+ when (V =/= undefined) ->
+ e(lists:flatten(io_lib:format("Verbosity already set to ~w", [V])));
+process_args(["--warnings"|Args], State) ->
+ process_args(Args, State#state{warnings = true});
+process_args(["--o", Dir|Args], State) ->
+ case (catch file:read_file_info(Dir)) of
+ {ok, #file_info{type = directory}} ->
+ process_args(Args, State#state{outdir = Dir});
+ {ok, #file_info{type = BadType}} ->
+ e(lists:flatten(io_lib:format("Not a directory: ~p (~w)", [Dir, BadType])));
+ _ ->
+ e(lists:flatten(io_lib:format("Bad directory: ~p", [Dir])))
+ end;
+process_args(["--i", Dir|Args], State) ->
+ case (catch file:read_file_info(Dir)) of
+ {ok, #file_info{type = directory}} ->
+ IPath = [Dir | State#state.include_dirs],
+ process_args(Args, State#state{include_dirs = IPath});
+ {ok, #file_info{type = BadType}} ->
+ e(lists:flatten(io_lib:format("Not a directory: ~p (~w)", [Dir, BadType])));
+ _ ->
+ e(lists:flatten(io_lib:format("Bad directory: ~p", [Dir])))
+ end;
+process_args(["--il", Dir|Args], State) ->
+ case (catch file:read_file_info(Dir)) of
+ {ok, #file_info{type = directory}} ->
+ IlPath = [Dir | State#state.include_lib_dirs],
+ process_args(Args, State#state{include_lib_dirs = IlPath});
+ {ok, #file_info{type = BadType}} ->
+ e(lists:flatten(io_lib:format("Not a directory: ~p (~w)", [Dir, BadType])));
+ _ ->
+ e(lists:flatten(io_lib:format("Bad directory: ~p", [Dir])))
+ end;
+process_args(["--db", DB0|Args], State) ->
+ DB = list_to_atom(DB0),
+ case lists:member(DB, [volatile,persistent,mnesia]) of
+ true ->
+ process_args(Args, State#state{db = DB});
+ false ->
+ e(lists:flatten(io_lib:format("Invalid db: ~s", [DB0])))
+ end;
+process_args(["--dep"|Args], State) ->
+ process_args(Args, State#state{deprecated = true});
+process_args(["--sgc"|Args], State) ->
+ process_args(Args, State#state{group_check = false});
+process_args(["--desc"|Args], State) ->
+ process_args(Args, State#state{description = true});
+process_args(["--ref"|Args], State) ->
+ process_args(Args, State#state{reference = true});
+process_args(["--imp"|Args], State) ->
+ process_args(Args, State#state{imports = true});
+process_args(["--mi"|Args], State) ->
+ process_args(Args, State#state{module_identity = true});
+process_args(["--mod", Module0|Args], #state{module = M} = State)
+ when (M =:= undefined) ->
+ Module = list_to_atom(Module0),
+ process_args(Args, State#state{module = Module});
+process_args(["--mod"|_Args], #state{module = M})
+ when (M =/= undefined) ->
+ e(lists:flatten(io_lib:format("Module already set to ~w", [M])));
+process_args(["--nd"|Args], State) ->
+ process_args(Args, State#state{no_defaults = true});
+process_args(["--rrnac"|Args], State) ->
+ process_args(Args, State#state{relaxed_row_name_assigne_check = true});
+process_args([MIB], State) ->
+ Ext = filename:extension(MIB),
+ if
+ ((Ext =:= ".mib") orelse (Ext =:= ".bin")) ->
+ case (catch file:read_file_info(MIB)) of
+ {ok, #file_info{type = regular}} ->
+ process_args([], State#state{file = MIB});
+ {ok, #file_info{type = BadType}} ->
+ e(lists:flatten(io_lib:format("~s not a file: ~w", [MIB, BadType])));
+ {error, enoent} ->
+ e(lists:flatten(io_lib:format("No such file: ~s", [MIB])));
+ _ ->
+ e(lists:flatten(io_lib:format("Bad file: ~s", [MIB])))
+ end;
+ true ->
+ e(lists:flatten(io_lib:format("Unknown option: ~s", [MIB])))
+ end;
+process_args([Arg|Args], _State) when Args =/= [] ->
+ e(lists:flatten(io_lib:format("Unknown option: ~s", [Arg]))).
+
+usage(ReasonStr) ->
+ io:format("ERROR: ~s~n", [ReasonStr]),
+ usage().
+
+usage() ->
+ io:format("Usage: snmpc [options] MIB.mib|MIB.bin"
+ "~nCompile a MIB (.mib -> .bin) or generate an erlang header "
+ "~nfile from a compiled MIB file (.bin -> .hrl)"
+ "~nOptions:"
+ "~n --help - Prints this info."
+ "~n --version - Prints compiler version."
+ "~n --verbosity <verbosity> - Print debug info."
+ "~n verbosity = trace | debug | log | info | silence"
+ "~n Defaults to silence."
+ "~n --warnings - Print warning messages."
+ "~n --o <output dir> - The output dir."
+ "~n Defaults to current working dir."
+ "~n --i <include dir> - Add this dir to the list of dirs that will be"
+ "~n searched for imported (compiled) MIB files."
+ "~n The current workin dir will always be included. "
+ "~n --il <include_lib dir> - Add this dir to the list of dirs that will be"
+ "~n searched for imported (compiled) MIB files."
+ "~n It assumes that the first element in the dir name"
+ "~n correspond to an OTP application. For example snmp/mibs/"
+ "~n The current workin dir and the <snmp-home>/priv/mibs "
+ "~n are always listed last the includ path. "
+ "~n --db <DB> - Database to used for the default instrumentation."
+ "~n Defaults to volatile."
+ "~n --sgc - This option (skip group check), if present, disables "
+ "~n the \"group check\" of the mib compiler. "
+ "~n That is, should the OBJECT-GROUP and the NOTIFICATION-GROUP "
+ "~n macro(s) be checked for correctness or not. "
+ "~n By default the check is done. "
+ "~n --dep - Keep deprecated definition(s)."
+ "~n If not specified the compiler will ignore"
+ "~n deprecated definitions."
+ "~n --desc - The DESCRIPTION field will be included."
+ "~n --ref - The REFERENCE field will be included."
+ "~n --imp - The IMPORTS field will be included."
+ "~n --mi - The MODULE-IDENTITY field will be included."
+ "~n --mc - The MODULE-COMPLIANCE field will be included."
+ "~n --ac - The AGENT-CAPABILITIES field will be included."
+ "~n --mod <module> - The module which implements all the instrumentation"
+ "~n functions. "
+ "~n The name of all instrumentation functions must"
+ "~n be the same as the corresponding managed object"
+ "~n it implements."
+ "~n --nd - The default instrumentation functions will *not* be used"
+ "~n if a managed object have no instrumentation function. "
+ "~n Instead this will be reported as an error, and the "
+ "~n compilation aborts. "
+ "~n --rrnac - This option, if present, specifies that the row name "
+ "~n assign check shall not be done strictly according to"
+ "~n the SMI (which allows only the value 1). "
+ "~n With this option, all values greater than zero is allowed"
+ "~n (>= 1). This means that the error will be converted to "
+ "~n a warning. "
+ "~n By default it is not included, but if this option is "
+ "~n present it will be. "
+ "~n "
+ "~n", []),
+ halt(1).
+
+
+e(Reason) ->
+ throw({error, Reason}).
+
diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl
index 4490412e84..4f71c47bfa 100644
--- a/lib/snmp/src/compile/snmpc_lib.erl
+++ b/lib/snmp/src/compile/snmpc_lib.erl
@@ -306,7 +306,10 @@ import_mib({{'SNMPv2-TC', ImportsFromMib},Line}) ->
Macros = ['TEXTUAL-CONVENTION'],
import_built_in_loop(ImportsFromMib,Nodes,Types,Macros,'SNMPv2-TC',Line);
import_mib({{'SNMPv2-CONF', ImportsFromMib},Line}) ->
- Macros = ['OBJECT-GROUP','NOTIFICATION-GROUP','MODULE-COMPLIANCE'],
+ Macros = ['OBJECT-GROUP',
+ 'NOTIFICATION-GROUP',
+ 'MODULE-COMPLIANCE',
+ 'AGENT-CAPABILITIES'],
import_built_in_loop(ImportsFromMib,[],[],Macros,'SNMPv2-CONF',Line);
import_mib({{'RFC1155-SMI', ImportsFromMib},Line}) ->
Nodes = [makeInternalNode(internet, [1,3,6,1]),
diff --git a/lib/snmp/src/compile/snmpc_mib_gram.yrl b/lib/snmp/src/compile/snmpc_mib_gram.yrl
index 1957f52936..74b9ddaa25 100644
--- a/lib/snmp/src/compile/snmpc_mib_gram.yrl
+++ b/lib/snmp/src/compile/snmpc_mib_gram.yrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -59,6 +59,7 @@ newtypename
objectidentifier
objectname
objecttypev1
+prodrel
range_num
referpart
size
@@ -79,7 +80,7 @@ revisions
listofdefinitionsv2
mibid
last_updated
-oranization
+organization
contact_info
revision
revision_string
@@ -101,19 +102,31 @@ textualconvention
objectgroup
notificationgroup
modulecompliance
-modulepart
-modules
-module
-modulenamepart
-mandatorypart
-compliancepart
-compliances
-compliance
-compliancegroup
-object
+mc_modulepart
+mc_modules
+mc_module
+mc_modulenamepart
+mc_mandatorypart
+mc_compliancepart
+mc_compliances
+mc_compliance
+mc_compliancegroup
+mc_object
+mc_accesspart
+agentcapabilities
+ac_status
+ac_modulepart
+ac_modules
+ac_module
+ac_modulenamepart
+ac_variationpart
+ac_variations
+ac_variation
+ac_accesspart
+ac_access
+ac_creationpart
syntaxpart
writesyntaxpart
-accesspart
fsyntax
defbitsvalue
defbitsnames
@@ -161,6 +174,12 @@ integer variable atom string quote '{' '}' '::=' ':' '=' ',' '.' '(' ')' ';' '|'
'CONTACT-INFO'
'MODULE-IDENTITY'
'NOTIFICATION-TYPE'
+'PRODUCT-RELEASE'
+'AGENT-CAPABILITIES'
+'INCLUDES'
+'SUPPORTS'
+'VARIATION'
+'CREATION-REQUIRES'
'MODULE-COMPLIANCE'
'OBJECT-GROUP'
'NOTIFICATION-GROUP'
@@ -212,8 +231,8 @@ mib -> mibname 'DEFINITIONS' implies 'BEGIN'
defs = Defs}.
v1orv2 -> moduleidentity listofdefinitionsv2 :
- {v2_mib, ['$1'|lists:reverse('$2')]}.
-v1orv2 -> listofdefinitions : {v1_mib, lists:reverse('$1')}.
+ {v2_mib, ['$1'|lreverse(v1orv2_mod, '$2')]}.
+v1orv2 -> listofdefinitions : {v1_mib, lreverse(v1orv2_list, '$1')}.
definition -> objectidentifier : '$1'.
definition -> objecttypev1 : '$1'.
@@ -231,7 +250,7 @@ imports -> imports_from_one_mib : ['$1'].
imports -> imports_from_one_mib imports : ['$1' | '$2'].
imports_from_one_mib -> listofimports 'FROM' variable :
- {{val('$3'), lists:reverse('$1')}, line_of('$2')}.
+ {{val('$3'), lreverse(imports_from_one_mib, '$1')}, line_of('$2')}.
listofimports -> import_stuff : ['$1'].
listofimports -> listofimports ',' import_stuff : ['$3' | '$1'].
@@ -251,6 +270,8 @@ import_stuff -> 'MODULE-IDENTITY'
: ensure_ver(2,'$1'), {builtin, 'MODULE-IDENTITY'}.
import_stuff -> 'NOTIFICATION-TYPE'
: ensure_ver(2,'$1'), {builtin, 'NOTIFICATION-TYPE'}.
+import_stuff -> 'AGENT-CAPABILITIES'
+ : ensure_ver(2,'$1'), {builtin, 'AGENT-CAPABILITIES'}.
import_stuff -> 'MODULE-COMPLIANCE'
: ensure_ver(2,'$1'), {builtin, 'MODULE-COMPLIANCE'}.
import_stuff -> 'NOTIFICATION-GROUP'
@@ -296,7 +317,7 @@ import_stuff -> 'TAddress'
traptype -> objectname 'TRAP-TYPE' 'ENTERPRISE' objectname varpart
description referpart implies integer :
- Trap = make_trap('$1', '$4', lists:reverse('$5'),
+ Trap = make_trap('$1', '$4', lreverse(traptype, '$5'),
'$6', '$7', val('$9')),
{Trap, line_of('$2')}.
@@ -324,7 +345,7 @@ newtype -> newtypename implies syntax :
{NT, line_of('$2')}.
tableentrydefinition -> newtypename implies 'SEQUENCE' '{' fields '}' :
- Seq = make_sequence('$1', lists:reverse('$5')),
+ Seq = make_sequence('$1', lreverse(tableentrydefinition, '$5')),
{Seq, line_of('$3')}.
% returns: list of {<fieldname>, <asn1_type>}
@@ -408,9 +429,9 @@ variables -> variables ',' objectname : ['$3' | '$1'].
implies -> '::=' : '$1'.
implies -> ':' ':' '=' : w("Sloppy asignment on line ~p", [line_of('$1')]), '$1'.
-descriptionfield -> string : lists:reverse(val('$1')).
+descriptionfield -> string : lreverse(descriptionfield, val('$1')).
descriptionfield -> '$empty' : undefined.
-description -> 'DESCRIPTION' string : lists:reverse(val('$2')).
+description -> 'DESCRIPTION' string : lreverse(description, val('$2')).
description -> '$empty' : undefined.
displaypart -> 'DISPLAY-HINT' string : display_hint('$2') .
@@ -418,7 +439,7 @@ displaypart -> '$empty' : undefined .
% returns: {indexes, undefined}
% | {indexes, IndexList} where IndexList is a list of aliasnames.
-indexpartv1 -> 'INDEX' '{' indextypesv1 '}' : {indexes, lists:reverse('$3')}.
+indexpartv1 -> 'INDEX' '{' indextypesv1 '}' : {indexes, lreverse(indexpartv1, '$3')}.
indexpartv1 -> '$empty' : {indexes, undefined}.
indextypesv1 -> indextypev1 : ['$1'].
@@ -436,14 +457,16 @@ parentintegers -> atom '(' integer ')' parentintegers : [val('$3') | '$5'].
defvalpart -> 'DEFVAL' '{' integer '}' : {defval, val('$3')}.
defvalpart -> 'DEFVAL' '{' atom '}' : {defval, val('$3')}.
defvalpart -> 'DEFVAL' '{' '{' defbitsvalue '}' '}' : {defval, '$4'}.
-defvalpart -> 'DEFVAL' '{' quote atom '}'
- : {defval, make_defval_for_string(line_of('$1'), lists:reverse(val('$3')),
- val('$4'))}.
-defvalpart -> 'DEFVAL' '{' quote variable '}'
- : {defval, make_defval_for_string(line_of('$1'), lists:reverse(val('$3')),
- val('$4'))}.
-defvalpart -> 'DEFVAL' '{' string '}'
- : {defval, lists:reverse(val('$3'))}.
+defvalpart -> 'DEFVAL' '{' quote atom '}' :
+ {defval, make_defval_for_string(line_of('$1'),
+ lreverse(defvalpart_quote_atom, val('$3')),
+ val('$4'))}.
+defvalpart -> 'DEFVAL' '{' quote variable '}' :
+ {defval, make_defval_for_string(line_of('$1'),
+ lreverse(defvalpart_quote_variable, val('$3')),
+ val('$4'))}.
+defvalpart -> 'DEFVAL' '{' string '}' :
+ {defval, lreverse(defvalpart_string, val('$3'))}.
defvalpart -> '$empty' : undefined.
defbitsvalue -> defbitsnames : '$1'.
@@ -461,7 +484,7 @@ accessv1 -> atom: accessv1('$1').
statusv1 -> atom : statusv1('$1').
-referpart -> 'REFERENCE' string : lists:reverse(val('$2')).
+referpart -> 'REFERENCE' string : lreverse(referpart, val('$2')).
referpart -> '$empty' : undefined.
@@ -471,7 +494,7 @@ referpart -> '$empty' : undefined.
%%----------------------------------------------------------------------
moduleidentity -> mibid 'MODULE-IDENTITY'
'LAST-UPDATED' last_updated
- 'ORGANIZATION' oranization
+ 'ORGANIZATION' organization
'CONTACT-INFO' contact_info
'DESCRIPTION' descriptionfield
revisionpart nameassign :
@@ -480,20 +503,20 @@ moduleidentity -> mibid 'MODULE-IDENTITY'
{MI, line_of('$2')}.
mibid -> atom : val('$1').
-last_updated -> string : lists:reverse(val('$1')) .
-oranization -> string : lists:reverse(val('$1')) .
-contact_info -> string : lists:reverse(val('$1')) .
+last_updated -> string : lreverse(last_updated, val('$1')) .
+organization -> string : lreverse(organization, val('$1')) .
+contact_info -> string : lreverse(contact_info, val('$1')) .
revisionpart -> '$empty' : [] .
-revisionpart -> revisions : lists:reverse('$1') .
+revisionpart -> revisions : lreverse(revisionpart, '$1') .
revisions -> revision : ['$1'] .
revisions -> revisions revision : ['$2' | '$1'] .
revision -> 'REVISION' revision_string 'DESCRIPTION' revision_desc :
make_revision('$2', '$4') .
-revision_string -> string : lists:reverse(val('$1')) .
-revision_desc -> string : lists:reverse(val('$1')) .
+revision_string -> string : lreverse(revision_string, val('$1')) .
+revision_desc -> string : lreverse(revision_desc, val('$1')) .
definitionv2 -> objectidentifier : '$1'.
definitionv2 -> objecttypev2 : '$1'.
@@ -505,6 +528,7 @@ definitionv2 -> notification : '$1'.
definitionv2 -> objectgroup : '$1'.
definitionv2 -> notificationgroup : '$1'.
definitionv2 -> modulecompliance : '$1'.
+definitionv2 -> agentcapabilities : '$1'.
listofdefinitionsv2 -> '$empty' : [] .
listofdefinitionsv2 -> listofdefinitionsv2 definitionv2 : ['$2' | '$1'].
@@ -535,46 +559,127 @@ notificationgroup -> objectname 'NOTIFICATION-GROUP' 'NOTIFICATIONS' '{'
{NG, line_of('$2')}.
modulecompliance -> objectname 'MODULE-COMPLIANCE' 'STATUS' statusv2
- description referpart modulepart nameassign :
+ description referpart mc_modulepart nameassign :
+%% io:format("modulecompliance -> "
+%% "~n '$1': ~p"
+%% "~n '$4': ~p"
+%% "~n '$5': ~p"
+%% "~n '$6': ~p"
+%% "~n '$7': ~p"
+%% "~n '$8': ~p"
+%% "~n", ['$1', '$4', '$5', '$6', '$7', '$8']),
MC = make_module_compliance('$1', '$4', '$5', '$6',
'$7', '$8'),
+%% io:format("modulecompliance -> "
+%% "~n MC: ~p"
+%% "~n", [MC]),
{MC, line_of('$2')}.
-modulepart -> '$empty'.
-modulepart -> modules.
-modules -> module.
-modules -> modules module.
+agentcapabilities -> objectname 'AGENT-CAPABILITIES'
+ 'PRODUCT-RELEASE' prodrel
+ 'STATUS' ac_status
+ description referpart ac_modulepart nameassign :
+ AC = make_agent_capabilities('$1', '$4', '$6', '$7',
+ '$8', '$9', '$10'),
+ {AC, line_of('$2')}.
+
+prodrel -> string : lreverse(prodrel, val('$1')).
+
+ac_status -> atom : ac_status('$1').
+
+ac_modulepart -> ac_modules :
+ lreverse(ac_modulepart, '$1').
+ac_modulepart -> '$empty' :
+ [].
+
+ac_modules -> ac_module :
+ ['$1'].
+ac_modules -> ac_module ac_modules :
+ ['$1' | '$2'].
+
+ac_module -> 'SUPPORTS' ac_modulenamepart 'INCLUDES' '{' objects '}' ac_variationpart :
+ make_ac_module('$2', '$5', '$7').
+
+ac_modulenamepart -> mibname : '$1'.
+ac_modulenamepart -> '$empty' : undefined.
+
+ac_variationpart -> '$empty' :
+ [].
+ac_variationpart -> ac_variations :
+ lreverse(ac_variationpart, '$1').
+
+ac_variations -> ac_variation :
+ ['$1'].
+ac_variations -> ac_variation ac_variations :
+ ['$1' | '$2'].
+
+%% ac_variation -> ac_objectvariation.
+%% ac_variation -> ac_notificationvariation.
+
+ac_variation -> 'VARIATION' objectname syntaxpart writesyntaxpart ac_accesspart ac_creationpart defvalpart description :
+ make_ac_variation('$2', '$3', '$4', '$5', '$6', '$7', '$8').
+
+ac_accesspart -> 'ACCESS' ac_access : '$2'.
+ac_accesspart -> '$empty' : undefined.
+
+ac_access -> atom: ac_access('$1').
+
+ac_creationpart -> 'CREATION-REQUIRES' '{' objects '}' :
+ lreverse(ac_creationpart, '$3').
+ac_creationpart -> '$empty' :
+ [].
+
+mc_modulepart -> '$empty' :
+ [].
+mc_modulepart -> mc_modules :
+ lreverse(mc_modulepart, '$1').
+
+mc_modules -> mc_module :
+ ['$1'].
+mc_modules -> mc_module mc_modules :
+ ['$1' | '$2'].
-module -> 'MODULE' modulenamepart mandatorypart compliancepart.
+mc_module -> 'MODULE' mc_modulenamepart mc_mandatorypart mc_compliancepart :
+ make_mc_module('$2', '$3', '$4').
-modulenamepart -> mibname.
-modulenamepart -> '$empty'.
+mc_modulenamepart -> mibname : '$1'.
+mc_modulenamepart -> '$empty' : undefined.
-mandatorypart -> 'MANDATORY-GROUPS' '{' objects '}'.
-mandatorypart -> '$empty'.
+mc_mandatorypart -> 'MANDATORY-GROUPS' '{' objects '}' :
+ lreverse(mc_mandatorypart, '$3').
+mc_mandatorypart -> '$empty' :
+ [].
-compliancepart -> compliances.
-compliancepart -> '$empty'.
+mc_compliancepart -> mc_compliances :
+ lreverse(mc_compliancepart, '$1').
+mc_compliancepart -> '$empty' :
+ [].
-compliances -> compliance.
-compliances -> compliances compliance.
+mc_compliances -> mc_compliance :
+ ['$1'].
+mc_compliances -> mc_compliance mc_compliances :
+ ['$1' | '$2'].
-compliance -> compliancegroup.
-compliance -> object.
+mc_compliance -> mc_compliancegroup :
+ '$1'.
+mc_compliance -> mc_object :
+ '$1'.
-compliancegroup -> 'GROUP' objectname description.
+mc_compliancegroup -> 'GROUP' objectname description :
+ make_mc_compliance_group('$2', '$3').
-object -> 'OBJECT' objectname syntaxpart writesyntaxpart accesspart description.
+mc_object -> 'OBJECT' objectname syntaxpart writesyntaxpart mc_accesspart description :
+ make_mc_object('$2', '$3', '$4', '$5', '$6').
-syntaxpart -> 'SYNTAX' syntax.
-syntaxpart -> '$empty'.
+syntaxpart -> 'SYNTAX' syntax : '$2'.
+syntaxpart -> '$empty' : undefined.
-writesyntaxpart -> 'WRITE-SYNTAX' syntax.
-writesyntaxpart -> '$empty'.
+writesyntaxpart -> 'WRITE-SYNTAX' syntax : '$2'.
+writesyntaxpart -> '$empty' : undefined.
-accesspart -> 'MIN-ACCESS' accessv2.
-accesspart -> '$empty'.
+mc_accesspart -> 'MIN-ACCESS' accessv2 : '$2'.
+mc_accesspart -> '$empty' : undefined.
objecttypev2 -> objectname 'OBJECT-TYPE'
'SYNTAX' syntax
@@ -589,7 +694,7 @@ objecttypev2 -> objectname 'OBJECT-TYPE'
'$11', '$12', Kind, '$15'),
{OT, line_of('$2')}.
-indexpartv2 -> 'INDEX' '{' indextypesv2 '}' : {indexes, lists:reverse('$3')}.
+indexpartv2 -> 'INDEX' '{' indextypesv2 '}' : {indexes, lreverse(indexpartv2, '$3')}.
indexpartv2 -> 'AUGMENTS' '{' entry '}' : {augments, '$3'}.
indexpartv2 -> '$empty' : {indexes, undefined}.
@@ -614,7 +719,7 @@ notification -> objectname 'NOTIFICATION-TYPE' objectspart
Not = make_notification('$1','$3','$5', '$7', '$8', '$9'),
{Not, line_of('$2')}.
-objectspart -> 'OBJECTS' '{' objects '}' : lists:reverse('$3').
+objectspart -> 'OBJECTS' '{' objects '}' : lreverse(objectspart, '$3').
objectspart -> '$empty' : [].
objects -> objectname : ['$1'].
@@ -655,6 +760,14 @@ statusv2(Tok) ->
"syntax error before: " ++ atom_to_list(Else))
end.
+ac_status(Tok) ->
+ case val(Tok) of
+ current -> current;
+ obsolete -> obsolete;
+ Else -> return_error(line_of(Tok),
+ "syntax error before: " ++ atom_to_list(Else))
+ end.
+
accessv1(Tok) ->
case val(Tok) of
'read-only' -> 'read-only';
@@ -676,6 +789,18 @@ accessv2(Tok) ->
"syntax error before: " ++ atom_to_list(Else))
end.
+ac_access(Tok) ->
+ case val(Tok) of
+ 'not-implemented' -> 'not-implemented'; % only for notifications
+ 'accessible-for-notify' -> 'accessible-for-notify';
+ 'read-only' -> 'read-only';
+ 'read-write' -> 'read-write';
+ 'read-create' -> 'read-create';
+ 'write-only' -> 'write-only'; % for backward-compatibility only
+ Else -> return_error(line_of(Tok),
+ "syntax error before: " ++ atom_to_list(Else))
+ end.
+
%% ---------------------------------------------------------------------
%% Various basic record build functions
%% ---------------------------------------------------------------------
@@ -744,14 +869,79 @@ make_notification(Name, Vars, Status, Desc, Ref, NA) ->
reference = Ref,
name_assign = NA}.
-make_module_compliance(Name, Status, Desc, Ref, Mod, NA) ->
+make_agent_capabilities(Name, ProdRel, Status, Desc, Ref, Mods, NA) ->
+ #mc_agent_capabilities{name = Name,
+ product_release = ProdRel,
+ status = Status,
+ description = Desc,
+ reference = Ref,
+ modules = Mods,
+ name_assign = NA}.
+
+make_ac_variation(Name,
+ undefined = _Syntax,
+ undefined = _WriteSyntax,
+ Access,
+ undefined = _Creation,
+ undefined = _DefVal,
+ Desc) ->
+%% io:format("make_ac_variation -> entry with"
+%% "~n Name: ~p"
+%% "~n Access: ~p"
+%% "~n Desc: ~p"
+%% "~n", [Name, Access, Desc]),
+ #mc_ac_notification_variation{name = Name,
+ access = Access,
+ description = Desc};
+
+make_ac_variation(Name, Syntax, WriteSyntax, Access, Creation, DefVal, Desc) ->
+%% io:format("make_ac_variation -> entry with"
+%% "~n Name: ~p"
+%% "~n Syntax: ~p"
+%% "~n WriteSyntax: ~p"
+%% "~n Access: ~p"
+%% "~n Creation: ~p"
+%% "~n DefVal: ~p"
+%% "~n Desc: ~p"
+%% "~n", [Name, Syntax, WriteSyntax, Access, Creation, DefVal, Desc]),
+ #mc_ac_object_variation{name = Name,
+ syntax = Syntax,
+ write_syntax = WriteSyntax,
+ access = Access,
+ creation = Creation,
+ default_value = DefVal,
+ description = Desc}.
+
+make_ac_module(Name, Grps, Var) ->
+ #mc_ac_module{name = Name,
+ groups = Grps,
+ variation = Var}.
+
+
+make_module_compliance(Name, Status, Desc, Ref, Mods, NA) ->
#mc_module_compliance{name = Name,
status = Status,
description = Desc,
reference = Ref,
- module = Mod,
+ modules = Mods,
name_assign = NA}.
+make_mc_module(Name, Mand, Compl) ->
+ #mc_mc_module{name = Name,
+ mandatory = Mand,
+ compliance = Compl}.
+
+make_mc_compliance_group(Name, Desc) ->
+ #mc_mc_compliance_group{name = Name,
+ description = Desc}.
+
+make_mc_object(Name, Syntax, WriteSyntax, Access, Desc) ->
+ #mc_mc_object{name = Name,
+ syntax = Syntax,
+ write_syntax = WriteSyntax,
+ access = Access,
+ description = Desc}.
+
make_object_group(Name, Objs, Status, Desc, Ref, NA) ->
#mc_object_group{name = Name,
objects = Objs,
@@ -968,6 +1158,12 @@ filter_v2imports(_,Type) -> {type, Type}.
w(F, A) ->
?vwarning(F, A).
-%i(F, A) ->
-% io:format("~w:" ++ F ++ "~n", [?MODULE|A]).
+lreverse(_Tag, L) when is_list(L) ->
+ lists:reverse(L);
+lreverse(Tag, X) ->
+ exit({bad_list, Tag, X}).
+
+
+%% i(F, A) ->
+%% io:format("~w:" ++ F ++ "~n", [?MODULE|A]).
diff --git a/lib/snmp/src/compile/snmpc_mib_to_hrl.erl b/lib/snmp/src/compile/snmpc_mib_to_hrl.erl
index 07bd29231b..decc1ce557 100644
--- a/lib/snmp/src/compile/snmpc_mib_to_hrl.erl
+++ b/lib/snmp/src/compile/snmpc_mib_to_hrl.erl
@@ -24,7 +24,8 @@
-include("snmpc_lib.hrl").
%% External exports
--export([convert/1, compile/3]).
+-export([convert/1, convert/3, compile/3]).
+
%%-----------------------------------------------------------------
%% Func: convert/1
diff --git a/lib/snmp/src/compile/snmpc_tok.erl b/lib/snmp/src/compile/snmpc_tok.erl
index 6b99e7ae43..e238b256d0 100644
--- a/lib/snmp/src/compile/snmpc_tok.erl
+++ b/lib/snmp/src/compile/snmpc_tok.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -37,6 +37,8 @@
-export([null_get_line/0, format_error/1, terminate/2, handle_call/3, init/1,
test/0]).
+-include("snmpc_lib.hrl").
+
%%----------------------------------------------------------------------
%% Reserved_words: list of KeyWords. Example: ['IF', 'BEGIN', ..., 'GOTO']
@@ -130,6 +132,10 @@ test() ->
'current','deprecated','not-accessible','obsolete',
'read-create','read-only','read-write', 'IMPORTS', 'FROM',
'MODULE-COMPLIANCE',
+ 'AGENT-CAPABILITIES',
+ 'PRODUCT-RELEASE',
+ 'SUPPORTS',
+ 'INCLUDES',
'DisplayString',
'PhysAddress',
'MacAddress',
@@ -225,6 +231,7 @@ get_all_tokens(Str,Toks) ->
case catch tokenise(Str) of
{error, ErrorInfo} -> {error, ErrorInfo};
{Token, RestChars} when is_tuple(Token) ->
+ %% ?vtrace("get_all_tokens -> Token: ~p", [Token]),
get_all_tokens(RestChars, [Token|Toks])
end.
diff --git a/lib/snmp/test/klas3.erl b/lib/snmp/test/klas3.erl
index a5ce2af8c5..ec78d19dbb 100644
--- a/lib/snmp/test/klas3.erl
+++ b/lib/snmp/test/klas3.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk
index 6a0c3e9481..eacc749b53 100644
--- a/lib/snmp/test/modules.mk
+++ b/lib/snmp/test/modules.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+# Copyright Ericsson AB 2004-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -62,6 +62,8 @@ COMPILER_MIB_FILES = \
OTP8574-MIB
MIB_FILES = \
+ AC-TEST-MIB.mib \
+ MC-TEST-MIB.mib \
OLD-SNMPEA-MIB.mib \
OLD-SNMPEA-MIB-v2.mib \
Klas1.mib \
diff --git a/lib/snmp/test/sa.erl b/lib/snmp/test/sa.erl
index ad3ccce08f..fee50c0e8c 100644
--- a/lib/snmp/test/sa.erl
+++ b/lib/snmp/test/sa.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/snmp.cover b/lib/snmp/test/snmp.cover
index 027dce68c1..a2e7dd978f 100644
--- a/lib/snmp/test/snmp.cover
+++ b/lib/snmp/test/snmp.cover
@@ -1,5 +1,7 @@
%% -*- erlang -*-
-{exclude,
+{incl_app,snmp,details}.
+
+{excl_mods,snmp,
[snmp_index,
snmpa_error_io,
snmpa_authentication_service,
diff --git a/lib/snmp/test/snmp.spec b/lib/snmp/test/snmp.spec
index 0af52c139e..88ae0145f0 100644
--- a/lib/snmp/test/snmp.spec
+++ b/lib/snmp/test/snmp.spec
@@ -1 +1 @@
-{topcase, {dir, "../snmp_test"}}.
+{suites,"../snmp_test",all}.
diff --git a/lib/snmp/test/snmp_SUITE.erl b/lib/snmp/test/snmp_SUITE.erl
index f560e36663..b6d72da2fa 100644
--- a/lib/snmp/test/snmp_SUITE.erl
+++ b/lib/snmp/test/snmp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,27 +19,14 @@
-module(snmp_SUITE).
--export([all/1,
- init_per_testcase/2, fin_per_testcase/2
+-export([all/0,
+ suite/0,
+ groups/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_group/2, end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2
]).
--export([app/1, compiler/1, misc/1, agent/1, manager/1]).
-
--export([
- app_test/1,
- appup_test/1,
- compiler_test/1,
- conf_test/1,
- pdus_test/1,
- log_test/1,
- note_store_test/1,
- mibs_test/1,
- nfilter_test/1,
- agent_test/1,
- manager_config_test/1,
- manager_user_test/1,
- manager_test/1
- ]).
%%
%% -----
@@ -48,110 +35,60 @@
init_per_testcase(_Case, Config) when is_list(Config) ->
Config.
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Config.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Top test case
-all(doc) ->
- ["Test suites for the snmp application.",
- "There are eight different sub test-suites."];
-
-all(suite) ->
- [
- app,
- compiler,
- misc,
- agent,
- manager
-
- ].
-
-app(suite) ->
- [
- app_test,
- appup_test
- ].
-
-compiler(suite) ->
- [
- compiler_test
- ].
-
-misc(suite) ->
- [
- conf_test,
- pdus_test,
- log_test,
- note_store_test
- ].
-
-agent(suite) ->
- [
- mibs_test,
- nfilter_test,
- agent_test
- ].
-
-manager(suite) ->
- [
- manager_config_test,
- manager_user_test,
- manager_test
- ].
-
-
-app_test(suite) ->
- [{snmp_app_test, all}].
-
-
-appup_test(suite) ->
- [{snmp_appup_test, all}].
-
-
-compiler_test(suite) ->
- [{snmp_compiler_test, all}].
-
-
-conf_test(suite) ->
- [{snmp_conf_test, all}].
-
-
-pdus_test(suite) ->
- [{snmp_pdus_test, all}].
-
-
-log_test(suite) ->
- [{snmp_log_test, all}].
-
-
-note_store_test(suite) ->
- [{snmp_note_store_test, all}].
-
-
-mibs_test(suite) ->
- [{snmp_agent_mibs_test, all}].
-
-
-nfilter_test(suite) ->
- [{snmp_agent_nfilter_test, all}].
-
-
-agent_test(suite) ->
- [{snmp_agent_test, all}].
-
-
-manager_config_test(suite) ->
- [{snmp_manager_config_test, all}].
-
-
-manager_user_test(suite) ->
- [{snmp_manager_user_test, all}].
+suite() ->
+ [{ct_hooks, [ts_install_cth]}].
+
+all() ->
+ [{group, app},
+ {group, compiler},
+ {group, misc},
+ {group, agent},
+ {group, manager}].
+
+groups() ->
+ [{app, [], [{group, app_test},
+ {group, appup_test}]},
+ {compiler, [], [{group, compiler_test}]},
+ {misc, [], [{group, conf_test},
+ {group, pdus_test},
+ {group, log_test},
+ {group, note_store_test}]},
+ {agent, [], [{group, mibs_test},
+ {group, nfilter_test},
+ {group, agent_test}]},
+ {manager, [], [{group, manager_config_test},
+ {group, manager_user_test},
+ {group, manager_test}]},
+ {app_test, [], [{snmp_app_test, all}]},
+ {appup_test, [], [{snmp_appup_test, all}]},
+ {compiler_test, [], [{snmp_compiler_test, all}]},
+ {conf_test, [], [{snmp_conf_test, all}]},
+ {pdus_test, [], [{snmp_pdus_test, all}]},
+ {log_test, [], [{snmp_log_test, all}]},
+ {note_store_test, [], [{snmp_note_store_test, all}]},
+ {mibs_test, [], [{snmp_agent_mibs_test, all}]},
+ {nfilter_test, [], [{snmp_agent_nfilter_test, all}]},
+ {agent_test, [], [{snmp_agent_test, all}]},
+ {manager_config_test, [], [{snmp_manager_config_test, all}]},
+ {manager_user_test, [], [{snmp_manager_user_test, all}]},
+ {manager_test, [], [{snmp_manager_test, all}]}].
+
+init_per_suite(Config) ->
+ Config.
+end_per_suite(_Config) ->
+ ok.
-manager_test(suite) ->
- [{snmp_manager_test, all}].
+init_per_group(_GroupName, Config) ->
+ Config.
+end_per_group(_GroupName, Config) ->
+ Config.
diff --git a/lib/snmp/test/snmp_agent_bl_test.erl b/lib/snmp/test/snmp_agent_bl_test.erl
index 4608d90201..b17489a755 100644
--- a/lib/snmp/test/snmp_agent_bl_test.erl
+++ b/lib/snmp/test/snmp_agent_bl_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -89,7 +89,7 @@ init_per_testcase(_Case, Config) when list(Config) ->
Dog = ?t:timetrap(?t:minutes(6)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) when list(Config) ->
+end_per_testcase(_Case, Config) when list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
Config.
diff --git a/lib/snmp/test/snmp_agent_mibs_test.erl b/lib/snmp/test/snmp_agent_mibs_test.erl
index 5f1ff53a79..3e48130fac 100644
--- a/lib/snmp/test/snmp_agent_mibs_test.erl
+++ b/lib/snmp/test/snmp_agent_mibs_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,7 +26,7 @@
%%----------------------------------------------------------------------
%% Include files
%%----------------------------------------------------------------------
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-include_lib("snmp/include/snmp_types.hrl").
-include_lib("snmp/include/SNMP-COMMUNITY-MIB.hrl").
@@ -39,12 +39,12 @@
%% External exports
%%----------------------------------------------------------------------
-export([
- all/1,
- init_per_testcase/2, fin_per_testcase/2,
- init_all/1, finish_all/1,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
+ init_per_suite/1, end_per_suite/1,
start_and_stop/1,
- size_check/1,
+
size_check_ets/1,
size_check_dets/1,
size_check_mnesia/1,
@@ -58,8 +58,6 @@
%%----------------------------------------------------------------------
%% Internal exports
%%----------------------------------------------------------------------
--export([
- ]).
%%----------------------------------------------------------------------
%% Macros
@@ -100,20 +98,20 @@ init_per_testcase(cache_test, Config) when is_list(Config) ->
init_per_testcase(_Case, Config) when is_list(Config) ->
Config.
-fin_per_testcase(size_check_dets, Config) when is_list(Config) ->
+end_per_testcase(size_check_dets, Config) when is_list(Config) ->
Dir = ?config(dets_dir, Config),
?line ok = ?DEL_DIR(Dir),
lists:keydelete(dets_dir, 1, Config);
-fin_per_testcase(size_check_mnesia, Config) when is_list(Config) ->
+end_per_testcase(size_check_mnesia, Config) when is_list(Config) ->
mnesia_stop(),
Dir = ?config(mnesia_dir, Config),
?line ok = ?DEL_DIR(Dir),
lists:keydelete(mnesia_dir, 1, Config);
-fin_per_testcase(cache_test, Config) when is_list(Config) ->
+end_per_testcase(cache_test, Config) when is_list(Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
Config;
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Config.
@@ -121,20 +119,25 @@ fin_per_testcase(_Case, Config) when is_list(Config) ->
%% Test case definitions
%%======================================================================
-all(suite) ->
- {conf, init_all, cases(), finish_all}.
+all() ->
+cases().
+
+groups() ->
+ [{size_check, [],
+ [size_check_ets, size_check_dets, size_check_mnesia]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-cases() ->
- [
- start_and_stop,
- load_unload,
- size_check,
- me_lookup,
- which_mib,
- cache_test
- ].
+cases() ->
+[start_and_stop, load_unload, {group, size_check},
+ me_lookup, which_mib, cache_test].
-init_all(Config) when is_list(Config) ->
+init_per_suite(Config) when is_list(Config) ->
%% Data dir points wrong
DataDir0 = ?config(data_dir, Config),
DataDir1 = filename:split(filename:absname(DataDir0)),
@@ -142,7 +145,7 @@ init_all(Config) when is_list(Config) ->
DataDir = filename:join(lists:reverse(DataDir2) ++ [?snmp_test_data]),
[{snmp_data_dir, DataDir ++ "/"}|Config].
-finish_all(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
lists:keydelete(snmp_data_dir, 1, Config).
@@ -217,12 +220,6 @@ load_unload(Config) when is_list(Config) ->
%% ---------------------------------------------------------------------
-size_check(suite) ->
- [
- size_check_ets,
- size_check_dets,
- size_check_mnesia
- ].
size_check_ets(suite) ->
[];
diff --git a/lib/snmp/test/snmp_agent_ms_test.erl b/lib/snmp/test/snmp_agent_ms_test.erl
index 3a3a790e6a..1f34f1c8d1 100644
--- a/lib/snmp/test/snmp_agent_ms_test.erl
+++ b/lib/snmp/test/snmp_agent_ms_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -28,7 +28,7 @@
-define(application, snmp).
-include_lib("kernel/include/file.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-define(SNMP_USE_V3, true).
-include_lib("snmp/include/snmp_types.hrl").
@@ -83,39 +83,165 @@
_ -> V3
end).
-all(suite) -> {req,
- [mnesia, distribution,
- {local_slave_nodes, 2}, {time, 360}],
- [{conf, init_all, cases(), finish_all}]}.
+all() ->
+[cases()].
+
+groups() ->
+ [{mib_storage, [],
+ [{group, mib_storage_ets}, {group, mib_storage_dets},
+ {group, mib_storage_mnesia},
+ {group, mib_storage_size_check_ets},
+ {group, mib_storage_size_check_dets},
+ {group, mib_storage_size_check_mnesia},
+ {group, mib_storage_varm_dets},
+ {group, mib_storage_varm_mnesia}]},
+ {mib_storage_ets, [], mib_storage_ets_cases()},
+ {mib_storage_dets, [], mib_storage_dets_cases()},
+ {mib_storage_mnesia, [], mib_storage_mnesia_cases()},
+ {mib_storage_size_check_ets, [],
+ mse_size_check_cases()},
+ {mib_storage_size_check_dets, [],
+ msd_size_check_cases()},
+ {mib_storage_size_check_mnesia, [],
+ msm_size_check_cases()},
+ {mib_storage_varm_dets, [],
+ varm_mib_storage_dets_cases()},
+ {mib_storage_varm_mnesia, [],
+ varm_mib_storage_mnesia_cases()},
+ {test_v1, [], v1_cases()}, {test_v2, [], v2_cases()},
+ {test_v1_v2, [], v1_v2_cases()},
+ {test_v3, [], v3_cases()},
+ {test_multi_threaded, [], mt_cases()},
+ {multiple_reqs, [], mul_cases()},
+ {multiple_reqs_2, [], mul_cases_2()},
+ {v2_inform, [], [v2_inform_i]},
+ {v3_security, [],
+ [v3_crypto_basic, v3_md5_auth, v3_sha_auth,
+ v3_des_priv]},
+ {standard_mibs, [],
+ [snmp_standard_mib, snmp_community_mib,
+ snmp_framework_mib, snmp_target_mib,
+ snmp_notification_mib, snmp_view_based_acm_mib]},
+ {standard_mibs_2, [],
+ [snmpv2_mib_2, snmp_community_mib_2,
+ snmp_framework_mib_2, snmp_target_mib_2,
+ snmp_notification_mib_2, snmp_view_based_acm_mib_2]},
+ {standard_mibs_3, [],
+ [snmpv2_mib_3, snmp_framework_mib_3, snmp_mpd_mib_3,
+ snmp_target_mib_3, snmp_notification_mib_3,
+ snmp_view_based_acm_mib_3, snmp_user_based_sm_mib_3]},
+ {reported_bugs, [],
+ [otp_1128, otp_1129, otp_1131, otp_1162, otp_1222,
+ otp_1298, otp_1331, otp_1338, otp_1342, otp_2776,
+ otp_2979, otp_3187, otp_3725]},
+ {reported_bugs_2, [],
+ [otp_1128_2, otp_1129_2, otp_1131_2, otp_1162_2,
+ otp_1222_2, otp_1298_2, otp_1331_2, otp_1338_2,
+ otp_1342_2, otp_2776_2, otp_2979_2, otp_3187_2]},
+ {reported_bugs_3, [],
+ [otp_1128_3, otp_1129_3, otp_1131_3, otp_1162_3,
+ otp_1222_3, otp_1298_3, otp_1331_3, otp_1338_3,
+ otp_1342_3, otp_2776_3, otp_2979_3, otp_3187_3,
+ otp_3542]},
+ {tickets, [], [{group, otp_4394}]},
+ {otp_4394, [], [otp_4394_test]}].
+
+init_per_group(otp_4394, Config) ->
+ init_otp_4394(Config);
+init_per_group(v2_inform, Config) ->
+ init_v2_inform(Config);
+init_per_group(multiple_reqs_2, Config) ->
+ init_mul(Config);
+init_per_group(multiple_reqs, Config) ->
+ init_mul(Config);
+init_per_group(test_multi_threaded, Config) ->
+ init_mt(Config);
+init_per_group(test_v3, Config) ->
+ init_v3(Config);
+init_per_group(test_v1_v2, Config) ->
+ init_v1_v2(Config);
+init_per_group(test_v2, Config) ->
+ init_v2(Config);
+init_per_group(test_v1, Config) ->
+ init_v1(Config);
+init_per_group(mib_storage_varm_mnesia, Config) ->
+ init_varm_mib_storage_mnesia(Config);
+init_per_group(mib_storage_varm_dets, Config) ->
+ init_varm_mib_storage_dets(Config);
+init_per_group(mib_storage_size_check_mnesia, Config) ->
+ init_size_check_msm(Config);
+init_per_group(mib_storage_size_check_dets, Config) ->
+ init_size_check_msd(Config);
+init_per_group(mib_storage_size_check_ets, Config) ->
+ init_size_check_mse(Config);
+init_per_group(mib_storage_mnesia, Config) ->
+ init_mib_storage_mnesia(Config);
+init_per_group(mib_storage_dets, Config) ->
+ init_mib_storage_dets(Config);
+init_per_group(mib_storage_ets, Config) ->
+ init_mib_storage_ets(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(otp_4394, Config) ->
+ finish_otp_4394(Config);
+end_per_group(v2_inform, Config) ->
+ finish_v2_inform(Config);
+end_per_group(multiple_reqs_2, Config) ->
+ finish_mul(Config);
+end_per_group(multiple_reqs, Config) ->
+ finish_mul(Config);
+end_per_group(test_multi_threaded, Config) ->
+ finish_mt(Config);
+end_per_group(test_v3, Config) ->
+ finish_v3(Config);
+end_per_group(test_v1_v2, Config) ->
+ finish_v1_v2(Config);
+end_per_group(test_v2, Config) ->
+ finish_v2(Config);
+end_per_group(test_v1, Config) ->
+ finish_v1(Config);
+end_per_group(mib_storage_varm_mnesia, Config) ->
+ finish_varm_mib_storage_mnesia(Config);
+end_per_group(mib_storage_varm_dets, Config) ->
+ finish_varm_mib_storage_dets(Config);
+end_per_group(mib_storage_size_check_mnesia, Config) ->
+ finish_size_check_msm(Config);
+end_per_group(mib_storage_size_check_dets, Config) ->
+ finish_size_check_msd(Config);
+end_per_group(mib_storage_size_check_ets, Config) ->
+ finish_size_check_mse(Config);
+end_per_group(mib_storage_mnesia, Config) ->
+ finish_mib_storage_mnesia(Config);
+end_per_group(mib_storage_dets, Config) ->
+ finish_mib_storage_dets(Config);
+end_per_group(mib_storage_ets, Config) ->
+ finish_mib_storage_ets(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) when list(Config) ->
Dog = ?t:timetrap(?t:minutes(6)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) when list(Config) ->
+end_per_testcase(_Case, Config) when list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
Config.
-cases() ->
- case ?OSTYPE() of
- vxworks ->
- %% No crypto app, so skip v3 testcases
- [
- app_info,
- test_v1, test_v2, test_v1_v2,
- test_multi_threaded,
- mib_storage,
- tickets];
- _Else ->
- [
- app_info,
- test_v1, test_v2, test_v1_v2, test_v3,
- test_multi_threaded,
- mib_storage,
- tickets
- ]
- end.
+cases() ->
+case ?OSTYPE() of
+ vxworks ->
+ [app_info, {group, test_v1}, {group, test_v2},
+ {group, test_v1_v2}, {group, test_multi_threaded},
+ {group, mib_storage}, {group, tickets}];
+ _Else ->
+ [app_info, {group, test_v1}, {group, test_v2},
+ {group, test_v1_v2}, {group, test_v3},
+ {group, test_multi_threaded}, {group, mib_storage},
+ {group, tickets}]
+end.
%%%-----------------------------------------------------------------
@@ -460,144 +586,56 @@ delete_mib_storage_mnesia_tables() ->
%% <base>, and a second version <base>_2. There may be several
%% versions as well, <base>_N.
%%-----------------------------------------------------------------
-mib_storage(suite) -> [
- mib_storage_ets,
- mib_storage_dets,
- mib_storage_mnesia,
- mib_storage_size_check_ets,
- mib_storage_size_check_dets,
- mib_storage_size_check_mnesia,
- mib_storage_varm_dets,
- mib_storage_varm_mnesia
- ].
-
-mib_storage_ets(suite) -> {req, [], {conf, init_mib_storage_ets,
- mib_storage_ets_cases(),
- finish_mib_storage_ets}}.
-
-mib_storage_dets(suite) -> {req, [], {conf, init_mib_storage_dets,
- mib_storage_dets_cases(),
- finish_mib_storage_dets}}.
-
-mib_storage_mnesia(suite) -> {req, [], {conf, init_mib_storage_mnesia,
- mib_storage_mnesia_cases(),
- finish_mib_storage_mnesia}}.
-
-mib_storage_size_check_ets(suite) ->
- {req, [], {conf,
- init_size_check_mse,
- mse_size_check_cases(),
- finish_size_check_mse}}.
-
-mib_storage_size_check_dets(suite) ->
- {req, [], {conf,
- init_size_check_msd,
- msd_size_check_cases(),
- finish_size_check_msd}}.
-
-mib_storage_size_check_mnesia(suite) ->
- {req, [], {conf,
- init_size_check_msm,
- msm_size_check_cases(),
- finish_size_check_msm}}.
-
-mib_storage_varm_dets(suite) ->
- {req, [], {conf,
- init_varm_mib_storage_dets,
- varm_mib_storage_dets_cases(),
- finish_varm_mib_storage_dets}}.
-
-mib_storage_varm_mnesia(suite) ->
- {req, [], {conf,
- init_varm_mib_storage_mnesia,
- varm_mib_storage_mnesia_cases(),
- finish_varm_mib_storage_mnesia}}.
-
-mib_storage_ets_cases() ->
- [
- mse_simple,
- mse_v1_processing,
- mse_big,
- mse_big2,
- mse_loop_mib,
- mse_api,
- mse_sa_register,
- mse_v1_trap,
- mse_sa_error,
- mse_next_across_sa,
- mse_undo,
- mse_standard_mib,
- mse_community_mib,
- mse_framework_mib,
- mse_target_mib,
- mse_notification_mib,
- mse_view_based_acm_mib,
- mse_sparse_table,
- mse_me_of,
- mse_mib_of].
-
-mib_storage_dets_cases() ->
- [
- msd_simple,
- msd_v1_processing,
- msd_big,
- msd_big2,
- msd_loop_mib,
- msd_api,
- msd_sa_register,
- msd_v1_trap,
- msd_sa_error,
- msd_next_across_sa,
- msd_undo,
- msd_standard_mib,
- msd_community_mib,
- msd_framework_mib,
- msd_target_mib,
- msd_notification_mib,
- msd_view_based_acm_mib,
- msd_sparse_table,
- msd_me_of,
- msd_mib_of
- ].
-
-mib_storage_mnesia_cases() ->
- [
- msm_simple,
- msm_v1_processing,
- msm_big,
- msm_big2,
- msm_loop_mib,
- msm_api,
- msm_sa_register,
- msm_v1_trap,
- msm_sa_error,
- msm_next_across_sa,
- msm_undo,
- msm_standard_mib,
- msm_community_mib,
- msm_framework_mib,
- msm_target_mib,
- msm_notification_mib,
- msm_view_based_acm_mib,
- msm_sparse_table,
- msm_me_of,
- msm_mib_of
- ].
-
-mse_size_check_cases() ->
- [mse_size_check].
-
-msd_size_check_cases() ->
- [msd_size_check].
-
-msm_size_check_cases() ->
- [msm_size_check].
-
-varm_mib_storage_dets_cases() ->
- [msd_varm_mib_start].
-
-varm_mib_storage_mnesia_cases() ->
- [msm_varm_mib_start].
+
+
+
+
+
+
+
+
+
+mib_storage_ets_cases() ->
+[mse_simple, mse_v1_processing, mse_big, mse_big2,
+ mse_loop_mib, mse_api, mse_sa_register, mse_v1_trap,
+ mse_sa_error, mse_next_across_sa, mse_undo,
+ mse_standard_mib, mse_community_mib, mse_framework_mib,
+ mse_target_mib, mse_notification_mib,
+ mse_view_based_acm_mib, mse_sparse_table, mse_me_of,
+ mse_mib_of].
+
+mib_storage_dets_cases() ->
+[msd_simple, msd_v1_processing, msd_big, msd_big2,
+ msd_loop_mib, msd_api, msd_sa_register, msd_v1_trap,
+ msd_sa_error, msd_next_across_sa, msd_undo,
+ msd_standard_mib, msd_community_mib, msd_framework_mib,
+ msd_target_mib, msd_notification_mib,
+ msd_view_based_acm_mib, msd_sparse_table, msd_me_of,
+ msd_mib_of].
+
+mib_storage_mnesia_cases() ->
+[msm_simple, msm_v1_processing, msm_big, msm_big2,
+ msm_loop_mib, msm_api, msm_sa_register, msm_v1_trap,
+ msm_sa_error, msm_next_across_sa, msm_undo,
+ msm_standard_mib, msm_community_mib, msm_framework_mib,
+ msm_target_mib, msm_notification_mib,
+ msm_view_based_acm_mib, msm_sparse_table, msm_me_of,
+ msm_mib_of].
+
+mse_size_check_cases() ->
+[mse_size_check].
+
+msd_size_check_cases() ->
+[msd_size_check].
+
+msm_size_check_cases() ->
+[msm_size_check].
+
+varm_mib_storage_dets_cases() ->
+[msd_varm_mib_start].
+
+varm_mib_storage_mnesia_cases() ->
+[msm_varm_mib_start].
init_mib_storage_ets(Config) when list(Config) ->
?LOG("init_mib_storage_ets -> entry", []),
@@ -1099,20 +1137,14 @@ app_dir(App) ->
end.
-test_v1(suite) -> {req, [], {conf, init_v1, v1_cases(), finish_v1}}.
%v1_cases() -> [loop_mib];
-v1_cases() ->
- [simple,
- db_notify_client,
- v1_processing, big, big2, loop_mib,
- api, subagent, mnesia, multiple_reqs,
- sa_register, v1_trap, sa_error, next_across_sa, undo, reported_bugs,
- standard_mibs, sparse_table, cnt_64,
- opaque,
- % opaque].
-
- change_target_addr_config].
+v1_cases() ->
+[simple, db_notify_client, v1_processing, big, big2,
+ loop_mib, api, subagent, mnesia, {group, multiple_reqs},
+ sa_register, v1_trap, sa_error, next_across_sa, undo,
+ {group, reported_bugs}, {group, standard_mibs},
+ sparse_table, cnt_64, opaque, change_target_addr_config].
init_v1(Config) when list(Config) ->
?line SaNode = ?config(snmp_sa, Config),
@@ -1129,15 +1161,15 @@ finish_v1(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v2(suite) -> {req, [], {conf, init_v2, v2_cases(), finish_v2}}.
%v2_cases() -> [loop_mib_2];
-v2_cases() ->
- [simple_2, v2_processing, big_2, big2_2, loop_mib_2,
- api_2, subagent_2, mnesia_2,
- multiple_reqs_2, sa_register_2, v2_trap, v2_inform, sa_error_2,
- next_across_sa_2, undo_2, reported_bugs_2, standard_mibs_2,
- v2_types, implied, sparse_table_2, cnt_64_2, opaque_2, v2_caps].
+v2_cases() ->
+[simple_2, v2_processing, big_2, big2_2, loop_mib_2,
+ api_2, subagent_2, mnesia_2, {group, multiple_reqs_2},
+ sa_register_2, v2_trap, {group, v2_inform}, sa_error_2,
+ next_across_sa_2, undo_2, {group, reported_bugs_2},
+ {group, standard_mibs_2}, v2_types, implied,
+ sparse_table_2, cnt_64_2, opaque_2, v2_caps].
init_v2(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1154,10 +1186,9 @@ finish_v2(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v1_v2(suite) -> {req, [], {conf, init_v1_v2, v1_v2_cases(), finish_v1_v2}}.
-v1_v2_cases() ->
- [simple_bi].
+v1_v2_cases() ->
+[simple_bi].
init_v1_v2(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1174,16 +1205,16 @@ finish_v1_v2(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v3(suite) -> {req, [], {conf, init_v3, v3_cases(), finish_v3}}.
%v3_cases() -> [loop_mib_3];
-v3_cases() ->
- [simple_3, v3_processing,
- big_3, big2_3, api_3, subagent_3, mnesia_3, loop_mib_3,
- multiple_reqs_3, sa_register_3, v3_trap, v3_inform, sa_error_3,
- next_across_sa_3, undo_3, reported_bugs_3, standard_mibs_3,
- v3_security,
- v2_types_3, implied_3, sparse_table_3, cnt_64_3, opaque_3, v2_caps_3].
+v3_cases() ->
+[simple_3, v3_processing, big_3, big2_3, api_3,
+ subagent_3, mnesia_3, loop_mib_3, multiple_reqs_3,
+ sa_register_3, v3_trap, v3_inform, sa_error_3,
+ next_across_sa_3, undo_3, {group, reported_bugs_3},
+ {group, standard_mibs_3}, {group, v3_security},
+ v2_types_3, implied_3, sparse_table_3, cnt_64_3,
+ opaque_3, v2_caps_3].
init_v3(Config) when list(Config) ->
%% Make sure crypto works, otherwise start_agent will fail
@@ -1221,10 +1252,9 @@ finish_v3(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_multi_threaded(suite) -> {req, [], {conf, init_mt, mt_cases(), finish_mt}}.
-mt_cases() ->
- [multi_threaded, mt_trap].
+mt_cases() ->
+[multi_threaded, mt_trap].
init_mt(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1739,21 +1769,19 @@ mnesia_2(X) -> mnesia(X).
mnesia_3(X) -> mnesia(X).
-multiple_reqs(suite) ->
- {req, [], {conf, init_mul, mul_cases(), finish_mul}}.
-mul_cases() ->
- [mul_get, mul_get_err, mul_next, mul_next_err, mul_set_err].
+mul_cases() ->
+[mul_get, mul_get_err, mul_next, mul_next_err,
+ mul_set_err].
-multiple_reqs_2(suite) ->
- {req, [], {conf, init_mul, mul_cases_2(), finish_mul}}.
multiple_reqs_3(_X) ->
{req, [], {conf, init_mul, mul_cases_3(), finish_mul}}.
-mul_cases_2() ->
- [mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2, mul_set_err_2].
+mul_cases_2() ->
+[mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2,
+ mul_set_err_2].
mul_cases_3() ->
@@ -1939,8 +1967,6 @@ v2_trap(Config) when list(Config) ->
v3_trap(X) ->
v2_trap(X).
-v2_inform(suite) ->
- {req, [], {conf, init_v2_inform, [v2_inform_i], finish_v2_inform}}.
v3_inform(_X) ->
%% v2_inform(X).
@@ -2112,7 +2138,6 @@ v3_processing(Config) when list(Config) ->
%% accomplished by the first inform sent. That one will generate a
%% report, which makes it in sync. The notification-generating
%% application times out, and send again. This time it'll work.
-v3_security(suite) -> [v3_crypto_basic, v3_md5_auth, v3_sha_auth, v3_des_priv].
v3_crypto_basic(suite) -> [];
v3_crypto_basic(_Config) ->
@@ -3591,22 +3616,8 @@ bad_return() ->
%%% Note that many of the functions in the standard mib is
%%% already tested by the normal tests.
%%%-----------------------------------------------------------------
-standard_mibs(suite) ->
- [snmp_standard_mib, snmp_community_mib,
- snmp_framework_mib,
- snmp_target_mib, snmp_notification_mib,
- snmp_view_based_acm_mib].
-
-standard_mibs_2(suite) ->
- [snmpv2_mib_2, snmp_community_mib_2,
- snmp_framework_mib_2,
- snmp_target_mib_2, snmp_notification_mib_2,
- snmp_view_based_acm_mib_2].
-
-standard_mibs_3(suite) ->
- [snmpv2_mib_3,snmp_framework_mib_3, snmp_mpd_mib_3,
- snmp_target_mib_3, snmp_notification_mib_3,
- snmp_view_based_acm_mib_3, snmp_user_based_sm_mib_3].
+
+
%%-----------------------------------------------------------------
%% For this test, the agent is configured for v1.
@@ -4527,27 +4538,12 @@ loop_it_2(Oid, N) ->
%%% Testing of reported bugs and other tickets.
%%%-----------------------------------------------------------------
-reported_bugs(suite) ->
- [otp_1128, otp_1129, otp_1131, otp_1162,
- otp_1222, otp_1298, otp_1331, otp_1338,
- otp_1342, otp_2776, otp_2979, otp_3187, otp_3725].
-reported_bugs_2(suite) ->
- [otp_1128_2, otp_1129_2, otp_1131_2, otp_1162_2,
- otp_1222_2, otp_1298_2, otp_1331_2, otp_1338_2,
- otp_1342_2, otp_2776_2, otp_2979_2, otp_3187_2].
-reported_bugs_3(suite) ->
- [otp_1128_3, otp_1129_3, otp_1131_3, otp_1162_3,
- otp_1222_3, otp_1298_3, otp_1331_3, otp_1338_3,
- otp_1342_3, otp_2776_3, otp_2979_3, otp_3187_3,
- otp_3542].
%% These are (ticket) test cases where the initiation has to be done
%% individually.
-tickets(suite) ->
- [otp_4394].
%%-----------------------------------------------------------------
%% Ticket: OTP-1128
@@ -4971,10 +4967,6 @@ otp_3725_test(MaNode) ->
%%-----------------------------------------------------------------
-otp_4394(suite) -> {req, [], {conf,
- init_otp_4394,
- [otp_4394_test],
- finish_otp_4394}}.
init_otp_4394(Config) when list(Config) ->
?DBG("init_otp_4394 -> entry with"
diff --git a/lib/snmp/test/snmp_agent_mt_test.erl b/lib/snmp/test/snmp_agent_mt_test.erl
index 8d5a57f58d..4f125c0017 100644
--- a/lib/snmp/test/snmp_agent_mt_test.erl
+++ b/lib/snmp/test/snmp_agent_mt_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -28,7 +28,7 @@
-define(application, snmp).
-include_lib("kernel/include/file.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-define(SNMP_USE_V3, true).
-include_lib("snmp/include/snmp_types.hrl").
@@ -83,39 +83,165 @@
_ -> V3
end).
-all(suite) -> {req,
- [mnesia, distribution,
- {local_slave_nodes, 2}, {time, 360}],
- [{conf, init_all, cases(), finish_all}]}.
+all() ->
+[cases()].
+
+groups() ->
+ [{mib_storage, [],
+ [{group, mib_storage_ets}, {group, mib_storage_dets},
+ {group, mib_storage_mnesia},
+ {group, mib_storage_size_check_ets},
+ {group, mib_storage_size_check_dets},
+ {group, mib_storage_size_check_mnesia},
+ {group, mib_storage_varm_dets},
+ {group, mib_storage_varm_mnesia}]},
+ {mib_storage_ets, [], mib_storage_ets_cases()},
+ {mib_storage_dets, [], mib_storage_dets_cases()},
+ {mib_storage_mnesia, [], mib_storage_mnesia_cases()},
+ {mib_storage_size_check_ets, [],
+ mse_size_check_cases()},
+ {mib_storage_size_check_dets, [],
+ msd_size_check_cases()},
+ {mib_storage_size_check_mnesia, [],
+ msm_size_check_cases()},
+ {mib_storage_varm_dets, [],
+ varm_mib_storage_dets_cases()},
+ {mib_storage_varm_mnesia, [],
+ varm_mib_storage_mnesia_cases()},
+ {test_v1, [], v1_cases()}, {test_v2, [], v2_cases()},
+ {test_v1_v2, [], v1_v2_cases()},
+ {test_v3, [], v3_cases()},
+ {test_multi_threaded, [], mt_cases()},
+ {multiple_reqs, [], mul_cases()},
+ {multiple_reqs_2, [], mul_cases_2()},
+ {v2_inform, [], [v2_inform_i]},
+ {v3_security, [],
+ [v3_crypto_basic, v3_md5_auth, v3_sha_auth,
+ v3_des_priv]},
+ {standard_mibs, [],
+ [snmp_standard_mib, snmp_community_mib,
+ snmp_framework_mib, snmp_target_mib,
+ snmp_notification_mib, snmp_view_based_acm_mib]},
+ {standard_mibs_2, [],
+ [snmpv2_mib_2, snmp_community_mib_2,
+ snmp_framework_mib_2, snmp_target_mib_2,
+ snmp_notification_mib_2, snmp_view_based_acm_mib_2]},
+ {standard_mibs_3, [],
+ [snmpv2_mib_3, snmp_framework_mib_3, snmp_mpd_mib_3,
+ snmp_target_mib_3, snmp_notification_mib_3,
+ snmp_view_based_acm_mib_3, snmp_user_based_sm_mib_3]},
+ {reported_bugs, [],
+ [otp_1128, otp_1129, otp_1131, otp_1162, otp_1222,
+ otp_1298, otp_1331, otp_1338, otp_1342, otp_2776,
+ otp_2979, otp_3187, otp_3725]},
+ {reported_bugs_2, [],
+ [otp_1128_2, otp_1129_2, otp_1131_2, otp_1162_2,
+ otp_1222_2, otp_1298_2, otp_1331_2, otp_1338_2,
+ otp_1342_2, otp_2776_2, otp_2979_2, otp_3187_2]},
+ {reported_bugs_3, [],
+ [otp_1128_3, otp_1129_3, otp_1131_3, otp_1162_3,
+ otp_1222_3, otp_1298_3, otp_1331_3, otp_1338_3,
+ otp_1342_3, otp_2776_3, otp_2979_3, otp_3187_3,
+ otp_3542]},
+ {tickets, [], [{group, otp_4394}]},
+ {otp_4394, [], [otp_4394_test]}].
+
+init_per_group(otp_4394, Config) ->
+ init_otp_4394(Config);
+init_per_group(v2_inform, Config) ->
+ init_v2_inform(Config);
+init_per_group(multiple_reqs_2, Config) ->
+ init_mul(Config);
+init_per_group(multiple_reqs, Config) ->
+ init_mul(Config);
+init_per_group(test_multi_threaded, Config) ->
+ init_mt(Config);
+init_per_group(test_v3, Config) ->
+ init_v3(Config);
+init_per_group(test_v1_v2, Config) ->
+ init_v1_v2(Config);
+init_per_group(test_v2, Config) ->
+ init_v2(Config);
+init_per_group(test_v1, Config) ->
+ init_v1(Config);
+init_per_group(mib_storage_varm_mnesia, Config) ->
+ init_varm_mib_storage_mnesia(Config);
+init_per_group(mib_storage_varm_dets, Config) ->
+ init_varm_mib_storage_dets(Config);
+init_per_group(mib_storage_size_check_mnesia, Config) ->
+ init_size_check_msm(Config);
+init_per_group(mib_storage_size_check_dets, Config) ->
+ init_size_check_msd(Config);
+init_per_group(mib_storage_size_check_ets, Config) ->
+ init_size_check_mse(Config);
+init_per_group(mib_storage_mnesia, Config) ->
+ init_mib_storage_mnesia(Config);
+init_per_group(mib_storage_dets, Config) ->
+ init_mib_storage_dets(Config);
+init_per_group(mib_storage_ets, Config) ->
+ init_mib_storage_ets(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(otp_4394, Config) ->
+ finish_otp_4394(Config);
+end_per_group(v2_inform, Config) ->
+ finish_v2_inform(Config);
+end_per_group(multiple_reqs_2, Config) ->
+ finish_mul(Config);
+end_per_group(multiple_reqs, Config) ->
+ finish_mul(Config);
+end_per_group(test_multi_threaded, Config) ->
+ finish_mt(Config);
+end_per_group(test_v3, Config) ->
+ finish_v3(Config);
+end_per_group(test_v1_v2, Config) ->
+ finish_v1_v2(Config);
+end_per_group(test_v2, Config) ->
+ finish_v2(Config);
+end_per_group(test_v1, Config) ->
+ finish_v1(Config);
+end_per_group(mib_storage_varm_mnesia, Config) ->
+ finish_varm_mib_storage_mnesia(Config);
+end_per_group(mib_storage_varm_dets, Config) ->
+ finish_varm_mib_storage_dets(Config);
+end_per_group(mib_storage_size_check_mnesia, Config) ->
+ finish_size_check_msm(Config);
+end_per_group(mib_storage_size_check_dets, Config) ->
+ finish_size_check_msd(Config);
+end_per_group(mib_storage_size_check_ets, Config) ->
+ finish_size_check_mse(Config);
+end_per_group(mib_storage_mnesia, Config) ->
+ finish_mib_storage_mnesia(Config);
+end_per_group(mib_storage_dets, Config) ->
+ finish_mib_storage_dets(Config);
+end_per_group(mib_storage_ets, Config) ->
+ finish_mib_storage_ets(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) when list(Config) ->
Dog = ?t:timetrap(?t:minutes(6)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) when list(Config) ->
+end_per_testcase(_Case, Config) when list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
Config.
-cases() ->
- case ?OSTYPE() of
- vxworks ->
- %% No crypto app, so skip v3 testcases
- [
- app_info,
- test_v1, test_v2, test_v1_v2,
- test_multi_threaded,
- mib_storage,
- tickets];
- _Else ->
- [
- app_info,
- test_v1, test_v2, test_v1_v2, test_v3,
- test_multi_threaded,
- mib_storage,
- tickets
- ]
- end.
+cases() ->
+case ?OSTYPE() of
+ vxworks ->
+ [app_info, {group, test_v1}, {group, test_v2},
+ {group, test_v1_v2}, {group, test_multi_threaded},
+ {group, mib_storage}, {group, tickets}];
+ _Else ->
+ [app_info, {group, test_v1}, {group, test_v2},
+ {group, test_v1_v2}, {group, test_v3},
+ {group, test_multi_threaded}, {group, mib_storage},
+ {group, tickets}]
+end.
%%%-----------------------------------------------------------------
@@ -460,144 +586,56 @@ delete_mib_storage_mnesia_tables() ->
%% <base>, and a second version <base>_2. There may be several
%% versions as well, <base>_N.
%%-----------------------------------------------------------------
-mib_storage(suite) -> [
- mib_storage_ets,
- mib_storage_dets,
- mib_storage_mnesia,
- mib_storage_size_check_ets,
- mib_storage_size_check_dets,
- mib_storage_size_check_mnesia,
- mib_storage_varm_dets,
- mib_storage_varm_mnesia
- ].
-
-mib_storage_ets(suite) -> {req, [], {conf, init_mib_storage_ets,
- mib_storage_ets_cases(),
- finish_mib_storage_ets}}.
-
-mib_storage_dets(suite) -> {req, [], {conf, init_mib_storage_dets,
- mib_storage_dets_cases(),
- finish_mib_storage_dets}}.
-
-mib_storage_mnesia(suite) -> {req, [], {conf, init_mib_storage_mnesia,
- mib_storage_mnesia_cases(),
- finish_mib_storage_mnesia}}.
-
-mib_storage_size_check_ets(suite) ->
- {req, [], {conf,
- init_size_check_mse,
- mse_size_check_cases(),
- finish_size_check_mse}}.
-
-mib_storage_size_check_dets(suite) ->
- {req, [], {conf,
- init_size_check_msd,
- msd_size_check_cases(),
- finish_size_check_msd}}.
-
-mib_storage_size_check_mnesia(suite) ->
- {req, [], {conf,
- init_size_check_msm,
- msm_size_check_cases(),
- finish_size_check_msm}}.
-
-mib_storage_varm_dets(suite) ->
- {req, [], {conf,
- init_varm_mib_storage_dets,
- varm_mib_storage_dets_cases(),
- finish_varm_mib_storage_dets}}.
-
-mib_storage_varm_mnesia(suite) ->
- {req, [], {conf,
- init_varm_mib_storage_mnesia,
- varm_mib_storage_mnesia_cases(),
- finish_varm_mib_storage_mnesia}}.
-
-mib_storage_ets_cases() ->
- [
- mse_simple,
- mse_v1_processing,
- mse_big,
- mse_big2,
- mse_loop_mib,
- mse_api,
- mse_sa_register,
- mse_v1_trap,
- mse_sa_error,
- mse_next_across_sa,
- mse_undo,
- mse_standard_mib,
- mse_community_mib,
- mse_framework_mib,
- mse_target_mib,
- mse_notification_mib,
- mse_view_based_acm_mib,
- mse_sparse_table,
- mse_me_of,
- mse_mib_of].
-
-mib_storage_dets_cases() ->
- [
- msd_simple,
- msd_v1_processing,
- msd_big,
- msd_big2,
- msd_loop_mib,
- msd_api,
- msd_sa_register,
- msd_v1_trap,
- msd_sa_error,
- msd_next_across_sa,
- msd_undo,
- msd_standard_mib,
- msd_community_mib,
- msd_framework_mib,
- msd_target_mib,
- msd_notification_mib,
- msd_view_based_acm_mib,
- msd_sparse_table,
- msd_me_of,
- msd_mib_of
- ].
-
-mib_storage_mnesia_cases() ->
- [
- msm_simple,
- msm_v1_processing,
- msm_big,
- msm_big2,
- msm_loop_mib,
- msm_api,
- msm_sa_register,
- msm_v1_trap,
- msm_sa_error,
- msm_next_across_sa,
- msm_undo,
- msm_standard_mib,
- msm_community_mib,
- msm_framework_mib,
- msm_target_mib,
- msm_notification_mib,
- msm_view_based_acm_mib,
- msm_sparse_table,
- msm_me_of,
- msm_mib_of
- ].
-
-mse_size_check_cases() ->
- [mse_size_check].
-
-msd_size_check_cases() ->
- [msd_size_check].
-
-msm_size_check_cases() ->
- [msm_size_check].
-
-varm_mib_storage_dets_cases() ->
- [msd_varm_mib_start].
-
-varm_mib_storage_mnesia_cases() ->
- [msm_varm_mib_start].
+
+
+
+
+
+
+
+
+
+mib_storage_ets_cases() ->
+[mse_simple, mse_v1_processing, mse_big, mse_big2,
+ mse_loop_mib, mse_api, mse_sa_register, mse_v1_trap,
+ mse_sa_error, mse_next_across_sa, mse_undo,
+ mse_standard_mib, mse_community_mib, mse_framework_mib,
+ mse_target_mib, mse_notification_mib,
+ mse_view_based_acm_mib, mse_sparse_table, mse_me_of,
+ mse_mib_of].
+
+mib_storage_dets_cases() ->
+[msd_simple, msd_v1_processing, msd_big, msd_big2,
+ msd_loop_mib, msd_api, msd_sa_register, msd_v1_trap,
+ msd_sa_error, msd_next_across_sa, msd_undo,
+ msd_standard_mib, msd_community_mib, msd_framework_mib,
+ msd_target_mib, msd_notification_mib,
+ msd_view_based_acm_mib, msd_sparse_table, msd_me_of,
+ msd_mib_of].
+
+mib_storage_mnesia_cases() ->
+[msm_simple, msm_v1_processing, msm_big, msm_big2,
+ msm_loop_mib, msm_api, msm_sa_register, msm_v1_trap,
+ msm_sa_error, msm_next_across_sa, msm_undo,
+ msm_standard_mib, msm_community_mib, msm_framework_mib,
+ msm_target_mib, msm_notification_mib,
+ msm_view_based_acm_mib, msm_sparse_table, msm_me_of,
+ msm_mib_of].
+
+mse_size_check_cases() ->
+[mse_size_check].
+
+msd_size_check_cases() ->
+[msd_size_check].
+
+msm_size_check_cases() ->
+[msm_size_check].
+
+varm_mib_storage_dets_cases() ->
+[msd_varm_mib_start].
+
+varm_mib_storage_mnesia_cases() ->
+[msm_varm_mib_start].
init_mib_storage_ets(Config) when list(Config) ->
?LOG("init_mib_storage_ets -> entry", []),
@@ -1099,20 +1137,14 @@ app_dir(App) ->
end.
-test_v1(suite) -> {req, [], {conf, init_v1, v1_cases(), finish_v1}}.
%v1_cases() -> [loop_mib];
-v1_cases() ->
- [simple,
- db_notify_client,
- v1_processing, big, big2, loop_mib,
- api, subagent, mnesia, multiple_reqs,
- sa_register, v1_trap, sa_error, next_across_sa, undo, reported_bugs,
- standard_mibs, sparse_table, cnt_64,
- opaque,
- % opaque].
-
- change_target_addr_config].
+v1_cases() ->
+[simple, db_notify_client, v1_processing, big, big2,
+ loop_mib, api, subagent, mnesia, {group, multiple_reqs},
+ sa_register, v1_trap, sa_error, next_across_sa, undo,
+ {group, reported_bugs}, {group, standard_mibs},
+ sparse_table, cnt_64, opaque, change_target_addr_config].
init_v1(Config) when list(Config) ->
?line SaNode = ?config(snmp_sa, Config),
@@ -1129,15 +1161,15 @@ finish_v1(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v2(suite) -> {req, [], {conf, init_v2, v2_cases(), finish_v2}}.
%v2_cases() -> [loop_mib_2];
-v2_cases() ->
- [simple_2, v2_processing, big_2, big2_2, loop_mib_2,
- api_2, subagent_2, mnesia_2,
- multiple_reqs_2, sa_register_2, v2_trap, v2_inform, sa_error_2,
- next_across_sa_2, undo_2, reported_bugs_2, standard_mibs_2,
- v2_types, implied, sparse_table_2, cnt_64_2, opaque_2, v2_caps].
+v2_cases() ->
+[simple_2, v2_processing, big_2, big2_2, loop_mib_2,
+ api_2, subagent_2, mnesia_2, {group, multiple_reqs_2},
+ sa_register_2, v2_trap, {group, v2_inform}, sa_error_2,
+ next_across_sa_2, undo_2, {group, reported_bugs_2},
+ {group, standard_mibs_2}, v2_types, implied,
+ sparse_table_2, cnt_64_2, opaque_2, v2_caps].
init_v2(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1154,10 +1186,9 @@ finish_v2(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v1_v2(suite) -> {req, [], {conf, init_v1_v2, v1_v2_cases(), finish_v1_v2}}.
-v1_v2_cases() ->
- [simple_bi].
+v1_v2_cases() ->
+[simple_bi].
init_v1_v2(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1174,16 +1205,16 @@ finish_v1_v2(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v3(suite) -> {req, [], {conf, init_v3, v3_cases(), finish_v3}}.
%v3_cases() -> [loop_mib_3];
-v3_cases() ->
- [simple_3, v3_processing,
- big_3, big2_3, api_3, subagent_3, mnesia_3, loop_mib_3,
- multiple_reqs_3, sa_register_3, v3_trap, v3_inform, sa_error_3,
- next_across_sa_3, undo_3, reported_bugs_3, standard_mibs_3,
- v3_security,
- v2_types_3, implied_3, sparse_table_3, cnt_64_3, opaque_3, v2_caps_3].
+v3_cases() ->
+[simple_3, v3_processing, big_3, big2_3, api_3,
+ subagent_3, mnesia_3, loop_mib_3, multiple_reqs_3,
+ sa_register_3, v3_trap, v3_inform, sa_error_3,
+ next_across_sa_3, undo_3, {group, reported_bugs_3},
+ {group, standard_mibs_3}, {group, v3_security},
+ v2_types_3, implied_3, sparse_table_3, cnt_64_3,
+ opaque_3, v2_caps_3].
init_v3(Config) when list(Config) ->
%% Make sure crypto works, otherwise start_agent will fail
@@ -1221,10 +1252,9 @@ finish_v3(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_multi_threaded(suite) -> {req, [], {conf, init_mt, mt_cases(), finish_mt}}.
-mt_cases() ->
- [multi_threaded, mt_trap].
+mt_cases() ->
+[multi_threaded, mt_trap].
init_mt(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1739,21 +1769,19 @@ mnesia_2(X) -> mnesia(X).
mnesia_3(X) -> mnesia(X).
-multiple_reqs(suite) ->
- {req, [], {conf, init_mul, mul_cases(), finish_mul}}.
-mul_cases() ->
- [mul_get, mul_get_err, mul_next, mul_next_err, mul_set_err].
+mul_cases() ->
+[mul_get, mul_get_err, mul_next, mul_next_err,
+ mul_set_err].
-multiple_reqs_2(suite) ->
- {req, [], {conf, init_mul, mul_cases_2(), finish_mul}}.
multiple_reqs_3(_X) ->
{req, [], {conf, init_mul, mul_cases_3(), finish_mul}}.
-mul_cases_2() ->
- [mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2, mul_set_err_2].
+mul_cases_2() ->
+[mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2,
+ mul_set_err_2].
mul_cases_3() ->
@@ -1939,8 +1967,6 @@ v2_trap(Config) when list(Config) ->
v3_trap(X) ->
v2_trap(X).
-v2_inform(suite) ->
- {req, [], {conf, init_v2_inform, [v2_inform_i], finish_v2_inform}}.
v3_inform(_X) ->
%% v2_inform(X).
@@ -2112,7 +2138,6 @@ v3_processing(Config) when list(Config) ->
%% accomplished by the first inform sent. That one will generate a
%% report, which makes it in sync. The notification-generating
%% application times out, and send again. This time it'll work.
-v3_security(suite) -> [v3_crypto_basic, v3_md5_auth, v3_sha_auth, v3_des_priv].
v3_crypto_basic(suite) -> [];
v3_crypto_basic(_Config) ->
@@ -3591,22 +3616,8 @@ bad_return() ->
%%% Note that many of the functions in the standard mib is
%%% already tested by the normal tests.
%%%-----------------------------------------------------------------
-standard_mibs(suite) ->
- [snmp_standard_mib, snmp_community_mib,
- snmp_framework_mib,
- snmp_target_mib, snmp_notification_mib,
- snmp_view_based_acm_mib].
-
-standard_mibs_2(suite) ->
- [snmpv2_mib_2, snmp_community_mib_2,
- snmp_framework_mib_2,
- snmp_target_mib_2, snmp_notification_mib_2,
- snmp_view_based_acm_mib_2].
-
-standard_mibs_3(suite) ->
- [snmpv2_mib_3,snmp_framework_mib_3, snmp_mpd_mib_3,
- snmp_target_mib_3, snmp_notification_mib_3,
- snmp_view_based_acm_mib_3, snmp_user_based_sm_mib_3].
+
+
%%-----------------------------------------------------------------
%% For this test, the agent is configured for v1.
@@ -4527,27 +4538,12 @@ loop_it_2(Oid, N) ->
%%% Testing of reported bugs and other tickets.
%%%-----------------------------------------------------------------
-reported_bugs(suite) ->
- [otp_1128, otp_1129, otp_1131, otp_1162,
- otp_1222, otp_1298, otp_1331, otp_1338,
- otp_1342, otp_2776, otp_2979, otp_3187, otp_3725].
-reported_bugs_2(suite) ->
- [otp_1128_2, otp_1129_2, otp_1131_2, otp_1162_2,
- otp_1222_2, otp_1298_2, otp_1331_2, otp_1338_2,
- otp_1342_2, otp_2776_2, otp_2979_2, otp_3187_2].
-reported_bugs_3(suite) ->
- [otp_1128_3, otp_1129_3, otp_1131_3, otp_1162_3,
- otp_1222_3, otp_1298_3, otp_1331_3, otp_1338_3,
- otp_1342_3, otp_2776_3, otp_2979_3, otp_3187_3,
- otp_3542].
%% These are (ticket) test cases where the initiation has to be done
%% individually.
-tickets(suite) ->
- [otp_4394].
%%-----------------------------------------------------------------
%% Ticket: OTP-1128
@@ -4971,10 +4967,6 @@ otp_3725_test(MaNode) ->
%%-----------------------------------------------------------------
-otp_4394(suite) -> {req, [], {conf,
- init_otp_4394,
- [otp_4394_test],
- finish_otp_4394}}.
init_otp_4394(Config) when list(Config) ->
?DBG("init_otp_4394 -> entry with"
diff --git a/lib/snmp/test/snmp_agent_nfilter_test.erl b/lib/snmp/test/snmp_agent_nfilter_test.erl
index 269c7c96c9..f08060cee3 100644
--- a/lib/snmp/test/snmp_agent_nfilter_test.erl
+++ b/lib/snmp/test/snmp_agent_nfilter_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
%%----------------------------------------------------------------------
%% Include files
%%----------------------------------------------------------------------
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
@@ -33,8 +33,8 @@
%% External exports
%%----------------------------------------------------------------------
-export([
- all/1,
- init_per_testcase/2, fin_per_testcase/2
+ all/0,
+ init_per_testcase/2, end_per_testcase/2
]).
%%----------------------------------------------------------------------
@@ -58,14 +58,14 @@
init_per_testcase(_Case, Config) when is_list(Config) ->
Config.
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Config.
%%======================================================================
%% Test case definitions
%%======================================================================
-all(_) ->
- ?SKIP(not_yet_implemented).
+all() ->
+ {skip,not_yet_implemented}.
%%======================================================================
diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl
index 9d2e9969c4..692d29fda0 100644
--- a/lib/snmp/test/snmp_agent_test.erl
+++ b/lib/snmp/test/snmp_agent_test.erl
@@ -28,7 +28,7 @@
-define(application, snmp).
-include_lib("kernel/include/file.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-define(SNMP_USE_V3, true).
-include_lib("snmp/include/snmp_types.hrl").
@@ -85,18 +85,171 @@
end).
-all(suite) ->
- Reqs = [mnesia, distribution, {local_slave_nodes, 2}, {time, 360}],
- Conf1 = [{conf, init_all, cases(), finish_all}],
- Conf2 = [tickets2],
- {req, Reqs, Conf1 ++ Conf2}.
+all() ->
+ Reqs = [mnesia, distribution, {local_slave_nodes, 2},
+ {time, 360}],
+ Conf1 = [{group, all_tcs}],
+ Conf2 = [{group, tickets2}],
+ Conf1 ++ Conf2.
+
+groups() ->
+ [{all_tcs, [], cases()},
+ {mib_storage, [],
+ [{group, mib_storage_ets}, {group, mib_storage_dets},
+ {group, mib_storage_mnesia},
+ {group, mib_storage_size_check_ets},
+ {group, mib_storage_size_check_dets},
+ {group, mib_storage_size_check_mnesia},
+ {group, mib_storage_varm_dets},
+ {group, mib_storage_varm_mnesia}]},
+ {mib_storage_ets, [], mib_storage_ets_cases()},
+ {mib_storage_dets, [], mib_storage_dets_cases()},
+ {mib_storage_mnesia, [], mib_storage_mnesia_cases()},
+ {mib_storage_size_check_ets, [],
+ mse_size_check_cases()},
+ {mib_storage_size_check_dets, [],
+ msd_size_check_cases()},
+ {mib_storage_size_check_mnesia, [],
+ msm_size_check_cases()},
+ {mib_storage_varm_dets, [],
+ varm_mib_storage_dets_cases()},
+ {mib_storage_varm_mnesia, [],
+ varm_mib_storage_mnesia_cases()},
+ {misc, [], misc_cases()}, {test_v1, [], v1_cases()},
+ {test_v2, [], v2_cases()},
+ {test_v1_v2, [], v1_v2_cases()},
+ {test_v3, [], v3_cases()},
+ {test_multi_threaded, [], mt_cases()},
+ {multiple_reqs, [], mul_cases()},
+ {multiple_reqs_2, [], mul_cases_2()},
+ {v2_inform, [], [v2_inform_i]},
+ {v3_security, [],
+ [v3_crypto_basic, v3_md5_auth, v3_sha_auth,
+ v3_des_priv]},
+ {standard_mibs, [],
+ [snmp_standard_mib, snmp_community_mib,
+ snmp_framework_mib, snmp_target_mib,
+ snmp_notification_mib, snmp_view_based_acm_mib]},
+ {standard_mibs_2, [],
+ [snmpv2_mib_2, snmp_community_mib_2,
+ snmp_framework_mib_2, snmp_target_mib_2,
+ snmp_notification_mib_2, snmp_view_based_acm_mib_2]},
+ {standard_mibs_3, [],
+ [snmpv2_mib_3, snmp_framework_mib_3, snmp_mpd_mib_3,
+ snmp_target_mib_3, snmp_notification_mib_3,
+ snmp_view_based_acm_mib_3, snmp_user_based_sm_mib_3]},
+ {reported_bugs, [],
+ [otp_1128, otp_1129, otp_1131, otp_1162, otp_1222,
+ otp_1298, otp_1331, otp_1338, otp_1342, otp_2776,
+ otp_2979, otp_3187, otp_3725]},
+ {reported_bugs_2, [],
+ [otp_1128_2, otp_1129_2, otp_1131_2, otp_1162_2,
+ otp_1222_2, otp_1298_2, otp_1331_2, otp_1338_2,
+ otp_1342_2, otp_2776_2, otp_2979_2, otp_3187_2]},
+ {reported_bugs_3, [],
+ [otp_1128_3, otp_1129_3, otp_1131_3, otp_1162_3,
+ otp_1222_3, otp_1298_3, otp_1331_3, otp_1338_3,
+ otp_1342_3, otp_2776_3, otp_2979_3, otp_3187_3,
+ otp_3542]},
+ {tickets1, [], [{group, otp_4394}, {group, otp_7157}]},
+ {tickets2, [], [otp8395]},
+ {otp_4394, [], [otp_4394_test]},
+ {otp_7157, [],
+ begin Reqs = [], Conf = [otp_7157_test], Conf end}].
+
+init_per_group(all_tcs, Config) ->
+ init_all(Config);
+init_per_group(otp_7157, Config) ->
+ init_otp_7157(Config);
+init_per_group(otp_4394, Config) ->
+ init_otp_4394(Config);
+init_per_group(v2_inform, Config) ->
+ init_v2_inform(Config);
+init_per_group(multiple_reqs_2, Config) ->
+ init_mul(Config);
+init_per_group(multiple_reqs, Config) ->
+ init_mul(Config);
+init_per_group(test_multi_threaded, Config) ->
+ init_mt(Config);
+init_per_group(test_v3, Config) ->
+ init_v3(Config);
+init_per_group(test_v1_v2, Config) ->
+ init_v1_v2(Config);
+init_per_group(test_v2, Config) ->
+ init_v2(Config);
+init_per_group(test_v1, Config) ->
+ init_v1(Config);
+init_per_group(misc, Config) ->
+ init_misc(Config);
+init_per_group(mib_storage_varm_mnesia, Config) ->
+ init_varm_mib_storage_mnesia(Config);
+init_per_group(mib_storage_varm_dets, Config) ->
+ init_varm_mib_storage_dets(Config);
+init_per_group(mib_storage_size_check_mnesia, Config) ->
+ init_size_check_msm(Config);
+init_per_group(mib_storage_size_check_dets, Config) ->
+ init_size_check_msd(Config);
+init_per_group(mib_storage_size_check_ets, Config) ->
+ init_size_check_mse(Config);
+init_per_group(mib_storage_mnesia, Config) ->
+ init_mib_storage_mnesia(Config);
+init_per_group(mib_storage_dets, Config) ->
+ init_mib_storage_dets(Config);
+init_per_group(mib_storage_ets, Config) ->
+ init_mib_storage_ets(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(all_tcs, Config) ->
+ finish_all(Config);
+end_per_group(otp_7157, Config) ->
+ finish_otp_7157(Config);
+end_per_group(otp_4394, Config) ->
+ finish_otp_4394(Config);
+end_per_group(v2_inform, Config) ->
+ finish_v2_inform(Config);
+end_per_group(multiple_reqs_2, Config) ->
+ finish_mul(Config);
+end_per_group(multiple_reqs, Config) ->
+ finish_mul(Config);
+end_per_group(test_multi_threaded, Config) ->
+ finish_mt(Config);
+end_per_group(test_v3, Config) ->
+ finish_v3(Config);
+end_per_group(test_v1_v2, Config) ->
+ finish_v1_v2(Config);
+end_per_group(test_v2, Config) ->
+ finish_v2(Config);
+end_per_group(test_v1, Config) ->
+ finish_v1(Config);
+end_per_group(misc, Config) ->
+ finish_misc(Config);
+end_per_group(mib_storage_varm_mnesia, Config) ->
+ finish_varm_mib_storage_mnesia(Config);
+end_per_group(mib_storage_varm_dets, Config) ->
+ finish_varm_mib_storage_dets(Config);
+end_per_group(mib_storage_size_check_mnesia, Config) ->
+ finish_size_check_msm(Config);
+end_per_group(mib_storage_size_check_dets, Config) ->
+ finish_size_check_msd(Config);
+end_per_group(mib_storage_size_check_ets, Config) ->
+ finish_size_check_mse(Config);
+end_per_group(mib_storage_mnesia, Config) ->
+ finish_mib_storage_mnesia(Config);
+end_per_group(mib_storage_dets, Config) ->
+ finish_mib_storage_dets(Config);
+end_per_group(mib_storage_ets, Config) ->
+ finish_mib_storage_ets(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(otp8395 = Case, Config) when is_list(Config) ->
?DBG("init_per_testcase -> entry with"
"~n Case: ~p"
"~n Config: ~p", [Case, Config]),
- Config2 = init_per_testcase2(Case, init_suite(Config)),
+ Config2 = init_per_testcase2(Case, init_per_suite(Config)),
otp8395({init, Config2});
init_per_testcase(otp_7157_test = _Case, Config) when is_list(Config) ->
?DBG("init_per_testcase -> entry with"
@@ -123,10 +276,10 @@ init_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?WD_START(?MINS(6)),
[{watchdog, Dog}|Config].
-fin_per_testcase(otp8395, Config) when is_list(Config) ->
+end_per_testcase(otp8395, Config) when is_list(Config) ->
otp8395({fin, Config});
-fin_per_testcase(_Case, Config) when is_list(Config) ->
- ?DBG("fin_per_testcase -> entry with"
+end_per_testcase(_Case, Config) when is_list(Config) ->
+ ?DBG("end_per_testcase -> entry with"
"~n Case: ~p"
"~n Config: ~p", [_Case, Config]),
Dog = ?config(watchdog, Config),
@@ -134,8 +287,8 @@ fin_per_testcase(_Case, Config) when is_list(Config) ->
Config.
-init_suite(Config) ->
- ?DBG("init_suite -> entry with"
+init_per_suite(Config) ->
+ ?DBG("init_per_suite -> entry with"
"~n Config: ~p", [Config]),
%% Suite root dir for test suite
@@ -170,12 +323,12 @@ init_suite(Config) ->
{mib_dir, MibDir},
{std_mib_dir, StdMibDir} | Config1],
- ?DBG("init_suite -> done when"
+ ?DBG("init_per_suite -> done when"
"~n Config2: ~p", [Config2]),
Config2.
%% end_per_suite(Config) ->
-end_suite(Config) ->
+end_per_suite(Config) ->
Config.
fix_data_dir(Config) ->
@@ -220,35 +373,22 @@ init_per_testcase2(Case, Config) ->
{sub_agent_top_dir, SubAgentTopDir},
{manager_top_dir, ManagerTopDir} | Config].
-fin_per_testcase2(_Case, Config) ->
+end_per_testcase2(_Case, Config) ->
Config.
-cases() ->
- case ?OSTYPE() of
- vxworks ->
- %% No crypto app, so skip v3 testcases
- [
- misc,
- test_v1,
- test_v2,
- test_v1_v2,
- test_multi_threaded,
- mib_storage,
- tickets1
- ];
- _Else ->
- [
- misc,
- test_v1,
- test_v2,
- test_v1_v2,
- test_v3,
- test_multi_threaded,
- mib_storage,
- tickets1
- ]
- end.
+cases() ->
+case ?OSTYPE() of
+ vxworks ->
+ [{group, misc}, {group, test_v1}, {group, test_v2},
+ {group, test_v1_v2}, {group, test_multi_threaded},
+ {group, mib_storage}, {group, tickets1}];
+ _Else ->
+ [{group, misc}, {group, test_v1}, {group, test_v2},
+ {group, test_v1_v2}, {group, test_v3},
+ {group, test_multi_threaded}, {group, mib_storage},
+ {group, tickets1}]
+end.
%%%-----------------------------------------------------------------
@@ -355,144 +495,56 @@ delete_mib_storage_mnesia_tables() ->
%% <base>, and a second version <base>_2. There may be several
%% versions as well, <base>_N.
%%-----------------------------------------------------------------
-mib_storage(suite) -> [
- mib_storage_ets,
- mib_storage_dets,
- mib_storage_mnesia,
- mib_storage_size_check_ets,
- mib_storage_size_check_dets,
- mib_storage_size_check_mnesia,
- mib_storage_varm_dets,
- mib_storage_varm_mnesia
- ].
-
-mib_storage_ets(suite) -> {req, [], {conf, init_mib_storage_ets,
- mib_storage_ets_cases(),
- finish_mib_storage_ets}}.
-
-mib_storage_dets(suite) -> {req, [], {conf, init_mib_storage_dets,
- mib_storage_dets_cases(),
- finish_mib_storage_dets}}.
-
-mib_storage_mnesia(suite) -> {req, [], {conf, init_mib_storage_mnesia,
- mib_storage_mnesia_cases(),
- finish_mib_storage_mnesia}}.
-
-mib_storage_size_check_ets(suite) ->
- {req, [], {conf,
- init_size_check_mse,
- mse_size_check_cases(),
- finish_size_check_mse}}.
-
-mib_storage_size_check_dets(suite) ->
- {req, [], {conf,
- init_size_check_msd,
- msd_size_check_cases(),
- finish_size_check_msd}}.
-
-mib_storage_size_check_mnesia(suite) ->
- {req, [], {conf,
- init_size_check_msm,
- msm_size_check_cases(),
- finish_size_check_msm}}.
-
-mib_storage_varm_dets(suite) ->
- {req, [], {conf,
- init_varm_mib_storage_dets,
- varm_mib_storage_dets_cases(),
- finish_varm_mib_storage_dets}}.
-
-mib_storage_varm_mnesia(suite) ->
- {req, [], {conf,
- init_varm_mib_storage_mnesia,
- varm_mib_storage_mnesia_cases(),
- finish_varm_mib_storage_mnesia}}.
-
-mib_storage_ets_cases() ->
- [
- mse_simple,
- mse_v1_processing,
- mse_big,
- mse_big2,
- mse_loop_mib,
- mse_api,
- mse_sa_register,
- mse_v1_trap,
- mse_sa_error,
- mse_next_across_sa,
- mse_undo,
- mse_standard_mib,
- mse_community_mib,
- mse_framework_mib,
- mse_target_mib,
- mse_notification_mib,
- mse_view_based_acm_mib,
- mse_sparse_table,
- mse_me_of,
- mse_mib_of].
-
-mib_storage_dets_cases() ->
- [
- msd_simple,
- msd_v1_processing,
- msd_big,
- msd_big2,
- msd_loop_mib,
- msd_api,
- msd_sa_register,
- msd_v1_trap,
- msd_sa_error,
- msd_next_across_sa,
- msd_undo,
- msd_standard_mib,
- msd_community_mib,
- msd_framework_mib,
- msd_target_mib,
- msd_notification_mib,
- msd_view_based_acm_mib,
- msd_sparse_table,
- msd_me_of,
- msd_mib_of
- ].
-
-mib_storage_mnesia_cases() ->
- [
- msm_simple,
- msm_v1_processing,
- msm_big,
- msm_big2,
- msm_loop_mib,
- msm_api,
- msm_sa_register,
- msm_v1_trap,
- msm_sa_error,
- msm_next_across_sa,
- msm_undo,
- msm_standard_mib,
- msm_community_mib,
- msm_framework_mib,
- msm_target_mib,
- msm_notification_mib,
- msm_view_based_acm_mib,
- msm_sparse_table,
- msm_me_of,
- msm_mib_of
- ].
-
-mse_size_check_cases() ->
- [mse_size_check].
-
-msd_size_check_cases() ->
- [msd_size_check].
-
-msm_size_check_cases() ->
- [msm_size_check].
-
-varm_mib_storage_dets_cases() ->
- [msd_varm_mib_start].
-
-varm_mib_storage_mnesia_cases() ->
- [msm_varm_mib_start].
+
+
+
+
+
+
+
+
+
+mib_storage_ets_cases() ->
+[mse_simple, mse_v1_processing, mse_big, mse_big2,
+ mse_loop_mib, mse_api, mse_sa_register, mse_v1_trap,
+ mse_sa_error, mse_next_across_sa, mse_undo,
+ mse_standard_mib, mse_community_mib, mse_framework_mib,
+ mse_target_mib, mse_notification_mib,
+ mse_view_based_acm_mib, mse_sparse_table, mse_me_of,
+ mse_mib_of].
+
+mib_storage_dets_cases() ->
+[msd_simple, msd_v1_processing, msd_big, msd_big2,
+ msd_loop_mib, msd_api, msd_sa_register, msd_v1_trap,
+ msd_sa_error, msd_next_across_sa, msd_undo,
+ msd_standard_mib, msd_community_mib, msd_framework_mib,
+ msd_target_mib, msd_notification_mib,
+ msd_view_based_acm_mib, msd_sparse_table, msd_me_of,
+ msd_mib_of].
+
+mib_storage_mnesia_cases() ->
+[msm_simple, msm_v1_processing, msm_big, msm_big2,
+ msm_loop_mib, msm_api, msm_sa_register, msm_v1_trap,
+ msm_sa_error, msm_next_across_sa, msm_undo,
+ msm_standard_mib, msm_community_mib, msm_framework_mib,
+ msm_target_mib, msm_notification_mib,
+ msm_view_based_acm_mib, msm_sparse_table, msm_me_of,
+ msm_mib_of].
+
+mse_size_check_cases() ->
+[mse_size_check].
+
+msd_size_check_cases() ->
+[msd_size_check].
+
+msm_size_check_cases() ->
+[msm_size_check].
+
+varm_mib_storage_dets_cases() ->
+[msd_varm_mib_start].
+
+varm_mib_storage_mnesia_cases() ->
+[msm_varm_mib_start].
init_mib_storage_ets(Config) when is_list(Config) ->
?LOG("init_mib_storage_ets -> entry", []),
@@ -975,8 +1027,6 @@ mib_of(Oid, ExpectedMibName) ->
end.
-misc(suite) ->
- {req, [], {conf, init_misc, misc_cases(), finish_misc}}.
init_misc(Config) ->
init_v1(Config).
@@ -984,11 +1034,8 @@ init_misc(Config) ->
finish_misc(Config) ->
finish_v1(Config).
-misc_cases() ->
- [
- app_info,
- info_test
- ].
+misc_cases() ->
+[app_info, info_test].
app_info(suite) -> [];
app_info(Config) when is_list(Config) ->
@@ -1021,34 +1068,14 @@ app_dir(App) ->
end.
-test_v1(suite) -> {req, [], {conf, init_v1, v1_cases(), finish_v1}}.
%v1_cases() -> [loop_mib];
-v1_cases() ->
- [
- simple,
- db_notify_client,
- v1_processing,
- big,
- big2,
- loop_mib,
- api,
- subagent,
- mnesia,
- multiple_reqs,
- sa_register,
- v1_trap,
- sa_error,
- next_across_sa,
- undo,
- reported_bugs,
- standard_mibs,
- sparse_table,
- cnt_64,
- opaque,
-
- change_target_addr_config
- ].
+v1_cases() ->
+[simple, db_notify_client, v1_processing, big, big2,
+ loop_mib, api, subagent, mnesia, {group, multiple_reqs},
+ sa_register, v1_trap, sa_error, next_across_sa, undo,
+ {group, reported_bugs}, {group, standard_mibs},
+ sparse_table, cnt_64, opaque, change_target_addr_config].
init_v1(Config) when is_list(Config) ->
?line SaNode = ?config(snmp_sa, Config),
@@ -1065,34 +1092,14 @@ finish_v1(Config) when is_list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v2(suite) -> {req, [], {conf, init_v2, v2_cases(), finish_v2}}.
-
-v2_cases() ->
- [
- simple_2,
- v2_processing,
- big_2,
- big2_2,
- loop_mib_2,
- api_2,
- subagent_2,
- mnesia_2,
- multiple_reqs_2,
- sa_register_2,
- v2_trap,
- v2_inform,
- sa_error_2,
- next_across_sa_2,
- undo_2,
- reported_bugs_2,
- standard_mibs_2,
- v2_types,
- implied,
- sparse_table_2,
- cnt_64_2,
- opaque_2,
- v2_caps
- ].
+
+v2_cases() ->
+[simple_2, v2_processing, big_2, big2_2, loop_mib_2,
+ api_2, subagent_2, mnesia_2, {group, multiple_reqs_2},
+ sa_register_2, v2_trap, {group, v2_inform}, sa_error_2,
+ next_across_sa_2, undo_2, {group, reported_bugs_2},
+ {group, standard_mibs_2}, v2_types, implied,
+ sparse_table_2, cnt_64_2, opaque_2, v2_caps].
init_v2(Config) when is_list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1109,11 +1116,9 @@ finish_v2(Config) when is_list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v1_v2(suite) ->
- {req, [], {conf, init_v1_v2, v1_v2_cases(), finish_v1_v2}}.
-v1_v2_cases() ->
- [simple_bi].
+v1_v2_cases() ->
+[simple_bi].
init_v1_v2(Config) when is_list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1130,35 +1135,15 @@ finish_v1_v2(Config) when is_list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v3(suite) -> {req, [], {conf, init_v3, v3_cases(), finish_v3}}.
-
-v3_cases() ->
- [
- simple_3,
- v3_processing,
- big_3,
- big2_3,
- api_3,
- subagent_3,
- mnesia_3,
- loop_mib_3,
- multiple_reqs_3,
- sa_register_3,
- v3_trap,
- v3_inform,
- sa_error_3,
- next_across_sa_3,
- undo_3,
- reported_bugs_3,
- standard_mibs_3,
- v3_security,
- v2_types_3,
- implied_3,
- sparse_table_3,
- cnt_64_3,
- opaque_3,
- v2_caps_3
- ].
+
+v3_cases() ->
+[simple_3, v3_processing, big_3, big2_3, api_3,
+ subagent_3, mnesia_3, loop_mib_3, multiple_reqs_3,
+ sa_register_3, v3_trap, v3_inform, sa_error_3,
+ next_across_sa_3, undo_3, {group, reported_bugs_3},
+ {group, standard_mibs_3}, {group, v3_security},
+ v2_types_3, implied_3, sparse_table_3, cnt_64_3,
+ opaque_3, v2_caps_3].
init_v3(Config) when is_list(Config) ->
%% Make sure crypto works, otherwise start_agent will fail
@@ -1196,11 +1181,9 @@ finish_v3(Config) when is_list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_multi_threaded(suite) ->
- {req, [], {conf, init_mt, mt_cases(), finish_mt}}.
-mt_cases() ->
- [multi_threaded, mt_trap].
+mt_cases() ->
+[multi_threaded, mt_trap].
init_mt(Config) when is_list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1690,21 +1673,19 @@ mnesia_2(X) -> ?P(mnesia_2), mnesia(X).
mnesia_3(X) -> ?P(mnesia_3), mnesia(X).
-multiple_reqs(suite) ->
- {req, [], {conf, init_mul, mul_cases(), finish_mul}}.
-mul_cases() ->
- [mul_get, mul_get_err, mul_next, mul_next_err, mul_set_err].
+mul_cases() ->
+[mul_get, mul_get_err, mul_next, mul_next_err,
+ mul_set_err].
-multiple_reqs_2(suite) ->
- {req, [], {conf, init_mul, mul_cases_2(), finish_mul}}.
multiple_reqs_3(_X) ->
{req, [], {conf, init_mul, mul_cases_3(), finish_mul}}.
-mul_cases_2() ->
- [mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2, mul_set_err_2].
+mul_cases_2() ->
+[mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2,
+ mul_set_err_2].
mul_cases_3() ->
@@ -1929,8 +1910,6 @@ v3_trap(Config) when is_list(Config) ->
?P(v3_trap),
trap2(Config).
-v2_inform(suite) ->
- {req, [], {conf, init_v2_inform, [v2_inform_i], finish_v2_inform}}.
v3_inform(_X) ->
%% v2_inform(X).
@@ -2190,13 +2169,6 @@ v3_processing(Config) when is_list(Config) ->
%% accomplished by the first inform sent. That one will generate a
%% report, which makes it in sync. The notification-generating
%% application times out, and send again. This time it'll work.
-v3_security(suite) ->
- [
- v3_crypto_basic,
- v3_md5_auth,
- v3_sha_auth,
- v3_des_priv
- ].
v3_crypto_basic(suite) -> [];
v3_crypto_basic(_Config) ->
@@ -4044,36 +4016,8 @@ bad_return() ->
%%% Note that many of the functions in the standard mib is
%%% already tested by the normal tests.
%%%-----------------------------------------------------------------
-standard_mibs(suite) ->
- [
- snmp_standard_mib,
- snmp_community_mib,
- snmp_framework_mib,
- snmp_target_mib,
- snmp_notification_mib,
- snmp_view_based_acm_mib
- ].
-
-standard_mibs_2(suite) ->
- [
- snmpv2_mib_2,
- snmp_community_mib_2,
- snmp_framework_mib_2,
- snmp_target_mib_2,
- snmp_notification_mib_2,
- snmp_view_based_acm_mib_2
- ].
-
-standard_mibs_3(suite) ->
- [
- snmpv2_mib_3,
- snmp_framework_mib_3,
- snmp_mpd_mib_3,
- snmp_target_mib_3,
- snmp_notification_mib_3,
- snmp_view_based_acm_mib_3,
- snmp_user_based_sm_mib_3
- ].
+
+
%%-----------------------------------------------------------------
%% For this test, the agent is configured for v1.
@@ -5117,70 +5061,14 @@ loop_it_2(Oid, N) ->
%%% Testing of reported bugs and other tickets.
%%%-----------------------------------------------------------------
-reported_bugs(suite) ->
- [
- otp_1128,
- otp_1129,
- otp_1131,
- otp_1162,
- otp_1222,
- otp_1298,
- otp_1331,
- otp_1338,
- otp_1342,
- otp_2776,
- otp_2979,
- otp_3187,
- otp_3725
- ].
-
-reported_bugs_2(suite) ->
- [
- otp_1128_2,
- otp_1129_2,
- otp_1131_2,
- otp_1162_2,
- otp_1222_2,
- otp_1298_2,
- otp_1331_2,
- otp_1338_2,
- otp_1342_2,
- otp_2776_2,
- otp_2979_2,
- otp_3187_2
- ].
-
-reported_bugs_3(suite) ->
- [
- otp_1128_3,
- otp_1129_3,
- otp_1131_3,
- otp_1162_3,
- otp_1222_3,
- otp_1298_3,
- otp_1331_3,
- otp_1338_3,
- otp_1342_3,
- otp_2776_3,
- otp_2979_3,
- otp_3187_3,
- otp_3542
- ].
+
+
%% These are (ticket) test cases where the initiation has to be done
%% individually.
-tickets1(suite) ->
- [
- otp_4394,
- otp_7157
- ].
-tickets2(suite) ->
- [
- otp8395
- ].
@@ -5661,10 +5549,6 @@ otp_3725_test(MaNode) ->
%%-----------------------------------------------------------------
-otp_4394(suite) -> {req, [], {conf,
- init_otp_4394,
- [otp_4394_test],
- finish_otp_4394}}.
init_otp_4394(Config) when is_list(Config) ->
?DBG("init_otp_4394 -> entry with"
@@ -5758,10 +5642,6 @@ otp_4394_test1() ->
%%-----------------------------------------------------------------
-otp_7157(suite) ->
- Reqs = [],
- Conf = [{conf, init_otp_7157, [otp_7157_test], finish_otp_7157}],
- {req, Reqs, Conf}.
init_otp_7157(Config) when is_list(Config) ->
%% <CONDITIONAL-SKIP>
diff --git a/lib/snmp/test/snmp_agent_v1_test.erl b/lib/snmp/test/snmp_agent_v1_test.erl
index 52ac6cf58f..737bb25cc3 100644
--- a/lib/snmp/test/snmp_agent_v1_test.erl
+++ b/lib/snmp/test/snmp_agent_v1_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -103,7 +103,7 @@ init_per_testcase(_Case, Config) when list(Config) ->
Dog = ?t:timetrap(?t:minutes(6)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) when list(Config) ->
+end_per_testcase(_Case, Config) when list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
Config.
diff --git a/lib/snmp/test/snmp_agent_v2_test.erl b/lib/snmp/test/snmp_agent_v2_test.erl
index eca66dc30d..dc94c18ad9 100644
--- a/lib/snmp/test/snmp_agent_v2_test.erl
+++ b/lib/snmp/test/snmp_agent_v2_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -28,7 +28,7 @@
-define(application, snmp).
-include_lib("kernel/include/file.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-define(SNMP_USE_V3, true).
-include_lib("snmp/include/snmp_types.hrl").
@@ -83,39 +83,165 @@
_ -> V3
end).
-all(suite) -> {req,
- [mnesia, distribution,
- {local_slave_nodes, 2}, {time, 360}],
- [{conf, init_all, cases(), finish_all}]}.
+all() ->
+[cases()].
+
+groups() ->
+ [{mib_storage, [],
+ [{group, mib_storage_ets}, {group, mib_storage_dets},
+ {group, mib_storage_mnesia},
+ {group, mib_storage_size_check_ets},
+ {group, mib_storage_size_check_dets},
+ {group, mib_storage_size_check_mnesia},
+ {group, mib_storage_varm_dets},
+ {group, mib_storage_varm_mnesia}]},
+ {mib_storage_ets, [], mib_storage_ets_cases()},
+ {mib_storage_dets, [], mib_storage_dets_cases()},
+ {mib_storage_mnesia, [], mib_storage_mnesia_cases()},
+ {mib_storage_size_check_ets, [],
+ mse_size_check_cases()},
+ {mib_storage_size_check_dets, [],
+ msd_size_check_cases()},
+ {mib_storage_size_check_mnesia, [],
+ msm_size_check_cases()},
+ {mib_storage_varm_dets, [],
+ varm_mib_storage_dets_cases()},
+ {mib_storage_varm_mnesia, [],
+ varm_mib_storage_mnesia_cases()},
+ {test_v1, [], v1_cases()}, {test_v2, [], v2_cases()},
+ {test_v1_v2, [], v1_v2_cases()},
+ {test_v3, [], v3_cases()},
+ {test_multi_threaded, [], mt_cases()},
+ {multiple_reqs, [], mul_cases()},
+ {multiple_reqs_2, [], mul_cases_2()},
+ {v2_inform, [], [v2_inform_i]},
+ {v3_security, [],
+ [v3_crypto_basic, v3_md5_auth, v3_sha_auth,
+ v3_des_priv]},
+ {standard_mibs, [],
+ [snmp_standard_mib, snmp_community_mib,
+ snmp_framework_mib, snmp_target_mib,
+ snmp_notification_mib, snmp_view_based_acm_mib]},
+ {standard_mibs_2, [],
+ [snmpv2_mib_2, snmp_community_mib_2,
+ snmp_framework_mib_2, snmp_target_mib_2,
+ snmp_notification_mib_2, snmp_view_based_acm_mib_2]},
+ {standard_mibs_3, [],
+ [snmpv2_mib_3, snmp_framework_mib_3, snmp_mpd_mib_3,
+ snmp_target_mib_3, snmp_notification_mib_3,
+ snmp_view_based_acm_mib_3, snmp_user_based_sm_mib_3]},
+ {reported_bugs, [],
+ [otp_1128, otp_1129, otp_1131, otp_1162, otp_1222,
+ otp_1298, otp_1331, otp_1338, otp_1342, otp_2776,
+ otp_2979, otp_3187, otp_3725]},
+ {reported_bugs_2, [],
+ [otp_1128_2, otp_1129_2, otp_1131_2, otp_1162_2,
+ otp_1222_2, otp_1298_2, otp_1331_2, otp_1338_2,
+ otp_1342_2, otp_2776_2, otp_2979_2, otp_3187_2]},
+ {reported_bugs_3, [],
+ [otp_1128_3, otp_1129_3, otp_1131_3, otp_1162_3,
+ otp_1222_3, otp_1298_3, otp_1331_3, otp_1338_3,
+ otp_1342_3, otp_2776_3, otp_2979_3, otp_3187_3,
+ otp_3542]},
+ {tickets, [], [{group, otp_4394}]},
+ {otp_4394, [], [otp_4394_test]}].
+
+init_per_group(otp_4394, Config) ->
+ init_otp_4394(Config);
+init_per_group(v2_inform, Config) ->
+ init_v2_inform(Config);
+init_per_group(multiple_reqs_2, Config) ->
+ init_mul(Config);
+init_per_group(multiple_reqs, Config) ->
+ init_mul(Config);
+init_per_group(test_multi_threaded, Config) ->
+ init_mt(Config);
+init_per_group(test_v3, Config) ->
+ init_v3(Config);
+init_per_group(test_v1_v2, Config) ->
+ init_v1_v2(Config);
+init_per_group(test_v2, Config) ->
+ init_v2(Config);
+init_per_group(test_v1, Config) ->
+ init_v1(Config);
+init_per_group(mib_storage_varm_mnesia, Config) ->
+ init_varm_mib_storage_mnesia(Config);
+init_per_group(mib_storage_varm_dets, Config) ->
+ init_varm_mib_storage_dets(Config);
+init_per_group(mib_storage_size_check_mnesia, Config) ->
+ init_size_check_msm(Config);
+init_per_group(mib_storage_size_check_dets, Config) ->
+ init_size_check_msd(Config);
+init_per_group(mib_storage_size_check_ets, Config) ->
+ init_size_check_mse(Config);
+init_per_group(mib_storage_mnesia, Config) ->
+ init_mib_storage_mnesia(Config);
+init_per_group(mib_storage_dets, Config) ->
+ init_mib_storage_dets(Config);
+init_per_group(mib_storage_ets, Config) ->
+ init_mib_storage_ets(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(otp_4394, Config) ->
+ finish_otp_4394(Config);
+end_per_group(v2_inform, Config) ->
+ finish_v2_inform(Config);
+end_per_group(multiple_reqs_2, Config) ->
+ finish_mul(Config);
+end_per_group(multiple_reqs, Config) ->
+ finish_mul(Config);
+end_per_group(test_multi_threaded, Config) ->
+ finish_mt(Config);
+end_per_group(test_v3, Config) ->
+ finish_v3(Config);
+end_per_group(test_v1_v2, Config) ->
+ finish_v1_v2(Config);
+end_per_group(test_v2, Config) ->
+ finish_v2(Config);
+end_per_group(test_v1, Config) ->
+ finish_v1(Config);
+end_per_group(mib_storage_varm_mnesia, Config) ->
+ finish_varm_mib_storage_mnesia(Config);
+end_per_group(mib_storage_varm_dets, Config) ->
+ finish_varm_mib_storage_dets(Config);
+end_per_group(mib_storage_size_check_mnesia, Config) ->
+ finish_size_check_msm(Config);
+end_per_group(mib_storage_size_check_dets, Config) ->
+ finish_size_check_msd(Config);
+end_per_group(mib_storage_size_check_ets, Config) ->
+ finish_size_check_mse(Config);
+end_per_group(mib_storage_mnesia, Config) ->
+ finish_mib_storage_mnesia(Config);
+end_per_group(mib_storage_dets, Config) ->
+ finish_mib_storage_dets(Config);
+end_per_group(mib_storage_ets, Config) ->
+ finish_mib_storage_ets(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) when list(Config) ->
Dog = ?t:timetrap(?t:minutes(6)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) when list(Config) ->
+end_per_testcase(_Case, Config) when list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
Config.
-cases() ->
- case ?OSTYPE() of
- vxworks ->
- %% No crypto app, so skip v3 testcases
- [
- app_info,
- test_v1, test_v2, test_v1_v2,
- test_multi_threaded,
- mib_storage,
- tickets];
- _Else ->
- [
- app_info,
- test_v1, test_v2, test_v1_v2, test_v3,
- test_multi_threaded,
- mib_storage,
- tickets
- ]
- end.
+cases() ->
+case ?OSTYPE() of
+ vxworks ->
+ [app_info, {group, test_v1}, {group, test_v2},
+ {group, test_v1_v2}, {group, test_multi_threaded},
+ {group, mib_storage}, {group, tickets}];
+ _Else ->
+ [app_info, {group, test_v1}, {group, test_v2},
+ {group, test_v1_v2}, {group, test_v3},
+ {group, test_multi_threaded}, {group, mib_storage},
+ {group, tickets}]
+end.
%%%-----------------------------------------------------------------
@@ -460,144 +586,56 @@ delete_mib_storage_mnesia_tables() ->
%% <base>, and a second version <base>_2. There may be several
%% versions as well, <base>_N.
%%-----------------------------------------------------------------
-mib_storage(suite) -> [
- mib_storage_ets,
- mib_storage_dets,
- mib_storage_mnesia,
- mib_storage_size_check_ets,
- mib_storage_size_check_dets,
- mib_storage_size_check_mnesia,
- mib_storage_varm_dets,
- mib_storage_varm_mnesia
- ].
-
-mib_storage_ets(suite) -> {req, [], {conf, init_mib_storage_ets,
- mib_storage_ets_cases(),
- finish_mib_storage_ets}}.
-
-mib_storage_dets(suite) -> {req, [], {conf, init_mib_storage_dets,
- mib_storage_dets_cases(),
- finish_mib_storage_dets}}.
-
-mib_storage_mnesia(suite) -> {req, [], {conf, init_mib_storage_mnesia,
- mib_storage_mnesia_cases(),
- finish_mib_storage_mnesia}}.
-
-mib_storage_size_check_ets(suite) ->
- {req, [], {conf,
- init_size_check_mse,
- mse_size_check_cases(),
- finish_size_check_mse}}.
-
-mib_storage_size_check_dets(suite) ->
- {req, [], {conf,
- init_size_check_msd,
- msd_size_check_cases(),
- finish_size_check_msd}}.
-
-mib_storage_size_check_mnesia(suite) ->
- {req, [], {conf,
- init_size_check_msm,
- msm_size_check_cases(),
- finish_size_check_msm}}.
-
-mib_storage_varm_dets(suite) ->
- {req, [], {conf,
- init_varm_mib_storage_dets,
- varm_mib_storage_dets_cases(),
- finish_varm_mib_storage_dets}}.
-
-mib_storage_varm_mnesia(suite) ->
- {req, [], {conf,
- init_varm_mib_storage_mnesia,
- varm_mib_storage_mnesia_cases(),
- finish_varm_mib_storage_mnesia}}.
-
-mib_storage_ets_cases() ->
- [
- mse_simple,
- mse_v1_processing,
- mse_big,
- mse_big2,
- mse_loop_mib,
- mse_api,
- mse_sa_register,
- mse_v1_trap,
- mse_sa_error,
- mse_next_across_sa,
- mse_undo,
- mse_standard_mib,
- mse_community_mib,
- mse_framework_mib,
- mse_target_mib,
- mse_notification_mib,
- mse_view_based_acm_mib,
- mse_sparse_table,
- mse_me_of,
- mse_mib_of].
-
-mib_storage_dets_cases() ->
- [
- msd_simple,
- msd_v1_processing,
- msd_big,
- msd_big2,
- msd_loop_mib,
- msd_api,
- msd_sa_register,
- msd_v1_trap,
- msd_sa_error,
- msd_next_across_sa,
- msd_undo,
- msd_standard_mib,
- msd_community_mib,
- msd_framework_mib,
- msd_target_mib,
- msd_notification_mib,
- msd_view_based_acm_mib,
- msd_sparse_table,
- msd_me_of,
- msd_mib_of
- ].
-
-mib_storage_mnesia_cases() ->
- [
- msm_simple,
- msm_v1_processing,
- msm_big,
- msm_big2,
- msm_loop_mib,
- msm_api,
- msm_sa_register,
- msm_v1_trap,
- msm_sa_error,
- msm_next_across_sa,
- msm_undo,
- msm_standard_mib,
- msm_community_mib,
- msm_framework_mib,
- msm_target_mib,
- msm_notification_mib,
- msm_view_based_acm_mib,
- msm_sparse_table,
- msm_me_of,
- msm_mib_of
- ].
-
-mse_size_check_cases() ->
- [mse_size_check].
-
-msd_size_check_cases() ->
- [msd_size_check].
-
-msm_size_check_cases() ->
- [msm_size_check].
-
-varm_mib_storage_dets_cases() ->
- [msd_varm_mib_start].
-
-varm_mib_storage_mnesia_cases() ->
- [msm_varm_mib_start].
+
+
+
+
+
+
+
+
+
+mib_storage_ets_cases() ->
+[mse_simple, mse_v1_processing, mse_big, mse_big2,
+ mse_loop_mib, mse_api, mse_sa_register, mse_v1_trap,
+ mse_sa_error, mse_next_across_sa, mse_undo,
+ mse_standard_mib, mse_community_mib, mse_framework_mib,
+ mse_target_mib, mse_notification_mib,
+ mse_view_based_acm_mib, mse_sparse_table, mse_me_of,
+ mse_mib_of].
+
+mib_storage_dets_cases() ->
+[msd_simple, msd_v1_processing, msd_big, msd_big2,
+ msd_loop_mib, msd_api, msd_sa_register, msd_v1_trap,
+ msd_sa_error, msd_next_across_sa, msd_undo,
+ msd_standard_mib, msd_community_mib, msd_framework_mib,
+ msd_target_mib, msd_notification_mib,
+ msd_view_based_acm_mib, msd_sparse_table, msd_me_of,
+ msd_mib_of].
+
+mib_storage_mnesia_cases() ->
+[msm_simple, msm_v1_processing, msm_big, msm_big2,
+ msm_loop_mib, msm_api, msm_sa_register, msm_v1_trap,
+ msm_sa_error, msm_next_across_sa, msm_undo,
+ msm_standard_mib, msm_community_mib, msm_framework_mib,
+ msm_target_mib, msm_notification_mib,
+ msm_view_based_acm_mib, msm_sparse_table, msm_me_of,
+ msm_mib_of].
+
+mse_size_check_cases() ->
+[mse_size_check].
+
+msd_size_check_cases() ->
+[msd_size_check].
+
+msm_size_check_cases() ->
+[msm_size_check].
+
+varm_mib_storage_dets_cases() ->
+[msd_varm_mib_start].
+
+varm_mib_storage_mnesia_cases() ->
+[msm_varm_mib_start].
init_mib_storage_ets(Config) when list(Config) ->
?LOG("init_mib_storage_ets -> entry", []),
@@ -1099,20 +1137,14 @@ app_dir(App) ->
end.
-test_v1(suite) -> {req, [], {conf, init_v1, v1_cases(), finish_v1}}.
%v1_cases() -> [loop_mib];
-v1_cases() ->
- [simple,
- db_notify_client,
- v1_processing, big, big2, loop_mib,
- api, subagent, mnesia, multiple_reqs,
- sa_register, v1_trap, sa_error, next_across_sa, undo, reported_bugs,
- standard_mibs, sparse_table, cnt_64,
- opaque,
- % opaque].
-
- change_target_addr_config].
+v1_cases() ->
+[simple, db_notify_client, v1_processing, big, big2,
+ loop_mib, api, subagent, mnesia, {group, multiple_reqs},
+ sa_register, v1_trap, sa_error, next_across_sa, undo,
+ {group, reported_bugs}, {group, standard_mibs},
+ sparse_table, cnt_64, opaque, change_target_addr_config].
init_v1(Config) when list(Config) ->
?line SaNode = ?config(snmp_sa, Config),
@@ -1129,15 +1161,15 @@ finish_v1(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v2(suite) -> {req, [], {conf, init_v2, v2_cases(), finish_v2}}.
%v2_cases() -> [loop_mib_2];
-v2_cases() ->
- [simple_2, v2_processing, big_2, big2_2, loop_mib_2,
- api_2, subagent_2, mnesia_2,
- multiple_reqs_2, sa_register_2, v2_trap, v2_inform, sa_error_2,
- next_across_sa_2, undo_2, reported_bugs_2, standard_mibs_2,
- v2_types, implied, sparse_table_2, cnt_64_2, opaque_2, v2_caps].
+v2_cases() ->
+[simple_2, v2_processing, big_2, big2_2, loop_mib_2,
+ api_2, subagent_2, mnesia_2, {group, multiple_reqs_2},
+ sa_register_2, v2_trap, {group, v2_inform}, sa_error_2,
+ next_across_sa_2, undo_2, {group, reported_bugs_2},
+ {group, standard_mibs_2}, v2_types, implied,
+ sparse_table_2, cnt_64_2, opaque_2, v2_caps].
init_v2(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1154,10 +1186,9 @@ finish_v2(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v1_v2(suite) -> {req, [], {conf, init_v1_v2, v1_v2_cases(), finish_v1_v2}}.
-v1_v2_cases() ->
- [simple_bi].
+v1_v2_cases() ->
+[simple_bi].
init_v1_v2(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1174,16 +1205,16 @@ finish_v1_v2(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v3(suite) -> {req, [], {conf, init_v3, v3_cases(), finish_v3}}.
%v3_cases() -> [loop_mib_3];
-v3_cases() ->
- [simple_3, v3_processing,
- big_3, big2_3, api_3, subagent_3, mnesia_3, loop_mib_3,
- multiple_reqs_3, sa_register_3, v3_trap, v3_inform, sa_error_3,
- next_across_sa_3, undo_3, reported_bugs_3, standard_mibs_3,
- v3_security,
- v2_types_3, implied_3, sparse_table_3, cnt_64_3, opaque_3, v2_caps_3].
+v3_cases() ->
+[simple_3, v3_processing, big_3, big2_3, api_3,
+ subagent_3, mnesia_3, loop_mib_3, multiple_reqs_3,
+ sa_register_3, v3_trap, v3_inform, sa_error_3,
+ next_across_sa_3, undo_3, {group, reported_bugs_3},
+ {group, standard_mibs_3}, {group, v3_security},
+ v2_types_3, implied_3, sparse_table_3, cnt_64_3,
+ opaque_3, v2_caps_3].
init_v3(Config) when list(Config) ->
%% Make sure crypto works, otherwise start_agent will fail
@@ -1221,10 +1252,9 @@ finish_v3(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_multi_threaded(suite) -> {req, [], {conf, init_mt, mt_cases(), finish_mt}}.
-mt_cases() ->
- [multi_threaded, mt_trap].
+mt_cases() ->
+[multi_threaded, mt_trap].
init_mt(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1739,21 +1769,19 @@ mnesia_2(X) -> mnesia(X).
mnesia_3(X) -> mnesia(X).
-multiple_reqs(suite) ->
- {req, [], {conf, init_mul, mul_cases(), finish_mul}}.
-mul_cases() ->
- [mul_get, mul_get_err, mul_next, mul_next_err, mul_set_err].
+mul_cases() ->
+[mul_get, mul_get_err, mul_next, mul_next_err,
+ mul_set_err].
-multiple_reqs_2(suite) ->
- {req, [], {conf, init_mul, mul_cases_2(), finish_mul}}.
multiple_reqs_3(_X) ->
{req, [], {conf, init_mul, mul_cases_3(), finish_mul}}.
-mul_cases_2() ->
- [mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2, mul_set_err_2].
+mul_cases_2() ->
+[mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2,
+ mul_set_err_2].
mul_cases_3() ->
@@ -1939,8 +1967,6 @@ v2_trap(Config) when list(Config) ->
v3_trap(X) ->
v2_trap(X).
-v2_inform(suite) ->
- {req, [], {conf, init_v2_inform, [v2_inform_i], finish_v2_inform}}.
v3_inform(_X) ->
%% v2_inform(X).
@@ -2112,7 +2138,6 @@ v3_processing(Config) when list(Config) ->
%% accomplished by the first inform sent. That one will generate a
%% report, which makes it in sync. The notification-generating
%% application times out, and send again. This time it'll work.
-v3_security(suite) -> [v3_crypto_basic, v3_md5_auth, v3_sha_auth, v3_des_priv].
v3_crypto_basic(suite) -> [];
v3_crypto_basic(_Config) ->
@@ -3591,22 +3616,8 @@ bad_return() ->
%%% Note that many of the functions in the standard mib is
%%% already tested by the normal tests.
%%%-----------------------------------------------------------------
-standard_mibs(suite) ->
- [snmp_standard_mib, snmp_community_mib,
- snmp_framework_mib,
- snmp_target_mib, snmp_notification_mib,
- snmp_view_based_acm_mib].
-
-standard_mibs_2(suite) ->
- [snmpv2_mib_2, snmp_community_mib_2,
- snmp_framework_mib_2,
- snmp_target_mib_2, snmp_notification_mib_2,
- snmp_view_based_acm_mib_2].
-
-standard_mibs_3(suite) ->
- [snmpv2_mib_3,snmp_framework_mib_3, snmp_mpd_mib_3,
- snmp_target_mib_3, snmp_notification_mib_3,
- snmp_view_based_acm_mib_3, snmp_user_based_sm_mib_3].
+
+
%%-----------------------------------------------------------------
%% For this test, the agent is configured for v1.
@@ -4527,27 +4538,12 @@ loop_it_2(Oid, N) ->
%%% Testing of reported bugs and other tickets.
%%%-----------------------------------------------------------------
-reported_bugs(suite) ->
- [otp_1128, otp_1129, otp_1131, otp_1162,
- otp_1222, otp_1298, otp_1331, otp_1338,
- otp_1342, otp_2776, otp_2979, otp_3187, otp_3725].
-reported_bugs_2(suite) ->
- [otp_1128_2, otp_1129_2, otp_1131_2, otp_1162_2,
- otp_1222_2, otp_1298_2, otp_1331_2, otp_1338_2,
- otp_1342_2, otp_2776_2, otp_2979_2, otp_3187_2].
-reported_bugs_3(suite) ->
- [otp_1128_3, otp_1129_3, otp_1131_3, otp_1162_3,
- otp_1222_3, otp_1298_3, otp_1331_3, otp_1338_3,
- otp_1342_3, otp_2776_3, otp_2979_3, otp_3187_3,
- otp_3542].
%% These are (ticket) test cases where the initiation has to be done
%% individually.
-tickets(suite) ->
- [otp_4394].
%%-----------------------------------------------------------------
%% Ticket: OTP-1128
@@ -4971,10 +4967,6 @@ otp_3725_test(MaNode) ->
%%-----------------------------------------------------------------
-otp_4394(suite) -> {req, [], {conf,
- init_otp_4394,
- [otp_4394_test],
- finish_otp_4394}}.
init_otp_4394(Config) when list(Config) ->
?DBG("init_otp_4394 -> entry with"
diff --git a/lib/snmp/test/snmp_agent_v3_test.erl b/lib/snmp/test/snmp_agent_v3_test.erl
index 823c914136..266be72878 100644
--- a/lib/snmp/test/snmp_agent_v3_test.erl
+++ b/lib/snmp/test/snmp_agent_v3_test.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -28,7 +28,7 @@
-define(application, snmp).
-include_lib("kernel/include/file.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-define(SNMP_USE_V3, true).
-include_lib("snmp/include/snmp_types.hrl").
@@ -83,39 +83,165 @@
_ -> V3
end).
-all(suite) -> {req,
- [mnesia, distribution,
- {local_slave_nodes, 2}, {time, 360}],
- [{conf, init_all, cases(), finish_all}]}.
+all() ->
+[cases()].
+
+groups() ->
+ [{mib_storage, [],
+ [{group, mib_storage_ets}, {group, mib_storage_dets},
+ {group, mib_storage_mnesia},
+ {group, mib_storage_size_check_ets},
+ {group, mib_storage_size_check_dets},
+ {group, mib_storage_size_check_mnesia},
+ {group, mib_storage_varm_dets},
+ {group, mib_storage_varm_mnesia}]},
+ {mib_storage_ets, [], mib_storage_ets_cases()},
+ {mib_storage_dets, [], mib_storage_dets_cases()},
+ {mib_storage_mnesia, [], mib_storage_mnesia_cases()},
+ {mib_storage_size_check_ets, [],
+ mse_size_check_cases()},
+ {mib_storage_size_check_dets, [],
+ msd_size_check_cases()},
+ {mib_storage_size_check_mnesia, [],
+ msm_size_check_cases()},
+ {mib_storage_varm_dets, [],
+ varm_mib_storage_dets_cases()},
+ {mib_storage_varm_mnesia, [],
+ varm_mib_storage_mnesia_cases()},
+ {test_v1, [], v1_cases()}, {test_v2, [], v2_cases()},
+ {test_v1_v2, [], v1_v2_cases()},
+ {test_v3, [], v3_cases()},
+ {test_multi_threaded, [], mt_cases()},
+ {multiple_reqs, [], mul_cases()},
+ {multiple_reqs_2, [], mul_cases_2()},
+ {v2_inform, [], [v2_inform_i]},
+ {v3_security, [],
+ [v3_crypto_basic, v3_md5_auth, v3_sha_auth,
+ v3_des_priv]},
+ {standard_mibs, [],
+ [snmp_standard_mib, snmp_community_mib,
+ snmp_framework_mib, snmp_target_mib,
+ snmp_notification_mib, snmp_view_based_acm_mib]},
+ {standard_mibs_2, [],
+ [snmpv2_mib_2, snmp_community_mib_2,
+ snmp_framework_mib_2, snmp_target_mib_2,
+ snmp_notification_mib_2, snmp_view_based_acm_mib_2]},
+ {standard_mibs_3, [],
+ [snmpv2_mib_3, snmp_framework_mib_3, snmp_mpd_mib_3,
+ snmp_target_mib_3, snmp_notification_mib_3,
+ snmp_view_based_acm_mib_3, snmp_user_based_sm_mib_3]},
+ {reported_bugs, [],
+ [otp_1128, otp_1129, otp_1131, otp_1162, otp_1222,
+ otp_1298, otp_1331, otp_1338, otp_1342, otp_2776,
+ otp_2979, otp_3187, otp_3725]},
+ {reported_bugs_2, [],
+ [otp_1128_2, otp_1129_2, otp_1131_2, otp_1162_2,
+ otp_1222_2, otp_1298_2, otp_1331_2, otp_1338_2,
+ otp_1342_2, otp_2776_2, otp_2979_2, otp_3187_2]},
+ {reported_bugs_3, [],
+ [otp_1128_3, otp_1129_3, otp_1131_3, otp_1162_3,
+ otp_1222_3, otp_1298_3, otp_1331_3, otp_1338_3,
+ otp_1342_3, otp_2776_3, otp_2979_3, otp_3187_3,
+ otp_3542]},
+ {tickets, [], [{group, otp_4394}]},
+ {otp_4394, [], [otp_4394_test]}].
+
+init_per_group(otp_4394, Config) ->
+ init_otp_4394(Config);
+init_per_group(v2_inform, Config) ->
+ init_v2_inform(Config);
+init_per_group(multiple_reqs_2, Config) ->
+ init_mul(Config);
+init_per_group(multiple_reqs, Config) ->
+ init_mul(Config);
+init_per_group(test_multi_threaded, Config) ->
+ init_mt(Config);
+init_per_group(test_v3, Config) ->
+ init_v3(Config);
+init_per_group(test_v1_v2, Config) ->
+ init_v1_v2(Config);
+init_per_group(test_v2, Config) ->
+ init_v2(Config);
+init_per_group(test_v1, Config) ->
+ init_v1(Config);
+init_per_group(mib_storage_varm_mnesia, Config) ->
+ init_varm_mib_storage_mnesia(Config);
+init_per_group(mib_storage_varm_dets, Config) ->
+ init_varm_mib_storage_dets(Config);
+init_per_group(mib_storage_size_check_mnesia, Config) ->
+ init_size_check_msm(Config);
+init_per_group(mib_storage_size_check_dets, Config) ->
+ init_size_check_msd(Config);
+init_per_group(mib_storage_size_check_ets, Config) ->
+ init_size_check_mse(Config);
+init_per_group(mib_storage_mnesia, Config) ->
+ init_mib_storage_mnesia(Config);
+init_per_group(mib_storage_dets, Config) ->
+ init_mib_storage_dets(Config);
+init_per_group(mib_storage_ets, Config) ->
+ init_mib_storage_ets(Config);
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(otp_4394, Config) ->
+ finish_otp_4394(Config);
+end_per_group(v2_inform, Config) ->
+ finish_v2_inform(Config);
+end_per_group(multiple_reqs_2, Config) ->
+ finish_mul(Config);
+end_per_group(multiple_reqs, Config) ->
+ finish_mul(Config);
+end_per_group(test_multi_threaded, Config) ->
+ finish_mt(Config);
+end_per_group(test_v3, Config) ->
+ finish_v3(Config);
+end_per_group(test_v1_v2, Config) ->
+ finish_v1_v2(Config);
+end_per_group(test_v2, Config) ->
+ finish_v2(Config);
+end_per_group(test_v1, Config) ->
+ finish_v1(Config);
+end_per_group(mib_storage_varm_mnesia, Config) ->
+ finish_varm_mib_storage_mnesia(Config);
+end_per_group(mib_storage_varm_dets, Config) ->
+ finish_varm_mib_storage_dets(Config);
+end_per_group(mib_storage_size_check_mnesia, Config) ->
+ finish_size_check_msm(Config);
+end_per_group(mib_storage_size_check_dets, Config) ->
+ finish_size_check_msd(Config);
+end_per_group(mib_storage_size_check_ets, Config) ->
+ finish_size_check_mse(Config);
+end_per_group(mib_storage_mnesia, Config) ->
+ finish_mib_storage_mnesia(Config);
+end_per_group(mib_storage_dets, Config) ->
+ finish_mib_storage_dets(Config);
+end_per_group(mib_storage_ets, Config) ->
+ finish_mib_storage_ets(Config);
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) when list(Config) ->
Dog = ?t:timetrap(?t:minutes(6)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) when list(Config) ->
+end_per_testcase(_Case, Config) when list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
Config.
-cases() ->
- case ?OSTYPE() of
- vxworks ->
- %% No crypto app, so skip v3 testcases
- [
- app_info,
- test_v1, test_v2, test_v1_v2,
- test_multi_threaded,
- mib_storage,
- tickets];
- _Else ->
- [
- app_info,
- test_v1, test_v2, test_v1_v2, test_v3,
- test_multi_threaded,
- mib_storage,
- tickets
- ]
- end.
+cases() ->
+case ?OSTYPE() of
+ vxworks ->
+ [app_info, {group, test_v1}, {group, test_v2},
+ {group, test_v1_v2}, {group, test_multi_threaded},
+ {group, mib_storage}, {group, tickets}];
+ _Else ->
+ [app_info, {group, test_v1}, {group, test_v2},
+ {group, test_v1_v2}, {group, test_v3},
+ {group, test_multi_threaded}, {group, mib_storage},
+ {group, tickets}]
+end.
%%%-----------------------------------------------------------------
@@ -460,144 +586,56 @@ delete_mib_storage_mnesia_tables() ->
%% <base>, and a second version <base>_2. There may be several
%% versions as well, <base>_N.
%%-----------------------------------------------------------------
-mib_storage(suite) -> [
- mib_storage_ets,
- mib_storage_dets,
- mib_storage_mnesia,
- mib_storage_size_check_ets,
- mib_storage_size_check_dets,
- mib_storage_size_check_mnesia,
- mib_storage_varm_dets,
- mib_storage_varm_mnesia
- ].
-
-mib_storage_ets(suite) -> {req, [], {conf, init_mib_storage_ets,
- mib_storage_ets_cases(),
- finish_mib_storage_ets}}.
-
-mib_storage_dets(suite) -> {req, [], {conf, init_mib_storage_dets,
- mib_storage_dets_cases(),
- finish_mib_storage_dets}}.
-
-mib_storage_mnesia(suite) -> {req, [], {conf, init_mib_storage_mnesia,
- mib_storage_mnesia_cases(),
- finish_mib_storage_mnesia}}.
-
-mib_storage_size_check_ets(suite) ->
- {req, [], {conf,
- init_size_check_mse,
- mse_size_check_cases(),
- finish_size_check_mse}}.
-
-mib_storage_size_check_dets(suite) ->
- {req, [], {conf,
- init_size_check_msd,
- msd_size_check_cases(),
- finish_size_check_msd}}.
-
-mib_storage_size_check_mnesia(suite) ->
- {req, [], {conf,
- init_size_check_msm,
- msm_size_check_cases(),
- finish_size_check_msm}}.
-
-mib_storage_varm_dets(suite) ->
- {req, [], {conf,
- init_varm_mib_storage_dets,
- varm_mib_storage_dets_cases(),
- finish_varm_mib_storage_dets}}.
-
-mib_storage_varm_mnesia(suite) ->
- {req, [], {conf,
- init_varm_mib_storage_mnesia,
- varm_mib_storage_mnesia_cases(),
- finish_varm_mib_storage_mnesia}}.
-
-mib_storage_ets_cases() ->
- [
- mse_simple,
- mse_v1_processing,
- mse_big,
- mse_big2,
- mse_loop_mib,
- mse_api,
- mse_sa_register,
- mse_v1_trap,
- mse_sa_error,
- mse_next_across_sa,
- mse_undo,
- mse_standard_mib,
- mse_community_mib,
- mse_framework_mib,
- mse_target_mib,
- mse_notification_mib,
- mse_view_based_acm_mib,
- mse_sparse_table,
- mse_me_of,
- mse_mib_of].
-
-mib_storage_dets_cases() ->
- [
- msd_simple,
- msd_v1_processing,
- msd_big,
- msd_big2,
- msd_loop_mib,
- msd_api,
- msd_sa_register,
- msd_v1_trap,
- msd_sa_error,
- msd_next_across_sa,
- msd_undo,
- msd_standard_mib,
- msd_community_mib,
- msd_framework_mib,
- msd_target_mib,
- msd_notification_mib,
- msd_view_based_acm_mib,
- msd_sparse_table,
- msd_me_of,
- msd_mib_of
- ].
-
-mib_storage_mnesia_cases() ->
- [
- msm_simple,
- msm_v1_processing,
- msm_big,
- msm_big2,
- msm_loop_mib,
- msm_api,
- msm_sa_register,
- msm_v1_trap,
- msm_sa_error,
- msm_next_across_sa,
- msm_undo,
- msm_standard_mib,
- msm_community_mib,
- msm_framework_mib,
- msm_target_mib,
- msm_notification_mib,
- msm_view_based_acm_mib,
- msm_sparse_table,
- msm_me_of,
- msm_mib_of
- ].
-
-mse_size_check_cases() ->
- [mse_size_check].
-
-msd_size_check_cases() ->
- [msd_size_check].
-
-msm_size_check_cases() ->
- [msm_size_check].
-
-varm_mib_storage_dets_cases() ->
- [msd_varm_mib_start].
-
-varm_mib_storage_mnesia_cases() ->
- [msm_varm_mib_start].
+
+
+
+
+
+
+
+
+
+mib_storage_ets_cases() ->
+[mse_simple, mse_v1_processing, mse_big, mse_big2,
+ mse_loop_mib, mse_api, mse_sa_register, mse_v1_trap,
+ mse_sa_error, mse_next_across_sa, mse_undo,
+ mse_standard_mib, mse_community_mib, mse_framework_mib,
+ mse_target_mib, mse_notification_mib,
+ mse_view_based_acm_mib, mse_sparse_table, mse_me_of,
+ mse_mib_of].
+
+mib_storage_dets_cases() ->
+[msd_simple, msd_v1_processing, msd_big, msd_big2,
+ msd_loop_mib, msd_api, msd_sa_register, msd_v1_trap,
+ msd_sa_error, msd_next_across_sa, msd_undo,
+ msd_standard_mib, msd_community_mib, msd_framework_mib,
+ msd_target_mib, msd_notification_mib,
+ msd_view_based_acm_mib, msd_sparse_table, msd_me_of,
+ msd_mib_of].
+
+mib_storage_mnesia_cases() ->
+[msm_simple, msm_v1_processing, msm_big, msm_big2,
+ msm_loop_mib, msm_api, msm_sa_register, msm_v1_trap,
+ msm_sa_error, msm_next_across_sa, msm_undo,
+ msm_standard_mib, msm_community_mib, msm_framework_mib,
+ msm_target_mib, msm_notification_mib,
+ msm_view_based_acm_mib, msm_sparse_table, msm_me_of,
+ msm_mib_of].
+
+mse_size_check_cases() ->
+[mse_size_check].
+
+msd_size_check_cases() ->
+[msd_size_check].
+
+msm_size_check_cases() ->
+[msm_size_check].
+
+varm_mib_storage_dets_cases() ->
+[msd_varm_mib_start].
+
+varm_mib_storage_mnesia_cases() ->
+[msm_varm_mib_start].
init_mib_storage_ets(Config) when list(Config) ->
?LOG("init_mib_storage_ets -> entry", []),
@@ -1099,20 +1137,14 @@ app_dir(App) ->
end.
-test_v1(suite) -> {req, [], {conf, init_v1, v1_cases(), finish_v1}}.
%v1_cases() -> [loop_mib];
-v1_cases() ->
- [simple,
- db_notify_client,
- v1_processing, big, big2, loop_mib,
- api, subagent, mnesia, multiple_reqs,
- sa_register, v1_trap, sa_error, next_across_sa, undo, reported_bugs,
- standard_mibs, sparse_table, cnt_64,
- opaque,
- % opaque].
-
- change_target_addr_config].
+v1_cases() ->
+[simple, db_notify_client, v1_processing, big, big2,
+ loop_mib, api, subagent, mnesia, {group, multiple_reqs},
+ sa_register, v1_trap, sa_error, next_across_sa, undo,
+ {group, reported_bugs}, {group, standard_mibs},
+ sparse_table, cnt_64, opaque, change_target_addr_config].
init_v1(Config) when list(Config) ->
?line SaNode = ?config(snmp_sa, Config),
@@ -1129,15 +1161,15 @@ finish_v1(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v2(suite) -> {req, [], {conf, init_v2, v2_cases(), finish_v2}}.
%v2_cases() -> [loop_mib_2];
-v2_cases() ->
- [simple_2, v2_processing, big_2, big2_2, loop_mib_2,
- api_2, subagent_2, mnesia_2,
- multiple_reqs_2, sa_register_2, v2_trap, v2_inform, sa_error_2,
- next_across_sa_2, undo_2, reported_bugs_2, standard_mibs_2,
- v2_types, implied, sparse_table_2, cnt_64_2, opaque_2, v2_caps].
+v2_cases() ->
+[simple_2, v2_processing, big_2, big2_2, loop_mib_2,
+ api_2, subagent_2, mnesia_2, {group, multiple_reqs_2},
+ sa_register_2, v2_trap, {group, v2_inform}, sa_error_2,
+ next_across_sa_2, undo_2, {group, reported_bugs_2},
+ {group, standard_mibs_2}, v2_types, implied,
+ sparse_table_2, cnt_64_2, opaque_2, v2_caps].
init_v2(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1154,10 +1186,9 @@ finish_v2(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v1_v2(suite) -> {req, [], {conf, init_v1_v2, v1_v2_cases(), finish_v1_v2}}.
-v1_v2_cases() ->
- [simple_bi].
+v1_v2_cases() ->
+[simple_bi].
init_v1_v2(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1174,16 +1205,16 @@ finish_v1_v2(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_v3(suite) -> {req, [], {conf, init_v3, v3_cases(), finish_v3}}.
%v3_cases() -> [loop_mib_3];
-v3_cases() ->
- [simple_3, v3_processing,
- big_3, big2_3, api_3, subagent_3, mnesia_3, loop_mib_3,
- multiple_reqs_3, sa_register_3, v3_trap, v3_inform, sa_error_3,
- next_across_sa_3, undo_3, reported_bugs_3, standard_mibs_3,
- v3_security,
- v2_types_3, implied_3, sparse_table_3, cnt_64_3, opaque_3, v2_caps_3].
+v3_cases() ->
+[simple_3, v3_processing, big_3, big2_3, api_3,
+ subagent_3, mnesia_3, loop_mib_3, multiple_reqs_3,
+ sa_register_3, v3_trap, v3_inform, sa_error_3,
+ next_across_sa_3, undo_3, {group, reported_bugs_3},
+ {group, standard_mibs_3}, {group, v3_security},
+ v2_types_3, implied_3, sparse_table_3, cnt_64_3,
+ opaque_3, v2_caps_3].
init_v3(Config) when list(Config) ->
%% Make sure crypto works, otherwise start_agent will fail
@@ -1221,10 +1252,9 @@ finish_v3(Config) when list(Config) ->
delete_files(C1),
lists:keydelete(vsn, 1, C1).
-test_multi_threaded(suite) -> {req, [], {conf, init_mt, mt_cases(), finish_mt}}.
-mt_cases() ->
- [multi_threaded, mt_trap].
+mt_cases() ->
+[multi_threaded, mt_trap].
init_mt(Config) when list(Config) ->
SaNode = ?config(snmp_sa, Config),
@@ -1739,21 +1769,19 @@ mnesia_2(X) -> mnesia(X).
mnesia_3(X) -> mnesia(X).
-multiple_reqs(suite) ->
- {req, [], {conf, init_mul, mul_cases(), finish_mul}}.
-mul_cases() ->
- [mul_get, mul_get_err, mul_next, mul_next_err, mul_set_err].
+mul_cases() ->
+[mul_get, mul_get_err, mul_next, mul_next_err,
+ mul_set_err].
-multiple_reqs_2(suite) ->
- {req, [], {conf, init_mul, mul_cases_2(), finish_mul}}.
multiple_reqs_3(_X) ->
{req, [], {conf, init_mul, mul_cases_3(), finish_mul}}.
-mul_cases_2() ->
- [mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2, mul_set_err_2].
+mul_cases_2() ->
+[mul_get_2, mul_get_err_2, mul_next_2, mul_next_err_2,
+ mul_set_err_2].
mul_cases_3() ->
@@ -1939,8 +1967,6 @@ v2_trap(Config) when list(Config) ->
v3_trap(X) ->
v2_trap(X).
-v2_inform(suite) ->
- {req, [], {conf, init_v2_inform, [v2_inform_i], finish_v2_inform}}.
v3_inform(_X) ->
%% v2_inform(X).
@@ -2112,7 +2138,6 @@ v3_processing(Config) when list(Config) ->
%% accomplished by the first inform sent. That one will generate a
%% report, which makes it in sync. The notification-generating
%% application times out, and send again. This time it'll work.
-v3_security(suite) -> [v3_crypto_basic, v3_md5_auth, v3_sha_auth, v3_des_priv].
v3_crypto_basic(suite) -> [];
v3_crypto_basic(_Config) ->
@@ -3591,22 +3616,8 @@ bad_return() ->
%%% Note that many of the functions in the standard mib is
%%% already tested by the normal tests.
%%%-----------------------------------------------------------------
-standard_mibs(suite) ->
- [snmp_standard_mib, snmp_community_mib,
- snmp_framework_mib,
- snmp_target_mib, snmp_notification_mib,
- snmp_view_based_acm_mib].
-
-standard_mibs_2(suite) ->
- [snmpv2_mib_2, snmp_community_mib_2,
- snmp_framework_mib_2,
- snmp_target_mib_2, snmp_notification_mib_2,
- snmp_view_based_acm_mib_2].
-
-standard_mibs_3(suite) ->
- [snmpv2_mib_3,snmp_framework_mib_3, snmp_mpd_mib_3,
- snmp_target_mib_3, snmp_notification_mib_3,
- snmp_view_based_acm_mib_3, snmp_user_based_sm_mib_3].
+
+
%%-----------------------------------------------------------------
%% For this test, the agent is configured for v1.
@@ -4527,27 +4538,12 @@ loop_it_2(Oid, N) ->
%%% Testing of reported bugs and other tickets.
%%%-----------------------------------------------------------------
-reported_bugs(suite) ->
- [otp_1128, otp_1129, otp_1131, otp_1162,
- otp_1222, otp_1298, otp_1331, otp_1338,
- otp_1342, otp_2776, otp_2979, otp_3187, otp_3725].
-reported_bugs_2(suite) ->
- [otp_1128_2, otp_1129_2, otp_1131_2, otp_1162_2,
- otp_1222_2, otp_1298_2, otp_1331_2, otp_1338_2,
- otp_1342_2, otp_2776_2, otp_2979_2, otp_3187_2].
-reported_bugs_3(suite) ->
- [otp_1128_3, otp_1129_3, otp_1131_3, otp_1162_3,
- otp_1222_3, otp_1298_3, otp_1331_3, otp_1338_3,
- otp_1342_3, otp_2776_3, otp_2979_3, otp_3187_3,
- otp_3542].
%% These are (ticket) test cases where the initiation has to be done
%% individually.
-tickets(suite) ->
- [otp_4394].
%%-----------------------------------------------------------------
%% Ticket: OTP-1128
@@ -4971,10 +4967,6 @@ otp_3725_test(MaNode) ->
%%-----------------------------------------------------------------
-otp_4394(suite) -> {req, [], {conf,
- init_otp_4394,
- [otp_4394_test],
- finish_otp_4394}}.
init_otp_4394(Config) when list(Config) ->
?DBG("init_otp_4394 -> entry with"
diff --git a/lib/snmp/test/snmp_app_test.erl b/lib/snmp/test/snmp_app_test.erl
index 5c5a5285a0..27a7b4af2e 100644
--- a/lib/snmp/test/snmp_app_test.erl
+++ b/lib/snmp/test/snmp_app_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,8 +23,9 @@
-module(snmp_app_test).
-export([
- all/1, init_suite/1, fin_suite/1,
- init_per_testcase/2, fin_per_testcase/2,
+ all/0,groups/0,init_per_group/2,end_per_group/2, init_per_suite/1,
+ end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2,
fields/1,
modules/1,
@@ -32,7 +33,7 @@
app_depend/1,
undef_funcs/1,
- start_and_stop/1,
+
start_and_stop_empty/1,
start_and_stop_with_agent/1,
start_and_stop_with_manager/1,
@@ -44,25 +45,34 @@
-include_lib("kernel/include/file.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- Cases =
- [
- fields,
- modules,
- exportall,
- app_depend,
- undef_funcs,
- start_and_stop
- ],
- {conf, init_suite, Cases, fin_suite}.
-
-init_suite(Config) when is_list(Config) ->
+all() ->
+Cases = [fields, modules, exportall, app_depend,
+ undef_funcs, {group, start_and_stop}],
+ Cases.
+
+groups() ->
+ [{start_and_stop, [],
+ [start_and_stop_empty, start_and_stop_with_agent,
+ start_and_stop_with_manager,
+ start_and_stop_with_agent_and_manager,
+ start_epmty_and_then_agent_and_manager_and_stop,
+ start_with_agent_and_then_manager_and_stop,
+ start_with_manager_and_then_agent_and_stop]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(Config) when is_list(Config) ->
?DISPLAY_SUITE_INFO(),
PrivDir = ?config(priv_dir, Config),
TopDir = filename:join(PrivDir, app),
@@ -97,9 +107,9 @@ is_app(App) ->
{error, {invalid_format, Error}}
end.
-fin_suite(suite) -> [];
-fin_suite(doc) -> [];
-fin_suite(Config) when is_list(Config) ->
+end_per_suite(suite) -> [];
+end_per_suite(doc) -> [];
+end_per_suite(Config) when is_list(Config) ->
Config.
@@ -112,7 +122,7 @@ init_per_testcase(undef_funcs, Config) ->
init_per_testcase(_Case, Config) ->
Config.
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Config.
@@ -290,6 +300,25 @@ undef_funcs(Config) when is_list(Config) ->
xref:stop(XRef),
analyze_undefined_function_calls(Undefs, Mods, []).
+valid_undef(crypto = CalledMod) ->
+ case (catch CalledMod:version()) of
+ Version when is_list(Version) ->
+ %% The called module was crypto and the version
+ %% function returns a valid value.
+ %% This means that the function is
+ %% actually undefined...
+ true;
+ _ ->
+ %% The called module was crypto but the version
+ %% function does *not* return a valid value.
+ %% This means the crypto was not actually not
+ %% build, which is an case snmp handles.
+ false
+ end;
+valid_undef(_) ->
+ true.
+
+
analyze_undefined_function_calls([], _, []) ->
ok;
analyze_undefined_function_calls([], _, AppUndefs) ->
@@ -302,14 +331,25 @@ analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs],
{Calling,Called} = AppUndef,
{Mod1,Func1,Ar1} = Calling,
{Mod2,Func2,Ar2} = Called,
- io:format("undefined function call: "
- "~n ~w:~w/~w calls ~w:~w/~w~n",
- [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
- analyze_undefined_function_calls(Undefs, AppModules,
- [AppUndef|AppUndefs]);
+ %% If the called module is crypto, then we will *not*
+ %% fail if crypto is not built (since crypto is actually
+ %% not built for all platforms)
+ case valid_undef(Mod2) of
+ true ->
+ io:format("undefined function call: "
+ "~n ~w:~w/~w calls ~w:~w/~w~n",
+ [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
+ analyze_undefined_function_calls(
+ Undefs, AppModules, [AppUndef|AppUndefs]);
+ false ->
+ io:format("skipping ~p (calling ~w:~w/~w)~n",
+ [Mod, Mod2, Func2, Ar2]),
+ analyze_undefined_function_calls(Undefs,
+ AppModules, AppUndefs)
+ end;
false ->
- io:format("dropping ~p~n", [Mod]),
- analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
+ io:format("dropping ~p~n", [Mod]),
+ analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
end.
%% This function is used simply to avoid cut-and-paste errors later...
@@ -319,16 +359,6 @@ undef_funcs_make_name(App, PostFix) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-start_and_stop(suite) ->
- [
- start_and_stop_empty,
- start_and_stop_with_agent,
- start_and_stop_with_manager,
- start_and_stop_with_agent_and_manager,
- start_epmty_and_then_agent_and_manager_and_stop,
- start_with_agent_and_then_manager_and_stop,
- start_with_manager_and_then_agent_and_stop
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/snmp/test/snmp_appup_mgr.erl b/lib/snmp/test/snmp_appup_mgr.erl
index 271d6a2847..6648ce9dbe 100644
--- a/lib/snmp/test/snmp_appup_mgr.erl
+++ b/lib/snmp/test/snmp_appup_mgr.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/snmp_appup_test.erl b/lib/snmp/test/snmp_appup_test.erl
index 18509526cf..99994a2410 100644
--- a/lib/snmp/test/snmp_appup_test.erl
+++ b/lib/snmp/test/snmp_appup_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,32 +23,46 @@
-module(snmp_appup_test).
-export([
- all/1, init_suite/1, fin_suite/1,
- init_per_testcase/2, fin_per_testcase/2,
+ all/0,
+ groups/0, init_per_group/2, end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2,
appup_file/1
]).
--include("test_server.hrl").
+-compile({no_auto_import, [error/1]}).
+
+-include_lib("common_test/include/ct.hrl").
-include("snmp_test_lib.hrl").
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
+all() ->
Cases =
[
appup_file
],
- {conf, init_suite, Cases, fin_suite}.
+ Cases.
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-init_suite(suite) -> [];
-init_suite(doc) -> [];
-init_suite(Config) when is_list(Config) ->
+init_per_suite(suite) -> [];
+init_per_suite(doc) -> [];
+init_per_suite(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
TopDir = filename:join(PrivDir, appup),
case file:make_dir(TopDir) of
@@ -76,9 +90,9 @@ file_name(App, Ext) ->
filename:join([LibDir, "ebin", atom_to_list(App) ++ Ext]).
-fin_suite(suite) -> [];
-fin_suite(doc) -> [];
-fin_suite(Config) when is_list(Config) ->
+end_per_suite(suite) -> [];
+end_per_suite(doc) -> [];
+end_per_suite(Config) when is_list(Config) ->
Config.
@@ -88,7 +102,7 @@ fin_suite(Config) when is_list(Config) ->
init_per_testcase(_Case, Config) when is_list(Config) ->
Config.
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Config.
diff --git a/lib/snmp/test/snmp_compiler_test.erl b/lib/snmp/test/snmp_compiler_test.erl
index ad77b01362..2e6020ae7a 100644
--- a/lib/snmp/test/snmp_compiler_test.erl
+++ b/lib/snmp/test/snmp_compiler_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,7 +28,7 @@
%%----------------------------------------------------------------------
%% Include files
%%----------------------------------------------------------------------
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-include_lib("snmp/include/snmp_types.hrl").
@@ -37,15 +37,17 @@
%% External exports
%%----------------------------------------------------------------------
-export([
- all/1,
- init_per_testcase/2, fin_per_testcase/2,
+ all/0,
+ groups/0, init_per_group/2, end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
description/1,
oid_conflicts/1,
imports/1,
module_identity/1,
+ agent_capabilities/1,
+ module_compliance/1,
- tickets/1,
otp_6150/1,
otp_8574/1,
otp_8595/1
@@ -78,9 +80,9 @@ init_per_testcase(_Case, Config) when is_list(Config) ->
MibDir = join(lists:reverse(["snmp_test_data"|RL])),
CompDir = join(Dir, "comp_dir/"),
?line ok = file:make_dir(CompDir),
- [{comp_dir, CompDir},{mib_dir, MibDir}|Config].
+ [{comp_dir, CompDir}, {mib_dir, MibDir} | Config].
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
CompDir = ?config(comp_dir, Config),
?line ok = ?DEL_DIR(CompDir),
lists:keydelete(comp_dir, 1, Config).
@@ -90,21 +92,27 @@ fin_per_testcase(_Case, Config) when is_list(Config) ->
%% Test case definitions
%%======================================================================
-all(suite) ->
+all() ->
[
- description,
- oid_conflicts,
- imports,
+ description,
+ oid_conflicts,
+ imports,
module_identity,
- tickets
+ agent_capabilities,
+ module_compliance,
+ {group, tickets}
].
-tickets(suite) ->
- [
- otp_6150,
- otp_8574,
- otp_8595
- ].
+groups() ->
+ [{tickets, [], [otp_6150, otp_8574, otp_8595]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%======================================================================
@@ -169,6 +177,88 @@ module_identity(Config) when is_list(Config) ->
?SKIP(not_yet_implemented).
+agent_capabilities(suite) ->
+ [];
+agent_capabilities(Config) when is_list(Config) ->
+ put(tname,agent_capabilities),
+ p("starting with Config: ~p~n", [Config]),
+
+ SnmpPrivDir = code:priv_dir(snmp),
+ SnmpMibsDir = join(SnmpPrivDir, "mibs"),
+ OtpMibsPrivDir = code:priv_dir(otp_mibs),
+ OtpMibsMibsDir = join(OtpMibsPrivDir, "mibs"),
+ Dir = ?config(mib_dir, Config),
+ AcMib = join(Dir,"AC-TEST-MIB.mib"),
+ ?line {ok, MibFile1} = snmpc:compile(AcMib, [options,
+ version,
+ {i, [SnmpMibsDir, OtpMibsMibsDir]},
+ {outdir, Dir},
+ {verbosity, trace}]),
+ ?line {ok, Mib1} = snmp_misc:read_mib(MibFile1),
+ ?line {ok, MibFile2} = snmpc:compile(AcMib, [options,
+ version,
+ agent_capabilities,
+ {i, [SnmpMibsDir, OtpMibsMibsDir]},
+ {outdir, Dir},
+ {verbosity, trace}]),
+ ?line {ok, Mib2} = snmp_misc:read_mib(MibFile2),
+ MEDiff = Mib2#mib.mes -- Mib1#mib.mes,
+ %% This is a rather pathetic test, but it is somthing...
+ io:format("agent_capabilities -> "
+ "~n MEDiff: ~p"
+ "~n Mib1: ~p"
+ "~n Mib2: ~p"
+ "~n", [MEDiff, Mib1, Mib2]),
+ case length(MEDiff) of
+ 2 ->
+ ok;
+ _BadLen ->
+ exit({unexpected_mes, MEDiff})
+ end,
+ ok.
+
+
+module_compliance(suite) ->
+ [];
+module_compliance(Config) when is_list(Config) ->
+ put(tname,module_compliance),
+ p("starting with Config: ~p~n", [Config]),
+
+ SnmpPrivDir = code:priv_dir(snmp),
+ SnmpMibsDir = join(SnmpPrivDir, "mibs"),
+ OtpMibsPrivDir = code:priv_dir(otp_mibs),
+ OtpMibsMibsDir = join(OtpMibsPrivDir, "mibs"),
+ Dir = ?config(mib_dir, Config),
+ AcMib = join(Dir,"MC-TEST-MIB.mib"),
+ ?line {ok, MibFile1} = snmpc:compile(AcMib, [options,
+ version,
+ {i, [SnmpMibsDir, OtpMibsMibsDir]},
+ {outdir, Dir},
+ {verbosity, trace}]),
+ ?line {ok, Mib1} = snmp_misc:read_mib(MibFile1),
+ ?line {ok, MibFile2} = snmpc:compile(AcMib, [options,
+ version,
+ module_compliance,
+ {i, [SnmpMibsDir, OtpMibsMibsDir]},
+ {outdir, Dir},
+ {verbosity, trace}]),
+ ?line {ok, Mib2} = snmp_misc:read_mib(MibFile2),
+ MEDiff = Mib2#mib.mes -- Mib1#mib.mes,
+ %% This is a rather pathetic test, but it is somthing...
+ io:format("agent_capabilities -> "
+ "~n MEDiff: ~p"
+ "~n Mib1: ~p"
+ "~n Mib2: ~p"
+ "~n", [MEDiff, Mib1, Mib2]),
+ case length(MEDiff) of
+ 1 ->
+ ok;
+ _BadLen ->
+ exit({unexpected_mes, MEDiff})
+ end,
+ ok.
+
+
otp_6150(suite) ->
[];
otp_6150(Config) when is_list(Config) ->
@@ -257,7 +347,7 @@ LAST-UPDATED \"0005290000Z\"
Ericsson Utvecklings AB
Open System
Box 1505
-SE-125 25 �LVSJ�\"
+SE-125 25 ÄLVSJÖ\"
DESCRIPTION
\" Objects for management \"
diff --git a/lib/snmp/test/snmp_conf_test.erl b/lib/snmp/test/snmp_conf_test.erl
index d2f9631947..c4341d8d7e 100644
--- a/lib/snmp/test/snmp_conf_test.erl
+++ b/lib/snmp/test/snmp_conf_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,7 +26,7 @@
%%----------------------------------------------------------------------
%% Include files
%%----------------------------------------------------------------------
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-include_lib("snmp/include/STANDARD-MIB.hrl").
@@ -37,8 +37,8 @@
%% External exports
%%----------------------------------------------------------------------
-export([
- all/1,
- init_per_testcase/2, fin_per_testcase/2,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
check_mandatory/1,
check_integer1/1,
@@ -80,32 +80,28 @@
init_per_testcase(_Case, Config) when is_list(Config) ->
Config.
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Config.
%%======================================================================
%% Test case definitions
%%======================================================================
-all(suite) ->
- [
- check_mandatory,
- check_integer1,
- check_integer2,
- check_string1,
- check_string2,
- check_atom,
- check_ip,
- check_taddress,
- check_packet_size,
- check_oid,
- check_sec_model1,
- check_sec_model2,
- check_sec_level,
- check_timer,
-
- read,
- read_files
- ].
+all() ->
+[check_mandatory, check_integer1, check_integer2,
+ check_string1, check_string2, check_atom, check_ip,
+ check_taddress, check_packet_size, check_oid,
+ check_sec_model1, check_sec_model2, check_sec_level,
+ check_timer, read, read_files].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%======================================================================
diff --git a/lib/snmp/test/snmp_log_test.erl b/lib/snmp/test/snmp_log_test.erl
index 91bdc3e849..b692017407 100644
--- a/lib/snmp/test/snmp_log_test.erl
+++ b/lib/snmp/test/snmp_log_test.erl
@@ -29,7 +29,7 @@
%%----------------------------------------------------------------------
%% Include files
%%----------------------------------------------------------------------
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-define(SNMP_USE_V3, true).
-include_lib("snmp/include/snmp_types.hrl").
@@ -40,19 +40,19 @@
%% External exports
%%----------------------------------------------------------------------
-export([
- init_per_testcase/2, fin_per_testcase/2,
+ init_per_testcase/2, end_per_testcase/2,
- all/1,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
open_and_close/1,
- open_write_and_close/1,
+
open_write_and_close1/1,
open_write_and_close2/1,
open_write_and_close3/1,
open_write_and_close4/1,
- log_to_io/1,
+
log_to_io1/1,
log_to_io2/1,
- log_to_txt/1,
+
log_to_txt1/1,
log_to_txt2/1,
log_to_txt3/1
@@ -97,7 +97,7 @@ init_per_testcase(Case, Config) when is_list(Config) ->
Dog = ?WD_START(?MINS(5)),
[{log_dir, CaseDir}, {watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
%% Leave the dirs created above (enable debugging of the test case(s))
Dog = ?config(watchdog, Config),
?WD_STOP(Dog),
@@ -108,37 +108,30 @@ fin_per_testcase(_Case, Config) when is_list(Config) ->
%% Test case definitions
%%======================================================================
%% ?SKIP(not_yet_implemented).
-all(suite) ->
- [
- open_and_close,
- open_write_and_close,
- log_to_io,
- log_to_txt
- ].
-
-
-open_write_and_close(suite) ->
- [
- open_write_and_close1,
- open_write_and_close2,
- open_write_and_close3,
- open_write_and_close4
- ].
-
-
-log_to_io(suite) ->
- [
- log_to_io1,
- log_to_io2
- ].
-
-
-log_to_txt(suite) ->
- [
- log_to_txt1,
- log_to_txt2,
- log_to_txt3
- ].
+all() ->
+[open_and_close, {group, open_write_and_close},
+ {group, log_to_io}, {group, log_to_txt}].
+
+groups() ->
+ [{open_write_and_close, [],
+ [open_write_and_close1, open_write_and_close2,
+ open_write_and_close3, open_write_and_close4]},
+ {log_to_io, [], [log_to_io1, log_to_io2]},
+ {log_to_txt, [],
+ [log_to_txt1, log_to_txt2, log_to_txt3]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+
+
+
+
+
%%======================================================================
diff --git a/lib/snmp/test/snmp_manager_config_test.erl b/lib/snmp/test/snmp_manager_config_test.erl
index d5dc1387f7..e38a99d413 100644
--- a/lib/snmp/test/snmp_manager_config_test.erl
+++ b/lib/snmp/test/snmp_manager_config_test.erl
@@ -31,7 +31,7 @@
%%----------------------------------------------------------------------
%% Include files
%%----------------------------------------------------------------------
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-include_lib("snmp/src/manager/snmpm_usm.hrl").
@@ -42,10 +42,10 @@
%% -compile(export_all).
-export([
- all/1,
- init_per_testcase/2, fin_per_testcase/2,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
- start_and_stop/1,
+
simple_start_and_stop/1,
start_without_mandatory_opts1/1,
@@ -58,36 +58,36 @@
start_with_invalid_agents_conf_file1/1,
start_with_invalid_usm_conf_file1/1,
- normal_op/1,
+
- system/1,
+
simple_system_op/1,
- users/1,
+
register_user_using_file/1,
register_user_using_function/1,
register_user_failed_using_function1/1,
- agents/1,
+
register_agent_using_file/1,
register_agent_using_function/1,
register_agent_failed_using_function1/1,
- usm_users/1,
+
register_usm_user_using_file/1,
register_usm_user_using_function/1,
register_usm_user_failed_using_function1/1,
update_usm_user_info/1,
- counter/1,
+
create_and_increment/1,
- stats_counter/1,
+
stats_create_and_increment/1,
- tickets/1,
+
otp_7219/1,
- otp_8395/1,
+
otp_8395_1/1,
otp_8395_2/1,
otp_8395_3/1,
@@ -150,8 +150,8 @@ init_per_testcase(Case, Config) when is_list(Config) ->
{manager_log_dir, MgrLogDir} | Config].
-fin_per_testcase(Case, Config) when is_list(Config) ->
- p("fin_per_testcase -> Case: ~p", [Case]),
+end_per_testcase(Case, Config) when is_list(Config) ->
+ p("end_per_testcase -> Case: ~p", [Case]),
%% The cleanup is removed due to some really discusting NFS behaviour...
%% CaseTopDir = ?config(manager_dir, Config),
%% ?line ok = ?DEL_DIR(CaseTopDir),
@@ -163,33 +163,60 @@ fin_per_testcase(Case, Config) when is_list(Config) ->
%%======================================================================
% all(doc) ->
% "The top snmp manager config test case";
-all(suite) ->
- [
- start_and_stop,
- normal_op,
- tickets
- ].
+all() ->
+[{group, start_and_stop}, {group, normal_op},
+ {group, tickets}].
+
+groups() ->
+ [{start_and_stop, [],
+ [simple_start_and_stop,
+ start_without_mandatory_opts1,
+ start_without_mandatory_opts2,
+ start_with_all_valid_opts, start_with_unknown_opts,
+ start_with_incorrect_opts,
+ start_with_invalid_manager_conf_file1,
+ start_with_invalid_users_conf_file1,
+ start_with_invalid_agents_conf_file1,
+ start_with_invalid_usm_conf_file1]},
+ {normal_op, [],
+ [{group, system},
+ {group, agents},
+ {group, users},
+ {group, usm_users},
+ {group, counter},
+ {group, stats_counter}]},
+ {system, [], [simple_system_op]},
+ {users, [],
+ [register_user_using_file,
+ register_user_using_function,
+ register_user_failed_using_function1]},
+ {agents, [],
+ [register_agent_using_file,
+ register_agent_using_function,
+ register_agent_failed_using_function1]},
+ {usm_users, [],
+ [register_usm_user_using_file,
+ register_usm_user_using_function,
+ register_usm_user_failed_using_function1,
+ update_usm_user_info]},
+ {counter, [], [create_and_increment]},
+ {stats_counter, [], [stats_create_and_increment]},
+ {tickets, [], [otp_7219, {group, otp_8395}]},
+ {otp_8395, [],
+ [otp_8395_1, otp_8395_2, otp_8395_3, otp_8395_4]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%======================================================================
%% Test functions
%%======================================================================
-start_and_stop(doc) ->
- "A collection of start and stop tests";
-start_and_stop(suite) ->
- [
- simple_start_and_stop,
- start_without_mandatory_opts1,
- start_without_mandatory_opts2,
- start_with_all_valid_opts,
- start_with_unknown_opts,
- start_with_incorrect_opts,
- start_with_invalid_manager_conf_file1,
- start_with_invalid_users_conf_file1,
- start_with_invalid_agents_conf_file1,
- start_with_invalid_usm_conf_file1
- ].
%%
@@ -794,7 +821,10 @@ start_with_invalid_users_conf_file1(Conf) when is_list(Conf) ->
p("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
- DbDir = ?config(manager_db_dir, Conf),
+ DbDir = ?config(manager_db_dir, Conf),
+
+ verify_dir_existing(conf, ConfDir),
+ verify_dir_existing(db, DbDir),
Opts = [{versions, [v1]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
@@ -895,7 +925,10 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) ->
p("start"),
process_flag(trap_exit, true),
ConfDir = ?config(manager_conf_dir, Conf),
- DbDir = ?config(manager_db_dir, Conf),
+ DbDir = ?config(manager_db_dir, Conf),
+
+ verify_dir_existing(conf, ConfDir),
+ verify_dir_existing(db, DbDir),
Opts = [{versions, [v1]},
{config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
@@ -1641,29 +1674,12 @@ start_with_invalid_usm_conf_file1(Conf) when is_list(Conf) ->
%% ---
%%
-normal_op(doc) ->
- "A collection of tests for normal operation";
-normal_op(suite) ->
- [
- system,
- agents,
- users,
- usm_users,
- counter,
- stats_counter
- ].
%%
%% ---
%%
-system(doc) ->
- "Various system related operations with the snmp manager config";
-system(suite) ->
- [
- simple_system_op
- ].
simple_system_op(suite) -> [];
simple_system_op(doc) ->
@@ -1702,14 +1718,6 @@ simple_system_op(Conf) when is_list(Conf) ->
%% ---
%%
-users(doc) ->
- "Various users related operations with the snmp manager config";
-users(suite) ->
- [
- register_user_using_file,
- register_user_using_function,
- register_user_failed_using_function1
- ].
%%
@@ -1764,14 +1772,6 @@ register_user_failed_using_function1(Conf) when is_list(Conf) ->
%% ---
%%
-agents(doc) ->
- "Various agents related operations with the snmp manager config";
-agents(suite) ->
- [
- register_agent_using_file,
- register_agent_using_function,
- register_agent_failed_using_function1
- ].
%%
@@ -1950,15 +1950,6 @@ register_agent_failed_using_function1(Conf) when is_list(Conf) ->
%% ---
%%
-usm_users(doc) ->
- "Various USM users related operations with the snmp manager config";
-usm_users(suite) ->
- [
- register_usm_user_using_file,
- register_usm_user_using_function,
- register_usm_user_failed_using_function1,
- update_usm_user_info
- ].
%%
@@ -2042,7 +2033,6 @@ register_usm_user_using_file(Conf) when is_list(Conf) ->
%% --
p("done"),
ok.
-%% ?SKIP(not_yet_implemented).
%%
@@ -2208,12 +2198,6 @@ update_usm_user_info(Conf) when is_list(Conf) ->
%% ---
%%
-counter(doc) ->
- "Various counter related operations with the snmp manager config";
-counter(suite) ->
- [
- create_and_increment
- ].
%%
@@ -2258,13 +2242,6 @@ create_and_increment(Conf) when is_list(Conf) ->
%% ---
%%
-stats_counter(doc) ->
- "Various statistic counter related operations with the "
- "snmp manager config";
-stats_counter(suite) ->
- [
- stats_create_and_increment
- ].
%%
@@ -2323,11 +2300,6 @@ loop(N, _, F) when (N > 0) andalso is_function(F) ->
%% Ticket test-cases
%%======================================================================
-tickets(suite) ->
- [
- otp_7219,
- otp_8395
- ].
otp_7219(suite) ->
@@ -2379,13 +2351,6 @@ otp_7219(Config) when is_list(Config) ->
-otp_8395(suite) ->
- [
- otp_8395_1,
- otp_8395_2,
- otp_8395_3,
- otp_8395_4
- ].
otp_8395_1(suite) -> [];
otp_8395_1(doc) ->
@@ -2696,9 +2661,21 @@ write_usm_conf2(Dir, Str) ->
write_conf_file(Dir, File, Str) ->
- ?line {ok, Fd} = file:open(filename:join(Dir, File), write),
- ?line ok = io:format(Fd, "~s", [Str]),
- file:close(Fd).
+ case file:open(filename:join(Dir, File), write) of
+ {ok, Fd} ->
+ ?line ok = io:format(Fd, "~s", [Str]),
+ file:close(Fd);
+ {error, Reason} ->
+ Info =
+ [{dir, Dir, case (catch file:read_file_info(Dir)) of
+ {ok, FI} ->
+ FI;
+ _ ->
+ undefined
+ end},
+ {file, File}],
+ exit({failed_writing_conf_file, Info, Reason})
+ end.
maybe_start_crypto() ->
@@ -2724,6 +2701,17 @@ maybe_stop_crypto() ->
%% ------
+verify_dir_existing(DirName, Dir) ->
+ case file:read_file_info(Dir) of
+ {ok, _} ->
+ ok;
+ {error, Reason} ->
+ exit({non_existing_dir, DirName, Dir, Reason})
+ end.
+
+
+%% ------
+
str(X) ->
lists:flatten(io_lib:format("~w", [X])).
diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl
index cef96417dc..50836db731 100644
--- a/lib/snmp/test/snmp_manager_test.erl
+++ b/lib/snmp/test/snmp_manager_test.erl
@@ -31,7 +31,7 @@
%% Include files
%%----------------------------------------------------------------------
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
-include("snmp_test_data/Test2.hrl").
@@ -43,10 +43,10 @@
%% External exports
%%----------------------------------------------------------------------
-export([
- all/1,
- init_per_testcase/2, fin_per_testcase/2,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
- start_and_stop_tests/1,
+
simple_start_and_stop1/1,
simple_start_and_stop2/1,
simple_start_and_monitor_crash1/1,
@@ -54,49 +54,49 @@
notify_started01/1,
notify_started02/1,
- user_tests/1,
+
register_user1/1,
- agent_tests/1,
+
register_agent1/1,
register_agent2/1,
- misc_tests/1,
+
info/1,
- request_tests/1,
+
- get_tests/1,
+
simple_sync_get1/1,
simple_sync_get2/1,
simple_async_get1/1,
simple_async_get2/1,
- get_next_tests/1,
+
simple_sync_get_next1/1,
simple_sync_get_next2/1,
simple_async_get_next1/1,
simple_async_get_next2/1,
- set_tests/1,
+
simple_sync_set1/1,
simple_sync_set2/1,
simple_async_set1/1,
simple_async_set2/1,
- bulk_tests/1,
+
simple_sync_get_bulk1/1,
simple_sync_get_bulk2/1,
simple_async_get_bulk1/1,
simple_async_get_bulk2/1,
- misc_request_tests/1,
+
misc_async1/1,
misc_async2/1,
discovery/1,
- event_tests/1,
+
trap1/1,
trap2/1,
@@ -109,10 +109,10 @@
report/1,
- tickets/1,
- otp8015/1,
+
+
otp8015_1/1,
- otp8395/1,
+
otp8395_1/1
]).
@@ -289,18 +289,18 @@ init_per_testcase3(Case, Config) ->
Config
end.
-fin_per_testcase(Case, Config) when is_list(Config) ->
+end_per_testcase(Case, Config) when is_list(Config) ->
?DBG("fin [~w] Nodes [1]: ~p", [Case, erlang:nodes()]),
Dog = ?config(watchdog, Config),
?WD_STOP(Dog),
Conf1 = lists:keydelete(watchdog, 1, Config),
- Conf2 = fin_per_testcase2(Case, Conf1),
+ Conf2 = end_per_testcase2(Case, Conf1),
?DBG("fin [~w] Nodes [2]: ~p", [Case, erlang:nodes()]),
%% TopDir = ?config(top_dir, Conf2),
%% ?DEL_DIR(TopDir),
Conf2.
-fin_per_testcase2(Case, Config) ->
+end_per_testcase2(Case, Config) ->
OldApiCases =
[
simple_sync_get1,
@@ -359,118 +359,64 @@ fin_per_testcase2(Case, Config) ->
%% Test case definitions
%%======================================================================
-all(suite) ->
- [
- start_and_stop_tests,
- misc_tests,
- user_tests,
- agent_tests,
- request_tests,
- event_tests,
- discovery,
- tickets
- ].
-
-start_and_stop_tests(suite) ->
- [
- simple_start_and_stop1,
- simple_start_and_stop2,
- simple_start_and_monitor_crash1,
- simple_start_and_monitor_crash2,
- notify_started01,
- notify_started02
- ].
-
-misc_tests(suite) ->
- [
- info
- ].
-
-user_tests(suite) ->
- [
- register_user1
- ].
-
-agent_tests(suite) ->
- [
- register_agent1,
- register_agent2
- ].
-
-request_tests(suite) ->
- [
- get_tests,
- get_next_tests,
- set_tests,
- bulk_tests,
- misc_request_tests
- ].
-
-get_tests(suite) ->
- [
- simple_sync_get1,
- simple_sync_get2,
- simple_async_get1,
- simple_async_get2
- ].
-
-get_next_tests(suite) ->
- [
- simple_sync_get_next1,
- simple_sync_get_next2,
- simple_async_get_next1,
- simple_async_get_next2
- ].
-
-set_tests(suite) ->
- [
- simple_sync_set1,
- simple_sync_set2,
- simple_async_set1,
- simple_async_set2
- ].
-
-bulk_tests(suite) ->
- [
- simple_sync_get_bulk1,
- simple_sync_get_bulk2,
- simple_async_get_bulk1,
- simple_async_get_bulk2
- ].
-
-misc_request_tests(suite) ->
- [
- misc_async1,
- misc_async2
- ].
-
-event_tests(suite) ->
- [
- trap1,
- trap2,
- inform1,
- inform2,
- inform3,
- inform4,
- inform_swarm,
- report
- ].
-
-tickets(suite) ->
- [
- otp8015,
- otp8395
- ].
-
-otp8015(suite) ->
- [
- otp8015_1
- ].
-
-otp8395(suite) ->
- [
- otp8395_1
- ].
+all() ->
+[{group, start_and_stop_tests}, {group, misc_tests},
+ {group, user_tests}, {group, agent_tests},
+ {group, request_tests}, {group, event_tests}, discovery,
+ {group, tickets}].
+
+groups() ->
+ [{start_and_stop_tests, [],
+ [simple_start_and_stop1, simple_start_and_stop2,
+ simple_start_and_monitor_crash1,
+ simple_start_and_monitor_crash2, notify_started01,
+ notify_started02]},
+ {misc_tests, [], [info]},
+ {user_tests, [], [register_user1]},
+ {agent_tests, [], [register_agent1, register_agent2]},
+ {request_tests, [],
+ [{group, get_tests}, {group, get_next_tests},
+ {group, set_tests}, {group, bulk_tests},
+ {group, misc_request_tests}]},
+ {get_tests, [],
+ [simple_sync_get1, simple_sync_get2, simple_async_get1,
+ simple_async_get2]},
+ {get_next_tests, [],
+ [simple_sync_get_next1, simple_sync_get_next2,
+ simple_async_get_next1, simple_async_get_next2]},
+ {set_tests, [],
+ [simple_sync_set1, simple_sync_set2, simple_async_set1,
+ simple_async_set2]},
+ {bulk_tests, [],
+ [simple_sync_get_bulk1, simple_sync_get_bulk2,
+ simple_async_get_bulk1, simple_async_get_bulk2]},
+ {misc_request_tests, [], [misc_async1, misc_async2]},
+ {event_tests, [],
+ [trap1, trap2, inform1, inform2, inform3, inform4,
+ inform_swarm, report]},
+ {tickets, [], [{group, otp8015}, {group, otp8395}]},
+ {otp8015, [], [otp8015_1]}, {otp8395, [], [otp8395_1]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
%%======================================================================
diff --git a/lib/snmp/test/snmp_manager_user.erl b/lib/snmp/test/snmp_manager_user.erl
index 07b56bde39..b0e192344d 100644
--- a/lib/snmp/test/snmp_manager_user.erl
+++ b/lib/snmp/test/snmp_manager_user.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/snmp/test/snmp_manager_user_old.erl b/lib/snmp/test/snmp_manager_user_old.erl
index b53514d699..edffc80dd4 100755
--- a/lib/snmp/test/snmp_manager_user_old.erl
+++ b/lib/snmp/test/snmp_manager_user_old.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% 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
diff --git a/lib/snmp/test/snmp_manager_user_test.erl b/lib/snmp/test/snmp_manager_user_test.erl
index 0f47d70873..fefa1ad713 100644
--- a/lib/snmp/test/snmp_manager_user_test.erl
+++ b/lib/snmp/test/snmp_manager_user_test.erl
@@ -26,7 +26,7 @@
%%----------------------------------------------------------------------
%% Include files
%%----------------------------------------------------------------------
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("snmp_test_lib.hrl").
@@ -36,10 +36,10 @@
%% -compile(export_all).
-export([
- all/1,
- init_per_testcase/2, fin_per_testcase/2,
+all/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
+
- register_user/1,
simple_register_and_unregister1/1,
simple_register_and_unregister2/1,
simple_register_and_unregister3/1,
@@ -62,7 +62,7 @@
register_monitor_request_and_crash3/1,
register_monitor_request_and_crash4/1,
- tickets/1,
+
otp7902/1
]).
@@ -123,8 +123,8 @@ init_per_testcase(Case, Config) when is_list(Config) ->
{manager_log_dir, MgrLogDir} | Config].
-fin_per_testcase(Case, Config) when is_list(Config) ->
- p("fin_per_testcase -> Case: ~p", [Case]),
+end_per_testcase(Case, Config) when is_list(Config) ->
+ p("end_per_testcase -> Case: ~p", [Case]),
% MgrTopDir = ?config(manager_dir, Config),
% ?DEL_DIR(MgrTopDir),
Config.
@@ -134,42 +134,41 @@ fin_per_testcase(Case, Config) when is_list(Config) ->
%% Test case definitions
%%======================================================================
-all(suite) ->
- [
- register_user,
- tickets
- ].
-
-register_user(suite) ->
- [
- simple_register_and_unregister1,
- simple_register_and_unregister2,
- simple_register_and_unregister3,
- register_and_crash1,
- register_and_crash2,
- register_and_crash3,
- register_request_and_crash1,
- register_request_and_crash2,
- register_request_and_crash3,
- simple_register_monitor_and_unregister1,
- simple_register_monitor_and_unregister2,
- simple_register_monitor_and_unregister3,
- register_monitor_and_crash1,
- register_monitor_and_crash2,
- register_monitor_and_crash3,
- register_monitor_and_crash4,
- register_monitor_and_crash5,
- register_monitor_request_and_crash1,
- register_monitor_request_and_crash2,
- register_monitor_request_and_crash3,
- register_monitor_request_and_crash4
- ].
-
-
-tickets(suite) ->
- [
- otp7902
- ].
+all() ->
+[{group, register_user}, {group, tickets}].
+
+groups() ->
+ [{register_user, [],
+ [simple_register_and_unregister1,
+ simple_register_and_unregister2,
+ simple_register_and_unregister3, register_and_crash1,
+ register_and_crash2, register_and_crash3,
+ register_request_and_crash1,
+ register_request_and_crash2,
+ register_request_and_crash3,
+ simple_register_monitor_and_unregister1,
+ simple_register_monitor_and_unregister2,
+ simple_register_monitor_and_unregister3,
+ register_monitor_and_crash1,
+ register_monitor_and_crash2,
+ register_monitor_and_crash3,
+ register_monitor_and_crash4,
+ register_monitor_and_crash5,
+ register_monitor_request_and_crash1,
+ register_monitor_request_and_crash2,
+ register_monitor_request_and_crash3,
+ register_monitor_request_and_crash4]},
+ {tickets, [], [otp7902]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+
+
%%======================================================================
diff --git a/lib/snmp/test/snmp_manager_user_test_lib.erl b/lib/snmp/test/snmp_manager_user_test_lib.erl
index a49fe93178..bf8fff7c4c 100644
--- a/lib/snmp/test/snmp_manager_user_test_lib.erl
+++ b/lib/snmp/test/snmp_manager_user_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/snmp_note_store_test.erl b/lib/snmp/test/snmp_note_store_test.erl
index 8686a47468..24ba88f986 100644
--- a/lib/snmp/test/snmp_note_store_test.erl
+++ b/lib/snmp/test/snmp_note_store_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,7 @@
%%----------------------------------------------------------------------
%% Include files
%%----------------------------------------------------------------------
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("snmp_test_lib.hrl").
@@ -33,8 +33,8 @@
%% External exports
%%----------------------------------------------------------------------
-export([
- init_per_testcase/2, fin_per_testcase/2,
- all/1,
+ init_per_testcase/2, end_per_testcase/2,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
start_and_stop/1,
notes/1,
info/1,
@@ -63,20 +63,24 @@
init_per_testcase(_Case, Config) when is_list(Config) ->
Config.
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Config.
%%======================================================================
%% Test case definitions
%%======================================================================
-all(suite) ->
- [
- start_and_stop,
- notes,
- info,
- garbage_in
-
- ].
+all() ->
+[start_and_stop, notes, info, garbage_in].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%======================================================================
diff --git a/lib/snmp/test/snmp_pdus_test.erl b/lib/snmp/test/snmp_pdus_test.erl
index 6dc5b779aa..ef510ad62e 100644
--- a/lib/snmp/test/snmp_pdus_test.erl
+++ b/lib/snmp/test/snmp_pdus_test.erl
@@ -25,7 +25,7 @@
%%----------------------------------------------------------------------
%% Include files
%%----------------------------------------------------------------------
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("snmp_test_lib.hrl").
-include_lib("snmp/include/snmp_types.hrl").
@@ -34,11 +34,11 @@
%% External exports
%%----------------------------------------------------------------------
-export([
- all/1,
- tickets/1,
+ all/0,groups/0,init_per_group/2,end_per_group/2,
+
otp7575/1,
otp8563/1,
- init_per_testcase/2, fin_per_testcase/2
+ init_per_testcase/2, end_per_testcase/2
]).
@@ -64,23 +64,26 @@
init_per_testcase(_Case, Config) when is_list(Config) ->
Config.
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
Config.
%%======================================================================
%% Test case definitions
%%======================================================================
-all(suite) ->
- [
- tickets
- ].
-
-tickets(suite) ->
- [
- otp7575,
- otp8563
- ].
+all() ->
+[{group, tickets}].
+
+groups() ->
+ [{tickets, [], [otp7575, otp8563]}].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
diff --git a/lib/snmp/test/snmp_test_data/AC-TEST-MIB.mib b/lib/snmp/test/snmp_test_data/AC-TEST-MIB.mib
new file mode 100644
index 0000000000..58defbe1cf
--- /dev/null
+++ b/lib/snmp/test/snmp_test_data/AC-TEST-MIB.mib
@@ -0,0 +1,131 @@
+--
+-- AC-TEST-MIB.mib
+-- MIB generated by MG-SOFT Visual MIB Builder Version 5.0 Build 250
+-- Tuesday, November 30, 2010 at 23:03:18
+--
+
+ AC-TEST-MIB DEFINITIONS ::= BEGIN
+
+ IMPORTS
+ otpExpr
+ FROM OTP-REG
+ OBJECT-GROUP, AGENT-CAPABILITIES
+ FROM SNMPv2-CONF
+ Integer32, OBJECT-TYPE, MODULE-IDENTITY, OBJECT-IDENTITY
+ FROM SNMPv2-SMI;
+
+
+ acTestModule MODULE-IDENTITY
+ LAST-UPDATED "201011302230Z" -- November 30, 2010 at 22:30 GMT
+ ORGANIZATION
+ "Ac Test Co."
+ CONTACT-INFO
+ DESCRIPTION
+ "Ac Test module."
+ ::= { reg 1 }
+
+
+
+--
+-- Node definitions
+--
+
+ acTest OBJECT-IDENTITY
+ STATUS current
+ DESCRIPTION
+ "Test area."
+ ::= { otpExpr 4321 }
+
+
+ reg OBJECT-IDENTITY
+ STATUS current
+ DESCRIPTION
+ "Registrations."
+ ::= { acTest 1 }
+
+
+ mib OBJECT-IDENTITY
+ STATUS current
+ DESCRIPTION
+ "Objects."
+ ::= { acTest 2 }
+
+
+ someObject OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Description."
+ ::= { mib 1 }
+
+
+ oneMore OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Description."
+ ::= { mib 2 }
+
+
+ grp OBJECT-IDENTITY
+ STATUS current
+ DESCRIPTION
+ "Groups
+ ."
+ ::= { acTest 3 }
+
+
+ basicGrp OBJECT-GROUP
+ OBJECTS { someObject }
+ STATUS current
+ DESCRIPTION
+ "Basic set of objects."
+ ::= { grp 1 }
+
+
+ allObjects OBJECT-GROUP
+ OBJECTS { someObject, oneMore }
+ STATUS current
+ DESCRIPTION
+ "Complete set."
+ ::= { grp 2 }
+
+
+ cap OBJECT-IDENTITY
+ STATUS current
+ DESCRIPTION
+ "Capabilities."
+ ::= { acTest 5 }
+
+
+ basicAgent AGENT-CAPABILITIES
+ PRODUCT-RELEASE
+ "Product release v1."
+ STATUS current
+ DESCRIPTION
+ "Basic agent."
+ SUPPORTS AC-TEST-MIB
+ INCLUDES { basicGrp }
+ ::= { cap 1 }
+
+
+ fullAgent AGENT-CAPABILITIES
+ PRODUCT-RELEASE
+ "Product release v2."
+ STATUS current
+ DESCRIPTION
+ "Full featured agent."
+ SUPPORTS AC-TEST-MIB
+ INCLUDES { allObjects }
+ ::= { cap 2 }
+
+
+
+ END
+
+--
+-- AC-TEST-MIB.mib
+--
diff --git a/lib/snmp/test/snmp_test_data/MC-TEST-MIB.mib b/lib/snmp/test/snmp_test_data/MC-TEST-MIB.mib
new file mode 100644
index 0000000000..cadaa6f891
--- /dev/null
+++ b/lib/snmp/test/snmp_test_data/MC-TEST-MIB.mib
@@ -0,0 +1,173 @@
+MC-TEST-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+ otpExpr
+ FROM OTP-REG
+ MODULE-IDENTITY, OBJECT-TYPE,
+ mib-2, NOTIFICATION-TYPE, OBJECT-IDENTITY
+ FROM SNMPv2-SMI
+ TDomain, TAddress, DisplayString, TEXTUAL-CONVENTION,
+ AutonomousType, RowPointer, TimeStamp,
+ RowStatus, StorageType
+ FROM SNMPv2-TC
+ MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
+ FROM SNMPv2-CONF;
+
+mcTestModule MODULE-IDENTITY
+ LAST-UPDATED "9605160000Z"
+ ORGANIZATION "MC Test Co."
+ CONTACT-INFO
+ DESCRIPTION
+ "MC Test module."
+ ::= { reg 1 }
+
+mcObjects OBJECT IDENTIFIER ::= { mcTestModule 1 }
+
+-- MIB contains one group
+
+mcMisc OBJECT IDENTIFIER ::= { mcObjects 1 }
+mcGeneral OBJECT IDENTIFIER ::= { mcObjects 2 }
+
+
+mcTest OBJECT-IDENTITY
+ STATUS current
+ DESCRIPTION
+ "Test area."
+ ::= { otpExpr 4322 }
+
+
+reg OBJECT-IDENTITY
+ STATUS current
+ DESCRIPTION
+ "Registrations."
+ ::= { mcTest 1 }
+
+
+mcTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF McEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "This table contains one row per physical entity. There is
+ always at least one row for an 'overall' physical entity."
+ ::= { mcMisc 1 }
+
+mcEntry OBJECT-TYPE
+ SYNTAX McEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Table entry..."
+ INDEX { mcIndex }
+ ::= { mcTable 1 }
+
+McEntry ::= SEQUENCE {
+ mcIndex INTEGER,
+ mcName DisplayString,
+ mcStorageType StorageType,
+ mcRowStatus RowStatus
+}
+
+mcIndex OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The index for this entry."
+ ::= { mcEntry 1 }
+
+mcName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Name of... "
+ ::= { mcEntry 2 }
+
+
+mcStorageType OBJECT-TYPE
+ SYNTAX StorageType
+ MAX-ACCESS read-create
+ STATUS current
+ DESCRIPTION
+ "The storage type for this conceptual row."
+ DEFVAL { nonVolatile }
+ ::= { mcEntry 3 }
+
+mcRowStatus OBJECT-TYPE
+ SYNTAX RowStatus
+ MAX-ACCESS read-create
+ STATUS current
+ DESCRIPTION
+ "The status of this conceptual row..."
+ ::= { mcEntry 4 }
+
+
+-- last change time stamp for the whole MIB
+mcTimeStamp OBJECT-TYPE
+ SYNTAX TimeStamp
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The sysUpTime value when of the last time *anything* in the
+ MIB was changed. "
+ ::= { mcGeneral 1 }
+
+-- Entity MIB Trap Definitions
+mcTraps OBJECT IDENTIFIER ::= { mcTestModule 2 }
+mcTrapPrefix OBJECT IDENTIFIER ::= { mcTraps 0 }
+
+mcConfigChange NOTIFICATION-TYPE
+ STATUS current
+ DESCRIPTION
+ "An mcConfigChange trap is sent when the value of
+ entLastChangeTime changes..."
+ ::= { mcTrapPrefix 1 }
+
+-- conformance information
+mcConformance OBJECT IDENTIFIER ::= { mcTestModule 3 }
+
+mcCompliances OBJECT IDENTIFIER ::= { mcConformance 1 }
+mcGroups OBJECT IDENTIFIER ::= { mcConformance 2 }
+
+-- compliance statements
+
+
+mcCompliance MODULE-COMPLIANCE
+ STATUS current
+ DESCRIPTION
+ "The compliance statement for SNMP entities which implement
+ the MC Test MIB."
+ MODULE -- this module
+ MANDATORY-GROUPS { mcGeneralGroup,
+ mcNotificationsGroup }
+ ::= { mcCompliances 1 }
+
+-- MIB groupings
+
+mcGeneralGroup OBJECT-GROUP
+ OBJECTS {
+ mcName,
+ mcStorageType,
+ mcRowStatus,
+ mcTimeStamp
+ }
+ STATUS current
+ DESCRIPTION
+ "The collection of objects which are used to represent
+ general information..."
+ ::= { mcGroups 1 }
+
+mcNotificationsGroup NOTIFICATION-GROUP
+ NOTIFICATIONS { mcConfigChange }
+ STATUS current
+ DESCRIPTION
+ "The collection of notifications..."
+ ::= { mcGroups 2 }
+
+
+END
+
+
+
diff --git a/lib/snmp/test/snmp_test_manager.erl b/lib/snmp/test/snmp_test_manager.erl
index 9d9c52ef8d..4cc6d36acc 100644
--- a/lib/snmp/test/snmp_test_manager.erl
+++ b/lib/snmp/test/snmp_test_manager.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-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
diff --git a/lib/snmp/test/snmp_test_mgr_misc.erl b/lib/snmp/test/snmp_test_mgr_misc.erl
index ef1ba0b948..fc6dedd96d 100644
--- a/lib/snmp/test/snmp_test_mgr_misc.erl
+++ b/lib/snmp/test/snmp_test_mgr_misc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -33,6 +33,8 @@
%% internal exports
-export([init_packet/10]).
+-compile({no_auto_import, [error/2]}).
+
-define(SNMP_USE_V3, true).
-include_lib("snmp/include/snmp_types.hrl").
diff --git a/lib/snmp/test/snmp_test_server.erl b/lib/snmp/test/snmp_test_server.erl
index d0a5185452..ffbd2126a3 100644
--- a/lib/snmp/test/snmp_test_server.erl
+++ b/lib/snmp/test/snmp_test_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -33,7 +33,7 @@
fatal_skip/3,
init_per_testcase/2,
- fin_per_testcase/2
+ end_per_testcase/2
]).
-include("snmp_test_lib.hrl").
@@ -229,7 +229,7 @@ eval(Mod, Fun, Config) ->
Eval = fun() -> do_eval(Self, Mod, Fun, Config2) end,
Pid = spawn_link(Eval),
R = wait_for_evaluator(Pid, Mod, Fun, Config2, []),
- Mod:fin_per_testcase(Fun, Config2),
+ Mod:end_per_testcase(Fun, Config2),
global:unregister_name(?TEST_CASE_SUP),
process_flag(trap_exit, Flag),
R.
@@ -361,7 +361,7 @@ init_per_testcase(_Case, Config) ->
global:register_name(?GLOBAL_LOGGER, group_leader()),
Config.
-fin_per_testcase(_Case, _Config) ->
+end_per_testcase(_Case, _Config) ->
global:unregister_name(?GLOBAL_LOGGER),
ok.
diff --git a/lib/snmp/test/snmp_test_suite.erl b/lib/snmp/test/snmp_test_suite.erl
index a6e203eba3..77aaa508ad 100644
--- a/lib/snmp/test/snmp_test_suite.erl
+++ b/lib/snmp/test/snmp_test_suite.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -29,7 +29,7 @@ behaviour_info(callbacks) ->
[
{all, 1},
{init_per_testcase, 2},
- {fin_per_testcase, 2}
+ {end_per_testcase, 2}
];
behaviour_info(_Other) ->
undefined.
diff --git a/lib/snmp/test/test1.erl b/lib/snmp/test/test1.erl
index b26b03d4ce..23cfaf6aaa 100644
--- a/lib/snmp/test/test1.erl
+++ b/lib/snmp/test/test1.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/test2.erl b/lib/snmp/test/test2.erl
index dc010cfa11..a33208af7b 100644
--- a/lib/snmp/test/test2.erl
+++ b/lib/snmp/test/test2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/test_config/.gitignore b/lib/snmp/test/test_config/.gitignore
new file mode 100644
index 0000000000..fc2d5dbadf
--- /dev/null
+++ b/lib/snmp/test/test_config/.gitignore
@@ -0,0 +1,19 @@
+# Sys config files (Generated)
+/sys.config
+/sys-agent.config
+/sys-manager.config
+
+# Agent config files (Generated)
+/agent/agent.conf
+/agent/community.conf
+/agent/context.conf
+/agent/notify.conf
+/agent/standard.conf
+/agent/target_addr.conf
+/agent/target_params.conf
+/agent/usm.conf
+/agent/vacm.conf
+
+# Manager config files (Generated)
+/manager/manager.conf
+/manager/usm.conf
diff --git a/lib/snmp/test/test_config/Makefile b/lib/snmp/test/test_config/Makefile
new file mode 100644
index 0000000000..4953de7fe8
--- /dev/null
+++ b/lib/snmp/test/test_config/Makefile
@@ -0,0 +1,199 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+
+VSN = $(SNMP_VSN)
+
+
+# ----------------------------------------------------
+# Configured variables
+# ----------------------------------------------------
+
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+include modules.mk
+
+ERL_TARGETS = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+SYS_CONFIG_SRCS = $(SYS_CONFIG_FILES:%=%.src)
+AGENT_CONFIG_SRCS = $(AGENT_CONFIG_FILES:%=%.src)
+MANAGER_CONFIG_SRCS = $(MANAGER_CONFIG_FILES:%=%.src)
+
+CONFIG_FILES = \
+ $(SYS_CONFIG_FILES) \
+ $(AGENT_CONFIG_FILES) \
+ $(MANAGER_CONFIG_FILES)
+
+TARGETS = \
+ $(ERL_TARGETS) \
+ $(CONFIG_FILES)
+
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+ifeq ($(TESTROOT),)
+TESTROOT=/tmp
+endif
+RELSYSDIR = $(TESTROOT)
+
+
+# ----------------------------------------------------
+# FLAGS AND VARIABLES
+# ----------------------------------------------------
+
+EBIN = .
+
+ERL_COMPILE_FLAGS += +'{parse_transform,sys_pre_attributes}' \
+ +'{attribute,insert,app_vsn,$(APP_VSN)}'
+
+ifeq ($(ADDR),)
+ADDR = $(shell erl -noshell -s snmp_test_config ip_address -s init stop)
+endif
+
+ifeq ($(TARGET_NAME_PRE),)
+TARGET_NAME_PRE = $(shell erl -noshell -s snmp_test_config ip_address2 -s init stop)
+endif
+
+ifeq ($(SYS_CONTACT),)
+SYS_CONTACT = [email protected]
+endif
+
+ifeq ($(SYS_LOCATION),)
+SYS_LOCATION = Erlang/OTP
+endif
+
+ifeq ($(SYS_NAME),)
+SYS_NAME = FOO
+endif
+
+ifeq ($(AGENT_ENGINE_ID),)
+AGENT_ENGINE_ID = Agent engine of $(USER)
+endif
+
+ifeq ($(AGENT_USM_ENGINE_ID),)
+AGENT_USM_ENGINE_ID = $(AGENT_ENGINE_ID)
+endif
+
+ifeq ($(MANAGER_ENGINE_ID),)
+MANAGER_ENGINE_ID = Manager engine of $(USER)
+endif
+
+ifeq ($(MANAGER_USM_ENGINE_ID),)
+MANAGER_USM_ENGINE_ID = $(MANAGER_ENGINE_ID)
+endif
+
+
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+tests debug opt: $(TARGETS)
+
+clean:
+ rm -f $(CONFIG_FILES)
+ rm -f $(ERL_TARGETS)
+ rm -f core
+
+docs:
+
+%.config: %.config.src
+ @echo "$< -> $@"
+ $(PERL) -p -e 's?%DIR%?$(RELSYSDIR)? ' < $< > $@
+
+agent/%.conf: agent/%.conf.src
+ @echo "$< -> $@"
+ sed -e 's?%ADDR%?$(ADDR)? ' \
+ -e 's?%SYS_CONTACT%?$(SYS_CONTACT)? ' \
+ -e 's?%SYS_LOCATION%?$(SYS_LOCATION)? ' \
+ -e 's?%SYS_NAME%?$(SYS_NAME)? ' \
+ -e 's?%TARGET_NAME_PRE%?$(TARGET_NAME_PRE)? ' \
+ -e 's?%ENGINE_ID%?\"$(AGENT_ENGINE_ID)\"? ' \
+ -e 's?%USM_ENGINE_ID%?\"$(AGENT_USM_ENGINE_ID)\"? ' < $< > $@
+
+manager/%.conf: manager/%.conf.src
+ @echo "$< -> $@"
+ sed -e 's?%ADDR%?$(ADDR)? ' \
+ -e 's?%ENGINE_ID%?\"$(MANAGER_ENGINE_ID)\"? ' \
+ -e 's?%USM_ENGINE_ID%?\"$(MANAGER_USM_ENGINE_ID)\"? ' < $< > $@
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_tests_spec: clean opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELSYSDIR)/agent
+ chmod -f -R u+w $(RELSYSDIR)/agent
+ $(INSTALL_DIR) $(RELSYSDIR)/agent/conf
+ chmod -f -R u+w $(RELSYSDIR)/agent/conf
+ $(INSTALL_DIR) $(RELSYSDIR)/agent/db
+ chmod -f -R u+w $(RELSYSDIR)/agent/db
+ $(INSTALL_DIR) $(RELSYSDIR)/agent/log
+ chmod -f -R u+w $(RELSYSDIR)/agent/log
+ $(INSTALL_DIR) $(RELSYSDIR)/manager
+ chmod -f -R u+w $(RELSYSDIR)/manager
+ $(INSTALL_DIR) $(RELSYSDIR)/manager/conf
+ chmod -f -R u+w $(RELSYSDIR)/manager/conf
+ $(INSTALL_DIR) $(RELSYSDIR)/manager/db
+ chmod -f -R u+w $(RELSYSDIR)/manager/db
+ $(INSTALL_DIR) $(RELSYSDIR)/manager/log
+ chmod -f -R u+w $(RELSYSDIR)/manager/log
+ $(INSTALL_DATA) $(SYS_CONFIG_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(AGENT_CONFIG_FILES) $(RELSYSDIR)/agent/conf
+ $(INSTALL_DATA) $(MANAGER_CONFIG_FILES) $(RELSYSDIR)/manager/conf
+
+release_docs_spec:
+
+
+info:
+ @echo ""
+ @echo "RELSYSDIR = $(RELSYSDIR)"
+ @echo ""
+ @echo "SYS_CONFIG_SRCS = $(SYS_CONFIG_SRCS)"
+ @echo "SYS_CONFIG_FILES = $(SYS_CONFIG_FILES)"
+ @echo ""
+ @echo "AGENT_CONFIG_SRCS = $(AGENT_CONFIG_SRCS)"
+ @echo "AGENT_CONFIG_FILES = $(AGENT_CONFIG_FILES)"
+ @echo ""
+ @echo "MANAGER_CONFIG_SRCS = $(MANAGER_CONFIG_SRCS)"
+ @echo "MANAGER_CONFIG_FILES = $(MANAGER_CONFIG_FILES)"
+ @echo ""
+ @echo "ADDR = $(ADDR)"
+ @echo "TARGET_NAME_PRE = $(TARGET_NAME_PRE)"
+ @echo ""
+
+
diff --git a/lib/snmp/test/test_config/agent/agent.conf.src b/lib/snmp/test/test_config/agent/agent.conf.src
new file mode 100644
index 0000000000..1fe95cc72d
--- /dev/null
+++ b/lib/snmp/test/test_config/agent/agent.conf.src
@@ -0,0 +1,19 @@
+%% This file defines the Agent local configuration info
+%% The data is inserted into the snmpEngine* variables defined
+%% in SNMP-FRAMEWORK-MIB, and the intAgent* variables defined
+%% in OTP-SNMPEA-MIB.
+%% Each row is a 2-tuple:
+%% {AgentVariable, Value}.
+%% For example
+%% {intAgentUDPPort, 4000}.
+%% The ip address for the agent is sent as id in traps.
+%% {intAgentIpAddress, [127,42,17,5]}.
+%% {snmpEngineID, "agentEngine"}.
+%% {snmpEngineMaxMessageSize, 484}.
+%%
+
+
+{intAgentUDPPort, 4000}.
+{intAgentIpAddress, %ADDR%}.
+{snmpEngineID, %ENGINE_ID%}.
+{snmpEngineMaxMessageSize, 484}.
diff --git a/lib/snmp/test/test_config/agent/community.conf.src b/lib/snmp/test/test_config/agent/community.conf.src
new file mode 100644
index 0000000000..8dccb929c9
--- /dev/null
+++ b/lib/snmp/test/test_config/agent/community.conf.src
@@ -0,0 +1,15 @@
+%% This file defines the community info which maps to VACM parameters.
+%% The data is inserted into the snmpCommunityTable defined
+%% in SNMP-COMMUNITY-MIB.
+%% Each row is a 5-tuple:
+%% {CommunityIndex, CommunityName, SecurityName, ContextName, TransportTag}.
+%% For example
+%% {"1", "public", "initial", "", ""}.
+%% {"2", "secret", "secret_name", "", "tag"}.
+%% {"3", "bridge1", "initial", "bridge1", ""}.
+%%
+
+
+{"public", "public", "initial", "", ""}.
+{"all-rights", "all-rights", "all-rights", "", ""}.
+{"standard trap", "standard trap", "initial", "", ""}.
diff --git a/lib/snmp/test/test_config/agent/context.conf.src b/lib/snmp/test/test_config/agent/context.conf.src
new file mode 100644
index 0000000000..ea8b5a97eb
--- /dev/null
+++ b/lib/snmp/test/test_config/agent/context.conf.src
@@ -0,0 +1,14 @@
+%% This file defines the contexts known to the agent.
+%% The data is inserted into the vacmContextTable defined
+%% in SNMP-VIEW-BASED-ACM-MIB.
+%% Each row is a string:
+%% ContextName.
+%%
+%% The empty string is the default context.
+%% For example
+%% "bridge1".
+%% "bridge2".
+%%
+
+
+"".
diff --git a/lib/snmp/test/test_config/agent/notify.conf.src b/lib/snmp/test/test_config/agent/notify.conf.src
new file mode 100644
index 0000000000..164fd25b95
--- /dev/null
+++ b/lib/snmp/test/test_config/agent/notify.conf.src
@@ -0,0 +1,13 @@
+%% This file defines the notification parameters.
+%% The data is inserted into the snmpNotifyTable defined
+%% in SNMP-NOTIFICATION-MIB.
+%% The Name is used as CommunityString for v1 and v2c.
+%% Each row is a 3-tuple:
+%% {Name, Tag, Type}.
+%% For example
+%% {"standard trap", "std_trap", trap}.
+%% {"standard inform", "std_inform", inform}.
+%%
+
+
+{"stadard_trap", "std_trap", trap}.
diff --git a/lib/snmp/test/test_config/agent/standard.conf.src b/lib/snmp/test/test_config/agent/standard.conf.src
new file mode 100644
index 0000000000..31e04e7695
--- /dev/null
+++ b/lib/snmp/test/test_config/agent/standard.conf.src
@@ -0,0 +1,21 @@
+%% This file defines the STANDARD-MIB info.
+%% Each row is a 2-tuple:
+%% {StandardVariable, Value}.
+%% For example
+%% {sysDescr, "Erlang SNMP agent"}.
+%% {sysObjectID, [1,2,3]}.
+%% {sysContact, "[email protected]"}.
+%% {sysName, "test"}.
+%% {sysLocation, "erlang"}.
+%% {sysServices, 72}.
+%% {snmpEnableAuthenTraps, enabled}.
+%%
+
+
+{sysDescr, "Erlang SNMP agent"}.
+{sysObjectID, [1,2,3]}.
+{sysContact, "%SYS_CONTACT%"}.
+{sysLocation, "%SYS_LOCATION%"}.
+{sysServices, 72}.
+{snmpEnableAuthenTraps, disabled}.
+{sysName, "%SYS_NAME%"}.
diff --git a/lib/snmp/test/test_config/agent/target_addr.conf.src b/lib/snmp/test/test_config/agent/target_addr.conf.src
new file mode 100644
index 0000000000..740df74ecf
--- /dev/null
+++ b/lib/snmp/test/test_config/agent/target_addr.conf.src
@@ -0,0 +1,21 @@
+%% This file defines the target address parameters.
+%% The data is inserted into the snmpTargetAddrTable defined
+%% in SNMP-TARGET-MIB, and in the snmpTargetAddrExtTable defined
+%% in SNMP-COMMUNITY-MIB.
+%% Each row is a 10-tuple:
+%% {Name, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId,
+%% TMask, MaxMessageSize}.
+%% The EngineId value is only used if Inform-Requests are sent to this
+%% target. If Informs are not sent, this value is ignored, and can be
+%% e.g. an empty string. However, if Informs are sent, it is essential
+%% that the value of EngineId matches the value of the target's
+%% actual snmpEngineID.
+%% For example
+%% {"1.2.3.4 v1", [1,2,3,4], 162,
+%% 1500, 3, "std_inform", "otp_v2", "",
+%% [127,0,0,0], 2048}.
+%%
+
+
+{"%TARGET_NAME_PRE% v2", %ADDR%, 5000, 1500, 3, "std_trap", "target_v2", "", [], 2048}.
+{"%TARGET_NAME_PRE% v2.2", %ADDR%, 5000, 1500, 3, "std_inform", "target_v2", "", [], 2048}.
diff --git a/lib/snmp/test/test_config/agent/target_params.conf.src b/lib/snmp/test/test_config/agent/target_params.conf.src
new file mode 100644
index 0000000000..a4a535baa2
--- /dev/null
+++ b/lib/snmp/test/test_config/agent/target_params.conf.src
@@ -0,0 +1,11 @@
+%% This file defines the target parameters.
+%% The data is inserted into the snmpTargetParamsTable defined
+%% in SNMP-TARGET-MIB.
+%% Each row is a 5-tuple:
+%% {Name, MPModel, SecurityModel, SecurityName, SecurityLevel}.
+%% For example
+%% {"target_v3", v3, usm, "", noAuthNoPriv}.
+%%
+
+
+{"target_v2", v2c, v2c, "initial", noAuthNoPriv}.
diff --git a/lib/snmp/test/test_config/agent/usm.conf.src b/lib/snmp/test/test_config/agent/usm.conf.src
new file mode 100644
index 0000000000..0409084048
--- /dev/null
+++ b/lib/snmp/test/test_config/agent/usm.conf.src
@@ -0,0 +1,17 @@
+%% This file defines the security parameters for the user-based
+%% security model.
+%% The data is inserted into the usmUserTable defined
+%% in SNMP-USER-BASED-SM-MIB.
+%% Each row is a 13-tuple:
+%% {EngineID, UserName, SecName, Clone, AuthP, AuthKeyC, OwnAuthKeyC,
+%% PrivP, PrivKeyC, OwnPrivKeyC, Public, AuthKey, PrivKey}.
+%% For example
+%% {"agentEngine", "initial", "initial", zeroDotZero,
+%% usmNoAuthProtocol, "", "", usmNoPrivProtocol, "", "", "",
+%% "", ""}.
+%%
+
+
+{%USM_ENGINE_ID%, "initial", "initial", zeroDotZero, usmHMACMD5AuthProtocol, "", "", usmNoPrivProtocol, "", "", "", [160,66,33,136,178,59,246,214,102,63,131,131,54,14,221,177], ""}.
+{%USM_ENGINE_ID%, "templateMD5", "templateMD5", zeroDotZero, usmHMACMD5AuthProtocol, "", "", usmNoPrivProtocol, "", "", "", [160,66,33,136,178,59,246,214,102,63,131,131,54,14,221,177], ""}.
+{%USM_ENGINE_ID%, "templateSHA", "templateSHA", zeroDotZero, usmHMACSHAAuthProtocol, "", "", usmNoPrivProtocol, "", "", "", [199,94,239,13,229,135,141,77,124,129,65,189,230,240,115,163,239,15,13,242], ""}.
diff --git a/lib/snmp/test/test_config/agent/vacm.conf.src b/lib/snmp/test/test_config/agent/vacm.conf.src
new file mode 100644
index 0000000000..86271443ad
--- /dev/null
+++ b/lib/snmp/test/test_config/agent/vacm.conf.src
@@ -0,0 +1,27 @@
+%% This file defines the Mib Views.
+%% The data is inserted into the vacm* tables defined
+%% in SNMP-VIEW-BASED-ACM-MIB.
+%% Each row is one of 3 tuples; one for each table in the MIB:
+%% {vacmSecurityToGroup, SecModel, SecName, GroupName}.
+%% {vacmAccess, GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV}.
+%% {vacmViewTreeFamily, ViewIndex, ViewSubtree, ViewStatus, ViewMask}.
+%% For example
+%% {vacmSecurityToGroup, v2c, "initial", "initial"}.
+%% {vacmSecurityToGroup, usm, "initial", "initial"}.
+%% read/notify access to system
+%% {vacmAccess, "initial", "", any, noAuthNoPriv, exact,
+%% "system", "", "system"}.
+%% {vacmViewTreeFamily, "system", [1,3,6,1,2,1,1], included, null}.
+%% {vacmViewTreeFamily, "exmib", [1,3,6,1,3], included, null}. % for EX1-MIB
+%% {vacmViewTreeFamily, "internet", [1,3,6,1], included, null}.
+%%
+
+
+{vacmSecurityToGroup, v2c, "initial", "initial"}.
+{vacmSecurityToGroup, v2c, "all-rights", "all-rights"}.
+{vacmAccess, "initial", "", any, noAuthNoPriv, exact, "restricted", "", "restricted"}.
+{vacmAccess, "initial", "", usm, authNoPriv, exact, "internet", "internet", "internet"}.
+{vacmAccess, "initial", "", usm, authPriv, exact, "internet", "internet", "internet"}.
+{vacmAccess, "all-rights", "", any, noAuthNoPriv, exact, "internet", "internet", "internet"}.
+{vacmViewTreeFamily, "restricted", [1,3,6,1], included, null}.
+{vacmViewTreeFamily, "internet", [1,3,6,1], included, null}.
diff --git a/lib/snmp/test/test_config/manager/manager.conf.src b/lib/snmp/test/test_config/manager/manager.conf.src
new file mode 100644
index 0000000000..c38a61b13c
--- /dev/null
+++ b/lib/snmp/test/test_config/manager/manager.conf.src
@@ -0,0 +1,16 @@
+%% This file was generated by snmp_config (version-4.9.3) 2007-06-29 13:35:05
+%% This file defines the Manager local configuration info
+%% Each row is a 2-tuple:
+%% {Variable, Value}.
+%% For example
+%% {port, 5000}.
+%% {address, [127,42,17,5]}.
+%% {engine_id, "managerEngine"}.
+%% {max_message_size, 484}.
+%%
+
+
+{port, 5000}.
+{address, %ADDR%}.
+{engine_id, %ENGINE_ID%}.
+{max_message_size, 484}.
diff --git a/lib/snmp/test/test_config/manager/usm.conf.src b/lib/snmp/test/test_config/manager/usm.conf.src
new file mode 100644
index 0000000000..a558c86710
--- /dev/null
+++ b/lib/snmp/test/test_config/manager/usm.conf.src
@@ -0,0 +1,9 @@
+%% This file was generated by snmp_config (version-4.9.3) 2007-06-29 13:35:05
+%% This file defines the usm users the manager handles
+%% Each row is a 6 or 7-tuple:
+%% {EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey}
+%% {EngineID, UserName, SecName, AuthP, AuthKey, PrivP, PrivKey}
+%%
+
+{%USM_ENGINE_ID%, "initial", usmNoAuthProtocol, "", usmNoPrivProtocol, ""}.
+
diff --git a/lib/snmp/test/test_config/modules.mk b/lib/snmp/test/test_config/modules.mk
new file mode 100644
index 0000000000..3d084cef01
--- /dev/null
+++ b/lib/snmp/test/test_config/modules.mk
@@ -0,0 +1,41 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+SYS_CONFIG_FILES = \
+ sys.config \
+ sys-agent.config \
+ sys-manager.config
+
+AGENT_CONFIG_FILES = \
+ agent/agent.conf \
+ agent/community.conf \
+ agent/context.conf \
+ agent/notify.conf \
+ agent/standard.conf \
+ agent/target_addr.conf \
+ agent/target_params.conf \
+ agent/usm.conf \
+ agent/vacm.conf
+
+MANAGER_CONFIG_FILES = \
+ manager/manager.conf \
+ manager/usm.conf
+
+MODULES = \
+ snmp_test_config
diff --git a/lib/snmp/test/test_config/snmp_test_config.erl b/lib/snmp/test/test_config/snmp_test_config.erl
new file mode 100644
index 0000000000..550a276c4c
--- /dev/null
+++ b/lib/snmp/test/test_config/snmp_test_config.erl
@@ -0,0 +1,32 @@
+%%
+%% %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(snmp_test_config).
+
+-export([ip_address/0, ip_address2/0]).
+
+ip_address() ->
+ {ok, Hostname} = inet:gethostname(),
+ {ok, Address} = inet:getaddr(Hostname, inet),
+ io:format("~w", [tuple_to_list(Address)]).
+
+ip_address2() ->
+ {ok, Hostname} = inet:gethostname(),
+ {ok, {A1, A2, A3, A4}} = inet:getaddr(Hostname, inet),
+ io:format("~w.~w.~w.~w", [A1, A2, A3, A4]).
diff --git a/lib/snmp/test/test_config/sys-agent.config.src b/lib/snmp/test/test_config/sys-agent.config.src
new file mode 100644
index 0000000000..46a458203d
--- /dev/null
+++ b/lib/snmp/test/test_config/sys-agent.config.src
@@ -0,0 +1,43 @@
+%% This is an example sys config file for starting the snmp application
+%% with only a agent running.
+[{snmp,
+ [
+ {agent,
+ [
+ {priority, normal},
+ {versions, [v1,v2,v3]},
+ {db_dir, "%DIR%/agent/db"},
+ {mib_storage, ets},
+%% {agent_mib_storage, volatile},
+ {agent_mib_storage, persistent},
+ {target_cache, [{verbosity,silence}]},
+ {symbolic_store, [{verbosity,silence}]},
+ {local_db, [{repair,true},{auto_save,5000},{verbosity,silence}]},
+ {error_report_module, snmpa_error_logger},
+ {agent_type, master},
+ {agent_verbosity, trace},
+ {audit_trail_log, [{type, read},
+ {dir, "%DIR%/agent/log"},
+ {size, {10240,10}}]},
+ {config, [{dir, "%DIR%/agent/conf"},
+ {force_load, true},
+ {verbosity, trace}]},
+ {multi_threaded, true},
+ {mib_server, [{mibentry_override, false},
+ {trapentry_override, false},
+ {cache, true},
+ {verbosity, trace}]},
+ {note_store, [{timeout,30000}, {verbosity,silence}]},
+ {supervisor, [{verbosity,silence}]},
+ {net_if, [{module, snmpa_net_if},
+ {verbosity, silence},
+ {options, [{bind_to, true},
+ {no_reuse, false},
+ {req_limit, infinity},
+ {sndbuf, 32000},
+ {recbuf, 32000}]}]}
+ ]
+ }
+ ]
+ }
+].
diff --git a/lib/snmp/test/test_config/sys-manager.config.src b/lib/snmp/test/test_config/sys-manager.config.src
new file mode 100644
index 0000000000..4366263084
--- /dev/null
+++ b/lib/snmp/test/test_config/sys-manager.config.src
@@ -0,0 +1,35 @@
+%% This is an example sys config file for starting the snmp application
+%% with only a manager running.
+[{snmp,
+ [
+ {manager,
+ [
+ {priority, normal},
+ {versions, [v1,v2,v3]},
+ {config, [{dir, "%DIR%/manager/conf"},
+ {verbosity, trace},
+ {db_dir, "%DIR%/manager/db"},
+ {repair, true},
+ {auto_save, 5000}]},
+ {inform_request_behaviour, user},
+ {mibs, []},
+ {server, [{timeout, 30000},
+ {verbosity, trace}]},
+ {note_store, [{timeout,30000},
+ {verbosity,silence}]},
+ {audit_trail_log, [{type, read},
+ {dir, "%DIR%/manager/log"},
+ {size, {10240,10}}]},
+ {net_if, [{module,snmpm_net_if},
+ {verbosity, trace},
+ {options, [{bind_to, true},
+ {no_reuse, false},
+% {sndbuf, 32000},
+ {recbuf, 45000}]}]},
+ {def_user_mod, snmpm_user_default},
+ {def_user_data, undefined}
+ ]
+ }
+ ]
+ }
+].
diff --git a/lib/snmp/test/test_config/sys.config.src b/lib/snmp/test/test_config/sys.config.src
new file mode 100644
index 0000000000..b2cd399883
--- /dev/null
+++ b/lib/snmp/test/test_config/sys.config.src
@@ -0,0 +1,68 @@
+%% This is an example sys config file for starting the snmp application
+%% with both an agent and a manager running.
+[{snmp,
+ [
+ {agent,
+ [
+ {priority, normal},
+ {versions, [v1,v2,v3]},
+ {db_dir, "%DIR%/agent/db"},
+ {mib_storage, ets},
+ {agent_mib_storage, volatile},
+ {target_cache, [{verbosity,silence}]},
+ {symbolic_store, [{verbosity,silence}]},
+ {local_db, [{repair,true},{auto_save,5000},{verbosity,silence}]},
+ {error_report_module, snmpa_error_logger},
+ {agent_type, master},
+ {agent_verbosity, silence},
+ {audit_trail_log, [{type, read},
+ {dir, "%DIR%/agent/log"},
+ {size, {10240,10}}]},
+ {config, [{dir, "%DIR%/agent/conf"},
+ {force_load, true},
+ {verbosity, silence}]},
+ {multi_threaded, false},
+ {mib_server, [{mibentry_override, false},
+ {trapentry_override, false},
+ {verbosity, silence}]},
+ {note_store, [{timeout,30000},{verbosity,silence}]},
+ {net_if, [{module, snmpa_net_if},
+ {verbosity, silence},
+ {options, [{bind_to, true},
+ {no_reuse, false},
+ {req_limit, infinity},
+ {sndbuf, 32000},
+ {recbuf, 32000}]}]}
+ ]
+ },
+ {manager,
+ [
+ {priority, normal},
+ {versions, [v1,v2,v3]},
+ {config, [{dir, "%DIR%/manager/conf"},
+ {verbosity, silence},
+ {db_dir, "%DIR%/manager/db"},
+ {repair, true},
+ {auto_save, 5000}]},
+ {inform_request_behaviour, auto},
+ {mibs, []},
+ {server, [{timeout, 30000},
+ {verbosity, silence}]},
+ {note_store, [{timeout, 30000},
+ {verbosity, silence}]},
+ {audit_trail_log, [{type, read},
+ {dir, "%DIR%/manager/log"},
+ {size, {10240,10}}]},
+ {net_if, [{module,snmpm_net_if},
+ {verbosity, silence},
+ {options, [{bind_to, true},
+ {no_reuse, false},
+ {recbuf, 33000},
+ {sndbuf, 34000}]}]},
+ {def_user_mod, snmpm_user_default},
+ {def_user_data, undefined}
+ ]
+ }
+ ]
+ }
+].
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index 1229b12ae2..e70c97dcb8 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -1,3 +1,22 @@
-SNMP_VSN = 4.18
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+SNMP_VSN = 4.19
PRE_VSN =
APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)"
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 950c249e72..af667b1a71 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -29,8 +29,91 @@
<file>notes.xml</file>
</header>
- <section><title>Ssh 2.0.1</title>
+<section><title>Ssh 2.0.4</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>In some cases SSH returned {error, normal} when a channel was terminated
+ unexpectedly. This has now been changed to {error, channel_closed}.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8987 Aux Id: seq11748</p>
+ </item>
+ <item>
+ <p>
+ SSH did not handle the error reason enetunreach
+ when trying to open a IPv6 connection.</p>
+ <p>
+ Own Id: OTP-9031</p>
+ </item>
+ </list>
+ </section>
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ It is now possible to use SSH to sign and verify binary data.</p>
+ <p>
+ Own Id: OTP-8986</p>
+ </item>
+ <item>
+ <p>
+ SSH now ensures that the .ssh directory exists before trying
+ to access files located in that directory.</p>
+ <p>
+ Own Id: OTP-9010</p>
+ </item>
+ </list>
+ </section>
+</section>
+<section><title>Ssh 2.0.3</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The fix regarding OTP-8849 was not included in the
+ previous version as stated.</p>
+ <p>
+ Own Id: OTP-8918</p>
+ </item>
+ </list>
+ </section>
+</section>
+
+<section><title>Ssh 2.0.2</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The ssh_system_sup did not catch noproc and shutdown
+ messages.</p>
+ <p>
+ Own Id: OTP-8863</p>
+ </item>
+ <item>
+ <p>
+ In some cases a crash report was generated when a
+ connection was closing down. This was caused by a race
+ condition between two processes.</p>
+ <p>
+ Own Id: OTP-8881 Aux Id: seq11656, seq11648 </p>
+ </item>
+ </list>
+ </section>
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ SSH no longer use deprecated public_key functions.</p>
+ <p>
+ Own Id: OTP-8849</p>
+ </item>
+ </list>
+ </section>
+ </section>
+ <section><title>Ssh 2.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index 71e6b2cd3d..2c5096a25f 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -283,6 +283,22 @@
</func>
<func>
+ <name>sign_data(Data, Algorithm) -> Signature | {error, Reason}</name>
+ <fsummary> </fsummary>
+ <type>
+ <v> Data = binary()</v>
+ <v> Algorithm = "ssh-rsa"</v>
+ <v> Signature = binary()</v>
+ <v> Reason = term()</v>
+ </type>
+ <desc>
+ <p>Signs the supplied binary using the SSH key.
+ </p>
+ </desc>
+ </func>
+
+
+ <func>
<name>start() -> </name>
<name>start(Type) -> ok | {error, Reason}</name>
<fsummary>Starts the Ssh application. </fsummary>
@@ -339,6 +355,22 @@
by the listener up and running.</p>
</desc>
</func>
+
+ <func>
+ <name>verify_data(Data, Signature, Algorithm) -> ok | {error, Reason}</name>
+ <fsummary> </fsummary>
+ <type>
+ <v> Data = binary()</v>
+ <v> Algorithm = "ssh-rsa"</v>
+ <v> Signature = binary()</v>
+ <v> Reason = term()</v>
+ </type>
+ <desc>
+ <p>Verifies the supplied binary against the binary signature.
+ </p>
+ </desc>
+ </func>
+
</funcs>
</erlref>
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index 21f7508555..501da8ceb9 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,9 +19,35 @@
{"%VSN%",
[
+ {"2.0.3", [{load_module, ssh_file, soft_purge, soft_purge, []},
+ {load_module, ssh, soft_purge, soft_purge, []},
+ {load_module, ssh_rsa, soft_purge, soft_purge, []},
+ {load_module, ssh_acceptor, soft_purge, soft_purge, []},
+ {load_module, ssh_transport, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]},
+ {"2.0.2", [{load_module, ssh_file, soft_purge, soft_purge, []},
+ {load_module, ssh, soft_purge, soft_purge, []},
+ {load_module, ssh_rsa, soft_purge, soft_purge, []},
+ {load_module, ssh_acceptor, soft_purge, soft_purge, []},
+ {load_module, ssh_transport, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]},
+ {"2.0.1", [{restart_application, ssh}]}
],
[
- ]
+ {"2.0.3", [{load_module, ssh_file, soft_purge, soft_purge, []},
+ {load_module, ssh, soft_purge, soft_purge, []},
+ {load_module, ssh_rsa, soft_purge, soft_purge, []},
+ {load_module, ssh_acceptor, soft_purge, soft_purge, []},
+ {load_module, ssh_transport, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]},
+ {"2.0.2", [{load_module, ssh_file, soft_purge, soft_purge, []},
+ {load_module, ssh, soft_purge, soft_purge, []},
+ {load_module, ssh_rsa, soft_purge, soft_purge, []},
+ {load_module, ssh_acceptor, soft_purge, soft_purge, []},
+ {load_module, ssh_transport, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]},
+ {"2.0.1", [{restart_application, ssh}]}
+ ]
}.
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 994c77436a..cada109df0 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -30,6 +30,8 @@
stop_listener/1, stop_listener/2, stop_daemon/1, stop_daemon/2,
shell/1, shell/2, shell/3]).
+-export([sign_data/2, verify_data/3]).
+
%%--------------------------------------------------------------------
%% Function: start([, Type]) -> ok
%%
@@ -94,11 +96,17 @@ connect(Host, Port, Options, Timeout) ->
do_demonitor(MRef, Manager),
{error, Other};
{'DOWN', MRef, _, Manager, Reason} when is_pid(Manager) ->
+ error_logger:warning_report([{ssh, connect},
+ {diagnose,
+ "Connection was closed before properly set up."},
+ {host, Host},
+ {port, Port},
+ {reason, Reason}]),
receive %% Clear EXIT message from queue
{'EXIT', Manager, _What} ->
- {error, Reason}
+ {error, channel_closed}
after 0 ->
- {error, Reason}
+ {error, channel_closed}
end
after Timeout ->
do_demonitor(MRef, Manager),
@@ -239,6 +247,43 @@ shell(Host, Port, Options) ->
Error
end.
+
+%%--------------------------------------------------------------------
+%% Function: sign_data(Data, Algorithm) -> binary() |
+%% {error, Reason}
+%%
+%% Data = binary()
+%% Algorithm = "ssh-rsa"
+%%
+%% Description: Use SSH key to sign data.
+%%--------------------------------------------------------------------
+sign_data(Data, Algorithm) when is_binary(Data) ->
+ case ssh_file:private_identity_key(Algorithm,[]) of
+ {ok, Key} when Algorithm == "ssh-rsa" ->
+ ssh_rsa:sign(Key, Data);
+ Error ->
+ Error
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: verify_data(Data, Signature, Algorithm) -> ok |
+%% {error, Reason}
+%%
+%% Data = binary()
+%% Signature = binary()
+%% Algorithm = "ssh-rsa"
+%%
+%% Description: Use SSH signature to verify data.
+%%--------------------------------------------------------------------
+verify_data(Data, Signature, Algorithm) when is_binary(Data), is_binary(Signature) ->
+ case ssh_file:public_identity_key(Algorithm, []) of
+ {ok, Key} when Algorithm == "ssh-rsa" ->
+ ssh_rsa:verify(Key, Data, Signature);
+ Error ->
+ Error
+ end.
+
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl
index 9060626ab3..59fbd24cf5 100644
--- a/lib/ssh/src/ssh_acceptor.erl
+++ b/lib/ssh/src/ssh_acceptor.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -55,6 +55,10 @@ acceptor_init(Parent, Port, Address, SockOpts, Opts, AcceptTimeout) ->
do_socket_listen(Callback, Port, Opts) ->
case Callback:listen(Port, Opts) of
+ {error, nxdomain} ->
+ Callback:listen(Port, lists:delete(inet6, Opts));
+ {error, enetunreach} ->
+ Callback:listen(Port, lists:delete(inet6, Opts));
{error, eafnosupport} ->
Callback:listen(Port, lists:delete(inet6, Opts));
Other ->
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index d46002c494..0ba11b0a26 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -705,11 +705,19 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName,
Byte == ?SSH_MSG_CHANNEL_REQUEST;
Byte == ?SSH_MSG_CHANNEL_SUCCESS;
Byte == ?SSH_MSG_CHANNEL_FAILURE ->
- ssh_connection_manager:event(Pid, Msg),
- State = generate_event_new_state(State0, EncData),
- next_packet(State),
- {next_state, StateName, State};
+ try
+ ssh_connection_manager:event(Pid, Msg),
+ State = generate_event_new_state(State0, EncData),
+ next_packet(State),
+ {next_state, StateName, State}
+ catch
+ exit:{noproc, _Reason} ->
+ Report = io_lib:format("~p Connection Handler terminated: ~p~n",
+ [self(), Pid]),
+ error_logger:info_report(Report),
+ {stop, normal, State0}
+ end;
generate_event(Msg, StateName, State0, EncData) ->
Event = ssh_bits:decode(Msg),
State = generate_event_new_state(State0, EncData),
diff --git a/lib/ssh/src/ssh_connection_manager.erl b/lib/ssh/src/ssh_connection_manager.erl
index 6bf89224cf..9bfd5270da 100644
--- a/lib/ssh/src/ssh_connection_manager.erl
+++ b/lib/ssh/src/ssh_connection_manager.erl
@@ -147,7 +147,7 @@ close(ConnectionManager, ChannelId) ->
try call(ConnectionManager, {close, ChannelId}) of
ok ->
ok;
- {error,normal} ->
+ {error, channel_closed} ->
ok
catch
exit:{noproc, _} ->
@@ -158,7 +158,7 @@ stop(ConnectionManager) ->
try call(ConnectionManager, stop) of
ok ->
ok;
- {error,normal} ->
+ {error, channel_closed} ->
ok
catch
exit:{noproc, _} ->
@@ -604,7 +604,7 @@ call(Pid, Msg, Timeout) ->
exit:{timeout, _} ->
{error, timeout};
exit:{normal, _} ->
- {error, normal}
+ {error, channel_closed}
end.
cast(Pid, Msg) ->
diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl
index 5572349fe7..ff23f714cd 100755
--- a/lib/ssh/src/ssh_file.erl
+++ b/lib/ssh/src/ssh_file.erl
@@ -27,14 +27,16 @@
-include("PKCS-1.hrl").
-include("DSS.hrl").
+-include_lib("kernel/include/file.hrl").
+
-export([public_host_dsa_key/2,private_host_dsa_key/2,
public_host_rsa_key/2,private_host_rsa_key/2,
public_host_key/2,private_host_key/2,
lookup_host_key/3, add_host_key/3, % del_host_key/2,
lookup_user_key/3, ssh_dir/2, file_name/3]).
--export([private_identity_key/2]).
-%% , public_identity_key/2,
+-export([private_identity_key/2,
+ public_identity_key/2]).
%% identity_keys/2]).
-export([encode_public_key/1, decode_public_key_v2/2]).
@@ -43,6 +45,9 @@
-define(DBG_PATHS, true).
+-define(PERM_700, 8#700).
+-define(PERM_644, 8#644).
+
%% API
public_host_dsa_key(Type, Opts) ->
File = file_name(Type, "ssh_host_dsa_key.pub", Opts),
@@ -113,8 +118,10 @@ do_lookup_host_key(Host, Alg, Opts) ->
add_host_key(Host, Key, Opts) ->
Host1 = add_ip(replace_localhost(Host)),
- case file:open(file_name(user, "known_hosts", Opts),[write,append]) of
+ KnownHosts = file_name(user, "known_hosts", Opts),
+ case file:open(KnownHosts, [write,append]) of
{ok, Fd} ->
+ ok = file:change_mode(KnownHosts, ?PERM_644),
Res = add_key_fd(Fd, Host1, Key),
file:close(Fd),
Res;
@@ -140,6 +147,11 @@ private_identity_key(Alg, Opts) ->
Path = file_name(user, identity_key_filename(Alg), Opts),
read_private_key_v2(Path, Alg).
+public_identity_key(Alg, Opts) ->
+ Path = file_name(user, identity_key_filename(Alg) ++ ".pub", Opts),
+ read_public_key_v2(Path, Alg).
+
+
read_public_key_v2(File, Type) ->
case file:read_file(File) of
{ok,Bin} ->
@@ -198,12 +210,17 @@ read_public_key_v1(File) ->
%% pem_type("ssh-rsa") -> "RSA".
read_private_key_v2(File, Type) ->
- case catch (public_key:pem_to_der(File)) of
- {ok, [{_, Bin, not_encrypted}]} ->
- decode_private_key_v2(Bin, Type);
- Error -> %% Note we do not handle password encrypted keys at the moment
- {error, Error}
- end.
+ case file:read_file(File) of
+ {ok, PemBin} ->
+ case catch (public_key:pem_decode(PemBin)) of
+ [{_, Bin, not_encrypted}] ->
+ decode_private_key_v2(Bin, Type);
+ Error -> %% Note we do not handle password encrypted keys at the moment
+ {error, Error}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
%% case file:read_file(File) of
%% {ok,Bin} ->
%% case read_pem(binary_to_list(Bin), pem_type(Type)) of
@@ -527,4 +544,7 @@ file_name(Type, Name, Opts) ->
default_user_dir()->
{ok,[[Home|_]]} = init:get_argument(home),
- filename:join(Home, ".ssh").
+ UserDir = filename:join(Home, ".ssh"),
+ ok = filelib:ensure_dir(filename:join(UserDir, "dummy")),
+ ok = file:change_mode(UserDir, ?PERM_700),
+ UserDir.
diff --git a/lib/ssh/src/ssh_rsa.erl b/lib/ssh/src/ssh_rsa.erl
index e27cdcf7bd..91b8285b2e 100755
--- a/lib/ssh/src/ssh_rsa.erl
+++ b/lib/ssh/src/ssh_rsa.erl
@@ -202,8 +202,7 @@ rsassa_pkcs1_v1_5_verify(Public=#ssh_key { public={N,_E}}, Mb, Sb) ->
case emsa_pkcs1_v1_5_encode(Mb, K) of
EM -> ok;
_S ->
- io:format("S: ~p~n", [_S]),
- {error, invalid_signature} % exit(invalid_signature)
+ {error, invalid_signature}
end.
diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl
index f4570b8a48..920baaadef 100644
--- a/lib/ssh/src/ssh_system_sup.erl
+++ b/lib/ssh/src/ssh_system_sup.erl
@@ -85,7 +85,7 @@ start_subsystem(SystemSup, Options) ->
supervisor:start_child(SystemSup, Spec).
stop_subsystem(SystemSup, SubSys) ->
- case lists:keyfind(SubSys, 2, supervisor:which_children(SystemSup)) of
+ case catch lists:keyfind(SubSys, 2, supervisor:which_children(SystemSup)) of
false ->
{error, not_found};
{Id, _, _, _} ->
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index e79ccdda0c..de3e29e2f1 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -169,6 +169,8 @@ do_connect(Callback, Address, Port, SocketOpts, Timeout) ->
Callback:connect(Address, Port, lists:delete(inet6, Opts), Timeout);
{error, eafnosupport} ->
Callback:connect(Address, Port, lists:delete(inet6, Opts), Timeout);
+ {error, enetunreach} ->
+ Callback:connect(Address, Port, lists:delete(inet6, Opts), Timeout);
Other ->
Other
end.
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 79fd36cd83..51f9f47446 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,4 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 2.0.1
+SSH_VSN = 2.0.4
APP_VSN = "ssh-$(SSH_VSN)"
+
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index 5f9e436348..8f81ccb567 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -31,7 +31,134 @@
<p>This document describes the changes made to the SSL application.
</p>
- <section><title>SSL 4.0.1</title>
+ <section><title>SSL 4.1.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed error in cache-handling fix from ssl-4.1.2</p>
+ <p>
+ Own Id: OTP-9018 Aux Id: seq11739 </p>
+ </item>
+ <item>
+ <p>
+ Verification of a critical extended_key_usage-extension
+ corrected</p>
+ <p>
+ Own Id: OTP-9029 Aux Id: seq11541 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 4.1.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The ssl application caches certificate files, it will now
+ invalidate cache entries if the diskfile is changed.</p>
+ <p>
+ Own Id: OTP-8965 Aux Id: seq11739 </p>
+ </item>
+ <item>
+ <p>
+ Now runs the terminate function before returning from the
+ call made by ssl:close/1, as before the caller of
+ ssl:close/1 could get problems with the reuseaddr option.</p>
+ <p>
+ Own Id: OTP-8992</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 4.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Correct handling of client certificate verify message
+ When checking the client certificate verify message the
+ server used the wrong algorithm identifier to determine
+ the signing algorithm, causing a function clause error in
+ the public_key application when the key-exchange
+ algorithm and the public key algorithm of the client
+ certificate happen to differ.</p>
+ <p>
+ Own Id: OTP-8897</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ For testing purposes ssl now also support some anonymous
+ cipher suites when explicitly configured to do so.</p>
+ <p>
+ Own Id: OTP-8870</p>
+ </item>
+ <item>
+ <p>
+ Sends an error alert instead of crashing if a crypto
+ function for the selected cipher suite fails.</p>
+ <p>
+ Own Id: OTP-8930 Aux Id: seq11720 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 4.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Updated ssl to ignore CA certs that violate the asn1-spec
+ for a certificate, and updated public key asn1 spec to
+ handle inherited DSS-params.</p>
+ <p>
+ Own Id: OTP-7884</p>
+ </item>
+ <item>
+ <p>
+ Changed ssl implementation to retain backwards
+ compatibility for old option {verify, 0} that shall be
+ equivalent to {verify, verify_none}, also separate the
+ cases unknown ca and selfsigned peer cert, and restored
+ return value of deprecated function
+ public_key:pem_to_der/1.</p>
+ <p>
+ Own Id: OTP-8858</p>
+ </item>
+ <item>
+ <p>
+ Changed the verify fun so that it differentiate between
+ the peer certificate and CA certificates by using
+ valid_peer or valid as the second argument to the verify
+ fun. It may not always be trivial or even possible to
+ know when the peer certificate is reached otherwise.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8873</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 4.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index d5b7253ef3..daf7b77527 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2010</year>
+ <year>1999</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -72,10 +72,10 @@
{verify_fun, {fun(), term()}} |
{fail_if_no_peer_cert, boolean()}
{depth, integer()} |
- {cert, der_bin()}| {certfile, path()} |
- {key, der_bin()} | {keyfile, path()} | {password, string()} |
- {cacerts, [der_bin()]} | {cacertfile, path()} |
- |{dh, der_bin()} | {dhfile, path()} | {ciphers, ciphers()} |
+ {cert, der_encoded()}| {certfile, path()} |
+ {key, der_encoded()} | {keyfile, path()} | {password, string()} |
+ {cacerts, [der_encoded()]} | {cacertfile, path()} |
+ |{dh, der_encoded()} | {dhfile, path()} | {ciphers, ciphers()} |
{ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} | {reuse_session, fun()}
</c></p>
@@ -95,7 +95,7 @@
<p><c>path() = string() - representing a file path.</c></p>
- <p><c>der_bin() = binary() -Asn1 DER encoded entity as an erlang binary.</c></p>
+ <p><c>der_encoded() = binary() -Asn1 DER encoded entity as an erlang binary.</c></p>
<p><c>host() = hostname() | ipaddress()</c></p>
@@ -114,7 +114,7 @@
<p><c>ciphersuite() =
{key_exchange(), cipher(), hash()}</c></p>
- <p><c>key_exchange() = rsa | dhe_dss | dhe_rsa
+ <p><c>key_exchange() = rsa | dhe_dss | dhe_rsa | dh_anon
</c></p>
<p><c>cipher() = rc4_128 | des_cbc | '3des_ede_cbc'
@@ -136,14 +136,14 @@
<taglist>
- <tag>{cert, der_bin()}</tag>
+ <tag>{cert, der_encoded()}</tag>
<item> The DER encoded users certificate. If this option
is supplied it will override the certfile option.</item>
<tag>{certfile, path()}</tag>
<item>Path to a file containing the user's certificate.</item>
- <tag>{key, der_bin()}</tag>
+ <tag>{key, der_encoded()}</tag>
<item> The DER encoded users private key. If this option
is supplied it will override the keyfile option.</item>
@@ -158,7 +158,7 @@
Only used if the private keyfile is password protected.
</item>
- <tag>{cacerts, [der_bin()]}</tag>
+ <tag>{cacerts, [der_encoded()]}</tag>
<item> The DER encoded trusted certificates. If this option
is supplied it will override the cacertfile option.</item>
@@ -170,8 +170,13 @@
<tag>{ciphers, ciphers()}</tag>
<item>The cipher suites that should be supported. The function
- <c>ciphers_suites/0</c> can be used to find all available
- ciphers.
+ <c>cipher_suites/0</c> can be used to find all available
+ ciphers. Additionally some anonymous cipher suites ({dh_anon,
+ rc4_128, md5}, {dh_anon, des_cbc, sha}, {dh_anon,
+ '3des_ede_cbc', sha}, {dh_anon, aes_128_cbc, sha}, {dh_anon,
+ aes_256_cbc, sha}) are supported for testing purposes and will
+ only work if explicitly enabled by this option and they are supported/enabled
+ by the peer also.
</item>
<tag>{ssl_imp, ssl_imp()}</tag>
@@ -202,10 +207,10 @@
<p>The verification fun should be defined as:</p>
<code>
-fun(OtpCert :: #'OtpCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
+fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
{extension, #'Extension'{}}, InitialUserState :: term()) ->
- {valid, UserState :: term()} | {fail, Reason :: term()} |
- {unknown, UserState :: term()}.
+ {valid, UserState :: term()} | {valid_peer, UserState :: term()} |
+ {fail, Reason :: term()} | {unknown, UserState :: term()}.
</code>
<p>The verify fun will be called during the X509-path
@@ -213,10 +218,12 @@ fun(OtpCert :: #'OtpCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
application is encountered. Additionally it will be called
when a certificate is considered valid by the path validation
to allow access to each certificate in the path to the user
- application.
- See
- <seealso marker="public_key:application">public_key(3)</seealso>
- for definition of #'OtpCertificate'{} and #'Extension'{}.</p>
+ application. Note that the it will differentiate between the
+ peer certificate and CA certificates by using valid_peer or
+ valid as the second argument to the verify fun. See <seealso
+ marker="public_key:cert_records">the public_key User's
+ Guide</seealso> for definition of #'OTPCertificate'{} and
+ #'Extension'{}.</p>
<p>If the verify callback fun returns {fail, Reason}, the
verification process is immediately stopped and an alert is
@@ -237,21 +244,23 @@ fun(OtpCert :: #'OtpCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
(_,{extension, _}, UserState) ->
{unknown, UserState};
(_, valid, UserState) ->
- {valid, UserState}
+ {valid, UserState};
+ (_, valid_peer, UserState) ->
+ {valid, UserState}
end, []}
</code>
<p>The default verify_fun option in verify_none mode:</p>
<code>
-{fun(_,{bad_cert, unknown_ca}, UserState) ->
+{fun(_,{bad_cert, _}, UserState) ->
{valid, UserState};
- (_,{bad_cert, _} = Reason, _) ->
- {fail, Reason};
(_,{extension, _}, UserState) ->
{unknown, UserState};
(_, valid, UserState) ->
- {valid, UserState}
+ {valid, UserState};
+ (_, valid_peer, UserState) ->
+ {valid, UserState}
end, []}
</code>
@@ -267,13 +276,14 @@ fun(OtpCert :: #'OtpCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<section>
<title>SSL OPTION DESCRIPTIONS - CLIENT SIDE</title>
- <p>Option described here are client specific or has a slightly different
+ <p>Options described here are client specific or has a slightly different
meaning in the client than in the server.</p>
<taglist>
<tag>{verify, verify_type()}</tag>
- <item> In verify_none mode the x509-path validation error {bad_cert, unknown_ca}
- will automatically be accepted. See also the verify_fun option.
+ <item> In verify_none mode the default behavior will be to
+ allow all x509-path validation errors. See also the verify_fun
+ option.
</item>
<tag>{reuse_sessions, boolean()}</tag>
<item>Specifies if client should try to reuse sessions
@@ -286,12 +296,12 @@ fun(OtpCert :: #'OtpCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<section>
<title>SSL OPTION DESCRIPTIONS - SERVER SIDE</title>
- <p>Option described here are server specific or has a slightly different
+ <p>Options described here are server specific or has a slightly different
meaning in the server than in the client.</p>
<taglist>
- <tag>{dh, der_bin()}</tag>
+ <tag>{dh, der_encoded()}</tag>
<item>The DER encoded Diffie Hellman parameters. If this option
is supplied it will override the dhfile option.
</item>
diff --git a/lib/ssl/src/inet_ssl_dist.erl b/lib/ssl/src/inet_ssl_dist.erl
index f62aefd35a..6c0fbc0618 100644
--- a/lib/ssl/src/inet_ssl_dist.erl
+++ b/lib/ssl/src/inet_ssl_dist.erl
@@ -1,8 +1,8 @@
-%%<copyright>
-%% <year>2000-2008</year>
-%% <holder>Ericsson AB, All Rights Reserved</holder>
-%%</copyright>
-%%<legalnotice>
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
@@ -14,8 +14,9 @@
%% the License for the specific language governing rights and limitations
%% under the License.
%%
-%% The Initial Developer of the Original Code is Ericsson AB.
-%%</legalnotice>
+%% %CopyrightEnd%
+%%
+
%%
-module(inet_ssl_dist).
@@ -135,6 +136,9 @@ accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
[self(), AcceptPid, Socket, MyNode,
Allowed, SetupTime]).
+%% Suppress dialyzer warning, we do not really care about old ssl code
+%% as we intend to remove it.
+-spec(do_accept(_,_,_,_,_,_) -> no_return()).
do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
process_flag(priority, max),
receive
@@ -167,8 +171,8 @@ do_accept(Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
ssl_prim:getll(S)
end,
f_address = fun get_remote_id/2,
- mf_tick = {?MODULE, tick},
- mf_getstat = {?MODULE,getstat}
+ mf_tick = fun ?MODULE:tick/1,
+ mf_getstat = fun ?MODULE:getstat/1
},
dist_util:handshake_other_started(HSData);
{false,IP} ->
@@ -204,6 +208,9 @@ setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
LongOrShortNames,
SetupTime]).
+%% Suppress dialyzer warning, we do not really care about old ssl code
+%% as we intend to remove it.
+-spec(do_setup(_,_,_,_,_,_) -> no_return()).
do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
process_flag(priority, max),
?trace("~p~n",[{inet_ssl_dist,self(),setup,Node}]),
@@ -258,8 +265,8 @@ do_setup(Kernel, Node, Type, MyNode, LongOrShortNames,SetupTime) ->
protocol = ssl,
family = inet}
end,
- mf_tick = {?MODULE, tick},
- mf_getstat = {?MODULE,getstat},
+ mf_tick = fun ?MODULE:tick/1,
+ mf_getstat = fun ?MODULE:getstat/1,
request_type = Type
},
dist_util:handshake_we_started(HSData);
diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src
index 88cd73be74..e6a8c557fc 100644
--- a/lib/ssl/src/ssl.appup.src
+++ b/lib/ssl/src/ssl.appup.src
@@ -1,32 +1,15 @@
%% -*- erlang -*-
{"%VSN%",
[
- {"4.0", [{restart_application, ssl}]},
- {"3.11.1", [{restart_application, ssl}]},
- {"3.11", [{restart_application, ssl}]},
- {"3.10", [{restart_application, ssl}]},
- {"3.10.1", [{restart_application, ssl}]},
- {"3.10.2", [{restart_application, ssl}]},
- {"3.10.3", [{restart_application, ssl}]},
- {"3.10.4", [{restart_application, ssl}]},
- {"3.10.5", [{restart_application, ssl}]},
- {"3.10.6", [{restart_application, ssl}]},
- {"3.10.7", [{restart_application, ssl}]},
- {"3.10.8", [{restart_application, ssl}]},
- {"3.10.9", [{restart_application, ssl}]}
+ {"4.1.2", [{restart_application, ssl}]},
+ {"4.1.1", [{restart_application, ssl}]},
+ {"4.1", [{restart_application, ssl}]},
+ {"4.0.1", [{restart_application, ssl}]}
],
[
- {"4.0", [{restart_application, ssl}]},
- {"3.11.1", [{restart_application, ssl}]},
- {"3.11", [{restart_application, ssl}]},
- {"3.10", [{restart_application, ssl}]},
- {"3.10.1", [{restart_application, ssl}]},
- {"3.10.2", [{restart_application, ssl}]},
- {"3.10.3", [{restart_application, ssl}]},
- {"3.10.4", [{restart_application, ssl}]},
- {"3.10.5", [{restart_application, ssl}]},
- {"3.10.6", [{restart_application, ssl}]},
- {"3.10.8", [{restart_application, ssl}]},
- {"3.10.9", [{restart_application, ssl}]}
+ {"4.1.2", [{restart_application, ssl}]},
+ {"4.1.1", [{restart_application, ssl}]},
+ {"4.1", [{restart_application, ssl}]},
+ {"4.0.1", [{restart_application, ssl}]}
]}.
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 314bdd1aab..b85188b878 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -49,10 +49,31 @@
inet_ssl, %% inet options for internal ssl socket
cb %% Callback info
}).
+-type option() :: socketoption() | ssloption() | transportoption().
+-type socketoption() :: [{property(), term()}]. %% See gen_tcp and inet
+-type property() :: atom().
+
+-type ssloption() :: {verify, verify_type()} |
+ {verify_fun, {fun(), InitialUserState::term()}} |
+ {fail_if_no_peer_cert, boolean()} | {depth, integer()} |
+ {cert, der_encoded()} | {certfile, path()} | {key, der_encoded()} |
+ {keyfile, path()} | {password, string()} | {cacerts, [der_encoded()]} |
+ {cacertfile, path()} | {dh, der_encoded()} | {dhfile, path()} |
+ {ciphers, ciphers()} | {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} |
+ {reuse_session, fun()}.
+
+-type verify_type() :: verify_none | verify_peer.
+-type path() :: string().
+-type ciphers() :: [erl_cipher_suite()] |
+ string(). % (according to old API)
+-type ssl_imp() :: new | old.
+
+-type transportoption() :: {CallbackModule::atom(), DataTag::atom(), ClosedTag::atom()}.
+
%%--------------------------------------------------------------------
--spec start() -> ok.
--spec start(permanent | transient | temporary) -> ok.
+-spec start() -> ok | {error, reason()}.
+-spec start(permanent | transient | temporary) -> ok | {error, reason()}.
%%
%% Description: Utility function that starts the ssl,
%% crypto and public_key applications. Default type
@@ -77,9 +98,12 @@ stop() ->
application:stop(ssl).
%%--------------------------------------------------------------------
--spec connect(host() | port(), list()) -> {ok, #sslsocket{}}.
--spec connect(host() | port(), list() | port_num(), timeout() | list()) -> {ok, #sslsocket{}}.
--spec connect(host() | port(), port_num(), list(), timeout()) -> {ok, #sslsocket{}}.
+-spec connect(host() | port(), [option()]) -> {ok, #sslsocket{}} |
+ {error, reason()}.
+-spec connect(host() | port(), [option()] | port_num(), timeout() | list()) ->
+ {ok, #sslsocket{}} | {error, reason()}.
+-spec connect(host() | port(), port_num(), list(), timeout()) ->
+ {ok, #sslsocket{}} | {error, reason()}.
%%
%% Description: Connect to a ssl server.
@@ -126,7 +150,7 @@ connect(Host, Port, Options0, Timeout) ->
end.
%%--------------------------------------------------------------------
--spec listen(port_num(), list()) ->{ok, #sslsocket{}} | {error, reason()}.
+-spec listen(port_num(), [option()]) ->{ok, #sslsocket{}} | {error, reason()}.
%%
%% Description: Creates a ssl listen socket.
@@ -150,8 +174,10 @@ listen(Port, Options0) ->
end.
%%--------------------------------------------------------------------
--spec transport_accept(#sslsocket{}) -> {ok, #sslsocket{}}.
--spec transport_accept(#sslsocket{}, timeout()) -> {ok, #sslsocket{}}.
+-spec transport_accept(#sslsocket{}) -> {ok, #sslsocket{}} |
+ {error, reason()}.
+-spec transport_accept(#sslsocket{}, timeout()) -> {ok, #sslsocket{}} |
+ {error, reason()}.
%%
%% Description: Performs transport accept on a ssl listen socket
%%--------------------------------------------------------------------
@@ -189,9 +215,10 @@ transport_accept(#sslsocket{} = ListenSocket, Timeout) ->
ssl_broker:transport_accept(Pid, ListenSocket, Timeout).
%%--------------------------------------------------------------------
--spec ssl_accept(#sslsocket{}) -> {ok, #sslsocket{}} | {error, reason()}.
--spec ssl_accept(#sslsocket{}, list() | timeout()) -> {ok, #sslsocket{}} | {error, reason()}.
--spec ssl_accept(port(), list(), timeout()) -> {ok, #sslsocket{}} | {error, reason()}.
+-spec ssl_accept(#sslsocket{}) -> ok | {error, reason()}.
+-spec ssl_accept(#sslsocket{} | port(), timeout()| [option()]) ->
+ ok | {ok, #sslsocket{}} | {error, reason()}.
+-spec ssl_accept(port(), [option()], timeout()) -> {ok, #sslsocket{}} | {error, reason()}.
%%
%% Description: Performs accept on a ssl listen socket. e.i. performs
%% ssl handshake.
@@ -621,17 +648,19 @@ handle_options(Opts0, _Role) ->
ReuseSessionFun = fun(_, _, _, _) -> true end,
- VerifyNoneFun =
- {fun(_,{bad_cert, unknown_ca}, UserState) ->
+ DefaultVerifyNoneFun =
+ {fun(_,{bad_cert, _}, UserState) ->
{valid, UserState};
- (_,{bad_cert, _} = Reason, _) ->
- {fail, Reason};
(_,{extension, _}, UserState) ->
{unknown, UserState};
(_, valid, UserState) ->
+ {valid, UserState};
+ (_, valid_peer, UserState) ->
{valid, UserState}
end, []},
+ VerifyNoneFun = handle_option(verify_fun, Opts, DefaultVerifyNoneFun),
+
UserFailIfNoPeerCert = handle_option(fail_if_no_peer_cert, Opts, false),
UserVerifyFun = handle_option(verify_fun, Opts, undefined),
CaCerts = handle_option(cacerts, Opts, undefined),
@@ -727,6 +756,8 @@ validate_option(verify_fun, Fun) when is_function(Fun) ->
(_,{extension, _}, UserState) ->
{unknown, UserState};
(_, valid, UserState) ->
+ {valid, UserState};
+ (_, valid_peer, UserState) ->
{valid, UserState}
end, Fun};
validate_option(verify_fun, {Fun, _} = Value) when is_function(Fun) ->
@@ -743,7 +774,7 @@ validate_option(depth, Value) when is_integer(Value),
validate_option(cert, Value) when Value == undefined;
is_binary(Value) ->
Value;
-validate_option(certfile, Value) when is_list(Value) ->
+validate_option(certfile, Value) when Value == undefined; is_list(Value) ->
Value;
validate_option(key, undefined) ->
@@ -886,7 +917,7 @@ cipher_suites(Version, [{_,_,_}| _] = Ciphers0) ->
Ciphers = [ssl_cipher:suite(C) || C <- Ciphers0],
cipher_suites(Version, Ciphers);
cipher_suites(Version, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) ->
- Supported = ssl_cipher:suites(Version),
+ Supported = ssl_cipher:suites(Version) ++ ssl_cipher:anonymous_suites(),
case [Cipher || Cipher <- Ciphers0, lists:member(Cipher, Supported)] of
[] ->
Supported;
diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl
index d2ab21657c..8c0c2bfa5d 100644
--- a/lib/ssl/src/ssl_certificate.erl
+++ b/lib/ssl/src/ssl_certificate.erl
@@ -28,7 +28,6 @@
-include("ssl_handshake.hrl").
-include("ssl_alert.hrl").
-include("ssl_internal.hrl").
--include("ssl_debug.hrl").
-include_lib("public_key/include/public_key.hrl").
-export([trusted_cert_and_path/2,
@@ -57,30 +56,32 @@
trusted_cert_and_path(CertChain, CertDbRef) ->
Path = [Cert | _] = lists:reverse(CertChain),
OtpCert = public_key:pkix_decode_cert(Cert, otp),
- IssuerID =
+ SignedAndIssuerID =
case public_key:pkix_is_self_signed(OtpCert) of
true ->
{ok, IssuerId} = public_key:pkix_issuer_id(OtpCert, self),
- IssuerId;
+ {self, IssuerId};
false ->
case public_key:pkix_issuer_id(OtpCert, other) of
{ok, IssuerId} ->
- IssuerId;
+ {other, IssuerId};
{error, issuer_not_found} ->
case find_issuer(OtpCert, no_candidate) of
{ok, IssuerId} ->
- IssuerId;
+ {other, IssuerId};
Other ->
Other
end
end
end,
- case IssuerID of
+ case SignedAndIssuerID of
{error, issuer_not_found} ->
%% The root CA was not sent and can not be found.
{unknown_ca, Path};
- {SerialNr, Issuer} ->
+ {self, _} when length(Path) == 1 ->
+ {selfsigned_peer, Path};
+ {_ ,{SerialNr, Issuer}} ->
case ssl_manager:lookup_trusted_cert(CertDbRef, SerialNr, Issuer) of
{ok, {BinCert,_}} ->
{BinCert, Path};
@@ -130,6 +131,8 @@ validate_extension(_, {bad_cert, _} = Reason, _) ->
validate_extension(_, {extension, _}, Role) ->
{unknown, Role};
validate_extension(_, valid, Role) ->
+ {valid, Role};
+validate_extension(_, valid_peer, Role) ->
{valid, Role}.
%%--------------------------------------------------------------------
diff --git a/lib/ssl/src/ssl_certificate_db.erl b/lib/ssl/src/ssl_certificate_db.erl
index 39d9847e3b..3eceefa304 100644
--- a/lib/ssl/src/ssl_certificate_db.erl
+++ b/lib/ssl/src/ssl_certificate_db.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -27,7 +27,9 @@
-export([create/0, remove/1, add_trusted_certs/3,
remove_trusted_certs/2, lookup_trusted_cert/3, issuer_candidate/1,
- lookup_cached_certs/1, cache_pem_file/3]).
+ lookup_cached_certs/1, cache_pem_file/4, uncache_pem_file/2, lookup/2]).
+
+-type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
%%====================================================================
%% Internal application API
@@ -98,17 +100,35 @@ add_trusted_certs(Pid, File, [CertsDb, FileToRefDb, PidToFileDb]) ->
insert(Pid, File, PidToFileDb),
{ok, Ref}.
%%--------------------------------------------------------------------
--spec cache_pem_file(pid(), string(), certdb_ref()) -> term().
+-spec cache_pem_file(pid(), string(), time(), certdb_ref()) -> term().
%%
%% Description: Cache file as binary in DB
%%--------------------------------------------------------------------
-cache_pem_file(Pid, File, [CertsDb, _FileToRefDb, PidToFileDb]) ->
+cache_pem_file(Pid, File, Time, [CertsDb, _FileToRefDb, PidToFileDb]) ->
{ok, PemBin} = file:read_file(File),
Content = public_key:pem_decode(PemBin),
- insert({file, File}, Content, CertsDb),
+ insert({file, File}, {Time, Content}, CertsDb),
insert(Pid, File, PidToFileDb),
{ok, Content}.
+%--------------------------------------------------------------------
+-spec uncache_pem_file(string(), certdb_ref()) -> no_return().
+%%
+%% Description: If a cached file is no longer valid (changed on disk)
+%% we must terminate the connections using the old file content, and
+%% when those processes are finish the cache will be cleaned. It is
+%% a rare but possible case a new ssl client/server is started with
+%% a filename with the same name as previously started client/server
+%% but with different content.
+%% --------------------------------------------------------------------
+uncache_pem_file(File, [_CertsDb, _FileToRefDb, PidToFileDb]) ->
+ Pids = select(PidToFileDb, [{{'$1', File},[],['$$']}]),
+ lists:foreach(fun([Pid]) ->
+ exit(Pid, shutdown)
+ end, Pids).
+
+
+
%%--------------------------------------------------------------------
-spec remove_trusted_certs(pid(), certdb_ref()) -> term().
@@ -174,6 +194,22 @@ issuer_candidate(PrevCandidateKey) ->
end.
%%--------------------------------------------------------------------
+-spec lookup(term(), term()) -> term() | undefined.
+%%
+%% Description: Looks up an element in a certificat <Db>.
+%%--------------------------------------------------------------------
+lookup(Key, Db) ->
+ case ets:lookup(Db, Key) of
+ [] ->
+ undefined;
+ Contents ->
+ Pick = fun({_, Data}) -> Data;
+ ({_,_,Data}) -> Data
+ end,
+ [Pick(Data) || Data <- Contents]
+ end.
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
certificate_db_name() ->
@@ -191,16 +227,8 @@ ref_count(Key, Db,N) ->
delete(Key, Db) ->
_ = ets:delete(Db, Key).
-lookup(Key, Db) ->
- case ets:lookup(Db, Key) of
- [] ->
- undefined;
- Contents ->
- Pick = fun({_, Data}) -> Data;
- ({_,_,Data}) -> Data
- end,
- [Pick(Data) || Data <- Contents]
- end.
+select(Db, MatchSpec)->
+ ets:select(Db, MatchSpec).
remove_certs(Ref, CertsDb) ->
ets:match_delete(CertsDb, {{Ref, '_', '_'}, '_'}).
@@ -223,8 +251,8 @@ add_certs(Cert, Ref, CertsDb) ->
TBSCertificate#'OTPTBSCertificate'.issuer),
insert({Ref, SerialNumber, Issuer}, {Cert,ErlCert}, CertsDb)
catch
- error:Reason ->
- Report = io_lib:format("SSL WARNING: Ignoring CA cert: ~p~n Due to decoding error:~p ~n",
- [Cert, Reason]),
+ error:_ ->
+ Report = io_lib:format("SSL WARNING: Ignoring a CA cert as "
+ "it could not be correctly decoded.~n", []),
error_logger:info_report(Report)
end.
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index 8230149304..72f02a4362 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -29,12 +29,11 @@
-include("ssl_record.hrl").
-include("ssl_cipher.hrl").
-include("ssl_alert.hrl").
--include("ssl_debug.hrl").
-include_lib("public_key/include/public_key.hrl").
-export([security_parameters/2, suite_definition/1,
decipher/5, cipher/4,
- suite/1, suites/1,
+ suite/1, suites/1, anonymous_suites/0,
openssl_suite/1, openssl_suite_name/1, filter/2]).
-compile(inline).
@@ -75,20 +74,12 @@ cipher(?RC4, CipherState, Mac, Fragment) ->
S -> S
end,
GenStreamCipherList = [Fragment, Mac],
-
- ?DBG_HEX(GenStreamCipherList),
- ?DBG_HEX(State0),
{State1, T} = crypto:rc4_encrypt_with_state(State0, GenStreamCipherList),
- ?DBG_HEX(T),
{T, CipherState#cipher_state{state = State1}};
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(?'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)
@@ -109,11 +100,7 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0,
TotSz = byte_size(Mac) + erlang:iolist_size(Fragment) + 1,
{PaddingLength, Padding} = get_padding(TotSz, BlockSz),
L = [Fragment, Mac, PaddingLength, Padding],
- ?DBG_HEX(Key),
- ?DBG_HEX(IV),
- ?DBG_HEX(L),
T = Fun(Key, IV, L),
- ?DBG_HEX(T),
NextIV = next_iv(T, IV),
{T, CS0#cipher_state{iv=NextIV}}.
@@ -127,26 +114,29 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0,
decipher(?NULL, _HashSz, CipherState, Fragment, _) ->
{Fragment, <<>>, CipherState};
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);
S -> S
end,
- ?DBG_HEX(State0),
- ?DBG_HEX(Fragment),
- {State1, T} = crypto:rc4_encrypt_with_state(State0, Fragment),
- ?DBG_HEX(T),
- GSC = generic_stream_cipher_from_bin(T, HashSz),
- #generic_stream_cipher{content=Content, mac=Mac} = GSC,
- {Content, Mac, CipherState#cipher_state{state=State1}};
+ try crypto:rc4_encrypt_with_state(State0, Fragment) of
+ {State, Text} ->
+ GSC = generic_stream_cipher_from_bin(Text, HashSz),
+ #generic_stream_cipher{content = Content, mac = Mac} = GSC,
+ {Content, Mac, CipherState#cipher_state{state = State}}
+ catch
+ _:_ ->
+ %% This is a DECRYPTION_FAILED but
+ %% "differentiating between bad_record_mac and decryption_failed
+ %% alerts may permit certain attacks against CBC mode as used in
+ %% TLS [CBCATT]. It is preferable to uniformly use the
+ %% bad_record_mac alert to hide the specific type of the error."
+ ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
+ end;
+
decipher(?DES, HashSz, CipherState, Fragment, Version) ->
block_decipher(fun(Key, IV, T) ->
crypto:des_cbc_decrypt(Key, IV, T)
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)
@@ -164,22 +154,27 @@ decipher(?AES, HashSz, CipherState, Fragment, Version) ->
block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0,
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),
- 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 ->
+ try Fun(Key, IV, Fragment) of
+ Text ->
+ GBC = generic_block_cipher_from_bin(Text, HashSz),
+ 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
+ catch
+ _:_ ->
+ %% This is a DECRYPTION_FAILED but
+ %% "differentiating between bad_record_mac and decryption_failed
+ %% alerts may permit certain attacks against CBC mode as used in
+ %% TLS [CBCATT]. It is preferable to uniformly use the
+ %% bad_record_mac alert to hide the specific type of the error."
?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
end.
-
%%--------------------------------------------------------------------
-spec suites(tls_version()) -> [cipher_suite()].
%%
@@ -191,6 +186,19 @@ suites({3, N}) when N == 1; N == 2 ->
ssl_tls1:suites().
%%--------------------------------------------------------------------
+-spec anonymous_suites() -> [cipher_suite()].
+%%
+%% Description: Returns a list of the anonymous cipher suites, only supported
+%% if explicitly set by user. Intended only for testing.
+%%--------------------------------------------------------------------
+anonymous_suites() ->
+ [?TLS_DH_anon_WITH_RC4_128_MD5,
+ ?TLS_DH_anon_WITH_DES_CBC_SHA,
+ ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
+ ?TLS_DH_anon_WITH_AES_128_CBC_SHA,
+ ?TLS_DH_anon_WITH_AES_256_CBC_SHA].
+
+%%--------------------------------------------------------------------
-spec suite_definition(cipher_suite()) -> erl_cipher_suite().
%%
%% Description: Return erlang cipher suite definition.
@@ -235,7 +243,20 @@ suite_definition(?TLS_RSA_WITH_AES_256_CBC_SHA) ->
suite_definition(?TLS_DHE_DSS_WITH_AES_256_CBC_SHA) ->
{dhe_dss, aes_256_cbc, sha};
suite_definition(?TLS_DHE_RSA_WITH_AES_256_CBC_SHA) ->
- {dhe_rsa, aes_256_cbc, sha}.
+ {dhe_rsa, aes_256_cbc, sha};
+
+%%% DH-ANON deprecated by TLS spec and not available
+%%% by default, but good for testing purposes.
+suite_definition(?TLS_DH_anon_WITH_RC4_128_MD5) ->
+ {dh_anon, rc4_128, md5};
+suite_definition(?TLS_DH_anon_WITH_DES_CBC_SHA) ->
+ {dh_anon, des_cbc, sha};
+suite_definition(?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA) ->
+ {dh_anon, '3des_ede_cbc', sha};
+suite_definition(?TLS_DH_anon_WITH_AES_128_CBC_SHA) ->
+ {dh_anon, aes_128_cbc, sha};
+suite_definition(?TLS_DH_anon_WITH_AES_256_CBC_SHA) ->
+ {dh_anon, aes_256_cbc, sha}.
%%--------------------------------------------------------------------
-spec suite(erl_cipher_suite()) -> cipher_suite().
@@ -266,12 +287,12 @@ suite({dhe_rsa, des_cbc, sha}) ->
?TLS_DHE_RSA_WITH_DES_CBC_SHA;
suite({dhe_rsa, '3des_ede_cbc', sha}) ->
?TLS_DHE_RSA_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;
+suite({dh_anon, rc4_128, md5}) ->
+ ?TLS_DH_anon_WITH_RC4_128_MD5;
+suite({dh_anon, des_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}) ->
@@ -280,16 +301,16 @@ 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}) ->
-%% ?TLS_DH_anon_WITH_AES_128_CBC_SHA;
+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({dhe_dss, aes_256_cbc, sha}) ->
?TLS_DHE_DSS_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.
+ ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
+suite({dh_anon, aes_256_cbc, sha}) ->
+ ?TLS_DH_anon_WITH_AES_256_CBC_SHA.
%%--------------------------------------------------------------------
-spec openssl_suite(openssl_cipher_suite()) -> cipher_suite().
@@ -390,8 +411,6 @@ bulk_cipher_algorithm(null) ->
%% ?IDEA;
bulk_cipher_algorithm(rc4_128) ->
?RC4;
-%% bulk_cipher_algorithm(des40_cbc) ->
-%% ?DES40;
bulk_cipher_algorithm(des_cbc) ->
?DES;
bulk_cipher_algorithm('3des_ede_cbc') ->
@@ -405,7 +424,6 @@ type(Cipher) when Cipher == null;
?STREAM;
type(Cipher) when Cipher == idea_cbc;
- Cipher == des40_cbc;
Cipher == des_cbc;
Cipher == '3des_ede_cbc';
Cipher == aes_128_cbc;
@@ -417,8 +435,6 @@ key_material(null) ->
key_material(Cipher) when Cipher == idea_cbc;
Cipher == rc4_128 ->
16;
-%%key_material(des40_cbc) ->
-%% 5;
key_material(des_cbc) ->
8;
key_material('3des_ede_cbc') ->
@@ -433,8 +449,7 @@ expanded_key_material(null) ->
expanded_key_material(Cipher) when Cipher == idea_cbc;
Cipher == rc4_128 ->
16;
-expanded_key_material(Cipher) when Cipher == des_cbc;
- Cipher == des40_cbc ->
+expanded_key_material(Cipher) when Cipher == des_cbc ->
8;
expanded_key_material('3des_ede_cbc') ->
24;
@@ -445,8 +460,6 @@ expanded_key_material(Cipher) when Cipher == aes_128_cbc;
effective_key_bits(null) ->
0;
-%%effective_key_bits(des40_cbc) ->
-%% 40;
effective_key_bits(des_cbc) ->
56;
effective_key_bits(Cipher) when Cipher == idea_cbc;
@@ -465,7 +478,6 @@ iv_size(Cipher) ->
block_size(Cipher).
block_size(Cipher) when Cipher == idea_cbc;
- Cipher == des40_cbc;
Cipher == des_cbc;
Cipher == '3des_ede_cbc' ->
8;
@@ -580,5 +592,3 @@ filter_rsa_suites(Use, KeyUse, CipherSuits, RsaSuites) ->
false ->
CipherSuits -- RsaSuites
end.
-
-
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index bd1ba6978a..85245f4342 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -29,7 +29,6 @@
-behaviour(gen_fsm).
--include("ssl_debug.hrl").
-include("ssl_handshake.hrl").
-include("ssl_alert.hrl").
-include("ssl_record.hrl").
@@ -71,7 +70,6 @@
%% {{md5_hash, sha_hash}, {prev_md5, prev_sha}} (binary())
tls_handshake_hashes, % see above
tls_cipher_texts, % list() received but not deciphered yet
- own_cert, % binary()
session, % #session{} from ssl_handshake.hrl
session_cache, %
session_cache_cb, %
@@ -91,7 +89,8 @@
log_alert, % boolean()
renegotiation, % {boolean(), From | internal | peer}
recv_during_renegotiation, %boolean()
- send_queue % queue()
+ send_queue, % queue()
+ terminated = false %
}).
-define(DEFAULT_DIFFIE_HELLMAN_PARAMS,
@@ -305,8 +304,9 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options,
try ssl_init(SSLOpts0, Role) of
{ok, Ref, CacheRef, OwnCert, Key, DHParams} ->
+ Session = State0#state.session,
State = State0#state{tls_handshake_hashes = Hashes0,
- own_cert = OwnCert,
+ session = Session#session{own_certificate = OwnCert},
cert_db_ref = Ref,
session_cache = CacheRef,
private_key = Key,
@@ -332,14 +332,13 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options,
%%--------------------------------------------------------------------
hello(start, #state{host = Host, port = Port, role = client,
ssl_options = SslOpts,
+ session = #session{own_certificate = Cert} = Session0,
transport_cb = Transport, socket = Socket,
connection_states = ConnectionStates,
- renegotiation = {Renegotiation, _}}
- = State0) ->
-
+ renegotiation = {Renegotiation, _}} = State0) ->
Hello = ssl_handshake:client_hello(Host, Port,
ConnectionStates,
- SslOpts, Renegotiation),
+ SslOpts, Renegotiation, Cert),
Version = Hello#client_hello.client_version,
Hashes0 = ssl_handshake:init_hashes(),
@@ -348,13 +347,13 @@ hello(start, #state{host = Host, port = Port, role = client,
Transport:send(Socket, BinMsg),
State1 = State0#state{connection_states = CS2,
negotiated_version = Version, %% Requested version
- session =
- #session{session_id = Hello#client_hello.session_id,
- is_resumable = false},
+ session =
+ Session0#session{session_id = Hello#client_hello.session_id,
+ is_resumable = false},
tls_handshake_hashes = Hashes1},
{Record, State} = next_record(State1),
next_state(hello, Record, State);
-
+
hello(start, #state{role = server} = State0) ->
{Record, State} = next_record(State0),
next_state(hello, Record, State);
@@ -371,10 +370,9 @@ hello(#server_hello{cipher_suite = CipherSuite,
negotiated_version = ReqVersion,
renegotiation = {Renegotiation, _},
ssl_options = SslOptions} = State0) ->
-
case ssl_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of
{Version, NewId, ConnectionStates} ->
- {KeyAlgorithm, _, _} =
+ {KeyAlgorithm, _, _} =
ssl_cipher:suite_definition(CipherSuite),
PremasterSecret = make_premaster_secret(ReqVersion, KeyAlgorithm),
@@ -397,13 +395,11 @@ hello(#server_hello{cipher_suite = CipherSuite,
hello(Hello = #client_hello{client_version = ClientVersion},
State = #state{connection_states = ConnectionStates0,
- port = Port, session = Session0,
+ port = Port, session = #session{own_certificate = Cert} = Session0,
renegotiation = {Renegotiation, _},
session_cache = Cache,
session_cache_cb = CacheCb,
- ssl_options = SslOpts,
- own_cert = Cert}) ->
-
+ ssl_options = SslOpts}) ->
case ssl_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb,
ConnectionStates0, Cert}, Renegotiation) of
{Version, {Type, Session}, ConnectionStates} ->
@@ -512,7 +508,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 ->
+ when Alg == dhe_dss; Alg == dhe_rsa; Alg == dh_anon ->
case handle_server_key(KeyExchangeMsg, State0) of
#state{} = State1 ->
{Record, State} = next_record(State1),
@@ -537,7 +533,7 @@ certify(#server_hello_done{},
connection_states = ConnectionStates0,
negotiated_version = Version,
premaster_secret = undefined,
- role = client} = State0) ->
+ role = client} = State0) ->
case ssl_handshake:master_secret(Version, Session,
ConnectionStates0, client) of
{MasterSecret, ConnectionStates1} ->
@@ -613,25 +609,9 @@ certify_client_key_exchange(#client_diffie_hellman_public{dh_public = ClientPubl
#state{negotiated_version = Version,
diffie_hellman_params = #'DHParameter'{prime = P,
base = G},
- diffie_hellman_keys = {_, ServerDhPrivateKey},
- role = Role,
- session = Session,
- connection_states = ConnectionStates0} = State0) ->
-
- PMpint = crypto:mpint(P),
- GMpint = crypto:mpint(G),
- PremasterSecret = crypto:dh_compute_key(mpint_binary(ClientPublicDhKey),
- ServerDhPrivateKey,
- [PMpint, GMpint]),
-
- case ssl_handshake:master_secret(Version, PremasterSecret,
- ConnectionStates0, Role) of
- {MasterSecret, ConnectionStates} ->
- State1 = State0#state{session =
- Session#session{master_secret
- = MasterSecret},
- connection_states = ConnectionStates},
-
+ diffie_hellman_keys = {_, ServerDhPrivateKey}} = State0) ->
+ case dh_master_secret(crypto:mpint(P), crypto:mpint(G), ClientPublicDhKey, ServerDhPrivateKey, State0) of
+ #state{} = State1 ->
{Record, State} = next_record(State1),
next_state(cipher, Record, State);
#alert{} = Alert ->
@@ -653,12 +633,10 @@ cipher(#certificate_verify{signature = Signature},
public_key_info = PublicKeyInfo,
negotiated_version = Version,
session = #session{master_secret = MasterSecret},
- key_algorithm = Algorithm,
tls_handshake_hashes = Hashes
} = State0) ->
case ssl_handshake:certificate_verify(Signature, PublicKeyInfo,
- Version, MasterSecret,
- Algorithm, Hashes) of
+ Version, MasterSecret, Hashes) of
valid ->
{Record, State} = next_record(State0),
next_state(cipher, Record, State);
@@ -674,8 +652,7 @@ cipher(#finished{verify_data = Data} = Finished,
role = Role,
session = #session{master_secret = MasterSecret}
= Session0,
- tls_handshake_hashes = Hashes0} = State) ->
-
+ tls_handshake_hashes = Hashes0} = State) ->
case ssl_handshake:verify_connection(Version, Finished,
opposite_role(Role),
MasterSecret, Hashes0) of
@@ -696,15 +673,15 @@ cipher(Msg, State) ->
%%--------------------------------------------------------------------
connection(#hello_request{}, #state{host = Host, port = Port,
socket = Socket,
+ session = #session{own_certificate = Cert},
ssl_options = SslOpts,
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, Renegotiation),
+ SslOpts, Renegotiation, Cert),
{BinMsg, ConnectionStates1, Hashes1} =
encode_handshake(Hello, Version, ConnectionStates0, Hashes0),
@@ -795,8 +772,12 @@ handle_sync_event(start, _, connection, State) ->
handle_sync_event(start, From, StateName, State) ->
{next_state, StateName, State#state{from = From}};
-handle_sync_event(close, _, _StateName, State) ->
- {stop, normal, ok, State};
+handle_sync_event(close, _, StateName, State) ->
+ %% Run terminate before returning
+ %% so that the reuseaddr inet-option will work
+ %% as intended.
+ (catch terminate(user_close, StateName, State)),
+ {stop, normal, ok, State#state{terminated = true}};
handle_sync_event({shutdown, How0}, _, StateName,
#state{transport_cb = Transport,
@@ -984,24 +965,28 @@ handle_info(Msg, StateName, State) ->
%% necessary cleaning up. When it returns, the gen_fsm terminates with
%% Reason. The return value is ignored.
%%--------------------------------------------------------------------
-terminate(_Reason, connection, #state{negotiated_version = Version,
+terminate(_, _, #state{terminated = true}) ->
+ %% Happens when user closes the connection using ssl:close/1
+ %% we want to guarantee that Transport:close has been called
+ %% when ssl:close/1 returns.
+ ok;
+terminate(Reason, connection, #state{negotiated_version = Version,
connection_states = ConnectionStates,
transport_cb = Transport,
socket = Socket, send_queue = SendQueue,
renegotiation = Renegotiate}) ->
notify_senders(SendQueue),
notify_renegotiater(Renegotiate),
- {BinAlert, _} = encode_alert(?ALERT_REC(?WARNING,?CLOSE_NOTIFY),
- Version, ConnectionStates),
+ BinAlert = terminate_alert(Reason, Version, ConnectionStates),
Transport:send(Socket, BinAlert),
- workaround_transport_delivery_problems(Socket, Transport),
+ workaround_transport_delivery_problems(Socket, Transport, Reason),
Transport:close(Socket);
-terminate(_Reason, _StateName, #state{transport_cb = Transport,
+terminate(Reason, _StateName, #state{transport_cb = Transport,
socket = Socket, send_queue = SendQueue,
renegotiation = Renegotiate}) ->
notify_senders(SendQueue),
notify_renegotiater(Renegotiate),
- workaround_transport_delivery_problems(Socket, Transport),
+ workaround_transport_delivery_problems(Socket, Transport, Reason),
Transport:close(Socket).
%%--------------------------------------------------------------------
@@ -1058,6 +1043,8 @@ init_certificates(#ssl_options{cacerts = CaCerts,
end,
init_certificates(Cert, CertDbRef, CacheRef, CertFile, Role).
+init_certificates(undefined, CertDbRef, CacheRef, "", _) ->
+ {ok, CertDbRef, CacheRef, undefined};
init_certificates(undefined, CertDbRef, CacheRef, CertFile, client) ->
try
@@ -1068,18 +1055,18 @@ init_certificates(undefined, CertDbRef, CacheRef, CertFile, client) ->
end;
init_certificates(undefined, CertDbRef, CacheRef, CertFile, server) ->
- try
+ try
[OwnCert] = ssl_certificate:file_to_certificats(CertFile),
{ok, CertDbRef, CacheRef, OwnCert}
- catch
- Error:Reason ->
- handle_file_error(?LINE, Error, Reason, CertFile, ecertfile,
- erlang:get_stacktrace())
- end;
+ catch
+ Error:Reason ->
+ handle_file_error(?LINE, Error, Reason, CertFile, ecertfile,
+ erlang:get_stacktrace())
+ end;
init_certificates(Cert, CertDbRef, CacheRef, _, _) ->
{ok, CertDbRef, CacheRef, Cert}.
-init_private_key(undefined, "", _Password, client) ->
+init_private_key(undefined, "", _Password, _Client) ->
undefined;
init_private_key(undefined, KeyFile, Password, _) ->
try
@@ -1099,12 +1086,13 @@ init_private_key({rsa, PrivateKey}, _, _,_) ->
init_private_key({dsa, PrivateKey},_,_,_) ->
public_key:der_decode('DSAPrivateKey', PrivateKey).
+-spec(handle_file_error(_,_,_,_,_,_) -> no_return()).
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).
--spec(file_error/6 :: (_,_,_,_,_,_) -> no_return()).
+-spec(file_error(_,_,_,_,_,_) -> no_return()).
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]),
@@ -1164,7 +1152,7 @@ certify_client(#state{client_certificate_requested = true, role = client,
transport_cb = Transport,
negotiated_version = Version,
cert_db_ref = CertDbRef,
- own_cert = OwnCert,
+ session = #session{own_certificate = OwnCert},
socket = Socket,
tls_handshake_hashes = Hashes0} = State) ->
Certificate = ssl_handshake:certificate(OwnCert, CertDbRef, client),
@@ -1180,18 +1168,17 @@ verify_client_cert(#state{client_certificate_requested = true, role = client,
connection_states = ConnectionStates0,
transport_cb = Transport,
negotiated_version = Version,
- own_cert = OwnCert,
socket = Socket,
- key_algorithm = KeyAlg,
private_key = PrivateKey,
- session = #session{master_secret = MasterSecret},
+ session = #session{master_secret = MasterSecret,
+ own_certificate = OwnCert},
tls_handshake_hashes = Hashes0} = State) ->
+
case ssl_handshake:client_certificate_verify(OwnCert, MasterSecret,
- Version, KeyAlg,
- PrivateKey, Hashes0) of
+ Version, PrivateKey, Hashes0) of
#certificate_verify{} = Verified ->
{BinVerified, ConnectionStates1, Hashes1} =
- encode_handshake(Verified, KeyAlg, Version,
+ encode_handshake(Verified, Version,
ConnectionStates0, Hashes0),
Transport:send(Socket, BinVerified),
State#state{connection_states = ConnectionStates1,
@@ -1340,15 +1327,17 @@ server_hello_done(#state{transport_cb = Transport,
Transport:send(Socket, BinHelloDone),
State#state{connection_states = NewConnectionStates,
tls_handshake_hashes = NewHashes}.
-
-certify_server(#state{transport_cb = Transport,
- socket = Socket,
- negotiated_version = Version,
- connection_states = ConnectionStates,
- tls_handshake_hashes = Hashes,
- cert_db_ref = CertDbRef,
- own_cert = OwnCert} = State) ->
+certify_server(#state{key_algorithm = dh_anon} = State) ->
+ State;
+
+certify_server(#state{transport_cb = Transport,
+ socket = Socket,
+ negotiated_version = Version,
+ connection_states = ConnectionStates,
+ tls_handshake_hashes = Hashes,
+ cert_db_ref = CertDbRef,
+ session = #session{own_certificate = OwnCert}} = State) ->
case ssl_handshake:certificate(OwnCert, CertDbRef, server) of
CertMsg = #certificate{} ->
{BinCertMsg, NewConnectionStates, NewHashes} =
@@ -1373,8 +1362,8 @@ key_exchange(#state{role = server, key_algorithm = Algo,
transport_cb = Transport
} = State)
when Algo == dhe_dss;
- Algo == dhe_rsa ->
-
+ Algo == dhe_rsa;
+ Algo == dh_anon ->
Keys = crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]),
ConnectionState =
ssl_record:pending_connection_state(ConnectionStates0, read),
@@ -1392,11 +1381,6 @@ key_exchange(#state{role = server, key_algorithm = Algo,
diffie_hellman_keys = Keys,
tls_handshake_hashes = Hashes1};
-
-%% key_algorithm = dh_anon is not supported. Should be by default disabled
-%% if support is implemented and then we need a key_exchange clause for it
-%% here.
-
key_exchange(#state{role = client,
connection_states = ConnectionStates0,
key_algorithm = rsa,
@@ -1419,7 +1403,8 @@ key_exchange(#state{role = client,
socket = Socket, transport_cb = Transport,
tls_handshake_hashes = Hashes0} = State)
when Algorithm == dhe_dss;
- Algorithm == dhe_rsa ->
+ Algorithm == dhe_rsa;
+ Algorithm == dh_anon ->
Msg = ssl_handshake:key_exchange(client, {dh, DhPubKey}),
{BinMsg, ConnectionStates1, Hashes1} =
encode_handshake(Msg, Version, ConnectionStates0, Hashes0),
@@ -1427,8 +1412,6 @@ key_exchange(#state{role = client,
State#state{connection_states = ConnectionStates1,
tls_handshake_hashes = Hashes1}.
--spec(rsa_key_exchange/2 :: (_,_) -> no_return()).
-
rsa_key_exchange(PremasterSecret, PublicKeyInfo = {Algorithm, _, _})
when Algorithm == ?rsaEncryption;
Algorithm == ?md2WithRSAEncryption;
@@ -1497,23 +1480,30 @@ save_verify_data(client, #finished{verify_data = Data}, ConnectionStates, abbrev
save_verify_data(server, #finished{verify_data = Data}, ConnectionStates, abbreviated) ->
ssl_record:set_server_verify_data(current_write, Data, ConnectionStates).
+handle_server_key(#server_key_exchange{params =
+ #server_dh_params{dh_p = P,
+ dh_g = G,
+ dh_y = ServerPublicDhKey},
+ signed_params = <<>>},
+ #state{key_algorithm = dh_anon} = State) ->
+ dh_master_secret(P, G, ServerPublicDhKey, undefined, State);
+
handle_server_key(
#server_key_exchange{params =
#server_dh_params{dh_p = P,
dh_g = G,
dh_y = ServerPublicDhKey},
signed_params = Signed},
- #state{session = Session, negotiated_version = Version, role = Role,
- public_key_info = PubKeyInfo,
+ #state{public_key_info = PubKeyInfo,
key_algorithm = KeyAlgo,
- connection_states = ConnectionStates0} = State) ->
+ connection_states = ConnectionStates} = State) ->
PLen = size(P),
GLen = size(G),
YLen = size(ServerPublicDhKey),
ConnectionState =
- ssl_record:pending_connection_state(ConnectionStates0, read),
+ ssl_record:pending_connection_state(ConnectionStates, read),
SecParams = ConnectionState#connection_state.security_parameters,
#security_parameters{client_random = ClientRandom,
server_random = ServerRandom} = SecParams,
@@ -1527,29 +1517,11 @@ handle_server_key(
case verify_dh_params(Signed, Hash, PubKeyInfo) of
true ->
- PMpint = mpint_binary(P),
- GMpint = mpint_binary(G),
- Keys = {_, ClientDhPrivateKey} =
- crypto:dh_generate_key([PMpint,GMpint]),
- PremasterSecret =
- crypto:dh_compute_key(mpint_binary(ServerPublicDhKey),
- ClientDhPrivateKey, [PMpint, GMpint]),
- case ssl_handshake:master_secret(Version, PremasterSecret,
- ConnectionStates0, Role) of
- {MasterSecret, ConnectionStates} ->
- State#state{diffie_hellman_keys = Keys,
- session =
- Session#session{master_secret
- = MasterSecret},
- connection_states = ConnectionStates};
- #alert{} = Alert ->
- Alert
- end;
+ dh_master_secret(P, G, ServerPublicDhKey, undefined, State);
false ->
- ?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE)
+ ?ALERT_REC(?FATAL, ?DECRYPT_ERROR)
end.
-
verify_dh_params(Signed, Hashes, {?rsaEncryption, PubKey, _PubKeyParams}) ->
case public_key:decrypt_public(Signed, PubKey,
[{rsa_pad, rsa_pkcs1_padding}]) of
@@ -1561,6 +1533,30 @@ verify_dh_params(Signed, Hashes, {?rsaEncryption, PubKey, _PubKeyParams}) ->
verify_dh_params(Signed, Hash, {?'id-dsa', PublicKey, PublicKeyParams}) ->
public_key:verify(Hash, none, Signed, {PublicKey, PublicKeyParams}).
+dh_master_secret(Prime, Base, PublicDhKey, undefined, State) ->
+ PMpint = mpint_binary(Prime),
+ GMpint = mpint_binary(Base),
+ Keys = {_, PrivateDhKey} =
+ crypto:dh_generate_key([PMpint,GMpint]),
+ dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey, State#state{diffie_hellman_keys = Keys});
+
+dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey,
+ #state{session = Session,
+ negotiated_version = Version, role = Role,
+ connection_states = ConnectionStates0} = State) ->
+ PremasterSecret =
+ crypto:dh_compute_key(mpint_binary(PublicDhKey), PrivateDhKey,
+ [PMpint, GMpint]),
+ case ssl_handshake:master_secret(Version, PremasterSecret,
+ ConnectionStates0, Role) of
+ {MasterSecret, ConnectionStates} ->
+ State#state{
+ session =
+ Session#session{master_secret = MasterSecret},
+ connection_states = ConnectionStates};
+ #alert{} = Alert ->
+ Alert
+ end.
cipher_role(client, Data, Session, #state{connection_states = ConnectionStates0} = State) ->
ConnectionStates = ssl_record:set_server_verify_data(current_both, Data, ConnectionStates0),
@@ -1578,20 +1574,13 @@ cipher_role(server, Data, Session, #state{connection_states = ConnectionStates0
tls_handshake_hashes =
Hashes})).
encode_alert(#alert{} = Alert, Version, ConnectionStates) ->
- ?DBG_TERM(Alert),
ssl_record:encode_alert_record(Alert, Version, ConnectionStates).
encode_change_cipher(#change_cipher_spec{}, Version, ConnectionStates) ->
- ?DBG_TERM(#change_cipher_spec{}),
ssl_record:encode_change_cipher_spec(Version, ConnectionStates).
-encode_handshake(HandshakeRec, Version, ConnectionStates, Hashes) ->
- encode_handshake(HandshakeRec, null, Version,
- ConnectionStates, Hashes).
-
-encode_handshake(HandshakeRec, SigAlg, Version, ConnectionStates0, Hashes0) ->
- ?DBG_TERM(HandshakeRec),
- Frag = ssl_handshake:encode_handshake(HandshakeRec, Version, SigAlg),
+encode_handshake(HandshakeRec, Version, ConnectionStates0, Hashes0) ->
+ Frag = ssl_handshake:encode_handshake(HandshakeRec, Version),
Hashes1 = ssl_handshake:update_hashes(Hashes0, Frag),
{E, ConnectionStates1} =
ssl_record:encode_handshake(Frag, Version, ConnectionStates0),
@@ -1848,7 +1837,6 @@ next_state(StateName, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, State
next_state(StateName, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} =
_ChangeCipher,
#state{connection_states = ConnectionStates0} = State0) ->
- ?DBG_TERM(_ChangeCipher),
ConnectionStates1 =
ssl_record:activate_pending_connection_state(ConnectionStates0, read),
{Record, State} = next_record(State0#state{connection_states = ConnectionStates1}),
@@ -1925,14 +1913,22 @@ next_state_connection(StateName, #state{send_queue = Queue0,
next_state_is_connection(State)
end.
+%% In next_state_is_connection/1: clear tls_handshake_hashes,
+%% premaster_secret and public_key_info (only needed during handshake)
+%% to reduce memory foot print of a connection.
next_state_is_connection(State =
#state{recv_during_renegotiation = true, socket_options =
#socket_options{active = false}}) ->
- passive_receive(State#state{recv_during_renegotiation = false}, connection);
+ passive_receive(State#state{recv_during_renegotiation = false,
+ premaster_secret = undefined,
+ public_key_info = undefined,
+ tls_handshake_hashes = {<<>>, <<>>}}, connection);
next_state_is_connection(State0) ->
{Record, State} = next_record_if_active(State0),
- next_state(connection, Record, State).
+ next_state(connection, Record, State#state{premaster_secret = undefined,
+ public_key_info = undefined,
+ tls_handshake_hashes = {<<>>, <<>>}}).
register_session(_, _, _, #session{is_resumable = true} = Session) ->
Session; %% Already registered
@@ -2179,7 +2175,7 @@ renegotiate(#state{role = server,
negotiated_version = Version,
connection_states = ConnectionStates0} = State0) ->
HelloRequest = ssl_handshake:hello_request(),
- Frag = ssl_handshake:encode_handshake(HelloRequest, Version, null),
+ Frag = ssl_handshake:encode_handshake(HelloRequest, Version),
Hs0 = ssl_handshake:init_hashes(),
{BinMsg, ConnectionStates} =
ssl_record:encode_handshake(Frag, Version, ConnectionStates0),
@@ -2199,10 +2195,23 @@ notify_renegotiater({true, From}) when not is_atom(From) ->
notify_renegotiater(_) ->
ok.
-workaround_transport_delivery_problems(Socket, Transport) ->
+terminate_alert(Reason, Version, ConnectionStates) when Reason == normal; Reason == shutdown;
+ Reason == user_close ->
+ {BinAlert, _} = encode_alert(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
+ Version, ConnectionStates),
+ BinAlert;
+terminate_alert(_, Version, ConnectionStates) ->
+ {BinAlert, _} = encode_alert(?ALERT_REC(?FATAL, ?INTERNAL_ERROR),
+ Version, ConnectionStates),
+ BinAlert.
+
+workaround_transport_delivery_problems(_,_, user_close) ->
+ 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.
+ %% before tcp port is closed so that the peer will
+ %% get a correct error message.
inet:setopts(Socket, [{active, false}]),
Transport:shutdown(Socket, write),
Transport:recv(Socket, 0).
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 3f01be101c..1f4c44d115 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,16 +28,15 @@
-include("ssl_cipher.hrl").
-include("ssl_alert.hrl").
-include("ssl_internal.hrl").
--include("ssl_debug.hrl").
-include_lib("public_key/include/public_key.hrl").
--export([master_secret/4, client_hello/5, server_hello/4, hello/4,
+-export([master_secret/4, client_hello/6, server_hello/4, hello/4,
hello_request/0, certify/6, certificate/3,
- client_certificate_verify/6, certificate_verify/6,
+ client_certificate_verify/5, certificate_verify/5,
certificate_request/2, key_exchange/2, server_key_exchange_hash/2,
finished/4, verify_connection/5, get_tls_handshake/2,
- decode_client_key/3, server_hello_done/0, sig_alg/1,
- encode_handshake/3, init_hashes/0, update_hashes/2,
+ decode_client_key/3, server_hello_done/0,
+ encode_handshake/2, init_hashes/0, update_hashes/2,
decrypt_premaster_secret/2]).
-type tls_handshake() :: #client_hello{} | #server_hello{} |
@@ -50,13 +49,13 @@
%%====================================================================
%%--------------------------------------------------------------------
-spec client_hello(host(), port_num(), #connection_states{},
- #ssl_options{}, boolean()) -> #client_hello{}.
+ #ssl_options{}, boolean(), der_cert()) -> #client_hello{}.
%%
%% Description: Creates a client hello message.
%%--------------------------------------------------------------------
client_hello(Host, Port, ConnectionStates, #ssl_options{versions = Versions,
ciphers = UserSuites}
- = SslOpts, Renegotiation) ->
+ = SslOpts, Renegotiation, OwnCert) ->
Fun = fun(Version) ->
ssl_record:protocol_version(Version)
@@ -66,7 +65,7 @@ client_hello(Host, Port, ConnectionStates, #ssl_options{versions = Versions,
SecParams = Pending#connection_state.security_parameters,
Ciphers = available_suites(UserSuites, Version),
- Id = ssl_manager:client_session_id(Host, Port, SslOpts),
+ Id = ssl_manager:client_session_id(Host, Port, SslOpts, OwnCert),
#client_hello{session_id = Id,
client_version = Version,
@@ -195,14 +194,12 @@ certify(#certificate{asn1_certificates = ASN1Certs}, CertDbRef,
{fun(OtpCert, ExtensionOrError, {SslState, UserState}) ->
case ssl_certificate:validate_extension(OtpCert,
ExtensionOrError,
- SslState) of
- {valid, _} ->
- apply_user_fun(Fun, OtpCert,
- ExtensionOrError, UserState,
- SslState);
- {fail, Reason} ->
- apply_user_fun(Fun, OtpCert, Reason, UserState,
- SslState);
+ SslState) of
+ {valid, NewSslState} ->
+ {valid, {NewSslState, UserState}};
+ {fail, Reason} ->
+ apply_user_fun(Fun, OtpCert, Reason, UserState,
+ SslState);
{unknown, _} ->
apply_user_fun(Fun, OtpCert,
ExtensionOrError, UserState, SslState)
@@ -237,7 +234,7 @@ certificate(OwnCert, CertDbRef, client) ->
{error, _} ->
%% If no suitable certificate is available, the client
%% SHOULD send a certificate message containing no
- %% certificates. (chapter 7.4.6. rfc 4346)
+ %% certificates. (chapter 7.4.6. RFC 4346)
[]
end,
#certificate{asn1_certificates = Chain};
@@ -252,17 +249,17 @@ certificate(OwnCert, CertDbRef, server) ->
%%--------------------------------------------------------------------
-spec client_certificate_verify(undefined | der_cert(), binary(),
- tls_version(), key_algo(), private_key(),
+ tls_version(), private_key(),
{{binary(), binary()},{binary(), binary()}}) ->
#certificate_verify{} | ignore | #alert{}.
%%
%% Description: Creates a certificate_verify message, called by the client.
%%--------------------------------------------------------------------
-client_certificate_verify(undefined, _, _, _, _, _) ->
+client_certificate_verify(undefined, _, _, _, _) ->
ignore;
-client_certificate_verify(_, _, _, _, undefined, _) ->
+client_certificate_verify(_, _, _, undefined, _) ->
ignore;
-client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm,
+client_certificate_verify(OwnCert, MasterSecret, Version,
PrivateKey, {Hashes0, _}) ->
case public_key:pkix_is_fixed_dh_cert(OwnCert) of
true ->
@@ -270,33 +267,30 @@ client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm,
false ->
Hashes =
calc_certificate_verify(Version, MasterSecret,
- Algorithm, Hashes0),
+ alg_oid(PrivateKey), Hashes0),
Signed = digitally_signed(Hashes, PrivateKey),
#certificate_verify{signature = Signed}
end.
%%--------------------------------------------------------------------
-spec certificate_verify(binary(), public_key_info(), tls_version(),
- binary(), key_algo(),
- {_, {binary(), binary()}}) -> valid | #alert{}.
+ binary(), {_, {binary(), binary()}}) -> valid | #alert{}.
%%
%% Description: Checks that the certificate_verify message is valid.
%%--------------------------------------------------------------------
-certificate_verify(Signature, {_, PublicKey, _}, Version,
- MasterSecret, Algorithm, {_, Hashes0})
- when Algorithm == rsa;
- Algorithm == dhe_rsa ->
+certificate_verify(Signature, {?'rsaEncryption'= Algorithm, PublicKey, _}, Version,
+ MasterSecret, {_, Hashes0}) ->
Hashes = calc_certificate_verify(Version, MasterSecret,
Algorithm, Hashes0),
- case public_key:decrypt_public(Signature, PublicKey,
+ case public_key:decrypt_public(Signature, PublicKey,
[{rsa_pad, rsa_pkcs1_padding}]) of
Hashes ->
valid;
_ ->
?ALERT_REC(?FATAL, ?BAD_CERTIFICATE)
end;
-certificate_verify(Signature, {_, PublicKey, PublicKeyParams}, Version,
- MasterSecret, dhe_dss = Algorithm, {_, Hashes0}) ->
+certificate_verify(Signature, {?'id-dsa' = Algorithm, PublicKey, PublicKeyParams}, Version,
+ MasterSecret, {_, Hashes0}) ->
Hashes = calc_certificate_verify(Version, MasterSecret,
Algorithm, Hashes0),
case public_key:verify(Hashes, none, Signature, {PublicKey, PublicKeyParams}) of
@@ -355,15 +349,22 @@ key_exchange(server, {dh, {<<?UINT32(Len), PublicKey:Len/binary>>, _},
YLen = byte_size(PublicKey),
ServerDHParams = #server_dh_params{dh_p = PBin,
dh_g = GBin, dh_y = PublicKey},
- Hash =
- server_key_exchange_hash(KeyAlgo, <<ClientRandom/binary,
- ServerRandom/binary,
- ?UINT16(PLen), PBin/binary,
- ?UINT16(GLen), GBin/binary,
- ?UINT16(YLen), PublicKey/binary>>),
- Signed = digitally_signed(Hash, PrivateKey),
- #server_key_exchange{params = ServerDHParams,
- signed_params = Signed}.
+
+ case KeyAlgo of
+ dh_anon ->
+ #server_key_exchange{params = ServerDHParams,
+ signed_params = <<>>};
+ _ ->
+ Hash =
+ server_key_exchange_hash(KeyAlgo, <<ClientRandom/binary,
+ ServerRandom/binary,
+ ?UINT16(PLen), PBin/binary,
+ ?UINT16(GLen), GBin/binary,
+ ?UINT16(YLen), PublicKey/binary>>),
+ Signed = digitally_signed(Hash, PrivateKey),
+ #server_key_exchange{params = ServerDHParams,
+ signed_params = Signed}
+ end.
%%--------------------------------------------------------------------
-spec master_secret(tls_version(), #session{} | binary(), #connection_states{},
@@ -424,13 +425,11 @@ finished(Version, Role, MasterSecret, {Hashes, _}) -> % use the current hashes
verify_connection(Version, #finished{verify_data = Data},
Role, MasterSecret, {_, {MD5, SHA}}) ->
%% use the previous hashes
- ?DBG_HEX(crypto:md5_final(MD5)),
- ?DBG_HEX(crypto:sha_final(SHA)),
case calc_finished(Version, Role, MasterSecret, {MD5, SHA}) of
Data ->
verified;
- _E ->
- ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)
+ _ ->
+ ?ALERT_REC(?FATAL, ?DECRYPT_ERROR)
end.
%%--------------------------------------------------------------------
-spec server_hello_done() -> #server_hello_done{}.
@@ -441,13 +440,12 @@ server_hello_done() ->
#server_hello_done{}.
%%--------------------------------------------------------------------
--spec encode_handshake(tls_handshake(), tls_version(), key_algo()) -> iolist().
+-spec encode_handshake(tls_handshake(), tls_version()) -> iolist().
%%
%% Description: Encode a handshake packet to binary
%%--------------------------------------------------------------------
-encode_handshake(Package, Version, KeyAlg) ->
- SigAlg = sig_alg(KeyAlg),
- {MsgType, Bin} = enc_hs(Package, Version, SigAlg),
+encode_handshake(Package, Version) ->
+ {MsgType, Bin} = enc_hs(Package, Version),
Len = byte_size(Bin),
[MsgType, ?uint24(Len), Bin].
@@ -504,11 +502,8 @@ update_hashes(Hashes, % special-case SSL2 client hello
CipherSuites:CSLength/binary,
ChallengeData:CDLength/binary>>);
update_hashes({{MD50, SHA0}, _Prev}, Data) ->
- ?DBG_HEX(Data),
{MD51, SHA1} = {crypto:md5_update(MD50, Data),
crypto:sha_update(SHA0, Data)},
- ?DBG_HEX(crypto:md5_final(MD51)),
- ?DBG_HEX(crypto:sha_final(SHA1)),
{{MD51, SHA1}, {MD50, SHA0}}.
%%--------------------------------------------------------------------
@@ -522,11 +517,11 @@ decrypt_premaster_secret(Secret, RSAPrivateKey) ->
[{rsa_pad, rsa_pkcs1_padding}])
catch
_:_ ->
- throw(?ALERT_REC(?FATAL, ?DECRYPTION_FAILED))
+ throw(?ALERT_REC(?FATAL, ?DECRYPT_ERROR))
end.
%%--------------------------------------------------------------------
--spec server_key_exchange_hash(rsa | dhe_rsa| dhe_dss, binary()) -> binary().
+-spec server_key_exchange_hash(rsa | dhe_rsa| dhe_dss | dh_anon, binary()) -> binary().
%%
%% Description: Calculate server key exchange hash
@@ -541,21 +536,6 @@ server_key_exchange_hash(dhe_dss, Value) ->
crypto:sha(Value).
%%--------------------------------------------------------------------
--spec sig_alg(atom()) -> integer().
-
-%%
-%% Description: Translate atom representation to enum representation.
-%%--------------------------------------------------------------------
-sig_alg(dh_anon) ->
- ?SIGNATURE_ANONYMOUS;
-sig_alg(Alg) when Alg == dhe_rsa; Alg == rsa ->
- ?SIGNATURE_RSA;
-sig_alg(dhe_dss) ->
- ?SIGNATURE_DSA;
-sig_alg(_) ->
- ?NULL.
-
-%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
get_tls_handshake_aux(<<?BYTE(Type), ?UINT24(Length),
@@ -578,6 +558,8 @@ path_validation_alert({bad_cert, unknown_critical_extension}) ->
?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE);
path_validation_alert({bad_cert, cert_revoked}) ->
?ALERT_REC(?FATAL, ?CERTIFICATE_REVOKED);
+path_validation_alert({bad_cert, selfsigned_peer}) ->
+ ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE);
path_validation_alert({bad_cert, unknown_ca}) ->
?ALERT_REC(?FATAL, ?UNKNOWN_CA);
path_validation_alert(_) ->
@@ -587,7 +569,7 @@ select_session(Hello, Port, Session, Version,
#ssl_options{ciphers = UserSuites} = SslOpts, Cache, CacheCb, Cert) ->
SuggestedSessionId = Hello#client_hello.session_id,
SessionId = ssl_manager:server_session_id(Port, SuggestedSessionId,
- SslOpts),
+ SslOpts, Cert),
Suites = available_suites(Cert, UserSuites, Version),
case ssl_session:is_new(SuggestedSessionId, SessionId) of
@@ -792,8 +774,7 @@ master_secret(Version, MasterSecret, #security_parameters{
ServerWriteKey, ClientIV, ServerIV} =
setup_keys(Version, MasterSecret, ServerRandom,
ClientRandom, HashSize, KML, EKML, IVS),
- ?DBG_HEX(ClientWriteKey),
- ?DBG_HEX(ClientIV),
+
ConnStates1 = ssl_record:set_master_secret(MasterSecret, ConnectionStates),
ConnStates2 =
ssl_record:set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret,
@@ -817,8 +798,6 @@ dec_hs(?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor),
?UINT16(CDLength),
CipherSuites:CSLength/binary,
ChallengeData:CDLength/binary>>) ->
- ?DBG_HEX(CipherSuites),
- ?DBG_HEX(CipherSuites),
#client_hello{client_version = {Major, Minor},
random = ssl_ssl2:client_random(ChallengeData, CDLength),
session_id = 0,
@@ -874,6 +853,13 @@ dec_hs(?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>) ->
dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
?UINT16(GLen), G:GLen/binary,
?UINT16(YLen), Y:YLen/binary,
+ ?UINT16(0)>>) -> %% May happen if key_algorithm is dh_anon
+ #server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G,
+ dh_y = Y},
+ signed_params = <<>>};
+dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
+ ?UINT16(GLen), G:GLen/binary,
+ ?UINT16(YLen), Y:YLen/binary,
?UINT16(Len), Sig:Len/binary>>) ->
#server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G,
dh_y = Y},
@@ -956,14 +942,14 @@ certs_from_list(ACList) ->
<<?UINT24(CertLen), Cert/binary>>
end || Cert <- ACList]).
-enc_hs(#hello_request{}, _Version, _) ->
+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,
- renegotiation_info = RenegotiationInfo}, _Version, _) ->
+ renegotiation_info = RenegotiationInfo}, _Version) ->
SIDLength = byte_size(SessionID),
BinCompMethods = list_to_binary(CompMethods),
CmLength = byte_size(BinCompMethods),
@@ -981,20 +967,20 @@ enc_hs(#server_hello{server_version = {Major, Minor},
session_id = Session_ID,
cipher_suite = Cipher_suite,
compression_method = Comp_method,
- renegotiation_info = RenegotiationInfo}, _Version, _) ->
+ 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), ExtensionsBin/binary>>};
-enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version, _) ->
+enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version) ->
ASN1Certs = certs_from_list(ASN1CertList),
ACLen = erlang:iolist_size(ASN1Certs),
{?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>};
enc_hs(#server_key_exchange{params = #server_dh_params{
dh_p = P, dh_g = G, dh_y = Y},
- signed_params = SignedParams}, _Version, _) ->
+ signed_params = SignedParams}, _Version) ->
PLen = byte_size(P),
GLen = byte_size(G),
YLen = byte_size(Y),
@@ -1006,21 +992,21 @@ enc_hs(#server_key_exchange{params = #server_dh_params{
};
enc_hs(#certificate_request{certificate_types = CertTypes,
certificate_authorities = CertAuths},
- _Version, _) ->
+ _Version) ->
CertTypesLen = byte_size(CertTypes),
CertAuthsLen = byte_size(CertAuths),
{?CERTIFICATE_REQUEST,
<<?BYTE(CertTypesLen), CertTypes/binary,
?UINT16(CertAuthsLen), CertAuths/binary>>
};
-enc_hs(#server_hello_done{}, _Version, _) ->
+enc_hs(#server_hello_done{}, _Version) ->
{?SERVER_HELLO_DONE, <<>>};
-enc_hs(#client_key_exchange{exchange_keys = ExchangeKeys}, Version, _) ->
+enc_hs(#client_key_exchange{exchange_keys = ExchangeKeys}, Version) ->
{?CLIENT_KEY_EXCHANGE, enc_cke(ExchangeKeys, Version)};
-enc_hs(#certificate_verify{signature = BinSig}, _, _) ->
+enc_hs(#certificate_verify{signature = BinSig}, _) ->
EncSig = enc_bin_sig(BinSig),
{?CERTIFICATE_VERIFY, EncSig};
-enc_hs(#finished{verify_data = VerifyData}, _Version, _) ->
+enc_hs(#finished{verify_data = VerifyData}, _Version) ->
{?FINISHED, VerifyData}.
enc_cke(#encrypted_premaster_secret{premaster_secret = PKEPMS},{3, 0}) ->
@@ -1150,7 +1136,7 @@ calc_certificate_verify({3, N}, _, Algorithm, Hashes)
key_exchange_alg(rsa) ->
?KEY_EXCHANGE_RSA;
key_exchange_alg(Alg) when Alg == dhe_rsa; Alg == dhe_dss;
- Alg == dh_dss; Alg == dh_rsa ->
+ Alg == dh_dss; Alg == dh_rsa; Alg == dh_anon ->
?KEY_EXCHANGE_DIFFIE_HELLMAN;
key_exchange_alg(_) ->
?NULL.
@@ -1164,3 +1150,8 @@ apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState) ->
{unknown, UserState} ->
{unknown, {SslState, UserState}}
end.
+
+alg_oid(#'RSAPrivateKey'{}) ->
+ ?'rsaEncryption';
+alg_oid(#'DSAPrivateKey'{}) ->
+ ?'id-dsa'.
diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl
index 74fba3786c..8ae4d2332e 100644
--- a/lib/ssl/src/ssl_handshake.hrl
+++ b/lib/ssl/src/ssl_handshake.hrl
@@ -26,9 +26,17 @@
-ifndef(ssl_handshake).
-define(ssl_handshake, true).
+-include_lib("public_key/include/public_key.hrl").
+
+-type algo_oid() :: ?'rsaEncryption' | ?'id-dsa'.
+-type public_key() :: #'RSAPublicKey'{} | integer().
+-type public_key_params() :: #'Dss-Parms'{} | term().
+-type public_key_info() :: {algo_oid(), public_key(), public_key_params()}.
+
-record(session, {
session_id,
peer_certificate,
+ own_certificate,
compression_method,
cipher_suite,
master_secret,
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index ddb05e70f6..715941e3ad 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,12 +19,29 @@
%%
-
-ifndef(ssl_internal).
-define(ssl_internal, true).
-include_lib("public_key/include/public_key.hrl").
+-type reason() :: term().
+-type reply() :: term().
+-type msg() :: term().
+-type from() :: term().
+-type host() :: string() | tuple().
+-type port_num() :: integer().
+-type session_id() :: 0 | binary().
+-type tls_version() :: {integer(), integer()}.
+-type tls_atom_version() :: sslv3 | tlsv1.
+-type cache_ref() :: term().
+-type certdb_ref() :: term().
+-type key_algo() :: null | rsa | dhe_rsa | dhe_dss | dh_anon.
+-type der_cert() :: binary().
+-type private_key() :: #'RSAPrivateKey'{} | #'DSAPrivateKey'{}.
+-type issuer() :: tuple().
+-type serialnumber() :: integer().
+-type cert_key() :: {reference(), integer(), issuer()}.
+
%% basic binary constructors
-define(BOOLEAN(X), X:8/unsigned-big-integer).
-define(BYTE(X), X:8/unsigned-big-integer).
@@ -93,28 +110,6 @@
active = true
}).
--type reason() :: term().
--type reply() :: term().
--type msg() :: term().
--type from() :: term().
--type host() :: string() | tuple().
--type port_num() :: integer().
--type session_id() :: 0 | binary().
--type tls_version() :: {integer(), integer()}.
--type tls_atom_version() :: sslv3 | tlsv1.
--type cache_ref() :: term().
--type certdb_ref() :: term().
--type key_algo() :: null | rsa | dhe_rsa | dhe_dss.
--type enum_algo() :: integer().
--type public_key() :: #'RSAPublicKey'{} | integer().
--type public_key_params() :: #'Dss-Parms'{} | term().
--type public_key_info() :: {enum_algo(), public_key(), public_key_params()}.
--type der_cert() :: binary().
--type private_key() :: #'RSAPrivateKey'{} | #'DSAPrivateKey'{}.
--type issuer() :: tuple().
--type serialnumber() :: integer().
--type cert_key() :: {reference(), integer(), issuer()}.
-
-endif. % -ifdef(ssl_internal).
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index 3b02d96562..f845b1ecc0 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -29,8 +29,8 @@
%% Internal application API
-export([start_link/1,
connection_init/2, cache_pem_file/1,
- lookup_trusted_cert/3, issuer_candidate/1, client_session_id/3,
- server_session_id/3,
+ lookup_trusted_cert/3, issuer_candidate/1, client_session_id/4,
+ server_session_id/4,
register_session/2, register_session/3, invalidate_session/2,
invalidate_session/3]).
@@ -43,6 +43,7 @@
-include("ssl_handshake.hrl").
-include("ssl_internal.hrl").
+-include_lib("kernel/include/file.hrl").
-record(state, {
session_cache,
@@ -76,16 +77,17 @@ start_link(Opts) ->
connection_init(Trustedcerts, Role) ->
call({connection_init, Trustedcerts, Role}).
%%--------------------------------------------------------------------
--spec cache_pem_file(string()) -> {ok, term()}.
+-spec cache_pem_file(string()) -> {ok, term()} | {error, reason()}.
%%
-%% Description: Cach a pem file and
+%% Description: Cach a pem file and return its content.
%%--------------------------------------------------------------------
-cache_pem_file(File) ->
- case ssl_certificate_db:lookup_cached_certs(File) of
- [{_,Content}] ->
- {ok, Content};
- [] ->
- call({cache_pem, File})
+cache_pem_file(File) ->
+ try file:read_file_info(File) of
+ {ok, #file_info{mtime = LastWrite}} ->
+ cache_pem_file(File, LastWrite)
+ catch
+ _:Reason ->
+ {error, Reason}
end.
%%--------------------------------------------------------------------
-spec lookup_trusted_cert(reference(), serialnumber(), issuer()) ->
@@ -106,20 +108,21 @@ lookup_trusted_cert(Ref, SerialNumber, Issuer) ->
issuer_candidate(PrevCandidateKey) ->
ssl_certificate_db:issuer_candidate(PrevCandidateKey).
%%--------------------------------------------------------------------
--spec client_session_id(host(), port_num(), #ssl_options{}) -> session_id().
+-spec client_session_id(host(), port_num(), #ssl_options{},
+ der_cert() | undefined) -> session_id().
%%
%% Description: Select a session id for the client.
%%--------------------------------------------------------------------
-client_session_id(Host, Port, SslOpts) ->
- call({client_session_id, Host, Port, SslOpts}).
+client_session_id(Host, Port, SslOpts, OwnCert) ->
+ call({client_session_id, Host, Port, SslOpts, OwnCert}).
%%--------------------------------------------------------------------
--spec server_session_id(host(), port_num(), #ssl_options{}) -> session_id().
+-spec server_session_id(host(), port_num(), #ssl_options{}, der_cert()) -> session_id().
%%
%% Description: Select a session id for the server.
%%--------------------------------------------------------------------
-server_session_id(Port, SuggestedSessionId, SslOpts) ->
- call({server_session_id, Port, SuggestedSessionId, SslOpts}).
+server_session_id(Port, SuggestedSessionId, SslOpts, OwnCert) ->
+ call({server_session_id, Port, SuggestedSessionId, SslOpts, OwnCert}).
%%--------------------------------------------------------------------
-spec register_session(port_num(), #session{}) -> ok.
@@ -201,28 +204,35 @@ handle_call({{connection_init, Trustedcerts, _Role}, Pid}, _From,
end,
{reply, Result, State};
-handle_call({{client_session_id, Host, Port, SslOpts}, _}, _,
+handle_call({{client_session_id, Host, Port, SslOpts, OwnCert}, _}, _,
#state{session_cache = Cache,
session_cache_cb = CacheCb} = State) ->
- Id = ssl_session:id({Host, Port, SslOpts}, Cache, CacheCb),
+ Id = ssl_session:id({Host, Port, SslOpts}, Cache, CacheCb, OwnCert),
{reply, Id, State};
-handle_call({{server_session_id, Port, SuggestedSessionId, SslOpts}, _},
+handle_call({{server_session_id, Port, SuggestedSessionId, SslOpts, OwnCert}, _},
_, #state{session_cache_cb = CacheCb,
session_cache = Cache,
session_lifetime = LifeTime} = State) ->
Id = ssl_session:id(Port, SuggestedSessionId, SslOpts,
- Cache, CacheCb, LifeTime),
+ Cache, CacheCb, LifeTime, OwnCert),
{reply, Id, State};
-handle_call({{cache_pem, File},Pid}, _, State = #state{certificate_db = Db}) ->
- try ssl_certificate_db:cache_pem_file(Pid,File,Db) of
+handle_call({{cache_pem, File, LastWrite}, Pid}, _,
+ #state{certificate_db = Db} = State) ->
+ try ssl_certificate_db:cache_pem_file(Pid, File, LastWrite, Db) of
Result ->
{reply, Result, State}
catch
_:Reason ->
{reply, {error, Reason}, State}
- end.
+ end;
+handle_call({{recache_pem, File, LastWrite}, Pid}, From,
+ #state{certificate_db = Db} = State) ->
+ ssl_certificate_db:uncache_pem_file(File, Db),
+ cast({recache_pem, File, LastWrite, Pid, From}),
+ {noreply, State}.
+
%%--------------------------------------------------------------------
-spec handle_cast(msg(), #state{}) -> {noreply, #state{}}.
%% Possible return values not used now.
@@ -259,7 +269,21 @@ handle_cast({invalidate_session, Port, #session{session_id = ID}},
#state{session_cache = Cache,
session_cache_cb = CacheCb} = State) ->
CacheCb:delete(Cache, {Port, ID}),
- {noreply, State}.
+ {noreply, State};
+
+handle_cast({recache_pem, File, LastWrite, Pid, From},
+ #state{certificate_db = [_, FileToRefDb, _]} = State0) ->
+ case ssl_certificate_db:lookup(File, FileToRefDb) of
+ undefined ->
+ {reply, Msg, State} = handle_call({{cache_pem, File, LastWrite}, Pid}, From, State0),
+ gen_server:reply(From, Msg),
+ {noreply, State};
+ _ -> %% Send message to self letting cleanup messages be handled
+ %% first so that no reference to the old version of file
+ %% exists when we cache the new one.
+ cast({recache_pem, File, LastWrite, Pid, From}),
+ {noreply, State0}
+ end.
%%--------------------------------------------------------------------
-spec handle_info(msg(), #state{}) -> {noreply, #state{}}.
@@ -286,12 +310,14 @@ handle_info({'EXIT', _, _}, State) ->
handle_info({'DOWN', _Ref, _Type, _Pid, ecacertfile}, State) ->
{noreply, State};
+handle_info({'DOWN', _Ref, _Type, Pid, shutdown}, State) ->
+ handle_info({remove_trusted_certs, Pid}, State);
handle_info({'DOWN', _Ref, _Type, Pid, _Reason}, State) ->
erlang:send_after(?CERTIFICATE_CACHE_CLEANUP, self(),
{remove_trusted_certs, Pid}),
{noreply, State};
handle_info({remove_trusted_certs, Pid},
- State = #state{certificate_db = Db}) ->
+ #state{certificate_db = Db} = State) ->
ssl_certificate_db:remove_trusted_certs(Pid, Db),
{noreply, State};
@@ -362,3 +388,16 @@ session_validation({{{Host, Port}, _}, Session}, LifeTime) ->
session_validation({{Port, _}, Session}, LifeTime) ->
validate_session(Port, Session, LifeTime),
LifeTime.
+
+cache_pem_file(File, LastWrite) ->
+ case ssl_certificate_db:lookup_cached_certs(File) of
+ [{_, {Mtime, Content}}] ->
+ case LastWrite of
+ Mtime ->
+ {ok, Content};
+ _ ->
+ call({recache_pem, File, LastWrite})
+ end;
+ [] ->
+ call({cache_pem, File, LastWrite})
+ end.
diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl
index 803baeb09c..f1c0073965 100644
--- a/lib/ssl/src/ssl_record.erl
+++ b/lib/ssl/src/ssl_record.erl
@@ -30,7 +30,6 @@
-include("ssl_alert.hrl").
-include("ssl_handshake.hrl").
-include("ssl_cipher.hrl").
--include("ssl_debug.hrl").
%% Connection state handling
-export([init_connection_states/1,
@@ -649,9 +648,7 @@ cipher(Type, Version, Fragment, CS0) ->
BCA}
}} =
hash_and_bump_seqno(CS0, Type, Version, Length, Fragment),
- ?DBG_HEX(Fragment),
{Ciphered, CipherS1} = ssl_cipher:cipher(BCA, CipherS0, MacHash, Fragment),
- ?DBG_HEX(Ciphered),
CS2 = CS1#connection_state{cipher_state=CipherS1},
{Ciphered, CS2}.
diff --git a/lib/ssl/src/ssl_session.erl b/lib/ssl/src/ssl_session.erl
index 25e7445180..dc4b7a711c 100644
--- a/lib/ssl/src/ssl_session.erl
+++ b/lib/ssl/src/ssl_session.erl
@@ -28,7 +28,7 @@
-include("ssl_internal.hrl").
%% Internal application API
--export([is_new/2, id/3, id/6, valid_session/2]).
+-export([is_new/2, id/4, id/7, valid_session/2]).
-define(GEN_UNIQUE_ID_MAX_TRIES, 10).
@@ -48,13 +48,14 @@ is_new(_ClientSuggestion, _ServerDecision) ->
true.
%%--------------------------------------------------------------------
--spec id({host(), port_num(), #ssl_options{}}, cache_ref(), atom()) -> binary().
+-spec id({host(), port_num(), #ssl_options{}}, cache_ref(), atom(),
+ undefined | binary()) -> binary().
%%
%% Description: Should be called by the client side to get an id
%% for the client hello message.
%%--------------------------------------------------------------------
-id(ClientInfo, Cache, CacheCb) ->
- case select_session(ClientInfo, Cache, CacheCb) of
+id(ClientInfo, Cache, CacheCb, OwnCert) ->
+ case select_session(ClientInfo, Cache, CacheCb, OwnCert) of
no_session ->
<<>>;
SessionId ->
@@ -63,19 +64,19 @@ id(ClientInfo, Cache, CacheCb) ->
%%--------------------------------------------------------------------
-spec id(port_num(), binary(), #ssl_options{}, cache_ref(),
- atom(), seconds()) -> binary().
+ atom(), seconds(), binary()) -> binary().
%%
%% Description: Should be called by the server side to get an id
%% for the server hello message.
%%--------------------------------------------------------------------
-id(Port, <<>>, _, Cache, CacheCb, _) ->
+id(Port, <<>>, _, Cache, CacheCb, _, _) ->
new_id(Port, ?GEN_UNIQUE_ID_MAX_TRIES, Cache, CacheCb);
id(Port, SuggestedSessionId, #ssl_options{reuse_sessions = ReuseEnabled,
reuse_session = ReuseFun},
- Cache, CacheCb, SecondLifeTime) ->
+ Cache, CacheCb, SecondLifeTime, OwnCert) ->
case is_resumable(SuggestedSessionId, Port, ReuseEnabled,
- ReuseFun, Cache, CacheCb, SecondLifeTime) of
+ ReuseFun, Cache, CacheCb, SecondLifeTime, OwnCert) of
true ->
SuggestedSessionId;
false ->
@@ -93,19 +94,20 @@ valid_session(#session{time_stamp = TimeStamp}, LifeTime) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-select_session({HostIP, Port, SslOpts}, Cache, CacheCb) ->
+select_session({HostIP, Port, SslOpts}, Cache, CacheCb, OwnCert) ->
Sessions = CacheCb:select_session(Cache, {HostIP, Port}),
- select_session(Sessions, SslOpts).
+ select_session(Sessions, SslOpts, OwnCert).
-select_session([], _) ->
+select_session([], _, _) ->
no_session;
select_session(Sessions, #ssl_options{ciphers = Ciphers,
- reuse_sessions = ReuseSession}) ->
+ reuse_sessions = ReuseSession}, OwnCert) ->
IsResumable =
fun(Session) ->
ReuseSession andalso (Session#session.is_resumable) andalso
lists:member(Session#session.cipher_suite, Ciphers)
+ andalso (OwnCert == Session#session.own_certificate)
end,
case [Id || [Id, Session] <- Sessions, IsResumable(Session)] of
[] ->
@@ -140,14 +142,16 @@ new_id(Port, Tries, Cache, CacheCb) ->
end.
is_resumable(SuggestedSessionId, Port, ReuseEnabled, ReuseFun, Cache,
- CacheCb, SecondLifeTime) ->
+ CacheCb, SecondLifeTime, OwnCert) ->
case CacheCb:lookup(Cache, {Port, SuggestedSessionId}) of
#session{cipher_suite = CipherSuite,
+ own_certificate = SessionOwnCert,
compression_method = Compression,
is_resumable = Is_resumable,
peer_certificate = PeerCert} = Session ->
ReuseEnabled
andalso Is_resumable
+ andalso (OwnCert == SessionOwnCert)
andalso valid_session(Session, SecondLifeTime)
andalso ReuseFun(SuggestedSessionId, PeerCert,
Compression, CipherSuite);
diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_ssl3.erl
index 1add203fb0..f2926b2d2f 100644
--- a/lib/ssl/src/ssl_ssl3.erl
+++ b/lib/ssl/src/ssl_ssl3.erl
@@ -25,7 +25,6 @@
-module(ssl_ssl3).
-include("ssl_cipher.hrl").
--include("ssl_debug.hrl").
-include("ssl_internal.hrl").
-include("ssl_record.hrl"). % MD5 and SHA
@@ -41,9 +40,6 @@
-spec master_secret(binary(), binary(), binary()) -> binary().
master_secret(PremasterSecret, ClientRandom, ServerRandom) ->
- ?DBG_HEX(PremasterSecret),
- ?DBG_HEX(ClientRandom),
- ?DBG_HEX(ServerRandom),
%% draft-ietf-tls-ssl-version3-00 - 6.2.2
%% key_block =
%% MD5(master_secret + SHA(`A' + master_secret +
@@ -55,9 +51,8 @@ master_secret(PremasterSecret, ClientRandom, ServerRandom) ->
%% MD5(master_secret + SHA(`CCC' + master_secret +
%% ServerHello.random +
%% ClientHello.random)) + [...];
- B = generate_keyblock(PremasterSecret, ClientRandom, ServerRandom, 48),
- ?DBG_HEX(B),
- B.
+ Block = generate_keyblock(PremasterSecret, ClientRandom, ServerRandom, 48),
+ Block.
-spec finished(client | server, binary(), {binary(), binary()}) -> binary().
@@ -79,10 +74,9 @@ finished(Role, MasterSecret, {MD5Hash, SHAHash}) ->
SHA = handshake_hash(?SHA, MasterSecret, Sender, SHAHash),
<<MD5/binary, SHA/binary>>.
--spec certificate_verify(key_algo(), binary(), {binary(), binary()}) -> binary().
+-spec certificate_verify(OID::tuple(), binary(), {binary(), binary()}) -> binary().
-certificate_verify(Algorithm, MasterSecret, {MD5Hash, SHAHash})
- when Algorithm == rsa; Algorithm == dhe_rsa ->
+certificate_verify(?'rsaEncryption', MasterSecret, {MD5Hash, SHAHash}) ->
%% md5_hash
%% MD5(master_secret + pad_2 +
%% MD5(handshake_messages + master_secret + pad_1));
@@ -94,7 +88,7 @@ certificate_verify(Algorithm, MasterSecret, {MD5Hash, SHAHash})
SHA = handshake_hash(?SHA, MasterSecret, undefined, SHAHash),
<<MD5/binary, SHA/binary>>;
-certificate_verify(dhe_dss, MasterSecret, {_, SHAHash}) ->
+certificate_verify(?'id-dsa', MasterSecret, {_, SHAHash}) ->
%% sha_hash
%% SHA(master_secret + pad_2 +
%% SHA(handshake_messages + master_secret + pad_1));
@@ -108,17 +102,9 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) ->
%% hash(MAC_write_secret + pad_1 + seq_num +
%% SSLCompressed.type + SSLCompressed.length +
%% SSLCompressed.fragment));
- case Method of
- ?NULL -> ok;
- _ ->
- ?DBG_HEX(Mac_write_secret),
- ?DBG_HEX(hash(Method, Fragment)),
- ok
- end,
Mac = mac_hash(Method, Mac_write_secret,
[<<?UINT64(Seq_num), ?BYTE(Type),
?UINT16(Length)>>, Fragment]),
- ?DBG_HEX(Mac),
Mac.
-spec setup_keys(binary(), binary(), binary(),
@@ -140,12 +126,6 @@ setup_keys(MasterSecret, ServerRandom, ClientRandom, HS, KML, _EKML, IVS) ->
<<ClientWriteMacSecret:HS/binary, ServerWriteMacSecret:HS/binary,
ClientWriteKey:KML/binary, ServerWriteKey:KML/binary,
ClientIV:IVS/binary, ServerIV:IVS/binary>> = KeyBlock,
- ?DBG_HEX(ClientWriteMacSecret),
- ?DBG_HEX(ServerWriteMacSecret),
- ?DBG_HEX(ClientWriteKey),
- ?DBG_HEX(ServerWriteKey),
- ?DBG_HEX(ClientIV),
- ?DBG_HEX(ServerIV),
{ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
ServerWriteKey, ClientIV, ServerIV}.
diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/ssl_tls1.erl
index d1bc0730ba..5f9850c386 100644
--- a/lib/ssl/src/ssl_tls1.erl
+++ b/lib/ssl/src/ssl_tls1.erl
@@ -27,7 +27,6 @@
-include("ssl_cipher.hrl").
-include("ssl_internal.hrl").
-include("ssl_record.hrl").
--include("ssl_debug.hrl").
-export([master_secret/3, finished/3, certificate_verify/2, mac_hash/7,
setup_keys/6, suites/0]).
@@ -60,15 +59,14 @@ finished(Role, MasterSecret, {MD5Hash, SHAHash}) ->
SHA = hash_final(?SHA, SHAHash),
prf(MasterSecret, finished_label(Role), [MD5, SHA], 12).
--spec certificate_verify(key_algo(), {binary(), binary()}) -> binary().
+-spec certificate_verify(OID::tuple(), {binary(), binary()}) -> binary().
-certificate_verify(Algorithm, {MD5Hash, SHAHash}) when Algorithm == rsa;
- Algorithm == dhe_rsa ->
+certificate_verify(?'rsaEncryption', {MD5Hash, SHAHash}) ->
MD5 = hash_final(?MD5, MD5Hash),
SHA = hash_final(?SHA, SHAHash),
<<MD5/binary, SHA/binary>>;
-certificate_verify(dhe_dss, {_, SHAHash}) ->
+certificate_verify(?'id-dsa', {_, SHAHash}) ->
hash_final(?SHA, SHAHash).
-spec setup_keys(binary(), binary(), binary(), integer(),
@@ -130,18 +128,10 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor},
%% HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
%% TLSCompressed.version + TLSCompressed.length +
%% TLSCompressed.fragment));
- case Method of
- ?NULL -> ok;
- _ ->
- ?DBG_HEX(Mac_write_secret),
- ?DBG_HEX(hash(Method, Fragment)),
- ok
- end,
Mac = hmac_hash(Method, Mac_write_secret,
[<<?UINT64(Seq_num), ?BYTE(Type),
?BYTE(Major), ?BYTE(Minor), ?UINT16(Length)>>,
Fragment]),
- ?DBG_HEX(Mac),
Mac.
-spec suites() -> [cipher_suite()].
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
index 9e4aecac45..823401c863 100644
--- a/lib/ssl/test/Makefile
+++ b/lib/ssl/test/Makefile
@@ -40,6 +40,7 @@ MODULES = \
ssl_packet_SUITE \
ssl_payload_SUITE \
ssl_to_openssl_SUITE \
+ ssl_session_cache_SUITE \
ssl_test_MACHINE \
old_ssl_active_SUITE \
old_ssl_active_once_SUITE \
@@ -125,7 +126,7 @@ release_spec: opt
release_tests_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(HRL_FILES_NEEDED_IN_TEST) $(COVER_FILE) $(RELSYSDIR)
- $(INSTALL_DATA) ssl.spec $(RELSYSDIR)
+ $(INSTALL_DATA) ssl.spec ssl.cover $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/ssl/test/make_certs.erl b/lib/ssl/test/make_certs.erl
index 3c18a905b4..693289990c 100644
--- a/lib/ssl/test/make_certs.erl
+++ b/lib/ssl/test/make_certs.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/ssl/test/old_ssl_active_SUITE.erl b/lib/ssl/test/old_ssl_active_SUITE.erl
index d1cec26827..a878c5af68 100644
--- a/lib/ssl/test/old_ssl_active_SUITE.erl
+++ b/lib/ssl/test/old_ssl_active_SUITE.erl
@@ -20,11 +20,10 @@
%%
-module(old_ssl_active_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
- config/1,
- finish/1,
+ end_per_testcase/2,
cinit_return_chkclose/1,
sinit_return_chkclose/1,
cinit_big_return_chkclose/1,
@@ -40,7 +39,7 @@
-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
test_server_only/6]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ssl_test_MACHINE.hrl").
-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
@@ -49,33 +48,35 @@ init_per_testcase(_Case, Config) ->
WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of ssl.erl interface in active mode.";
-all(suite) ->
- {conf,
- config,
- [cinit_return_chkclose,
- sinit_return_chkclose,
- cinit_big_return_chkclose,
- sinit_big_return_chkclose,
- cinit_big_echo_chkclose,
- cinit_huge_echo_chkclose,
- sinit_big_echo_chkclose,
- cinit_few_echo_chkclose,
- cinit_many_echo_chkclose,
- cinit_cnocert],
- finish}.
-
-config(doc) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [cinit_return_chkclose, sinit_return_chkclose,
+ cinit_big_return_chkclose, sinit_big_return_chkclose,
+ cinit_big_echo_chkclose, cinit_huge_echo_chkclose,
+ sinit_big_echo_chkclose, cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose, cinit_cnocert].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(doc) ->
"Want to se what Config contains, and record the number of available "
"file descriptors";
-config(suite) ->
+init_per_suite(suite) ->
[];
-config(Config) ->
+init_per_suite(Config) ->
io:format("Config: ~p~n", [Config]),
case os:type() of
{unix, _} ->
@@ -87,20 +88,25 @@ config(Config) ->
%% operating system, version of OTP, Erts, kernel and stdlib.
%% Check if SSL exists. If this case fails, all other cases are skipped
- crypto:start(),
- application:start(public_key),
- case ssl:start() of
- ok -> ssl:stop();
- {error, {already_started, _}} -> ssl:stop();
- Error -> ?t:fail({failed_starting_ssl,Error})
- end,
- Config.
-
-finish(doc) ->
+ case catch crypto:start() of
+ ok ->
+ application:start(public_key),
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config;
+ _Else ->
+ {skip,"Could not start crypto!"}
+ end.
+
+end_per_suite(doc) ->
"This test case has no mission other than closing the conf case";
-finish(suite) ->
+end_per_suite(suite) ->
[];
-finish(Config) ->
+end_per_suite(Config) ->
+ crypto:stop(),
Config.
cinit_return_chkclose(doc) ->
diff --git a/lib/ssl/test/old_ssl_active_once_SUITE.erl b/lib/ssl/test/old_ssl_active_once_SUITE.erl
index 63eaa730e9..b68ff6c66a 100644
--- a/lib/ssl/test/old_ssl_active_once_SUITE.erl
+++ b/lib/ssl/test/old_ssl_active_once_SUITE.erl
@@ -20,11 +20,10 @@
%%
-module(old_ssl_active_once_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
- config/1,
- finish/1,
+ end_per_testcase/2,
server_accept_timeout/1,
cinit_return_chkclose/1,
sinit_return_chkclose/1,
@@ -40,7 +39,7 @@
-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
test_server_only/6]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ssl_test_MACHINE.hrl").
-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
@@ -49,50 +48,57 @@ init_per_testcase(_Case, Config) ->
WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of ssl.erl interface in passive mode.";
-all(suite) ->
- {conf,
- config,
- [server_accept_timeout,
- cinit_return_chkclose,
- sinit_return_chkclose,
- cinit_big_return_chkclose,
- sinit_big_return_chkclose,
- cinit_big_echo_chkclose,
- cinit_huge_echo_chkclose,
- sinit_big_echo_chkclose,
- cinit_few_echo_chkclose,
- cinit_many_echo_chkclose,
- cinit_cnocert],
- finish}.
-
-config(doc) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [server_accept_timeout, cinit_return_chkclose,
+ sinit_return_chkclose, cinit_big_return_chkclose,
+ sinit_big_return_chkclose, cinit_big_echo_chkclose,
+ cinit_huge_echo_chkclose, sinit_big_echo_chkclose,
+ cinit_few_echo_chkclose, cinit_many_echo_chkclose,
+ cinit_cnocert].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(doc) ->
"Want to se what Config contains.";
-config(suite) ->
+init_per_suite(suite) ->
[];
-config(Config) ->
+init_per_suite(Config) ->
io:format("Config: ~p~n", [Config]),
%% Check if SSL exists. If this case fails, all other cases are skipped
- crypto:start(),
- application:start(public_key),
- case ssl:start() of
- ok -> ssl:stop();
- {error, {already_started, _}} -> ssl:stop();
- Error -> ?t:fail({failed_starting_ssl,Error})
- end,
- Config.
-
-finish(doc) ->
+ case catch crypto:start() of
+ ok ->
+ application:start(public_key),
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config;
+ _Else ->
+ {skip,"Could not start crypto"}
+ end.
+
+end_per_suite(doc) ->
"This test case has no mission other than closing the conf case";
-finish(suite) ->
+end_per_suite(suite) ->
[];
-finish(Config) ->
+end_per_suite(Config) ->
+ crypto:stop(),
Config.
server_accept_timeout(doc) ->
diff --git a/lib/ssl/test/old_ssl_dist_SUITE.erl b/lib/ssl/test/old_ssl_dist_SUITE.erl
index 97090c1409..6a072c9d98 100644
--- a/lib/ssl/test/old_ssl_dist_SUITE.erl
+++ b/lib/ssl/test/old_ssl_dist_SUITE.erl
@@ -29,28 +29,38 @@
%%%-------------------------------------------------------------------
-module(old_ssl_dist_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(DEFAULT_TIMETRAP_SECS, 240).
-define(AWAIT_SLL_NODE_UP_TIMEOUT, 30000).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([init_per_suite/1,
end_per_suite/1,
init_per_testcase/2,
- fin_per_testcase/2]).
+ end_per_testcase/2]).
-export([cnct2tstsrvr/1]).
-export([basic/1]).
-record(node_handle, {connection_handler, socket, name, nodename}).
-all(doc) ->
- [];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[basic].
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_suite(Config) ->
add_ssl_opts_config(Config).
@@ -61,7 +71,7 @@ init_per_testcase(Case, Config) when list(Config) ->
Dog = ?t:timetrap(?t:seconds(?DEFAULT_TIMETRAP_SECS)),
[{watchdog, Dog},{testcase, Case}|Config].
-fin_per_testcase(_Case, Config) when list(Config) ->
+end_per_testcase(_Case, Config) when list(Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
diff --git a/lib/ssl/test/old_ssl_misc_SUITE.erl b/lib/ssl/test/old_ssl_misc_SUITE.erl
index 2767123a12..e1a21096bc 100644
--- a/lib/ssl/test/old_ssl_misc_SUITE.erl
+++ b/lib/ssl/test/old_ssl_misc_SUITE.erl
@@ -20,18 +20,17 @@
%%
-module(old_ssl_misc_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
- config/1,
- finish/1,
+ end_per_testcase/2,
seed/1,
app/1
]).
-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
test_server_only/6]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ssl_test_MACHINE.hrl").
-define(MANYCONNS, 5).
@@ -40,41 +39,52 @@ init_per_testcase(_Case, Config) ->
WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of misc in ssl.erl interface.";
-all(suite) ->
- {conf,
- config,
- [seed, app],
- finish
- }.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-config(doc) ->
+all() ->
+ [seed, app].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(doc) ->
"Want to se what Config contains.";
-config(suite) ->
+init_per_suite(suite) ->
[];
-config(Config) ->
+init_per_suite(Config) ->
io:format("Config: ~p~n", [Config]),
%% Check if SSL exists. If this case fails, all other cases are skipped
- crypto:start(),
- application:start(public_key),
- case ssl:start() of
- ok -> ssl:stop();
- {error, {already_started, _}} -> ssl:stop();
- Error -> ?t:fail({failed_starting_ssl,Error})
- end,
- Config.
-
-finish(doc) ->
+ case catch crypto:start() of
+ ok ->
+ application:start(public_key),
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config;
+ _Else ->
+ {skip,"Could not start crypto!"}
+ end.
+
+end_per_suite(doc) ->
"This test case has no mission other than closing the conf case";
-finish(suite) ->
+end_per_suite(suite) ->
[];
-finish(Config) ->
+end_per_suite(Config) ->
+ crypto:stop(),
Config.
seed(doc) ->
diff --git a/lib/ssl/test/old_ssl_passive_SUITE.erl b/lib/ssl/test/old_ssl_passive_SUITE.erl
index 96a7938583..8bdadd4ea6 100644
--- a/lib/ssl/test/old_ssl_passive_SUITE.erl
+++ b/lib/ssl/test/old_ssl_passive_SUITE.erl
@@ -20,11 +20,10 @@
%%
-module(old_ssl_passive_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1,
+ end_per_suite/1, init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
- config/1,
- finish/1,
+ end_per_testcase/2,
server_accept_timeout/1,
cinit_return_chkclose/1,
sinit_return_chkclose/1,
@@ -40,7 +39,7 @@
-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
test_server_only/6]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ssl_test_MACHINE.hrl").
-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
@@ -49,49 +48,56 @@ init_per_testcase(_Case, Config) ->
WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of ssl.erl interface in passive mode.";
-all(suite) ->
- {conf,
- config,
- [server_accept_timeout,
- cinit_return_chkclose,
- sinit_return_chkclose,
- cinit_big_return_chkclose,
- sinit_big_return_chkclose,
- cinit_big_echo_chkclose,
- sinit_big_echo_chkclose,
- cinit_few_echo_chkclose,
- cinit_many_echo_chkclose,
- cinit_cnocert],
- finish}.
-
-config(doc) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [server_accept_timeout, cinit_return_chkclose,
+ sinit_return_chkclose, cinit_big_return_chkclose,
+ sinit_big_return_chkclose, cinit_big_echo_chkclose,
+ sinit_big_echo_chkclose, cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose, cinit_cnocert].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(doc) ->
"Want to se what Config contains.";
-config(suite) ->
+init_per_suite(suite) ->
[];
-config(Config) ->
+init_per_suite(Config) ->
io:format("Config: ~p~n", [Config]),
%% Check if SSL exists. If this case fails, all other cases are skipped
- crypto:start(),
- application:start(public_key),
- case ssl:start() of
- ok -> ssl:stop();
- {error, {already_started, _}} -> ssl:stop();
- Error -> ?t:fail({failed_starting_ssl,Error})
- end,
- Config.
-
-finish(doc) ->
+ case catch crypto:start() of
+ ok ->
+ application:start(public_key),
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config;
+ _Else ->
+ {skip,"Could not start crypto"}
+ end.
+
+end_per_suite(doc) ->
"This test case has no mission other than closing the conf case";
-finish(suite) ->
+end_per_suite(suite) ->
[];
-finish(Config) ->
+end_per_suite(Config) ->
+ crypto:stop(),
Config.
server_accept_timeout(doc) ->
diff --git a/lib/ssl/test/old_ssl_peer_cert_SUITE.erl b/lib/ssl/test/old_ssl_peer_cert_SUITE.erl
index e5b3975d41..54f06aec2f 100644
--- a/lib/ssl/test/old_ssl_peer_cert_SUITE.erl
+++ b/lib/ssl/test/old_ssl_peer_cert_SUITE.erl
@@ -20,11 +20,10 @@
%%
-module(old_ssl_peer_cert_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
- config/1,
- finish/1,
+ end_per_testcase/2,
cinit_plain/1,
cinit_both_verify/1,
cinit_cnocert/1
@@ -32,7 +31,7 @@
-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
test_server_only/6]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ssl_test_MACHINE.hrl").
@@ -40,42 +39,52 @@ init_per_testcase(_Case, Config) ->
WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of ssl verification and peer certificate retrieval.";
-all(suite) ->
- {conf,
- config,
- [cinit_plain,
- cinit_both_verify,
- cinit_cnocert],
- finish}.
-
-config(doc) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [cinit_plain, cinit_both_verify, cinit_cnocert].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(doc) ->
"Want to se what Config contains.";
-config(suite) ->
+init_per_suite(suite) ->
[];
-config(Config) ->
+init_per_suite(Config) ->
io:format("Config: ~p~n", [Config]),
%% Check if SSL exists. If this case fails, all other cases are skipped
- crypto:start(),
- application:start(public_key),
- case ssl:start() of
- ok -> ssl:stop();
- {error, {already_started, _}} -> ssl:stop();
- Error -> ?t:fail({failed_starting_ssl,Error})
- end,
- Config.
-
-finish(doc) ->
+ case catch crypto:start() of
+ ok ->
+ application:start(public_key),
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config;
+ _Else ->
+ {skip,"Could not start crypto"}
+ end.
+
+end_per_suite(doc) ->
"This test case has no mission other than closing the conf case";
-finish(suite) ->
+end_per_suite(suite) ->
[];
-finish(Config) ->
+end_per_suite(Config) ->
+ crypto:stop(),
Config.
cinit_plain(doc) ->
diff --git a/lib/ssl/test/old_ssl_protocol_SUITE.erl b/lib/ssl/test/old_ssl_protocol_SUITE.erl
index efdbf45a3d..779491ee69 100644
--- a/lib/ssl/test/old_ssl_protocol_SUITE.erl
+++ b/lib/ssl/test/old_ssl_protocol_SUITE.erl
@@ -20,13 +20,15 @@
%%
-module(old_ssl_protocol_SUITE).
--export([all/1, init_per_testcase/2, fin_per_testcase/2, config/1,
- finish/1, sslv2/1, sslv3/1, tlsv1/1, sslv2_sslv3/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
+ sslv2/1, sslv3/1, tlsv1/1, sslv2_sslv3/1,
sslv2_tlsv1/1, sslv3_tlsv1/1, sslv2_sslv3_tlsv1/1]).
-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
test_server_only/6]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ssl_test_MACHINE.hrl").
@@ -34,41 +36,53 @@ init_per_testcase(_Case, Config) ->
WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of configuration protocol_version.";
-all(suite) ->
- {conf,
- config,
- [sslv2, sslv3, tlsv1, sslv2_sslv3, sslv2_tlsv1, sslv3_tlsv1,
- sslv2_sslv3_tlsv1],
- finish}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-config(doc) ->
+all() ->
+ [sslv2, sslv3, tlsv1, sslv2_sslv3, sslv2_tlsv1,
+ sslv3_tlsv1, sslv2_sslv3_tlsv1].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(doc) ->
"Want to se what Config contains.";
-config(suite) ->
+init_per_suite(suite) ->
[];
-config(Config) ->
+init_per_suite(Config) ->
io:format("Config: ~p~n", [Config]),
%% Check if SSL exists. If this case fails, all other cases are skipped
- crypto:start(),
- application:start(public_key),
- case ssl:start() of
- ok -> ssl:stop();
- {error, {already_started, _}} -> ssl:stop();
- Error -> ?t:fail({failed_starting_ssl,Error})
- end,
- Config.
-
-finish(doc) ->
+ case catch crypto:start() of
+ ok ->
+ application:start(public_key),
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config;
+ _Else ->
+ {skip,"Could not start crypto"}
+ end.
+
+end_per_suite(doc) ->
"This test case has no other purpose than closing the conf case.";
-finish(suite) ->
+end_per_suite(suite) ->
[];
-finish(Config) ->
+end_per_suite(Config) ->
+ crypto:stop(),
Config.
%%%%%
diff --git a/lib/ssl/test/old_ssl_verify_SUITE.erl b/lib/ssl/test/old_ssl_verify_SUITE.erl
index 7a8cd1578a..d388484141 100644
--- a/lib/ssl/test/old_ssl_verify_SUITE.erl
+++ b/lib/ssl/test/old_ssl_verify_SUITE.erl
@@ -20,18 +20,17 @@
%%
-module(old_ssl_verify_SUITE).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
- config/1,
- finish/1,
+ end_per_testcase/2,
cinit_both_verify/1,
cinit_cnocert/1
]).
-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
test_server_only/6]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("ssl_test_MACHINE.hrl").
@@ -39,41 +38,52 @@ init_per_testcase(_Case, Config) ->
WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
[{watchdog, WatchDog}| Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test of ssl.erl interface in active mode.";
-all(suite) ->
- {conf,
- config,
- [cinit_both_verify,
- cinit_cnocert],
- finish}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
-config(doc) ->
+all() ->
+ [cinit_both_verify, cinit_cnocert].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(doc) ->
"Want to se what Config contains.";
-config(suite) ->
+init_per_suite(suite) ->
[];
-config(Config) ->
+init_per_suite(Config) ->
io:format("Config: ~p~n", [Config]),
%% Check if SSL exists. If this case fails, all other cases are skipped
- crypto:start(),
- application:start(public_key),
- case ssl:start() of
- ok -> ssl:stop();
- {error, {already_started, _}} -> ssl:stop();
- Error -> ?t:fail({failed_starting_ssl,Error})
- end,
- Config.
-
-finish(doc) ->
+ case catch crypto:start() of
+ ok ->
+ application:start(public_key),
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config;
+ _Else ->
+ {skip,"Could not start crypto"}
+ end.
+
+end_per_suite(doc) ->
"This test case has no mission other than closing the conf case";
-finish(suite) ->
+end_per_suite(suite) ->
[];
-finish(Config) ->
+end_per_suite(Config) ->
+ crypto:stop(),
Config.
cinit_both_verify(doc) ->
diff --git a/lib/ssl/test/old_transport_accept_SUITE.erl b/lib/ssl/test/old_transport_accept_SUITE.erl
index 71c1d9e181..21ee0690b1 100644
--- a/lib/ssl/test/old_transport_accept_SUITE.erl
+++ b/lib/ssl/test/old_transport_accept_SUITE.erl
@@ -19,16 +19,17 @@
%%
-module(old_transport_accept_SUITE).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
%% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
-define(application, ssh).
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
+ end_per_testcase/2,
config/1,
echo_once/1,
echo_twice/1,
@@ -43,15 +44,31 @@ init_per_testcase(_Case, Config) ->
[{watchdog, WatchDog}, {protomod, gen_tcp}, {serialize_accept, true}|
Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
WatchDog = ?config(watchdog, Config),
test_server:timetrap_cancel(WatchDog).
-all(doc) ->
- "Test transport_accept and ssl_accept";
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[config, echo_once, echo_twice, close_before_ssl_accept].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
config(doc) ->
"Want to se what Config contains.";
config(suite) ->
diff --git a/lib/ssl/test/ssl.cover b/lib/ssl/test/ssl.cover
index e8daa363c5..60774cc0f1 100644
--- a/lib/ssl/test/ssl.cover
+++ b/lib/ssl/test/ssl.cover
@@ -1,19 +1,21 @@
-{exclude, [ssl_pkix_oid,
- 'PKIX1Algorithms88',
- 'PKIX1Explicit88',
- 'PKIX1Implicit88',
- 'PKIXAttributeCertificate',
- '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'
+{incl_app,ssl,details}.
+
+{excl_mods, ssl, [ssl_pkix_oid,
+ 'PKIX1Algorithms88',
+ 'PKIX1Explicit88',
+ 'PKIX1Implicit88',
+ 'PKIXAttributeCertificate',
+ '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.spec b/lib/ssl/test/ssl.spec
index 6ef4fb73db..fc7c1bbb82 100644
--- a/lib/ssl/test/ssl.spec
+++ b/lib/ssl/test/ssl.spec
@@ -1 +1 @@
-{topcase, {dir, "../ssl_test"}}.
+{suites,"../ssl_test",all}.
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 3cb9337775..87d5fc8d71 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -24,22 +24,18 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.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(LONG_TIMEOUT, 600000).
-define(EXPIRE, 10).
-define(SLEEP, 500).
--behaviour(ssl_session_cache_api).
-
-%% For the session cache tests
--export([init/1, terminate/1, lookup/2, update/3,
- delete/2, foldl/3, select_session/2]).
-
%% Test server callback functions
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
@@ -51,21 +47,24 @@
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config0) ->
- Dog = ssl_test_lib:timetrap(?TIMEOUT *2),
- crypto:start(),
- application:start(public_key),
- ssl:start(),
-
- %% make rsa certs using oppenssl
- Result =
- (catch make_certs:all(?config(data_dir, Config0),
- ?config(priv_dir, Config0))),
- test_server:format("Make certs ~p~n", [Result]),
-
- Config1 = ssl_test_lib:make_dsa_cert(Config0),
- Config = ssl_test_lib:cert_options(Config1),
- [{watchdog, Dog} | Config].
-
+ Dog = ssl_test_lib:timetrap(?LONG_TIMEOUT *2),
+ case application:start(crypto) of
+ ok ->
+ application:start(public_key),
+ ssl:start(),
+
+ %% make rsa certs using oppenssl
+ Result =
+ (catch make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0))),
+ test_server:format("Make certs ~p~n", [Result]),
+
+ Config1 = ssl_test_lib:make_dsa_cert(Config0),
+ Config = ssl_test_lib:cert_options(Config1),
+ [{watchdog, Dog} | Config];
+ _ ->
+ {skip, "Crypto did not start"}
+ end.
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
%% Config - [tuple()]
@@ -74,7 +73,7 @@ init_per_suite(Config0) ->
%%--------------------------------------------------------------------
end_per_suite(_Config) ->
ssl:stop(),
- crypto:stop().
+ application:stop(crypto).
%%--------------------------------------------------------------------
%% Function: init_per_testcase(TestCase, Config) -> Config
@@ -137,6 +136,9 @@ init_per_testcase(empty_protocol_versions, Config) ->
ssl:start(),
Config;
+init_per_testcase(different_ca_peer_sign, Config0) ->
+ ssl_test_lib:make_mix_cert(Config0);
+
init_per_testcase(_TestCase, Config0) ->
Config = lists:keydelete(watchdog, 1, Config0),
Dog = test_server:timetrap(?TIMEOUT),
@@ -198,46 +200,66 @@ end_per_testcase(_TestCase, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test the basic ssl functionality"];
+suite() -> [{ct_hooks,[ts_install_cth]}].
-all(suite) ->
+all() ->
[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,
+ 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_rsa_signed_certs, ciphers_rsa_signed_certs_ssl3,
ciphers_rsa_signed_certs_openssl_names,
ciphers_rsa_signed_certs_openssl_names_ssl3,
- ciphers_dsa_signed_certs,
- ciphers_dsa_signed_certs_ssl3,
+ ciphers_dsa_signed_certs, ciphers_dsa_signed_certs_ssl3,
ciphers_dsa_signed_certs_openssl_names,
ciphers_dsa_signed_certs_openssl_names_ssl3,
+ anonymous_cipher_suites,
+ default_reject_anonymous,
send_close,
- close_transport_accept, dh_params, server_verify_peer_passive,
- server_verify_peer_active, server_verify_peer_active_once,
+ 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_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,
- no_authority_key_identifier,
- invalid_signature_client, invalid_signature_server, cert_expired,
- client_with_cert_cipher_suites_handshake, unknown_server_ca_fail,
- der_input, unknown_server_ca_accept_verify_none, unknown_server_ca_accept_verify_peer,
- unknown_server_ca_accept_backwardscompatibilty
- ].
+ server_verify_client_once_active_once,
+ client_verify_none_passive, client_verify_none_active,
+ client_verify_none_active_once,
+ 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_verify_peer,
+ extended_key_usage_verify_none,
+ no_authority_key_identifier, invalid_signature_client,
+ invalid_signature_server, cert_expired,
+ client_with_cert_cipher_suites_handshake,
+ unknown_server_ca_fail, der_input,
+ unknown_server_ca_accept_verify_none,
+ unknown_server_ca_accept_verify_peer,
+ unknown_server_ca_accept_backwardscompatibilty,
+ %%different_ca_peer_sign,
+ no_reuses_session_server_restart_new_cert,
+ no_reuses_session_server_restart_new_cert_file, reuseaddr].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%% Test cases starts here.
%%--------------------------------------------------------------------
@@ -352,7 +374,6 @@ basic_test(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-
%%--------------------------------------------------------------------
controlling_process(doc) ->
@@ -552,9 +573,7 @@ client_closes_socket(Config) when is_list(Config) ->
_Client = spawn_link(Connect),
- ssl_test_lib:check_result(Server, {error,closed}),
-
- ssl_test_lib:close(Server).
+ ssl_test_lib:check_result(Server, {error,closed}).
%%--------------------------------------------------------------------
@@ -769,7 +788,6 @@ socket_options(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
{ok, Listen} = ssl:listen(0, ServerOpts),
{ok,[{mode,list}]} = ssl:getopts(Listen, [mode]),
@@ -872,6 +890,7 @@ send_recv(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
send_close(doc) ->
[""];
@@ -898,8 +917,7 @@ send_close(Config) when is_list(Config) ->
ok = ssl:send(SslS, "Hello world"),
{ok,<<"Hello world">>} = ssl:recv(SslS, 11),
gen_tcp:close(TcpS),
- {error, _} = ssl:send(SslS, "Hello world"),
- ssl_test_lib:close(Server).
+ {error, _} = ssl:send(SslS, "Hello world").
%%--------------------------------------------------------------------
close_transport_accept(doc) ->
@@ -1074,8 +1092,7 @@ tcp_connect(Config) when is_list(Config) ->
{Server, {error, Error}} ->
test_server:format("Error ~p", [Error])
end
- end,
- ssl_test_lib:close(Server).
+ end.
dummy(_Socket) ->
@@ -1084,6 +1101,8 @@ dummy(_Socket) ->
exit(kill).
%%--------------------------------------------------------------------
+ipv6() ->
+ [{require, ipv6_hosts}].
ipv6(doc) ->
["Test ipv6."];
ipv6(suite) ->
@@ -1091,7 +1110,7 @@ ipv6(suite) ->
ipv6(Config) when is_list(Config) ->
{ok, Hostname0} = inet:gethostname(),
- case lists:member(list_to_atom(Hostname0), ?config(ipv6_hosts, Config)) of
+ case lists:member(list_to_atom(Hostname0), ct:get_config(ipv6_hosts)) of
true ->
ClientOpts = ?config(client_opts, Config),
ServerOpts = ?config(server_opts, Config),
@@ -1165,13 +1184,13 @@ ecertfile(Config) when is_list(Config) ->
Server =
ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
- {options, ServerBadOpts}]),
+ {options, ServerBadOpts}]),
Port = ssl_test_lib:inet_port(Server),
Client =
ssl_test_lib:start_client_error([{node, ClientNode},
- {port, Port}, {host, Hostname},
+ {port, Port}, {host, Hostname},
{from, self()},
{options, ClientOpts}]),
@@ -1180,13 +1199,13 @@ ecertfile(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-ecacertfile(doc) ->
+ecacertfile(doc) ->
["Test what happens with an invalid cacert file"];
-ecacertfile(suite) ->
+ecacertfile(suite) ->
[];
-ecacertfile(Config) when is_list(Config) ->
+ecacertfile(Config) when is_list(Config) ->
ClientOpts = [{reuseaddr, true}|?config(client_opts, Config)],
ServerBadOpts = [{reuseaddr, true}|?config(server_bad_ca, Config)],
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -1522,6 +1541,14 @@ ciphers_dsa_signed_certs_openssl_names_ssl3(Config) when is_list(Config) ->
Ciphers = ssl_test_lib:openssl_dsa_suites(),
run_suites(Ciphers, Version, Config, dsa).
+anonymous_cipher_suites(doc)->
+ ["Test the anonymous ciphersuites"];
+anonymous_cipher_suites(suite) ->
+ [];
+anonymous_cipher_suites(Config) when is_list(Config) ->
+ Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+ Ciphers = ssl_test_lib:anonymous_suites(),
+ run_suites(Ciphers, Version, Config, anonymous).
run_suites(Ciphers, Version, Config, Type) ->
{ClientOpts, ServerOpts} =
@@ -1531,8 +1558,12 @@ run_suites(Ciphers, Version, Config, Type) ->
?config(server_opts, Config)};
dsa ->
{?config(client_opts, Config),
- ?config(server_dsa_opts, Config)}
- end,
+ ?config(server_dsa_opts, Config)};
+ anonymous ->
+ %% No certs in opts!
+ {?config(client_opts, Config),
+ ?config(server_anon, Config)}
+ end,
Result = lists:map(fun(Cipher) ->
cipher(Cipher, Version, Config, ClientOpts, ServerOpts) end,
@@ -1551,7 +1582,7 @@ erlang_cipher_suite(Suite) ->
Suite.
cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
- process_flag(trap_exit, true),
+ %% process_flag(trap_exit, true),
test_server:format("Testing CipherSuite ~p~n", [CipherSuite]),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -1575,16 +1606,8 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
Result = ssl_test_lib:wait_for_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
- receive
- {'EXIT', Server, normal} ->
- ok
- end,
ssl_test_lib:close(Client),
- receive
- {'EXIT', Client, normal} ->
- ok
- end,
- process_flag(trap_exit, false),
+
case Result of
ok ->
[];
@@ -1593,6 +1616,32 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
end.
%%--------------------------------------------------------------------
+default_reject_anonymous(doc)->
+ ["Test that by default anonymous cipher suites are rejected "];
+default_reject_anonymous(suite) ->
+ [];
+default_reject_anonymous(Config) when is_list(Config) ->
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ [Cipher | _] = ssl_test_lib:anonymous_suites(),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options,
+ [{ciphers,[Cipher]} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, "insufficient security"},
+ Client, {error, "insufficient security"}).
+
+%%--------------------------------------------------------------------
reuse_session(doc) ->
["Test reuse of sessions (short handshake)"];
@@ -1600,7 +1649,6 @@ reuse_session(suite) ->
[];
reuse_session(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
ClientOpts = ?config(client_opts, Config),
ServerOpts = ?config(server_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -1608,13 +1656,13 @@ reuse_session(Config) when is_list(Config) ->
Server =
ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, session_info_result, []}},
- {options, ServerOpts}]),
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Client0 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
- {mfa, {ssl_test_lib, no_result, []}},
+ {mfa, {ssl_test_lib, no_result, []}},
{from, self()}, {options, ClientOpts}]),
SessionInfo =
receive
@@ -1622,16 +1670,16 @@ reuse_session(Config) when is_list(Config) ->
Info
end,
- Server ! listen,
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
%% 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}]),
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
receive
{Client1, SessionInfo} ->
ok;
@@ -1641,10 +1689,10 @@ reuse_session(Config) when is_list(Config) ->
test_server:fail(session_not_reused)
end,
- Server ! listen,
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
Client2 =
- ssl_test_lib:start_client([{node, ClientNode},
+ ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
{mfa, {?MODULE, session_info_result, []}},
{from, self()}, {options, [{reuse_sessions, false}
@@ -1658,10 +1706,6 @@ reuse_session(Config) when is_list(Config) ->
end,
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client0),
- ssl_test_lib:close(Client1),
- ssl_test_lib:close(Client2),
-
Server1 =
ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
@@ -1673,7 +1717,7 @@ reuse_session(Config) when is_list(Config) ->
Client3 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port1}, {host, Hostname},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, no_result, []}},
{from, self()}, {options, ClientOpts}]),
SessionInfo1 =
@@ -1682,7 +1726,7 @@ reuse_session(Config) when is_list(Config) ->
Info1
end,
- Server1 ! listen,
+ Server1 ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
%% Make sure session is registered
test_server:sleep(?SLEEP),
@@ -1698,14 +1742,16 @@ reuse_session(Config) when is_list(Config) ->
test_server:fail(
session_reused_when_session_reuse_disabled_by_server);
{Client4, _Other} ->
+ test_server:format("OTHER: ~p ~n", [_Other]),
ok
end,
-
+
ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ ssl_test_lib:close(Client2),
ssl_test_lib:close(Client3),
- ssl_test_lib:close(Client4),
- process_flag(trap_exit, false).
-
+ ssl_test_lib:close(Client4).
session_info_result(Socket) ->
ssl:session_info(Socket).
@@ -1718,7 +1764,6 @@ reuse_session_expired(suite) ->
[];
reuse_session_expired(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
ClientOpts = ?config(client_opts, Config),
ServerOpts = ?config(server_opts, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -1739,8 +1784,8 @@ reuse_session_expired(Config) when is_list(Config) ->
{Server, Info} ->
Info
end,
-
- Server ! listen,
+
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
%% Make sure session is registered
test_server:sleep(?SLEEP),
@@ -1760,7 +1805,7 @@ reuse_session_expired(Config) when is_list(Config) ->
end,
Server ! listen,
-
+
%% Make sure session is unregistered due to expiration
test_server:sleep((?EXPIRE+1) * 1000),
@@ -1775,12 +1820,12 @@ reuse_session_expired(Config) when is_list(Config) ->
{Client2, _} ->
ok
end,
-
+ process_flag(trap_exit, false),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client0),
ssl_test_lib:close(Client1),
- ssl_test_lib:close(Client2),
- process_flag(trap_exit, false).
+ ssl_test_lib:close(Client2).
+
%%--------------------------------------------------------------------
server_does_not_want_to_reuse_session(doc) ->
["Test reuse of sessions (short handshake)"];
@@ -1813,10 +1858,11 @@ server_does_not_want_to_reuse_session(Config) when is_list(Config) ->
Info
end,
- Server ! listen,
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
%% Make sure session is registered
test_server:sleep(?SLEEP),
+ ssl_test_lib:close(Client0),
Client1 =
ssl_test_lib:start_client([{node, ClientNode},
@@ -1829,11 +1875,9 @@ server_does_not_want_to_reuse_session(Config) when is_list(Config) ->
{Client1, _Other} ->
ok
end,
-
+
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client0),
- ssl_test_lib:close(Client1),
- process_flag(trap_exit, false).
+ ssl_test_lib:close(Client1).
%%--------------------------------------------------------------------
@@ -2000,6 +2044,7 @@ server_verify_none_active_once(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+
%%--------------------------------------------------------------------
server_verify_client_once_passive(doc) ->
@@ -2027,7 +2072,7 @@ server_verify_client_once_passive(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client0, ok),
ssl_test_lib:close(Client0),
- Server ! listen,
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
@@ -2065,7 +2110,7 @@ server_verify_client_once_active(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client0, ok),
ssl_test_lib:close(Client0),
- Server ! listen,
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
{from, self()},
@@ -2076,7 +2121,6 @@ server_verify_client_once_active(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client1).
-
%%--------------------------------------------------------------------
server_verify_client_once_active_once(doc) ->
@@ -2104,18 +2148,17 @@ server_verify_client_once_active_once(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client0, ok),
ssl_test_lib:close(Client0),
- Server ! listen,
-
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
Client1 = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
- {host, Hostname},
- {from, self()},
- {mfa, {?MODULE, result_ok, []}},
- {options, [{active, once} | ClientOpts]}]),
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, result_ok, []}},
+ {options, [{active, once} | ClientOpts]}]),
ssl_test_lib:check_result(Client1, ok),
ssl_test_lib:close(Server),
ssl_test_lib:close(Client1).
-
+
%%--------------------------------------------------------------------
server_verify_no_cacerts(doc) ->
@@ -2123,9 +2166,8 @@ server_verify_no_cacerts(doc) ->
server_verify_no_cacerts(suite) ->
[];
-
server_verify_no_cacerts(Config) when is_list(Config) ->
- ServerOpts = ServerOpts = ?config(server_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
{_, ServerNode, _} = ssl_test_lib:run_where(Config),
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
{from, self()},
@@ -2286,8 +2328,6 @@ client_verify_none_active_once(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
-
-
%%--------------------------------------------------------------------
client_renegotiate(doc) ->
["Test ssl:renegotiate/1 on client."];
@@ -2296,7 +2336,6 @@ client_renegotiate(suite) ->
[];
client_renegotiate(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
ServerOpts = ?config(server_opts, Config),
ClientOpts = ?config(client_opts, Config),
@@ -2319,11 +2358,9 @@ client_renegotiate(Config) when is_list(Config) ->
{options, [{reuse_sessions, false} | ClientOpts]}]),
ssl_test_lib:check_result(Client, ok, Server, ok),
-
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false),
- ok.
+ ssl_test_lib:close(Client).
+
%%--------------------------------------------------------------------
server_renegotiate(doc) ->
["Test ssl:renegotiate/1 on server."];
@@ -2332,7 +2369,6 @@ server_renegotiate(suite) ->
[];
server_renegotiate(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
ServerOpts = ?config(server_opts, Config),
ClientOpts = ?config(client_opts, Config),
@@ -2355,8 +2391,7 @@ server_renegotiate(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- ok.
+ ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
client_renegotiate_reused_session(doc) ->
@@ -2366,7 +2401,6 @@ 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),
@@ -2389,11 +2423,8 @@ client_renegotiate_reused_session(Config) when is_list(Config) ->
{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.
+ ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
server_renegotiate_reused_session(doc) ->
["Test ssl:renegotiate/1 on server when the ssl session will be reused."];
@@ -2402,7 +2433,6 @@ 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),
@@ -2425,9 +2455,7 @@ server_renegotiate_reused_session(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- ok.
-
+ ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
client_no_wrap_sequence_number(doc) ->
["Test that erlang client will renegotiate session when",
@@ -2439,7 +2467,6 @@ client_no_wrap_sequence_number(suite) ->
[];
client_no_wrap_sequence_number(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
ServerOpts = ?config(server_opts, Config),
ClientOpts = ?config(client_opts, Config),
@@ -2464,11 +2491,8 @@ client_no_wrap_sequence_number(Config) when is_list(Config) ->
{renegotiate_at, N} | ClientOpts]}]),
ssl_test_lib:check_result(Client, ok),
-
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- process_flag(trap_exit, false),
- ok.
+ ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
server_no_wrap_sequence_number(doc) ->
["Test that erlang server will renegotiate session when",
@@ -2480,7 +2504,6 @@ server_no_wrap_sequence_number(suite) ->
[];
server_no_wrap_sequence_number(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
ServerOpts = ?config(server_opts, Config),
ClientOpts = ?config(client_opts, Config),
@@ -2504,17 +2527,15 @@ server_no_wrap_sequence_number(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok),
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client),
- ok.
-
+ ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
-extended_key_usage(doc) ->
- ["Test cert that has a critical extended_key_usage extension"];
+extended_key_usage_verify_peer(doc) ->
+ ["Test cert that has a critical extended_key_usage extension in verify_peer mode"];
-extended_key_usage(suite) ->
+extended_key_usage_verify_peer(suite) ->
[];
-extended_key_usage(Config) when is_list(Config) ->
+extended_key_usage_verify_peer(Config) when is_list(Config) ->
ClientOpts = ?config(client_verification_opts, Config),
ServerOpts = ?config(server_verification_opts, Config),
PrivDir = ?config(priv_dir, Config),
@@ -2530,13 +2551,13 @@ extended_key_usage(Config) when is_list(Config) ->
ServerExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-serverAuth']},
ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate,
ServerExtensions = ServerOTPTbsCert#'OTPTBSCertificate'.extensions,
- NewServerOTPTbsCert = ServerOTPTbsCert#'OTPTBSCertificate'{extensions =
- [ServerExtKeyUsageExt |
+ NewServerOTPTbsCert = ServerOTPTbsCert#'OTPTBSCertificate'{extensions =
+ [ServerExtKeyUsageExt |
ServerExtensions]},
- NewServerDerCert = public_key:pkix_sign(NewServerOTPTbsCert, Key),
+ NewServerDerCert = public_key:pkix_sign(NewServerOTPTbsCert, Key),
ssl_test_lib:der_to_pem(NewServerCertFile, [{'Certificate', NewServerDerCert, not_encrypted}]),
NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
-
+
ClientCertFile = proplists:get_value(certfile, ClientOpts),
NewClientCertFile = filename:join(PrivDir, "client/new_cert.pem"),
[{'Certificate', ClientDerCert, _}] = ssl_test_lib:pem_to_der(ClientCertFile),
@@ -2544,28 +2565,90 @@ extended_key_usage(Config) when is_list(Config) ->
ClientExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-clientAuth']},
ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate,
ClientExtensions = ClientOTPTbsCert#'OTPTBSCertificate'.extensions,
- NewClientOTPTbsCert = ClientOTPTbsCert#'OTPTBSCertificate'{extensions =
+ NewClientOTPTbsCert = ClientOTPTbsCert#'OTPTBSCertificate'{extensions =
[ClientExtKeyUsageExt |
ClientExtensions]},
- NewClientDerCert = public_key:pkix_sign(NewClientOTPTbsCert, Key),
+ NewClientDerCert = public_key:pkix_sign(NewClientOTPTbsCert, Key),
ssl_test_lib:der_to_pem(NewClientCertFile, [{'Certificate', 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()},
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
{mfa, {?MODULE, send_recv_result_active, []}},
{options, [{verify, verify_peer} | NewServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
- Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
- {from, self()},
+ {from, self()},
{mfa, {?MODULE, send_recv_result_active, []}},
{options, [{verify, verify_peer} | NewClientOpts]}]),
-
+
ssl_test_lib:check_result(Server, ok, Client, ok),
-
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+extended_key_usage_verify_none(doc) ->
+ ["Test cert that has a critical extended_key_usage extension in verify_none mode"];
+
+extended_key_usage_verify_none(suite) ->
+ [];
+
+extended_key_usage_verify_none(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, "otpCA/private/key.pem"),
+ [KeyEntry] = ssl_test_lib:pem_to_der(KeyFile),
+ Key = public_key:pem_entry_decode(KeyEntry),
+
+ ServerCertFile = proplists:get_value(certfile, ServerOpts),
+ NewServerCertFile = filename:join(PrivDir, "server/new_cert.pem"),
+ [{'Certificate', ServerDerCert, _}] = ssl_test_lib:pem_to_der(ServerCertFile),
+ 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:pkix_sign(NewServerOTPTbsCert, Key),
+ ssl_test_lib:der_to_pem(NewServerCertFile, [{'Certificate', NewServerDerCert, not_encrypted}]),
+ NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
+
+ ClientCertFile = proplists:get_value(certfile, ClientOpts),
+ NewClientCertFile = filename:join(PrivDir, "client/new_cert.pem"),
+ [{'Certificate', ClientDerCert, _}] = ssl_test_lib:pem_to_der(ClientCertFile),
+ 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:pkix_sign(NewClientOTPTbsCert, Key),
+ ssl_test_lib:der_to_pem(NewClientCertFile, [{'Certificate', 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, [{verify, verify_none} | 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_none} | NewClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
@@ -2857,11 +2940,13 @@ unknown_server_ca_fail(Config) when is_list(Config) ->
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
- FunAndState = {fun(_,{bad_cert, _} = Reason, _) ->
+ FunAndState = {fun(_,{bad_cert, unknown_ca} = Reason, _) ->
{fail, Reason};
(_,{extension, _}, UserState) ->
{unknown, UserState};
(_, valid, UserState) ->
+ {valid, [test_to_update_user_state | UserState]};
+ (_, valid_peer, UserState) ->
{valid, UserState}
end, []},
@@ -2876,9 +2961,7 @@ unknown_server_ca_fail(Config) when is_list(Config) ->
| ClientOpts]}]),
ssl_test_lib:check_result(Server, {error,"unknown ca"},
- Client, {error, "unknown ca"}),
- ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
+ Client, {error, "unknown ca"}).
%%--------------------------------------------------------------------
unknown_server_ca_accept_verify_none(doc) ->
@@ -2930,6 +3013,8 @@ unknown_server_ca_accept_verify_peer(Config) when is_list(Config) ->
(_,{extension, _}, UserState) ->
{unknown, UserState};
(_, valid, UserState) ->
+ {valid, UserState};
+ (_, valid_peer, UserState) ->
{valid, UserState}
end, []},
@@ -2948,7 +3033,7 @@ unknown_server_ca_accept_verify_peer(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
unknown_server_ca_accept_backwardscompatibilty(doc) ->
- ["Test that the client succeds if the ca is unknown in verify_none mode"];
+ ["Test that old style verify_funs will work"];
unknown_server_ca_accept_backwardscompatibilty(suite) ->
[];
unknown_server_ca_accept_backwardscompatibilty(Config) when is_list(Config) ->
@@ -3041,6 +3126,199 @@ der_input_opts(Opts) ->
{Cert, {rsa, Key}, CaCerts, DHParams}.
%%--------------------------------------------------------------------
+%% different_ca_peer_sign(doc) ->
+%% ["Check that a CA can have a different signature algorithm than the peer cert."];
+
+%% different_ca_peer_sign(suite) ->
+%% [];
+
+%% different_ca_peer_sign(Config) when is_list(Config) ->
+%% ClientOpts = ?config(client_mix_opts, Config),
+%% ServerOpts = ?config(server_mix_verify_opts, Config),
+
+%% {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+%% Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+%% {from, self()},
+%% {mfa, {?MODULE, send_recv_result_active_once, []}},
+%% {options, [{active, once},
+%% {verify, verify_peer} | ServerOpts]}]),
+%% Port = ssl_test_lib:inet_port(Server),
+
+%% Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+%% {host, Hostname},
+%% {from, self()},
+%% {mfa, {?MODULE,
+%% send_recv_result_active_once,
+%% []}},
+%% {options, [{active, once},
+%% {verify, verify_peer}
+%% | ClientOpts]}]),
+
+%% ssl_test_lib:check_result(Server, ok, Client, ok),
+%% ssl_test_lib:close(Server),
+%% ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+no_reuses_session_server_restart_new_cert(doc) ->
+ ["Check that a session is not reused if the server is restarted with a new cert."];
+
+no_reuses_session_server_restart_new_cert(suite) ->
+ [];
+
+no_reuses_session_server_restart_new_cert(Config) when is_list(Config) ->
+
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ DsaServerOpts = ?config(server_dsa_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ %% Make sure session is registered
+ test_server:sleep(?SLEEP),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, DsaServerOpts}]),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ test_server:fail(session_reused_when_server_has_new_cert);
+ {Client1, _Other} ->
+ ok
+ end,
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client1).
+
+%%--------------------------------------------------------------------
+no_reuses_session_server_restart_new_cert_file(doc) ->
+ ["Check that a session is not reused if a server is restarted with a new "
+ "cert contained in a file with the same name as the old cert."];
+
+no_reuses_session_server_restart_new_cert_file(suite) ->
+ [];
+
+no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ DsaServerOpts = ?config(server_dsa_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ NewServerOpts = new_config(PrivDir, ServerOpts),
+ {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, NewServerOpts}]),
+ 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,
+
+ %% Make sure session is registered and we get
+ %% new file time stamp when calling new_config!
+ test_server:sleep(?SLEEP* 2),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+
+ NewServerOpts = new_config(PrivDir, DsaServerOpts),
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, NewServerOpts}]),
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ test_server:fail(session_reused_when_server_has_new_cert);
+ {Client1, _Other} ->
+ ok
+ end,
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client1).
+
+%%--------------------------------------------------------------------
+reuseaddr(doc) ->
+ [""];
+
+reuseaddr(suite) ->
+ [];
+
+reuseaddr(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+ test_server:sleep(?SLEEP),
+ ssl_test_lib:close(Server),
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server1, ok, Client1, ok),
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client1).
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
send_recv_result(Socket) ->
@@ -3065,7 +3343,6 @@ send_recv_result_active_once(Socket) ->
result_ok(_Socket) ->
ok.
-
renegotiate(Socket, Data) ->
test_server:format("Renegotiating ~n", []),
Result = ssl:renegotiate(Socket),
@@ -3082,7 +3359,27 @@ renegotiate_reuse_session(Socket, Data) ->
%% Make sure session is registerd
test_server:sleep(?SLEEP),
renegotiate(Socket, Data).
-
+
+new_config(PrivDir, ServerOpts0) ->
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts0),
+ CertFile = proplists:get_value(certfile, ServerOpts0),
+ KeyFile = proplists:get_value(keyfile, ServerOpts0),
+ NewCaCertFile = filename:join(PrivDir, "new_ca.pem"),
+ NewCertFile = filename:join(PrivDir, "new_cert.pem"),
+ NewKeyFile = filename:join(PrivDir, "new_key.pem"),
+ file:copy(CaCertFile, NewCaCertFile),
+ file:copy(CertFile, NewCertFile),
+ file:copy(KeyFile, NewKeyFile),
+ ServerOpts1 = proplists:delete(cacertfile, ServerOpts0),
+ ServerOpts2 = proplists:delete(certfile, ServerOpts1),
+ ServerOpts = proplists:delete(keyfile, ServerOpts2),
+
+ {ok, PEM} = file:read_file(NewCaCertFile),
+ test_server:format("CA file content: ~p~n", [public_key:pem_decode(PEM)]),
+
+ [{cacertfile, NewCaCertFile}, {certfile, NewCertFile},
+ {keyfile, NewKeyFile} | ServerOpts].
+
session_cache_process_list(doc) ->
["Test reuse of sessions (short handshake)"];
@@ -3099,7 +3396,7 @@ session_cache_process_mnesia(suite) ->
session_cache_process_mnesia(Config) when is_list(Config) ->
session_cache_process(mnesia,Config).
-session_cache_process(_Type,Config) when is_list(Config) ->
+session_cache_process(Type,Config) when is_list(Config) ->
reuse_session(Config).
init([Type]) ->
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
index 88d2d99ef8..1ecf55d6e8 100644
--- a/lib/ssl/test/ssl_packet_SUITE.erl
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,7 +23,7 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(BYTE(X), X:8/unsigned-big-integer).
-define(UINT16(X), X:16/unsigned-big-integer).
@@ -53,15 +53,18 @@
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- crypto:start(),
- application:start(public_key),
- ssl:start(),
- Result =
- (catch make_certs:all(?config(data_dir, Config),
- ?config(priv_dir, Config))),
- test_server:format("Make certs ~p~n", [Result]),
- ssl_test_lib:cert_options(Config).
-
+ case application:start(crypto) of
+ ok ->
+ application:start(public_key),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config))),
+ test_server:format("Make certs ~p~n", [Result]),
+ ssl_test_lib:cert_options(Config);
+ _ ->
+ {skip, "Crypto did not start"}
+ end.
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
%% Config - [tuple()]
@@ -70,7 +73,7 @@ init_per_suite(Config) ->
%%--------------------------------------------------------------------
end_per_suite(_Config) ->
ssl:stop(),
- crypto:stop().
+ application:stop(crypto).
%%--------------------------------------------------------------------
%% Function: init_per_testcase(TestCase, Config) -> Config
@@ -115,56 +118,56 @@ end_per_testcase(_TestCase, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test that erlang:decode_packet/3 seems to be handled correctly."
- "We only use the most basic packet types in our tests as testing of"
- "the packet types are for inet to verify"
- ];
-
-all(suite) ->
- [packet_raw_passive_many_small,
- packet_0_passive_many_small, packet_1_passive_many_small,
- packet_2_passive_many_small, packet_4_passive_many_small,
- packet_raw_passive_some_big, packet_0_passive_some_big,
- packet_1_passive_some_big,
- packet_2_passive_some_big, packet_4_passive_some_big,
- packet_raw_active_once_many_small,
- packet_0_active_once_many_small, packet_1_active_once_many_small,
- packet_2_active_once_many_small, packet_4_active_once_many_small,
- packet_raw_active_once_some_big,
- packet_0_active_once_some_big, packet_1_active_once_some_big,
- packet_2_active_once_some_big, packet_4_active_once_some_big,
- packet_raw_active_many_small, packet_0_active_many_small,
- packet_1_active_many_small,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [packet_raw_passive_many_small,
+ packet_0_passive_many_small,
+ packet_1_passive_many_small,
+ packet_2_passive_many_small,
+ packet_4_passive_many_small,
+ packet_raw_passive_some_big, packet_0_passive_some_big,
+ packet_1_passive_some_big, packet_2_passive_some_big,
+ packet_4_passive_some_big,
+ packet_raw_active_once_many_small,
+ packet_0_active_once_many_small,
+ packet_1_active_once_many_small,
+ packet_2_active_once_many_small,
+ packet_4_active_once_many_small,
+ packet_raw_active_once_some_big,
+ packet_0_active_once_some_big,
+ packet_1_active_once_some_big,
+ packet_2_active_once_some_big,
+ packet_4_active_once_some_big,
+ packet_raw_active_many_small,
+ packet_0_active_many_small, packet_1_active_many_small,
packet_2_active_many_small, packet_4_active_many_small,
- packet_raw_active_some_big, packet_0_active_some_big,
- packet_1_active_some_big, packet_2_active_some_big,
- packet_4_active_some_big,
- packet_send_to_large,
+ packet_raw_active_some_big, packet_0_active_some_big,
+ packet_1_active_some_big, packet_2_active_some_big,
+ packet_4_active_some_big, packet_send_to_large,
packet_wait_passive, packet_wait_active,
packet_baddata_passive, packet_baddata_active,
packet_size_passive, packet_size_active,
- packet_cdr_decode,
- packet_cdr_decode_list,
- packet_http_decode,
- packet_http_decode_list,
- packet_http_bin_decode_multi,
- packet_http_error_passive,
- packet_line_decode,
- packet_line_decode_list,
- packet_asn1_decode,
- packet_asn1_decode_list,
- packet_tpkt_decode,
- packet_tpkt_decode_list,
- %packet_fcgi_decode,
- packet_sunrm_decode,
- packet_sunrm_decode_list,
- header_decode_one_byte,
- header_decode_two_bytes,
+ packet_cdr_decode, packet_cdr_decode_list,
+ packet_http_decode, packet_http_decode_list,
+ packet_http_bin_decode_multi, packet_http_error_passive,
+ packet_line_decode, packet_line_decode_list,
+ packet_asn1_decode, packet_asn1_decode_list,
+ packet_tpkt_decode, packet_tpkt_decode_list,
+ packet_sunrm_decode, packet_sunrm_decode_list,
+ header_decode_one_byte, header_decode_two_bytes,
header_decode_two_bytes_one_sent,
- header_decode_two_bytes_two_sent
+ header_decode_two_bytes_two_sent].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
- ].
%% Test cases starts here.
%%--------------------------------------------------------------------
diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl
index d80df0bfbd..f57d7fa0e8 100644
--- a/lib/ssl/test/ssl_payload_SUITE.erl
+++ b/lib/ssl/test/ssl_payload_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,7 +22,7 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(TIMEOUT, 600000).
@@ -37,12 +37,15 @@
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- crypto:start(),
- application:start(public_key),
- ssl:start(),
- make_certs:all(?config(data_dir, Config), ?config(priv_dir, Config)),
- ssl_test_lib:cert_options(Config).
-
+ case application:start(crypto) of
+ ok ->
+ application:start(public_key),
+ ssl:start(),
+ make_certs:all(?config(data_dir, Config), ?config(priv_dir, Config)),
+ ssl_test_lib:cert_options(Config);
+ _ ->
+ {skip, "Crypto did not start"}
+ end.
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
%% Config - [tuple()]
@@ -51,7 +54,7 @@ init_per_suite(Config) ->
%%--------------------------------------------------------------------
end_per_suite(_Config) ->
ssl:stop(),
- crypto:stop().
+ application:stop(crypto).
%%--------------------------------------------------------------------
%% Function: init_per_testcase(TestCase, Config) -> Config
@@ -96,24 +99,30 @@ end_per_testcase(_TestCase, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test payload over ssl in all socket modes, active, active_once,"
- "and passive mode."];
-
-all(suite) ->
- [server_echos_passive_small, server_echos_active_once_small,
- server_echos_active_small,
- client_echos_passive_small, client_echos_active_once_small,
- client_echos_active_small,
- server_echos_passive_big, server_echos_active_once_big,
- server_echos_active_big,
- client_echos_passive_big, client_echos_active_once_big,
- client_echos_active_big,
- server_echos_passive_huge, server_echos_active_once_huge,
- server_echos_active_huge,
- client_echos_passive_huge, client_echos_active_once_huge,
- client_echos_active_huge
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [server_echos_passive_small,
+ server_echos_active_once_small,
+ server_echos_active_small, client_echos_passive_small,
+ client_echos_active_once_small,
+ client_echos_active_small, server_echos_passive_big,
+ server_echos_active_once_big, server_echos_active_big,
+ client_echos_passive_big, client_echos_active_once_big,
+ client_echos_active_big, server_echos_passive_huge,
+ server_echos_active_once_huge, server_echos_active_huge,
+ client_echos_passive_huge,
+ client_echos_active_once_huge, client_echos_active_huge].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Test cases starts here.
%%--------------------------------------------------------------------
diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl
new file mode 100644
index 0000000000..b47efe0941
--- /dev/null
+++ b/lib/ssl/test/ssl_session_cache_SUITE.erl
@@ -0,0 +1,317 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.2
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_session_cache_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-define(SLEEP, 500).
+-define(TIMEOUT, 60000).
+-define(LONG_TIMEOUT, 600000).
+-behaviour(ssl_session_cache_api).
+
+%% For the session cache tests
+-export([init/1, terminate/1, lookup/2, update/3,
+ delete/2, foldl/3, select_session/2]).
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initialization before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config0) ->
+ Dog = ssl_test_lib:timetrap(?LONG_TIMEOUT *2),
+ case application:start(crypto) of
+ ok ->
+ application:start(public_key),
+ ssl:start(),
+
+ %% make rsa certs using oppenssl
+ Result =
+ (catch make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0))),
+ test_server:format("Make certs ~p~n", [Result]),
+
+ Config1 = ssl_test_lib:make_dsa_cert(Config0),
+ Config = ssl_test_lib:cert_options(Config1),
+ [{watchdog, Dog} | Config];
+ _ ->
+ {skip, "Crypto did not start"}
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ssl:stop(),
+ application:stop(crypto).
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initialization before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initialization before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(session_cache_process_list, Config) ->
+ init_customized_session_cache(list, Config);
+
+init_per_testcase(session_cache_process_mnesia, Config) ->
+ mnesia:start(),
+ init_customized_session_cache(mnesia, Config);
+
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = test_server:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+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].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(session_cache_process_list, Config) ->
+ application:unset_env(ssl, session_cb),
+ end_per_testcase(default_action, Config);
+end_per_testcase(session_cache_process_mnesia, Config) ->
+ application:unset_env(ssl, session_cb),
+ application:unset_env(ssl, session_cb_init_args),
+ mnesia:kill(),
+ ssl:stop(),
+ ssl:start(),
+ end_per_testcase(default_action, Config);
+end_per_testcase(_TestCase, Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [session_cache_process_list,
+ session_cache_process_mnesia].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+session_cache_process_list(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+session_cache_process_list(suite) ->
+ [];
+session_cache_process_list(Config) when is_list(Config) ->
+ session_cache_process(list,Config).
+%%--------------------------------------------------------------------
+session_cache_process_mnesia(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+session_cache_process_mnesia(suite) ->
+ [];
+session_cache_process_mnesia(Config) when is_list(Config) ->
+ session_cache_process(mnesia,Config).
+
+
+%%--------------------------------------------------------------------
+%%% Session cache API callbacks
+%%--------------------------------------------------------------------
+
+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, []),
+ sess_cache
+ end.
+
+session_cb() ->
+ [{type, Type}] = ets:lookup(ssl_test, type),
+ Type.
+
+terminate(Cache) ->
+ case session_cb() of
+ list ->
+ Cache ! terminate;
+ mnesia ->
+ catch {atomic,ok} =
+ mnesia:delete_table(sess_cache)
+ end.
+
+lookup(Cache, Key) ->
+ case session_cb() of
+ list ->
+ Cache ! {self(), lookup, Key},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ case mnesia:transaction(fun() ->
+ mnesia:read(sess_cache,
+ Key, read)
+ end) of
+ {atomic, [{sess_cache, Key, Value}]} ->
+ Value;
+ _ ->
+ undefined
+ end
+ end.
+
+update(Cache, Key, Value) ->
+ case session_cb() of
+ list ->
+ Cache ! {update, Key, Value};
+ mnesia ->
+ {atomic, ok} =
+ mnesia:transaction(fun() ->
+ mnesia:write(sess_cache,
+ {sess_cache, Key, Value}, write)
+ end)
+ end.
+
+delete(Cache, Key) ->
+ case session_cb() of
+ list ->
+ Cache ! {delete, Key};
+ mnesia ->
+ {atomic, ok} =
+ mnesia:transaction(fun() ->
+ mnesia:delete(sess_cache, Key)
+ end)
+ end.
+
+foldl(Fun, Acc, Cache) ->
+ case session_cb() of
+ list ->
+ Cache ! {self(),foldl,Fun,Acc},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ Foldl = fun() ->
+ mnesia:foldl(Fun, Acc, sess_cache)
+ end,
+ {atomic, Res} = mnesia:transaction(Foldl),
+ Res
+ end.
+
+select_session(Cache, PartialKey) ->
+ case session_cb() of
+ list ->
+ Cache ! {self(),select_session, PartialKey},
+ receive
+ {Cache, Res} ->
+ Res
+ end;
+ mnesia ->
+ Sel = fun() ->
+ mnesia:select(Cache,
+ [{{sess_cache,{PartialKey,'$1'}, '$2'},
+ [],['$$']}])
+ end,
+ {atomic, Res} = mnesia:transaction(Sel),
+ Res
+ end.
+
+session_loop(Sess) ->
+ receive
+ terminate ->
+ ok;
+ {Pid, lookup, Key} ->
+ case lists:keysearch(Key,1,Sess) of
+ {value, {Key,Value}} ->
+ Pid ! {self(), Value};
+ _ ->
+ Pid ! {self(), undefined}
+ end,
+ session_loop(Sess);
+ {update, Key, Value} ->
+ NewSess = [{Key,Value}| lists:keydelete(Key,1,Sess)],
+ session_loop(NewSess);
+ {delete, Key} ->
+ session_loop(lists:keydelete(Key,1,Sess));
+ {Pid,foldl,Fun,Acc} ->
+ Res = lists:foldl(Fun, Acc,Sess),
+ Pid ! {self(), Res},
+ session_loop(Sess);
+ {Pid,select_session,PKey} ->
+ Sel = fun({{PKey0, Id},Session}, Acc) when PKey == PKey0 ->
+ [[Id, Session]|Acc];
+ (_,Acc) ->
+ Acc
+ end,
+ Sessions = lists:foldl(Sel, [], Sess),
+ Pid ! {self(), Sessions},
+ session_loop(Sess)
+ end.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+
+session_cache_process(_Type,Config) when is_list(Config) ->
+ ssl_basic_SUITE:reuse_session(Config).
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index ce164f7e4c..f6ccbe85e3 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -81,14 +81,20 @@ run_server(ListenSocket, Opts) ->
no_result_msg ->
ok;
Msg ->
- test_server:format("Msg: ~p ~n", [Msg]),
+ test_server:format("Server Msg: ~p ~n", [Msg]),
Pid ! {self(), Msg}
end,
- receive
+ receive
listen ->
run_server(ListenSocket, Opts);
+ {listen, MFA} ->
+ run_server(ListenSocket, [MFA | proplists:delete(mfa, Opts)]);
close ->
- ok = rpc:call(Node, ssl, close, [AcceptSocket])
+ test_server:format("Server closing ~p ~n", [self()]),
+ Result = rpc:call(Node, ssl, close, [AcceptSocket], 500),
+ test_server:format("Result ~p ~n", [Result]);
+ {ssl_closed, _} ->
+ ok
end.
%%% To enable to test with s_client -reconnect
@@ -151,19 +157,30 @@ run_client(Opts) ->
no_result_msg ->
ok;
Msg ->
+ test_server:format("Client Msg: ~p ~n", [Msg]),
Pid ! {self(), Msg}
end,
- receive
+ receive
close ->
- ok = rpc:call(Node, ssl, close, [Socket])
+ test_server:format("Client closing~n", []),
+ rpc:call(Node, ssl, close, [Socket]);
+ {ssl_closed, Socket} ->
+ ok
end;
{error, Reason} ->
- test_server:format("Client: connection failed: ~p ~n", [Reason]),
+ test_server:format("Client: connection failed: ~p ~n", [Reason]),
Pid ! {self(), {error, Reason}}
end.
close(Pid) ->
- Pid ! close.
+ test_server:format("Close ~p ~n", [Pid]),
+ Monitor = erlang:monitor(process, Pid),
+ Pid ! close,
+ receive
+ {'DOWN', Monitor, process, Pid, Reason} ->
+ erlang:demonitor(Monitor),
+ test_server:format("Pid: ~p down due to:~p ~n", [Pid, Reason])
+ end.
check_result(Server, ServerMsg, Client, ClientMsg) ->
receive
@@ -208,47 +225,27 @@ check_result(Pid, Msg) ->
test_server:fail(Reason)
end.
-check_result_ignore_renegotiation_reject(Pid, Msg) ->
- receive
- {Pid, fail_session_fatal_alert_during_renegotiation} ->
- test_server:comment("Server rejected old renegotiation"),
- ok;
- {ssl_error, _, esslconnect} ->
- test_server:comment("Server rejected old renegotiation"),
- ok;
- {Pid, Msg} ->
- ok;
- {Port, {data,Debug}} when is_port(Port) ->
- io:format("openssl ~s~n",[Debug]),
- check_result(Pid,Msg);
- Unexpected ->
- Reason = {{expected, {Pid, Msg}},
- {got, Unexpected}},
- test_server:fail(Reason)
- end.
-
-
wait_for_result(Server, ServerMsg, Client, ClientMsg) ->
receive
{Server, ServerMsg} ->
receive
{Client, ClientMsg} ->
- ok;
- Unexpected ->
- Unexpected
+ ok
+ %% Unexpected ->
+ %% Unexpected
end;
{Client, ClientMsg} ->
receive
{Server, ServerMsg} ->
- ok;
- Unexpected ->
- Unexpected
+ ok
+ %% Unexpected ->
+ %% Unexpected
end;
{Port, {data,Debug}} when is_port(Port) ->
io:format("openssl ~s~n",[Debug]),
- wait_for_result(Server, ServerMsg, Client, ClientMsg);
- Unexpected ->
- Unexpected
+ wait_for_result(Server, ServerMsg, Client, ClientMsg)
+ %% Unexpected ->
+ %% Unexpected
end.
@@ -258,9 +255,9 @@ wait_for_result(Pid, Msg) ->
ok;
{Port, {data,Debug}} when is_port(Port) ->
io:format("openssl ~s~n",[Debug]),
- wait_for_result(Pid,Msg);
- Unexpected ->
- Unexpected
+ wait_for_result(Pid,Msg)
+ %% Unexpected ->
+ %% Unexpected
end.
cert_options(Config) ->
@@ -300,6 +297,7 @@ cert_options(Config) ->
{ssl_imp, new}]},
{server_opts, [{ssl_imp, new},{reuseaddr, true},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
+ {server_anon, [{ssl_imp, new},{reuseaddr, true}, {ciphers, anonymous_suites()}]},
{server_verification_opts, [{ssl_imp, new},{reuseaddr, true},
{cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
@@ -326,8 +324,8 @@ cert_options(Config) ->
make_dsa_cert(Config) ->
- {ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_dsa_cert_files("server", Config),
- {ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_dsa_cert_files("client", Config),
+ {ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_cert_files("server", Config, dsa, dsa, ""),
+ {ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_cert_files("client", Config, dsa, dsa, ""),
[{server_dsa_opts, [{ssl_imp, new},{reuseaddr, true},
{cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
@@ -341,22 +339,41 @@ make_dsa_cert(Config) ->
| Config].
-
-make_dsa_cert_files(RoleStr, Config) ->
- CaInfo = {CaCert, _} = erl_make_certs:make_cert([{key, dsa}]),
- {Cert, CertKey} = erl_make_certs:make_cert([{key, dsa}, {issuer, CaInfo}]),
+make_mix_cert(Config) ->
+ {ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_cert_files("server", Config, dsa,
+ rsa, "mix"),
+ {ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_cert_files("client", Config, dsa,
+ rsa, "mix"),
+ [{server_mix_opts, [{ssl_imp, new},{reuseaddr, true},
+ {cacertfile, ServerCaCertFile},
+ {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
+ {server_mix_verify_opts, [{ssl_imp, new},{reuseaddr, true},
+ {cacertfile, ClientCaCertFile},
+ {certfile, ServerCertFile}, {keyfile, ServerKeyFile},
+ {verify, verify_peer}]},
+ {client_mix_opts, [{ssl_imp, new},{reuseaddr, true},
+ {cacertfile, ClientCaCertFile},
+ {certfile, ClientCertFile}, {keyfile, ClientKeyFile}]}
+ | Config].
+
+make_cert_files(RoleStr, Config, Alg1, Alg2, Prefix) ->
+ Alg1Str = atom_to_list(Alg1),
+ Alg2Str = atom_to_list(Alg2),
+ CaInfo = {CaCert, _} = erl_make_certs:make_cert([{key, Alg1}]),
+ {Cert, CertKey} = erl_make_certs:make_cert([{key, Alg2}, {issuer, CaInfo}]),
CaCertFile = filename:join([?config(priv_dir, Config),
- RoleStr, "dsa_cacerts.pem"]),
+ RoleStr, Prefix ++ Alg1Str ++ "_cacerts.pem"]),
CertFile = filename:join([?config(priv_dir, Config),
- RoleStr, "dsa_cert.pem"]),
+ RoleStr, Prefix ++ Alg2Str ++ "_cert.pem"]),
KeyFile = filename:join([?config(priv_dir, Config),
- RoleStr, "dsa_key.pem"]),
+ RoleStr, Prefix ++ Alg2Str ++ "_key.pem"]),
der_to_pem(CaCertFile, [{'Certificate', CaCert, not_encrypted}]),
der_to_pem(CertFile, [{'Certificate', Cert, not_encrypted}]),
der_to_pem(KeyFile, [CertKey]),
{CaCertFile, CertFile, KeyFile}.
+
start_upgrade_server(Args) ->
Result = spawn_link(?MODULE, run_upgrade_server, [Args]),
receive
@@ -394,10 +411,12 @@ run_upgrade_server(Opts) ->
end,
{Module, Function, Args} = proplists:get_value(mfa, Opts),
Msg = rpc:call(Node, Module, Function, [SslAcceptSocket | Args]),
+ test_server:format("Upgrade Server Msg: ~p ~n", [Msg]),
Pid ! {self(), Msg},
receive
close ->
- ok = rpc:call(Node, ssl, close, [SslAcceptSocket])
+ test_server:format("Upgrade Server closing~n", []),
+ rpc:call(Node, ssl, close, [SslAcceptSocket])
end
catch error:{badmatch, Error} ->
Pid ! {self(), Error}
@@ -427,10 +446,12 @@ run_upgrade_client(Opts) ->
test_server:format("apply(~p, ~p, ~p)~n",
[Module, Function, [SslSocket | Args]]),
Msg = rpc:call(Node, Module, Function, [SslSocket | Args]),
+ test_server:format("Upgrade Client Msg: ~p ~n", [Msg]),
Pid ! {self(), Msg},
receive
close ->
- ok = rpc:call(Node, ssl, close, [SslSocket])
+ test_server:format("Upgrade Client closing~n", []),
+ rpc:call(Node, ssl, close, [SslSocket])
end.
start_upgrade_server_error(Args) ->
@@ -616,6 +637,13 @@ openssl_dsa_suites() ->
end
end, Ciphers).
+anonymous_suites() ->
+ [{dh_anon, rc4_128, md5},
+ {dh_anon, des_cbc, sha},
+ {dh_anon, '3des_ede_cbc', sha},
+ {dh_anon, aes_128_cbc, sha},
+ {dh_anon, aes_256_cbc, sha}].
+
pem_to_der(File) ->
{ok, PemBin} = file:read_file(File),
public_key:pem_decode(PemBin).
@@ -633,7 +661,7 @@ cipher_result(Socket, Result) ->
receive
{ssl, Socket, "Hello\n"} ->
ssl:send(Socket, " world\n"),
- receive
+ receive
{ssl, Socket, " world\n"} ->
ok
end;
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
index 7f512f2ab9..4ab8fe3273 100644
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -24,9 +24,10 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-define(TIMEOUT, 120000).
+-define(LONG_TIMEOUT, 600000).
-define(SLEEP, 1000).
-define(OPENSSL_RENEGOTIATE, "r\n").
-define(OPENSSL_QUIT, "Q\n").
@@ -44,21 +45,25 @@
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config0) ->
- Dog = ssl_test_lib:timetrap(?TIMEOUT *2),
+ Dog = ssl_test_lib:timetrap(?LONG_TIMEOUT *2),
case os:find_executable("openssl") of
false ->
{skip, "Openssl not found"};
_ ->
- crypto:start(),
- application:start(public_key),
- ssl:start(),
- Result =
- (catch make_certs:all(?config(data_dir, Config0),
- ?config(priv_dir, Config0))),
- test_server:format("Make certs ~p~n", [Result]),
- Config1 = ssl_test_lib:make_dsa_cert(Config0),
- Config = ssl_test_lib:cert_options(Config1),
- [{watchdog, Dog} | Config]
+ case application:start(crypto) of
+ ok ->
+ application:start(public_key),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config0),
+ ?config(priv_dir, Config0))),
+ test_server:format("Make certs ~p~n", [Result]),
+ Config1 = ssl_test_lib:make_dsa_cert(Config0),
+ Config = ssl_test_lib:cert_options(Config1),
+ [{watchdog, Dog} | Config];
+ _ ->
+ {skip, "Crypto did not start"}
+ end
end.
%%--------------------------------------------------------------------
@@ -69,7 +74,7 @@ init_per_suite(Config0) ->
%%--------------------------------------------------------------------
end_per_suite(_Config) ->
ssl:stop(),
- crypto:stop().
+ application:stop(crypto).
%%--------------------------------------------------------------------
%% Function: init_per_testcase(TestCase, Config) -> Config
@@ -138,11 +143,10 @@ end_per_testcase(_, Config) ->
%% Name of a test case.
%% Description: Returns a list of all test cases in this test suite
%%--------------------------------------------------------------------
-all(doc) ->
- ["Test erlangs ssl against openssl"];
+suite() -> [{ct_hooks,[ts_install_cth]}].
-all(suite) ->
- [erlang_client_openssl_server,
+all() ->
+ [erlang_client_openssl_server,
erlang_server_openssl_client,
tls1_erlang_client_openssl_server_dsa_cert,
tls1_erlang_server_openssl_client_dsa_cert,
@@ -153,22 +157,29 @@ all(suite) ->
erlang_client_openssl_server_no_wrap_sequence_number,
erlang_server_openssl_client_no_wrap_sequence_number,
erlang_client_openssl_server_no_server_ca_cert,
- ssl3_erlang_client_openssl_server,
+ ssl3_erlang_client_openssl_server,
ssl3_erlang_server_openssl_client,
ssl3_erlang_client_openssl_server_client_cert,
ssl3_erlang_server_openssl_client_client_cert,
ssl3_erlang_server_erlang_client_client_cert,
- tls1_erlang_client_openssl_server,
+ tls1_erlang_client_openssl_server,
tls1_erlang_server_openssl_client,
tls1_erlang_client_openssl_server_client_cert,
tls1_erlang_server_openssl_client_client_cert,
tls1_erlang_server_erlang_client_client_cert,
- ciphers_rsa_signed_certs,
- ciphers_dsa_signed_certs,
- erlang_client_bad_openssl_server,
- expired_session,
- ssl2_erlang_server_openssl_client
- ].
+ ciphers_rsa_signed_certs, ciphers_dsa_signed_certs,
+ erlang_client_bad_openssl_server, expired_session,
+ ssl2_erlang_server_openssl_client].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% Test cases starts here.
%%--------------------------------------------------------------------
@@ -1116,8 +1127,6 @@ run_suites(Ciphers, Version, Config, Type) ->
test_server:fail(cipher_suite_failed_see_test_case_log)
end.
-
-
cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
process_flag(trap_exit, true),
test_server:format("Testing CipherSuite ~p~n", [CipherSuite]),
@@ -1128,8 +1137,8 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
KeyFile = proplists:get_value(keyfile, ServerOpts),
Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
- " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "",
-
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "",
+
test_server:format("openssl cmd: ~p~n", [Cmd]),
OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
@@ -1140,11 +1149,11 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
{host, Hostname},
- {from, self()},
- {mfa, {ssl_test_lib, cipher_result, [ConnectionInfo]}},
- {options,
- [{ciphers,[CipherSuite]} |
- ClientOpts]}]),
+ {from, self()},
+ {mfa, {ssl_test_lib, cipher_result, [ConnectionInfo]}},
+ {options,
+ [{ciphers,[CipherSuite]} |
+ ClientOpts]}]),
port_command(OpenSslPort, "Hello\n"),
@@ -1165,10 +1174,6 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) ->
close_port(OpenSslPort),
%% Clean close down!
ssl_test_lib:close(Client),
- receive
- {'EXIT', Client, normal} ->
- ok
- end,
Return = case Result of
ok ->
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index 709a089892..a4be7bb889 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1 +1,2 @@
-SSL_VSN = 4.0.1
+
+SSL_VSN = 4.1.3
diff --git a/lib/stdlib/doc/src/calendar.xml b/lib/stdlib/doc/src/calendar.xml
index 36f0c03162..f90d8308b6 100644
--- a/lib/stdlib/doc/src/calendar.xml
+++ b/lib/stdlib/doc/src/calendar.xml
@@ -63,6 +63,14 @@
given as local time, they must be converted to universal time, in
order to get the correct value of the elapsed time between epochs.
Use of the function <c>time_difference/2</c> is discouraged.</p>
+ <p>There exists different definitions for the week of the year.
+ The calendar module contains a week of the year implementation
+ which conforms to the ISO 8601 standard. Since the week number for
+ a given date can fall on the previous, the current or on the next
+ year it is important to provide the information which year is it
+ together with the week number. The function <c>iso_week_number/0</c>
+ and <c>iso_week_number/1</c> returns a tuple of the year and the
+ week number.</p>
</description>
<section>
@@ -154,6 +162,30 @@ time() = {Hour, Minute, Second}
</desc>
</func>
<func>
+ <name>iso_week_number() -> IsoWeekNumber</name>
+ <fsummary>Compute the iso week number for the actual date</fsummary>
+ <type>
+ <v>IsoWeekNumber = {int(), int()}</v>
+ </type>
+ <desc>
+ <p>This function returns the tuple {Year, WeekNum} representing
+ the iso week number for the actual date. For determining the
+ actual date, the function <c>local_time/0</c> is used.</p>
+ </desc>
+ </func>
+ <func>
+ <name>iso_week_number(Date) -> IsoWeekNumber</name>
+ <fsummary>Compute the iso week number for the given date</fsummary>
+ <type>
+ <v>Date = date()</v>
+ <v>IsoWeekNumber = {int(), int()}</v>
+ </type>
+ <desc>
+ <p>This function returns the tuple {Year, WeekNum} representing
+ the iso week number for the given date.</p>
+ </desc>
+ </func>
+ <func>
<name>last_day_of_the_month(Year, Month) -> int()</name>
<fsummary>Compute the number of days in a month</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/dets.xml b/lib/stdlib/doc/src/dets.xml
index ad100d2cf5..b002af6616 100644
--- a/lib/stdlib/doc/src/dets.xml
+++ b/lib/stdlib/doc/src/dets.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>
@@ -816,7 +816,7 @@ ok
</item>
<item>
<p><c>{max_no_slots, no_slots()}</c>, the maximum number
- of slots that will be used. The default value is 2 M, and
+ of slots that will be used. The default value as well as
the maximal value is 32 M. Note that a higher value may
increase the fragmentation of the table, and conversely,
that a smaller value may decrease the fragmentation, at
diff --git a/lib/stdlib/doc/src/dict.xml b/lib/stdlib/doc/src/dict.xml
index ebcd2eed09..1695e9d14f 100644
--- a/lib/stdlib/doc/src/dict.xml
+++ b/lib/stdlib/doc/src/dict.xml
@@ -165,8 +165,8 @@ dictionary()
<v>Dict = dictionary()</v>
</type>
<desc>
- <p>This function converts the key/value list <c>List</c> to a
- dictionary.</p>
+ <p>This function converts the <c>Key</c> - <c>Value</c> list
+ <c>List</c> to a dictionary.</p>
</desc>
</func>
<func>
@@ -270,7 +270,7 @@ merge(Fun, D1, D2) ->
<v>Dict1 = Dict2 = dictionary()</v>
</type>
<desc>
- <p>Update the a value in a dictionary by calling <c>Fun</c> on
+ <p>Update a value in a dictionary by calling <c>Fun</c> on
the value to get a new value. An exception is generated if
<c>Key</c> is not present in the dictionary.</p>
</desc>
@@ -285,7 +285,7 @@ merge(Fun, D1, D2) ->
<v>Dict1 = Dict2 = dictionary()</v>
</type>
<desc>
- <p>Update the a value in a dictionary by calling <c>Fun</c> on
+ <p>Update a value in a dictionary by calling <c>Fun</c> on
the value to get a new value. If <c>Key</c> is not present
in the dictionary then <c>Initial</c> will be stored as
the first value. For example <c>append/3</c> could be defined
diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml
index dd4a289c61..746f94d3f4 100644
--- a/lib/stdlib/doc/src/ets.xml
+++ b/lib/stdlib/doc/src/ets.xml
@@ -56,8 +56,8 @@
Even if there are no references to a table from any process, it
will not automatically be destroyed unless the owner process
terminates. It can be destroyed explicitly by using
- <c>delete/1</c>.</p>
- <p>Since R13B01, table ownership can be transferred at process termination
+ <c>delete/1</c>. The default owner is the process that created the
+ table. Table ownership can be transferred at process termination
by using the <seealso marker="#heir">heir</seealso> option or explicitly
by calling <seealso marker="#give_away/3">give_away/3</seealso>.</p>
<p>Some implementation details:</p>
@@ -82,11 +82,15 @@
<c>float()</c> that extends to the same value, hence the key
<c>1</c> and the key <c>1.0</c> are regarded as equal in an
<c>ordered_set</c> table.</p>
- <p>In general, the functions below will exit with reason
- <c>badarg</c> if any argument is of the wrong format, or if the
- table identifier is invalid.</p>
</description>
-
+ <section>
+ <title>Failure</title>
+ <p>In general, the functions below will exit with reason
+ <c>badarg</c> if any argument is of the wrong format, if the
+ table identifier is invalid or if the operation is denied due to
+ table access rights (<seealso marker="#protected">protected</seealso>
+ or <seealso marker="#private">private</seealso>).</p>
+ </section>
<section><marker id="concurrency"></marker>
<title>Concurrency</title>
<p>This module provides some limited support for concurrent access.
@@ -481,6 +485,9 @@ Error: fun containing local Erlang function calls
<item><c>Item=protection, Value=public|protected|private</c> <br></br>
The table access rights.</item>
+ <item><c>Item=compressed, Value=true|false</c> <br></br>
+
+ Indicates if the table is compressed or not.</item>
</list>
</desc>
</func>
@@ -947,9 +954,10 @@ ets:select(Table,MatchSpec),</code>
<type>
<v>Name = atom()</v>
<v>Options = [Option]</v>
- <v>&nbsp;Option = Type | Access | named_table | {keypos,Pos} | {heir,pid(),HeirData} | {heir,none} | {write_concurrency,bool()}</v>
+ <v>&nbsp;Option = Type | Access | named_table | {keypos,Pos} | {heir,pid(),HeirData} | {heir,none} | Tweaks</v>
<v>&nbsp;&nbsp;Type = set | ordered_set | bag | duplicate_bag</v>
<v>&nbsp;&nbsp;Access = public | protected | private</v>
+ <v>&nbsp;&nbsp;Tweaks = {write_concurrency,bool()} | {read_concurrency,bool()} | compressed</v>
<v>&nbsp;&nbsp;Pos = int()</v>
<v>&nbsp;&nbsp;HeirData = term()</v>
</type>
@@ -963,7 +971,7 @@ ets:select(Table,MatchSpec),</code>
table is named or not. If one or more options are left out,
the default values are used. This means that not specifying
any options (<c>[]</c>) is the same as specifying
- <c>[set,protected,{keypos,1},{heir,none},{write_concurrency,false}]</c>.</p>
+ <c>[set,protected,{keypos,1},{heir,none},{write_concurrency,false},{read_concurrency,false}]</c>.</p>
<list type="bulleted">
<item>
<p><c>set</c>
@@ -1002,12 +1010,14 @@ ets:select(Table,MatchSpec),</code>
Any process may read or write to the table.</p>
</item>
<item>
+ <marker id="protected"></marker>
<p><c>protected</c>
The owner process can read and write to the table. Other
processes can only read the table. This is the default
setting for the access rights.</p>
</item>
<item>
+ <marker id="private"></marker>
<p><c>private</c>
Only the owner process can read or write to the table.</p>
</item>
@@ -1041,13 +1051,13 @@ ets:select(Table,MatchSpec),</code>
<item>
<marker id="new_2_write_concurrency"></marker>
<p><c>{write_concurrency,bool()}</c>
- Performance tuning. Default is <c>false</c>. An operation that
+ Performance tuning. Default is <c>false</c>, in which case an operation that
mutates (writes to) the table will obtain exclusive access,
blocking any concurrent access of the same table until finished.
If set to <c>true</c>, the table is optimized towards concurrent
write access. Different objects of the same table can be mutated
(and read) by concurrent processes. This is achieved to some degree
- at the expense of single access and concurrent reader performance.
+ at the expense of sequential access and concurrent reader performance.
The <c>write_concurrency</c> option can be combined with the
<seealso marker="#new_2_read_concurrency">read_concurrency</seealso>
option. You typically want to combine these when large concurrent
@@ -1085,6 +1095,15 @@ ets:select(Table,MatchSpec),</code>
option. You typically want to combine these when large concurrent
read bursts and large concurrent write bursts are common.</p>
</item>
+ <item>
+ <marker id="new_2_compressed"></marker>
+ <p><c>compressed</c>
+ If this option is present, the table data will be stored in a more compact format to
+ consume less memory. The downside is that it will make table operations slower.
+ Especially operations that need to inspect entire objects,
+ such as <c>match</c> and <c>select</c>, will get much slower. The key element
+ is not compressed in current implementation.</p>
+ </item>
</list>
</desc>
</func>
diff --git a/lib/stdlib/doc/src/filelib.xml b/lib/stdlib/doc/src/filelib.xml
index c1c4ca9350..47d64f245c 100644
--- a/lib/stdlib/doc/src/filelib.xml
+++ b/lib/stdlib/doc/src/filelib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -36,14 +36,23 @@
<description>
<p>This module contains utilities on a higher level than the <c>file</c>
module.</p>
+ <p>The module supports Unicode file names, so that it will match against regular expressions given in Unicode and that it will find and process raw file names (i.e. files named in a way that does not confirm to the expected encoding).</p>
+ <p>If the VM operates in Unicode file naming mode on a machine with transparent file naming, the <c>fun()</c> provided to <c>fold_files/5</c> needs to be prepared to handle binary file names.</p>
+ <p>For more information about raw file names, see the <seealso marker="kernel:file">file</seealso> module.</p>
</description>
<section>
<title>DATA TYPES</title>
<code type="none">
-filename() = string() | atom() | DeepList
-dirname() = filename()
-DeepList = [char() | atom() | DeepList]</code>
+filename() = = string() | atom() | DeepList | RawFilename
+ DeepList = [char() | atom() | DeepList]
+ RawFilename = binary()
+ If VM is in unicode filename mode, string() and char() are allowed to be > 255.
+ RawFilename is a filename not subject to Unicode translation, meaning that it
+ can contain characters not conforming to the Unicode encoding expected from the
+ filesystem (i.e. non-UTF-8 characters although the VM is started in Unicode
+ filename mode).
+dirname() = filename()</code>
</section>
<funcs>
@@ -90,6 +99,18 @@ DeepList = [char() | atom() | DeepList]</code>
If <c>Recursive</c> is true all sub-directories to <c>Dir</c>
are processed. The regular expression matching is done on just
the filename without the directory part.</p>
+
+ <p>If Unicode file name translation is in effect and the file
+ system is completely transparent, file names that cannot be
+ interpreted as Unicode may be encountered, in which case the
+ <c>fun()</c> must be prepared to handle raw file names
+ (i.e. binaries). If the regular expression contains
+ codepoints beyond 255, it will not match file names that do
+ not conform to the expected character encoding (i.e. are not
+ encoded in valid UTF-8).</p>
+
+ <p>For more information about raw file names, see the
+ <seealso marker="kernel:file">file</seealso> module.</p>
</desc>
</func>
<func>
@@ -160,6 +181,12 @@ DeepList = [char() | atom() | DeepList]</code>
<p>Matches any number of characters up to the end of
the filename, the next dot, or the next slash.</p>
</item>
+ <tag>[Character1,Character2,...]</tag>
+ <item>
+ <p>Matches any of the characters listed. Two characters
+ separated by a hyphen will match a range of characters.
+ Example: <c>[A-Z]</c> will match any uppercase letter.</p>
+ </item>
<tag>{Item,...}</tag>
<item>
<p>Alternation. Matches one of the alternatives.</p>
diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml
index fe6c6f898e..cdee6e4a81 100644
--- a/lib/stdlib/doc/src/filename.xml
+++ b/lib/stdlib/doc/src/filename.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -43,13 +43,22 @@
only, even if the arguments contain back slashes. Use
<c>join/1</c> to normalize a file name by removing redundant
directory separators.</p>
+ <p>The module supports raw file names in the way that if a binary is present, or the file name cannot be interpreted according to the return value of
+ <seealso marker="kernel:file#native_name_encoding/0">file:native_name_encoding/0</seealso>, a raw file name will also be returned. For example filename:join/1 provided with a path component being a binary (and also not being possible to interpret under the current native file name encoding) will result in a raw file name being returned (the join operation will have been performed of course). For more information about raw file names, see the <seealso marker="kernel:file">file</seealso> module.</p>
</description>
<section>
<title>DATA TYPES</title>
<code type="none">
-name() = string() | atom() | DeepList
-DeepList = [char() | atom() | DeepList]</code>
+name() = string() | atom() | DeepList | RawFilename
+ DeepList = [char() | atom() | DeepList]
+ RawFilename = binary()
+ If VM is in unicode filename mode, string() and char() are allowed to be > 255.
+ RawFilename is a filename not subject to Unicode translation, meaning that it
+ can contain characters not conforming to the Unicode encoding expected from the
+ filesystem (i.e. non-UTF-8 characters although the VM is started in Unicode
+ filename mode).
+ </code>
</section>
<funcs>
<func>
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index 6c618bc798..a8fe41f000 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -30,6 +30,144 @@
</header>
<p>This document describes the changes made to the STDLIB application.</p>
+<section><title>STDLIB 1.17.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Several type specifications for standard libraries were
+ wrong in the R14B01 release. This is now corrected. The
+ corrections concern types in re,io,filename and the
+ module erlang itself.</p>
+ <p>
+ Own Id: OTP-9008</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>STDLIB 1.17.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> When several clients accessed a Dets table
+ simultaneously, one of them calling
+ <c>dets:insert_new/2</c>, the Dets server could crash.
+ Alternatively, under the same conditions, <c>ok</c> was
+ sometimes returned instead of <c>true</c>. (Thanks to
+ John Hughes.) </p>
+ <p>
+ Own Id: OTP-8856</p>
+ </item>
+ <item>
+ <p> When several clients accessed a Dets table
+ simultaneously, inserted or updated objects were
+ sometimes lost due to the Dets file being truncated.
+ (Thanks to John Hughes.) </p>
+ <p>
+ Own Id: OTP-8898</p>
+ </item>
+ <item>
+ <p> When several clients accessed a Dets table
+ simultaneously, modifications of the Dets server's
+ internal state were sometimes thrown away. The symptoms
+ are diverse: error with reason <c>bad_object</c>;
+ inserted objects not returned by <c>lookup()</c>; et
+ cetera. (Thanks to John Hughes.) </p>
+ <p>
+ Own Id: OTP-8899</p>
+ </item>
+ <item>
+ <p> If a Dets table was closed after calling
+ <c>bchunk/2</c>, <c>match/1,3</c>,
+ <c>match_object/1,3</c>, or <c>select/1,3</c> and then
+ opened again, a subsequent call using the returned
+ continuation would normally return a reply. This bug has
+ fixed; now the call fails with reason <c>badarg</c>. </p>
+ <p>
+ Own Id: OTP-8903</p>
+ </item>
+ <item>
+ <p> Cover did not collect coverage data for files such as
+ Yecc parses containing include directives. The bug has
+ been fixed by modifying <c>epp</c>, the Erlang Code
+ Preprocessor. </p>
+ <p>
+ Own Id: OTP-8911</p>
+ </item>
+ <item>
+ <p> If a Dets table with fewer slots than keys was opened
+ and then closed after just a lookup, the contents were no
+ longer well-formed. This bug has been fixed. (Thanks to
+ Matthew Evans.) </p>
+ <p>
+ Own Id: OTP-8923</p>
+ </item>
+ <item>
+ <p>
+ In a supervisor, when it terminates a child, if that
+ child happens to have exited fractionally early, with
+ normal, the supervisor reports this as an error. This
+ should not be reported as an error.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8938 Aux Id: seq11615 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The documentation filelib:wildcard/1,2 now describes the
+ character set syntax for wildcards.</p>
+ <p>
+ Own Id: OTP-8879 Aux Id: seq11683 </p>
+ </item>
+ <item>
+ <p>Buffer overflows have been prevented in <c>erlc</c>,
+ <c>dialyzer</c>, <c>typer</c>, <c>run_test</c>,
+ <c>heart</c>, <c>escript</c>, and <c>erlexec</c>.</p>
+ (Thanks to Michael Santos.)
+ <p>
+ Own Id: OTP-8892</p>
+ </item>
+ <item>
+ <p>
+ Using a float for the number of copies for
+ <c>string:copies/2</c> resulted in an infinite loop. Now
+ it will fail with an exception instead. (Thanks to
+ Michael Santos.)</p>
+ <p>
+ Own Id: OTP-8915</p>
+ </item>
+ <item>
+ <p>
+ New ETS option <c>compressed</c>, to enable a more
+ compact storage format at the expence of heavier table
+ operations. For test and evaluation, <c>erl +ec</c> can
+ be used to force compression on all ETS tables.</p>
+ <p>
+ Own Id: OTP-8922 Aux Id: seq11658 </p>
+ </item>
+ <item>
+ <p> The default maximum number of slots of a Dets table
+ has been changed as to be equal to the maximum number of
+ slots. (Thanks to Richard Carlsson.) </p>
+ <p>
+ Own Id: OTP-8959</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>STDLIB 1.17.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/stdlib/doc/src/orddict.xml b/lib/stdlib/doc/src/orddict.xml
index 08c808f822..9d036f0725 100644
--- a/lib/stdlib/doc/src/orddict.xml
+++ b/lib/stdlib/doc/src/orddict.xml
@@ -172,8 +172,8 @@ ordered_dictionary()
<v>Orddict = ordered_dictionary()</v>
</type>
<desc>
- <p>This function converts the key/value list <c>List</c> to a
- dictionary.</p>
+ <p>This function converts the <c>Key</c> - <c>Value</c> list
+ <c>List</c> to a dictionary.</p>
</desc>
</func>
<func>
@@ -277,7 +277,7 @@ merge(Fun, D1, D2) ->
<v>Orddict1 = Orddict2 = ordered_dictionary()</v>
</type>
<desc>
- <p>Update the a value in a dictionary by calling <c>Fun</c> on
+ <p>Update a value in a dictionary by calling <c>Fun</c> on
the value to get a new value. An exception is generated if
<c>Key</c> is not present in the dictionary.</p>
</desc>
@@ -292,7 +292,7 @@ merge(Fun, D1, D2) ->
<v>Orddict1 = Orddict2 = ordered_dictionary()</v>
</type>
<desc>
- <p>Update the a value in a dictionary by calling <c>Fun</c> on
+ <p>Update a value in a dictionary by calling <c>Fun</c> on
the value to get a new value. If <c>Key</c> is not present
in the dictionary then <c>Initial</c> will be stored as
the first value. For example <c>append/3</c> could be defined
diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml
index 80adc3e347..056e7bc9b9 100644
--- a/lib/stdlib/doc/src/re.xml
+++ b/lib/stdlib/doc/src/re.xml
@@ -37,29 +37,24 @@
<modulesummary>Perl like regular expressions for Erlang</modulesummary>
<description>
- <p>This module contains functions for regular expression
- matching for strings and binaries.</p>
+ <p>This module contains regular expression matching functions for
+ strings and binaries.</p>
<p>The regular expression syntax and semantics resemble that of
- Perl. This library in many ways replaces the old regexp library
- written purely in Erlang, as it has a richer syntax as well as
- many more options. The library is also faster than the
- older regexp implementation.</p>
-
- <p>Although the library's matching algorithms are currently based
- on the PCRE library, it is not to be viewed as an Erlang to PCRE
- mapping. Only parts of the PCRE library is interfaced and the re
- library in some ways extend PCRE. The PCRE documentation contains
- many parts of no interest to the Erlang programmer, why only the
- relevant part of the documentation is included here. There should
- bee no need to go directly to the PCRE library documentation.</p>
+ Perl. This library replaces the deprecated pure-Erlang regexp
+ library; it has a richer syntax, more options and is faster.</p>
+
+ <p>The library's matching algorithms are currently based on the
+ PCRE library, but not all of the PCRE library is interfaced and
+ some parts of the library go beyond what PCRE offers. The sections of
+ the PCRE documentation which are relevant to this module are included
+ here.</p>
<note>
- <p>The Erlang literal syntax for strings give special
- meaning to the &quot;\&quot; (backslash) character. To literally write
- a regular expression or a replacement string containing a
- backslash in your code or in the shell, two backslashes have to be written:
- &quot;\\&quot;.</p>
+ <p>The Erlang literal syntax for strings uses the &quot;\&quot;
+ (backslash) character as an escape code. You need to escape
+ backslashes in literal strings, both in your code and in the shell,
+ with an additional backslash, i.e.: &quot;\\&quot;.</p>
</note>
@@ -72,7 +67,7 @@
- a binary is allowed as the tail of the list</code>
<code type="none">
unicode_binary() = binary() with characters encoded in UTF-8 coding standard
- unicode_char() = integer() representing valid unicode codepoint
+ unicode_char() = integer() representing a valid unicode codepoint
chardata() = charlist() | unicode_binary()
@@ -82,9 +77,9 @@
<code type="none">
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
+ 're_pattern' as its 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>
+ may change in future releases.</code>
</section>
<funcs>
<func>
@@ -132,7 +127,7 @@
<tag><c>dollar_endonly</c></tag>
<item>A dollar metacharacter in the pattern matches only at the end of the subject string. Without this option, a dollar also matches immediately before a newline at the end of the string (but not before any other newlines). The <c>dollar_endonly</c> option is ignored if <c>multiline</c> is given. There is no equivalent option in Perl, and no way to set it within a pattern.</item>
<tag><c>dotall</c></tag>
- <item>A dot maturate in the pattern matches all characters, including those that indicate newline. Without it, a dot does not match when the current position is at a newline. This option is equivalent to Perl's /s option, and it can be changed within a pattern by a (?s) option setting. A negative class such as [^a] always matches newline characters, independent of the setting of this option.</item>
+ <item>A dot in the pattern matches all characters, including those that indicate newline. Without it, a dot does not match when the current position is at a newline. This option is equivalent to Perl's /s option, and it can be changed within a pattern by a (?s) option setting. A negative class such as [^a] always matches newline characters, independent of this option's setting.</item>
<tag><c>extended</c></tag>
<item>Whitespace data characters in the pattern are ignored except when escaped or inside a character class. Whitespace does not include the VT character (ASCII 11). In addition, characters between an unescaped # outside a character class and the next newline, inclusive, are also ignored. This is equivalent to Perl's /x option, and it can be changed within a pattern by a (?x) option setting.
@@ -214,9 +209,10 @@ This option makes it possible to include comments inside complicated patterns. N
or as a pre compiled <c>mp()</c> in which case it is executed
against the subject directly.</p>
- <p>When compilation is involved, the exception <c>badarg</c> is thrown if
- a compilation error occurs. To locate the error in the regular
- expression, use the function <c>re:compile/2</c> to get more information.</p>
+ <p>When compilation is involved, the exception <c>badarg</c> is
+ thrown if a compilation error occurs. Call <c>re:compile/2</c>
+ to get information about the location of the error in the
+ regular expression.</p>
<p>If the regular expression is previously compiled, the option
list can only contain the options <c>anchored</c>,
@@ -246,7 +242,7 @@ This option makes it possible to include comments inside complicated patterns. N
how captured substrings are to be returned (as index tuples,
lists or binaries). The <c>capture</c> option makes the function
quite flexible and powerful. The different options are described
- in detail below</p>
+ in detail below.</p>
<p>If the capture options describe that no substring capturing
at all is to be done (<c>{capture, none}</c>), the function will
@@ -256,7 +252,7 @@ This option makes it possible to include comments inside complicated patterns. N
be done either by specifying <c>none</c> or an empty list as
<c>ValueSpec</c>.</p>
- <p>A description of all the options relevant for execution follows:</p>
+ <p>The options relevant for execution are:</p>
<taglist>
<tag><c>anchored</c></tag>
@@ -270,27 +266,25 @@ This option makes it possible to include comments inside complicated patterns. N
<tag><c>global</c></tag>
<item>
- <p>Implements global (repetitive) search as the <c>g</c> flag in
- i.e. Perl. Each match found is returned as a separate
+ <p>Implements global (repetitive) search (the <c>g</c> flag in
+ Perl). Each match is returned as a separate
<c>list()</c> containing the specific match as well as any
matching subexpressions (or as specified by the <c>capture
option</c>). The <c>Captured</c> part of the return value will
- hence be a <c>list()</c> of <c>list()</c>'s when this
+ hence be a <c>list()</c> of <c>list()</c>s when this
option is given.</p>
- <p>When the regular expression matches an empty string, the
- behaviour might seem non-intuitive, why the behaviour requites
- some clarifying. With the global option, <c>re:run/3</c>
- handles empty matches in the same way as Perl, meaning that a
- match at any point giving an empty string (with length 0) will
- be retried with the options
- <c>[anchored, notempty]</c> as well. If that
- search gives a result of length &gt; 0, the result is included.
- An example:</p>
+ <p>The interaction of the global option with a regular
+ expression which matches an empty string surprises some users.
+ When the global option is given, <c>re:run/3</c> handles empty
+ matches in the same way as Perl: a zero-length match at any
+ point will be retried with the options <c>[anchored,
+ notempty]</c> as well. If that search gives a result of length
+ &gt; 0, the result is included. For example:</p>
<code> re:run("cat","(|at)",[global]).</code>
- <p>The matching will be performed as following:</p>
+ <p>The following matching will be performed:</p>
<taglist>
<tag>At offset <c>0</c></tag>
<item>The regexp <c>(|at)</c> will first match at the initial
@@ -302,11 +296,11 @@ This option makes it possible to include comments inside complicated patterns. N
<item> The search is retried
with the options <c>[anchored, notempty]</c> at the same
position, which does not give any interesting result of longer
- length, why the search position is now advanced to the next
+ length, so the search position is now advanced to the next
character (<c>a</c>).</item>
<tag>At offset <c>1</c></tag>
- <item>Now the search results in
- <c>[{1,0},{1,0}]</c> meaning this search will also be repeated
+ <item>This time, the search results in
+ <c>[{1,0},{1,0}]</c>, so this search will also be repeated
with the extra options.</item>
<tag>At offset <c>1</c> with <c>[anchored, notempty]</c></tag>
<item>Now the <c>ab</c> alternative
@@ -333,16 +327,17 @@ This option makes it possible to include comments inside complicated patterns. N
entire match fails. For example, if the pattern</p>
<code> a?b?</code>
<p>is applied to a string not beginning with "a" or "b", it
- matches the empty string at the start of the subject. With
- <c>notempty</c> given, this match is not valid, so re:run/3 searches
- further into the string for occurrences of "a" or "b".</p>
+ would normally match the empty string at the start of the
+ subject. With the <c>notempty</c> option, this match is not
+ valid, so re:run/3 searches further into the string for
+ occurrences of "a" or "b".</p>
<p>Perl has no direct equivalent of <c>notempty</c>, but it does
make a special case of a pattern match of the empty string
within its split() function, and when using the /g modifier. It
is possible to emulate Perl's behavior after matching a null
string by first trying the match again at the same offset with
- <c>notempty</c> and <c>anchored</c>, and then if that fails by
+ <c>notempty</c> and <c>anchored</c>, and then, if that fails, by
advancing the starting offset (see below) and trying an ordinary
match again.</p>
</item>
@@ -352,7 +347,7 @@ This option makes it possible to include comments inside complicated patterns. N
string is not the beginning of a line, so the circumflex
metacharacter should not match before it. Setting this without
<c>multiline</c> (at compile time) causes circumflex never to
- match. This option affects only the behavior of the circumflex
+ match. This option only affects the behavior of the circumflex
metacharacter. It does not affect \A.</item>
<tag><c>noteol</c></tag>
@@ -388,7 +383,7 @@ This option makes it possible to include comments inside complicated patterns. N
</taglist>
</item>
<tag><c>bsr_anycrlf</c></tag>
- <item>Specifies specifically that \R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters.(overrides compilation option)</item>
+ <item>Specifies specifically that \R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters. (overrides compilation option)</item>
<tag><c>bsr_unicode</c></tag>
<item>Specifies specifically that \R is to match all the Unicode newline characters (including crlf etc, the default).(overrides compilation option)</item>
@@ -444,7 +439,7 @@ This option makes it possible to include comments inside complicated patterns. N
<tag><c>none</c></tag>
<item>Do not return matching subpatterns at all, yielding the single atom <c>match</c> as the return value of the function when matching successfully instead of the <c>{match, list()}</c> return. Specifying an empty list gives the same behavior.</item>
</taglist>
- <p>The value list is a list of indexes for the subpatterns to return, where index 0 is for all of the pattern, and 1 is for the first explicit capturing subpattern in the regular expression, and so forth. When using named captured subpatterns (see below) in the regular expression, one can use <c>atom()</c>'s or <c>string()</c>'s to specify the subpatterns to be returned. This deserves an example, consider the following regular expression:</p>
+ <p>The value list is a list of indexes for the subpatterns to return, where index 0 is for all of the pattern, and 1 is for the first explicit capturing subpattern in the regular expression, and so forth. When using named captured subpatterns (see below) in the regular expression, one can use <c>atom()</c>s or <c>string()</c>s to specify the subpatterns to be returned. For example, consider the regular expression:</p>
<code> ".*(abcd).*"</code>
<p>matched against the string ""ABCabcdABC", capturing only the "abcd" part (the first explicit subpattern):</p>
<code> re:run("ABCabcdABC",".*(abcd).*",[{capture,[1]}]).</code>
@@ -455,7 +450,7 @@ This option makes it possible to include comments inside complicated patterns. N
<code> ".*(?&lt;FOO&gt;abcd).*"</code>
<p>With this expression, we could still give the index of the subpattern with the following call:</p>
<code> re:run("ABCabcdABC",".*(?&lt;FOO&gt;abcd).*",[{capture,[1]}]).</code>
- <p>giving the same result as before. But as the subpattern is named, we can also give its name in the value list:</p>
+ <p>giving the same result as before. But, since the subpattern is named, we can also specify its name in the value list:</p>
<code> re:run("ABCabcdABC",".*(?&lt;FOO&gt;abcd).*",[{capture,['FOO']}]).</code>
<p>which would yield the same result as the earlier examples, namely:</p>
<code> {match,[{3,4}]}</code>
@@ -473,15 +468,15 @@ This option makes it possible to include comments inside complicated patterns. N
<item><p>Optionally specifies how captured substrings are to be returned. If omitted, the default of <c>index</c> is used. The <c>Type</c> can be one of the following:</p>
<taglist>
<tag><c>index</c></tag>
- <item>Return captured substrings as pairs of byte indexes into the subject string and length of the matching string in the subject (as if the subject string was flattened with <c>iolist_to_binary/1</c> or <c>unicode:characters_to_binary/2</c> prior to matching). Note that the <c>unicode</c> option results in <em>byte-oriented</em> indexes in a (possibly imagined) <em>UTF-8 encoded</em> binary. A byte index tuple <c>{0,2}</c> might therefore represent one or two characters when <c>unicode</c> is in effect. This might seem contra-intuitive, but has been deemed the most effective and useful way to way to do it. To return lists instead might result in simpler code if that is desired. This return type is the default.</item>
+ <item>Return captured substrings as pairs of byte indexes into the subject string and length of the matching string in the subject (as if the subject string was flattened with <c>iolist_to_binary/1</c> or <c>unicode:characters_to_binary/2</c> prior to matching). Note that the <c>unicode</c> option results in <em>byte-oriented</em> indexes in a (possibly virtual) <em>UTF-8 encoded</em> binary. A byte index tuple <c>{0,2}</c> might therefore represent one or two characters when <c>unicode</c> is in effect. This might seem counter-intuitive, but has been deemed the most effective and useful way to way to do it. To return lists instead might result in simpler code if that is desired. This return type is the default.</item>
<tag><c>list</c></tag>
- <item>Return matching substrings as lists of characters (Erlang <c>string()</c>'s). It the <c>unicode</c> option is used in combination with the \C sequence in the regular expression, a captured subpattern can contain bytes that has is not valid UTF-8 (\C matches bytes regardless of character encoding). In that case the <c>list</c> capturing may result in the same types of tuples that <c>unicode:characters_to_list/2</c> can return, namely three-tuples with the tag <c>incomplete</c> or <c>error</c>, the successfully converted characters and the invalid UTF-8 tail of the conversion as a binary. The best strategy is to avoid using the \C sequence when capturing lists.</item>
+ <item>Return matching substrings as lists of characters (Erlang <c>string()</c>s). It the <c>unicode</c> option is used in combination with the \C sequence in the regular expression, a captured subpattern can contain bytes that are not valid UTF-8 (\C matches bytes regardless of character encoding). In that case the <c>list</c> capturing may result in the same types of tuples that <c>unicode:characters_to_list/2</c> can return, namely three-tuples with the tag <c>incomplete</c> or <c>error</c>, the successfully converted characters and the invalid UTF-8 tail of the conversion as a binary. The best strategy is to avoid using the \C sequence when capturing lists.</item>
<tag><c>binary</c></tag>
- <item>Return matching substrings as binaries. If the <c>unicode</c> option is used, these binaries is in UTF-8. If the \C sequence is used together with <c>unicode</c> the binaries may be invalid UTF-8.</item>
+ <item>Return matching substrings as binaries. If the <c>unicode</c> option is used, these binaries are in UTF-8. If the \C sequence is used together with <c>unicode</c> the binaries may be invalid UTF-8.</item>
</taglist>
</item>
</taglist>
- <p>In general, subpatterns that got assigned no value in the match are returned as the tuple <c>{-1,0}</c> when <c>type</c> is <c>index</c>. Unassigned subpatterns are returned as the empty binary or list respectively for other return types. Consider the regular expression:</p>
+ <p>In general, subpatterns that were not assigned a value in the match are returned as the tuple <c>{-1,0}</c> when <c>type</c> is <c>index</c>. Unassigned subpatterns are returned as the empty binary or list, respectively, for other return types. Consider the regular expression:</p>
<code> ".*((?&lt;FOO&gt;abdd)|a(..d)).*"</code>
<p>There are three explicitly capturing subpatterns, where the opening parenthesis position determines the order in the result, hence <c>((?&lt;FOO&gt;abdd)|a(..d))</c> is subpattern index 1, <c>(?&lt;FOO&gt;abdd)</c> is subpattern index 2 and <c>(..d)</c> is subpattern index 3. When matched against the following string:</p>
<code> "ABCabcdABC"</code>
@@ -533,8 +528,8 @@ This option makes it possible to include comments inside complicated patterns. N
<v>NLSpec = cr | crlf | lf | anycrlf | any </v>
</type>
<desc>
- <p>Replaces the matched part of the <c>Subject</c> string with the content of <c>Replacement</c>.</p>
- <p>Options are given as to the <c>re:run/3</c> function except that the <c>capture</c> option of <c>re:run/3</c> is not allowed.
+ <p>Replaces the matched part of the <c>Subject</c> string with the contents of <c>Replacement</c>.</p>
+ <p>The permissible options are the same as for <c>re:run/3</c>, except that the <c>capture</c> option is not allowed.
Instead a <c>{return, ReturnType}</c> is present. The default return type is <c>iodata</c>, constructed in a
way to minimize copying. The <c>iodata</c> result can be used directly in many i/o-operations. If a flat <c>list()</c> is
desired, specify <c>{return, list}</c> and if a binary is preferred, specify <c>{return, binary}</c>.</p>
@@ -544,7 +539,7 @@ This option makes it possible to include comments inside complicated patterns. N
a Unicode <c>charlist()</c>. If compilation is done implicitly
and the <c>unicode</c> compilation option is given to this
function, both the regular expression and the <c>Subject</c>
- should be given as valid Unicode <c>charlist()</c>'s.</p>
+ should be given as valid Unicode <c>charlist()</c>s.</p>
<p>The replacement string can contain the special character
<c>&amp;</c>, which inserts the whole matching expression in the
@@ -554,7 +549,7 @@ This option makes it possible to include comments inside complicated patterns. N
generated by the regular expression, nothing is inserted.</p>
<p>To insert an <c>&amp;</c> or <c>\</c> in the result, precede it
with a <c>\</c>. Note that Erlang already gives a special
- meaning to <c>\</c> in literal strings, why a single <c>\</c>
+ meaning to <c>\</c> in literal strings, so a single <c>\</c>
has to be written as <c>"\\"</c> and therefore a double <c>\</c>
as <c>"\\\\"</c>. Example:</p>
<code> re:replace("abcd","c","[&amp;]",[{return,list}]).</code>
@@ -611,7 +606,7 @@ This option makes it possible to include comments inside complicated patterns. N
a Unicode <c>charlist()</c>. If compilation is done implicitly
and the <c>unicode</c> compilation option is given to this
function, both the regular expression and the <c>Subject</c>
- should be given as valid Unicode <c>charlist()</c>'s.</p>
+ should be given as valid Unicode <c>charlist()</c>s.</p>
<p>The result is given as a list of &quot;strings&quot;, the
preferred datatype given in the <c>return</c> option (default iodata).</p>
@@ -656,25 +651,25 @@ This option makes it possible to include comments inside complicated patterns. N
<p>Here the regular expression matched first the &quot;l&quot;,
causing &quot;Er&quot; to be the first part in the result. When
the regular expression matched, the (only) subexpression was
- bound to the &quot;l&quot;, why the &quot;l&quot; is inserted
+ bound to the &quot;l&quot;, so the &quot;l&quot; is inserted
in the group together with &quot;Er&quot;. The next match is of
the &quot;n&quot;, making &quot;a&quot; the next part to be
- returned. As the subexpression is bound to the substring
+ returned. Since the subexpression is bound to the substring
&quot;n&quot; in this case, the &quot;n&quot; is inserted into
this group. The last group consists of the rest of the string,
as no more matches are found.</p>
<p>By default, all parts of the string, including the empty
- strings are returned from the function. As an example:</p>
+ strings, are returned from the function. For example:</p>
<code> re:split("Erlang","[lg]",[{return,list}]).</code>
- <p>The result will be:</p>
+ <p>will return:</p>
<code> ["Er","an",[]]</code>
- <p>as the matching of the &quot;g&quot; in the end of the string
+ <p>since the matching of the &quot;g&quot; in the end of the string
leaves an empty rest which is also returned. This behaviour
differs from the default behaviour of the split function in
Perl, where empty strings at the end are by default removed. To
@@ -701,10 +696,10 @@ This option makes it possible to include comments inside complicated patterns. N
<p>Note that the last part is &quot;ang&quot;, not
&quot;an&quot;, as we only specified splitting into two parts,
- and the splitting stops when enough parts are given, why the
- result differs from that of <c>trim</c>.</p>
+ and the splitting stops when enough parts are given, which is
+ why the result differs from that of <c>trim</c>.</p>
- <p>More than three parts are not possible with this indata, why</p>
+ <p>More than three parts are not possible with this indata, so</p>
<code> re:split("Erlang","[lg]",[{return,list},{parts,4}]).</code>
@@ -745,7 +740,7 @@ This option makes it possible to include comments inside complicated patterns. N
the parts of the string matching the subexpressions of the
regexp.</p>
<p>The return value from the function will in this case be a
- <c>list()</c> of <c>list()</c>'s. Each sublist begins with the
+ <c>list()</c> of <c>list()</c>s. Each sublist begins with the
string picked out of the subject string, followed by the parts
matching each of the subexpressions in order of occurrence in the
regular expression.</p>
@@ -782,10 +777,8 @@ This option makes it possible to include comments inside complicated patterns. N
<title>PERL LIKE REGULAR EXPRESSIONS SYNTAX</title>
<p>The following sections contain reference material for the
regular expressions used by this module. The regular expression
- reference is taken from the PCRE documentation, but converted as
- needed.</p>
- <p>The documentation is altered where appropriate and where the re
- module behaves differently than the PCRE library.</p>
+ reference is based on the PCRE documentation, with changes in
+ cases where the re module behaves differently to the PCRE library.</p>
</section>
<section><title>PCRE regular expression details</title>
diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml
index f1b0659ea2..416df1f02c 100644
--- a/lib/stdlib/doc/src/unicode_usage.xml
+++ b/lib/stdlib/doc/src/unicode_usage.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1999</year>
- <year>2009</year>
+ <year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -168,6 +168,48 @@ Eshell V5.7 (abort with ^G)
<image file="ushell2.gif"><icaption>Unicode characters in allowed and disallowed context</icaption></image>
</section>
<section>
+<title>Unicode file names</title>
+<p>Most modern operating systems support Unicode file names in some way or another. There are several different ways to do this and Erlang by default treats the different approaches differently:</p>
+<taglist>
+<tag>Mandatory Unicode file naming</tag>
+<item>
+<p>Windows and, for most common uses, MacOSX enforces Unicode support for file names. All files created in the filesystem have names that can consistently be interpreted. In MacOSX, all file names are retrieved in UTF-8 encoding, while Windows has selected an approach where each system call handling file names has a special Unicode aware variant, giving much the same effect. There are no file names on these systems that are not Unicode file names, why the default behavior of the Erlang VM is to work in &quot;Unicode file name translation mode&quot;, meaning that a file name can be given as a Unicode list and that will be automatically translated to the proper name encoding for the underlying operating and file system.</p>
+<p>Doing i.e. a <c>file:list_dir/1</c> on one of these systems may return Unicode lists with codepoints beyond 255, depending on the content of the actual filesystem.</p>
+<p>As the feature is fairly new, you may still stumble upon non core applications that cannot handle being provided with file names containing characters with codepoints larger than 255, but the core Erlang system should have no problems with Unicode file names.</p>
+</item>
+<tag>Transparent file naming</tag>
+<item>
+<p>Most Unix operating systems have adopted a simpler approach, namely that Unicode file naming is not enforced, but by convention. Those systems usually use UTF-8 encoding for Unicode file names, but do not enforce it. On such a system, a file name containing characters having codepoints between 128 and 255 may be named either as plain ISO-latin-1 or using UTF-8 encoding. As no consistency is enforced, the Erlang VM can do no consistent translation of all file names. If the VM would automatically select encoding based on heuristics, one could get unexpected behavior on these systems, therefore file names not being encoded in UTF-8 are returned as &quot;raw file names&quot; if Unicode file naming support is turned on.</p>
+<p>A raw file name is not a list, but a binary. Many non core applications still do not handle file names given as binaries, why such raw names are avoided by default. This means that systems having implemented Unicode file naming through transparent file systems and an UTF-8 convention, do not by default have Unicode file naming turned on. Explicitly turning Unicode file name handling on for these types of systems is considered experimental.</p>
+</item>
+</taglist>
+<p>The Unicode file naming support was introduced with OTP release R14B01. A VM operating in Unicode file mode can work with files having names in any language or character set (as long as it's supported by the underlying OS and file system). The Unicode character list is used to denote file or directory names and if the file system content is listed, you will also be able to get Unicode lists as return value. The support lies in the kernel and stdlib modules, why most applications (that does not explicitly require the file names to be in the ISO-latin-1 range) will benefit from the Unicode support without change.</p>
+
+<p>On Operating systems with mandatory Unicode file names, this means that you more easily conform to the file names of other (non Erlang) applications, and you can also process file names that, at least on Windows, were completely inaccessible (due to having names that could not be represented in ISO-latin-1). Also you will avoid creating incomprehensible file names on MacOSX as the vfs layer of the OS will accept all your file names as UTF-8 and will not rewrite them.</p>
+
+<p>For most systems, turning on Unicode file name translation is no problem even if it uses transparent file naming. Very few systems have mixed file name encodings. A consistent UTF-8 named system will work perfectly in Unicode file name mode. It is still however considered experimental in R14B01. Unicode file name translation is turned on with the <c>+fnu</c> switch to the <c>erl</c> program. If the VM is started in Unicode file name translation mode, <c>file:native_name_encoding/0</c> will return the atom <c>utf8</c>.</p>
+
+<p>In Unicode file name mode, file names given to the BIF <c>open_port/2</c> with the option <c>{spawn_executable,...}</c> are also interpreted as Unicode. So is the parameter list given in the <c>args</c> option available when using <c>spawn_executable</c>. The UTF-8 translation of arguments can be avoided using binaries, see the discussion about raw file names below.</p>
+
+<p>It is worth noting that the file <c>encoding</c> options given when opening a file has nothing to do with the file <em>name</em> encoding convention. You can very well open files containing UTF-8 but having file names in ISO-latin-1 or vice versa.</p>
+
+<note>Erlang drivers and NIF shared objects still can not be named with names containing codepoints beyond 127. This is a known limitation to be removed in a future release. Erlang modules however can, but it is definitely not a good idea and is still considered experimental.</note>
+
+<section>
+<title>Notes about raw file names and automatic file name conversion</title>
+<p>Raw file names is introduced together with Unicode file name support in erts-5.8.2 (OTP R14B01). The reason &quot;raw file names&quot; is introduced in the system is to be able to consistently represent file names given in different encodings on the same system. Having the VM automatically translate a file name that is not in UTF-8 to a list of Unicode characters might seem practical, but this would open up for both duplicate file names and other inconsistent behavior. Consider a directory containing a file named &quot;bj�rn&quot; in ISO-latin-1, while the Erlang VM is operating in Unicode file name mode (and therefore expecting UTF-8 file naming). The ISO-latin-1 name is not valid UTF-8 and one could be tempted to think that automatic conversion in for example <c>file:list_dir/1</c> is a good idea. But what would happen if we later tried to open the file and have the name as a Unicode list (magically converted from the ISO-latin-1 file name)? The VM will convert the file name given to UTF-8, as this is the encoding expected. Effectively this means trying to open the file named &lt;&lt;&quot;bj�rn&quot;/utf8&gt;&gt;. This file does not exist, and even if it existed it would not be the same file as the one that was listed. We could even create two files named &quot;bj�rn&quot;, one named in the UTF-8 encoding and one not. If <c>file:list_dir/1</c> would automatically convert the ISO-latin-1 file name to a list, we would get two identical file names as the result. To avoid this, we need to differentiate between file names being properly encoded according to the Unicode file naming convention (i.e. UTF-8) and file names being invalid under the encoding. This is done by representing invalid encoding as &quot;raw&quot; file names, i.e. as binaries.</p>
+<p>The core system of Erlang (kernel and stdlib) accepts raw file names except for loadable drivers and executables invoked using <c>open_port({spawn, ...} ...)</c>. <c>open_port({spawn_executable, ...} ...)</c> however does accept them. As mentioned earlier, the arguments given in the option list to <c>open_port({spawn_executable, ...} ...)</c> undergo the same conversion as the file names, meaning that the executable will be provided with arguments in UTF-8 as well. This translation is avoided consistently with how the file names are treated, by giving the argument as a binary.</p>
+<p>To force Unicode file name translation mode on systems where this is not the default is considered experimental in OTP R14B01 due to the raw file names possibly being a new experience to the programmer and that the non core applications of OTP are not tested for compliance with raw file names yet. Unicode file name translation is expected to be default in future releases.</p>
+<p>If working with raw file names, one can still conform to the encoding convention of the Erlang VM by using the <c>file:native_name_encoding/0</c> function, which returns either the atom <c>latin1</c> or the atom <c>utf8</c> depending on the file name translation mode. On Linux, a VM started without explicitly stating the file name translation mode will default to <c>latin1</c> as the native file name encoding, why file names on the disk encoded as UTF-8 will be returned as a list of the names interpreted as ISO-latin-1. The &quot;UTF-8 list&quot; is not a practical type for displaying or operating on in Erlang, but it is backward compatible and usable in all functions requiring a file name. On Windows and MacOSX, the default behavior is that of file name translation, why the <c>file:native_name_encoding/0</c> by default returns <c>utf8</c> on those systems (the fact that Windows actually does not use UTF-8 on the file system level can safely be ignored by the Erlang programmer). The default behavior can be changed using the <c>+fnu</c> or <c>+fnl</c> options to the VM, see the <c>erl</c> command manual page.</p>
+<p>Even if you are operating without Unicode file naming translation automatically done by the VM, you can access and create files with names in UTF-8 encoding by using raw file names encoded as UTF-8. Enforcing the UTF-8 encoding regardless of the mode the Erlang VM is started in might, in some circumstances be a good idea, as the convention of using UTF-8 file names is spreading.</p>
+</section>
+<section>
+<title>Notes about MacOSX</title>
+<p>MacOSXs vfs layer enforces UTF-8 file names in a quite aggressive way. Older versions did this by simply refusing to create non UTF-8 conforming file names, while newer versions replace offending bytes with the sequence &quot;%HH&quot;, where HH is the original character in hexadecimal notation. As Unicode translation is enabled by default on MacOSX, the only way to come up against this is to either start the VM with the <c>+fnl</c> flag or to use a raw file name in <c>latin1</c> encoding. In that case, the file can not be opened with the same name as the one used to create this. The problem is by design in newer versions of MacOSX.</p>
+<p>MacOSX also reorganizes the names of files so that the representation of accents etc is denormalized, i.e. the character <c>�</c> is represented as the codepoints [111,776], where 111 is the character <c>o</c> and 776 is a special accent character. This type of denormalized Unicode is otherwise very seldom used and Erlang normalizes those file names on retrieval, so that denormalized file names is not passed up to the Erlang application. In Erlang the file name &quot;bj�rn&quot; is retrieved as [98,106,246,114,110], not as [98,106,117,776,114,110], even though the file system might think differently.</p>
+</section>
+</section>
+<section>
<title>Unicode-aware modules</title>
<p>Most of the modules in Erlang/OTP are of course Unicode-unaware in the sense that they have no notion of Unicode and really shouldn't have. Typically they handle non-textual or byte-oriented data (like <c>gen_tcp</c> etc).</p>
<p>Modules that actually handle textual data (like <c>io_lib</c>, <c>string</c> etc) are sometimes subject to conversion or extension to be able to handle Unicode characters.</p>
diff --git a/lib/stdlib/src/base64.erl b/lib/stdlib/src/base64.erl
index ebef998ee1..a14a72ac6d 100644
--- a/lib/stdlib/src/base64.erl
+++ b/lib/stdlib/src/base64.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -114,7 +114,7 @@ decode(List) when is_list(List) ->
mime_decode(Bin) when is_binary(Bin) ->
mime_decode_binary(<<>>, Bin);
mime_decode(List) when is_list(List) ->
- list_to_binary(mime_decode_l(List)).
+ mime_decode(list_to_binary(List)).
-spec decode_l(string()) -> string().
@@ -125,7 +125,7 @@ decode_l(List) ->
-spec mime_decode_l(string()) -> string().
mime_decode_l(List) ->
- L = strip_illegal(List, []),
+ L = strip_illegal(List, [], 0),
decode(L, []).
%%-------------------------------------------------------------------------
@@ -198,6 +198,9 @@ decode_binary(Result, <<>>) ->
true = is_binary(Result),
Result.
+%% Skipping pad character if not at end of string. Also liberal about
+%% excess padding and skipping of other illegal (non-base64 alphabet)
+%% characters. See section 3.3 of RFC4648
mime_decode_binary(Result, <<0:8,T/bits>>) ->
mime_decode_binary(Result, T);
mime_decode_binary(Result0, <<C:8,T/bits>>) ->
@@ -205,15 +208,27 @@ mime_decode_binary(Result0, <<C:8,T/bits>>) ->
Bits when is_integer(Bits) ->
mime_decode_binary(<<Result0/bits,Bits:6>>, T);
eq ->
- case tail_contains_equal(T) of
- true ->
- Split = byte_size(Result0) - 1,
- <<Result:Split/bytes,_:4>> = Result0,
- Result;
- false ->
- Split = byte_size(Result0) - 1,
- <<Result:Split/bytes,_:2>> = Result0,
- Result
+ case tail_contains_more(T, false) of
+ {<<>>, Eq} ->
+ %% No more valid data.
+ case bit_size(Result0) rem 8 of
+ 0 ->
+ %% '====' is not uncommon.
+ Result0;
+ 4 when Eq ->
+ %% enforce at least one more '=' only ignoring illegals and spacing
+ Split = byte_size(Result0) - 1,
+ <<Result:Split/bytes,_:4>> = Result0,
+ Result;
+ 2 ->
+ %% remove 2 bits
+ Split = byte_size(Result0) - 1,
+ <<Result:Split/bytes,_:2>> = Result0,
+ Result
+ end;
+ {More, _} ->
+ %% More valid data, skip the eq as invalid
+ mime_decode_binary(Result0, More)
end;
_ ->
mime_decode_binary(Result0, T)
@@ -262,31 +277,63 @@ strip_ws(<<$\s,T/binary>>) ->
strip_ws(T);
strip_ws(T) -> T.
-strip_illegal([0|Cs], A) ->
- strip_illegal(Cs, A);
-strip_illegal([C|Cs], A) ->
+%% Skipping pad character if not at end of string. Also liberal about
+%% excess padding and skipping of other illegal (non-base64 alphabet)
+%% characters. See section 3.3 of RFC4648
+strip_illegal([], A, _Cnt) ->
+ A;
+strip_illegal([0|Cs], A, Cnt) ->
+ strip_illegal(Cs, A, Cnt);
+strip_illegal([C|Cs], A, Cnt) ->
case element(C, ?DECODE_MAP) of
- bad -> strip_illegal(Cs, A);
- ws -> strip_illegal(Cs, A);
- eq -> strip_illegal_end(Cs, [$=|A]);
- _ -> strip_illegal(Cs, [C|A])
- end;
-strip_illegal([], A) -> A.
+ bad ->
+ strip_illegal(Cs, A, Cnt);
+ ws ->
+ strip_illegal(Cs, A, Cnt);
+ eq ->
+ case {tail_contains_more(Cs, false), Cnt rem 4} of
+ {{[], _}, 0} ->
+ A; %% Ignore extra =
+ {{[], true}, 2} ->
+ [$=|[$=|A]]; %% 'XX=='
+ {{[], _}, 3} ->
+ [$=|A]; %% 'XXX='
+ {{[H|T], _}, _} ->
+ %% more data, skip equals
+ strip_illegal(T, [H|A], Cnt+1)
+ end;
+ _ ->
+ strip_illegal(Cs, [C|A], Cnt+1)
+ end.
-strip_illegal_end([0|Cs], A) ->
- strip_illegal_end(Cs, A);
-strip_illegal_end([C|Cs], A) ->
+%% Search the tail for more valid data and remember if we saw
+%% another equals along the way.
+tail_contains_more([], Eq) ->
+ {[], Eq};
+tail_contains_more(<<>>, Eq) ->
+ {<<>>, Eq};
+tail_contains_more([C|T]=More, Eq) ->
case element(C, ?DECODE_MAP) of
- bad -> strip_illegal(Cs, A);
- ws -> strip_illegal(Cs, A);
- eq -> [C|A];
- _ -> strip_illegal(Cs, [C|A])
+ bad ->
+ tail_contains_more(T, Eq);
+ ws ->
+ tail_contains_more(T, Eq);
+ eq ->
+ tail_contains_more(T, true);
+ _ ->
+ {More, Eq}
end;
-strip_illegal_end([], A) -> A.
-
-tail_contains_equal(<<$=,_/binary>>) -> true;
-tail_contains_equal(<<_,T/binary>>) -> tail_contains_equal(T);
-tail_contains_equal(<<>>) -> false.
+tail_contains_more(<<C:8,T/bits>> =More, Eq) ->
+ case element(C, ?DECODE_MAP) of
+ bad ->
+ tail_contains_more(T, Eq);
+ ws ->
+ tail_contains_more(T, Eq);
+ eq ->
+ tail_contains_more(T, true);
+ _ ->
+ {More, Eq}
+ end.
%% accessors
b64e(X) ->
diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl
index 6d50a575eb..235ea939a8 100644
--- a/lib/stdlib/src/c.erl
+++ b/lib/stdlib/src/c.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -42,31 +42,31 @@
-spec help() -> 'ok'.
help() ->
- format("bt(Pid) -- stack backtrace for a process\n"
- "c(File) -- compile and load code in <File>\n"
- "cd(Dir) -- change working directory\n"
- "flush() -- flush any messages sent to the shell\n"
- "help() -- help info\n"
- "i() -- information about the system\n"
- "ni() -- information about the networked system\n"
- "i(X,Y,Z) -- information about pid <X,Y,Z>\n"
- "l(Module) -- load or reload module\n"
- "lc([File]) -- compile a list of Erlang modules\n"
- "ls() -- list files in the current directory\n"
- "ls(Dir) -- list files in directory <Dir>\n"
- "m() -- which modules are loaded\n"
- "m(Mod) -- information about module <Mod>\n"
- "memory() -- memory allocation information\n"
- "memory(T) -- memory allocation information of type <T>\n"
- "nc(File) -- compile and load code in <File> on all nodes\n"
- "nl(Module) -- load module on all nodes\n"
- "pid(X,Y,Z) -- convert X,Y,Z to a Pid\n"
- "pwd() -- print working directory\n"
- "q() -- quit - shorthand for init:stop()\n"
- "regs() -- information about registered processes\n"
- "nregs() -- information about all registered processes\n"
- "xm(M) -- cross reference check a module\n"
- "y(File) -- generate a Yecc parser\n").
+ io:put_chars(<<"bt(Pid) -- stack backtrace for a process\n"
+ "c(File) -- compile and load code in <File>\n"
+ "cd(Dir) -- change working directory\n"
+ "flush() -- flush any messages sent to the shell\n"
+ "help() -- help info\n"
+ "i() -- information about the system\n"
+ "ni() -- information about the networked system\n"
+ "i(X,Y,Z) -- information about pid <X,Y,Z>\n"
+ "l(Module) -- load or reload module\n"
+ "lc([File]) -- compile a list of Erlang modules\n"
+ "ls() -- list files in the current directory\n"
+ "ls(Dir) -- list files in directory <Dir>\n"
+ "m() -- which modules are loaded\n"
+ "m(Mod) -- information about module <Mod>\n"
+ "memory() -- memory allocation information\n"
+ "memory(T) -- memory allocation information of type <T>\n"
+ "nc(File) -- compile and load code in <File> on all nodes\n"
+ "nl(Module) -- load module on all nodes\n"
+ "pid(X,Y,Z) -- convert X,Y,Z to a Pid\n"
+ "pwd() -- print working directory\n"
+ "q() -- quit - shorthand for init:stop()\n"
+ "regs() -- information about registered processes\n"
+ "nregs() -- information about all registered processes\n"
+ "xm(M) -- cross reference check a module\n"
+ "y(File) -- generate a Yecc parser\n">>).
%% c(FileName)
%% Compile a file/module.
@@ -659,7 +659,7 @@ portformat(Name, Id, Cmd) ->
pwd() ->
case file:get_cwd() of
{ok, Str} ->
- ok = io:format("~s\n", [Str]);
+ ok = io:format("~ts\n", [fixup_one_bin(Str)]);
{error, _} ->
ok = io:format("Cannot determine current directory\n")
end.
@@ -684,11 +684,27 @@ ls() ->
ls(Dir) ->
case file:list_dir(Dir) of
{ok, Entries} ->
- ls_print(sort(Entries));
+ ls_print(sort(fixup_bin(Entries)));
{error,_E} ->
format("Invalid directory\n")
end.
+fixup_one_bin(X) when is_binary(X) ->
+ L = binary_to_list(X),
+ [ if
+ El > 127 ->
+ $?;
+ true ->
+ El
+ end || El <- L];
+fixup_one_bin(X) ->
+ X.
+fixup_bin([H|T]) ->
+ [fixup_one_bin(H) | fixup_bin(T)];
+fixup_bin([]) ->
+ [].
+
+
ls_print([]) -> ok;
ls_print(L) ->
Width = min([max(lengths(L, [])), 40]) + 5,
@@ -698,7 +714,7 @@ ls_print(X, Width, Len) when Width + Len >= 80 ->
io:nl(),
ls_print(X, Width, 0);
ls_print([H|T], Width, Len) ->
- io:format("~-*s",[Width,H]),
+ io:format("~-*ts",[Width,H]),
ls_print(T, Width, Len+Width);
ls_print([], _, _) ->
io:nl().
diff --git a/lib/stdlib/src/calendar.erl b/lib/stdlib/src/calendar.erl
index ddc0666f77..57b7c28dee 100644
--- a/lib/stdlib/src/calendar.erl
+++ b/lib/stdlib/src/calendar.erl
@@ -28,6 +28,8 @@
gregorian_days_to_date/1,
gregorian_seconds_to_datetime/1,
is_leap_year/1,
+ iso_week_number/0,
+ iso_week_number/1,
last_day_of_the_month/2,
local_time/0,
local_time_to_universal_time/1,
@@ -70,6 +72,7 @@
-type second() :: 0..59.
-type daynum() :: 1..7.
-type ldom() :: 28 | 29 | 30 | 31. % last day of month
+-type weeknum() :: 1..53.
-type t_now() :: {non_neg_integer(),non_neg_integer(),non_neg_integer()}.
@@ -77,6 +80,7 @@
-type t_time() :: {hour(),minute(),second()}.
-type t_datetime() :: {t_date(),t_time()}.
-type t_datetime1970() :: {{year1970(),month(),day()},t_time()}.
+-type t_yearweeknum() :: {year(),weeknum()}.
%%----------------------------------------------------------------------
@@ -172,6 +176,42 @@ is_leap_year1(Year) when Year rem 400 =:= 0 ->
is_leap_year1(_) -> false.
+%%
+%% Calculates the iso week number for the current date.
+%%
+-spec iso_week_number() -> t_yearweeknum().
+iso_week_number() ->
+ {Date, _} = local_time(),
+ iso_week_number(Date).
+
+
+%%
+%% Calculates the iso week number for the given date.
+%%
+-spec iso_week_number(t_date()) -> t_yearweeknum().
+iso_week_number({Year, Month, Day}) ->
+ D = date_to_gregorian_days({Year, Month, Day}),
+ W01_1_Year = gregorian_days_of_iso_w01_1(Year),
+ W01_1_NextYear = gregorian_days_of_iso_w01_1(Year + 1),
+ if W01_1_Year =< D andalso D < W01_1_NextYear ->
+ % Current Year Week 01..52(,53)
+ {Year, (D - W01_1_Year) div 7 + 1};
+ D < W01_1_Year ->
+ % Previous Year 52 or 53
+ PWN = case day_of_the_week(Year - 1, 1, 1) of
+ 4 -> 53;
+ _ -> case day_of_the_week(Year - 1, 12, 31) of
+ 4 -> 53;
+ _ -> 52
+ end
+ end,
+ {Year - 1, PWN};
+ W01_1_NextYear =< D ->
+ % Next Year, Week 01
+ {Year + 1, 1}
+ end.
+
+
%% last_day_of_the_month(Year, Month)
%%
%% Returns the number of days in a month.
@@ -377,6 +417,19 @@ dty(Y, D1, D2) when D1 < D2 ->
dty(Y, _D1, D2) ->
{Y, D2}.
+%%
+%% The Gregorian days of the iso week 01 day 1 for a given year.
+%%
+-spec gregorian_days_of_iso_w01_1(year()) -> non_neg_integer().
+gregorian_days_of_iso_w01_1(Year) ->
+ D0101 = date_to_gregorian_days(Year, 1, 1),
+ DOW = day_of_the_week(Year, 1, 1),
+ if DOW =< 4 ->
+ D0101 - DOW + 1;
+ true ->
+ D0101 + 7 - DOW + 1
+ end.
+
%% year_day_to_date(Year, DayOfYear) = {Month, DayOfMonth}
%%
%% Note: 1 is the first day of the month.
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index 4584b8184f..6c91f1efb7 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.erl
@@ -147,6 +147,7 @@
bin, % small chunk not consumed, or 'eof' at end-of-file
alloc, % the part of the file not yet scanned, mostly a binary
tab,
+ proc, % the pid of the Dets process
match_program % true | compiled_match_spec() | undefined
}).
@@ -208,8 +209,6 @@ all() ->
bchunk(Tab, start) ->
badarg(treq(Tab, {bchunk_init, Tab}), [Tab, start]);
-bchunk(Tab, #dets_cont{bin = eof, tab = Tab}) ->
- '$end_of_table';
bchunk(Tab, #dets_cont{what = bchunk, tab = Tab} = State) ->
badarg(treq(Tab, {bchunk, State}), [Tab, State]);
bchunk(Tab, Term) ->
@@ -722,11 +721,14 @@ init_chunk_match(Tab, Pat, What, N) when is_integer(N), N >= 0;
N =:= default ->
case compile_match_spec(What, Pat) of
{Spec, MP} ->
- case req(dets_server:get_pid(Tab), {match, MP, Spec, N}) of
+ Proc = dets_server:get_pid(Tab),
+ case req(Proc, {match, MP, Spec, N}) of
{done, L} ->
- {L, #dets_cont{tab = Tab, what = What, bin = eof}};
+ {L, #dets_cont{tab = Tab, proc = Proc, what = What,
+ bin = eof}};
{cont, State} ->
- chunk_match(State#dets_cont{what = What, tab = Tab});
+ chunk_match(State#dets_cont{what = What, tab = Tab,
+ proc = Proc});
Error ->
Error
end;
@@ -736,34 +738,28 @@ init_chunk_match(Tab, Pat, What, N) when is_integer(N), N >= 0;
init_chunk_match(_Tab, _Pat, _What, _) ->
badarg.
-chunk_match(State) ->
- case catch dets_server:get_pid(State#dets_cont.tab) of
- {'EXIT', _Reason} ->
- badarg;
- _Proc when State#dets_cont.bin =:= eof ->
- '$end_of_table';
- Proc ->
- case req(Proc, {match_init, State}) of
- {cont, {Bins, NewState}} ->
- MP = NewState#dets_cont.match_program,
- case catch do_foldl_bins(Bins, MP) of
- {'EXIT', _} ->
- case ets:is_compiled_ms(MP) of
- true ->
- Bad = dets_utils:bad_object(chunk_match,
- Bins),
- req(Proc, {corrupt, Bad});
- false ->
- badarg
- end;
- [] ->
- chunk_match(NewState);
- Terms ->
- {Terms, NewState}
- end;
- Error ->
- Error
- end
+chunk_match(#dets_cont{proc = Proc}=State) ->
+ case req(Proc, {match_init, State}) of
+ '$end_of_table'=Reply ->
+ Reply;
+ {cont, {Bins, NewState}} ->
+ MP = NewState#dets_cont.match_program,
+ case catch do_foldl_bins(Bins, MP) of
+ {'EXIT', _} ->
+ case ets:is_compiled_ms(MP) of
+ true ->
+ Bad = dets_utils:bad_object(chunk_match, Bins),
+ req(Proc, {corrupt, Bad});
+ false ->
+ badarg
+ end;
+ [] ->
+ chunk_match(NewState);
+ Terms ->
+ {Terms, NewState}
+ end;
+ Error ->
+ Error
end.
do_foldl_bins(Bins, true) ->
@@ -1094,7 +1090,9 @@ do_apply_op(Op, From, Head, N) ->
{N2, H2} when is_record(H2, head), is_integer(N2) ->
open_file_loop(H2, N2);
H2 when is_record(H2, head) ->
- open_file_loop(H2, N)
+ open_file_loop(H2, N);
+ {{more,From1,Op1,N1}, NewHead} ->
+ do_apply_op(Op1, From1, NewHead, N1)
catch
exit:normal ->
exit(normal);
@@ -1363,37 +1361,35 @@ start_auto_save_timer(Head) ->
%% lookup requests in parallel. Evalute delete_object, delete and
%% insert as well.
stream_op(Op, Pid, Pids, Head, N) ->
- stream_op(Head, Pids, [], N, Pid, Op, Head#head.fixed).
+ #head{fixed = Fxd, update_mode = M} = Head,
+ stream_op(Head, Pids, [], N, Pid, Op, Fxd, M).
-stream_loop(Head, Pids, C, N, false = Fxd) ->
+stream_loop(Head, Pids, C, N, false = Fxd, M) ->
receive
?DETS_CALL(From, Message) ->
- stream_op(Head, Pids, C, N, From, Message, Fxd)
+ stream_op(Head, Pids, C, N, From, Message, Fxd, M)
after 0 ->
stream_end(Head, Pids, C, N, no_more)
end;
-stream_loop(Head, Pids, C, N, _Fxd) ->
+stream_loop(Head, Pids, C, N, _Fxd, _M) ->
stream_end(Head, Pids, C, N, no_more).
-stream_op(Head, Pids, C, N, Pid, {lookup_keys,Keys}, Fxd) ->
+stream_op(Head, Pids, C, N, Pid, {lookup_keys,Keys}, Fxd, M) ->
NC = [{{lookup,Pid},Keys} | C],
- stream_loop(Head, Pids, NC, N, Fxd);
-stream_op(Head, Pids, C, N, Pid, {insert, _Objects} = Op, Fxd) ->
- NC = [Op | C],
- stream_loop(Head, [Pid | Pids], NC, N, Fxd);
-stream_op(Head, Pids, C, N, Pid, {insert_new, _Objects} = Op, Fxd) ->
+ stream_loop(Head, Pids, NC, N, Fxd, M);
+stream_op(Head, Pids, C, N, Pid, {insert, _Objects} = Op, Fxd, dirty = M) ->
NC = [Op | C],
- stream_loop(Head, [Pid | Pids], NC, N, Fxd);
-stream_op(Head, Pids, C, N, Pid, {delete_key, _Keys} = Op, Fxd) ->
+ stream_loop(Head, [Pid | Pids], NC, N, Fxd, M);
+stream_op(Head, Pids, C, N, Pid, {delete_key, _Keys} = Op, Fxd, dirty = M) ->
NC = [Op | C],
- stream_loop(Head, [Pid | Pids], NC, N, Fxd);
-stream_op(Head, Pids, C, N, Pid, {delete_object, _Objects} = Op, Fxd) ->
+ stream_loop(Head, [Pid | Pids], NC, N, Fxd, M);
+stream_op(Head, Pids, C, N, Pid, {delete_object, _Os} = Op, Fxd, dirty = M) ->
NC = [Op | C],
- stream_loop(Head, [Pid | Pids], NC, N, Fxd);
-stream_op(Head, Pids, C, N, Pid, {member, Key}, Fxd) ->
+ stream_loop(Head, [Pid | Pids], NC, N, Fxd, M);
+stream_op(Head, Pids, C, N, Pid, {member, Key}, Fxd, M) ->
NC = [{{lookup,[Pid]},[Key]} | C],
- stream_loop(Head, Pids, NC, N, Fxd);
-stream_op(Head, Pids, C, N, Pid, Op, _Fxd) ->
+ stream_loop(Head, Pids, NC, N, Fxd, M);
+stream_op(Head, Pids, C, N, Pid, Op, _Fxd, _M) ->
stream_end(Head, Pids, C, N, {Pid,Op}).
stream_end(Head, Pids0, C, N, Next) ->
@@ -1438,7 +1434,7 @@ stream_end2([], Ps, no_more, N, C, Head, _Reply) ->
penalty(Head, Ps, C),
{N, Head};
stream_end2([], _Ps, {From, Op}, N, _C, Head, _Reply) ->
- apply_op(Op, From, Head, N).
+ {{more,From,Op,N},Head}.
penalty(H, _Ps, _C) when H#head.fixed =:= false ->
ok;
@@ -1578,13 +1574,18 @@ do_bchunk_init(Head, Tab) ->
L = dets_utils:all_allocated(H2),
C0 = #dets_cont{no_objs = default, bin = <<>>, alloc = L},
BinParms = term_to_binary(Parms),
- {H2, {C0#dets_cont{tab = Tab, what = bchunk}, [BinParms]}}
+ {H2, {C0#dets_cont{tab = Tab, proc = self(),what = bchunk},
+ [BinParms]}}
end;
{NewHead, _} = HeadError when is_record(NewHead, head) ->
HeadError
end.
%% -> {NewHead, {cont(), [binary()]}} | {NewHead, Error}
+do_bchunk(Head, #dets_cont{proc = Proc}) when Proc =/= self() ->
+ {Head, badarg};
+do_bchunk(Head, #dets_cont{bin = eof}) ->
+ {Head, '$end_of_table'};
do_bchunk(Head, State) ->
case dets_v9:read_bchunks(Head, State#dets_cont.alloc) of
{error, Reason} ->
@@ -1954,6 +1955,8 @@ flookup_keys(Head, Keys) ->
end.
%% -> {NewHead, Result}
+fmatch_init(Head, #dets_cont{bin = eof}) ->
+ {Head, '$end_of_table'};
fmatch_init(Head, C) ->
case scan(Head, C) of
{scan_error, Reason} ->
diff --git a/lib/stdlib/src/dets.hrl b/lib/stdlib/src/dets.hrl
index 6e59770753..fbffc9d008 100644
--- a/lib/stdlib/src/dets.hrl
+++ b/lib/stdlib/src/dets.hrl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -18,7 +18,7 @@
%%
-define(DEFAULT_MIN_NO_SLOTS, 256).
--define(DEFAULT_MAX_NO_SLOTS, 2*1024*1024).
+-define(DEFAULT_MAX_NO_SLOTS, 32*1024*1024).
-define(DEFAULT_AUTOSAVE, 3). % minutes
-define(DEFAULT_CACHE, {3000, 14000}). % {delay,size} in {milliseconds,bytes}
diff --git a/lib/stdlib/src/dets_v8.erl b/lib/stdlib/src/dets_v8.erl
index 1f9f84cd27..af36958c1c 100644
--- a/lib/stdlib/src/dets_v8.erl
+++ b/lib/stdlib/src/dets_v8.erl
@@ -1074,6 +1074,8 @@ wl([], _Type, Del, Lookup, I, Objs) ->
[{Del, Lookup, Objs} | I].
%% -> {NewHead, ok} | {NewHead, Error}
+may_grow(Head, 0, once) ->
+ {Head, ok};
may_grow(Head, _N, _How) when Head#head.fixed =/= false ->
{Head, ok};
may_grow(#head{access = read}=Head, _N, _How) ->
diff --git a/lib/stdlib/src/dets_v9.erl b/lib/stdlib/src/dets_v9.erl
index 53238e962f..132af01f79 100644
--- a/lib/stdlib/src/dets_v9.erl
+++ b/lib/stdlib/src/dets_v9.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -1908,6 +1908,9 @@ write_cache(Head) ->
end.
%% -> {NewHead, ok} | {NewHead, Error}
+may_grow(Head, 0, once) ->
+ %% Do not re-hash if there is a chance that the file is not dirty.
+ {Head, ok};
may_grow(Head, _N, _How) when Head#head.fixed =/= false ->
{Head, ok};
may_grow(#head{access = read}=Head, _N, _How) ->
diff --git a/lib/stdlib/src/digraph.erl b/lib/stdlib/src/digraph.erl
index b5f52da921..5edc868a94 100644
--- a/lib/stdlib/src/digraph.erl
+++ b/lib/stdlib/src/digraph.erl
@@ -36,7 +36,7 @@
-export([get_short_path/3, get_short_cycle/2]).
--export_type([d_type/0, vertex/0]).
+-export_type([digraph/0, d_type/0, vertex/0]).
-record(digraph, {vtab = notable :: ets:tab(),
etab = notable :: ets:tab(),
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index 81b2431f40..e5ccaddbb4 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -33,7 +33,9 @@
%% Epp state record.
-record(epp, {file, %Current file
location, %Current location
+ delta, %Offset from Location (-file)
name="", %Current file name
+ name2="", %-"-, modified by -file
istk=[], %Ifdef stack
sstk=[], %State stack
path=[], %Include-path
@@ -234,8 +236,8 @@ init_server(Pid, Name, File, AtLocation, Path, Pdm, Pre) ->
case user_predef(Pdm, Ms0) of
{ok,Ms1} ->
epp_reply(Pid, {ok,self()}),
- St = #epp{file=File, location=AtLocation, name=Name,
- path=Path, macs=Ms1, pre_opened = Pre},
+ St = #epp{file=File, location=AtLocation, delta=0, name=Name,
+ name2=Name, path=Path, macs=Ms1, pre_opened = Pre},
From = wait_request(St),
enter_file_reply(From, Name, AtLocation, AtLocation),
wait_req_scan(St);
@@ -358,8 +360,8 @@ enter_file2(NewF, Pname, From, St, AtLocation, ExtraPath) ->
enter_file_reply(From, Pname, Loc, AtLocation),
Ms = dict:store({atom,'FILE'}, {none,[{string,Loc,Pname}]}, St#epp.macs),
Path = St#epp.path ++ ExtraPath,
- #epp{location=Loc,file=NewF,
- name=Pname,sstk=[St|St#epp.sstk],path=Path,macs=Ms}.
+ #epp{file=NewF,location=Loc,name=Pname,delta=0,
+ sstk=[St|St#epp.sstk],path=Path,macs=Ms}.
enter_file_reply(From, Name, Location, AtLocation) ->
Attr = loc_attr(AtLocation),
@@ -391,14 +393,23 @@ leave_file(From, St) ->
case St#epp.sstk of
[OldSt|Sts] ->
close_file(St),
- enter_file_reply(From, OldSt#epp.name,
- OldSt#epp.location, OldSt#epp.location),
+ #epp{location=OldLoc, delta=Delta, name=OldName,
+ name2=OldName2} = OldSt,
+ CurrLoc = add_line(OldLoc, Delta),
Ms = dict:store({atom,'FILE'},
- {none,
- [{string,OldSt#epp.location,
- OldSt#epp.name}]},
+ {none,[{string,CurrLoc,OldName2}]},
St#epp.macs),
- wait_req_scan(OldSt#epp{sstk=Sts,macs=Ms});
+ NextSt = OldSt#epp{sstk=Sts,macs=Ms},
+ enter_file_reply(From, OldName, CurrLoc, CurrLoc),
+ case OldName2 =:= OldName of
+ true ->
+ From;
+ false ->
+ NFrom = wait_request(NextSt),
+ enter_file_reply(NFrom, OldName2, OldLoc,
+ neg_line(CurrLoc))
+ end,
+ wait_req_scan(NextSt);
[] ->
epp_reply(From, {eof,St#epp.location}),
wait_req_scan(St)
@@ -768,7 +779,8 @@ scan_file([{'(',_Llp},{string,_Ls,Name},{',',_Lc},{integer,_Li,Ln},{')',_Lrp},
Ms = dict:store({atom,'FILE'}, {none,[{string,1,Name}]}, St#epp.macs),
Locf = loc(Tf),
NewLoc = new_location(Ln, St#epp.location, Locf),
- wait_req_scan(St#epp{name=Name,location=NewLoc,macs=Ms});
+ Delta = abs(get_line(element(2, Tf)))-Ln + St#epp.delta,
+ wait_req_scan(St#epp{name2=Name,location=NewLoc,delta=Delta,macs=Ms});
scan_file(_Toks, Tf, From, St) ->
epp_reply(From, {error,{loc(Tf),epp,{bad,file}}}),
wait_req_scan(St).
@@ -1132,6 +1144,9 @@ neg_line(L) ->
abs_line(L) ->
erl_scan:set_attribute(line, L, fun(Line) -> abs(Line) end).
+add_line(L, Offset) ->
+ erl_scan:set_attribute(line, L, fun(Line) -> Line+Offset end).
+
start_loc(Line) when is_integer(Line) ->
1;
start_loc({_Line, _Column}) ->
@@ -1191,10 +1206,10 @@ interpret_file_attr([{attribute,Loc,file,{File,Line}}=Form | Forms],
%% -include or -include_lib
% true = L =:= Line,
case Fs of
- [_, Delta1, File | Fs1] -> % end of included file
- [Form | interpret_file_attr(Forms, Delta1, [File | Fs1])];
+ [_, File | Fs1] -> % end of included file
+ [Form | interpret_file_attr(Forms, 0, [File | Fs1])];
_ -> % start of included file
- [Form | interpret_file_attr(Forms, 0, [File, Delta | Fs])]
+ [Form | interpret_file_attr(Forms, 0, [File | Fs])]
end
end;
interpret_file_attr([Form0 | Forms], Delta, Fs) ->
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 077621ac91..cfb9f0ca98 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -60,6 +60,10 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
(_Opt, Def) -> Def
end, Default, Opts).
+%% The maximum number of arguments allowed for a function.
+
+-define(MAX_ARGUMENTS, 255).
+
%% The error and warning info structures, {Line,Module,Descriptor},
%% are kept in their seperate fields in the lint state record together
%% with the name of the file (when a new file is entered, marked by
@@ -226,6 +230,9 @@ format_error({obsolete_guard, {F, A}}) ->
io_lib:format("~p/~p obsolete", [F, A]);
format_error({reserved_for_future,K}) ->
io_lib:format("atom ~w: future reserved keyword - rename or quote", [K]);
+format_error({too_many_arguments,Arity}) ->
+ io_lib:format("too many arguments (~w) - "
+ "maximum allowed is ~w", [Arity,?MAX_ARGUMENTS]);
%% --- patterns and guards ---
format_error(illegal_pattern) -> "illegal pattern";
format_error(illegal_bin_pattern) ->
@@ -311,6 +318,8 @@ 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({bad_export_type, _ETs}) ->
+ io_lib:format("bad export_type declaration", []);
format_error({duplicated_export_type, {T, A}}) ->
io_lib:format("type ~w/~w already exported", [T, A]);
format_error({undefined_type, {TypeName, Arity}}) ->
@@ -1128,8 +1137,7 @@ export(Line, Es, #lint{exports = Es0, called = Called} = St0) ->
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}) ->
+ try foldl(fun ({T,A}=TA, {E,U,St2}) when is_atom(T), is_integer(A) ->
St = case gb_sets:is_element(TA, E) of
true ->
Warn = {duplicated_export_type,TA},
@@ -1139,8 +1147,13 @@ export_type(Line, ETs, #lint{usage = Usage, exp_types = ETs0} = St0) ->
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}.
+ {ETs0,UTs0,St0}, ETs) of
+ {ETs1,UTs1,St1} ->
+ St1#lint{usage = Usage#usage{used_types = UTs1}, exp_types = ETs1}
+ catch
+ error:_ ->
+ add_error(Line, {bad_export_type, ETs}, St0)
+ end.
-type import() :: {module(), [fa()]} | module().
-spec import(line(), import(), lint_state()) -> lint_state().
@@ -1301,13 +1314,18 @@ define_function(Line, Name, Arity, St0) ->
true ->
add_error(Line, {redefine_function,NA}, St1);
false ->
- St2 = St1#lint{defined=gb_sets:add_element(NA, St1#lint.defined)},
- case imported(Name, Arity, St2) of
- {yes,_M} -> add_error(Line, {define_import,NA}, St2);
- no -> St2
+ St2 = function_check_max_args(Line, Arity, St1),
+ St3 = St2#lint{defined=gb_sets:add_element(NA, St2#lint.defined)},
+ case imported(Name, Arity, St3) of
+ {yes,_M} -> add_error(Line, {define_import,NA}, St3);
+ no -> St3
end
end.
+function_check_max_args(Line, Arity, St) when Arity > ?MAX_ARGUMENTS ->
+ add_error(Line, {too_many_arguments,Arity}, St);
+function_check_max_args(_, _, St) -> St.
+
%% clauses([Clause], VarTable, State) -> {VarTable, State}.
clauses(Cs, Vt, St) ->
diff --git a/lib/stdlib/src/erl_posix_msg.erl b/lib/stdlib/src/erl_posix_msg.erl
index fe981b23a7..909cc1d102 100644
--- a/lib/stdlib/src/erl_posix_msg.erl
+++ b/lib/stdlib/src/erl_posix_msg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -24,143 +24,146 @@
-spec message(atom()) -> string().
-message(e2big) -> "argument list too long";
-message(eacces) -> "permission denied";
-message(eaddrinuse) -> "address already in use";
-message(eaddrnotavail) -> "can't assign requested address";
-message(eadv) -> "advertise error";
-message(eafnosupport) -> "address family not supported by protocol family";
-message(eagain) -> "resource temporarily unavailable";
-message(ealign) -> "EALIGN";
-message(ealready) -> "operation already in progress";
-message(ebade) -> "bad exchange descriptor";
-message(ebadf) -> "bad file number";
-message(ebadfd) -> "file descriptor in bad state";
-message(ebadmsg) -> "not a data message";
-message(ebadr) -> "bad request descriptor";
-message(ebadrpc) -> "RPC structure is bad";
-message(ebadrqc) -> "bad request code";
-message(ebadslt) -> "invalid slot";
-message(ebfont) -> "bad font file format";
-message(ebusy) -> "file busy";
-message(echild) -> "no children";
-message(echrng) -> "channel number out of range";
-message(ecomm) -> "communication error on send";
-message(econnaborted) -> "software caused connection abort";
-message(econnrefused) -> "connection refused";
-message(econnreset) -> "connection reset by peer";
-message(edeadlk) -> "resource deadlock avoided";
-message(edeadlock) -> "resource deadlock avoided";
-message(edestaddrreq) -> "destination address required";
-message(edirty) -> "mounting a dirty fs w/o force";
-message(edom) -> "math argument out of range";
-message(edotdot) -> "cross mount point";
-message(edquot) -> "disk quota exceeded";
-message(eduppkg) -> "duplicate package name";
-message(eexist) -> "file already exists";
-message(efault) -> "bad address in system call argument";
-message(efbig) -> "file too large";
-message(ehostdown) -> "host is down";
-message(ehostunreach) -> "host is unreachable";
-message(eidrm) -> "identifier removed";
-message(einit) -> "initialization error";
-message(einprogress) -> "operation now in progress";
-message(eintr) -> "interrupted system call";
-message(einval) -> "invalid argument";
-message(eio) -> "I/O error";
-message(eisconn) -> "socket is already connected";
-message(eisdir) -> "illegal operation on a directory";
-message(eisnam) -> "is a name file";
-message(elbin) -> "ELBIN";
-message(el2hlt) -> "level 2 halted";
-message(el2nsync) -> "level 2 not synchronized";
-message(el3hlt) -> "level 3 halted";
-message(el3rst) -> "level 3 reset";
-message(elibacc) -> "can not access a needed shared library";
-message(elibbad) -> "accessing a corrupted shared library";
-message(elibexec) -> "can not exec a shared library directly";
-message(elibmax) ->
- "attempting to link in more shared libraries than system limit";
-message(elibscn) -> ".lib section in a.out corrupted";
-message(elnrng) -> "link number out of range";
-message(eloop) -> "too many levels of symbolic links";
-message(emfile) -> "too many open files";
-message(emlink) -> "too many links";
-message(emsgsize) -> "message too long";
-message(emultihop) -> "multihop attempted";
-message(enametoolong) -> "file name too long";
-message(enavail) -> "not available";
-message(enet) -> "ENET";
-message(enetdown) -> "network is down";
-message(enetreset) -> "network dropped connection on reset";
-message(enetunreach) -> "network is unreachable";
-message(enfile) -> "file table overflow";
-message(enoano) -> "anode table overflow";
-message(enobufs) -> "no buffer space available";
-message(enocsi) -> "no CSI structure available";
-message(enodata) -> "no data available";
-message(enodev) -> "no such device";
-message(enoent) -> "no such file or directory";
-message(enoexec) -> "exec format error";
-message(enolck) -> "no locks available";
-message(enolink) -> "link has be severed";
-message(enomem) -> "not enough memory";
-message(enomsg) -> "no message of desired type";
-message(enonet) -> "machine is not on the network";
-message(enopkg) -> "package not installed";
-message(enoprotoopt) -> "bad proocol option";
-message(enospc) -> "no space left on device";
-message(enosr) -> "out of stream resources or not a stream device";
-message(enosym) -> "unresolved symbol name";
-message(enosys) -> "function not implemented";
-message(enotblk) -> "block device required";
-message(enotconn) -> "socket is not connected";
-message(enotdir) -> "not a directory";
-message(enotempty) -> "directory not empty";
-message(enotnam) -> "not a name file";
-message(enotsock) -> "socket operation on non-socket";
-message(enotsup) -> "operation not supported";
-message(enotty) -> "inappropriate device for ioctl";
-message(enotuniq) -> "name not unique on network";
-message(enxio) -> "no such device or address";
-message(eopnotsupp) -> "operation not supported on socket";
-message(eperm) -> "not owner";
-message(epfnosupport) -> "protocol family not supported";
-message(epipe) -> "broken pipe";
-message(eproclim) -> "too many processes";
-message(eprocunavail) -> "bad procedure for program";
-message(eprogmismatch) -> "program version wrong";
-message(eprogunavail) -> "RPC program not available";
-message(eproto) -> "protocol error";
-message(eprotonosupport) -> "protocol not suppored";
-message(eprototype) -> "protocol wrong type for socket";
-message(erange) -> "math result unrepresentable";
-message(erefused) -> "EREFUSED";
-message(eremchg) -> "remote address changed";
-message(eremdev) -> "remote device";
-message(eremote) -> "pathname hit remote file system";
-message(eremoteio) -> "remote i/o error";
-message(eremoterelease) -> "EREMOTERELEASE";
-message(erofs) -> "read-only file system";
-message(erpcmismatch) -> "RPC version is wrong";
-message(erremote) -> "object is remote";
-message(eshutdown) -> "can't send after socket shutdown";
-message(esocktnosupport) -> "socket type not supported";
-message(espipe) -> "invalid seek";
-message(esrch) -> "no such process";
-message(esrmnt) -> "srmount error";
-message(estale) -> "stale remote file handle";
-message(esuccess) -> "Error 0";
-message(etime) -> "timer expired";
-message(etimedout) -> "connection timed out";
-message(etoomanyrefs) -> "too many references: can't splice";
-message(etxtbsy) -> "text file or pseudo-device busy";
-message(euclean) -> "structure needs cleaning";
-message(eunatch) -> "protocol driver not attached";
-message(eusers) -> "too many users";
-message(eversion) -> "version mismatch";
-message(ewouldblock) -> "operation would block";
-message(exdev) -> "cross-domain link";
-message(exfull) -> "message tables full";
-message(nxdomain) -> "non-existing domain";
-message(_) -> "unknown POSIX error".
+message(T) ->
+ binary_to_list(message_1(T)).
+
+message_1(e2big) -> <<"argument list too long">>;
+message_1(eacces) -> <<"permission denied">>;
+message_1(eaddrinuse) -> <<"address already in use">>;
+message_1(eaddrnotavail) -> <<"can't assign requested address">>;
+message_1(eadv) -> <<"advertise error">>;
+message_1(eafnosupport) -> <<"address family not supported by protocol family">>;
+message_1(eagain) -> <<"resource temporarily unavailable">>;
+message_1(ealign) -> <<"EALIGN">>;
+message_1(ealready) -> <<"operation already in progress">>;
+message_1(ebade) -> <<"bad exchange descriptor">>;
+message_1(ebadf) -> <<"bad file number">>;
+message_1(ebadfd) -> <<"file descriptor in bad state">>;
+message_1(ebadmsg) -> <<"not a data message">>;
+message_1(ebadr) -> <<"bad request descriptor">>;
+message_1(ebadrpc) -> <<"RPC structure is bad">>;
+message_1(ebadrqc) -> <<"bad request code">>;
+message_1(ebadslt) -> <<"invalid slot">>;
+message_1(ebfont) -> <<"bad font file format">>;
+message_1(ebusy) -> <<"file busy">>;
+message_1(echild) -> <<"no children">>;
+message_1(echrng) -> <<"channel number out of range">>;
+message_1(ecomm) -> <<"communication error on send">>;
+message_1(econnaborted) -> <<"software caused connection abort">>;
+message_1(econnrefused) -> <<"connection refused">>;
+message_1(econnreset) -> <<"connection reset by peer">>;
+message_1(edeadlk) -> <<"resource deadlock avoided">>;
+message_1(edeadlock) -> <<"resource deadlock avoided">>;
+message_1(edestaddrreq) -> <<"destination address required">>;
+message_1(edirty) -> <<"mounting a dirty fs w/o force">>;
+message_1(edom) -> <<"math argument out of range">>;
+message_1(edotdot) -> <<"cross mount point">>;
+message_1(edquot) -> <<"disk quota exceeded">>;
+message_1(eduppkg) -> <<"duplicate package name">>;
+message_1(eexist) -> <<"file already exists">>;
+message_1(efault) -> <<"bad address in system call argument">>;
+message_1(efbig) -> <<"file too large">>;
+message_1(ehostdown) -> <<"host is down">>;
+message_1(ehostunreach) -> <<"host is unreachable">>;
+message_1(eidrm) -> <<"identifier removed">>;
+message_1(einit) -> <<"initialization error">>;
+message_1(einprogress) -> <<"operation now in progress">>;
+message_1(eintr) -> <<"interrupted system call">>;
+message_1(einval) -> <<"invalid argument">>;
+message_1(eio) -> <<"I/O error">>;
+message_1(eisconn) -> <<"socket is already connected">>;
+message_1(eisdir) -> <<"illegal operation on a directory">>;
+message_1(eisnam) -> <<"is a name file">>;
+message_1(elbin) -> <<"ELBIN">>;
+message_1(el2hlt) -> <<"level 2 halted">>;
+message_1(el2nsync) -> <<"level 2 not synchronized">>;
+message_1(el3hlt) -> <<"level 3 halted">>;
+message_1(el3rst) -> <<"level 3 reset">>;
+message_1(elibacc) -> <<"can not access a needed shared library">>;
+message_1(elibbad) -> <<"accessing a corrupted shared library">>;
+message_1(elibexec) -> <<"can not exec a shared library directly">>;
+message_1(elibmax) ->
+ <<"attempting to link in more shared libraries than system limit">>;
+message_1(elibscn) -> <<".lib section in a.out corrupted">>;
+message_1(elnrng) -> <<"link number out of range">>;
+message_1(eloop) -> <<"too many levels of symbolic links">>;
+message_1(emfile) -> <<"too many open files">>;
+message_1(emlink) -> <<"too many links">>;
+message_1(emsgsize) -> <<"message too long">>;
+message_1(emultihop) -> <<"multihop attempted">>;
+message_1(enametoolong) -> <<"file name too long">>;
+message_1(enavail) -> <<"not available">>;
+message_1(enet) -> <<"ENET">>;
+message_1(enetdown) -> <<"network is down">>;
+message_1(enetreset) -> <<"network dropped connection on reset">>;
+message_1(enetunreach) -> <<"network is unreachable">>;
+message_1(enfile) -> <<"file table overflow">>;
+message_1(enoano) -> <<"anode table overflow">>;
+message_1(enobufs) -> <<"no buffer space available">>;
+message_1(enocsi) -> <<"no CSI structure available">>;
+message_1(enodata) -> <<"no data available">>;
+message_1(enodev) -> <<"no such device">>;
+message_1(enoent) -> <<"no such file or directory">>;
+message_1(enoexec) -> <<"exec format error">>;
+message_1(enolck) -> <<"no locks available">>;
+message_1(enolink) -> <<"link has be severed">>;
+message_1(enomem) -> <<"not enough memory">>;
+message_1(enomsg) -> <<"no message of desired type">>;
+message_1(enonet) -> <<"machine is not on the network">>;
+message_1(enopkg) -> <<"package not installed">>;
+message_1(enoprotoopt) -> <<"bad proocol option">>;
+message_1(enospc) -> <<"no space left on device">>;
+message_1(enosr) -> <<"out of stream resources or not a stream device">>;
+message_1(enosym) -> <<"unresolved symbol name">>;
+message_1(enosys) -> <<"function not implemented">>;
+message_1(enotblk) -> <<"block device required">>;
+message_1(enotconn) -> <<"socket is not connected">>;
+message_1(enotdir) -> <<"not a directory">>;
+message_1(enotempty) -> <<"directory not empty">>;
+message_1(enotnam) -> <<"not a name file">>;
+message_1(enotsock) -> <<"socket operation on non-socket">>;
+message_1(enotsup) -> <<"operation not supported">>;
+message_1(enotty) -> <<"inappropriate device for ioctl">>;
+message_1(enotuniq) -> <<"name not unique on network">>;
+message_1(enxio) -> <<"no such device or address">>;
+message_1(eopnotsupp) -> <<"operation not supported on socket">>;
+message_1(eperm) -> <<"not owner">>;
+message_1(epfnosupport) -> <<"protocol family not supported">>;
+message_1(epipe) -> <<"broken pipe">>;
+message_1(eproclim) -> <<"too many processes">>;
+message_1(eprocunavail) -> <<"bad procedure for program">>;
+message_1(eprogmismatch) -> <<"program version wrong">>;
+message_1(eprogunavail) -> <<"RPC program not available">>;
+message_1(eproto) -> <<"protocol error">>;
+message_1(eprotonosupport) -> <<"protocol not suppored">>;
+message_1(eprototype) -> <<"protocol wrong type for socket">>;
+message_1(erange) -> <<"math result unrepresentable">>;
+message_1(erefused) -> <<"EREFUSED">>;
+message_1(eremchg) -> <<"remote address changed">>;
+message_1(eremdev) -> <<"remote device">>;
+message_1(eremote) -> <<"pathname hit remote file system">>;
+message_1(eremoteio) -> <<"remote i/o error">>;
+message_1(eremoterelease) -> <<"EREMOTERELEASE">>;
+message_1(erofs) -> <<"read-only file system">>;
+message_1(erpcmismatch) -> <<"RPC version is wrong">>;
+message_1(erremote) -> <<"object is remote">>;
+message_1(eshutdown) -> <<"can't send after socket shutdown">>;
+message_1(esocktnosupport) -> <<"socket type not supported">>;
+message_1(espipe) -> <<"invalid seek">>;
+message_1(esrch) -> <<"no such process">>;
+message_1(esrmnt) -> <<"srmount error">>;
+message_1(estale) -> <<"stale remote file handle">>;
+message_1(esuccess) -> <<"Error 0">>;
+message_1(etime) -> <<"timer expired">>;
+message_1(etimedout) -> <<"connection timed out">>;
+message_1(etoomanyrefs) -> <<"too many references: can't splice">>;
+message_1(etxtbsy) -> <<"text file or pseudo-device busy">>;
+message_1(euclean) -> <<"structure needs cleaning">>;
+message_1(eunatch) -> <<"protocol driver not attached">>;
+message_1(eusers) -> <<"too many users">>;
+message_1(eversion) -> <<"version mismatch">>;
+message_1(ewouldblock) -> <<"operation would block">>;
+message_1(exdev) -> <<"cross-domain link">>;
+message_1(exfull) -> <<"message tables full">>;
+message_1(nxdomain) -> <<"non-existing domain">>;
+message_1(_) -> <<"unknown POSIX error">>.
diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl
index 99e454f593..0d2d23180a 100644
--- a/lib/stdlib/src/escript.erl
+++ b/lib/stdlib/src/escript.erl
@@ -31,7 +31,7 @@
%%-----------------------------------------------------------------------
--type mode() :: 'compile' | 'debug' | 'interpret' | 'run'.
+-type mode() :: 'native' | 'compile' | 'debug' | 'interpret' | 'run'.
-type source() :: 'archive' | 'beam' | 'text'.
-record(state, {file :: file:filename(),
@@ -304,7 +304,11 @@ parse_and_run(File, Args, Options) ->
false ->
case lists:member("i", Options) of
true -> interpret;
- false -> Mode
+ false ->
+ case lists:member("n", Options) of
+ true -> native;
+ false -> Mode
+ end
end
end
end,
@@ -321,6 +325,14 @@ parse_and_run(File, Args, Options) ->
_Other ->
fatal("There were compilation errors.")
end;
+ native ->
+ case compile:forms(FormsOrBin, [report,native]) of
+ {ok, Module, BeamBin} ->
+ {module, Module} = code:load_binary(Module, File, BeamBin),
+ run(Module, Args);
+ _Other ->
+ fatal("There were compilation errors.")
+ end;
debug ->
case compile:forms(FormsOrBin, [report, debug_info]) of
{ok,Module,BeamBin} ->
@@ -570,9 +582,7 @@ parse_beam(S, File, HeaderSz, CheckOnly) ->
forms_or_bin = Bin}
end;
{error, beam_lib, Reason} when is_tuple(Reason) ->
- fatal(element(1, Reason));
- {error, beam_lib, Reason} ->
- fatal(Reason)
+ fatal(element(1, Reason))
end.
parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) ->
@@ -666,7 +676,7 @@ epp_parse_file2(Epp, S, Forms, Parsed) ->
{attribute,Ln,mode,NewMode} ->
S2 = S#state{mode = NewMode},
if
- NewMode =:= compile; NewMode =:= interpret; NewMode =:= debug ->
+ NewMode =:= compile; NewMode =:= interpret; NewMode =:= debug; NewMode =:= native ->
epp_parse_file(Epp, S2, [Form | Forms]);
true ->
Args = lists:flatten(io_lib:format("illegal mode attribute: ~p", [NewMode])),
diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl
index 1d033f6f7b..6e6e949e2c 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.erl
@@ -512,7 +512,7 @@ file2tab(File) ->
file2tab(File, Opts) ->
try
- {ok,Verify} = parse_f2t_opts(Opts,false),
+ {ok,Verify,TabArg} = parse_f2t_opts(Opts,false,[]),
Name = make_ref(),
{ok, Major, Minor, FtOptions, MD5State, FullHeader, DLContext} =
case disk_log:open([{name, Name},
@@ -540,7 +540,7 @@ file2tab(File, Opts) ->
true ->
ok
end,
- {ok, Tab, HeadCount} = create_tab(FullHeader),
+ {ok, Tab, HeadCount} = create_tab(FullHeader, TabArg),
StrippedOptions =
case Verify of
true ->
@@ -676,15 +676,17 @@ do_read_and_verify(ReadFun,InitState,Tab,FtOptions,HeadCount,Verify) ->
{ok,Tab}
end.
-parse_f2t_opts([],Verify) ->
- {ok,Verify};
-parse_f2t_opts([{verify, true}|T],_OV) ->
- parse_f2t_opts(T,true);
-parse_f2t_opts([{verify,false}|T],OV) ->
- parse_f2t_opts(T,OV);
-parse_f2t_opts([Unexpected|_],_) ->
+parse_f2t_opts([],Verify,Tab) ->
+ {ok,Verify,Tab};
+parse_f2t_opts([{verify, true}|T],_OV,Tab) ->
+ parse_f2t_opts(T,true,Tab);
+parse_f2t_opts([{verify,false}|T],OV,Tab) ->
+ parse_f2t_opts(T,OV,Tab);
+parse_f2t_opts([{table,Tab}|T],OV,[]) ->
+ parse_f2t_opts(T,OV,Tab);
+parse_f2t_opts([Unexpected|_],_,_) ->
throw({unknown_option,Unexpected});
-parse_f2t_opts(Malformed,_) ->
+parse_f2t_opts(Malformed,_,_) ->
throw({malformed_option,Malformed}).
count_mandatory([]) ->
@@ -860,19 +862,28 @@ load_table(ReadFun, State, Tab) ->
load_table(ReadFun, NewState, Tab)
end.
-create_tab(I) ->
+create_tab(I, TabArg) ->
{name, Name} = lists:keyfind(name, 1, I),
{type, Type} = lists:keyfind(type, 1, I),
{protection, P} = lists:keyfind(protection, 1, I),
{named_table, Val} = lists:keyfind(named_table, 1, I),
{keypos, _Kp} = Keypos = lists:keyfind(keypos, 1, I),
{size, Sz} = lists:keyfind(size, 1, I),
- try
- Tab = ets:new(Name, [Type, P, Keypos | named_table(Val)]),
- {ok, Tab, Sz}
- catch
- _:_ ->
- throw(cannot_create_table)
+ Comp = case lists:keyfind(compressed, 1, I) of
+ {compressed, true} -> [compressed];
+ {compressed, false} -> [];
+ false -> []
+ end,
+ case TabArg of
+ [] ->
+ try
+ Tab = ets:new(Name, [Type, P, Keypos] ++ named_table(Val) ++ Comp),
+ {ok, Tab, Sz}
+ catch _:_ ->
+ throw(cannot_create_table)
+ end;
+ _ ->
+ {ok, TabArg, Sz}
end.
named_table(true) -> [named_table];
diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl
index d5ddf9ed7e..c845b61204 100644
--- a/lib/stdlib/src/filelib.erl
+++ b/lib/stdlib/src/filelib.erl
@@ -47,14 +47,14 @@ wildcard(Pattern) when is_list(Pattern) ->
?HANDLE_ERROR(do_wildcard(Pattern, file)).
-spec wildcard(file:name(), file:name() | atom()) -> [file:filename()].
-wildcard(Pattern, Cwd) when is_list(Pattern), is_list(Cwd) ->
+wildcard(Pattern, Cwd) when is_list(Pattern), (is_list(Cwd) or is_binary(Cwd)) ->
?HANDLE_ERROR(do_wildcard(Pattern, Cwd, file));
wildcard(Pattern, Mod) when is_list(Pattern), is_atom(Mod) ->
?HANDLE_ERROR(do_wildcard(Pattern, Mod)).
-spec wildcard(file:name(), file:name(), atom()) -> [file:filename()].
wildcard(Pattern, Cwd, Mod)
- when is_list(Pattern), is_list(Cwd), is_atom(Mod) ->
+ when is_list(Pattern), (is_list(Cwd) or is_binary(Cwd)), is_atom(Mod) ->
?HANDLE_ERROR(do_wildcard(Pattern, Cwd, Mod)).
-spec is_dir(file:name()) -> boolean().
@@ -118,7 +118,7 @@ do_wildcard_comp({compiled_wildcard,{exists,File}}, Mod) ->
do_wildcard_comp({compiled_wildcard,[Base|Rest]}, Mod) ->
do_wildcard_1([Base], Rest, Mod).
-do_wildcard(Pattern, Cwd, Mod) when is_list(Pattern), is_list(Cwd) ->
+do_wildcard(Pattern, Cwd, Mod) when is_list(Pattern), (is_list(Cwd) or is_binary(Cwd)) ->
do_wildcard_comp(do_compile_wildcard(Pattern), Cwd, Mod).
do_wildcard_comp({compiled_wildcard,{exists,File}}, Cwd, Mod) ->
@@ -127,9 +127,18 @@ do_wildcard_comp({compiled_wildcard,{exists,File}}, Cwd, Mod) ->
_ -> []
end;
do_wildcard_comp({compiled_wildcard,[current|Rest]}, Cwd0, Mod) ->
- Cwd = filename:join([Cwd0]), %Slash away redundant slashes.
- PrefixLen = length(Cwd)+1,
- [lists:nthtail(PrefixLen, N) || N <- do_wildcard_1([Cwd], Rest, Mod)];
+ {Cwd,PrefixLen} = case filename:join([Cwd0]) of
+ Bin when is_binary(Bin) -> {Bin,byte_size(Bin)+1};
+ Other -> {Other,length(Other)+1}
+ end, %Slash away redundant slashes.
+ [
+ if
+ is_binary(N) ->
+ <<_:PrefixLen/binary,Res/binary>> = N,
+ Res;
+ true ->
+ lists:nthtail(PrefixLen, N)
+ end || N <- do_wildcard_1([Cwd], Rest, Mod)];
do_wildcard_comp({compiled_wildcard,[Base|Rest]}, _Cwd, Mod) ->
do_wildcard_1([Base], Rest, Mod).
@@ -166,36 +175,44 @@ do_is_regular(File, Mod) ->
%% If <Recursive> is true all sub-directories to <Dir> are processed
do_fold_files(Dir, RegExp, Recursive, Fun, Acc, Mod) ->
- {ok, Re1} = re:compile(RegExp),
- do_fold_files1(Dir, Re1, Recursive, Fun, Acc, Mod).
+ {ok, Re1} = re:compile(RegExp,[unicode]),
+ do_fold_files1(Dir, Re1, RegExp, Recursive, Fun, Acc, Mod).
-do_fold_files1(Dir, RegExp, Recursive, Fun, Acc, Mod) ->
+do_fold_files1(Dir, RegExp, OrigRE, Recursive, Fun, Acc, Mod) ->
case eval_list_dir(Dir, Mod) of
- {ok, Files} -> do_fold_files2(Files, Dir, RegExp, Recursive, Fun, Acc, Mod);
+ {ok, Files} -> do_fold_files2(Files, Dir, RegExp, OrigRE,
+ Recursive, Fun, Acc, Mod);
{error, _} -> Acc
end.
-do_fold_files2([], _Dir, _RegExp, _Recursive, _Fun, Acc, _Mod) ->
+%% OrigRE is not to be compiled as it's for non conforming filenames,
+%% i.e. for filenames that does not comply to the current encoding, which should
+%% be very rare. We use it only in those cases and do not want to precompile.
+do_fold_files2([], _Dir, _RegExp, _OrigRE, _Recursive, _Fun, Acc, _Mod) ->
Acc;
-do_fold_files2([File|T], Dir, RegExp, Recursive, Fun, Acc0, Mod) ->
+do_fold_files2([File|T], Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod) ->
FullName = filename:join(Dir, File),
case do_is_regular(FullName, Mod) of
true ->
- case re:run(File, RegExp, [{capture,none}]) of
+ case (catch re:run(File, if is_binary(File) -> OrigRE;
+ true -> RegExp end,
+ [{capture,none}])) of
match ->
Acc = Fun(FullName, Acc0),
- do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc, Mod);
+ do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc, Mod);
+ {'EXIT',_} ->
+ do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod);
nomatch ->
- do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc0, Mod)
+ do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod)
end;
false ->
case Recursive andalso do_is_dir(FullName, Mod) of
true ->
- Acc1 = do_fold_files1(FullName, RegExp, Recursive,
+ Acc1 = do_fold_files1(FullName, RegExp, OrigRE, Recursive,
Fun, Acc0, Mod),
- do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc1, Mod);
+ do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc1, Mod);
false ->
- do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc0, Mod)
+ do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod)
end
end.
@@ -268,6 +285,13 @@ do_wildcard_3(Base, [Pattern|Rest], Result, Mod) ->
do_wildcard_3(Base, [], Result, _Mod) ->
[Base|Result].
+wildcard_4(Pattern, [File|Rest], Base, Result) when is_binary(File) ->
+ case wildcard_5(Pattern, binary_to_list(File)) of
+ true ->
+ wildcard_4(Pattern, Rest, Base, [join(Base, File)|Result]);
+ false ->
+ wildcard_4(Pattern, Rest, Base, Result)
+ end;
wildcard_4(Pattern, [File|Rest], Base, Result) ->
case wildcard_5(Pattern, File) of
true ->
diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl
index 01c06e4596..24abf1e977 100644
--- a/lib/stdlib/src/filename.erl
+++ b/lib/stdlib/src/filename.erl
@@ -41,6 +41,9 @@
-include_lib("kernel/include/file.hrl").
+-define(IS_DRIVELETTER(Letter),(((Letter >= $A) andalso (Letter =< $Z)) orelse
+ ((Letter >= $a) andalso (Letter =< $z)))).
+
%% Converts a relative filename to an absolute filename
%% or the filename itself if it already is an absolute filename
%% Note that no attempt is made to create the most beatiful
@@ -57,12 +60,18 @@
%% (for Unix) : absname("/") -> "/"
%% (for WIN32): absname("/") -> "D:/"
--spec absname(file:name()) -> string().
+
+-spec absname(file:name()) -> file:filename().
absname(Name) ->
{ok, Cwd} = file:get_cwd(),
absname(Name, Cwd).
--spec absname(file:name(), string()) -> string().
+-spec absname(file:name(), file:filename()) -> file:filename().
+absname(Name, AbsBase) when is_binary(Name), is_list(AbsBase) ->
+ absname(Name,filename_string_to_binary(AbsBase));
+absname(Name, AbsBase) when is_list(Name), is_binary(AbsBase) ->
+ absname(filename_string_to_binary(Name),AbsBase);
+
absname(Name, AbsBase) ->
case pathtype(Name) of
relative ->
@@ -77,6 +86,20 @@ absname(Name, AbsBase) ->
%% Handles volumerelative names (on Windows only).
+absname_vr([<<"/">>|Rest1], [Volume|_], _AbsBase) ->
+ %% Absolute path on current drive.
+ join([Volume|Rest1]);
+absname_vr([<<X, $:>>|Rest1], [<<X,_/binary>>|_], AbsBase) ->
+ %% Relative to current directory on current drive.
+ absname(join(Rest1), AbsBase);
+absname_vr([<<X, $:>>|Name], _, _AbsBase) ->
+ %% Relative to current directory on another drive.
+ Dcwd =
+ case file:get_cwd([X, $:]) of
+ {ok, Dir} -> filename_string_to_binary(Dir);
+ {error, _} -> <<X, $:, $/>>
+ end,
+ absname(join(Name), Dcwd);
absname_vr(["/"|Rest1], [Volume|_], _AbsBase) ->
%% Absolute path on current drive.
join([Volume|Rest1]);
@@ -92,41 +115,13 @@ absname_vr([[X, $:]|Name], _, _AbsBase) ->
end,
absname(join(Name), Dcwd).
-%% Joins a relative filename to an absolute base. For VxWorks the
-%% resulting name is fixed to minimize the length by collapsing
-%% ".." directories.
-%% For other systems this is just a join/2, but assumes that
+%% Joins a relative filename to an absolute base.
+%% This is just a join/2, but assumes that
%% AbsBase must be absolute and Name must be relative.
--spec absname_join(string(), file:name()) -> string().
+-spec absname_join(file:filename(), file:name()) -> file:filename().
absname_join(AbsBase, Name) ->
- case major_os_type() of
- vxworks ->
- absname_pretty(AbsBase, split(Name), lists:reverse(split(AbsBase)));
- _Else ->
- join(AbsBase, flatten(Name))
- end.
-
-%% Handles absolute filenames for VxWorks - these are 'pretty-printed',
-%% since a C function call chdir("/erlang/lib/../bin") really sets
-%% cwd to '/erlang/lib/../bin' which also works, but the long term
-%% effect is potentially not so good ...
-%%
-%% absname_pretty("../bin", "/erlang/lib") -> "/erlang/bin"
-%% absname_pretty("../../../..", "/erlang") -> "/erlang"
-
-absname_pretty(Abspath, Relpath, []) ->
- %% AbsBase _must_ begin with a vxworks device name
- {device, _Rest, Dev} = vxworks_first(Abspath),
- absname_pretty(Abspath, Relpath, [lists:reverse(Dev)]);
-absname_pretty(_Abspath, [], AbsBase) ->
- join(lists:reverse(AbsBase));
-absname_pretty(Abspath, [[$.]|Rest], AbsBase) ->
- absname_pretty(Abspath, Rest, AbsBase);
-absname_pretty(Abspath, [[$.,$.]|Rest], [_|AbsRest]) ->
- absname_pretty(Abspath, Rest, AbsRest);
-absname_pretty(Abspath, [First|Rest], AbsBase) ->
- absname_pretty(Abspath, Rest, [First|AbsBase]).
+ join(AbsBase, flatten(Name)).
%% Returns the part of the filename after the last directory separator,
%% or the filename itself if it has no separators.
@@ -136,18 +131,40 @@ absname_pretty(Abspath, [First|Rest], AbsBase) ->
%% basename("/usr/foo/") -> "foo" (trailing slashes ignored)
%% basename("/") -> []
--spec basename(file:name()) -> string().
+-spec basename(file:name()) -> file:filename().
+basename(Name) when is_binary(Name) ->
+ case os:type() of
+ {win32,_} ->
+ win_basenameb(Name);
+ _ ->
+ basenameb(Name,[<<"/">>])
+ end;
+
basename(Name0) ->
Name = flatten(Name0),
{DirSep2, DrvSep} = separators(),
basename1(skip_prefix(Name, DrvSep), [], DirSep2).
+win_basenameb(<<Letter,$:,Rest/binary>>) when ?IS_DRIVELETTER(Letter) ->
+ basenameb(Rest,[<<"/">>,<<"\\">>]);
+win_basenameb(O) ->
+ basenameb(O,[<<"/">>,<<"\\">>]).
+basenameb(Bin,Sep) ->
+ Parts = [ X || X <- binary:split(Bin,Sep,[global]),
+ X =/= <<>> ],
+ if
+ Parts =:= [] ->
+ <<>>;
+ true ->
+ lists:last(Parts)
+ end.
+
+
+
basename1([$/|[]], Tail, DirSep2) ->
basename1([], Tail, DirSep2);
basename1([$/|Rest], _Tail, DirSep2) ->
basename1(Rest, [], DirSep2);
-basename1([[_|_]=List|Rest], Tail, DirSep2) ->
- basename1(List++Rest, Tail, DirSep2);
basename1([DirSep2|Rest], Tail, DirSep2) when is_integer(DirSep2) ->
basename1([$/|Rest], Tail, DirSep2);
basename1([Char|Rest], Tail, DirSep2) when is_integer(Char) ->
@@ -155,26 +172,11 @@ basename1([Char|Rest], Tail, DirSep2) when is_integer(Char) ->
basename1([], Tail, _DirSep2) ->
lists:reverse(Tail).
-skip_prefix(Name, false) -> % No prefix for unix, but for VxWorks.
- case major_os_type() of
- vxworks ->
- case vxworks_first(Name) of
- {device, Rest, _Device} ->
- Rest;
- {not_device, _Rest, _First} ->
- Name
- end;
- _Else ->
- Name
- end;
-skip_prefix(Name, DrvSep) ->
- skip_prefix1(Name, DrvSep).
-
-skip_prefix1([L, DrvSep|Name], DrvSep) when is_integer(L) ->
+skip_prefix(Name, false) ->
Name;
-skip_prefix1([L], _) when is_integer(L) ->
- [L];
-skip_prefix1(Name, _) ->
+skip_prefix([L, DrvSep|Name], DrvSep) when ?IS_DRIVELETTER(L) ->
+ Name;
+skip_prefix(Name, _) ->
Name.
%% Returns the last component of the filename, with the given
@@ -190,7 +192,29 @@ skip_prefix1(Name, _) ->
%% rootname(basename("xxx.jam")) -> "xxx"
%% rootname(basename("xxx.erl")) -> "xxx"
--spec basename(file:name(), file:name()) -> string().
+-spec basename(file:name(), file:name()) -> file:filename().
+basename(Name, Ext) when is_binary(Name), is_list(Ext) ->
+ basename(Name,filename_string_to_binary(Ext));
+basename(Name, Ext) when is_list(Name), is_binary(Ext) ->
+ basename(filename_string_to_binary(Name),Ext);
+basename(Name, Ext) when is_binary(Name), is_binary(Ext) ->
+ BName = basename(Name),
+ LAll = byte_size(Name),
+ LN = byte_size(BName),
+ LE = byte_size(Ext),
+ case LN - LE of
+ Neg when Neg < 0 ->
+ BName;
+ Pos ->
+ StartLen = LAll - Pos - LE,
+ case Name of
+ <<_:StartLen/binary,Part:Pos/binary,Ext/binary>> ->
+ Part;
+ _Other ->
+ BName
+ end
+ end;
+
basename(Name0, Ext0) ->
Name = flatten(Name0),
Ext = flatten(Ext0),
@@ -204,7 +228,7 @@ basename([$/|[]], Ext, Tail, DrvSep2) ->
basename([], Ext, Tail, DrvSep2);
basename([$/|Rest], Ext, _Tail, DrvSep2) ->
basename(Rest, Ext, [], DrvSep2);
-basename([$\\|Rest], Ext, Tail, DirSep2) when is_integer(DirSep2) ->
+basename([DirSep2|Rest], Ext, Tail, DirSep2) when is_integer(DirSep2) ->
basename([$/|Rest], Ext, Tail, DirSep2);
basename([Char|Rest], Ext, Tail, DrvSep2) when is_integer(Char) ->
basename(Rest, Ext, [Char|Tail], DrvSep2);
@@ -216,24 +240,44 @@ basename([], _Ext, Tail, _DrvSep2) ->
%% Example: dirname("/usr/src/kalle.erl") -> "/usr/src",
%% dirname("kalle.erl") -> "."
--spec dirname(file:name()) -> string().
+-spec dirname(file:name()) -> file:filename().
+dirname(Name) when is_binary(Name) ->
+ {Dsep,Drivesep} = separators(),
+ SList = case Dsep of
+ Sep when is_integer(Sep) ->
+ [ <<Sep>> ];
+ _ ->
+ []
+ end,
+ {XPart0,Dirs} = case Drivesep of
+ X when is_integer(X) ->
+ case Name of
+ <<DL,X,Rest/binary>> when ?IS_DRIVELETTER(DL) ->
+ {<<DL,X>>,Rest};
+ _ ->
+ {<<>>,Name}
+ end;
+ _ ->
+ {<<>>,Name}
+ end,
+ Parts0 = binary:split(Dirs,[<<"/">>|SList],[global]),
+ %% Fairly short lists of parts, OK to reverse twice...
+ Parts = case Parts0 of
+ [] -> [];
+ _ -> lists:reverse(fstrip(tl(lists:reverse(Parts0))))
+ end,
+ XPart = case {Parts,XPart0} of
+ {[],<<>>} ->
+ <<".">>;
+ _ ->
+ XPart0
+ end,
+ dirjoin(Parts,XPart,<<"/">>);
+
dirname(Name0) ->
Name = flatten(Name0),
- case os:type() of
- vxworks ->
- {Devicep, Restname, FirstComp} = vxworks_first(Name),
- case Devicep of
- device ->
- dirname(Restname, FirstComp, [], separators());
- _ ->
- dirname(Name, [], [], separators())
- end;
- _ ->
- dirname(Name, [], [], separators())
- end.
+ dirname(Name, [], [], separators()).
-dirname([[_|_]=List|Rest], Dir, File, Seps) ->
- dirname(List++Rest, Dir, File, Seps);
dirname([$/|Rest], Dir, File, Seps) ->
dirname(Rest, File++Dir, [$/], Seps);
dirname([DirSep|Rest], Dir, File, {DirSep,_}=Seps) when is_integer(DirSep) ->
@@ -258,6 +302,26 @@ dirname([], [DrvSep,Dl], File, {_,DrvSep}) ->
end;
dirname([], Dir, _, _) ->
lists:reverse(Dir).
+
+%% Compatibility with lists variant, remove trailing slashes
+fstrip([<<>>,X|Y]) ->
+ fstrip([X|Y]);
+fstrip(A) ->
+ A.
+
+
+dirjoin([<<>>|T],Acc,Sep) ->
+ dirjoin1(T,<<Acc/binary,"/">>,Sep);
+dirjoin(A,B,C) ->
+ dirjoin1(A,B,C).
+
+dirjoin1([],Acc,_) ->
+ Acc;
+dirjoin1([One],Acc,_) ->
+ <<Acc/binary,One/binary>>;
+dirjoin1([H|T],Acc,Sep) ->
+ dirjoin(T,<<Acc/binary,H/binary,Sep/binary>>,Sep).
+
%% Given a filename string, returns the file extension,
%% including the period. Returns an empty list if there
@@ -268,7 +332,29 @@ dirname([], Dir, _, _) ->
%%
%% On Windows: fn:dirname("\\usr\\src/kalle.erl") -> "/usr/src"
--spec extension(file:name()) -> string().
+-spec extension(file:name()) -> file:filename().
+extension(Name) when is_binary(Name) ->
+ {Dsep,_} = separators(),
+ SList = case Dsep of
+ Sep when is_integer(Sep) ->
+ [ <<Sep>> ];
+ _ ->
+ []
+ end,
+ case binary:matches(Name,[<<".">>]) of
+ [] ->
+ <<>>;
+ List ->
+ {Pos,_} = lists:last(List),
+ <<_:Pos/binary,Part/binary>> = Name,
+ case binary:match(Part,[<<"/">>|SList]) of
+ nomatch ->
+ Part;
+ _ ->
+ <<>>
+ end
+ end;
+
extension(Name0) ->
Name = flatten(Name0),
extension(Name, [], major_os_type()).
@@ -281,8 +367,6 @@ extension([$/|Rest], _Result, OsType) ->
extension(Rest, [], OsType);
extension([$\\|Rest], _Result, win32) ->
extension(Rest, [], win32);
-extension([$\\|Rest], _Result, vxworks) ->
- extension(Rest, [], vxworks);
extension([Char|Rest], Result, OsType) when is_integer(Char) ->
extension(Rest, [Char|Result], OsType);
extension([], Result, _OsType) ->
@@ -290,23 +374,36 @@ extension([], Result, _OsType) ->
%% Joins a list of filenames with directory separators.
--spec join([string()]) -> string().
+-spec join([file:filename()]) -> file:filename().
join([Name1, Name2|Rest]) ->
join([join(Name1, Name2)|Rest]);
join([Name]) when is_list(Name) ->
join1(Name, [], [], major_os_type());
+join([Name]) when is_binary(Name) ->
+ join1b(Name, <<>>, [], major_os_type());
join([Name]) when is_atom(Name) ->
join([atom_to_list(Name)]).
%% Joins two filenames with directory separators.
--spec join(string(), string()) -> string().
+-spec join(file:filename(), file:filename()) -> file:filename().
join(Name1, Name2) when is_list(Name1), is_list(Name2) ->
OsType = major_os_type(),
case pathtype(Name2) of
relative -> join1(Name1, Name2, [], OsType);
_Other -> join1(Name2, [], [], OsType)
end;
+join(Name1, Name2) when is_binary(Name1), is_list(Name2) ->
+ join(Name1,filename_string_to_binary(Name2));
+join(Name1, Name2) when is_list(Name1), is_binary(Name2) ->
+ join(filename_string_to_binary(Name1),Name2);
+join(Name1, Name2) when is_binary(Name1), is_binary(Name2) ->
+ OsType = major_os_type(),
+ case pathtype(Name2) of
+ relative -> join1b(Name1, Name2, [], OsType);
+ _Other -> join1b(Name2, <<>>, [], OsType)
+ end;
+
join(Name1, Name2) when is_atom(Name1) ->
join(atom_to_list(Name1), Name2);
join(Name1, Name2) when is_atom(Name2) ->
@@ -321,8 +418,6 @@ when is_integer(UcLetter), UcLetter >= $A, UcLetter =< $Z ->
join1(Rest, RelativeName, [$:, UcLetter+$a-$A], win32);
join1([$\\|Rest], RelativeName, Result, win32) ->
join1([$/|Rest], RelativeName, Result, win32);
-join1([$\\|Rest], RelativeName, Result, vxworks) ->
- join1([$/|Rest], RelativeName, Result, vxworks);
join1([$/|Rest], RelativeName, [$., $/|Result], OsType) ->
join1(Rest, RelativeName, [$/|Result], OsType);
join1([$/|Rest], RelativeName, [$/|Result], OsType) ->
@@ -344,6 +439,26 @@ join1([Char|Rest], RelativeName, Result, OsType) when is_integer(Char) ->
join1([Atom|Rest], RelativeName, Result, OsType) when is_atom(Atom) ->
join1(atom_to_list(Atom)++Rest, RelativeName, Result, OsType).
+join1b(<<UcLetter, $:, Rest/binary>>, RelativeName, [], win32)
+when is_integer(UcLetter), UcLetter >= $A, UcLetter =< $Z ->
+ join1b(Rest, RelativeName, [$:, UcLetter+$a-$A], win32);
+join1b(<<$\\,Rest/binary>>, RelativeName, Result, win32) ->
+ join1b(<<$/,Rest/binary>>, RelativeName, Result, win32);
+join1b(<<$/,Rest/binary>>, RelativeName, [$., $/|Result], OsType) ->
+ join1b(Rest, RelativeName, [$/|Result], OsType);
+join1b(<<$/,Rest/binary>>, RelativeName, [$/|Result], OsType) ->
+ join1b(Rest, RelativeName, [$/|Result], OsType);
+join1b(<<>>, <<>>, Result, OsType) ->
+ list_to_binary(maybe_remove_dirsep(Result, OsType));
+join1b(<<>>, RelativeName, [$:|Rest], win32) ->
+ join1b(RelativeName, <<>>, [$:|Rest], win32);
+join1b(<<>>, RelativeName, [$/|Result], OsType) ->
+ join1b(RelativeName, <<>>, [$/|Result], OsType);
+join1b(<<>>, RelativeName, Result, OsType) ->
+ join1b(RelativeName, <<>>, [$/|Result], OsType);
+join1b(<<Char,Rest/binary>>, RelativeName, Result, OsType) when is_integer(Char) ->
+ join1b(Rest, RelativeName, [Char|Result], OsType).
+
maybe_remove_dirsep([$/, $:, Letter], win32) ->
[Letter, $:, $/];
maybe_remove_dirsep([$/], _) ->
@@ -357,7 +472,13 @@ maybe_remove_dirsep(Name, _) ->
%% a given base directory, which is is assumed to be normalised
%% by a previous call to join/{1,2}.
--spec append(string(), file:name()) -> string().
+-spec append(file:filename(), file:name()) -> file:filename().
+append(Dir, Name) when is_binary(Dir), is_binary(Name) ->
+ <<Dir/binary,$/:8,Name/binary>>;
+append(Dir, Name) when is_binary(Dir) ->
+ append(Dir,filename_string_to_binary(Name));
+append(Dir, Name) when is_binary(Name) ->
+ append(filename_string_to_binary(Dir),Name);
append(Dir, Name) ->
Dir ++ [$/|Name].
@@ -376,19 +497,14 @@ append(Dir, Name) ->
-spec pathtype(file:name()) -> 'absolute' | 'relative' | 'volumerelative'.
pathtype(Atom) when is_atom(Atom) ->
pathtype(atom_to_list(Atom));
-pathtype(Name) when is_list(Name) ->
+pathtype(Name) when is_list(Name) or is_binary(Name) ->
case os:type() of
{unix, _} -> unix_pathtype(Name);
- {win32, _} -> win32_pathtype(Name);
- vxworks -> case vxworks_first(Name) of
- {device, _Rest, _Dev} ->
- absolute;
- _ ->
- relative
- end;
- {ose,_} -> unix_pathtype(Name)
+ {win32, _} -> win32_pathtype(Name)
end.
+unix_pathtype(<<$/,_/binary>>) ->
+ absolute;
unix_pathtype([$/|_]) ->
absolute;
unix_pathtype([List|Rest]) when is_list(List) ->
@@ -404,6 +520,15 @@ win32_pathtype([Atom|Rest]) when is_atom(Atom) ->
win32_pathtype(atom_to_list(Atom)++Rest);
win32_pathtype([Char, List|Rest]) when is_list(List) ->
win32_pathtype([Char|List++Rest]);
+win32_pathtype(<<$/, $/, _/binary>>) -> absolute;
+win32_pathtype(<<$\\, $/, _/binary>>) -> absolute;
+win32_pathtype(<<$/, $\\, _/binary>>) -> absolute;
+win32_pathtype(<<$\\, $\\, _/binary>>) -> absolute;
+win32_pathtype(<<$/, _/binary>>) -> volumerelative;
+win32_pathtype(<<$\\, _/binary>>) -> volumerelative;
+win32_pathtype(<<_Letter, $:, $/, _/binary>>) -> absolute;
+win32_pathtype(<<_Letter, $:, $\\, _/binary>>) -> absolute;
+win32_pathtype(<<_Letter, $:, _/binary>>) -> volumerelative;
win32_pathtype([$/, $/|_]) -> absolute;
win32_pathtype([$\\, $/|_]) -> absolute;
win32_pathtype([$/, $\\|_]) -> absolute;
@@ -422,7 +547,9 @@ win32_pathtype(_) -> relative.
%% Examples: rootname("/jam.src/kalle") -> "/jam.src/kalle"
%% rootname("/jam.src/foo.erl") -> "/jam.src/foo"
--spec rootname(file:name()) -> string().
+-spec rootname(file:name()) -> file:filename().
+rootname(Name) when is_binary(Name) ->
+ list_to_binary(rootname(binary_to_list(Name))); % No need to handle unicode, . is < 128
rootname(Name0) ->
Name = flatten(Name0),
rootname(Name, [], [], major_os_type()).
@@ -431,8 +558,6 @@ rootname([$/|Rest], Root, Ext, OsType) ->
rootname(Rest, [$/]++Ext++Root, [], OsType);
rootname([$\\|Rest], Root, Ext, win32) ->
rootname(Rest, [$/]++Ext++Root, [], win32);
-rootname([$\\|Rest], Root, Ext, vxworks) ->
- rootname(Rest, [$/]++Ext++Root, [], vxworks);
rootname([$.|Rest], Root, [], OsType) ->
rootname(Rest, Root, ".", OsType);
rootname([$.|Rest], Root, Ext, OsType) ->
@@ -451,7 +576,13 @@ rootname([], Root, _Ext, _OsType) ->
%% Examples: rootname("/jam.src/kalle.jam", ".erl") -> "/jam.src/kalle.jam"
%% rootname("/jam.src/foo.erl", ".erl") -> "/jam.src/foo"
--spec rootname(file:name(), file:name()) -> string().
+-spec rootname(file:name(), file:name()) -> file:filename().
+rootname(Name, Ext) when is_binary(Name), is_binary(Ext) ->
+ list_to_binary(rootname(binary_to_list(Name),binary_to_list(Ext)));
+rootname(Name, Ext) when is_binary(Name) ->
+ rootname(Name,filename_string_to_binary(Ext));
+rootname(Name, Ext) when is_binary(Ext) ->
+ rootname(filename_string_to_binary(Name),Ext);
rootname(Name0, Ext0) ->
Name = flatten(Name0),
Ext = flatten(Ext0),
@@ -471,27 +602,55 @@ rootname2([Char|Rest], Ext, Result) when is_integer(Char) ->
%% split("foo/bar") -> ["foo", "bar"]
%% split("a:\\msdev\\include") -> ["a:/", "msdev", "include"]
--spec split(file:name()) -> [string()].
+-spec split(file:name()) -> [file:filename()].
+split(Name) when is_binary(Name) ->
+ case os:type() of
+ {win32, _} -> win32_splitb(Name);
+ _ -> unix_splitb(Name)
+ end;
+
split(Name0) ->
Name = flatten(Name0),
case os:type() of
- {unix, _} -> unix_split(Name);
{win32, _} -> win32_split(Name);
- vxworks -> vxworks_split(Name);
- {ose,_} -> unix_split(Name)
+ _ -> unix_split(Name)
end.
-%% If a VxWorks filename starts with '[/\].*[^/\]' '[/\].*:' or '.*:'
-%% that part of the filename is considered a device.
-%% The rest of the name is interpreted exactly as for win32.
-%% XXX - dirty solution to make filename:split([]) return the same thing on
-%% VxWorks as on unix and win32.
-vxworks_split([]) ->
- [];
-vxworks_split(L) ->
- {_Devicep, Rest, FirstComp} = vxworks_first(L),
- split(Rest, [], [lists:reverse(FirstComp)], win32).
+unix_splitb(Name) ->
+ L = binary:split(Name,[<<"/">>],[global]),
+ LL = case L of
+ [<<>>|Rest] ->
+ [<<"/">>|Rest];
+ _ ->
+ L
+ end,
+ [ X || X <- LL, X =/= <<>>].
+
+
+fix_driveletter(Letter0) ->
+ if
+ Letter0 >= $A, Letter0 =< $Z ->
+ Letter0+$a-$A;
+ true ->
+ Letter0
+ end.
+win32_splitb(<<Letter0,$:, Slash, Rest/binary>>) when (((Slash =:= $\\) orelse (Slash =:= $/)) andalso
+ ?IS_DRIVELETTER(Letter0)) ->
+ Letter = fix_driveletter(Letter0),
+ L = binary:split(Rest,[<<"/">>,<<"\\">>],[global]),
+ [<<Letter,$:,$/>> | [ X || X <- L, X =/= <<>> ]];
+win32_splitb(<<Letter0,$:,Rest/binary>>) when ?IS_DRIVELETTER(Letter0) ->
+ Letter = fix_driveletter(Letter0),
+ L = binary:split(Rest,[<<"/">>,<<"\\">>],[global]),
+ [<<Letter,$:>> | [ X || X <- L, X =/= <<>> ]];
+win32_splitb(<<Slash,Rest/binary>>) when ((Slash =:= $\\) orelse (Slash =:= $/)) ->
+ L = binary:split(Rest,[<<"/">>,<<"\\">>],[global]),
+ [<<$/>> | [ X || X <- L, X =/= <<>> ]];
+win32_splitb(Name) ->
+ L = binary:split(Name,[<<"/">>,<<"\\">>],[global]),
+ [ X || X <- L, X =/= <<>> ].
+
unix_split(Name) ->
split(Name, [], unix).
@@ -502,8 +661,6 @@ win32_split([X, $\\|Rest]) when is_integer(X) ->
win32_split([X, $/|Rest]);
win32_split([X, Y, $\\|Rest]) when is_integer(X), is_integer(Y) ->
win32_split([X, Y, $/|Rest]);
-win32_split([$/, $/|Rest]) ->
- split(Rest, [], [[$/, $/]]);
win32_split([UcLetter, $:|Rest]) when UcLetter >= $A, UcLetter =< $Z ->
win32_split([UcLetter+$a-$A, $:|Rest]);
win32_split([Letter, $:, $/|Rest]) ->
@@ -528,8 +685,6 @@ split([$/|Rest], Comp, Components, OsType) ->
split(Rest, [], [lists:reverse(Comp)|Components], OsType);
split([Char|Rest], Comp, Components, OsType) when is_integer(Char) ->
split(Rest, [Char|Comp], Components, OsType);
-split([List|Rest], Comp, Components, OsType) when is_list(List) ->
- split(List++Rest, Comp, Components, OsType);
split([], [], Components, _OsType) ->
lists:reverse(Components);
split([], Comp, Components, OsType) ->
@@ -540,7 +695,7 @@ split([], Comp, Components, OsType) ->
%% will be converted to backslashes. On all platforms, the
%% name will be normalized as done by join/1.
--spec nativename(string()) -> string().
+-spec nativename(file:filename()) -> file:filename().
nativename(Name0) ->
Name = join([Name0]), %Normalize.
case os:type() of
@@ -557,13 +712,12 @@ win32_nativename([]) ->
separators() ->
case os:type() of
- {unix, _} -> {false, false};
{win32, _} -> {$\\, $:};
- vxworks -> {$\\, false};
- {ose,_} -> {false, false}
+ _ -> {false, false}
end.
+
%% find_src(Module) --
%% find_src(Module, Rules) --
%%
@@ -733,45 +887,12 @@ major_os_type() ->
OsT -> OsT
end.
-%% Need to take care of the first pathname component separately
-%% due to VxWorks less than good device naming rules.
-%% (i.e. this is VxWorks specific ...)
-%% The following four all starts with device names
-%% elrond:/foo -> elrond:
-%% elrond:\\foo.bar -> elrond:
-%% /DISK1:foo -> /DISK1:
-%% /usr/include -> /usr
-%% This one doesn't:
-%% foo/bar
-
-vxworks_first([]) ->
- {not_device, [], []};
-vxworks_first([$/|T]) ->
- vxworks_first2(device, T, [$/]);
-vxworks_first([$\\|T]) ->
- vxworks_first2(device, T, [$/]);
-vxworks_first([H|T]) when is_list(H) ->
- vxworks_first(H++T);
-vxworks_first([H|T]) ->
- vxworks_first2(not_device, T, [H]).
-
-vxworks_first2(Devicep, [], FirstComp) ->
- {Devicep, [], FirstComp};
-vxworks_first2(Devicep, [$/|T], FirstComp) ->
- {Devicep, [$/|T], FirstComp};
-vxworks_first2(Devicep, [$\\|T], FirstComp) ->
- {Devicep, [$/|T], FirstComp};
-vxworks_first2(_Devicep, [$:|T], FirstComp)->
- {device, T, [$:|FirstComp]};
-vxworks_first2(Devicep, [H|T], FirstComp) when is_list(H) ->
- vxworks_first2(Devicep, H++T, FirstComp);
-vxworks_first2(Devicep, [H|T], FirstComp) ->
- vxworks_first2(Devicep, T, [H|FirstComp]).
-
%% flatten(List)
%% Flatten a list, also accepting atoms.
--spec flatten(file:name()) -> string().
+-spec flatten(file:name()) -> file:filename().
+flatten(Bin) when is_binary(Bin) ->
+ Bin;
flatten(List) ->
do_flatten(List, []).
@@ -785,3 +906,12 @@ do_flatten([], Tail) ->
Tail;
do_flatten(Atom, Tail) when is_atom(Atom) ->
atom_to_list(Atom) ++ flatten(Tail).
+
+filename_string_to_binary(List) ->
+ case unicode:characters_to_binary(flatten(List),unicode,file:native_name_encoding()) of
+ {error,_,_} ->
+ erlang:error(badarg);
+ Bin when is_binary(Bin) ->
+ Bin
+ end.
+
diff --git a/lib/stdlib/src/gb_sets.erl b/lib/stdlib/src/gb_sets.erl
index 086dc79b46..113f29e252 100644
--- a/lib/stdlib/src/gb_sets.erl
+++ b/lib/stdlib/src/gb_sets.erl
@@ -657,7 +657,7 @@ intersection_2([], _, As, S) ->
intersection_2(_, [], As, S) ->
{S, balance_revlist(As, S)}.
--spec intersection([gb_set()]) -> gb_set().
+-spec intersection([gb_set(),...]) -> gb_set().
intersection([S | Ss]) ->
intersection_list(S, Ss).
diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl
index 1d0f9374bc..3efa68ca09 100644
--- a/lib/stdlib/src/io.erl
+++ b/lib/stdlib/src/io.erl
@@ -39,6 +39,8 @@
-type device() :: atom() | pid().
-type prompt() :: atom() | string().
+-type error_description() :: term(). % Whatever the io-server sends.
+-type request_error() :: {'error',error_description()}.
%% XXX: Some uses of line() in this file may need to read erl_scan:location()
-type line() :: pos_integer().
@@ -53,26 +55,12 @@
to_tuple(T) when is_tuple(T) -> T;
to_tuple(T) -> {T}.
-%% Problem: the variables Other, Name and Args may collide with surrounding
-%% ones.
-%% Give extra args to macro, being the variables to use.
--define(O_REQUEST(Io, Request),
- case request(Io, Request) of
- {error, Reason} ->
- [Name | Args] = tuple_to_list(to_tuple(Request)),
- erlang:error(conv_reason(Name, Reason), [Name, Io | Args]);
- Other ->
- Other
- end).
-
o_request(Io, Request, Func) ->
case request(Io, Request) of
{error, Reason} ->
[_Name | Args] = tuple_to_list(to_tuple(Request)),
- {'EXIT',{undef,[_Current|Mfas]}} = (catch erlang:error(undef)),
- MFA = {io, Func, [Io | Args]},
- exit({conv_reason(Func, Reason),[MFA|Mfas]});
-% erlang:error(conv_reason(Name, Reason), [Name, Io | Args]);
+ {'EXIT',{get_stacktrace,[_Current|Mfas]}} = (catch erlang:error(get_stacktrace)),
+ erlang:raise(error, conv_reason(Func, Reason), [{io, Func, [Io | Args]}|Mfas]);
Other ->
Other
end.
@@ -299,32 +287,32 @@ format(Io, Format, Args) ->
%% Scanning Erlang code.
--spec scan_erl_exprs(prompt()) -> erl_scan:tokens_result().
+-spec scan_erl_exprs(prompt()) -> erl_scan:tokens_result() | request_error().
scan_erl_exprs(Prompt) ->
scan_erl_exprs(default_input(), Prompt, 1).
--spec scan_erl_exprs(device(), prompt()) -> erl_scan:tokens_result().
+-spec scan_erl_exprs(device(), prompt()) -> erl_scan:tokens_result() | request_error().
scan_erl_exprs(Io, Prompt) ->
scan_erl_exprs(Io, Prompt, 1).
--spec scan_erl_exprs(device(), prompt(), line()) -> erl_scan:tokens_result().
+-spec scan_erl_exprs(device(), prompt(), line()) -> erl_scan:tokens_result() | request_error().
scan_erl_exprs(Io, Prompt, Pos0) ->
request(Io, {get_until,unicode,Prompt,erl_scan,tokens,[Pos0]}).
--spec scan_erl_form(prompt()) -> erl_scan:tokens_result().
+-spec scan_erl_form(prompt()) -> erl_scan:tokens_result() | request_error().
scan_erl_form(Prompt) ->
scan_erl_form(default_input(), Prompt, 1).
--spec scan_erl_form(device(), prompt()) -> erl_scan:tokens_result().
+-spec scan_erl_form(device(), prompt()) -> erl_scan:tokens_result() | request_error().
scan_erl_form(Io, Prompt) ->
scan_erl_form(Io, Prompt, 1).
--spec scan_erl_form(device(), prompt(), line()) -> erl_scan:tokens_result().
+-spec scan_erl_form(device(), prompt(), line()) -> erl_scan:tokens_result() | request_error().
scan_erl_form(Io, Prompt, Pos0) ->
request(Io, {get_until,unicode,Prompt,erl_scan,tokens,[Pos0]}).
@@ -335,7 +323,8 @@ scan_erl_form(Io, Prompt, Pos0) ->
-type parse_ret() :: {'ok', erl_parse_expr_list(), line()}
| {'eof', line()}
- | {'error', erl_scan:error_info(), line()}.
+ | {'error', erl_scan:error_info(), line()}
+ | request_error().
-spec parse_erl_exprs(prompt()) -> parse_ret().
@@ -364,7 +353,8 @@ parse_erl_exprs(Io, Prompt, Pos0) ->
-type parse_form_ret() :: {'ok', erl_parse_absform(), line()}
| {'eof', line()}
- | {'error', erl_scan:error_info(), line()}.
+ | {'error', erl_scan:error_info(), line()}
+ | request_error().
-spec parse_erl_form(prompt()) -> parse_form_ret().
diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl
index 08ee595f4d..c669c1f7c1 100644
--- a/lib/stdlib/src/lists.erl
+++ b/lib/stdlib/src/lists.erl
@@ -350,7 +350,7 @@ sort_1(X, [], R) ->
%% merge(List) -> L
%% merges a list of sorted lists
--spec merge([T]) -> [T].
+-spec merge([[T]]) -> [T].
merge(L) ->
mergel(L, []).
@@ -358,7 +358,7 @@ merge(L) ->
%% merge3(X, Y, Z) -> L
%% merges three sorted lists X, Y and Z
--spec merge3([_], [_], [_]) -> [_].
+-spec merge3([X], [Y], [Z]) -> [(X | Y | Z)].
merge3(L1, [], L3) ->
merge(L1, L3);
@@ -370,7 +370,7 @@ merge3(L1, [H2 | T2], [H3 | T3]) ->
%% rmerge3(X, Y, Z) -> L
%% merges three reversed sorted lists X, Y and Z
--spec rmerge3([_], [_], [_]) -> [_].
+-spec rmerge3([X], [Y], [Z]) -> [(X | Y | Z)].
rmerge3(L1, [], L3) ->
rmerge(L1, L3);
@@ -382,7 +382,7 @@ rmerge3(L1, [H2 | T2], [H3 | T3]) ->
%% merge(X, Y) -> L
%% merges two sorted lists X and Y
--spec merge([_], [_]) -> [_].
+-spec merge([X], [Y]) -> [(X | Y)].
merge(T1, []) ->
T1;
@@ -394,7 +394,7 @@ merge(T1, [H2 | T2]) ->
%% reverse(rmerge(reverse(A),reverse(B))) is equal to merge(I,A,B).
--spec rmerge([_], [_]) -> [_].
+-spec rmerge([X], [Y]) -> [(X | Y)].
rmerge(T1, []) ->
T1;
@@ -420,12 +420,12 @@ thing_to_list(X) when is_list(X) -> X. %Assumed to be a string
%% flatten(List, Tail)
%% Flatten a list, adding optional tail.
--spec flatten([_]) -> [_].
+-spec flatten([term()]) -> [term()].
flatten(List) when is_list(List) ->
do_flatten(List, []).
--spec flatten([_], [_]) -> [_].
+-spec flatten([term()], [term()]) -> [term()].
flatten(List, Tail) when is_list(List), is_list(Tail) ->
do_flatten(List, Tail).
@@ -440,7 +440,7 @@ do_flatten([], Tail) ->
%% flatlength(List)
%% Calculate the length of a list of lists.
--spec flatlength([_]) -> non_neg_integer().
+-spec flatlength([term()]) -> non_neg_integer().
flatlength(List) ->
flatlength(List, 0).
@@ -481,7 +481,7 @@ flatlength([], L) -> L.
% keysearch3(Key, N, T);
%keysearch3(Key, N, []) -> false.
--spec keydelete(_, pos_integer(), [T]) -> [T].
+-spec keydelete(term(), pos_integer(), [T]) -> [T] when T :: tuple().
keydelete(K, N, L) when is_integer(N), N > 0 ->
keydelete3(K, N, L).
@@ -491,7 +491,7 @@ keydelete3(Key, N, [H|T]) ->
[H|keydelete3(Key, N, T)];
keydelete3(_, _, []) -> [].
--spec keyreplace(_, pos_integer(), [_], tuple()) -> [_].
+-spec keyreplace(term(), pos_integer(), [tuple()], tuple()) -> [tuple()].
keyreplace(K, N, L, New) when is_integer(N), N > 0, is_tuple(New) ->
keyreplace3(K, N, L, New).
@@ -502,7 +502,8 @@ keyreplace3(Key, Pos, [H|T], New) ->
[H|keyreplace3(Key, Pos, T, New)];
keyreplace3(_, _, [], _) -> [].
--spec keytake(_, pos_integer(), [_]) -> {'value', tuple(), [_]} | 'false'.
+-spec keytake(term(), pos_integer(), [tuple()]) ->
+ {'value', tuple(), [tuple()]} | 'false'.
keytake(Key, N, L) when is_integer(N), N > 0 ->
keytake(Key, N, L, []).
@@ -513,7 +514,8 @@ keytake(Key, N, [H|T], L) ->
keytake(Key, N, T, [H|L]);
keytake(_K, _N, [], _L) -> false.
--spec keystore(_, pos_integer(), [_], tuple()) -> [_].
+-spec keystore(term(), pos_integer(), [tuple()], tuple()) -> [tuple(),...].
+
keystore(K, N, L, New) when is_integer(N), N > 0, is_tuple(New) ->
keystore2(K, N, L, New).
@@ -524,7 +526,7 @@ keystore2(Key, N, [H|T], New) ->
keystore2(_Key, _N, [], New) ->
[New].
--spec keysort(pos_integer(), [T]) -> [T] when is_subtype(T, tuple()).
+-spec keysort(pos_integer(), [T]) -> [T] when T :: tuple().
keysort(I, L) when is_integer(I), I > 0 ->
case L of
@@ -582,7 +584,7 @@ keysort_1(_I, X, _EX, [], R) ->
lists:reverse(R, [X]).
-spec keymerge(pos_integer(), [X], [Y]) ->
- [R] when is_subtype(X, tuple()), is_subtype(Y, tuple()), is_subtype(R, tuple()).
+ [R] when X :: tuple(), Y :: tuple(), R :: tuple().
keymerge(Index, T1, L2) when is_integer(Index), Index > 0 ->
case L2 of
@@ -597,7 +599,7 @@ keymerge(Index, T1, L2) when is_integer(Index), Index > 0 ->
%% reverse(rkeymerge(I,reverse(A),reverse(B))) is equal to keymerge(I,A,B).
-spec rkeymerge(pos_integer(), [X], [Y]) ->
- [R] when is_subtype(X, tuple()), is_subtype(Y, tuple()), is_subtype(R, tuple()).
+ [R] when X :: tuple(), Y :: tuple(), R :: tuple().
rkeymerge(Index, T1, L2) when is_integer(Index), Index > 0 ->
case L2 of
@@ -609,7 +611,7 @@ rkeymerge(Index, T1, L2) when is_integer(Index), Index > 0 ->
lists:reverse(M, [])
end.
--spec ukeysort(pos_integer(), [T]) -> [T] when is_subtype(T, tuple()).
+-spec ukeysort(pos_integer(), [T]) -> [T] when T :: tuple().
ukeysort(I, L) when is_integer(I), I > 0 ->
case L of
@@ -675,7 +677,7 @@ ukeysort_1(_I, X, _EX, []) ->
[X].
-spec ukeymerge(pos_integer(), [X], [Y]) ->
- [(X | Y)] when is_subtype(X, tuple()), is_subtype(Y, tuple()).
+ [(X | Y)] when X :: tuple(), Y :: tuple().
ukeymerge(Index, L1, T2) when is_integer(Index), Index > 0 ->
case L1 of
@@ -690,7 +692,7 @@ ukeymerge(Index, L1, T2) when is_integer(Index), Index > 0 ->
%% reverse(rukeymerge(I,reverse(A),reverse(B))) is equal to ukeymerge(I,A,B).
-spec rukeymerge(pos_integer(), [X], [Y]) ->
- [(X | Y)] when is_subtype(X, tuple()), is_subtype(Y, tuple()).
+ [(X | Y)] when X :: tuple(), Y :: tuple().
rukeymerge(Index, T1, L2) when is_integer(Index), Index > 0 ->
case L2 of
@@ -702,7 +704,7 @@ rukeymerge(Index, T1, L2) when is_integer(Index), Index > 0 ->
lists:reverse(M, [])
end.
--spec keymap(fun((_) -> _), pos_integer(), [tuple()]) -> [tuple()].
+-spec keymap(fun((term()) -> term()), pos_integer(), [tuple()]) -> [tuple()].
keymap(Fun, Index, [Tup|Tail]) ->
[setelement(Index, Tup, Fun(element(Index, Tup)))|keymap(Fun, Index, Tail)];
@@ -725,7 +727,7 @@ sort(Fun, [X, Y | T]) ->
fsplit_2(Y, X, Fun, T, [], [])
end.
--spec merge(fun((X, Y) -> boolean()), [X], [Y]) -> [_].
+-spec merge(fun((X, Y) -> boolean()), [X], [Y]) -> [(X | Y)].
merge(Fun, T1, [H2 | T2]) when is_function(Fun, 2) ->
lists:reverse(fmerge2_1(T1, H2, Fun, T2, []), []);
@@ -734,7 +736,7 @@ merge(Fun, T1, []) when is_function(Fun, 2) ->
%% reverse(rmerge(F,reverse(A),reverse(B))) is equal to merge(F,A,B).
--spec rmerge(fun((X, Y) -> boolean()), [X], [Y]) -> [_].
+-spec rmerge(fun((X, Y) -> boolean()), [X], [Y]) -> [(X | Y)].
rmerge(Fun, T1, [H2 | T2]) when is_function(Fun, 2) ->
lists:reverse(rfmerge2_1(T1, H2, Fun, T2, []), []);
@@ -768,7 +770,7 @@ usort_1(Fun, X, [Y | L]) ->
ufsplit_2(Y, L, Fun, [X])
end.
--spec umerge(fun((X, Y) -> boolean()), [X], [Y]) -> [_].
+-spec umerge(fun((X, Y) -> boolean()), [X], [Y]) -> [(X | Y)].
umerge(Fun, [], T2) when is_function(Fun, 2) ->
T2;
@@ -777,7 +779,7 @@ umerge(Fun, [H1 | T1], T2) when is_function(Fun, 2) ->
%% reverse(rumerge(F,reverse(A),reverse(B))) is equal to umerge(F,A,B).
--spec rumerge(fun((X, Y) -> boolean()), [X], [Y]) -> [_].
+-spec rumerge(fun((X, Y) -> boolean()), [X], [Y]) -> [(X | Y)].
rumerge(Fun, T1, []) when is_function(Fun, 2) ->
T1;
@@ -842,7 +844,7 @@ usort_1(X, []) ->
%% umerge(List) -> L
%% merges a list of sorted lists without duplicates, removes duplicates
--spec umerge([T]) -> [T].
+-spec umerge([[T]]) -> [T].
umerge(L) ->
umergel(L).
@@ -851,7 +853,7 @@ umerge(L) ->
%% merges three sorted lists X, Y and Z without duplicates,
%% removes duplicates
--spec umerge3([_], [_], [_]) -> [_].
+-spec umerge3([X], [Y], [Z]) -> [(X | Y | Z)].
umerge3(L1, [], L3) ->
umerge(L1, L3);
@@ -864,7 +866,7 @@ umerge3(L1, [H2 | T2], [H3 | T3]) ->
%% merges three reversed sorted lists X, Y and Z without duplicates,
%% removes duplicates
--spec rumerge3([_], [_], [_]) -> [_].
+-spec rumerge3([X], [Y], [Z]) -> [(X | Y | Z)].
rumerge3(L1, [], L3) ->
rumerge(L1, L3);
@@ -876,7 +878,7 @@ rumerge3(L1, [H2 | T2], [H3 | T3]) ->
%% umerge(X, Y) -> L
%% merges two sorted lists X and Y without duplicates, removes duplicates
--spec umerge([_], [_]) -> [_].
+-spec umerge([X], [Y]) -> [(X | Y)].
umerge([], T2) ->
T2;
@@ -889,7 +891,7 @@ umerge([H1 | T1], T2) ->
%% reverse(rumerge(reverse(A),reverse(B))) is equal to umerge(I,A,B).
--spec rumerge([_], [_]) -> [_].
+-spec rumerge([X], [Y]) -> [(X | Y)].
rumerge(T1, []) ->
T1;
@@ -952,13 +954,13 @@ flatmap(F, [Hd|Tail]) ->
F(Hd) ++ flatmap(F, Tail);
flatmap(F, []) when is_function(F, 1) -> [].
--spec foldl(fun((T, _) -> _), _, [T]) -> _.
+-spec foldl(fun((T, term()) -> term()), term(), [T]) -> term().
foldl(F, Accu, [Hd|Tail]) ->
foldl(F, F(Hd, Accu), Tail);
foldl(F, Accu, []) when is_function(F, 2) -> Accu.
--spec foldr(fun((T, _) -> _), _, [T]) -> _.
+-spec foldr(fun((T, term()) -> term()), term(), [T]) -> term().
foldr(F, Accu, [Hd|Tail]) ->
F(Hd, foldr(F, Accu, Tail));
@@ -998,14 +1000,14 @@ zf(F, [Hd|Tail]) ->
end;
zf(F, []) when is_function(F, 1) -> [].
--spec foreach(F :: fun((T) -> _), List :: [T]) -> 'ok'.
+-spec foreach(F :: fun((T) -> term()), List :: [T]) -> 'ok'.
foreach(F, [Hd|Tail]) ->
F(Hd),
foreach(F, Tail);
foreach(F, []) when is_function(F, 1) -> ok.
--spec mapfoldl(fun((T, _) -> {_, _}), _, [T]) -> {[_], _}.
+-spec mapfoldl(fun((A, term()) -> {B, term()}), term(), [A]) -> {[B], term()}.
mapfoldl(F, Accu0, [Hd|Tail]) ->
{R,Accu1} = F(Hd, Accu0),
@@ -1013,7 +1015,7 @@ mapfoldl(F, Accu0, [Hd|Tail]) ->
{[R|Rs],Accu2};
mapfoldl(F, Accu, []) when is_function(F, 2) -> {[],Accu}.
--spec mapfoldr(fun((T, _) -> {_, _}), _, [T]) -> {[_], _}.
+-spec mapfoldr(fun((A, term()) -> {B, term()}), term(), [A]) -> {[B], term()}.
mapfoldr(F, Accu0, [Hd|Tail]) ->
{Rs,Accu1} = mapfoldr(F, Accu0, Tail),
diff --git a/lib/stdlib/src/orddict.erl b/lib/stdlib/src/orddict.erl
index c7b52b933e..8a13992785 100644
--- a/lib/stdlib/src/orddict.erl
+++ b/lib/stdlib/src/orddict.erl
@@ -151,7 +151,7 @@ map(F, [{Key,Val}|D]) ->
[{Key,F(Key, Val)}|map(F, D)];
map(F, []) when is_function(F, 2) -> [].
--spec filter(fun((term(), term()) -> term()), orddict()) -> orddict().
+-spec filter(fun((term(), term()) -> boolean()), orddict()) -> orddict().
filter(F, [{Key,Val}=E|D]) ->
case F(Key, Val) of
diff --git a/lib/stdlib/src/ordsets.erl b/lib/stdlib/src/ordsets.erl
index 05041c15f1..4c72e351d0 100644
--- a/lib/stdlib/src/ordsets.erl
+++ b/lib/stdlib/src/ordsets.erl
@@ -26,12 +26,14 @@
-export([subtract/2,is_subset/2]).
-export([fold/3,filter/2]).
+-export_type([ordset/1]).
+
-type ordset(T) :: [T].
%% new() -> Set.
%% Return a new empty ordered set.
--spec new() -> ordset(term()).
+-spec new() -> [].
new() -> [].
@@ -84,7 +86,7 @@ is_element(_, []) -> false.
%% add_element(Element, OrdSet) -> OrdSet.
%% Return OrdSet with Element inserted in it.
--spec add_element(term(), ordset(_)) -> ordset(_).
+-spec add_element(E, ordset(T)) -> [T | E,...].
add_element(E, [H|Es]) when E > H -> [H|add_element(E, Es)];
add_element(E, [H|_]=Set) when E < H -> [E|Set];
@@ -94,7 +96,7 @@ add_element(E, []) -> [E].
%% del_element(Element, OrdSet) -> OrdSet.
%% Return OrdSet but with Element removed.
--spec del_element(term(), ordset(_)) -> ordset(_).
+-spec del_element(term(), ordset(T)) -> ordset(T).
del_element(E, [H|Es]) when E > H -> [H|del_element(E, Es)];
del_element(E, [H|_]=Set) when E < H -> Set;
@@ -104,7 +106,7 @@ del_element(_, []) -> [].
%% union(OrdSet1, OrdSet2) -> OrdSet
%% Return the union of OrdSet1 and OrdSet2.
--spec union(ordset(_), ordset(_)) -> ordset(_).
+-spec union(ordset(T1), ordset(T2)) -> ordset(T1 | T2).
union([E1|Es1], [E2|_]=Set2) when E1 < E2 ->
[E1|union(Es1, Set2)];
@@ -118,7 +120,7 @@ union(Es1, []) -> Es1.
%% union([OrdSet]) -> OrdSet
%% Return the union of the list of ordered sets.
--spec union([ordset(_)]) -> ordset(_).
+-spec union([ordset(T)]) -> ordset(T).
union([S1,S2|Ss]) ->
union1(union(S1, S2), Ss);
@@ -147,7 +149,7 @@ intersection(_, []) ->
%% intersection([OrdSet]) -> OrdSet.
%% Return the intersection of the list of ordered sets.
--spec intersection([ordset(_)]) -> ordset(_).
+-spec intersection([ordset(_),...]) -> ordset(_).
intersection([S1,S2|Ss]) ->
intersection1(intersection(S1, S2), Ss);
@@ -206,7 +208,7 @@ is_subset(_, []) -> false.
%% fold(Fun, Accumulator, OrdSet) -> Accumulator.
%% Fold function Fun over all elements in OrdSet and return Accumulator.
--spec fold(fun((_, _) -> _), _, ordset(_)) -> _.
+-spec fold(fun((T, term()) -> term()), term(), ordset(T)) -> term().
fold(F, Acc, Set) ->
lists:foldl(F, Acc, Set).
@@ -214,7 +216,7 @@ fold(F, Acc, Set) ->
%% filter(Fun, OrdSet) -> OrdSet.
%% Filter OrdSet with Fun.
--spec filter(fun((_) -> boolean()), ordset(_)) -> ordset(_).
+-spec filter(fun((T) -> boolean()), ordset(T)) -> ordset(T).
filter(F, Set) ->
lists:filter(F, Set).
diff --git a/lib/stdlib/src/re.erl b/lib/stdlib/src/re.erl
index 296a6b3d23..9642de17b4 100644
--- a/lib/stdlib/src/re.erl
+++ b/lib/stdlib/src/re.erl
@@ -208,29 +208,25 @@ replace(Subject,RE,Replacement,Options) ->
process_repl_params(Options,iodata,false),
FlatSubject = to_binary(Subject, Unicode),
FlatReplacement = to_binary(Replacement, Unicode),
- case do_replace(FlatSubject,Subject,RE,FlatReplacement,NewOpt) of
- {error,_Err} ->
- throw(badre);
- IoList ->
- case Convert of
- iodata ->
- IoList;
- binary ->
- case Unicode of
- false ->
- iolist_to_binary(IoList);
- true ->
- unicode:characters_to_binary(IoList,unicode)
- end;
- list ->
- case Unicode of
- false ->
- binary_to_list(iolist_to_binary(IoList));
- true ->
- unicode:characters_to_list(IoList,unicode)
- end
- end
- end
+ IoList = do_replace(FlatSubject,Subject,RE,FlatReplacement,NewOpt),
+ case Convert of
+ iodata ->
+ IoList;
+ binary ->
+ case Unicode of
+ false ->
+ iolist_to_binary(IoList);
+ true ->
+ unicode:characters_to_binary(IoList,unicode)
+ end;
+ list ->
+ case Unicode of
+ false ->
+ binary_to_list(iolist_to_binary(IoList));
+ true ->
+ unicode:characters_to_list(IoList,unicode)
+ end
+ end
catch
throw:badopt ->
erlang:error(badarg,[Subject,RE,Replacement,Options]);
diff --git a/lib/stdlib/src/string.erl b/lib/stdlib/src/string.erl
index 6636a03f06..c987c224db 100644
--- a/lib/stdlib/src/string.erl
+++ b/lib/stdlib/src/string.erl
@@ -201,7 +201,7 @@ chars(C, 0, Tail) when is_integer(C) ->
-spec copies(string(), non_neg_integer()) -> string().
-copies(CharList, Num) when is_list(CharList), Num >= 0 ->
+copies(CharList, Num) when is_list(CharList), is_integer(Num), Num >= 0 ->
copies(CharList, Num, []).
copies(_CharList, 0, R) ->
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index f5d5441184..3c5800effa 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -33,12 +33,14 @@
-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]).
+%%--------------------------------------------------------------------------
+
+-export_type([child_spec/0, del_err/0, startchild_ret/0, strategy/0]).
%%--------------------------------------------------------------------------
-type child_id() :: pid() | 'undefined'.
--type mfargs() :: {module(), atom(), [term()]}.
+-type mfargs() :: {module(), atom(), [term()] | undefined}.
-type modules() :: [module()] | 'dynamic'.
-type restart() :: 'permanent' | 'transient' | 'temporary'.
-type shutdown() :: 'brutal_kill' | timeout().
@@ -67,7 +69,7 @@
-record(state, {name,
strategy :: strategy(),
children = [] :: [child()],
- dynamics = ?DICT:new() :: ?DICT(),
+ dynamics :: ?DICT() | list(),
intensity :: non_neg_integer(),
period :: pos_integer(),
restarts = [],
@@ -77,6 +79,10 @@
-define(is_simple(State), State#state.strategy =:= simple_one_for_one).
+%%--------------------------------------------------------------------------
+
+-spec behaviour_info(atom()) -> 'undefined' | [{atom(), arity()}].
+
behaviour_info(callbacks) ->
[{init,1}];
behaviour_info(_Other) ->
@@ -160,11 +166,13 @@ check_childspecs(X) -> {error, {badarg, X}}.
%%%
%%% ---------------------------------------------------
+-type init_sup_name() :: sup_name() | 'self'.
+
-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()]}) ->
+-spec init({init_sup_name(), module(), [term()]}) ->
{'ok', state()} | 'ignore' | {'stop', stop_rsn()}.
init({SupName, Mod, Args}) ->
@@ -184,7 +192,7 @@ init({SupName, Mod, Args}) ->
Error ->
{stop, {bad_return, {Mod, init, Error}}}
end.
-
+
init_children(State, StartSpec) ->
SupName = State#state.name,
case check_startspec(StartSpec) of
@@ -275,16 +283,15 @@ do_start_child_i(M, F, A) ->
-spec handle_call(call(), term(), state()) -> {'reply', term(), state()}.
handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) ->
- #child{mfargs = {M, F, A}} = hd(State#state.children),
+ Child = hd(State#state.children),
+ #child{mfargs = {M, F, A}} = Child,
Args = A ++ EArgs,
case do_start_child_i(M, F, Args) of
{ok, Pid} ->
- NState = State#state{dynamics =
- ?DICT:store(Pid, Args, State#state.dynamics)},
+ NState = save_dynamic_child(Child#child.restart_type, Pid, Args, State),
{reply, {ok, Pid}, NState};
{ok, Pid, Extra} ->
- NState = State#state{dynamics =
- ?DICT:store(Pid, Args, State#state.dynamics)},
+ NState = save_dynamic_child(Child#child.restart_type, Pid, Args, State),
{reply, {ok, Pid, Extra}, NState};
What ->
{reply, What, State}
@@ -343,10 +350,20 @@ handle_call({terminate_child, Name}, _From, State) ->
{reply, {error, not_found}, State}
end;
-handle_call(which_children, _From, State) when ?is_simple(State) ->
- [#child{child_type = CT, modules = Mods}] = State#state.children,
+handle_call(which_children, _From, #state{children = [#child{restart_type = temporary,
+ child_type = CT,
+ modules = Mods}]} =
+ State) when ?is_simple(State) ->
+ Reply = lists:map(fun(Pid) -> {undefined, Pid, CT, Mods} end, dynamics_db(temporary,
+ State#state.dynamics)),
+ {reply, Reply, State};
+
+handle_call(which_children, _From, #state{children = [#child{restart_type = RType,
+ child_type = CT,
+ modules = Mods}]} =
+ State) when ?is_simple(State) ->
Reply = lists:map(fun({Pid, _}) -> {undefined, Pid, CT, Mods} end,
- ?DICT:to_list(State#state.dynamics)),
+ ?DICT:to_list(dynamics_db(RType, State#state.dynamics))),
{reply, Reply, State};
handle_call(which_children, _From, State) ->
@@ -358,13 +375,31 @@ handle_call(which_children, _From, State) ->
State#state.children),
{reply, Resp, State};
-handle_call(count_children, _From, State) when ?is_simple(State) ->
- [#child{child_type = CT}] = State#state.children,
+
+handle_call(count_children, _From, #state{children = [#child{restart_type = temporary,
+ child_type = CT}]} = State)
+ when ?is_simple(State) ->
+ {Active, Count} =
+ lists:foldl(fun(Pid, {Alive, Tot}) ->
+ if is_pid(Pid) -> {Alive+1, Tot +1};
+ true -> {Alive, Tot + 1} end
+ end, {0, 0}, dynamics_db(temporary, State#state.dynamics)),
+ Reply = case CT of
+ supervisor -> [{specs, 1}, {active, Active},
+ {supervisors, Count}, {workers, 0}];
+ worker -> [{specs, 1}, {active, Active},
+ {supervisors, 0}, {workers, Count}]
+ end,
+ {reply, Reply, State};
+
+handle_call(count_children, _From, #state{children = [#child{restart_type = RType,
+ child_type = CT}]} = State)
+ when ?is_simple(State) ->
{Active, Count} =
?DICT:fold(fun(Pid, _Val, {Alive, Tot}) ->
if is_pid(Pid) -> {Alive+1, Tot +1};
true -> {Alive, Tot + 1} end
- end, {0, 0}, State#state.dynamics),
+ end, {0, 0}, dynamics_db(RType, State#state.dynamics)),
Reply = case CT of
supervisor -> [{specs, 1}, {active, Active},
{supervisors, Count}, {workers, 0}];
@@ -527,15 +562,11 @@ handle_start_child(Child, State) ->
false ->
case do_start_child(State#state.name, Child) of
{ok, Pid} ->
- Children = State#state.children,
{{ok, Pid},
- State#state{children =
- [Child#child{pid = Pid}|Children]}};
+ save_child(Child#child{pid = Pid}, State)};
{ok, Pid, Extra} ->
- Children = State#state.children,
{{ok, Pid, Extra},
- State#state{children =
- [Child#child{pid = Pid}|Children]}};
+ save_child(Child#child{pid = Pid}, State)};
{error, What} ->
{{error, {What, Child}}, State}
end;
@@ -550,22 +581,21 @@ handle_start_child(Child, State) ->
%%% Returns: {ok, state()} | {shutdown, state()}
%%% ---------------------------------------------------
-restart_child(Pid, Reason, State) when ?is_simple(State) ->
- case ?DICT:find(Pid, State#state.dynamics) of
+restart_child(Pid, Reason, #state{children = [Child]} = State) when ?is_simple(State) ->
+ RestartType = Child#child.restart_type,
+ case dynamic_child_args(Pid, dynamics_db(RestartType, State#state.dynamics)) of
{ok, Args} ->
- [Child] = State#state.children,
- RestartType = Child#child.restart_type,
{M, F, _} = Child#child.mfargs,
NChild = Child#child{pid = Pid, mfargs = {M, F, Args}},
do_restart(RestartType, Reason, NChild, State);
error ->
- {ok, State}
+ {ok, State}
end;
+
restart_child(Pid, Reason, State) ->
Children = State#state.children,
case lists:keyfind(Pid, #child.pid, Children) of
- #child{} = Child ->
- RestartType = Child#child.restart_type,
+ #child{restart_type = RestartType} = Child ->
do_restart(RestartType, Reason, Child, State);
false ->
{ok, State}
@@ -600,7 +630,8 @@ restart(Child, State) ->
restart(simple_one_for_one, Child, State) ->
#child{mfargs = {M, F, A}} = Child,
- Dynamics = ?DICT:erase(Child#child.pid, State#state.dynamics),
+ Dynamics = ?DICT:erase(Child#child.pid, dynamics_db(Child#child.restart_type,
+ State#state.dynamics)),
case do_start_child_i(M, F, A) of
{ok, Pid} ->
NState = State#state{dynamics = ?DICT:store(Pid, A, Dynamics)},
@@ -660,14 +691,15 @@ terminate_children([], _SupName, Res) ->
Res.
do_terminate(Child, SupName) when Child#child.pid =/= undefined ->
- case shutdown(Child#child.pid,
- Child#child.shutdown) of
- ok ->
- Child#child{pid = undefined};
- {error, OtherReason} ->
- report_error(shutdown_error, OtherReason, Child, SupName),
- Child#child{pid = undefined}
- end;
+ case shutdown(Child#child.pid, Child#child.shutdown) of
+ ok ->
+ ok;
+ {error, normal} when Child#child.restart_type =/= permanent ->
+ ok;
+ {error, OtherReason} ->
+ report_error(shutdown_error, OtherReason, Child, SupName)
+ end,
+ Child#child{pid = undefined};
do_terminate(Child, _SupName) ->
Child.
@@ -746,8 +778,40 @@ monitor_child(Pid) ->
%%-----------------------------------------------------------------
%% Child/State manipulating functions.
%%-----------------------------------------------------------------
-state_del_child(#child{pid = Pid}, State) when ?is_simple(State) ->
- NDynamics = ?DICT:erase(Pid, State#state.dynamics),
+
+%% Note we do not want to save the parameter list for temporary processes as
+%% they will not be restarted, and hence we do not need this information.
+%% Especially for dynamic children to simple_one_for_one supervisors
+%% it could become very costly as it is not uncommon to spawn
+%% very many such processes.
+save_child(#child{restart_type = temporary,
+ mfargs = {M, F, _}} = Child, #state{children = Children} = State) ->
+ State#state{children = [Child#child{mfargs = {M, F, undefined}} |Children]};
+save_child(Child, #state{children = Children} = State) ->
+ State#state{children = [Child |Children]}.
+
+save_dynamic_child(temporary, Pid, _, #state{dynamics = Dynamics} = State) ->
+ State#state{dynamics = [Pid | dynamics_db(temporary, Dynamics)]};
+save_dynamic_child(RestartType, Pid, Args, #state{dynamics = Dynamics} = State) ->
+ State#state{dynamics = ?DICT:store(Pid, Args, dynamics_db(RestartType, Dynamics))}.
+
+dynamics_db(temporary, undefined) ->
+ [];
+dynamics_db(_, undefined) ->
+ ?DICT:new();
+dynamics_db(_,Dynamics) ->
+ Dynamics.
+
+dynamic_child_args(_, Dynamics) when is_list(Dynamics)->
+ {ok, undefined};
+dynamic_child_args(Pid, Dynamics) ->
+ ?DICT:find(Pid, Dynamics).
+
+state_del_child(#child{pid = Pid, restart_type = temporary}, State) when ?is_simple(State) ->
+ NDynamics = lists:delete(Pid, dynamics_db(temporary, State#state.dynamics)),
+ State#state{dynamics = NDynamics};
+state_del_child(#child{pid = Pid, restart_type = RType}, State) when ?is_simple(State) ->
+ NDynamics = ?DICT:erase(Pid, dynamics_db(RType, State#state.dynamics)),
State#state{dynamics = NDynamics};
state_del_child(Child, State) ->
NChildren = del_child(Child#child.name, State#state.children),
diff --git a/lib/stdlib/src/timer.erl b/lib/stdlib/src/timer.erl
index 24e14caa69..b456c5d6c1 100644
--- a/lib/stdlib/src/timer.erl
+++ b/lib/stdlib/src/timer.erl
@@ -33,6 +33,9 @@
%% internal exports for test purposes only
-export([get_status/0]).
+%% types which can be used by other modules
+-export_type([tref/0]).
+
%% Max
-define(MAX_TIMEOUT, 16#0800000).
-define(TIMER_TAB, timer_tab).
diff --git a/lib/stdlib/src/unicode.erl b/lib/stdlib/src/unicode.erl
index 09b1deff9c..869505ba83 100644
--- a/lib/stdlib/src/unicode.erl
+++ b/lib/stdlib/src/unicode.erl
@@ -25,8 +25,17 @@
%% InEncoding is not {latin1 | unicode | utf8})
%%
--export([characters_to_list/1, characters_to_list_int/2, characters_to_binary/1,characters_to_binary_int/2, characters_to_binary/3,bom_to_encoding/1, encoding_to_bom/1]).
+-export([characters_to_list/1, characters_to_list_int/2,
+ characters_to_binary/1, characters_to_binary_int/2,
+ characters_to_binary/3,
+ bom_to_encoding/1, encoding_to_bom/1]).
+-export_type([encoding/0]).
+
+-type encoding() :: 'latin1' | 'unicode' | 'utf8'
+ | 'utf16' | {'utf16', endian()}
+ | 'utf32' | {'utf32', endian()}.
+-type endian() :: 'big' | 'little'.
characters_to_list(ML) ->
unicode:characters_to_list(ML,unicode).
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index 3bbd9ce318..3dd0a91870 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -133,7 +133,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) stdlib.spec stdlib.spec.vxworks $(EMAKEFILE) \
+ $(INSTALL_DATA) stdlib.spec $(EMAKEFILE) \
$(ERL_FILES) $(COVERFILE) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/stdlib/test/array_SUITE.erl b/lib/stdlib/test/array_SUITE.erl
index e7cfc65be1..a8b252f081 100644
--- a/lib/stdlib/test/array_SUITE.erl
+++ b/lib/stdlib/test/array_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -19,7 +19,7 @@
-module(array_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Default timetrap timeout (set in init_per_testcase).
%% This should be set relatively high (10-15 times the expected
@@ -27,8 +27,9 @@
-define(default_timeout, ?t:seconds(60)).
%% Test server specific exports
--export([all/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([
new_test/1,
@@ -64,33 +65,37 @@
%%
%% all/1
%%
-all(doc) ->
- [];
-all(suite) ->
- [new_test,
- fix_test,
- relax_test,
- resize_test,
- set_get_test,
- to_list_test,
- sparse_to_list_test,
- from_list_test,
- to_orddict_test,
- sparse_to_orddict_test,
- from_orddict_test,
- map_test,
- sparse_map_test,
- foldl_test,
- sparse_foldl_test,
- foldr_test,
- sparse_foldr_test
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [new_test, fix_test, relax_test, resize_test,
+ set_get_test, to_list_test, sparse_to_list_test,
+ from_list_test, to_orddict_test, sparse_to_orddict_test,
+ from_orddict_test, map_test, sparse_map_test,
+ foldl_test, sparse_foldl_test, foldr_test,
+ sparse_foldr_test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/stdlib/test/base64_SUITE.erl b/lib/stdlib/test/base64_SUITE.erl
index 44742063b3..c64a961ffa 100644
--- a/lib/stdlib/test/base64_SUITE.erl
+++ b/lib/stdlib/test/base64_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,18 +18,19 @@
%%
-module(base64_SUITE).
--author('[email protected]').
--include("test_server.hrl").
+-include_lib("common_test/include/ct.hrl").
-include("test_server_line.hrl").
%% Test server specific exports
--export([all/1, init_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
%% Test cases must be exported.
-export([base64_encode/1, base64_decode/1, base64_otp_5635/1,
base64_otp_6279/1, big/1, illegal/1, mime_decode/1,
- roundtrip/1]).
+ mime_decode_to_string/1, roundtrip/1]).
init_per_testcase(_, Config) ->
Dog = test_server:timetrap(?t:minutes(2)),
@@ -44,14 +45,29 @@ end_per_testcase(_, Config) ->
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
-all(doc) ->
- ["Test library functions for base64 encode and decode "
- "(taken from inets/test/http_format_SUITE)"];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[base64_encode, base64_decode, base64_otp_5635,
- base64_otp_6279, big, illegal, mime_decode,
+ base64_otp_6279, big, illegal, mime_decode, mime_decode_to_string,
roundtrip].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%-------------------------------------------------------------------------
base64_encode(doc) ->
@@ -59,7 +75,7 @@ base64_encode(doc) ->
base64_encode(suite) ->
[];
base64_encode(Config) when is_list(Config) ->
- %% Two pads
+ %% Two pads
<<"QWxhZGRpbjpvcGVuIHNlc2FtZQ==">> =
base64:encode("Aladdin:open sesame"),
%% One pad
@@ -77,8 +93,8 @@ base64_decode(doc) ->
base64_decode(suite) ->
[];
base64_decode(Config) when is_list(Config) ->
- %% Two pads
- <<"Aladdin:open sesame">> =
+ %% Two pads
+ <<"Aladdin:open sesame">> =
base64:decode("QWxhZGRpbjpvcGVuIHNlc2FtZQ=="),
%% One pad
<<"Hello World">> = base64:decode(<<"SGVsbG8gV29ybGQ=">>),
@@ -138,20 +154,85 @@ illegal(Config) when is_list(Config) ->
{'EXIT',{function_clause, _}} = (catch base64:decode("()")),
ok.
%%-------------------------------------------------------------------------
+%% mime_decode and mime_decode_to_string have different implementations
+%% so test both with the same input separately. Both functions have
+%% the same implementation for binary/string arguments.
mime_decode(doc) ->
["Test base64:mime_decode/1."];
mime_decode(suite) ->
[];
mime_decode(Config) when is_list(Config) ->
- %% Two pads
- <<"Aladdin:open sesame">> =
+ %% Test correct padding
+ <<"one">> = base64:mime_decode(<<"b25l">>),
+ <<"on">> = base64:mime_decode(<<"b24=">>),
+ <<"o">> = base64:mime_decode(<<"bw==">>),
+ %% Test 1 extra padding
+ <<"one">> = base64:mime_decode(<<"b25l= =">>),
+ <<"on">> = base64:mime_decode(<<"b24== =">>),
+ <<"o">> = base64:mime_decode(<<"bw=== =">>),
+ %% Test 2 extra padding
+ <<"one">> = base64:mime_decode(<<"b25l===">>),
+ <<"on">> = base64:mime_decode(<<"b24====">>),
+ <<"o">> = base64:mime_decode(<<"bw=====">>),
+ %% Test misc embedded padding
+ <<"one">> = base64:mime_decode(<<"b2=5l===">>),
+ <<"on">> = base64:mime_decode(<<"b=24====">>),
+ <<"o">> = base64:mime_decode(<<"b=w=====">>),
+ %% Test misc white space and illegals with embedded padding
+ <<"one">> = base64:mime_decode(<<" b~2=\r\n5()l===">>),
+ <<"on">> = base64:mime_decode(<<"\tb =2\"�4=�= ==">>),
+ <<"o">> = base64:mime_decode(<<"\nb=w=====">>),
+ %% Two pads
+ <<"Aladdin:open sesame">> =
base64:mime_decode("QWxhZGRpbjpvc()GVuIHNlc2FtZQ=="),
- %% One pad, followed by ignored text
- <<"Hello World">> = base64:mime_decode(<<"SGVsb)(G8gV29ybGQ=apa">>),
+ %% One pad to ignore, followed by more text
+ <<"Hello World!!">> = base64:mime_decode(<<"SGVsb)(G8gV29ybGQ=h IQ= =">>),
+ %% No pad
+ <<"Aladdin:open sesam">> =
+ base64:mime_decode("QWxhZGRpbjpvcG�\")(VuIHNlc2Ft"),
+ %% Encoded base 64 strings may be divided by non base 64 chars.
+ %% In this cases whitespaces.
+ <<"0123456789!@#0^&*();:<>,. []{}">> =
+ base64:mime_decode(
+ <<"MDEy MzQ1Njc4 \tOSFAIzBeJ \nio)(oKTs6 PD4sLi \r\nBbXXt9">>),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+%% Repeat of mime_decode() tests
+mime_decode_to_string(doc) ->
+ ["Test base64:mime_decode_to_string/1."];
+mime_decode_to_string(suite) ->
+ [];
+mime_decode_to_string(Config) when is_list(Config) ->
+ %% Test correct padding
+ "one" = base64:mime_decode_to_string(<<"b25l">>),
+ "on" = base64:mime_decode_to_string(<<"b24=">>),
+ "o" = base64:mime_decode_to_string(<<"bw==">>),
+ %% Test 1 extra padding
+ "one" = base64:mime_decode_to_string(<<"b25l= =">>),
+ "on" = base64:mime_decode_to_string(<<"b24== =">>),
+ "o" = base64:mime_decode_to_string(<<"bw=== =">>),
+ %% Test 2 extra padding
+ "one" = base64:mime_decode_to_string(<<"b25l===">>),
+ "on" = base64:mime_decode_to_string(<<"b24====">>),
+ "o" = base64:mime_decode_to_string(<<"bw=====">>),
+ %% Test misc embedded padding
+ "one" = base64:mime_decode_to_string(<<"b2=5l===">>),
+ "on" = base64:mime_decode_to_string(<<"b=24====">>),
+ "o" = base64:mime_decode_to_string(<<"b=w=====">>),
+ %% Test misc white space and illegals with embedded padding
+ "one" = base64:mime_decode_to_string(<<" b~2=\r\n5()l===">>),
+ "on" = base64:mime_decode_to_string(<<"\tb =2\"�4=�= ==">>),
+ "o" = base64:mime_decode_to_string(<<"\nb=w=====">>),
+ %% Two pads
+ "Aladdin:open sesame" =
+ base64:mime_decode_to_string("QWxhZGRpbjpvc()GVuIHNlc2FtZQ=="),
+ %% One pad to ignore, followed by more text
+ "Hello World!!" = base64:mime_decode_to_string(<<"SGVsb)(G8gV29ybGQ=h IQ= =">>),
%% No pad
"Aladdin:open sesam" =
base64:mime_decode_to_string("QWxhZGRpbjpvcG�\")(VuIHNlc2Ft"),
-
%% Encoded base 64 strings may be divided by non base 64 chars.
%% In this cases whitespaces.
"0123456789!@#0^&*();:<>,. []{}" =
@@ -159,6 +240,7 @@ mime_decode(Config) when is_list(Config) ->
<<"MDEy MzQ1Njc4 \tOSFAIzBeJ \nio)(oKTs6 PD4sLi \r\nBbXXt9">>),
ok.
+%%-------------------------------------------------------------------------
roundtrip(Config) when is_list(Config) ->
Sizes = lists:seq(1, 255) ++ lists:seq(2400-5, 2440),
diff --git a/lib/stdlib/test/beam_lib_SUITE.erl b/lib/stdlib/test/beam_lib_SUITE.erl
index bc867a3770..994abebc1a 100644
--- a/lib/stdlib/test/beam_lib_SUITE.erl
+++ b/lib/stdlib/test/beam_lib_SUITE.erl
@@ -1,6 +1,19 @@
%%
%% %CopyrightBegin%
%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
%% %CopyrightEnd%
%%
-module(beam_lib_SUITE).
@@ -14,25 +27,45 @@
-define(t,test_server).
-define(privdir, "beam_lib_SUITE_priv").
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(format(S, A), ok).
-define(privdir, ?config(priv_dir, Conf)).
-endif.
--export([all/1, normal/1, error/1, cmp/1, cmp_literals/1, strip/1, otp_6711/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ normal/1, error/1, cmp/1, cmp_literals/1, strip/1, otp_6711/1,
building/1, md5/1, encrypted_abstr/1, encrypted_abstr_file/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [error, normal, cmp, cmp_literals, strip, otp_6711,
+ building, md5, encrypted_abstr, encrypted_abstr_file].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [error, normal, cmp, cmp_literals, strip, otp_6711, building, md5,
- encrypted_abstr, encrypted_abstr_file].
init_per_testcase(_Case, Config) ->
Dog=?t:timetrap(?t:minutes(2)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl
index 16ed9a2c26..f6bf874741 100644
--- a/lib/stdlib/test/binary_module_SUITE.erl
+++ b/lib/stdlib/test/binary_module_SUITE.erl
@@ -1,6 +1,26 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
-module(binary_module_SUITE).
--export([all/1, interesting/1,random_ref_comp/1,random_ref_sr_comp/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ 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]).
@@ -16,8 +36,8 @@
-else.
--include("test_server.hrl").
--export([init_per_testcase/2, fin_per_testcase/2]).
+-include_lib("test_server/include/test_server.hrl").
+-export([init_per_testcase/2, end_per_testcase/2]).
% Default timetrap timeout (set in init_per_testcase).
% Some of these testcases are really heavy...
-define(default_timeout, ?t:minutes(20)).
@@ -38,15 +58,35 @@ init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_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].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [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].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-define(MASK_ERROR(EXPR),mask_error((catch (EXPR)))).
@@ -186,7 +226,7 @@ badargs(Config) when is_list(Config) ->
binary:match(<<1,2,3>>,
{ac,ets:match_spec_compile([{'_',[],['$_']}])},
[{scope,{0,1}}])),
- ?line nomatch =
+ ?line [] =
?MASK_ERROR(binary:matches(<<1,2,3>>,<<1>>,[{scope,{0,0}}])),
?line badarg =
?MASK_ERROR(binary:matches(<<1,2,3>>,{bm,<<>>},[{scope,{0,1}}])),
diff --git a/lib/stdlib/test/c_SUITE.erl b/lib/stdlib/test/c_SUITE.erl
index 2edbc7ab4c..e4c794ca84 100644
--- a/lib/stdlib/test/c_SUITE.erl
+++ b/lib/stdlib/test/c_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -17,18 +17,36 @@
%% %CopyrightEnd%
%%
-module(c_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([c_1/1, c_2/1, c_3/1, c_4/1, nc_1/1, nc_2/1, nc_3/1, nc_4/1,
memory/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-import(c, [c/2, nc/2]).
-all(doc) -> ["Test cases for the 'c' module."];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[c_1, c_2, c_3, c_4, nc_1, nc_2, nc_3, nc_4, memory].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%% Write output to a directory other than current directory:
c_1(doc) ->
diff --git a/lib/stdlib/test/calendar_SUITE.erl b/lib/stdlib/test/calendar_SUITE.erl
index 10fb72c1b1..8192d035ca 100644
--- a/lib/stdlib/test/calendar_SUITE.erl
+++ b/lib/stdlib/test/calendar_SUITE.erl
@@ -18,29 +18,43 @@
%%
-module(calendar_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
gregorian_days/1,
gregorian_seconds/1,
day_of_the_week/1,
day_of_the_week_calibrate/1,
leap_years/1,
last_day_of_the_month/1,
- local_time_to_universal_time_dst/1]).
+ local_time_to_universal_time_dst/1,
+ iso_week_number/1]).
-define(START_YEAR, 1947).
-define(END_YEAR, 2012).
-all(suite) -> [gregorian_days,
- gregorian_seconds,
- day_of_the_week,
- day_of_the_week_calibrate,
- leap_years,
- last_day_of_the_month,
- local_time_to_universal_time_dst];
+suite() -> [{ct_hooks,[ts_install_cth]}].
-all(doc) -> "This is the test suite for calendar.erl".
+all() ->
+ [gregorian_days, gregorian_seconds, day_of_the_week,
+ day_of_the_week_calibrate, leap_years,
+ last_day_of_the_month, local_time_to_universal_time_dst, iso_week_number].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
gregorian_days(doc) ->
"Tests that date_to_gregorian_days and gregorian_days_to_date "
@@ -156,6 +170,15 @@ local_time_to_universal_time_dst_x(Config) when is_list(Config) ->
{comment,"Bug in mktime() in this OS"}
end.
+iso_week_number(doc) ->
+ "Test the iso week number calculation for all three possibilities."
+ " When the date falls on the last week of the previous year,"
+ " when the date falls on a week within the given year and finally,"
+ " when the date falls on the first week of the next year.";
+iso_week_number(suite) ->
+ [];
+iso_week_number(Config) when is_list(Config) ->
+ ?line check_iso_week_number().
%%
%% LOCAL FUNCTIONS
@@ -245,7 +268,12 @@ check_last_day_of_the_month({SYr, SMon}, {EYr, EMon}) when SYr < EYr ->
check_last_day_of_the_month(_, _) ->
ok.
-
+%% check_iso_week_number
+%%
+check_iso_week_number() ->
+ ?line {2004, 53} = calendar:iso_week_number({2005, 1, 1}),
+ ?line {2007, 1} = calendar:iso_week_number({2007, 1, 1}),
+ ?line {2009, 1} = calendar:iso_week_number({2008, 12, 29}).
diff --git a/lib/stdlib/test/dets_SUITE.erl b/lib/stdlib/test/dets_SUITE.erl
index 760e610e00..a37822ea9d 100644
--- a/lib/stdlib/test/dets_SUITE.erl
+++ b/lib/stdlib/test/dets_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,13 +28,15 @@
-define(privdir(_), "./dets_SUITE_priv").
-define(datadir(_), "./dets_SUITE_data").
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(format(S, A), ok).
-define(privdir(Conf), ?config(priv_dir, Conf)).
-define(datadir(Conf), ?config(data_dir, Conf)).
-endif.
--export([all/1, not_run/1, newly_started/1, basic_v8/1, basic_v9/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ not_run/1, newly_started/1, basic_v8/1, basic_v9/1,
open_v8/1, open_v9/1, sets_v8/1, sets_v9/1, bags_v8/1,
bags_v9/1, duplicate_bags_v8/1, duplicate_bags_v9/1,
access_v8/1, access_v9/1, dirty_mark/1, dirty_mark2/1,
@@ -50,13 +52,14 @@
otp_4208/1, otp_4989/1, many_clients/1, otp_4906/1, otp_5402/1,
simultaneous_open/1, insert_new/1, repair_continuation/1,
otp_5487/1, otp_6206/1, otp_6359/1, otp_4738/1, otp_7146/1,
- otp_8070/1]).
+ otp_8070/1, otp_8856/1, otp_8898/1, otp_8899/1, otp_8903/1,
+ otp_8923/1]).
-export([dets_dirty_loop/0]).
-export([histogram/1, sum_histogram/1, ave_histogram/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%% Internal export.
-export([client/2]).
@@ -82,35 +85,51 @@ init_per_testcase(_Case, Config) ->
Dog=?t:timetrap(?t:minutes(15)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, _Config) ->
+end_per_testcase(_Case, _Config) ->
Dog=?config(watchdog, _Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
case os:type() of
- vxworks ->
- [not_run];
+ vxworks -> [not_run];
_ ->
- {req,[stdlib],
- [basic_v8, basic_v9, open_v8, open_v9, sets_v8, sets_v9,
- bags_v8, bags_v9, duplicate_bags_v8, duplicate_bags_v9,
- newly_started, open_file_v8, open_file_v9,
- init_table_v8, init_table_v9, repair_v8, repair_v9,
- access_v8, access_v9, oldbugs_v8, oldbugs_v9,
- unsafe_assumptions, truncated_segment_array_v8,
- truncated_segment_array_v9, dirty_mark, dirty_mark2,
- bag_next_v8, bag_next_v9, hash_v8b_v8c, phash, fold_v8,
- fold_v9, fixtable_v8, fixtable_v9, match_v8, match_v9,
- select_v8, select_v9, update_counter, badarg,
- cache_sets_v8, cache_sets_v9, cache_bags_v8,
- cache_bags_v9, cache_duplicate_bags_v8,
- cache_duplicate_bags_v9, otp_4208, otp_4989, many_clients,
- otp_4906, otp_5402, simultaneous_open, insert_new,
- repair_continuation, otp_5487, otp_6206, otp_6359, otp_4738,
- otp_7146, otp_8070]}
+ [basic_v8, basic_v9, open_v8, open_v9, sets_v8, sets_v9,
+ bags_v8, bags_v9, duplicate_bags_v8, duplicate_bags_v9,
+ newly_started, open_file_v8, open_file_v9,
+ init_table_v8, init_table_v9, repair_v8, repair_v9,
+ access_v8, access_v9, oldbugs_v8, oldbugs_v9,
+ unsafe_assumptions, truncated_segment_array_v8,
+ truncated_segment_array_v9, dirty_mark, dirty_mark2,
+ bag_next_v8, bag_next_v9, hash_v8b_v8c, phash, fold_v8,
+ fold_v9, fixtable_v8, fixtable_v9, match_v8, match_v9,
+ select_v8, select_v9, update_counter, badarg,
+ cache_sets_v8, cache_sets_v9, cache_bags_v8,
+ cache_bags_v9, cache_duplicate_bags_v8,
+ cache_duplicate_bags_v9, otp_4208, otp_4989,
+ many_clients, otp_4906, otp_5402, simultaneous_open,
+ insert_new, repair_continuation, otp_5487, otp_6206,
+ otp_6359, otp_4738, otp_7146, otp_8070, otp_8856, otp_8898,
+ otp_8899, otp_8903, otp_8923]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
not_run(suite) -> [];
not_run(Conf) when is_list(Conf) ->
{comment, "Not runnable VxWorks/NFS"}.
@@ -2935,6 +2954,57 @@ ets_init(Tab, N) ->
ets:insert(Tab, {N,N}),
ets_init(Tab, N - 1).
+otp_8898(doc) ->
+ ["OTP-8898. Truncated Dets file."];
+otp_8898(suite) ->
+ [];
+otp_8898(Config) when is_list(Config) ->
+ Tab = otp_8898,
+ ?line FName = filename(Tab, Config),
+
+ Server = self(),
+
+ ?line file:delete(FName),
+ ?line {ok, _} = dets:open_file(Tab,[{file, FName}]),
+ ?line [P1,P2,P3] = new_clients(3, Tab),
+
+ Seq = [{P1,[sync]},{P2,[{lookup,1,[]}]},{P3,[{insert,{1,b}}]}],
+ ?line atomic_requests(Server, Tab, [[]], Seq),
+ ?line true = get_replies([{P1,ok},{P2,ok},{P3,ok}]),
+ ?line ok = dets:close(Tab),
+ ?line {ok, _} = dets:open_file(Tab,[{file, FName}]),
+ ?line file:delete(FName),
+
+ ok.
+
+otp_8899(doc) ->
+ ["OTP-8899. Several clients. Updated Head was ignored."];
+otp_8899(suite) ->
+ [];
+otp_8899(Config) when is_list(Config) ->
+ Tab = many_clients,
+ ?line FName = filename(Tab, Config),
+
+ Server = self(),
+
+ ?line file:delete(FName),
+ ?line {ok, _} = dets:open_file(Tab,[{file, FName},{version,9}]),
+ ?line [P1,P2,P3,P4] = new_clients(4, Tab),
+
+ MC = [Tab],
+ Seq6a = [{P1,[{insert,[{used_to_be_skipped_by,match}]},
+ {lookup,1,[{1,a}]}]},
+ {P2,[{verbose,true,MC}]},
+ {P3,[{lookup,1,[{1,a}]}]}, {P4,[{verbose,true,MC}]}],
+ ?line atomic_requests(Server, Tab, [[{1,a},{2,b},{3,c}]], Seq6a),
+ ?line true = get_replies([{P1,ok}, {P2,ok}, {P3,ok}, {P4,ok}]),
+ ?line [{1,a},{2,b},{3,c},{used_to_be_skipped_by,match}] =
+ lists:sort(dets:match_object(Tab, '_')),
+ ?line _ = dets:close(Tab),
+ ?line file:delete(FName),
+
+ ok.
+
many_clients(doc) ->
["Several clients accessing a table simultaneously."];
many_clients(suite) ->
@@ -3071,6 +3141,11 @@ client(S, Tab) ->
eval([], _Tab) ->
ok;
+eval([{verbose,Bool,Expected} | L], Tab) ->
+ ?line case dets:verbose(Bool) of
+ Expected -> eval(L, Tab);
+ Error -> {error, {verbose,Error}}
+ end;
eval([sync | L], Tab) ->
?line case dets:sync(Tab) of
ok -> eval(L, Tab);
@@ -3701,6 +3776,87 @@ otp_8070(Config) when is_list(Config) ->
file:delete(File),
ok.
+otp_8856(doc) ->
+ ["OTP-8856. insert_new() bug."];
+otp_8856(suite) ->
+ [];
+otp_8856(Config) when is_list(Config) ->
+ Tab = otp_8856,
+ File = filename(Tab, Config),
+ file:delete(File),
+ Me = self(),
+ ?line {ok, _} = dets:open_file(Tab, [{type, bag}, {file, File}]),
+ spawn(fun()-> Me ! {1, dets:insert(Tab, [])} end),
+ spawn(fun()-> Me ! {2, dets:insert_new(Tab, [])} end),
+ ?line ok = dets:close(Tab),
+ ?line receive {1, ok} -> ok end,
+ ?line receive {2, true} -> ok end,
+ file:delete(File),
+
+ ?line {ok, _} = dets:open_file(Tab, [{type, set}, {file, File}]),
+ spawn(fun() -> dets:delete(Tab, 0) end),
+ spawn(fun() -> Me ! {3, dets:insert_new(Tab, {0,0})} end),
+ ?line ok = dets:close(Tab),
+ ?line receive {3, true} -> ok end,
+ file:delete(File),
+ ok.
+
+otp_8903(doc) ->
+ ["OTP-8903. bchunk/match/select bug."];
+otp_8903(suite) ->
+ [];
+otp_8903(Config) when is_list(Config) ->
+ Tab = otp_8903,
+ File = filename(Tab, Config),
+ ?line {ok,T} = dets:open_file(bug, [{file,File}]),
+ ?line ok = dets:insert(T, [{1,a},{2,b},{3,c}]),
+ ?line dets:safe_fixtable(T, true),
+ ?line {[_],C1} = dets:match_object(T, '_', 1),
+ ?line {BC1,_D} = dets:bchunk(T, start),
+ ?line ok = dets:close(T),
+ ?line {'EXIT', {badarg, _}} = (catch {foo,dets:match_object(C1)}),
+ ?line {'EXIT', {badarg, _}} = (catch {foo,dets:bchunk(T, BC1)}),
+ ?line {ok,T} = dets:open_file(bug, [{file,File}]),
+ ?line false = dets:info(T, safe_fixed),
+ ?line {'EXIT', {badarg, _}} = (catch {foo,dets:match_object(C1)}),
+ ?line {'EXIT', {badarg, _}} = (catch {foo,dets:bchunk(T, BC1)}),
+ ?line ok = dets:close(T),
+ file:delete(File),
+ ok.
+
+otp_8923(doc) ->
+ ["OTP-8923. rehash due to lookup after initialization."];
+otp_8923(suite) ->
+ [];
+otp_8923(Config) when is_list(Config) ->
+ Tab = otp_8923,
+ File = filename(Tab, Config),
+ %% Create a file with more than 256 keys:
+ file:delete(File),
+ Bin = list_to_binary([ 0 || _ <- lists:seq(1, 400) ]),
+ BigBin = list_to_binary([ 0 ||_ <- lists:seq(1, 4000)]),
+ Ets = ets:new(temp, [{keypos,1}]),
+ ?line [ true = ets:insert(Ets, {C,Bin}) || C <- lists:seq(1, 700) ],
+ ?line true = ets:insert(Ets, {helper_data,BigBin}),
+ ?line true = ets:insert(Ets, {prim_btree,BigBin}),
+ ?line true = ets:insert(Ets, {sec_btree,BigBin}),
+ %% Note: too few slots; re-hash will take place
+ ?line {ok, Tab} = dets:open_file(Tab, [{file,File}]),
+ ?line Tab = ets:to_dets(Ets, Tab),
+ ?line ok = dets:close(Tab),
+ ?line true = ets:delete(Ets),
+
+ ?line {ok,Ref} = dets:open_file(File),
+ ?line [{1,_}] = dets:lookup(Ref, 1),
+ ?line ok = dets:close(Ref),
+
+ ?line {ok,Ref2} = dets:open_file(File),
+ ?line [{helper_data,_}] = dets:lookup(Ref2, helper_data),
+ ?line ok = dets:close(Ref2),
+
+ file:delete(File),
+ ok.
+
%%
%% Parts common to several test cases
%%
diff --git a/lib/stdlib/test/dict_SUITE.erl b/lib/stdlib/test/dict_SUITE.erl
index 6a90870bda..396a8d4763 100644
--- a/lib/stdlib/test/dict_SUITE.erl
+++ b/lib/stdlib/test/dict_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,21 +22,41 @@
-module(dict_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
create/1,store/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-import(lists, [foldl/3,reverse/1]).
-all(suite) ->
- [create,store].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [create, store].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?t:minutes(5)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/stdlib/test/dict_test_lib.erl b/lib/stdlib/test/dict_test_lib.erl
index fd15baa5ff..92a75dad89 100644
--- a/lib/stdlib/test/dict_test_lib.erl
+++ b/lib/stdlib/test/dict_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/stdlib/test/digraph_SUITE.erl b/lib/stdlib/test/digraph_SUITE.erl
index 6ef5b1ddef..4e7c468097 100644
--- a/lib/stdlib/test/digraph_SUITE.erl
+++ b/lib/stdlib/test/digraph_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,19 +23,41 @@
-ifdef(STANDALONE).
-define(line, put(line, ?LINE), ).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-endif.
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
--export([opts/1, degree/1, path/1, cycle/1, misc/1, vertices/1,
- edges/1, data/1, tickets/1, otp_3522/1, otp_3630/1, otp_8066/1]).
+-export([opts/1, degree/1, path/1, cycle/1, vertices/1,
+ edges/1, data/1, otp_3522/1, otp_3630/1, otp_8066/1]).
-export([spawn_graph/2]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) -> {req, [stdlib], [opts, degree, path, cycle, misc, tickets]}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [opts, degree, path, cycle, {group, misc},
+ {group, tickets}].
+
+groups() ->
+ [{misc, [], [vertices, edges, data]},
+ {tickets, [], [otp_3522, otp_3630, otp_8066]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -147,7 +169,6 @@ cycle(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-misc(suite) -> [vertices, edges, data].
vertices(doc) -> [];
vertices(suite) -> [];
@@ -210,7 +231,6 @@ data(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-tickets(suite) -> [otp_3522, otp_3630, otp_8066].
otp_3522(doc) -> [];
otp_3522(suite) -> [];
diff --git a/lib/stdlib/test/digraph_utils_SUITE.erl b/lib/stdlib/test/digraph_utils_SUITE.erl
index d6d477b388..28daf0f0fb 100644
--- a/lib/stdlib/test/digraph_utils_SUITE.erl
+++ b/lib/stdlib/test/digraph_utils_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -22,10 +22,11 @@
-ifdef(debug).
-define(line, put(line, ?LINE), ).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-endif.
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([simple/1, loop/1, isolated/1, topsort/1, subgraph/1,
condensation/1, tree/1]).
@@ -33,8 +34,27 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) -> {req, [stdlib], [simple, loop, isolated, topsort,
- subgraph, condensation, tree]}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [simple, loop, isolated, topsort, subgraph,
+ condensation, tree].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/stdlib/test/dummy_h.erl b/lib/stdlib/test/dummy_h.erl
index 01eb790a75..7546fe78a0 100644
--- a/lib/stdlib/test/dummy_h.erl
+++ b/lib/stdlib/test/dummy_h.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/stdlib/test/edlin_expand_SUITE.erl b/lib/stdlib/test/edlin_expand_SUITE.erl
index 613bfd000e..514d22c4d2 100644
--- a/lib/stdlib/test/edlin_expand_SUITE.erl
+++ b/lib/stdlib/test/edlin_expand_SUITE.erl
@@ -17,13 +17,14 @@
%% %CopyrightEnd%
%%
-module(edlin_expand_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([normal/1, quoted_fun/1, quoted_module/1, quoted_both/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -31,16 +32,36 @@
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test cases for edlin_expand."];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[normal, quoted_fun, quoted_module, quoted_both].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ true = code:delete(expand_test),
+ true = code:delete(expand_test1),
+ true = code:delete('ExpandTestCaps'),
+ true = code:delete('ExpandTestCaps1'),
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
normal(doc) ->
[""];
normal(suite) ->
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index e31dfdd764..195eeb5e89 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -17,14 +17,15 @@
%% %CopyrightEnd%
-module(epp_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-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,
+ upcase_mac_1/1, upcase_mac_2/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_8665/1]).
+ otp_8562/1, otp_8665/1, otp_8911/1]).
-export([epp_parse_erl_form/2]).
@@ -44,8 +45,8 @@ config(priv_dir, _) ->
config(data_dir, _) ->
filename:absname("./epp_SUITE_data").
-else.
--include("test_server.hrl").
--export([init_per_testcase/2, fin_per_testcase/2]).
+-include_lib("test_server/include/test_server.hrl").
+-export([init_per_testcase/2, end_per_testcase/2]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -53,18 +54,36 @@ config(data_dir, _) ->
init_per_testcase(_, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_, Config) ->
+end_per_testcase(_, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-endif.
-all(doc) ->
- ["Test cases for epp."];
-all(suite) ->
- [rec_1, upcase_mac, predef_mac, variable, otp_4870, otp_4871, otp_5362,
- pmod, not_circular, skip_header, otp_6277, otp_7702, otp_8130,
- overload_mac, otp_8388, otp_8470, otp_8503, otp_8562, otp_8665].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [rec_1, {group, upcase_mac}, predef_mac,
+ {group, 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,
+ otp_8665, otp_8911].
+
+groups() ->
+ [{upcase_mac, [], [upcase_mac_1, upcase_mac_2]},
+ {variable, [], [variable_1]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
rec_1(doc) ->
["Recursive macros hang or crash epp (OTP-1398)."];
@@ -127,10 +146,6 @@ check_errors([{error, Info} | Rest]) ->
check_errors([_ | Rest]) ->
check_errors(Rest).
-upcase_mac(doc) ->
- ["Check that uppercase macro names are implicitly quoted (OTP-2608)"];
-upcase_mac(suite) ->
- [upcase_mac_1, upcase_mac_2].
upcase_mac_1(doc) ->
[];
@@ -176,10 +191,6 @@ predef_mac(Config) when is_list(Config) ->
end,
ok.
-variable(doc) ->
- ["Check variable as first file component of the include directives."];
-variable(suite) ->
- [variable_1].
variable_1(doc) ->
[];
@@ -1197,6 +1208,40 @@ otp_8562(Config) when is_list(Config) ->
?line [] = compile(Config, Cs),
ok.
+otp_8911(doc) ->
+ ["OTP-8911. -file and file inclusion bug"];
+otp_8911(suite) ->
+ [];
+otp_8911(Config) when is_list(Config) ->
+ ?line {ok, CWD} = file:get_cwd(),
+ ?line ok = file:set_cwd(?config(priv_dir, Config)),
+
+ File = "i.erl",
+ Cont = <<"-module(i).
+ -compile(export_all).
+ -file(\"fil1\", 100).
+ -include(\"i1.erl\").
+ t() ->
+ a.
+ ">>,
+ ?line ok = file:write_file(File, Cont),
+ Incl = <<"-file(\"fil2\", 35).
+ t1() ->
+ b.
+ ">>,
+ File1 = "i1.erl",
+ ?line ok = file:write_file(File1, Incl),
+
+ ?line {ok, i} = cover:compile(File),
+ ?line a = i:t(),
+ ?line {ok,[{{i,6},1}]} = cover:analyse(i, calls, line),
+ ?line cover:stop(),
+
+ file:delete(File),
+ file:delete(File1),
+ ?line file:set_cwd(CWD),
+ ok.
+
otp_8665(doc) ->
["OTP-8665. Bugfix premature end."];
otp_8665(suite) ->
diff --git a/lib/stdlib/test/erl_eval_SUITE.erl b/lib/stdlib/test/erl_eval_SUITE.erl
index c60a558fa1..6277b2c52e 100644
--- a/lib/stdlib/test/erl_eval_SUITE.erl
+++ b/lib/stdlib/test/erl_eval_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -17,7 +17,8 @@
%% %CopyrightEnd%
-module(erl_eval_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([guard_1/1, guard_2/1,
match_pattern/1,
@@ -38,7 +39,8 @@
otp_8133/1,
funs/1,
try_catch/1,
- eval_expr_5/1]).
+ eval_expr_5/1,
+ zero_width/1]).
%%
%% Define to run outside of test server
@@ -57,26 +59,42 @@
config(priv_dir,_) ->
".".
-else.
--include("test_server.hrl").
--export([init_per_testcase/2, fin_per_testcase/2]).
+-include_lib("test_server/include/test_server.hrl").
+-export([init_per_testcase/2, end_per_testcase/2]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-endif.
-all(doc) ->
- ["Test cases for the 'erl_eval' module."];
-all(suite) ->
- [guard_1, guard_2, match_pattern, string_plusplus, pattern_expr,
- match_bin, guard_3, guard_4,
- lc, simple_cases, unary_plus, apply_atom, otp_5269, otp_6539, otp_6543,
- otp_6787, otp_6977, otp_7550, otp_8133, funs, try_catch, eval_expr_5].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [guard_1, guard_2, match_pattern, string_plusplus,
+ pattern_expr, match_bin, guard_3, guard_4, lc,
+ simple_cases, unary_plus, apply_atom, otp_5269,
+ otp_6539, otp_6543, otp_6787, otp_6977, otp_7550,
+ otp_8133, funs, try_catch, eval_expr_5, zero_width].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
guard_1(doc) ->
["(OTP-2405)"];
@@ -1326,6 +1344,14 @@ eval_expr_5(Config) when is_list(Config) ->
ok
end.
+zero_width(Config) when is_list(Config) ->
+ ?line check(fun() ->
+ {'EXIT',{badarg,_}} = (catch <<not_a_number:0>>),
+ ok
+ end, "begin {'EXIT',{badarg,_}} = (catch <<not_a_number:0>>), "
+ "ok end.", ok),
+ ok.
+
%% Check the string in different contexts: as is; in fun; from compiled code.
check(F, String, Result) ->
check1(F, String, Result),
diff --git a/lib/stdlib/test/erl_eval_helper.erl b/lib/stdlib/test/erl_eval_helper.erl
index 7fdbabcb17..6863b40108 100644
--- a/lib/stdlib/test/erl_eval_helper.erl
+++ b/lib/stdlib/test/erl_eval_helper.erl
@@ -1,7 +1,7 @@
%%
%% %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
diff --git a/lib/stdlib/test/erl_expand_records_SUITE.erl b/lib/stdlib/test/erl_expand_records_SUITE.erl
index 1d621c65df..44c986640f 100644
--- a/lib/stdlib/test/erl_expand_records_SUITE.erl
+++ b/lib/stdlib/test/erl_expand_records_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -27,15 +27,17 @@
-define(privdir, "erl_expand_records_SUITE_priv").
-define(t, test_server).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(privdir, ?config(priv_dir, Config)).
-endif.
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
-export([abstract_module/1, attributes/1, expr/1, guard/1,
init/1, pattern/1, strict/1, update/1,
- tickets/1, otp_5915/1, otp_7931/1, otp_5990/1,
+ otp_5915/1, otp_7931/1, otp_5990/1,
otp_7078/1, otp_7101/1]).
% Default timetrap timeout (set in init_per_testcase).
@@ -45,14 +47,33 @@ init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, _Config) ->
+end_per_testcase(_Case, _Config) ->
Dog = ?config(watchdog, _Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [abstract_module, attributes, expr, guard, init, pattern,
- strict, update, tickets].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [abstract_module, attributes, expr, guard, init,
+ pattern, strict, update, {group, tickets}].
+
+groups() ->
+ [{tickets, [],
+ [otp_5915, otp_7931, otp_5990, otp_7078, otp_7101]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
abstract_module(doc) ->
"Compile an abstract module.";
@@ -399,8 +420,6 @@ update(Config) when is_list(Config) ->
?line run(Config, Ts),
ok.
-tickets(suite) ->
- [otp_5915, otp_7931, otp_5990, otp_7078, otp_7101].
otp_5915(doc) ->
"Strict record tests in guards.";
diff --git a/lib/stdlib/test/erl_internal_SUITE.erl b/lib/stdlib/test/erl_internal_SUITE.erl
index 8f675c94ec..678e22c252 100644
--- a/lib/stdlib/test/erl_internal_SUITE.erl
+++ b/lib/stdlib/test/erl_internal_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,15 +18,35 @@
%%
-module(erl_internal_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([behav/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [behav].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [behav].
-define(default_timeout, ?t:minutes(2)).
@@ -34,7 +54,7 @@ init_per_testcase(_Case, Config) ->
?line Dog = test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index d0c0d68b4a..f980d52e4e 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -27,34 +27,37 @@
-define(privdir, "erl_lint_SUITE_priv").
-define(t, test_server).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(datadir, ?config(data_dir, Conf)).
-define(privdir, ?config(priv_dir, Conf)).
-endif.
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
-
--export([unused_vars_warn/1,
- unused_vars_warn_basic/1,
- unused_vars_warn_lc/1,
- unused_vars_warn_rec/1,
- unused_vars_warn_fun/1,
- unused_vars_OTP_4858/1,
- export_vars_warn/1,
- shadow_vars/1,
- unused_import/1,
- unused_function/1,
- unsafe_vars/1,unsafe_vars2/1,
- unsafe_vars_try/1,
- guard/1, otp_4886/1, otp_4988/1, otp_5091/1, otp_5276/1, otp_5338/1,
- otp_5362/1, otp_5371/1, otp_7227/1, otp_5494/1, otp_5644/1, otp_5878/1,
- otp_5917/1, otp_6585/1, otp_6885/1, export_all/1,
- bif_clash/1,
- behaviour_basic/1, behaviour_multiple/1,
- otp_7550/1,
- otp_8051/1,
- format_warn/1,
- on_load/1, on_load_successful/1, on_load_failing/1
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
+
+-export([
+ unused_vars_warn_basic/1,
+ unused_vars_warn_lc/1,
+ unused_vars_warn_rec/1,
+ unused_vars_warn_fun/1,
+ unused_vars_OTP_4858/1,
+ export_vars_warn/1,
+ shadow_vars/1,
+ unused_import/1,
+ unused_function/1,
+ unsafe_vars/1,unsafe_vars2/1,
+ unsafe_vars_try/1,
+ guard/1, otp_4886/1, otp_4988/1, otp_5091/1, otp_5276/1, otp_5338/1,
+ otp_5362/1, otp_5371/1, otp_7227/1, otp_5494/1, otp_5644/1, otp_5878/1,
+ otp_5917/1, otp_6585/1, otp_6885/1, export_all/1,
+ bif_clash/1,
+ behaviour_basic/1, behaviour_multiple/1,
+ otp_7550/1,
+ otp_8051/1,
+ format_warn/1,
+ on_load_successful/1, on_load_failing/1,
+ too_many_arguments/1
]).
% Default timetrap timeout (set in init_per_testcase).
@@ -64,24 +67,44 @@ init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, _Config) ->
+end_per_testcase(_Case, _Config) ->
Dog = ?config(watchdog, _Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [unused_vars_warn, export_vars_warn,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, unused_vars_warn}, export_vars_warn,
shadow_vars, unused_import, unused_function,
- unsafe_vars, unsafe_vars2, unsafe_vars_try,
- guard, otp_4886, otp_4988, otp_5091, otp_5276, otp_5338,
- otp_5362, otp_5371, otp_7227, otp_5494, otp_5644, otp_5878, otp_5917, otp_6585,
- otp_6885, export_all, bif_clash,
- behaviour_basic, behaviour_multiple, otp_7550, otp_8051, format_warn,
- on_load].
+ unsafe_vars, unsafe_vars2, unsafe_vars_try, guard,
+ otp_4886, otp_4988, otp_5091, otp_5276, otp_5338,
+ otp_5362, otp_5371, otp_7227, otp_5494, otp_5644,
+ otp_5878, otp_5917, otp_6585, otp_6885, export_all,
+ bif_clash, behaviour_basic, behaviour_multiple,
+ otp_7550, otp_8051, format_warn, {group, on_load},
+ too_many_arguments].
+
+groups() ->
+ [{unused_vars_warn, [],
+ [unused_vars_warn_basic, unused_vars_warn_lc,
+ unused_vars_warn_rec, unused_vars_warn_fun,
+ unused_vars_OTP_4858]},
+ {on_load, [], [on_load_successful, on_load_failing]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-unused_vars_warn(suite) ->
- [unused_vars_warn_basic, unused_vars_warn_lc, unused_vars_warn_rec,
- unused_vars_warn_fun, unused_vars_OTP_4858].
unused_vars_warn_basic(doc) ->
"Warnings for unused variables in some simple cases.";
@@ -2831,8 +2854,6 @@ format_level(Level, Count, Config) ->
%% Test the -on_load(Name/0) directive.
-on_load(suite) ->
- [on_load_successful, on_load_failing].
on_load_successful(Config) when is_list(Config) ->
Ts = [{on_load_1,
@@ -2913,6 +2934,21 @@ on_load_failing(Config) when is_list(Config) ->
?line [] = run(Config, Ts),
ok.
+too_many_arguments(doc) ->
+ "Test that too many arguments is not accepted.";
+too_many_arguments(suite) -> [];
+too_many_arguments(Config) when is_list(Config) ->
+ Ts = [{too_many_1,
+ <<"f(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_) -> ok.">>,
+ [],
+ {errors,
+ [{1,erl_lint,{too_many_arguments,256}}],[]}}
+ ],
+
+ ?line [] = run(Config, Ts),
+ ok.
+
+
run(Config, Tests) ->
F = fun({N,P,Ws,E}, BadL) ->
case catch run_test(Config, P, Ws) of
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index c57541fba9..e0f233fb2a 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -30,23 +30,25 @@
-define(privdir, "erl_pp_SUITE_priv").
-define(t, test_server).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(datadir, ?config(data_dir, Config)).
-define(privdir, ?config(priv_dir, Config)).
-endif.
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
--export([expr/1, func/1, call/1, recs/1, try_catch/1, if_then/1,
- receive_after/1, bits/1, head_tail/1, package/1,
- cond1/1, block/1, case1/1, ops/1, messages/1,
- old_mnemosyne_syntax/1,
- attributes/1, import_export/1, misc_attrs/1,
- hook/1,
- 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_8664/1]).
+-export([ func/1, call/1, recs/1, try_catch/1, if_then/1,
+ receive_after/1, bits/1, head_tail/1, package/1,
+ cond1/1, block/1, case1/1, ops/1, messages/1,
+ old_mnemosyne_syntax/1,
+ import_export/1, misc_attrs/1,
+ hook/1,
+ neg_indent/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_8664/1]).
%% Internal export.
-export([ehook/6]).
@@ -58,17 +60,40 @@ init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, _Config) ->
+end_per_testcase(_Case, _Config) ->
Dog = ?config(watchdog, _Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [expr, attributes, hook, neg_indent, tickets].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, expr}, {group, attributes}, hook, neg_indent,
+ {group, tickets}].
+
+groups() ->
+ [{expr, [],
+ [func, call, recs, try_catch, if_then, receive_after,
+ bits, head_tail, package, cond1, block, case1, ops,
+ messages, old_mnemosyne_syntax]},
+ {attributes, [], [misc_attrs, import_export]},
+ {tickets, [],
+ [otp_6321, otp_6911, otp_6914, otp_8150, otp_8238,
+ otp_8473, otp_8522, otp_8567, otp_8664]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-expr(suite) ->
- [func, call, recs, try_catch, if_then, receive_after, bits, head_tail,
- package, cond1, block, case1, ops, messages, old_mnemosyne_syntax].
func(suite) ->
[];
@@ -564,8 +589,6 @@ old_mnemosyne_syntax(Config) when is_list(Config) ->
ok.
-attributes(suite) ->
- [misc_attrs, import_export].
import_export(suite) ->
[];
@@ -763,9 +786,6 @@ neg_indent(Config) when is_list(Config) ->
ok.
-tickets(suite) ->
- [otp_6321, otp_6911, otp_6914, otp_8150, otp_8238, otp_8473, otp_8522,
- otp_8567, otp_8664].
otp_6321(doc) ->
"OTP_6321. Bug fix of exprs().";
diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl
index 32eb97bc92..75e908e97c 100644
--- a/lib/stdlib/test/erl_scan_SUITE.erl
+++ b/lib/stdlib/test/erl_scan_SUITE.erl
@@ -17,9 +17,10 @@
%% %CopyrightEnd%
-module(erl_scan_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
--export([error/1, error_1/1, error_2/1, iso88591/1, otp_7810/1]).
+-export([ error_1/1, error_2/1, iso88591/1, otp_7810/1]).
-import(lists, [nth/2,flatten/1]).
-import(io_lib, [print/1]).
@@ -39,14 +40,14 @@
%% config(data_dir, _) ->
%% ".".
-else.
--include("test_server.hrl").
--export([init_per_testcase/2, fin_per_testcase/2]).
+-include_lib("test_server/include/test_server.hrl").
+-export([init_per_testcase/2, end_per_testcase/2]).
init_per_testcase(_Case, Config) when is_list(Config) ->
?line Dog=test_server:timetrap(test_server:seconds(1200)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -55,15 +56,27 @@ fin_per_testcase(_Case, Config) ->
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
-all(doc) ->
- ["Test cases for the 'erl_scan' module."];
-all(suite) ->
- [error,iso88591,otp_7810].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, error}, iso88591, otp_7810].
+
+groups() ->
+ [{error, [], [error_1, error_2]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-error(doc) ->
- ["Error cases"];
-error(suite) ->
- [error_1, error_2].
error_1(doc) ->
["(OTP-2347)"];
diff --git a/lib/stdlib/test/error_logger_forwarder.erl b/lib/stdlib/test/error_logger_forwarder.erl
index 7d99d07860..5703ac769a 100644
--- a/lib/stdlib/test/error_logger_forwarder.erl
+++ b/lib/stdlib/test/error_logger_forwarder.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% 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
diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl
index 77fd190e45..447d6fb629 100644
--- a/lib/stdlib/test/escript_SUITE.erl
+++ b/lib/stdlib/test/escript_SUITE.erl
@@ -18,9 +18,10 @@
-module(escript_SUITE).
-export([
- all/1,
+ all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
+ end_per_testcase/2,
basic/1,
errors/1,
strange_name/1,
@@ -31,31 +32,40 @@
epp/1,
create_and_extract/1,
foldl/1,
+ overflow/1,
verify_sections/3
]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
-all(suite) ->
- [
- basic,
- errors,
- strange_name,
- emulator_flags,
- module_script,
- beam_script,
- archive_script,
- epp,
- create_and_extract,
- foldl
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic, errors, strange_name, emulator_flags,
+ module_script, beam_script, archive_script, epp,
+ create_and_extract, foldl, overflow].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?t:minutes(1)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -736,6 +746,17 @@ emulate_escript_foldl(Fun, Acc, File) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+overflow(Config) when is_list(Config) ->
+ Data = ?config(data_dir, Config),
+ Dir = filename:absname(Data), %Get rid of trailing slash.
+ ?line run(Dir, "arg_overflow",
+ [<<"ExitCode:0">>]),
+ ?line run(Dir, "linebuf_overflow",
+ [<<"ExitCode:0">>]),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
run(Dir, Cmd0, Expected0) ->
Expected = iolist_to_binary(expected_output(Expected0, Dir)),
Cmd = case os:type() of
diff --git a/lib/stdlib/test/escript_SUITE_data/arg_overflow b/lib/stdlib/test/escript_SUITE_data/arg_overflow
new file mode 100755
index 0000000000..dd5accc051
--- /dev/null
+++ b/lib/stdlib/test/escript_SUITE_data/arg_overflow
@@ -0,0 +1,5 @@
+#! /usr/bin/env escript
+%% -*- erlang -*-
+%%!x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
+main(_) ->
+ halt(0).
diff --git a/lib/stdlib/test/escript_SUITE_data/linebuf_overflow b/lib/stdlib/test/escript_SUITE_data/linebuf_overflow
new file mode 100755
index 0000000000..33133c1ce9
--- /dev/null
+++ b/lib/stdlib/test/escript_SUITE_data/linebuf_overflow
@@ -0,0 +1,5 @@
+#! /usr/bin/env escript
+%% -*- erlang -*-
+%%!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+main(_) ->
+ halt(0).
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 7f39dbe21f..9d348b5f1a 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,24 +18,25 @@
%%
-module(ets_SUITE).
--export([all/1]).
--export([new/1,default/1,setbag/1,badnew/1,verybadnew/1,named/1,keypos2/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([default/1,setbag/1,badnew/1,verybadnew/1,named/1,keypos2/1,
privacy/1,privacy_owner/2]).
--export([insert/1,empty/1,badinsert/1]).
--export([lookup/1,time_lookup/1,badlookup/1,lookup_order/1]).
--export([delete/1,delete_elem/1,delete_tab/1,delete_large_tab/1,
+-export([empty/1,badinsert/1]).
+-export([time_lookup/1,badlookup/1,lookup_order/1]).
+-export([delete_elem/1,delete_tab/1,delete_large_tab/1,
delete_large_named_table/1,
evil_delete/1,baddelete/1,match_delete/1,table_leak/1]).
-export([match_delete3/1]).
-export([firstnext/1,firstnext_concurrent/1]).
-export([slot/1]).
--export([match/1, match1/1, match2/1, match_object/1, match_object2/1]).
--export([misc/1, dups/1, misc1/1, safe_fixtable/1, info/1, tab2list/1]).
--export([files/1, tab2file/1, tab2file2/1, tab2file3/1, tabfile_ext1/1,
+-export([ match1/1, match2/1, match_object/1, match_object2/1]).
+-export([ dups/1, misc1/1, safe_fixtable/1, info/1, tab2list/1]).
+-export([ tab2file/1, tab2file2/1, tabfile_ext1/1,
tabfile_ext2/1, tabfile_ext3/1, tabfile_ext4/1]).
--export([heavy/1, heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]).
--export([lookup_element/1, lookup_element_mult/1]).
--export([fold/1]).
+-export([ heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]).
+-export([ lookup_element_mult/1]).
+-export([]).
-export([foldl_ordered/1, foldr_ordered/1, foldl/1, foldr/1, fold_empty/1]).
-export([t_delete_object/1, t_init_table/1, t_whitebox/1,
t_delete_all_objects/1, t_insert_list/1, t_test_ms/1,
@@ -59,7 +60,7 @@
-export([otp_7665/1]).
-export([meta_wb/1]).
-export([grow_shrink/1, grow_pseudo_deleted/1, shrink_pseudo_deleted/1]).
--export([meta_smp/1,
+-export([
meta_lookup_unnamed_read/1, meta_lookup_unnamed_write/1,
meta_lookup_named_read/1, meta_lookup_named_write/1,
meta_newdel_unnamed/1, meta_newdel_named/1]).
@@ -70,15 +71,15 @@
exit_many_tables_owner/1,
exit_many_many_tables_owner/1]).
-export([write_concurrency/1, heir/1, give_away/1, setopts/1]).
--export([bad_table/1]).
+-export([bad_table/1, types/1]).
--export([init_per_testcase/2, fin_per_testcase/2, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%% Convenience for manual testing
-export([random_test/0]).
% internal exports
-export([dont_make_worse_sub/0, make_better_sub1/0, make_better_sub2/0]).
--export([t_repair_continuation_do/1, default_do/1, t_bucket_disappears_do/1,
+-export([t_repair_continuation_do/1, t_bucket_disappears_do/1,
select_fail_do/1, whitebox_1/1, whitebox_2/1, t_delete_all_objects_do/1,
t_delete_object_do/1, t_init_table_do/1, t_insert_list_do/1,
update_element_opts/1, update_element_opts/4, update_element/4, update_element_do/4,
@@ -91,12 +92,16 @@
slot_do/1, match1_do/1, match2_do/1, match_object_do/1, match_object2_do/1,
misc1_do/1, safe_fixtable_do/1, info_do/1, dups_do/1, heavy_lookup_do/1,
heavy_lookup_element_do/1, member_do/1, otp_5340_do/1, otp_7665_do/1, meta_wb_do/1,
- do_heavy_concurrent/1
+ do_heavy_concurrent/1, tab2file2_do/2, exit_large_table_owner_do/2,
+ types_do/1, sleeper/0, rpc_externals/0, memory_do/1,
+ ms_tracee_dummy/1, ms_tracee_dummy/2, ms_tracee_dummy/3, ms_tracee_dummy/4
]).
-export([t_select_reverse/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+-define(m(A,B), ?line assert_eq(A,B)).
init_per_testcase(Case, Config) ->
Seed = {S1,S2,S3} = random:seed0(), %now(),
@@ -107,44 +112,80 @@ init_per_testcase(Case, Config) ->
Dog=test_server:timetrap(test_server:minutes(20)),
[{watchdog, Dog}, {test_case, Case} | Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
wait_for_test_procs(true),
test_server:timetrap_cancel(Dog).
-
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, new}, {group, insert}, {group, lookup},
+ {group, delete}, firstnext, firstnext_concurrent, slot,
+ {group, match}, t_match_spec_run,
+ {group, lookup_element}, {group, misc}, {group, files},
+ {group, heavy}, ordered, ordered_match,
+ interface_equality, fixtable_next, fixtable_insert,
+ rename, rename_unnamed, evil_rename, update_element,
+ update_counter, evil_update_counter, partly_bound,
+ match_heavy, {group, fold}, member, t_delete_object,
+ t_init_table, t_whitebox, t_delete_all_objects,
+ t_insert_list, t_test_ms, t_select_delete, t_ets_dets,
+ memory, t_select_reverse, t_bucket_disappears,
+ select_fail, t_insert_new, t_repair_continuation,
+ otp_5340, otp_6338, otp_6842_select_1000, otp_7665,
+ otp_8732, meta_wb, grow_shrink, grow_pseudo_deleted,
+ shrink_pseudo_deleted, {group, meta_smp}, smp_insert,
+ smp_fixed_delete, smp_unfix_fix, smp_select_delete,
+ otp_8166, exit_large_table_owner,
+ exit_many_large_table_owner, exit_many_tables_owner,
+ exit_many_many_tables_owner, write_concurrency, heir,
+ give_away, setopts, bad_table, types].
+
+groups() ->
+ [{new, [],
+ [default, setbag, badnew, verybadnew, named, keypos2,
+ privacy]},
+ {insert, [], [empty, badinsert]},
+ {lookup, [], [time_lookup, badlookup, lookup_order]},
+ {lookup_element, [], [lookup_element_mult]},
+ {delete, [],
+ [delete_elem, delete_tab, delete_large_tab,
+ delete_large_named_table, evil_delete, table_leak,
+ baddelete, match_delete, match_delete3]},
+ {match, [],
+ [match1, match2, match_object, match_object2]},
+ {misc, [],
+ [misc1, safe_fixtable, info, dups, tab2list]},
+ {files, [],
+ [tab2file, tab2file2, tabfile_ext1,
+ tabfile_ext2, tabfile_ext3, tabfile_ext4]},
+ {heavy, [],
+ [heavy_lookup, heavy_lookup_element, heavy_concurrent]},
+ {fold, [],
+ [foldl_ordered, foldr_ordered, foldl, foldr,
+ fold_empty]},
+ {meta_smp, [],
+ [meta_lookup_unnamed_read, meta_lookup_unnamed_write,
+ meta_lookup_named_read, meta_lookup_named_write,
+ meta_newdel_unnamed, meta_newdel_named]}].
+
+init_per_suite(Config) ->
+ Config.
end_per_suite(_Config) ->
stop_spawn_logger(),
catch erts_debug:set_internal_state(available_internal_state, false).
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) ->
- [
- new,insert,lookup,delete,firstnext,firstnext_concurrent,slot,match,
- t_match_spec_run,
- lookup_element, misc,files, heavy,
- ordered, ordered_match, interface_equality,
- fixtable_next, fixtable_insert, rename, rename_unnamed, evil_rename,
- update_element, update_counter, evil_update_counter, partly_bound,
- match_heavy, fold, member,
- t_delete_object, t_init_table, t_whitebox,
- t_delete_all_objects, t_insert_list, t_test_ms,
- t_select_delete, t_ets_dets, memory, t_select_reverse,
- t_bucket_disappears,
- select_fail,t_insert_new, t_repair_continuation, otp_5340, otp_6338,
- otp_6842_select_1000, otp_7665, otp_8732,
- meta_wb,
- grow_shrink, grow_pseudo_deleted, shrink_pseudo_deleted,
- meta_smp,
- smp_insert, smp_fixed_delete, smp_unfix_fix, smp_select_delete, otp_8166,
- exit_large_table_owner,
- exit_many_large_table_owner,
- exit_many_tables_owner,
- exit_many_many_tables_owner,
- write_concurrency, heir, give_away, setopts,
- bad_table
- ].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -157,7 +198,7 @@ t_bucket_disappears(Config) when is_list(Config) ->
t_bucket_disappears_do(Opts) ->
?line EtsMem = etsmem(),
- ?line ets:new(abcd, [named_table, public, {keypos, 2} | Opts]),
+ ?line ets_new(abcd, [named_table, public, {keypos, 2} | Opts]),
?line ets:insert(abcd, {abcd,1,2}),
?line ets:insert(abcd, {abcd,2,2}),
?line ets:insert(abcd, {abcd,3,2}),
@@ -175,29 +216,180 @@ t_match_spec_run(suite) ->
t_match_spec_run(doc) ->
["Check ets:match_spec_run/2."];
t_match_spec_run(Config) when is_list(Config) ->
+ init_externals(),
?line EtsMem = etsmem(),
- ?line [2,3] = ets:match_spec_run([{1},{2},{3}],
- ets:match_spec_compile(
- [{{'$1'},[{'>','$1',1}],['$1']}])),
+
+ t_match_spec_run_test([{1},{2},{3}],
+ [{{'$1'},[{'>','$1',1}],['$1']}],
+ [2,3]),
+
?line Huge = [{X} || X <- lists:seq(1,2500)],
?line L = lists:seq(2476,2500),
- ?line L = ets:match_spec_run(Huge,
- ets:match_spec_compile(
- [{{'$1'},[{'>','$1',2475}],['$1']}])),
+ t_match_spec_run_test(Huge, [{{'$1'},[{'>','$1',2475}],['$1']}], L),
+
?line L2 = [{X*16#FFFFFFF} || X <- L],
- ?line L2 = ets:match_spec_run(Huge,
- ets:match_spec_compile(
- [{{'$1'},
- [{'>','$1',2475}],
- [{{{'*','$1',16#FFFFFFF}}}]}])),
- ?line [500,1000,1500,2000,2500] =
- ets:match_spec_run(Huge,
- ets:match_spec_compile(
- [{{'$1'},
- [{'=:=',{'rem','$1',500},0}],
- ['$1']}])),
+ t_match_spec_run_test(Huge,
+ [{{'$1'}, [{'>','$1',2475}], [{{{'*','$1',16#FFFFFFF}}}]}],
+ L2),
+
+ t_match_spec_run_test(Huge, [{{'$1'}, [{'=:=',{'rem','$1',500},0}], ['$1']}],
+ [500,1000,1500,2000,2500]),
+
+ %% More matching fun with several match clauses and guards,
+ %% applied to a variety of terms.
+ Fun = fun(Term) ->
+ CTerm = {const, Term},
+
+ N_List = [{Term, "0", "v-element"},
+ {"=hidden_node", "0", Term},
+ {"0", Term, Term},
+ {"something", Term, "something else"},
+ {"guard and res", Term, 872346},
+ {Term, {'and',Term,'again'}, 3.14},
+ {Term, {'and',Term,'again'}, "m&g"},
+ {Term, {'and',Term,'again'}, "m&g&r"},
+ {[{second,Term}, 'and', "tail"], Term, ['and',"tail"]}],
+
+ N_MS = [{{'$1','$2','$3'},
+ [{'=:=','$1',CTerm}, {'=:=','$2',{const,"0"}}],
+ [{{"Guard only for $1",'$3'}}]},
+
+ {{'$3','$1','$4'},
+ [{'=:=','$3',"=hidden_node"}, {'=:=','$1',{const,"0"}}],
+ [{{"Result only for $4",'$4'}}]},
+
+ {{'$2','$1','$1'},
+ [{'=:=','$2',{const,"0"}}],
+ [{{"Match only for $1",'$2'}}]},
+
+ {{'$2',Term,['$3'|'_']},
+ [{is_list,'$2'},{'=:=','$3',$s}],
+ [{{"Matching term",'$2'}}]},
+
+ {{'$1','$2',872346},
+ [{'=:=','$2',CTerm}, {is_list,'$1'}],
+ [{{"Guard and result",'$2'}}]},
+
+ {{'$1', {'and','$1','again'}, '$2'},
+ [{is_float,'$2'}],
+ [{{"Match and result",'$1'}}]},
+
+ {{'$1', {'and','$1','again'}, '$2'},
+ [{'=:=','$1',CTerm}, {'=:=', '$2', "m&g"}],
+ [{{"Match and guard",'$2'}}]},
+
+ {{'$1', {'and','$1','again'}, "m&g&r"},
+ [{'=:=','$1',CTerm}],
+ [{{"Match, guard and result",'$1'}}]},
+
+ {{'$1', '$2', '$3'},
+ [{'=:=','$1',[{{second,'$2'}} | '$3']}],
+ [{{"Building guard"}}]}
+ ],
+
+ N_Result = [{"Guard only for $1", "v-element"},
+ {"Result only for $4", Term},
+ {"Match only for $1", "0"},
+ {"Matching term","something"},
+ {"Guard and result",Term},
+ {"Match and result",Term},
+ {"Match and guard","m&g"},
+ {"Match, guard and result",Term},
+ {"Building guard"}],
+
+ F = fun(N_MS_Perm) ->
+ t_match_spec_run_test(N_List, N_MS_Perm, N_Result)
+ end,
+ repeat_for_permutations(F, N_MS)
+ end,
+
+ test_terms(Fun, skip_refc_check),
+
?line verify_etsmem(EtsMem).
+t_match_spec_run_test(List, MS, Result) ->
+
+ %%io:format("ms = ~p\n",[MS]),
+
+ ?m(Result, ets:match_spec_run(List, ets:match_spec_compile(MS))),
+
+ %% Check that ets:select agree
+ Tab = ets:new(xxx, [bag]),
+ ets:insert(Tab, List),
+ SRes = lists:sort(Result),
+ ?m(SRes, lists:sort(ets:select(Tab, MS))),
+ ets:delete(Tab),
+
+ %% Check that tracing agree
+ Self = self(),
+ {Tracee, MonRef} = spawn_monitor(fun() -> ms_tracee(Self, List) end),
+ receive {Tracee, ready} -> ok end,
+
+ MST = lists:map(fun(Clause) -> ms_clause_ets_to_trace(Clause) end, MS),
+
+ %%io:format("MS = ~p\nMST= ~p\n",[MS,MST]),
+
+ erlang:trace_pattern({?MODULE,ms_tracee_dummy,'_'}, MST , [local]),
+ erlang:trace(Tracee, true, [call]),
+ Tracee ! start,
+ TRes = ms_tracer_collect(Tracee, MonRef, []),
+ %erlang:trace(Tracee, false, [call]),
+ %Tracee ! stop,
+ case TRes of
+ SRes -> ok;
+ _ ->
+ io:format("TRACE MATCH FAILED\n"),
+ io:format("Input = ~p\nMST = ~p\nExpected = ~p\nGot = ~p\n", [List, MST, SRes, TRes]),
+ ?t:fail("TRACE MATCH FAILED")
+ end,
+ ok.
+
+
+
+ms_tracer_collect(Tracee, Ref, Acc) ->
+ receive
+ {trace, Tracee, call, _Args, [Msg]} ->
+ %io:format("trace Args=~p Msg=~p\n", [_Args, Msg]),
+ ms_tracer_collect(Tracee, Ref, [Msg | Acc]);
+
+ {'DOWN', Ref, process, Tracee, _} ->
+ %io:format("monitor DOWN for ~p\n", [Tracee]),
+ TDRef = erlang:trace_delivered(Tracee),
+ ms_tracer_collect(Tracee, TDRef, Acc);
+
+ {trace_delivered, Tracee, Ref} ->
+ %%io:format("trace delivered for ~p\n", [Tracee]),
+ lists:sort(Acc);
+
+ Other ->
+ io:format("Unexpected message = ~p\n", [Other]),
+ ?t:fail("Unexpected tracer msg")
+ end.
+
+
+ms_tracee(Parent, CallArgList) ->
+ %io:format("ms_tracee ~p started with ArgList = ~p\n", [self(), CallArgList]),
+ Parent ! {self(), ready},
+ receive start -> ok end,
+ lists:foreach(fun(Args) ->
+ erlang:apply(?MODULE, ms_tracee_dummy, tuple_to_list(Args))
+ end, CallArgList).
+ %%receive stop -> ok end.
+
+
+
+ms_tracee_dummy(_) -> ok.
+ms_tracee_dummy(_,_) -> ok.
+ms_tracee_dummy(_,_,_) -> ok.
+ms_tracee_dummy(_,_,_,_) -> ok.
+
+ms_clause_ets_to_trace({Head, Guard, Body}) ->
+ {tuple_to_list(Head), Guard, [{message, Body}]}.
+
+assert_eq(A,A) -> ok;
+assert_eq(A,B) ->
+ io:format("FAILED MATCH:\n~p\n =/=\n~p\n",[A,B]),
+ ?t:fail("assert_eq failed").
t_repair_continuation(suite) ->
@@ -213,7 +405,7 @@ t_repair_continuation_do(Opts) ->
?line MS = [{'_',[],[true]}],
?line MS2 = [{{{'$1','_'},'_'},[],['$1']}],
(fun() ->
- ?line T = ets:new(x,[ordered_set|Opts]),
+ ?line T = ets_new(x,[ordered_set|Opts]),
?line F = fun(0,_)->ok;(N,F) -> ets:insert(T,{N,N}), F(N-1,F) end,
?line F(1000,F),
?line {_,C} = ets:select(T,MS,5),
@@ -225,7 +417,7 @@ t_repair_continuation_do(Opts) ->
?line true = ets:delete(T)
end)(),
(fun() ->
- ?line T = ets:new(x,[ordered_set|Opts]),
+ ?line T = ets_new(x,[ordered_set|Opts]),
?line F = fun(0,_)->ok;(N,F) -> ets:insert(T,{N,N}), F(N-1,F) end,
?line F(1000,F),
?line {_,C} = ets:select(T,MS,1001),
@@ -237,7 +429,7 @@ t_repair_continuation_do(Opts) ->
end)(),
(fun() ->
- ?line T = ets:new(x,[ordered_set|Opts]),
+ ?line T = ets_new(x,[ordered_set|Opts]),
?line F = fun(0,_)->ok;(N,F) ->
ets:insert(T,{integer_to_list(N),N}),
F(N-1,F)
@@ -252,7 +444,7 @@ t_repair_continuation_do(Opts) ->
?line true = ets:delete(T)
end)(),
(fun() ->
- ?line T = ets:new(x,[ordered_set|Opts]),
+ ?line T = ets_new(x,[ordered_set|Opts]),
?line F = fun(0,_)->ok;(N,F) ->
ets:insert(T,{{integer_to_list(N),N},N}),
F(N-1,F)
@@ -268,7 +460,7 @@ t_repair_continuation_do(Opts) ->
end)(),
(fun() ->
- ?line T = ets:new(x,[set|Opts]),
+ ?line T = ets_new(x,[set|Opts]),
?line F = fun(0,_)->ok;(N,F) ->
ets:insert(T,{N,N}),
F(N-1,F)
@@ -283,7 +475,7 @@ t_repair_continuation_do(Opts) ->
?line true = ets:delete(T)
end)(),
(fun() ->
- ?line T = ets:new(x,[set|Opts]),
+ ?line T = ets_new(x,[set|Opts]),
?line F = fun(0,_)->ok;(N,F) ->
ets:insert(T,{integer_to_list(N),N}),
F(N-1,F)
@@ -298,7 +490,7 @@ t_repair_continuation_do(Opts) ->
?line true = ets:delete(T)
end)(),
(fun() ->
- ?line T = ets:new(x,[bag|Opts]),
+ ?line T = ets_new(x,[bag|Opts]),
?line F = fun(0,_)->ok;(N,F) ->
ets:insert(T,{integer_to_list(N),N}),
F(N-1,F)
@@ -313,7 +505,7 @@ t_repair_continuation_do(Opts) ->
?line true = ets:delete(T)
end)(),
(fun() ->
- ?line T = ets:new(x,[duplicate_bag|Opts]),
+ ?line T = ets_new(x,[duplicate_bag|Opts]),
?line F = fun(0,_)->ok;(N,F) ->
ets:insert(T,{integer_to_list(N),N}),
F(N-1,F)
@@ -331,21 +523,22 @@ t_repair_continuation_do(Opts) ->
?line true = ets:is_compiled_ms(ets:match_spec_compile(MS)),
?line verify_etsmem(EtsMem).
-new(suite) -> [default,setbag,badnew,verybadnew,named,keypos2,privacy].
default(doc) ->
- ["Test case to check that a new ets table is defined as a `set' and "
- "`protected'"];
+ ["Check correct default vaules of a new ets table"];
default(suite) -> [];
default(Config) when is_list(Config) ->
%% Default should be set,protected
- repeat_for_opts(default_do).
-
-default_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Def = ets:new(def,Opts),
+ ?line Def = ets_new(def,[]),
?line set = ets:info(Def,type),
?line protected = ets:info(Def,protection),
+ Compressed = erlang:system_info(ets_always_compress),
+ ?line Compressed = ets:info(Def,compressed),
+ Self = self(),
+ ?line Self = ets:info(Def,owner),
+ ?line none = ets:info(Def, heir),
+ ?line false = ets:info(Def,named_table),
?line ets:delete(Def),
?line verify_etsmem(EtsMem).
@@ -359,7 +552,7 @@ select_fail(Config) when is_list(Config) ->
?line verify_etsmem(EtsMem).
select_fail_do(Opts) ->
- ?line T = ets:new(x,Opts),
+ ?line T = ets_new(x,Opts),
?line ets:insert(T,{a,a}),
?line case (catch
ets:select(T,[{{a,'_'},[],[{snuffla}]}])) of
@@ -382,20 +575,27 @@ select_fail_do(Opts) ->
-define(S(T),ets:info(T,memory)).
-define(TAB_STRUCT_SZ, erts_debug:get_internal_state('DbTable_words')).
--define(NORMAL_TAB_STRUCT_SZ, 26). %% SunOS5.8, 32-bit, non smp, private heap
+%%-define(NORMAL_TAB_STRUCT_SZ, 26). %% SunOS5.8, 32-bit, non smp, private heap
%%
%% The hardcoded expected memory sizes (in words) are the ones we expect on:
%% SunOS5.8, 32-bit, non smp, private heap
%%
-memory(doc) ->
- ["Whitebox test of ets:info(X,memory)"];
-memory(suite) ->
- [];
+memory(doc) -> ["Whitebox test of ets:info(X,memory)"];
+memory(suite) -> [];
memory(Config) when is_list(Config) ->
?line erts_debug:set_internal_state(available_internal_state, true),
?line ok = chk_normal_tab_struct_size(),
- ?line L = [T1,T2,T3,T4] = fill_sets_int(1000),
- ?line XRes1 = adjust_xmem(L, {13862,13072,13072,13078}),
+ repeat_for_opts(memory_do,[compressed]),
+ ?line catch erts_debug:set_internal_state(available_internal_state, false).
+
+memory_do(Opts) ->
+ ?line L = [T1,T2,T3,T4] = fill_sets_int(1000,Opts),
+ XR1 = case mem_mode(T1) of
+ {normal,_} -> {13836,13046,13046,13052}; %{13862,13072,13072,13078};
+ {compressed,4} -> {11041,10251,10251,10252}; %{11067,10277,10277,10278};
+ {compressed,8} -> {10050,9260,9260,9260} %{10076,9286,9286,9286}
+ end,
+ ?line XRes1 = adjust_xmem(L, XR1),
?line Res1 = {?S(T1),?S(T2),?S(T3),?S(T4)},
?line lists:foreach(fun(T) ->
Before = ets:info(T,size),
@@ -406,7 +606,12 @@ memory(Config) when is_list(Config) ->
[Key, ets:info(T,type), Before, ets:info(T,size), Objs])
end,
L),
- ?line XRes2 = adjust_xmem(L, {13852,13063,13054,13060}),
+ XR2 = case mem_mode(T1) of
+ {normal,_} -> {13826,13037,13028,13034}; %{13852,13063,13054,13060};
+ {compressed,4} -> {11031,10242,10233,10234}; %{11057,10268,10259,10260};
+ {compressed,8} -> {10040,9251,9242,9242} %10066,9277,9268,9268}
+ end,
+ ?line XRes2 = adjust_xmem(L, XR2),
?line Res2 = {?S(T1),?S(T2),?S(T3),?S(T4)},
?line lists:foreach(fun(T) ->
Before = ets:info(T,size),
@@ -417,13 +622,18 @@ memory(Config) when is_list(Config) ->
[Key, ets:info(T,type), Before, ets:info(T,size), Objs])
end,
L),
- ?line XRes3 = adjust_xmem(L, {13842,13054,13036,13042}),
+ XR3 = case mem_mode(T1) of
+ {normal,_} -> {13816,13028,13010,13016}; %{13842,13054,13036,13042};
+ {compressed,4} -> {11021,10233,10215,10216}; %{11047,10259,10241,10242};
+ {compressed,8} -> {10030,9242,9224,9224} %{10056,9268,9250,9250}
+ end,
+ ?line XRes3 = adjust_xmem(L, XR3),
?line Res3 = {?S(T1),?S(T2),?S(T3),?S(T4)},
?line lists:foreach(fun(T) ->
?line ets:delete_all_objects(T)
end,
L),
- ?line XRes4 = adjust_xmem(L, {76,286,286,286}),
+ ?line XRes4 = adjust_xmem(L, {50,260,260,260}), %{76,286,286,286}),
?line Res4 = {?S(T1),?S(T2),?S(T3),?S(T4)},
lists:foreach(fun(T) ->
?line ets:delete(T)
@@ -434,9 +644,9 @@ memory(Config) when is_list(Config) ->
?line ets:select_delete(T,[{'_',[],[true]}])
end,
L2),
- ?line XRes5 = adjust_xmem(L2, {76,286,286,286}),
+ ?line XRes5 = adjust_xmem(L2, {50,260,260,260}), %{76,286,286,286}),
?line Res5 = {?S(T11),?S(T12),?S(T13),?S(T14)},
- ?line ?t:format("XRes1 = ~p~n"
+ ?line io:format("XRes1 = ~p~n"
" Res1 = ~p~n~n"
"XRes2 = ~p~n"
" Res2 = ~p~n~n"
@@ -456,9 +666,15 @@ memory(Config) when is_list(Config) ->
?line XRes3 = Res3,
?line XRes4 = Res4,
?line XRes5 = Res5,
- ?line catch erts_debug:set_internal_state(available_internal_state, false),
?line ok.
+mem_mode(T) ->
+ {case ets:info(T,compressed) of
+ true -> compressed;
+ false -> normal
+ end,
+ erlang:system_info(wordsize)}.
+
chk_normal_tab_struct_size() ->
?line System = {os:type(),
os:version(),
@@ -466,36 +682,58 @@ chk_normal_tab_struct_size() ->
erlang:system_info(smp_support),
erlang:system_info(heap_type)},
?line ?t:format("System = ~p~n", [System]),
- ?line ?t:format("?NORMAL_TAB_STRUCT_SZ=~p~n", [?NORMAL_TAB_STRUCT_SZ]),
+ %%?line ?t:format("?NORMAL_TAB_STRUCT_SZ=~p~n", [?NORMAL_TAB_STRUCT_SZ]),
?line ?t:format("?TAB_STRUCT_SZ=~p~n", [?TAB_STRUCT_SZ]),
- ?line case System of
- {{unix, sunos}, {5, 8, 0}, 4, false, private} ->
- ?line ?NORMAL_TAB_STRUCT_SZ = ?TAB_STRUCT_SZ,
- ?line ok;
- _ ->
- ?line ok
- end.
-
-adjust_xmem([T1,T2,T3,T4], {A0,B0,C0,D0} = Mem0) ->
+ ok.
+% ?line case System of
+% {{unix, sunos}, {5, 8, 0}, 4, false, private} ->
+% ?line ?NORMAL_TAB_STRUCT_SZ = ?TAB_STRUCT_SZ,
+% ?line ok;
+% _ ->
+% ?line ok
+% end.
+
+-define(DB_TREE_STACK_NEED,50). % The static stack for a tree, in halfword pointers are two internal words
+ % so the stack gets twice as big
+-define(DB_HASH_SIZEOF_EXTSEG,260). % The segment size in words, in halfword this will be twice as large.
+
+adjust_xmem([T1,T2,T3,T4], {A0,B0,C0,D0} = _Mem0) ->
%% Adjust for 64-bit, smp, and os:
%% Table struct size may differ.
- Mem1 = case ?TAB_STRUCT_SZ of
- ?NORMAL_TAB_STRUCT_SZ ->
- Mem0;
- TabStructSz ->
- TabDiff = TabStructSz - ?NORMAL_TAB_STRUCT_SZ,
- {A0+TabDiff, B0+TabDiff, C0+TabDiff, D0+TabDiff}
- end,
+
+% Mem1 = case ?TAB_STRUCT_SZ of
+% ?NORMAL_TAB_STRUCT_SZ ->
+% Mem0;
+% TabStructSz ->
+% TabDiff = TabStructSz - ?NORMAL_TAB_STRUCT_SZ,
+% {A0+TabDiff, B0+TabDiff, C0+TabDiff, D0+TabDiff}
+% end,
+
+ TabDiff = ?TAB_STRUCT_SZ,
+ Mem1 = {A0+TabDiff, B0+TabDiff, C0+TabDiff, D0+TabDiff},
+
+ Mem2 = case {erlang:system_info({wordsize,internal}),erlang:system_info({wordsize,external})} of
+ %% Halfword, corrections for regular pointers occupying two internal words.
+ {4,8} ->
+ {A1,B1,C1,D1} = Mem1,
+ {A1+4*ets:info(T1, size)+?DB_TREE_STACK_NEED,
+ B1+3*ets:info(T2, size)+?DB_HASH_SIZEOF_EXTSEG,
+ C1+3*ets:info(T3, size)+?DB_HASH_SIZEOF_EXTSEG,
+ D1+3*ets:info(T4, size)+?DB_HASH_SIZEOF_EXTSEG};
+ _ ->
+ Mem1
+ end,
+
%% Adjust for hybrid and shared heaps:
%% Each record is one word smaller.
- Mem2 = case erlang:system_info(heap_type) of
- private ->
- Mem1;
- _ ->
- {A1,B1,C1,D1} = Mem1,
- {A1-ets:info(T1, size),B1-ets:info(T2, size),
- C1-ets:info(T3, size),D1-ets:info(T4, size)}
- end,
+ %%Mem2 = case erlang:system_info(heap_type) of
+ %% private ->
+ %% Mem1;
+ %% _ ->
+ %% {A1,B1,C1,D1} = Mem1,
+ %% {A1-ets:info(T1, size),B1-ets:info(T2, size),
+ %% C1-ets:info(T3, size),D1-ets:info(T4, size)}
+ %% end,
%%{Mem2,{ets:info(T1,stats),ets:info(T2,stats),ets:info(T3,stats),ets:info(T4,stats)}}.
Mem2.
@@ -514,7 +752,7 @@ t_whitebox(Config) when is_list(Config) ->
?line verify_etsmem(EtsMem).
whitebox_1(Opts) ->
- ?line T=ets:new(x,[bag | Opts]),
+ ?line T=ets_new(x,[bag | Opts]),
?line ets:insert(T,[{du,glade},{ta,en}]),
?line ets:insert(T,[{hej,hopp2},{du,glade2},{ta,en2}]),
?line {_,C}=ets:match(T,{ta,'$1'},1),
@@ -524,8 +762,8 @@ whitebox_1(Opts) ->
ok.
whitebox_2(Opts) ->
- ?line T=ets:new(x,[ordered_set, {keypos,2} | Opts]),
- ?line T2=ets:new(x,[set, {keypos,2}| Opts]),
+ ?line T=ets_new(x,[ordered_set, {keypos,2} | Opts]),
+ ?line T2=ets_new(x,[set, {keypos,2}| Opts]),
?line 0 = ets:select_delete(T,[{{hej},[],[true]}]),
?line 0 = ets:select_delete(T,[{{hej,hopp},[],[true]}]),
?line 0 = ets:select_delete(T2,[{{hej},[],[true]}]),
@@ -547,7 +785,7 @@ t_ets_dets(Config, Opts) ->
?line (catch file:delete(Fname)),
?line {ok,DTab} = dets:open_file(testdets_1,
[{file, Fname}]),
- ?line ETab = ets:new(x,Opts),
+ ?line ETab = ets_new(x,Opts),
?line filltabint(ETab,3000),
?line DTab = ets:to_dets(ETab,DTab),
?line ets:delete_all_objects(ETab),
@@ -559,7 +797,7 @@ t_ets_dets(Config, Opts) ->
(catch ets:to_dets(ETab,DTab)),
?line {'EXIT',{badarg,[{ets,from_dets,[ETab,DTab]}|_]}} =
(catch ets:from_dets(ETab,DTab)),
- ?line ETab2 = ets:new(x,Opts),
+ ?line ETab2 = ets_new(x,Opts),
?line filltabint(ETab2,3000),
?line dets:close(DTab),
?line {'EXIT',{badarg,[{ets,to_dets,[ETab2,DTab]}|_]}} =
@@ -580,7 +818,7 @@ t_delete_all_objects(Config) when is_list(Config) ->
?line verify_etsmem(EtsMem).
t_delete_all_objects_do(Opts) ->
- ?line T=ets:new(x,Opts),
+ ?line T=ets_new(x,Opts),
?line filltabint(T,4000),
?line O=ets:first(T),
?line ets:next(T,O),
@@ -609,7 +847,7 @@ t_delete_object(Config) when is_list(Config) ->
?line verify_etsmem(EtsMem).
t_delete_object_do(Opts) ->
- ?line T = ets:new(x,Opts),
+ ?line T = ets_new(x,Opts),
?line filltabint(T,4000),
?line del_one_by_one_set(T,1,4001),
?line filltabint(T,4000),
@@ -626,19 +864,19 @@ t_delete_object_do(Opts) ->
?line 3999 = ets:info(T,size),
?line 0 = ets:info(T,kept_objects),
?line ets:delete(T),
- ?line T1 = ets:new(x,[ordered_set | Opts]),
+ ?line T1 = ets_new(x,[ordered_set | Opts]),
?line filltabint(T1,4000),
?line del_one_by_one_set(T1,1,4001),
?line filltabint(T1,4000),
?line del_one_by_one_set(T1,4000,0),
?line ets:delete(T1),
- ?line T2 = ets:new(x,[bag | Opts]),
+ ?line T2 = ets_new(x,[bag | Opts]),
?line filltabint2(T2,4000),
?line del_one_by_one_bag(T2,1,4001),
?line filltabint2(T2,4000),
?line del_one_by_one_bag(T2,4000,0),
?line ets:delete(T2),
- ?line T3 = ets:new(x,[duplicate_bag | Opts]),
+ ?line T3 = ets_new(x,[duplicate_bag | Opts]),
?line filltabint3(T3,4000),
?line del_one_by_one_dbag_1(T3,1,4001),
?line filltabint3(T3,4000),
@@ -685,7 +923,7 @@ t_init_table(Config) when is_list(Config)->
?line verify_etsmem(EtsMem).
t_init_table_do(Opts) ->
- ?line T = ets:new(x,[duplicate_bag | Opts]),
+ ?line T = ets_new(x,[duplicate_bag | Opts]),
?line filltabint(T,4000),
?line ets:init_table(T, make_init_fun(1)),
?line del_one_by_one_dbag_1(T,4000,0),
@@ -767,7 +1005,7 @@ t_insert_list(Config) when is_list(Config) ->
?line verify_etsmem(EtsMem).
t_insert_list_do(Opts) ->
- ?line T = ets:new(x,[duplicate_bag | Opts]),
+ ?line T = ets_new(x,[duplicate_bag | Opts]),
?line do_fill_dbag_using_lists(T,4000),
?line del_one_by_one_dbag_2(T,4000,0),
?line ets:delete(T).
@@ -795,7 +1033,7 @@ t_select_reverse(doc) ->
t_select_reverse(suite) ->
[];
t_select_reverse(Config) when is_list(Config) ->
- ?line Table = ets:new(xxx, [ordered_set]),
+ ?line Table = ets_new(xxx, [ordered_set]),
?line filltabint(Table,1000),
?line A = lists:reverse(ets:select(Table,[{{'$1', '_'},
[{'>',
@@ -817,11 +1055,11 @@ t_select_reverse(Config) when is_list(Config) ->
['$_']}],3),
% A set/bag/duplicate_bag should get the same result regardless
% of select or select_reverse
- ?line Table2 = ets:new(xxx, [set]),
+ ?line Table2 = ets_new(xxx, [set]),
?line filltabint(Table2,1000),
- ?line Table3 = ets:new(xxx, [bag]),
+ ?line Table3 = ets_new(xxx, [bag]),
?line filltabint(Table3,1000),
- ?line Table4 = ets:new(xxx, [duplicate_bag]),
+ ?line Table4 = ets_new(xxx, [duplicate_bag]),
?line filltabint(Table4,1000),
?line lists:map(fun(Tab) ->
B = ets:select(Tab,[{{'$1', '_'},
@@ -1129,8 +1367,8 @@ random_test() ->
do_random_test() ->
?line EtsMem = etsmem(),
- ?line OrdSet = ets:new(xxx,[ordered_set]),
- ?line Set = ets:new(xxx,[]),
+ ?line OrdSet = ets_new(xxx,[ordered_set]),
+ ?line Set = ets_new(xxx,[]),
?line do_n_times(fun() ->
?line Key = create_random_string(25),
?line Value = create_random_tuple(25),
@@ -1334,8 +1572,8 @@ update_element_opts(Opts) ->
update_element_opts(Tuple,KeyPos,UpdPos,Opts) ->
- Set = ets:new(set,[{keypos,KeyPos} | Opts]),
- OrdSet = ets:new(ordered_set,[ordered_set,{keypos,KeyPos} | Opts]),
+ Set = ets_new(set,[{keypos,KeyPos} | Opts]),
+ OrdSet = ets_new(ordered_set,[ordered_set,{keypos,KeyPos} | Opts]),
update_element(Set,Tuple,KeyPos,UpdPos),
update_element(OrdSet,Tuple,KeyPos,UpdPos),
true = ets:delete(Set),
@@ -1343,7 +1581,7 @@ update_element_opts(Tuple,KeyPos,UpdPos,Opts) ->
ok.
update_element(T,Tuple,KeyPos,UpdPos) ->
- KeyList = [Key || Key <- lists:seq(1,100)],
+ KeyList = [17,"seventeen",<<"seventeen">>,{17},list_to_binary(lists:seq(1,100)),make_ref(), self()],
lists:foreach(fun(Key) ->
TupleWithKey = setelement(KeyPos,Tuple,Key),
update_element_do(T,TupleWithKey,Key,UpdPos)
@@ -1357,6 +1595,8 @@ update_element_do(Tab,Tuple,Key,UpdPos) ->
% This will try all combinations of {fromValue,toValue}
%
% IMPORTANT: size(Values) must be a prime number for this to work!!!
+
+ %io:format("update_element_do for key=~p\n",[Key]),
Big32 = 16#12345678,
Big64 = 16#123456789abcdef0,
Values = { 623, -27, 0, Big32, -Big32, Big64, -Big64, Big32*Big32,
@@ -1377,14 +1617,6 @@ update_element_do(Tab,Tuple,Key,UpdPos) ->
(ToIx, [], Pos, _Rand, _MeF) ->
{Pos, element(ToIx+1,Values)} % single {pos,value} arg
end,
-
- NewTupleF = fun({Pos,Val}, Tpl, _MeF) ->
- setelement(Pos, Tpl, Val);
- ([{Pos,Val} | Tail], Tpl, MeF) ->
- MeF(Tail,setelement(Pos, Tpl, Val),MeF);
- ([], Tpl, _MeF) ->
- Tpl
- end,
UpdateF = fun(ToIx,Rand) ->
PosValArg = PosValArgF(ToIx,[],UpdPos,Rand,PosValArgF),
@@ -1392,7 +1624,7 @@ update_element_do(Tab,Tuple,Key,UpdPos) ->
ArgHash = erlang:phash2({Tab,Key,PosValArg}),
?line true = ets:update_element(Tab, Key, PosValArg),
?line ArgHash = erlang:phash2({Tab,Key,PosValArg}),
- NewTuple = NewTupleF(PosValArg,Tuple,NewTupleF),
+ NewTuple = update_tuple(PosValArg,Tuple),
?line [NewTuple] = ets:lookup(Tab,Key)
end,
@@ -1420,9 +1652,18 @@ update_element_do(Tab,Tuple,Key,UpdPos) ->
?line Checksum = (Length-1)*Length*(Length+1) div 2, % if Length is a prime
ok.
+update_tuple({Pos,Val}, Tpl) ->
+ setelement(Pos, Tpl, Val);
+update_tuple([{Pos,Val} | Tail], Tpl) ->
+ update_tuple(Tail,setelement(Pos, Tpl, Val));
+update_tuple([], Tpl) ->
+ Tpl.
+
+
+
update_element_neg(Opts) ->
- Set = ets:new(set,Opts),
- OrdSet = ets:new(ordered_set,[ordered_set | Opts]),
+ Set = ets_new(set,Opts),
+ OrdSet = ets_new(ordered_set,[ordered_set | Opts]),
update_element_neg_do(Set),
update_element_neg_do(OrdSet),
ets:delete(Set),
@@ -1430,8 +1671,8 @@ update_element_neg(Opts) ->
ets:delete(OrdSet),
?line {'EXIT',{badarg,_}} = (catch ets:update_element(OrdSet,key,{2,1})),
- ?line Bag = ets:new(bag,[bag | Opts]),
- ?line DBag = ets:new(duplicate_bag,[duplicate_bag | Opts]),
+ ?line Bag = ets_new(bag,[bag | Opts]),
+ ?line DBag = ets_new(duplicate_bag,[duplicate_bag | Opts]),
?line {'EXIT',{badarg,_}} = (catch ets:update_element(Bag,key,{2,1})),
?line {'EXIT',{badarg,_}} = (catch ets:update_element(DBag,key,{2,1})),
true = ets:delete(Bag),
@@ -1481,8 +1722,8 @@ update_counter(Config) when is_list(Config) ->
?line verify_etsmem(EtsMem).
update_counter_do(Opts) ->
- Set = ets:new(set,Opts),
- OrdSet = ets:new(ordered_set,[ordered_set | Opts]),
+ Set = ets_new(set,Opts),
+ OrdSet = ets_new(ordered_set,[ordered_set | Opts]),
update_counter_for(Set),
update_counter_for(OrdSet),
ets:delete(Set),
@@ -1503,6 +1744,7 @@ update_counter_for(T) ->
(Obj, Times, Arg3, Myself) ->
?line {NewObj, Ret} = uc_mimic(Obj,Arg3),
ArgHash = erlang:phash2({T,a,Arg3}),
+ %%io:format("update_counter(~p, ~p, ~p) expecting ~p\n",[T,a,Arg3,Ret]),
?line Ret = ets:update_counter(T,a,Arg3),
?line ArgHash = erlang:phash2({T,a,Arg3}),
%%io:format("NewObj=~p~n ",[NewObj]),
@@ -1628,8 +1870,8 @@ uc_adder(Init, {_Pos, Add, Thres, Warp}) ->
end.
update_counter_neg(Opts) ->
- Set = ets:new(set,Opts),
- OrdSet = ets:new(ordered_set,[ordered_set | Opts]),
+ Set = ets_new(set,Opts),
+ OrdSet = ets_new(ordered_set,[ordered_set | Opts]),
update_counter_neg_for(Set),
update_counter_neg_for(OrdSet),
ets:delete(Set),
@@ -1637,8 +1879,8 @@ update_counter_neg(Opts) ->
ets:delete(OrdSet),
?line {'EXIT',{badarg,_}} = (catch ets:update_counter(OrdSet,key,1)),
- ?line Bag = ets:new(bag,[bag | Opts]),
- ?line DBag = ets:new(duplicate_bag,[duplicate_bag | Opts]),
+ ?line Bag = ets_new(bag,[bag | Opts]),
+ ?line DBag = ets_new(duplicate_bag,[duplicate_bag | Opts]),
?line {'EXIT',{badarg,_}} = (catch ets:update_counter(Bag,key,1)),
?line {'EXIT',{badarg,_}} = (catch ets:update_counter(DBag,key,1)),
true = ets:delete(Bag),
@@ -1711,7 +1953,7 @@ wait_for_all(Pids0) ->
end.
evil_counter(I,Opts) ->
- T = ets:new(a, Opts),
+ T = ets_new(a, Opts),
Start0 = case I rem 3 of
0 -> 16#12345678;
1 -> 16#12345678FFFFFFFF;
@@ -1719,7 +1961,7 @@ evil_counter(I,Opts) ->
end,
Start = Start0 + random:uniform(100000),
ets:insert(T, {dracula,Start}),
- Iter = 90000,
+ Iter = 40000,
End = Start + Iter,
End = evil_counter_1(Iter, T),
ets:delete(T).
@@ -1740,7 +1982,7 @@ fixtable_next(Config) when is_list(Config) ->
fixtable_next_do(Opts) ->
?line EtsMem = etsmem(),
- ?line do_fixtable_next(ets:new(set,[public | Opts])),
+ ?line do_fixtable_next(ets_new(set,[public | Opts])),
?line verify_etsmem(EtsMem).
do_fixtable_next(Tab) ->
@@ -1821,24 +2063,24 @@ write_concurrency(doc) -> ["The 'write_concurrency' option"];
write_concurrency(suite) -> [];
write_concurrency(Config) when is_list(Config) ->
?line EtsMem = etsmem(),
- Yes1 = ets:new(foo,[public,{write_concurrency,true}]),
- Yes2 = ets:new(foo,[protected,{write_concurrency,true}]),
- No1 = ets:new(foo,[private,{write_concurrency,true}]),
+ Yes1 = ets_new(foo,[public,{write_concurrency,true}]),
+ Yes2 = ets_new(foo,[protected,{write_concurrency,true}]),
+ No1 = ets_new(foo,[private,{write_concurrency,true}]),
- Yes3 = ets:new(foo,[bag,public,{write_concurrency,true}]),
- Yes4 = ets:new(foo,[bag,protected,{write_concurrency,true}]),
- No2 = ets:new(foo,[bag,private,{write_concurrency,true}]),
+ Yes3 = ets_new(foo,[bag,public,{write_concurrency,true}]),
+ Yes4 = ets_new(foo,[bag,protected,{write_concurrency,true}]),
+ No2 = ets_new(foo,[bag,private,{write_concurrency,true}]),
- Yes5 = ets:new(foo,[duplicate_bag,public,{write_concurrency,true}]),
- Yes6 = ets:new(foo,[duplicate_bag,protected,{write_concurrency,true}]),
- No3 = ets:new(foo,[duplicate_bag,private,{write_concurrency,true}]),
+ Yes5 = ets_new(foo,[duplicate_bag,public,{write_concurrency,true}]),
+ Yes6 = ets_new(foo,[duplicate_bag,protected,{write_concurrency,true}]),
+ No3 = ets_new(foo,[duplicate_bag,private,{write_concurrency,true}]),
- No4 = ets:new(foo,[ordered_set,public,{write_concurrency,true}]),
- No5 = ets:new(foo,[ordered_set,protected,{write_concurrency,true}]),
- No6 = ets:new(foo,[ordered_set,private,{write_concurrency,true}]),
+ No4 = ets_new(foo,[ordered_set,public,{write_concurrency,true}]),
+ No5 = ets_new(foo,[ordered_set,protected,{write_concurrency,true}]),
+ No6 = ets_new(foo,[ordered_set,private,{write_concurrency,true}]),
- No7 = ets:new(foo,[public,{write_concurrency,false}]),
- No8 = ets:new(foo,[protected,{write_concurrency,false}]),
+ No7 = ets_new(foo,[public,{write_concurrency,false}]),
+ No8 = ets_new(foo,[protected,{write_concurrency,false}]),
?line YesMem = ets:info(Yes1,memory),
?line NoHashMem = ets:info(No1,memory),
@@ -1865,10 +2107,10 @@ write_concurrency(Config) when is_list(Config) ->
?line true = YesMem =:= NoHashMem
end,
- ?line {'EXIT',{badarg,_}} = (catch ets:new(foo,[public,{write_concurrency,foo}])),
- ?line {'EXIT',{badarg,_}} = (catch ets:new(foo,[public,{write_concurrency}])),
- ?line {'EXIT',{badarg,_}} = (catch ets:new(foo,[public,{write_concurrency,true,foo}])),
- ?line {'EXIT',{badarg,_}} = (catch ets:new(foo,[public,write_concurrency])),
+ ?line {'EXIT',{badarg,_}} = (catch ets_new(foo,[public,{write_concurrency,foo}])),
+ ?line {'EXIT',{badarg,_}} = (catch ets_new(foo,[public,{write_concurrency}])),
+ ?line {'EXIT',{badarg,_}} = (catch ets_new(foo,[public,{write_concurrency,true,foo}])),
+ ?line {'EXIT',{badarg,_}} = (catch ets_new(foo,[public,write_concurrency])),
lists:foreach(fun(T) -> ets:delete(T) end,
[Yes1,Yes2,Yes3,Yes4,Yes5,Yes6,
@@ -1945,7 +2187,7 @@ heir_founder(Master, HeirData, Opts) ->
none -> {heir,none};
_ -> {heir, Heir, HeirData}
end,
- ?line T = ets:new(foo,[named_table, private, HeirTpl | Opts]),
+ ?line T = ets_new(foo,[named_table, private, HeirTpl | Opts]),
?line true = ets:insert(T,{key,1}),
?line [{key,1}] = ets:lookup(T,key),
Self = self(),
@@ -2017,7 +2259,7 @@ give_away(Config) when is_list(Config) ->
repeat_for_opts(give_away_do).
give_away_do(Opts) ->
- ?line T = ets:new(foo,[named_table, private | Opts]),
+ ?line T = ets_new(foo,[named_table, private | Opts]),
?line true = ets:insert(T,{key,1}),
?line [{key,1}] = ets:lookup(T,key),
Parent = self(),
@@ -2043,7 +2285,7 @@ give_away_do(Opts) ->
?line undefined = ets:info(T),
%% Give and then kill receiver to get back
- ?line T2 = ets:new(foo,[private | Opts]),
+ ?line T2 = ets_new(foo,[private | Opts]),
?line true = ets:insert(T2,{key,1}),
?line ets:setopts(T2,{heir,self(),"Som en gummiboll..."}),
?line {Receiver2,Mref2} = spawn_monitor(fun()-> give_away_receiver(T2,Parent) end),
@@ -2065,7 +2307,7 @@ give_away_do(Opts) ->
?line give_me = receive_any(),
?line {'EXIT',{badarg,_}} = (catch ets:give_away(T2,ReceiverNeg,"A deleted table")),
- ?line T3 = ets:new(foo,[public | Opts]),
+ ?line T3 = ets_new(foo,[public | Opts]),
spawn_link(fun()-> {'EXIT',{badarg,_}} = (catch ets:give_away(T3,ReceiverNeg,"From non owner")),
Parent ! done
end),
@@ -2100,7 +2342,7 @@ setopts(Config) when is_list(Config) ->
setopts_do(Opts) ->
Self = self(),
- ?line T = ets:new(foo,[named_table, private | Opts]),
+ ?line T = ets_new(foo,[named_table, private | Opts]),
?line none = ets:info(T,heir),
Heir = spawn_link(fun()->heir_heir(Self) end),
?line ets:setopts(T,{heir,Heir,"Data"}),
@@ -2153,10 +2395,10 @@ bad_table(Config) when is_list(Config) ->
bad_table_do(Opts, DummyFile) ->
Parent = self(),
- {Pid,Mref} = spawn_opt(fun()-> ets:new(priv,[private,named_table | Opts]),
- Priv = ets:new(priv,[private | Opts]),
- ets:new(prot,[protected,named_table | Opts]),
- Prot = ets:new(prot,[protected | Opts]),
+ {Pid,Mref} = spawn_opt(fun()-> ets_new(priv,[private,named_table | Opts]),
+ Priv = ets_new(priv,[private | Opts]),
+ ets_new(prot,[protected,named_table | Opts]),
+ Prot = ets_new(prot,[protected | Opts]),
Parent ! {self(),Priv,Prot},
die_please = receive_any()
end,
@@ -2214,11 +2456,11 @@ bad_table_do(Opts, DummyFile) ->
bad_table_op({Opts,Priv,Prot}, Op) ->
%%io:format("Doing Op=~p on ~p's\n",[Op,Type]),
- T1 = ets:new(noname,Opts),
+ T1 = ets_new(noname,Opts),
bad_table_call(noname,Op),
ets:delete(T1),
bad_table_call(T1,Op),
- T2 = ets:new(named,[named_table | Opts]),
+ T2 = ets_new(named,[named_table | Opts]),
ets:delete(T2),
bad_table_call(named,Op),
bad_table_call(T2,Op),
@@ -2252,7 +2494,7 @@ rename(Config) when is_list(Config) ->
rename_do(Opts) ->
?line EtsMem = etsmem(),
- ets:new(foobazz,[named_table, public | Opts]),
+ ets_new(foobazz,[named_table, public | Opts]),
ets:insert(foobazz,{foo,bazz}),
ungermanbazz = ets:rename(foobazz,ungermanbazz),
{'EXIT',{badarg, _}} = (catch ets:lookup(foobazz,foo)),
@@ -2270,7 +2512,7 @@ rename_unnamed(Config) when is_list(Config) ->
rename_unnamed_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(bonkz,[public | Opts]),
+ ?line Tab = ets_new(bonkz,[public | Opts]),
?line {'EXIT',{badarg, _}} = (catch ets:insert(bonkz,{foo,bazz})),
?line bonkz = ets:info(Tab, name),
?line Tab = ets:rename(Tab, tjabonkz),
@@ -2289,7 +2531,7 @@ evil_rename(Config) when is_list(Config) ->
evil_rename_1(Old, New, Flags) ->
?line process_flag(trap_exit, true),
- ?line Old = ets:new(Old, Flags),
+ ?line Old = ets_new(Old, Flags),
?line Fixer = fun() -> ets:safe_fixtable(Old, true) end,
?line crazy_fixtable(15000, Fixer),
?line erlang:yield(),
@@ -2299,7 +2541,7 @@ evil_rename_1(Old, New, Flags) ->
ok.
crazy_fixtable(N, Fixer) ->
- Dracula = ets:new(count_dracula, [public]),
+ Dracula = ets_new(count_dracula, [public]),
ets:insert(Dracula, {count,0}),
SpawnFun = fun() ->
Fixer(),
@@ -2333,7 +2575,7 @@ evil_creater_destroyer() ->
ets:delete(T1).
evil_create_fixed_tab() ->
- T = ets:new(arne, [public]),
+ T = ets_new(arne, [public]),
ets:safe_fixtable(T, true),
T.
@@ -2347,8 +2589,8 @@ interface_equality(Config) when is_list(Config) ->
interface_equality_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Set = ets:new(set,[set | Opts]),
- ?line OrderedSet = ets:new(ordered_set,[ordered_set | Opts]),
+ ?line Set = ets_new(set,[set | Opts]),
+ ?line OrderedSet = ets_new(ordered_set,[ordered_set | Opts]),
?line F = fun(X,T,FF) -> case X of
0 -> true;
_ ->
@@ -2427,7 +2669,7 @@ ordered_match_do(Opts) ->
FF(X-1,T,FF)
end
end,
- ?line T1 = ets:new(xxx,[ordered_set| Opts]),
+ ?line T1 = ets_new(xxx,[ordered_set| Opts]),
?line F(3000,T1,F),
?line [[3,3],[3,3],[3,3]] = ets:match(T1, {'_','_','$1','$2',3}),
?line F2 = fun(X,Rem,Res,FF) -> case X of
@@ -2465,7 +2707,7 @@ ordered(Config) when is_list(Config) ->
ordered_do(Opts) ->
?line EtsMem = etsmem(),
- ?line T = ets:new(oset, [ordered_set | Opts]),
+ ?line T = ets_new(oset, [ordered_set | Opts]),
?line InsList = [
25,26,27,28,
5,6,7,8,
@@ -2526,8 +2768,8 @@ setbag(doc) -> ["Small test case for both set and bag type ets tables."];
setbag(suite) -> [];
setbag(Config) when is_list(Config) ->
?line EtsMem = etsmem(),
- ?line Set = ets:new(set,[set]),
- ?line Bag = ets:new(bag,[bag]),
+ ?line Set = ets_new(set,[set]),
+ ?line Bag = ets_new(bag,[bag]),
?line Key = {foo,bar},
%% insert some value
@@ -2547,15 +2789,15 @@ setbag(Config) when is_list(Config) ->
?line verify_etsmem(EtsMem).
badnew(doc) ->
- ["Test case to check proper return values for illegal ets:new() calls."];
+ ["Test case to check proper return values for illegal ets_new() calls."];
badnew(suite) -> [];
badnew(Config) when is_list(Config) ->
?line EtsMem = etsmem(),
- ?line {'EXIT',{badarg,_}} = (catch ets:new(12,[])),
- ?line {'EXIT',{badarg,_}} = (catch ets:new({a,b},[])),
- ?line {'EXIT',{badarg,_}} = (catch ets:new(name,[foo])),
- ?line {'EXIT',{badarg,_}} = (catch ets:new(name,{bag})),
- ?line {'EXIT',{badarg,_}} = (catch ets:new(name,bag)),
+ ?line {'EXIT',{badarg,_}} = (catch ets_new(12,[])),
+ ?line {'EXIT',{badarg,_}} = (catch ets_new({a,b},[])),
+ ?line {'EXIT',{badarg,_}} = (catch ets_new(name,[foo])),
+ ?line {'EXIT',{badarg,_}} = (catch ets_new(name,{bag})),
+ ?line {'EXIT',{badarg,_}} = (catch ets_new(name,bag)),
?line verify_etsmem(EtsMem).
verybadnew(doc) ->
@@ -2564,7 +2806,7 @@ verybadnew(doc) ->
verybadnew(suite) -> [];
verybadnew(Config) when is_list(Config) ->
?line EtsMem = etsmem(),
- ?line {'EXIT',{badarg,_}} = (catch ets:new(verybad,[set|protected])),
+ ?line {'EXIT',{badarg,_}} = (catch ets_new(verybad,[set|protected])),
?line verify_etsmem(EtsMem).
named(doc) -> ["Small check to see if named tables work."];
@@ -2641,9 +2883,9 @@ privacy_check(Pub,Prot,Priv) ->
?line [] = ets:lookup(Prot,foo).
privacy_owner(Boss, Opts) ->
- ets:new(pub, [public,named_table | Opts]),
- ets:new(prot,[protected,named_table | Opts]),
- ets:new(priv,[private,named_table | Opts]),
+ ets_new(pub, [public,named_table | Opts]),
+ ets_new(prot,[protected,named_table | Opts]),
+ ets_new(priv,[private,named_table | Opts]),
Boss ! ok,
privacy_owner_loop(Boss).
@@ -2670,8 +2912,6 @@ rotate_tuple(Tuple, N) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-insert(doc) -> ["Test proper and improper inserts into a table."];
-insert(suite) -> [empty,badinsert].
empty(doc) ->
["Check lookup in an empty table and lookup of a non-existing key"];
@@ -2681,7 +2921,7 @@ empty(Config) when is_list(Config) ->
empty_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foo,Opts),
+ ?line Tab = ets_new(foo,Opts),
?line [] = ets:lookup(Tab,key),
?line true = ets:insert(Tab,{key2,val}),
?line [] = ets:lookup(Tab,key),
@@ -2698,10 +2938,10 @@ badinsert_do(Opts) ->
?line EtsMem = etsmem(),
?line {'EXIT',{badarg,_}} = (catch ets:insert(foo,{key,val})),
- ?line Tab = ets:new(foo,Opts),
+ ?line Tab = ets_new(foo,Opts),
?line {'EXIT',{badarg,_}} = (catch ets:insert(Tab,{})),
- ?line Tab3 = ets:new(foo,[{keypos,3}| Opts]),
+ ?line Tab3 = ets_new(foo,[{keypos,3}| Opts]),
?line {'EXIT',{badarg,_}} = (catch ets:insert(Tab3,{a,b})),
?line {'EXIT',{badarg,_}} = (catch ets:insert(Tab,[key,val2])),
@@ -2711,8 +2951,6 @@ badinsert_do(Opts) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-lookup(doc) -> ["Some tests for lookups (timing, bad lookups, etc.)."];
-lookup(suite) -> [time_lookup,badlookup,lookup_order].
time_lookup(doc) -> ["Lookup timing."];
time_lookup(suite) -> [];
@@ -2725,7 +2963,7 @@ time_lookup(Config) when is_list(Config) ->
"~p ets lookups/s",[Values]))}.
time_lookup_do(Opts) ->
- ?line Tab = ets:new(foo,Opts),
+ ?line Tab = ets_new(foo,Opts),
?line fill_tab(Tab,foo),
?line ets:insert(Tab,{{a,key},foo}),
?line {Time,_} = ?t:timecall(test_server,do_times,
@@ -2740,7 +2978,7 @@ badlookup(suite) -> [];
badlookup(Config) when is_list(Config) ->
?line EtsMem = etsmem(),
?line {'EXIT',{badarg,_}} = (catch ets:lookup(foo,key)),
- ?line Tab = ets:new(foo,[]),
+ ?line Tab = ets_new(foo,[]),
?line ets:delete(Tab),
?line {'EXIT',{badarg,_}} = (catch ets:lookup(Tab,key)),
?line verify_etsmem(EtsMem).
@@ -2765,7 +3003,7 @@ lookup_order_2(Opts, Fixed) ->
Pair = [{A,B},{B,A},{A,C},{C,A},{B,C},{C,B}],
Combos = [{D1,D2,D3} || D1<-ABC, D2<-Pair, D3<-Pair],
lists:foreach(fun({D1,{D2a,D2b},{D3a,D3b}}) ->
- T = ets:new(foo,Opts),
+ T = ets_new(foo,Opts),
case Fixed of
true -> ets:safe_fixtable(T,true);
false -> ok
@@ -2839,8 +3077,6 @@ fill_tab(Tab,Val) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-lookup_element(doc) -> ["Some tests for lookup_element."];
-lookup_element(suite) -> [lookup_element_mult].
lookup_element_mult(doc) -> ["Multiple return elements (OTP-2386)"];
lookup_element_mult(suite) -> [];
@@ -2849,10 +3085,12 @@ lookup_element_mult(Config) when is_list(Config) ->
lookup_element_mult_do(Opts) ->
?line EtsMem = etsmem(),
- ?line T = ets:new(service, [bag, {keypos, 2} | Opts]),
+ ?line T = ets_new(service, [bag, {keypos, 2} | Opts]),
?line D = lists:reverse(lem_data()),
?line lists:foreach(fun(X) -> ets:insert(T, X) end, D),
?line ok = lem_crash_3(T),
+ ?line ets:insert(T, {0, "heap_key"}),
+ ?line ets:lookup_element(T, "heap_key", 2),
?line true = ets:delete(T),
?line verify_etsmem(EtsMem).
@@ -2880,11 +3118,6 @@ lem_crash_3(T) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-delete(doc) ->
- ["Check delete functionality (proper/improper deletes)"];
-delete(suite) ->
- [delete_elem,delete_tab,delete_large_tab,delete_large_named_table,evil_delete,
- table_leak,baddelete,match_delete,match_delete3].
delete_elem(doc) ->
["Check delete of an element inserted in a `filled' table."];
@@ -2894,7 +3127,7 @@ delete_elem(Config) when is_list(Config) ->
delete_elem_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foo,Opts),
+ ?line Tab = ets_new(foo,Opts),
?line fill_tab(Tab,foo),
?line ets:insert(Tab,{{b,key},foo}),
?line ets:insert(Tab,{{c,key},foo}),
@@ -2914,17 +3147,17 @@ delete_tab(Config) when is_list(Config) ->
delete_tab_do(Opts) ->
Name = foo,
?line EtsMem = etsmem(),
- ?line Name = ets:new(Name, [named_table | Opts]),
+ ?line Name = ets_new(Name, [named_table | Opts]),
?line true = ets:delete(foo),
%% The name should be available again.
- ?line Name = ets:new(Name, [named_table | Opts]),
+ ?line Name = ets_new(Name, [named_table | Opts]),
?line true = ets:delete(Name),
?line verify_etsmem(EtsMem).
delete_large_tab(doc) ->
"Check that ets:delete/1 works and that other processes can run.";
delete_large_tab(Config) when is_list(Config) ->
- ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)],
+ ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 200000)],
?line EtsMem = etsmem(),
repeat_for_opts(fun(Opts) -> delete_large_tab_do(Opts,Data) end),
?line verify_etsmem(EtsMem).
@@ -2936,7 +3169,7 @@ delete_large_tab_do(Opts,Data) ->
delete_large_tab_1(Name, Flags, Data, Fix) ->
- ?line Tab = ets:new(Name, Flags),
+ ?line Tab = ets_new(Name, Flags),
?line ets:insert(Tab, Data),
case Fix of
@@ -3003,7 +3236,7 @@ delete_large_named_table_do(Opts,Data) ->
?line delete_large_named_table_1(foo_hash, [named_table | Opts], Data, true).
delete_large_named_table_1(Name, Flags, Data, Fix) ->
- ?line Tab = ets:new(Name, Flags),
+ ?line Tab = ets_new(Name, Flags),
?line ets:insert(Tab, Data),
case Fix of
@@ -3016,7 +3249,7 @@ delete_large_named_table_1(Name, Flags, Data, Fix) ->
Pid = spawn_link(fun() ->
receive
{trace,Parent,call,_} ->
- ets:new(Name, [named_table])
+ ets_new(Name, [named_table])
end
end),
?line erlang:trace(self(), true, [call,{tracer,Pid}]),
@@ -3050,7 +3283,7 @@ evil_delete_do(Opts,Data) ->
evil_delete_not_owner(Name, Flags, Data, Fix) ->
io:format("Not owner: ~p, fix = ~p", [Name,Fix]),
- ?line Tab = ets:new(Name, [public|Flags]),
+ ?line Tab = ets_new(Name, [public|Flags]),
?line ets:insert(Tab, Data),
case Fix of
false -> ok;
@@ -3075,7 +3308,7 @@ evil_delete_not_owner(Name, Flags, Data, Fix) ->
evil_delete_owner(Name, Flags, Data, Fix) ->
?line Fun = fun() ->
- ?line Tab = ets:new(Name, [public|Flags]),
+ ?line Tab = ets_new(Name, [public|Flags]),
?line ets:insert(Tab, Data),
case Fix of
false -> ok;
@@ -3102,48 +3335,60 @@ exit_large_table_owner(doc) ->
exit_large_table_owner(suite) ->
[];
exit_large_table_owner(Config) when is_list(Config) ->
- ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)],
+ %%?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)],
+ ?line FEData = fun(Do) -> repeat_while(fun(500000) -> {false,ok};
+ (I) -> Do({erlang:phash2(I, 16#ffffff),I}),
+ {true, I+1}
+ end, 1)
+ end,
?line EtsMem = etsmem(),
- repeat_for_opts(fun(Opts) -> exit_large_table_owner_do(Opts,Data,Config) end),
+ repeat_for_opts({exit_large_table_owner_do,{FEData,Config}}),
?line verify_etsmem(EtsMem).
-exit_large_table_owner_do(Opts,Data,Config) ->
- ?line verify_rescheduling_exit(Config, Data, [named_table | Opts], true, 1, 1),
- ?line verify_rescheduling_exit(Config, Data, Opts, false, 1, 1).
+exit_large_table_owner_do(Opts,{FEData,Config}) ->
+ ?line verify_rescheduling_exit(Config, FEData, [named_table | Opts], true, 1, 1),
+ ?line verify_rescheduling_exit(Config, FEData, Opts, false, 1, 1).
exit_many_large_table_owner(doc) -> [];
exit_many_large_table_owner(suite) -> [];
exit_many_large_table_owner(Config) when is_list(Config) ->
- ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)],
+ %%?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)],
+ ?line FEData = fun(Do) -> repeat_while(fun(500000) -> {false,ok};
+ (I) -> Do({erlang:phash2(I, 16#ffffff),I}),
+ {true, I+1}
+ end, 1)
+ end,
?line EtsMem = etsmem(),
- repeat_for_opts(fun(Opts) -> exit_many_large_table_owner_do(Opts,Data,Config) end),
+ repeat_for_opts(fun(Opts) -> exit_many_large_table_owner_do(Opts,FEData,Config) end),
?line verify_etsmem(EtsMem).
-exit_many_large_table_owner_do(Opts,Data,Config) ->
- ?line verify_rescheduling_exit(Config, Data, Opts, true, 1, 4),
- ?line verify_rescheduling_exit(Config, Data, [named_table | Opts], false, 1, 4).
+exit_many_large_table_owner_do(Opts,FEData,Config) ->
+ ?line verify_rescheduling_exit(Config, FEData, Opts, true, 1, 4),
+ ?line verify_rescheduling_exit(Config, FEData, [named_table | Opts], false, 1, 4).
exit_many_tables_owner(doc) -> [];
exit_many_tables_owner(suite) -> [];
exit_many_tables_owner(Config) when is_list(Config) ->
+ NoData = fun(_Do) -> ok end,
?line EtsMem = etsmem(),
- ?line verify_rescheduling_exit(Config, [], [named_table], false, 1000, 1),
- ?line verify_rescheduling_exit(Config, [], [named_table,{write_concurrency,true}], false, 1000, 1),
+ ?line verify_rescheduling_exit(Config, NoData, [named_table], false, 1000, 1),
+ ?line verify_rescheduling_exit(Config, NoData, [named_table,{write_concurrency,true}], false, 1000, 1),
?line verify_etsmem(EtsMem).
exit_many_many_tables_owner(doc) -> [];
exit_many_many_tables_owner(suite) -> [];
exit_many_many_tables_owner(Config) when is_list(Config) ->
?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 50)],
- repeat_for_opts(fun(Opts) -> exit_many_many_tables_owner_do(Opts,Data,Config) end).
+ ?line FEData = fun(Do) -> lists:foreach(Do, Data) end,
+ repeat_for_opts(fun(Opts) -> exit_many_many_tables_owner_do(Opts,FEData,Config) end).
-exit_many_many_tables_owner_do(Opts,Data,Config) ->
- ?line verify_rescheduling_exit(Config, Data, [named_table | Opts], true, 200, 5),
- ?line verify_rescheduling_exit(Config, Data, Opts, false, 200, 5),
+exit_many_many_tables_owner_do(Opts,FEData,Config) ->
+ ?line verify_rescheduling_exit(Config, FEData, [named_table | Opts], true, 200, 5),
+ ?line verify_rescheduling_exit(Config, FEData, Opts, false, 200, 5),
?line wait_for_test_procs(),
?line EtsMem = etsmem(),
- ?line verify_rescheduling_exit(Config, Data, Opts, true, 200, 5),
- ?line verify_rescheduling_exit(Config, Data, [named_table | Opts], false, 200, 5),
+ ?line verify_rescheduling_exit(Config, FEData, Opts, true, 200, 5),
+ ?line verify_rescheduling_exit(Config, FEData, [named_table | Opts], false, 200, 5),
?line verify_etsmem(EtsMem).
@@ -3186,7 +3431,7 @@ vre_fix_tables(Tab) ->
receive Go -> ok end,
ok.
-verify_rescheduling_exit(Config, Data, Flags, Fix, NOTabs, NOProcs) ->
+verify_rescheduling_exit(Config, ForEachData, Flags, Fix, NOTabs, NOProcs) ->
?line NoFix = 5,
?line TestCase = atom_to_list(?config(test_case, Config)),
?line Parent = self(),
@@ -3201,8 +3446,8 @@ verify_rescheduling_exit(Config, Data, Flags, Fix, NOTabs, NOProcs) ->
++ "-" ++ integer_to_list(A)
++ "-" ++ integer_to_list(B)
++ "-" ++ integer_to_list(C)),
- Tab = ets:new(Name, Flags),
- ets:insert(Tab, Data),
+ Tab = ets_new(Name, Flags),
+ ForEachData(fun(Data) -> ets:insert(Tab, Data) end),
case Fix of
false -> ok;
true ->
@@ -3210,10 +3455,10 @@ verify_rescheduling_exit(Config, Data, Flags, Fix, NOTabs, NOProcs) ->
vre_fix_tables(Tab)
end,
lists:seq(1,NoFix)),
- lists:foreach(fun({K,_}) ->
- ets:delete(Tab, K)
- end,
- Data)
+ KeyPos = ets:info(Tab,keypos),
+ ForEachData(fun(Data) ->
+ ets:delete(Tab, element(KeyPos,Data))
+ end)
end
end,
NOTabs),
@@ -3260,7 +3505,7 @@ table_leak(Config) when is_list(Config) ->
table_leak_1(_,0) -> ok;
table_leak_1(Opts,N) ->
- ?line T = ets:new(fooflarf, Opts),
+ ?line T = ets_new(fooflarf, Opts),
?line true = ets:delete(T),
table_leak_1(Opts,N-1).
@@ -3270,7 +3515,7 @@ baddelete(suite) -> [];
baddelete(Config) when is_list(Config) ->
?line EtsMem = etsmem(),
?line {'EXIT',{badarg,_}} = (catch ets:delete(foo)),
- ?line Tab = ets:new(foo,[]),
+ ?line Tab = ets_new(foo,[]),
?line true = ets:delete(Tab),
?line {'EXIT',{badarg,_}} = (catch ets:delete(Tab)),
?line verify_etsmem(EtsMem).
@@ -3285,7 +3530,7 @@ match_delete(Config) when is_list(Config) ->
match_delete_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(kad,Opts),
+ ?line Tab = ets_new(kad,Opts),
?line fill_tab(Tab,foo),
?line ets:insert(Tab,{{c,key},bar}),
?line _ = ets:match_delete(Tab,{'_',foo}),
@@ -3329,7 +3574,7 @@ firstnext(Config) when is_list(Config) ->
firstnext_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foo,Opts),
+ ?line Tab = ets_new(foo,Opts),
?line [] = firstnext_collect(Tab,ets:first(Tab),[]),
?line fill_tab(Tab,foo),
?line Len = length(ets:tab2list(Tab)),
@@ -3352,10 +3597,10 @@ firstnext_concurrent(Config) when is_list(Config) ->
[dynamic_go() || _ <- lists:seq(1, 2)],
receive
after 5000 -> ok
- end.
+ end.
ets_init(Tab, N) ->
- ets:new(Tab, [named_table,public,ordered_set]),
+ ets_new(Tab, [named_table,public,ordered_set]),
cycle(Tab, lists:seq(1,N+1)).
cycle(_Tab, [H|T]) when H > length(T)-> ok;
@@ -3388,7 +3633,7 @@ slot(Config) when is_list(Config) ->
slot_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foo,Opts),
+ ?line Tab = ets_new(foo,Opts),
?line fill_tab(Tab,foo),
?line Elts = ets:info(Tab,size),
?line Elts = slot_loop(Tab,0,0),
@@ -3407,7 +3652,6 @@ slot_loop(Tab,SlotNo,EltsSoFar) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-match(suite) -> [match1, match2, match_object, match_object2].
match1(suite) -> [];
match1(Config) when is_list(Config) ->
@@ -3415,7 +3659,7 @@ match1(Config) when is_list(Config) ->
match1_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foo,Opts),
+ ?line Tab = ets_new(foo,Opts),
?line fill_tab(Tab,foo),
?line [] = ets:match(Tab,{}),
?line ets:insert(Tab,{{one,4},4}),
@@ -3480,7 +3724,7 @@ match_object(Config) when is_list(Config) ->
match_object_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foobar, Opts),
+ ?line Tab = ets_new(foobar, Opts),
?line fill_tab(Tab, foo),
?line ets:insert(Tab, {{one, 4}, 4}),
?line ets:insert(Tab,{{one,5},5}),
@@ -3524,7 +3768,7 @@ match_object2(Config) when is_list(Config) ->
match_object2_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foo, [bag, {keypos, 2} | Opts]),
+ ?line Tab = ets_new(foo, [bag, {keypos, 2} | Opts]),
?line fill_tab2(Tab, 0, 13005), % match_db_object does 1000
% elements per pass, might
% change in the future.
@@ -3542,7 +3786,6 @@ match_object2_do(Opts) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-misc(suite) -> [misc1, safe_fixtable, info, dups, tab2list].
tab2list(doc) -> ["Tests tab2list (OTP-3319)"];
tab2list(suite) -> [];
@@ -3563,7 +3806,7 @@ misc1(Config) when is_list(Config) ->
misc1_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foo,Opts),
+ ?line Tab = ets_new(foo,Opts),
?line true = lists:member(Tab,ets:all()),
?line ets:delete(Tab),
?line false = lists:member(Tab,ets:all()),
@@ -3582,7 +3825,7 @@ safe_fixtable(Config) when is_list(Config) ->
safe_fixtable_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foo, Opts),
+ ?line Tab = ets_new(foo, Opts),
?line fill_tab(Tab, foobar),
?line true = ets:safe_fixtable(Tab, true),
?line receive after 1 -> ok end,
@@ -3621,7 +3864,7 @@ info_do(Opts) ->
?line EtsMem = etsmem(),
?line MeMyselfI=self(),
?line ThisNode=node(),
- ?line Tab = ets:new(foobar, [{keypos, 2} | Opts]),
+ ?line Tab = ets_new(foobar, [{keypos, 2} | Opts]),
%% Note: ets:info/1 used to return a tuple, but from R11B onwards it
%% returns a list.
@@ -3675,15 +3918,12 @@ dups_do(Opts) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-files(suite) -> [tab2file, tab2file2, tab2file3, tabfile_ext1, tabfile_ext2,
- tabfile_ext3, tabfile_ext4].
-
tab2file(doc) -> ["Check the ets:tab2file function on an empty "
"ets table."];
tab2file(suite) -> [];
tab2file(Config) when is_list(Config) ->
%% Write an empty ets table to a file, read back and check properties.
- ?line Tab = ets:new(ets_SUITE_foo_tab, [named_table, set, private,
+ ?line Tab = ets_new(ets_SUITE_foo_tab, [named_table, set, private,
{keypos, 2}]),
?line FName = filename:join([?config(priv_dir, Config),"tab2file_case"]),
?line ok = ets:tab2file(Tab, FName),
@@ -3699,51 +3939,36 @@ tab2file(Config) when is_list(Config) ->
?line verify_etsmem(EtsMem).
tab2file2(doc) -> ["Check the ets:tab2file function on a ",
- "filled set type ets table."];
+ "filled set/bag type ets table."];
tab2file2(suite) -> [];
-tab2file2(Config) when is_list(Config) ->
- %% Try the same on a filled set table.
- ?line EtsMem = etsmem(),
- ?line Tab = ets:new(ets_SUITE_foo_tab, [named_table, set, private,
- {keypos, 2}]),
- ?line FName = filename:join([?config(priv_dir, Config),"tab2file2_case"]),
- ?line ok = fill_tab2(Tab, 0, 10000), % Fill up the table (grucho mucho!)
- ?line Len = length(ets:tab2list(Tab)),
- ?line ok = ets:tab2file(Tab, FName),
- ?line true = ets:delete(Tab),
- %
- ?line {ok, Tab2} = ets:file2tab(FName),
- ?line private = ets:info(Tab2, protection),
- ?line true = ets:info(Tab2, named_table),
- ?line 2 = ets:info(Tab2, keypos),
- ?line set = ets:info(Tab2, type),
- ?line Len = length(ets:tab2list(Tab2)),
- ?line true = ets:delete(Tab2),
- ?line verify_etsmem(EtsMem).
+tab2file2(Config) when is_list(Config) ->
+ repeat_for_opts({tab2file2_do,Config}, [[set,bag],compressed]).
-tab2file3(doc) -> ["Check the ets:tab2file function on a ",
- "filled bag type ets table."];
-tab2file3(suite) -> [];
-tab2file3(Config) when is_list(Config) ->
- %% Try the same on a filled bag table.
+tab2file2_do(Opts, Config) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(ets_SUITE_foo_tab, [named_table, bag, private,
- {keypos, 2}]),
- ?line FName = filename:join([?config(priv_dir, Config),"tab2file3_case"]),
+ ?line Tab = ets_new(ets_SUITE_foo_tab, [named_table, private,
+ {keypos, 2} | Opts]),
+ ?line FName = filename:join([?config(priv_dir, Config),"tab2file2_case"]),
?line ok = fill_tab2(Tab, 0, 10000), % Fill up the table (grucho mucho!)
?line Len = length(ets:tab2list(Tab)),
?line Mem = ets:info(Tab, memory),
+ ?line Type = ets:info(Tab, type),
+ %%io:format("org tab: ~p\n",[ets:info(Tab)]),
?line ok = ets:tab2file(Tab, FName),
?line true = ets:delete(Tab),
+ ?line EtsMem4 = etsmem(),
+
?line {ok, Tab2} = ets:file2tab(FName),
+ %%io:format("loaded tab: ~p\n",[ets:info(Tab2)]),
?line private = ets:info(Tab2, protection),
?line true = ets:info(Tab2, named_table),
?line 2 = ets:info(Tab2, keypos),
- ?line bag = ets:info(Tab2, type),
+ ?line Type = ets:info(Tab2, type),
?line Len = length(ets:tab2list(Tab2)),
?line Mem = ets:info(Tab2, memory),
?line true = ets:delete(Tab2),
+ io:format("Between = ~p\n", [EtsMem4]),
?line verify_etsmem(EtsMem).
-define(test_list, [8,5,4,1,58,125,255, 250, 245, 240, 235,
@@ -3787,7 +4012,7 @@ tabfile_ext1_do(Opts,Config) ->
?line FName = filename:join([?config(priv_dir, Config),"nisse.dat"]),
?line FName2 = filename:join([?config(priv_dir, Config),"countflip.dat"]),
L = lists:seq(1,10),
- T = ets:new(x,Opts),
+ T = ets_new(x,Opts),
Name = make_ref(),
[ets:insert(T,{X,integer_to_list(X)}) || X <- L],
ok = ets:tab2file(T,FName,[{extended_info,[object_count]}]),
@@ -3827,7 +4052,7 @@ tabfile_ext2_do(Opts,Config) ->
?line FName = filename:join([?config(priv_dir, Config),"olle.dat"]),
?line FName2 = filename:join([?config(priv_dir, Config),"bitflip.dat"]),
L = lists:seq(1,10),
- T = ets:new(x,Opts),
+ T = ets_new(x,Opts),
Name = make_ref(),
[ets:insert(T,{X,integer_to_list(X)}) || X <- L],
ok = ets:tab2file(T,FName,[{extended_info,[md5sum]}]),
@@ -3865,7 +4090,7 @@ tabfile_ext3(Config) when is_list(Config) ->
?line FName2 = filename:join([?config(priv_dir, Config),"ncountflip.dat"]),
L = lists:seq(1,10),
Name = make_ref(),
- ?MODULE = ets:new(?MODULE,[named_table]),
+ ?MODULE = ets_new(?MODULE,[named_table]),
[ets:insert(?MODULE,{X,integer_to_list(X)}) || X <- L],
ets:tab2file(?MODULE,FName),
{error,cannot_create_table} = ets:file2tab(FName),
@@ -3897,7 +4122,7 @@ tabfile_ext4(doc) ->
tabfile_ext4(Config) when is_list(Config) ->
?line FName = filename:join([?config(priv_dir, Config),"bauta.dat"]),
LL = lists:seq(1,10000),
- TL = ets:new(x,[]),
+ TL = ets_new(x,[]),
Name2 = make_ref(),
[ets:insert(TL,{X,integer_to_list(X)}) || X <- LL],
ok = ets:tab2file(TL,FName,[{extended_info,[md5sum]}]),
@@ -3942,7 +4167,6 @@ make_sub_binary(List, Num) when is_list(List) ->
{_,B} = split_binary(Bin, N+1),
B.
-heavy(suite) -> [heavy_lookup, heavy_lookup_element, heavy_concurrent].
%% Lookup stuff like crazy...
heavy_lookup(doc) -> ["Performs multiple lookups for every key ",
@@ -3953,7 +4177,7 @@ heavy_lookup(Config) when is_list(Config) ->
heavy_lookup_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foobar_table, [set, protected, {keypos, 2} | Opts]),
+ ?line Tab = ets_new(foobar_table, [set, protected, {keypos, 2} | Opts]),
?line ok = fill_tab2(Tab, 0, 7000),
?line ?t:do_times(50, ?MODULE, do_lookup, [Tab, 6999]),
?line true = ets:delete(Tab),
@@ -3976,7 +4200,7 @@ heavy_lookup_element(Config) when is_list(Config) ->
heavy_lookup_element_do(Opts) ->
?line EtsMem = etsmem(),
- ?line Tab = ets:new(foobar_table, [set, protected, {keypos, 2} | Opts]),
+ ?line Tab = ets_new(foobar_table, [set, protected, {keypos, 2} | Opts]),
?line ok = fill_tab2(Tab, 0, 7000),
case os:type() of
vxworks ->
@@ -4005,13 +4229,13 @@ do_lookup_element(Tab, N, M) ->
end.
-heavy_concurrent(_Config) ->
+heavy_concurrent(Config) when is_list(Config) ->
repeat_for_opts(do_heavy_concurrent).
do_heavy_concurrent(Opts) ->
- ?line Size = 20000,
+ ?line Size = 10000,
?line EtsMem = etsmem(),
- ?line Tab = ets:new(blupp, [set, public, {keypos, 2} | Opts]),
+ ?line Tab = ets_new(blupp, [set, public, {keypos, 2} | Opts]),
?line ok = fill_tab2(Tab, 0, Size),
?line Procs = lists:map(
fun (N) ->
@@ -4043,9 +4267,6 @@ do_heavy_concurrent_proc(Tab, N, Offs) ->
_ = ets:lookup(Tab, N),
do_heavy_concurrent_proc(Tab, N-1, Offs).
-fold(suite) -> [foldl_ordered, foldr_ordered,
- foldl, foldr,
- fold_empty].
fold_empty(doc) ->
[];
@@ -4115,7 +4336,7 @@ member(Config) when is_list(Config) ->
member_do(Opts) ->
?line EtsMem = etsmem(),
- ?line T = ets:new(xxx, Opts),
+ ?line T = ets_new(xxx, Opts),
?line false = ets:member(T,hej),
?line E = fun(0,_F)->ok;
(N,F) ->
@@ -4140,7 +4361,7 @@ member_do(Opts) ->
build_table(L1,L2,Num) ->
- T = ets:new(xxx, [ordered_set]
+ T = ets_new(xxx, [ordered_set]
),
lists:foreach(
fun(X1) ->
@@ -4162,7 +4383,7 @@ build_table(L1,L2,Num) ->
T.
build_table2(L1,L2,Num) ->
- T = ets:new(xxx, [ordered_set]
+ T = ets_new(xxx, [ordered_set]
),
lists:foreach(
fun(X1) ->
@@ -4293,7 +4514,7 @@ do_n_times(Fun,N) ->
do_n_times(Fun,N-1).
make_table(Name, Options, Elements) ->
- T = ets:new(Name, Options),
+ T = ets_new(Name, Options),
lists:foreach(fun(E) -> ets:insert(T, E) end, Elements),
T.
filltabint(Tab,0) ->
@@ -4357,13 +4578,13 @@ xfilltabstr(Tab,N) ->
fill_sets_int(N) ->
fill_sets_int(N,[]).
fill_sets_int(N,Opts) ->
- Tab1 = ets:new(xxx, [ordered_set|Opts]),
+ Tab1 = ets_new(xxx, [ordered_set|Opts]),
filltabint(Tab1,N),
- Tab2 = ets:new(xxx, [set|Opts]),
+ Tab2 = ets_new(xxx, [set|Opts]),
filltabint(Tab2,N),
- Tab3 = ets:new(xxx, [bag|Opts]),
+ Tab3 = ets_new(xxx, [bag|Opts]),
filltabint2(Tab3,N),
- Tab4 = ets:new(xxx, [duplicate_bag|Opts]),
+ Tab4 = ets_new(xxx, [duplicate_bag|Opts]),
filltabint3(Tab4,N),
[Tab1,Tab2,Tab3,Tab4].
@@ -4515,7 +4736,7 @@ gen_dets_filename(Config,N) ->
"testdets_" ++ integer_to_list(N) ++ ".dets").
otp_6842_select_1000(Config) when is_list(Config) ->
- ?line Tab = ets:new(xxx,[ordered_set]),
+ ?line Tab = ets_new(xxx,[ordered_set]),
?line [ets:insert(Tab,{X,X}) || X <- lists:seq(1,10000)],
?line AllTrue = lists:duplicate(10,true),
?line AllTrue =
@@ -4548,7 +4769,7 @@ check_seq(A,B,C) ->
otp_6338(Config) when is_list(Config) ->
L = binary_to_term(<<131,108,0,0,0,2,104,2,108,0,0,0,2,103,100,0,19,112,112,98,49,95,98,115,49,50,64,98,108,97,100,101,95,48,95,53,0,0,33,50,0,0,0,4,1,98,0,0,23,226,106,100,0,4,101,120,105,116,104,2,108,0,0,0,2,104,2,100,0,3,115,98,109,100,0,19,112,112,98,50,95,98,115,49,50,64,98,108,97,100,101,95,48,95,56,98,0,0,18,231,106,100,0,4,114,101,99,118,106>>),
- T = ets:new(xxx,[ordered_set]),
+ T = ets_new(xxx,[ordered_set]),
lists:foreach(fun(X) -> ets:insert(T,X) end,L),
[[4839,recv]] = ets:match(T,{[{sbm,ppb2_bs12@blade_0_8},'$1'],'$2'}),
ets:delete(T).
@@ -4559,7 +4780,7 @@ otp_5340(Config) when is_list(Config) ->
otp_5340_do(Opts) ->
N = 3000,
- T = ets:new(otp_5340, [bag,public | Opts]),
+ T = ets_new(otp_5340, [bag,public | Opts]),
Ids = [1,2,3,4,5],
[w(T, N, Id) || Id <- Ids],
verify(T, Ids),
@@ -4595,7 +4816,7 @@ otp_7665(Config) when is_list(Config) ->
repeat_for_opts(otp_7665_do).
otp_7665_do(Opts) ->
- Tab = ets:new(otp_7665,[bag | Opts]),
+ Tab = ets_new(otp_7665,[bag | Opts]),
Min = 0,
Max = 10,
lists:foreach(fun(N)-> otp_7665_act(Tab,Min,Max,N) end,
@@ -4658,7 +4879,7 @@ meta_wb_do(Opts) ->
Names).
meta_wb_new(Name, _, Tabs, Opts) ->
- case (catch ets:new(Name,[named_table|Opts])) of
+ case (catch ets_new(Name,[named_table|Opts])) of
Name ->
?line false = lists:member(Name, Tabs),
[Name | Tabs];
@@ -4706,7 +4927,7 @@ grow_shrink_0([N|Ns], EtsMem) ->
grow_shrink_0([], _) -> ok.
grow_shrink_1(N, Flags) ->
- ?line T = ets:new(a, Flags),
+ ?line T = ets_new(a, Flags),
?line grow_shrink_2(N, N, T),
?line ets:delete(T).
@@ -4736,7 +4957,7 @@ grow_pseudo_deleted_do() ->
grow_pseudo_deleted_do(Type) ->
process_flag(scheduler,1),
Self = self(),
- ?line T = ets:new(kalle,[Type,public,{write_concurrency,true}]),
+ ?line T = ets_new(kalle,[Type,public,{write_concurrency,true}]),
Mod = 7, Mult = 10000,
filltabint(T,Mod*Mult),
?line true = ets:safe_fixtable(T,true),
@@ -4778,7 +4999,7 @@ shrink_pseudo_deleted_do() ->
shrink_pseudo_deleted_do(Type) ->
process_flag(scheduler,1),
Self = self(),
- ?line T = ets:new(kalle,[Type,public,{write_concurrency,true}]),
+ ?line T = ets_new(kalle,[Type,public,{write_concurrency,true}]),
Half = 10000,
filltabint(T,Half*2),
?line true = ets:safe_fixtable(T,true),
@@ -4807,17 +5028,10 @@ shrink_pseudo_deleted_do(Type) ->
process_flag(scheduler,0).
-meta_smp(suite) ->
- [meta_lookup_unnamed_read,
- meta_lookup_unnamed_write,
- meta_lookup_named_read,
- meta_lookup_named_write,
- meta_newdel_unnamed,
- meta_newdel_named].
meta_lookup_unnamed_read(suite) -> [];
meta_lookup_unnamed_read(Config) when is_list(Config) ->
- InitF = fun(_) -> Tab = ets:new(unnamed,[]),
+ InitF = fun(_) -> Tab = ets_new(unnamed,[]),
true = ets:insert(Tab,{key,data}),
Tab
end,
@@ -4830,7 +5044,7 @@ meta_lookup_unnamed_read(Config) when is_list(Config) ->
meta_lookup_unnamed_write(suite) -> [];
meta_lookup_unnamed_write(Config) when is_list(Config) ->
- InitF = fun(_) -> Tab = ets:new(unnamed,[]),
+ InitF = fun(_) -> Tab = ets_new(unnamed,[]),
{Tab,0}
end,
ExecF = fun({Tab,N}) -> true = ets:insert(Tab,{key,N}),
@@ -4843,7 +5057,7 @@ meta_lookup_unnamed_write(Config) when is_list(Config) ->
meta_lookup_named_read(suite) -> [];
meta_lookup_named_read(Config) when is_list(Config) ->
InitF = fun([ProcN|_]) -> Name = list_to_atom(integer_to_list(ProcN)),
- Tab = ets:new(Name,[named_table]),
+ Tab = ets_new(Name,[named_table]),
true = ets:insert(Tab,{key,data}),
Tab
end,
@@ -4857,7 +5071,7 @@ meta_lookup_named_read(Config) when is_list(Config) ->
meta_lookup_named_write(suite) -> [];
meta_lookup_named_write(Config) when is_list(Config) ->
InitF = fun([ProcN|_]) -> Name = list_to_atom(integer_to_list(ProcN)),
- Tab = ets:new(Name,[named_table]),
+ Tab = ets_new(Name,[named_table]),
{Tab,0}
end,
ExecF = fun({Tab,N}) -> true = ets:insert(Tab,{key,N}),
@@ -4870,7 +5084,7 @@ meta_lookup_named_write(Config) when is_list(Config) ->
meta_newdel_unnamed(suite) -> [];
meta_newdel_unnamed(Config) when is_list(Config) ->
InitF = fun(_) -> ok end,
- ExecF = fun(_) -> Tab = ets:new(unnamed,[]),
+ ExecF = fun(_) -> Tab = ets_new(unnamed,[]),
true = ets:delete(Tab)
end,
FiniF = fun(_) -> ok end,
@@ -4880,7 +5094,7 @@ meta_newdel_named(suite) -> [];
meta_newdel_named(Config) when is_list(Config) ->
InitF = fun([ProcN|_]) -> list_to_atom(integer_to_list(ProcN))
end,
- ExecF = fun(Name) -> Name = ets:new(Name,[named_table]),
+ ExecF = fun(Name) -> Name = ets_new(Name,[named_table]),
true = ets:delete(Name),
Name
end,
@@ -4890,7 +5104,7 @@ meta_newdel_named(Config) when is_list(Config) ->
smp_insert(doc) -> ["Concurrent insert's on same table"];
smp_insert(suite) -> [];
smp_insert(Config) when is_list(Config) ->
- ets:new(smp_insert,[named_table,public,{write_concurrency,true}]),
+ ets_new(smp_insert,[named_table,public,{write_concurrency,true}]),
InitF = fun(_) -> ok end,
ExecF = fun(_) -> true = ets:insert(smp_insert,{random:uniform(10000)})
end,
@@ -4905,7 +5119,7 @@ smp_fixed_delete(Config) when is_list(Config) ->
only_if_smp(fun()->smp_fixed_delete_do() end).
smp_fixed_delete_do() ->
- T = ets:new(foo,[public,{write_concurrency,true}]),
+ T = ets_new(foo,[public,{write_concurrency,true}]),
%%Mem = ets:info(T,memory),
NumOfObjs = 100000,
filltabint(T,NumOfObjs),
@@ -4941,7 +5155,7 @@ smp_unfix_fix(Config) when is_list(Config) ->
smp_unfix_fix_do() ->
process_flag(scheduler,1),
Parent = self(),
- T = ets:new(foo,[public,{write_concurrency,true}]),
+ T = ets_new(foo,[public,{write_concurrency,true}]),
%%Mem = ets:info(T,memory),
NumOfObjs = 100000,
Deleted = 50000,
@@ -5001,7 +5215,7 @@ otp_8166_do(WC) ->
%% Bug scenario: One process segv while reading the table because another
%% process is doing unfix without write-lock at the end of a trapping match_object.
process_flag(scheduler,1),
- T = ets:new(foo,[public, {write_concurrency,WC}]),
+ T = ets_new(foo,[public, {write_concurrency,WC}]),
NumOfObjs = 3000, %% Need more than 1000 live objects for match_object to trap one time
Deleted = NumOfObjs div 2,
filltabint(T,NumOfObjs),
@@ -5115,7 +5329,7 @@ verify_table_load(T) ->
otp_8732(doc) -> ["ets:select on a tree with NIL key object"];
otp_8732(Config) when is_list(Config) ->
- Tab = ets:new(noname,[ordered_set]),
+ Tab = ets_new(noname,[ordered_set]),
filltabstr(Tab,999),
ets:insert(Tab,{[],"nasty NIL object"}),
?line [] = ets:match(Tab,{'_',nomatch}), %% Will hang if bug not fixed
@@ -5126,7 +5340,7 @@ smp_select_delete(suite) -> [];
smp_select_delete(doc) ->
["Run concurrent select_delete (and inserts) on same table."];
smp_select_delete(Config) when is_list(Config) ->
- T = ets:new(smp_select_delete,[named_table,public,{write_concurrency,true}]),
+ T = ets_new(smp_select_delete,[named_table,public,{write_concurrency,true}]),
Mod = 17,
Zeros = erlang:make_tuple(Mod,0),
InitF = fun(_) -> Zeros end,
@@ -5179,6 +5393,39 @@ smp_select_delete(Config) when is_list(Config) ->
?line false = ets:info(T,fixed),
ets:delete(T).
+types(doc) -> ["Test different types"];
+types(Config) when is_list(Config) ->
+ init_externals(),
+ repeat_for_opts(types_do,[[set,ordered_set],compressed]).
+
+types_do(Opts) ->
+ EtsMem = etsmem(),
+ ?line T = ets_new(xxx,Opts),
+ Fun = fun(Term) ->
+ ets:insert(T,{Term}),
+ ?line [{Term}] = ets:lookup(T,Term),
+ ets:insert(T,{Term,xxx}),
+ ?line [{Term,xxx}] = ets:lookup(T,Term),
+ ets:insert(T,{Term,"xxx"}),
+ ?line [{Term,"xxx"}] = ets:lookup(T,Term),
+ ets:insert(T,{xxx,Term}),
+ ?line [{xxx,Term}] = ets:lookup(T,xxx),
+ ets:insert(T,{"xxx",Term}),
+ ?line [{"xxx",Term}] = ets:lookup(T,"xxx"),
+ ets:delete_all_objects(T),
+ ?line 0 = ets:info(T,size)
+ end,
+ test_terms(Fun, strict),
+ ets:delete(T),
+ ?line verify_etsmem(EtsMem).
+
+
+
+
+%
+% Utility functions:
+%
+
add_lists(L1,L2) ->
add_lists(L1,L2,[]).
add_lists([],[],Acc) ->
@@ -5243,7 +5490,29 @@ my_tab_to_list(_Ts,'$end_of_table', Acc) -> lists:reverse(Acc);
my_tab_to_list(Ts,Key, Acc) ->
my_tab_to_list(Ts,ets:next(Ts,Key),[ets:lookup(Ts, Key)| Acc]).
+wait_for_all_schedulers_online_to_execute() ->
+ PMs = lists:map(fun (Sched) ->
+ spawn_opt(fun () -> ok end,
+ [monitor, {scheduler, Sched}])
+ end,
+ lists:seq(1,erlang:system_info(schedulers_online))),
+ lists:foreach(fun ({P, M}) ->
+ receive
+ {'DOWN', M, process, P, _} -> ok
+ end
+ end,
+ PMs),
+ ok.
+
etsmem() ->
+ %% Wait until it is guaranteed that all already scheduled
+ %% deallocations of DbTable structures have completed.
+ wait_for_all_schedulers_online_to_execute(),
+
+ AllTabs = lists:map(fun(T) -> {T,ets:info(T,name),ets:info(T,size),
+ ets:info(T,memory),ets:info(T,type)}
+ end, ets:all()),
+ Mem =
{try erlang:memory(ets) catch error:notsup -> notsup end,
case erlang:system_info({allocator,ets_alloc}) of
false -> undefined;
@@ -5262,12 +5531,13 @@ etsmem() ->
{value,{_,BlSz,_,_}} = lists:keysearch(blocks_size, 1, L),
{Bl0+Bl,BlSz0+BlSz}
end, {0,0}, MSBCS)
- end}.
+ end},
+ {Mem,AllTabs}.
-verify_etsmem(MemInfo) ->
+verify_etsmem({MemInfo,AllTabs}) ->
wait_for_test_procs(),
case etsmem() of
- MemInfo ->
+ {MemInfo,_} ->
io:format("Ets mem info: ~p", [MemInfo]),
case MemInfo of
{ErlMem,EtsAlloc} when ErlMem == notsup; EtsAlloc == undefined ->
@@ -5276,12 +5546,15 @@ verify_etsmem(MemInfo) ->
_ ->
ok
end;
- Other ->
+ {MemInfo2, AllTabs2} ->
io:format("Expected: ~p", [MemInfo]),
- io:format("Actual: ~p", [Other]),
+ io:format("Actual: ~p", [MemInfo2]),
+ io:format("Changed tables before: ~p\n",[AllTabs -- AllTabs2]),
+ io:format("Changed tables after: ~p\n", [AllTabs2 -- AllTabs]),
?t:fail()
end.
+
start_loopers(N, Prio, Fun, State) ->
lists:map(fun (_) ->
my_spawn_opt(fun () -> looper(Fun, State) end,
@@ -5386,6 +5659,20 @@ repeat_while(Fun, Arg0) ->
{false,Ret} -> Ret
end.
+%% Some (but not all) permutations of List
+repeat_for_permutations(Fun, List) ->
+ repeat_for_permutations(Fun, List, length(List)-1).
+repeat_for_permutations(Fun, List, 0) ->
+ Fun(List);
+repeat_for_permutations(Fun, List, N) ->
+ {A,B} = lists:split(N, List),
+ L1 = B++A,
+ L2 = lists:reverse(L1),
+ L3 = B++lists:reverse(A),
+ L4 = lists:reverse(B)++A,
+ Fun(L1), Fun(L2), Fun(L3), Fun(L4),
+ repeat_for_permutations(Fun, List, N-1).
+
receive_any() ->
receive M ->
io:format("Process ~p got msg ~p\n", [self(),M]),
@@ -5441,22 +5728,232 @@ only_if_smp(Schedulers, Func) ->
{true,_} -> Func()
end.
+%% Copy-paste from emulator/test/binary_SUITE.erl
+-define(heap_binary_size, 64).
+test_terms(Test_Func, Mode) ->
+ garbage_collect(),
+ ?line Pib0 = process_info(self(),binary),
+
+ ?line Test_Func(atom),
+ ?line Test_Func(''),
+ ?line Test_Func('a'),
+ ?line Test_Func('ab'),
+ ?line Test_Func('abc'),
+ ?line Test_Func('abcd'),
+ ?line Test_Func('abcde'),
+ ?line Test_Func('abcdef'),
+ ?line Test_Func('abcdefg'),
+ ?line Test_Func('abcdefgh'),
+
+ ?line Test_Func(fun() -> ok end),
+ X = id([a,{b,c},c]),
+ Y = id({x,y,z}),
+ Z = id(1 bsl 8*257),
+ ?line Test_Func(fun() -> X end),
+ ?line Test_Func(fun() -> {X,Y} end),
+ ?line Test_Func([fun() -> {X,Y,Z} end,
+ fun() -> {Z,X,Y} end,
+ fun() -> {Y,Z,X} end]),
+
+ ?line Test_Func({trace_ts,{even_bigger,{some_data,fun() -> ok end}},{1,2,3}}),
+ ?line Test_Func({trace_ts,{even_bigger,{some_data,<<1,2,3,4,5,6,7,8,9,10>>}},
+ {1,2,3}}),
+
+ ?line Test_Func(1),
+ ?line Test_Func(42),
+ ?line Test_Func(-23),
+ ?line Test_Func(256),
+ ?line Test_Func(25555),
+ ?line Test_Func(-3333),
+
+ ?line Test_Func(1.0),
+
+ ?line Test_Func(183749783987483978498378478393874),
+ ?line Test_Func(-37894183749783987483978498378478393874),
+ Very_Big = very_big_num(),
+ ?line Test_Func(Very_Big),
+ ?line Test_Func(-Very_Big+1),
+
+ ?line Test_Func([]),
+ ?line Test_Func("abcdef"),
+ ?line Test_Func([a, b, 1, 2]),
+ ?line Test_Func([a|b]),
+
+ ?line Test_Func({}),
+ ?line Test_Func({1}),
+ ?line Test_Func({a, b}),
+ ?line Test_Func({a, b, c}),
+ ?line Test_Func(list_to_tuple(lists:seq(0, 255))),
+ ?line Test_Func(list_to_tuple(lists:seq(0, 256))),
+
+ ?line Test_Func(make_ref()),
+ ?line Test_Func([make_ref(), make_ref()]),
+
+ ?line Test_Func(make_port()),
+
+ ?line Test_Func(make_pid()),
+ ?line Test_Func(make_ext_pid()),
+ ?line Test_Func(make_ext_port()),
+ ?line Test_Func(make_ext_ref()),
+
+ Bin0 = list_to_binary(lists:seq(0, 14)),
+ ?line Test_Func(Bin0),
+ Bin1 = list_to_binary(lists:seq(0, ?heap_binary_size)),
+ ?line Test_Func(Bin1),
+ Bin2 = list_to_binary(lists:seq(0, ?heap_binary_size+1)),
+ ?line Test_Func(Bin2),
+ Bin3 = list_to_binary(lists:seq(0, 255)),
+ garbage_collect(),
+ Pib = process_info(self(),binary),
+ ?line Test_Func(Bin3),
+ garbage_collect(),
+ case Mode of
+ strict -> ?line Pib = process_info(self(),binary);
+ skip_refc_check -> ok
+ end,
+
+ ?line Test_Func(make_unaligned_sub_binary(Bin0)),
+ ?line Test_Func(make_unaligned_sub_binary(Bin1)),
+ ?line Test_Func(make_unaligned_sub_binary(Bin2)),
+ ?line Test_Func(make_unaligned_sub_binary(Bin3)),
+
+ ?line Test_Func(make_sub_binary(lists:seq(42, 43))),
+ ?line Test_Func(make_sub_binary([42,43,44])),
+ ?line Test_Func(make_sub_binary([42,43,44,45])),
+ ?line Test_Func(make_sub_binary([42,43,44,45,46])),
+ ?line Test_Func(make_sub_binary([42,43,44,45,46,47])),
+ ?line Test_Func(make_sub_binary([42,43,44,45,46,47,48])),
+ ?line Test_Func(make_sub_binary(lists:seq(42, 49))),
+ ?line Test_Func(make_sub_binary(lists:seq(0, 14))),
+ ?line Test_Func(make_sub_binary(lists:seq(0, ?heap_binary_size))),
+ ?line Test_Func(make_sub_binary(lists:seq(0, ?heap_binary_size+1))),
+ ?line Test_Func(make_sub_binary(lists:seq(0, 255))),
+
+ ?line Test_Func(make_unaligned_sub_binary(lists:seq(42, 43))),
+ ?line Test_Func(make_unaligned_sub_binary([42,43,44])),
+ ?line Test_Func(make_unaligned_sub_binary([42,43,44,45])),
+ ?line Test_Func(make_unaligned_sub_binary([42,43,44,45,46])),
+ ?line Test_Func(make_unaligned_sub_binary([42,43,44,45,46,47])),
+ ?line Test_Func(make_unaligned_sub_binary([42,43,44,45,46,47,48])),
+ ?line Test_Func(make_unaligned_sub_binary(lists:seq(42, 49))),
+ ?line Test_Func(make_unaligned_sub_binary(lists:seq(0, 14))),
+ ?line Test_Func(make_unaligned_sub_binary(lists:seq(0, ?heap_binary_size))),
+ ?line Test_Func(make_unaligned_sub_binary(lists:seq(0, ?heap_binary_size+1))),
+ ?line Test_Func(make_unaligned_sub_binary(lists:seq(0, 255))),
+
+ %% Bit level binaries.
+ ?line Test_Func(<<1:1>>),
+ ?line Test_Func(<<2:2>>),
+ ?line Test_Func(<<42:10>>),
+ ?line Test_Func(list_to_bitstring([<<5:6>>|lists:seq(0, 255)])),
+
+ ?line Test_Func(F = fun(A) -> 42*A end),
+ ?line Test_Func(lists:duplicate(32, F)),
+
+ ?line Test_Func(FF = fun binary_SUITE:all/1),
+ ?line Test_Func(lists:duplicate(32, FF)),
+
+ garbage_collect(),
+ case Mode of
+ strict -> ?line Pib0 = process_info(self(),binary);
+ skip_refc_check -> ok
+ end,
+ ok.
+
+
+id(I) -> I.
+
+very_big_num() ->
+ very_big_num(33, 1).
+
+very_big_num(Left, Result) when Left > 0 ->
+ ?line very_big_num(Left-1, Result*256);
+very_big_num(0, Result) ->
+ ?line Result.
+
+make_port() ->
+ ?line open_port({spawn, efile}, [eof]).
+
+make_pid() ->
+ ?line spawn_link(?MODULE, sleeper, []).
+
+sleeper() ->
+ ?line receive after infinity -> ok end.
+
+make_ext_pid() ->
+ {Pid, _, _} = get(externals),
+ Pid.
+
+make_ext_port() ->
+ {_, Port, _} = get(externals),
+ Port.
+make_ext_ref() ->
+ {_, _, Ref} = get(externals),
+ Ref.
+
+init_externals() ->
+ case get(externals) of
+ undefined ->
+ SysDistSz = ets:info(sys_dist,size),
+ ?line Pa = filename:dirname(code:which(?MODULE)),
+ ?line {ok, Node} = test_server:start_node(plopp, slave, [{args, " -pa " ++ Pa}]),
+ ?line Res = case rpc:call(Node, ?MODULE, rpc_externals, []) of
+ {badrpc, {'EXIT', E}} ->
+ test_server:fail({rpcresult, E});
+ R -> R
+ end,
+ ?line test_server:stop_node(Node),
+
+ %% Wait for table 'sys_dist' to stabilize
+ repeat_while(fun() ->
+ case ets:info(sys_dist,size) of
+ SysDistSz -> false;
+ Sz ->
+ io:format("Waiting for sys_dist to revert size from ~p to size ~p\n",
+ [Sz, SysDistSz]),
+ receive after 1000 -> true end
+ end
+ end),
+ put(externals, Res);
+
+ {_,_,_} -> ok
+ end.
+
+rpc_externals() ->
+ {self(), make_port(), make_ref()}.
+
+make_sub_binary(Bin) when is_binary(Bin) ->
+ {_,B} = split_binary(list_to_binary([0,1,3,Bin]), 3),
+ B;
+make_sub_binary(List) ->
+ make_sub_binary(list_to_binary(List)).
+
+make_unaligned_sub_binary(Bin0) when is_binary(Bin0) ->
+ Bin1 = <<0:3,Bin0/binary,31:5>>,
+ Sz = size(Bin0),
+ <<0:3,Bin:Sz/binary,31:5>> = id(Bin1),
+ Bin;
+make_unaligned_sub_binary(List) ->
+ make_unaligned_sub_binary(list_to_binary(List)).
%% Repeat test function with different combination of table options
%%
repeat_for_opts(F) ->
- repeat_for_opts(F, [write_concurrency, read_concurrency]).
+ repeat_for_opts(F, [write_concurrency, read_concurrency, compressed]).
repeat_for_opts(F, OptGenList) when is_atom(F) ->
repeat_for_opts(fun(Opts) -> ?MODULE:F(Opts) end, OptGenList);
+repeat_for_opts({F,Args}, OptGenList) when is_atom(F) ->
+ repeat_for_opts(fun(Opts) -> ?MODULE:F(Opts,Args) end, OptGenList);
repeat_for_opts(F, OptGenList) ->
repeat_for_opts(F, OptGenList, []).
repeat_for_opts(F, [], Acc) ->
- lists:map(fun(Opts) ->
- io:format("Calling with options ~p\n",[Opts]),
- F(Opts)
- end, Acc);
+ lists:map(fun(Opts) ->
+ OptList = lists:filter(fun(E) -> E =/= void end, Opts),
+ io:format("Calling with options ~p\n",[OptList]),
+ F(OptList)
+ end, Acc);
repeat_for_opts(F, [OptList | Tail], []) when is_list(OptList) ->
repeat_for_opts(F, Tail, [[Opt] || Opt <- OptList]);
repeat_for_opts(F, [OptList | Tail], AccList) when is_list(OptList) ->
@@ -5466,6 +5963,9 @@ repeat_for_opts(F, [Atom | Tail], AccList) when is_atom(Atom) ->
repeat_for_opts_atom2list(all_types) -> [set,ordered_set,bag,duplicate_bag];
repeat_for_opts_atom2list(write_concurrency) -> [{write_concurrency,false},{write_concurrency,true}];
-repeat_for_opts_atom2list(read_concurrency) -> [{read_concurrency,false},{read_concurrency,true}].
-
+repeat_for_opts_atom2list(read_concurrency) -> [{read_concurrency,false},{read_concurrency,true}];
+repeat_for_opts_atom2list(compressed) -> [compressed,void].
+ets_new(Name, Opts) ->
+ %%ets:new(Name, [compressed | Opts]).
+ ets:new(Name, Opts).
diff --git a/lib/stdlib/test/ets_tough_SUITE.erl b/lib/stdlib/test/ets_tough_SUITE.erl
index 4c8d941f13..0386a0272a 100644
--- a/lib/stdlib/test/ets_tough_SUITE.erl
+++ b/lib/stdlib/test/ets_tough_SUITE.erl
@@ -17,13 +17,33 @@
%% %CopyrightEnd%
%%
-module(ets_tough_SUITE).
--export([all/1,ex1/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,ex1/1]).
-export([init/1,terminate/2,handle_call/3,handle_info/2]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-compile([export_all]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [ex1].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [ex1].
-define(DEBUG(X),debug_disabled).
@@ -34,7 +54,7 @@ init_per_testcase(_Func, Config) ->
Dog=test_server:timetrap(test_server:seconds(300)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ets:delete(?GLOBAL_PARAMS).
diff --git a/lib/stdlib/test/file_sorter_SUITE.erl b/lib/stdlib/test/file_sorter_SUITE.erl
index c00ed91fe7..9ca2460a05 100644
--- a/lib/stdlib/test/file_sorter_SUITE.erl
+++ b/lib/stdlib/test/file_sorter_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -27,12 +27,13 @@
-define(t,test_server).
-define(privdir(_), "./file_sorter_SUITE_priv").
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(format(S, A), ok).
-define(privdir(Conf), ?config(priv_dir, Conf)).
-endif.
--export([all/1, basic/1, badarg/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, basic/1, badarg/1,
term_sort/1, term_keysort/1,
binary_term_sort/1, binary_term_keysort/1,
binary_sort/1,
@@ -44,30 +45,42 @@
binary_check/1,
inout/1, misc/1, many/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
init_per_testcase(_Case, Config) ->
Dog=?t:timetrap(?t:minutes(2)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- {req,[stdlib,kernel],
- [basic, badarg,
- term_sort, term_keysort,
- binary_term_sort, binary_term_keysort,
- binary_sort,
- term_merge, term_keymerge,
- binary_term_merge, binary_term_keymerge,
- binary_merge,
- term_check, binary_term_keycheck,
- binary_term_check, binary_term_keycheck,
- binary_check,
- inout, misc, many]}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic, badarg, term_sort, term_keysort,
+ binary_term_sort, binary_term_keysort, binary_sort,
+ term_merge, term_keymerge, binary_term_merge,
+ binary_term_keymerge, binary_merge, term_check,
+ binary_term_keycheck, binary_term_check,
+ binary_term_keycheck, binary_check, inout, misc, many].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
basic(doc) ->
["Basic test case."];
diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl
index d54741051f..628e741870 100644
--- a/lib/stdlib/test/filelib_SUITE.erl
+++ b/lib/stdlib/test/filelib_SUITE.erl
@@ -19,27 +19,47 @@
-module(filelib_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
wildcard_one/1,wildcard_two/1,wildcard_errors/1,
fold_files/1,otp_5960/1,ensure_dir_eexist/1]).
-import(lists, [foreach/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?t:minutes(5)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [wildcard_one,wildcard_two,wildcard_errors,fold_files,otp_5960,
- ensure_dir_eexist].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [wildcard_one, wildcard_two, wildcard_errors,
+ fold_files, otp_5960, ensure_dir_eexist].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
wildcard_one(Config) when is_list(Config) ->
?line {ok,OldCwd} = file:get_cwd(),
@@ -53,8 +73,11 @@ wildcard_one(Config) when is_list(Config) ->
wildcard_two(Config) when is_list(Config) ->
?line Dir = filename:join(?config(priv_dir, Config), "wildcard_two"),
+ ?line DirB = unicode:characters_to_binary(Dir, file:native_name_encoding()),
?line ok = file:make_dir(Dir),
- ?line do_wildcard_1(Dir, fun(Wc) -> filelib:wildcard(Wc, Dir) end),
+ ?line do_wildcard_1(Dir, fun(Wc) -> io:format("~p~n",[{Wc,Dir, X = filelib:wildcard(Wc, Dir)}]),X end),
+ ?line do_wildcard_1(Dir, fun(Wc) -> io:format("~p~n",[{Wc,DirB, X = filelib:wildcard(Wc, DirB)}]),
+ [unicode:characters_to_list(Y,file:native_name_encoding()) || Y <- X] end),
?line do_wildcard_1(Dir, fun(Wc) -> filelib:wildcard(Wc, Dir++"/") end),
case os:type() of
{win32,_} ->
@@ -253,5 +276,7 @@ ensure_dir_eexist(Config) when is_list(Config) ->
%% There already is a file with the name of the directory
%% we want to create.
?line NeedFile = filename:join(Name, "file"),
+ ?line NeedFileB = filename:join(Name, <<"file">>),
?line {error, eexist} = filelib:ensure_dir(NeedFile),
+ ?line {error, eexist} = filelib:ensure_dir(NeedFileB),
ok.
diff --git a/lib/stdlib/test/filename_SUITE.erl b/lib/stdlib/test/filename_SUITE.erl
index ab6521f37b..a72af3448b 100644
--- a/lib/stdlib/test/filename_SUITE.erl
+++ b/lib/stdlib/test/filename_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -17,17 +17,44 @@
%% %CopyrightEnd%
%%
-module(filename_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([absname/1, absname_2/1,
basename_1/1, basename_2/1,
dirname/1, extension/1, join/1, t_nativename/1]).
-export([pathtype/1,rootname/1,split/1,find_src/1]).
--include("test_server.hrl").
+-export([absname_bin/1, absname_bin_2/1,
+ basename_bin_1/1, basename_bin_2/1,
+ dirname_bin/1, extension_bin/1, join_bin/1]).
+-export([pathtype_bin/1,rootname_bin/1,split_bin/1]).
-all(suite) ->
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[absname, absname_2, basename_1, basename_2, dirname,
extension,
- join, pathtype, rootname, split, t_nativename, find_src].
+ join, pathtype, rootname, split, t_nativename, find_src,
+ absname_bin, absname_bin_2, basename_bin_1, basename_bin_2, dirname_bin,
+ extension_bin,
+ join_bin, pathtype_bin, rootname_bin, split_bin].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -457,3 +484,307 @@ find_src(Config) when is_list(Config) ->
%% Try to find the source for a preloaded module.
?line {error,{preloaded,init}} = filename:find_src(init),
ok.
+
+%%
+%%
+%% With binaries
+%%
+%%
+
+absname_bin(Config) when is_list(Config) ->
+ case os:type() of
+ {win32, _} ->
+ ?line [Drive|_] = ?config(priv_dir, Config),
+ ?line Temp = filename:join([Drive|":/"], "temp"),
+ ?line case file:make_dir(Temp) of
+ ok -> ok;
+ {error,eexist} -> ok
+ end,
+ ?line {ok,Cwd} = file:get_cwd(),
+ ?line ok = file:set_cwd(Temp),
+ ?line <<Drive:8,":/temp/foo">> = filename:absname(<<"foo">>),
+ ?line <<Drive:8,":/temp/../ebin">> = filename:absname(<<"../ebin">>),
+ ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>),
+ ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>),
+ ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\src">>),
+ ?line <<Drive:8,":/temp/erlang">> = filename:absname(<<Drive:8,":erlang">>),
+ ?line <<Drive:8,":/temp/erlang/src">> =
+ filename:absname(<<Drive:8,":erlang/src">>),
+ ?line <<Drive:8,":/temp/erlang/src">> =
+ filename:absname(<<Drive:8,":erlang\\src\\">>),
+ ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>),
+
+ ?line file:set_cwd(<<Drive:8,":/">>),
+ ?line <<Drive:8,":/foo">> = filename:absname(<<"foo">>),
+ ?line <<Drive:8,":/../ebin">> = filename:absname(<<"../ebin">>),
+ ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>),
+ ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>),
+ ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\\\src">>),
+ ?line <<Drive:8,":/erlang">> = filename:absname(<<Drive:8,":erlang">>),
+ ?line <<Drive:8,":/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>),
+ ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>),
+
+ ?line file:set_cwd(Cwd),
+ ok;
+ {unix, _} ->
+ ?line ok = file:set_cwd(<<"/usr">>),
+ ?line <<"/usr/foo">> = filename:absname(<<"foo">>),
+ ?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>),
+
+ ?line file:set_cwd(<<"/">>),
+ ?line <<"/foo">> = filename:absname(<<"foo">>),
+ ?line <<"/../ebin">> = filename:absname(<<"../ebin">>),
+ ?line <<"/erlang">> = filename:absname(<<"/erlang">>),
+ ?line <<"/erlang/src">> = filename:absname(<<"/erlang/src">>),
+ ?line <<"/erlang/src">> = filename:absname(<<"/erlang///src">>),
+ ok
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+absname_bin_2(Config) when is_list(Config) ->
+ case os:type() of
+ {win32, _} ->
+ ?line [Drive|_] = ?config(priv_dir, Config),
+ ?line <<Drive:8,":/temp/foo">> = filename:absname(<<"foo">>, <<Drive:8,":/temp">>),
+ ?line <<Drive:8,":/temp/../ebin">> = filename:absname(<<"../ebin">>,
+ <<Drive:8,":/temp">>),
+ ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>, <<Drive:8,":/temp">>),
+ ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>,
+ <<Drive:8,":/temp">>),
+ ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\src">>,
+ <<Drive:8,":/temp">>),
+ ?line <<Drive:8,":/temp/erlang">> = filename:absname(<<Drive:8,":erlang">>,
+ <<Drive:8,":/temp">>),
+ ?line <<Drive:8,":/temp/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>,
+ <<Drive:8,":/temp">>),
+ ?line <<Drive:8,":/temp/erlang/src">> =
+ filename:absname(<<Drive:8,":erlang\\src\\">>, <<Drive:8,":/temp">>),
+ ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>, <<Drive:8,":/temp">>),
+
+ ?line file:set_cwd(<<Drive:8,":/">>),
+ ?line <<Drive:8,":/foo">> = filename:absname(foo, <<Drive:8,":/">>),
+ ?line <<Drive:8,":/foo">> = filename:absname(<<"foo">>, <<Drive:8,":/">>),
+ ?line <<Drive:8,":/../ebin">> = filename:absname(<<"../ebin">>, <<Drive:8,":/">>),
+ ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>, <<Drive:8,":/">>),
+ ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>,
+ <<Drive:8,":/">>),
+ ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\\\src">>,
+ <<Drive:8,":/">>),
+ ?line <<Drive:8,":/erlang">> = filename:absname(<<Drive:8,":erlang">>,
+ <<Drive:8,":/">>),
+ ?line <<Drive:8,":/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>,
+ <<Drive:8,":/">>),
+ ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>, <<Drive:8,":/">>),
+
+ ok;
+ {unix, _} ->
+ ?line <<"/usr/foo">> = filename:absname(<<"foo">>, <<"/usr">>),
+ ?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>, <<"/usr">>),
+
+ ?line <<"/foo">> = filename:absname(<<"foo">>, <<"/">>),
+ ?line <<"/../ebin">> = filename:absname(<<"../ebin">>, <<"/">>),
+ ?line <<"/erlang">> = filename:absname(<<"/erlang">>, <<"/">>),
+ ?line <<"/erlang/src">> = filename:absname(<<"/erlang/src">>, <<"/">>),
+ ?line <<"/erlang/src">> = filename:absname(<<"/erlang///src">>, <<"/">>),
+ ok
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+basename_bin_1(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(10)),
+ ?line <<".">> = filename:basename(<<".">>),
+ ?line <<"foo">> = filename:basename(<<"foo">>),
+ ?line <<"foo">> = filename:basename(<<"/usr/foo">>),
+ ?line <<"foo.erl">> = filename:basename(<<"A:usr/foo.erl">>),
+ ?line case os:type() of
+ {win32, _} ->
+ ?line <<"foo">> = filename:basename(<<"A:\\usr\\foo">>),
+ ?line <<"foo">> = filename:basename(<<"A:foo">>);
+ {unix, _} ->
+ ?line <<"strange\\but\\true">> =
+ filename:basename(<<"strange\\but\\true">>)
+ end,
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+basename_bin_2(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(10)),
+ ?line <<".">> = filename:basename(<<".">>, <<".erl">>),
+ ?line <<"foo">> = filename:basename(<<"foo.erl">>, <<".erl">>),
+ ?line <<"foo.erl">> = filename:basename(<<"/usr/foo.erl">>, <<".hrl">>),
+ ?line <<"foo.erl">> = filename:basename(<<"/usr.hrl/foo.erl">>, <<".hrl">>),
+ ?line <<"foo">> = filename:basename(<<"/usr.hrl/foo">>, <<".hrl">>),
+ ?line <<"foo">> = filename:basename(<<"usr/foo/">>, <<".erl">>),
+ ?line <<"foo.erl">> = filename:basename(<<"usr/foo.erl/">>, <<".erl">>),
+ ?line case os:type() of
+ {win32, _} ->
+ ?line <<"foo">> = filename:basename(<<"A:foo">>, <<".erl">>),
+ ?line <<"foo.erl">> = filename:basename(<<"a:\\usr\\foo.erl">>,
+ <<".hrl">>),
+ ?line <<"foo.erl">> = filename:basename(<<"c:\\usr.hrl\\foo.erl">>,
+ <<".hrl">>),
+ ?line <<"foo">> = filename:basename(<<"A:\\usr\\foo">>, <<".hrl">>);
+ {unix, _} ->
+ ?line <<"strange\\but\\true">> =
+ filename:basename(<<"strange\\but\\true.erl">>, <<".erl">>),
+ ?line <<"strange\\but\\true">> =
+ filename:basename(<<"strange\\but\\true">>, <<".erl">>)
+ end,
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+dirname_bin(Config) when is_list(Config) ->
+ case os:type() of
+ {win32,_} ->
+ ?line <<"A:/usr">> = filename:dirname(<<"A:/usr/foo.erl">>),
+ ?line <<"A:usr">> = filename:dirname(<<"A:usr/foo.erl">>),
+ ?line <<"/usr">> = filename:dirname(<<"\\usr\\foo.erl">>),
+ ?line <<"/">> = filename:dirname(<<"\\usr">>),
+ ?line <<"A:">> = filename:dirname(<<"A:">>);
+ vxworks ->
+ ?line <<"net:/usr">> = filename:dirname(<<"net:/usr/foo.erl">>),
+ ?line <<"/disk0:/usr">> = filename:dirname(<<"/disk0:/usr/foo.erl">>),
+ ?line <<"/usr">> = filename:dirname(<<"\\usr\\foo.erl">>),
+ ?line <<"/usr">> = filename:dirname(<<"\\usr">>),
+ ?line <<"net:">> = filename:dirname(<<"net:">>);
+ _ -> true
+ end,
+ ?line <<"usr">> = filename:dirname(<<"usr///foo.erl">>),
+ ?line <<".">> = filename:dirname(<<"foo.erl">>),
+ ?line <<".">> = filename:dirname(<<".">>),
+ case os:type() of
+ vxworks ->
+ ?line <<"/">> = filename:dirname(<<"/">>),
+ ?line <<"/usr">> = filename:dirname(<<"/usr">>);
+ _ ->
+ ?line <<"/">> = filename:dirname(<<"/">>),
+ ?line <<"/">> = filename:dirname(<<"/usr">>)
+ end,
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+extension_bin(Config) when is_list(Config) ->
+ ?line <<".erl">> = filename:extension(<<"A:/usr/foo.erl">>),
+ ?line <<".erl">> = filename:extension(<<"A:/usr/foo.nisse.erl">>),
+ ?line <<".erl">> = filename:extension(<<"A:/usr.bar/foo.nisse.erl">>),
+ ?line <<"">> = filename:extension(<<"A:/usr.bar/foo">>),
+ ?line <<"">> = filename:extension(<<"A:/usr/foo">>),
+ ?line case os:type() of
+ {win32, _} ->
+ ?line <<"">> = filename:extension(<<"A:\\usr\\foo">>),
+ ?line <<".erl">> =
+ filename:extension(<<"A:/usr.bar/foo.nisse.erl">>),
+ ?line <<"">> = filename:extension(<<"A:/usr.bar/foo">>),
+ ok;
+ vxworks ->
+ ?line <<"">> = filename:extension(<<"/disk0:\\usr\\foo">>),
+ ?line <<".erl">> =
+ filename:extension(<<"net:/usr.bar/foo.nisse.erl">>),
+ ?line <<"">> = filename:extension(<<"net:/usr.bar/foo">>),
+ ok;
+ _ -> ok
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+join_bin(Config) when is_list(Config) ->
+ ?line <<"/">> = filename:join([<<"/">>]),
+ ?line <<"/">> = filename:join([<<"//">>]),
+ ?line <<"usr/foo.erl">> = filename:join(<<"usr">>,<<"foo.erl">>),
+ ?line <<"/src/foo.erl">> = filename:join(usr, <<"/src/foo.erl">>),
+ ?line <<"/src/foo.erl">> = filename:join([<<"/src/">>,'foo.erl']),
+ ?line <<"/src/foo.erl">> = filename:join(<<"usr">>, ["/sr", 'c/foo.erl']),
+ ?line <<"/src/foo.erl">> = filename:join(<<"usr">>, <<"/src/foo.erl">>),
+
+ %% Make sure that redundant slashes work too.
+ ?line <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c/////d//e/f/g">>]),
+ ?line <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c/">>, <<"d//e/f/g">>]),
+ ?line <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"d//e/f/g">>]),
+ ?line <<"/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"/d//e/f/g">>]),
+ ?line <<"/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"//d//e/f/g">>]),
+
+ ?line <<"foo/bar">> = filename:join([$f,$o,$o,$/,[]], <<"bar">>),
+
+ ?line case os:type() of
+ {win32, _} ->
+ ?line <<"d:/">> = filename:join([<<"D:/">>]),
+ ?line <<"d:/">> = filename:join([<<"D:\\">>]),
+ ?line <<"d:/abc">> = filename:join([<<"D:/">>, <<"abc">>]),
+ ?line <<"d:abc">> = filename:join([<<"D:">>, <<"abc">>]),
+ ?line <<"a/b/c/d/e/f/g">> =
+ filename:join([<<"a//b\\c//\\/\\d/\\e/f\\g">>]),
+ ?line <<"a:usr/foo.erl">> =
+ filename:join([<<"A:">>,<<"usr">>,<<"foo.erl">>]),
+ ?line <<"/usr/foo.erl">> =
+ filename:join([<<"A:">>,<<"/usr">>,<<"foo.erl">>]),
+ ?line <<"c:usr">> = filename:join(<<"A:">>,<<"C:usr">>),
+ ?line <<"a:usr">> = filename:join(<<"A:">>,<<"usr">>),
+ ?line <<"c:/usr">> = filename:join(<<"A:">>, <<"C:/usr">>),
+ ?line <<"c:/usr/foo.erl">> =
+ filename:join([<<"A:">>,<<"C:/usr">>,<<"foo.erl">>]),
+ ?line <<"c:usr/foo.erl">> =
+ filename:join([<<"A:">>,<<"C:usr">>,<<"foo.erl">>]),
+ ?line <<"d:/foo">> = filename:join([$D, $:, $/, []], <<"foo">>),
+ ok;
+ {unix, _} ->
+ ok
+ end.
+
+pathtype_bin(Config) when is_list(Config) ->
+ ?line relative = filename:pathtype(<<"..">>),
+ ?line relative = filename:pathtype(<<"foo">>),
+ ?line relative = filename:pathtype(<<"foo/bar">>),
+ ?line relative = filename:pathtype('foo/bar'),
+ case os:type() of
+ {win32, _} ->
+ ?line volumerelative = filename:pathtype(<<"/usr/local/bin">>),
+ ?line volumerelative = filename:pathtype(<<"A:usr/local/bin">>),
+ ok;
+ {unix, _} ->
+ ?line absolute = filename:pathtype(<<"/">>),
+ ?line absolute = filename:pathtype(<<"/usr/local/bin">>),
+ ok
+ end.
+
+rootname_bin(Config) when is_list(Config) ->
+ ?line <<"/jam.src/kalle">> = filename:rootname(<<"/jam.src/kalle">>),
+ ?line <<"/jam.src/foo">> = filename:rootname(<<"/jam.src/foo.erl">>),
+ ?line <<"/jam.src/foo">> = filename:rootname(<<"/jam.src/foo.erl">>, <<".erl">>),
+ ?line <<"/jam.src/foo.jam">> = filename:rootname(<<"/jam.src/foo.jam">>, <<".erl">>),
+ ?line <<"/jam.src/foo.jam">> = filename:rootname(["/jam.sr",'c/foo.j',"am"],<<".erl">>),
+ ?line <<"/jam.src/foo.jam">> = filename:rootname(["/jam.sr",'c/foo.j'|am],<<".erl">>),
+ ok.
+
+split_bin(Config) when is_list(Config) ->
+ case os:type() of
+ vxworks ->
+ ?line [<<"/usr">>,<<"local">>,<<"bin">>] = filename:split(<<"/usr/local/bin">>);
+ _ ->
+ ?line [<<"/">>,<<"usr">>,<<"local">>,<<"bin">>] = filename:split(<<"/usr/local/bin">>)
+ end,
+ ?line [<<"foo">>,<<"bar">>]= filename:split(<<"foo/bar">>),
+ ?line [<<"foo">>, <<"bar">>, <<"hello">>]= filename:split(<<"foo////bar//hello">>),
+ case os:type() of
+ {win32,_} ->
+ ?line [<<"a:/">>,<<"msdev">>,<<"include">>] =
+ filename:split(<<"a:/msdev/include">>),
+ ?line [<<"a:/">>,<<"msdev">>,<<"include">>] =
+ filename:split(<<"A:/msdev/include">>),
+ ?line [<<"msdev">>,<<"include">>] =
+ filename:split(<<"msdev\\include">>),
+ ?line [<<"a:/">>,<<"msdev">>,<<"include">>] =
+ filename:split(<<"a:\\msdev\\include">>),
+ ?line [<<"a:">>,<<"msdev">>,<<"include">>] =
+ filename:split(<<"a:msdev\\include">>),
+ ok;
+ _ ->
+ ok
+ end.
+
diff --git a/lib/stdlib/test/fixtable_SUITE.erl b/lib/stdlib/test/fixtable_SUITE.erl
index 1940ee147e..c2160d8ba7 100644
--- a/lib/stdlib/test/fixtable_SUITE.erl
+++ b/lib/stdlib/test/fixtable_SUITE.erl
@@ -21,22 +21,41 @@
%%%----------------------------------------------------------------------
-module(fixtable_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%%% Test cases
-export([multiple_fixes/1, multiple_processes/1,
other_process_deletes/1, owner_dies/1,
other_process_closes/1,insert_same_key/1]).
-export([fixbag/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%%% Internal exports
-export([command_loop/0,start_commander/0]).
-all(suite) -> {req, [stdlib],
- [multiple_fixes, multiple_processes,
- other_process_deletes, owner_dies,
- other_process_closes,insert_same_key,fixbag]}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
--include("test_server.hrl").
+all() ->
+ [multiple_fixes, multiple_processes,
+ other_process_deletes, owner_dies, other_process_closes,
+ insert_same_key, fixbag].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+-include_lib("test_server/include/test_server.hrl").
%%% I wrote this thinking I would use more than one temporary at a time, but
%%% I wasn't... Well, maybe in the future...
@@ -53,7 +72,7 @@ init_per_testcase(_Func, Config) ->
Dog=test_server:timetrap(test_server:seconds(60)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
lists:foreach(fun(X) ->
diff --git a/lib/stdlib/test/format_SUITE.erl b/lib/stdlib/test/format_SUITE.erl
index 1c9e953003..c1a896abe8 100644
--- a/lib/stdlib/test/format_SUITE.erl
+++ b/lib/stdlib/test/format_SUITE.erl
@@ -17,13 +17,14 @@
%% %CopyrightEnd%
%%
-module(format_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([hang_1/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -31,16 +32,32 @@
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test cases for io:format/[2,3]."];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[hang_1].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
hang_1(doc) ->
["Bad args can hang (OTP-2400)"];
hang_1(suite) ->
diff --git a/lib/stdlib/test/gen_event_SUITE.erl b/lib/stdlib/test/gen_event_SUITE.erl
index 4f7de451e3..8fa2f4e3a3 100644
--- a/lib/stdlib/test/gen_event_SUITE.erl
+++ b/lib/stdlib/test/gen_event_SUITE.erl
@@ -18,16 +18,39 @@
%%
-module(gen_event_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
--export([start/1, test_all/1, add_handler/1, add_sup_handler/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([start/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,
call_format_status/1, error_format_status/1]).
-all(suite) -> {req, [stdlib], [start, test_all, hibernate,
- call_format_status, error_format_status]}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [start, {group, test_all}, hibernate,
+ call_format_status, error_format_status].
+
+groups() ->
+ [{test_all, [],
+ [add_handler, add_sup_handler, delete_handler,
+ swap_handler, swap_sup_handler, notify, sync_notify,
+ call, info]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% --------------------------------------
%% Start an event manager.
@@ -171,9 +194,6 @@ hibernate(Config) when is_list(Config) ->
ok.
-test_all(suite) -> [add_handler, add_sup_handler, delete_handler,
- swap_handler, swap_sup_handler, notify,
- sync_notify, call, info].
add_handler(doc) -> [];
add_handler(suite) -> [];
diff --git a/lib/stdlib/test/gen_fsm_SUITE.erl b/lib/stdlib/test/gen_fsm_SUITE.erl
index dd120f8c05..9d9e1f8dd8 100644
--- a/lib/stdlib/test/gen_fsm_SUITE.erl
+++ b/lib/stdlib/test/gen_fsm_SUITE.erl
@@ -18,19 +18,20 @@
%%
-module(gen_fsm_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test cases
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
--export([start/1, start1/1, start2/1, start3/1, start4/1 , start5/1, start6/1,
+-export([ start1/1, start2/1, start3/1, start4/1 , start5/1, start6/1,
start7/1, start8/1, start9/1, start10/1, start11/1]).
--export([abnormal/1, abnormal1/1, abnormal2/1]).
+-export([ abnormal1/1, abnormal2/1]).
-export([shutdown/1]).
--export([sys/1, sys1/1, call_format_status/1, error_format_status/1]).
+-export([ 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]).
@@ -53,13 +54,31 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) ->
- [start, abnormal, shutdown, sys, hibernate, enter_loop].
-
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, start}, {group, abnormal}, shutdown,
+ {group, sys}, hibernate, enter_loop].
+
+groups() ->
+ [{start, [],
+ [start1, start2, start3, start4, start5, start6, start7,
+ start8, start9, start10, start11]},
+ {abnormal, [], [abnormal1, abnormal2]},
+ {sys, [],
+ [sys1, call_format_status, error_format_status]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+init_per_group(_GroupName, Config) ->
+ Config.
-start(suite) -> [start1, start2, start3, start4, start5, start6, start7,
- start8, start9, start10, start11].
+end_per_group(_GroupName, Config) ->
+ Config.
%% anonymous
start1(Config) when is_list(Config) ->
@@ -239,7 +258,6 @@ start11(Config) when is_list(Config) ->
test_server:messages_get(),
ok.
-abnormal(suite) -> [abnormal1, abnormal2].
%% Check that time outs in calls work
abnormal1(suite) -> [];
@@ -305,7 +323,6 @@ shutdown(Config) when is_list(Config) ->
ok.
-sys(suite) -> [sys1, call_format_status, error_format_status].
sys1(Config) when is_list(Config) ->
?line {ok, Pid} =
diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl
index 99388ba2e3..5a248d7c10 100644
--- a/lib/stdlib/test/gen_server_SUITE.erl
+++ b/lib/stdlib/test/gen_server_SUITE.erl
@@ -18,12 +18,13 @@
%%
-module(gen_server_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/inet.hrl").
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([start/1, crash/1, call/1, cast/1, cast_fast/1,
info/1, abcast/1, multicall/1, multicall_down/1,
call_remote1/1, call_remote2/1, call_remote3/1,
@@ -45,23 +46,55 @@
-export([init/1, handle_call/3, handle_cast/2,
handle_info/2, terminate/2, format_status/2]).
-all(suite) ->
- [start, crash, call, cast, cast_fast, info,
- abcast, multicall, multicall_down, call_remote1,
- call_remote2, call_remote3, call_remote_n1,
- call_remote_n2, call_remote_n3, spec_init,
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [start, crash, call, cast, cast_fast, info, abcast,
+ multicall, multicall_down, call_remote1, call_remote2,
+ call_remote3, call_remote_n1, 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, error_format_status,
+ spec_init_global_registered_parent, otp_5854, hibernate,
+ otp_7669, call_format_status, error_format_status,
call_with_huge_message_queue].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
-define(default_timeout, ?t:minutes(1)).
+init_per_testcase(Case, Config) when Case == call_remote1;
+ Case == call_remote2;
+ Case == call_remote3;
+ Case == call_remote_n1;
+ Case == call_remote_n2;
+ Case == call_remote_n3 ->
+ {ok,N} = start_node(hubba),
+ ?line Dog = ?t:timetrap(?default_timeout),
+ [{node,N},{watchdog, Dog} | Config];
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
+ case proplists:get_value(node, Config) of
+ undefined ->
+ ok;
+ N ->
+ test_server:stop_node(N)
+ end,
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -294,8 +327,8 @@ start_node(Name) ->
call_remote1(suite) -> [];
call_remote1(Config) when is_list(Config) ->
- ?line N = hubba,
- ?line {ok, Node} = start_node(N),
+ N = hubba,
+ ?line Node = proplists:get_value(node,Config),
?line {ok, Pid} = rpc:call(Node, gen_server, start,
[{global, N}, ?MODULE, [], []]),
?line ok = (catch gen_server:call({global, N}, started_p, infinity)),
@@ -308,7 +341,7 @@ call_remote1(Config) when is_list(Config) ->
call_remote2(suite) -> [];
call_remote2(Config) when is_list(Config) ->
?line N = hubba,
- ?line {ok, Node} = start_node(N),
+ ?line Node = proplists:get_value(node,Config),
?line {ok, Pid} = rpc:call(Node, gen_server, start,
[{global, N}, ?MODULE, [], []]),
@@ -321,8 +354,7 @@ call_remote2(Config) when is_list(Config) ->
call_remote3(suite) -> [];
call_remote3(Config) when is_list(Config) ->
- ?line N = hubba,
- ?line {ok, Node} = start_node(N),
+ ?line Node = proplists:get_value(node,Config),
?line {ok, Pid} = rpc:call(Node, gen_server, start,
[{local, piller}, ?MODULE, [], []]),
@@ -340,7 +372,7 @@ call_remote3(Config) when is_list(Config) ->
call_remote_n1(suite) -> [];
call_remote_n1(Config) when is_list(Config) ->
?line N = hubba,
- ?line {ok, Node} = start_node(N),
+ ?line Node = proplists:get_value(node,Config),
?line {ok, _Pid} = rpc:call(Node, gen_server, start,
[{global, N}, ?MODULE, [], []]),
?line _ = test_server:stop_node(Node),
@@ -352,7 +384,7 @@ call_remote_n1(Config) when is_list(Config) ->
call_remote_n2(suite) -> [];
call_remote_n2(Config) when is_list(Config) ->
?line N = hubba,
- ?line {ok, Node} = start_node(N),
+ ?line Node = proplists:get_value(node,Config),
?line {ok, Pid} = rpc:call(Node, gen_server, start,
[{global, N}, ?MODULE, [], []]),
@@ -364,8 +396,7 @@ call_remote_n2(Config) when is_list(Config) ->
call_remote_n3(suite) -> [];
call_remote_n3(Config) when is_list(Config) ->
- ?line N = hubba,
- ?line {ok, Node} = start_node(N),
+ ?line Node = proplists:get_value(node,Config),
?line {ok, _Pid} = rpc:call(Node, gen_server, start,
[{local, piller}, ?MODULE, [], []]),
diff --git a/lib/stdlib/test/id_transform_SUITE.erl b/lib/stdlib/test/id_transform_SUITE.erl
index 95ee509833..da52f43728 100644
--- a/lib/stdlib/test/id_transform_SUITE.erl
+++ b/lib/stdlib/test/id_transform_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,17 +21,37 @@
-include_lib("kernel/include/file.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
id_transform/1]).
-export([check/2,check2/1,g/0,f/1,t/1,t1/1,t2/1,t3/1,t4/1,
t5/1,t6/1,apa/1,new_fun/0]).
-% Serves as test...
+ % Serves as test...
-hej(hopp).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [id_transform].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [id_transform].
id_transform(doc) -> "Test erl_id_trans.";
id_transform(Config) when is_list(Config) ->
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 73efeb004a..497fd3c562 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,9 +18,10 @@
%%
-module(io_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-export([error_1/1, float_g/1, otp_5403/1, otp_5813/1, otp_6230/1,
otp_6282/1, otp_6354/1, otp_6495/1, otp_6517/1, otp_6502/1,
@@ -37,7 +38,7 @@
-define(t, test_server).
-define(privdir(_), "./io_SUITE_priv").
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(format(S, A), ok).
-define(privdir(Conf), ?config(priv_dir, Conf)).
-endif.
@@ -49,17 +50,35 @@
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, _Config) ->
+end_per_testcase(_Case, _Config) ->
Dog = ?config(watchdog, _Config),
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test cases for io."];
-all(suite) ->
- [error_1,float_g,otp_5403,otp_5813,otp_6230,otp_6282,otp_6354,otp_6495,
- otp_6517,otp_6502,manpage,otp_6708,otp_7084,otp_7421,
- io_lib_collect_line_3_wb,cr_whitespace_in_string,io_fread_newlines].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [error_1, float_g, otp_5403, otp_5813, otp_6230,
+ otp_6282, otp_6354, otp_6495, otp_6517, otp_6502,
+ manpage, otp_6708, otp_7084, otp_7421,
+ io_lib_collect_line_3_wb, cr_whitespace_in_string,
+ io_fread_newlines].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
error_1(doc) ->
["Error cases for output"];
diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl
index d9672a8c7b..3474f41ee6 100644
--- a/lib/stdlib/test/io_proto_SUITE.erl
+++ b/lib/stdlib/test/io_proto_SUITE.erl
@@ -19,15 +19,19 @@
-module(io_proto_SUITE).
-compile(r12).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--export([setopts_getopts/1,unicode_options/1,unicode_options_gen/1, binary_options/1, bc_with_r12/1,
- bc_with_r12_gl/1, read_modes_gl/1,bc_with_r12_ogl/1, read_modes_ogl/1, broken_unicode/1,eof_on_pipe/1,unicode_prompt/1]).
+-export([setopts_getopts/1,unicode_options/1,unicode_options_gen/1,
+ binary_options/1, bc_with_r12/1,
+ bc_with_r12_gl/1, read_modes_gl/1,bc_with_r12_ogl/1,
+ read_modes_ogl/1, broken_unicode/1,eof_on_pipe/1,unicode_prompt/1]).
--export([io_server_proxy/1,start_io_server_proxy/0, proxy_getall/1, proxy_setnext/2, proxy_quit/1]).
+-export([io_server_proxy/1,start_io_server_proxy/0, proxy_getall/1,
+ proxy_setnext/2, proxy_quit/1]).
%% For spawn
-export([toerl_server/3,hold_the_line/3,answering_machine1/3,
answering_machine2/3]).
@@ -42,7 +46,7 @@
-define(t, test_server).
-define(privdir(_), "./io_SUITE_priv").
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(privdir(Conf), ?config(priv_dir, Conf)).
-endif.
@@ -73,19 +77,36 @@ init_per_testcase(_Case, Config) ->
end,
os:putenv("TERM","vt100"),
[{watchdog, Dog}, {term, Term} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
Term = ?config(term,Config),
os:putenv("TERM",Term),
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test cases for the io_protocol."];
-all(suite) ->
- [setopts_getopts, unicode_options, unicode_options_gen, binary_options, bc_with_r12,
- bc_with_r12_gl,bc_with_r12_ogl, read_modes_gl, read_modes_ogl,
- broken_unicode,eof_on_pipe,unicode_prompt].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [setopts_getopts, unicode_options, unicode_options_gen,
+ binary_options, bc_with_r12, bc_with_r12_gl,
+ bc_with_r12_ogl, read_modes_gl, read_modes_ogl,
+ broken_unicode, eof_on_pipe, unicode_prompt].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-record(state, {
diff --git a/lib/stdlib/test/lists_SUITE.erl b/lib/stdlib/test/lists_SUITE.erl
index 0089e874c8..1fc9de09c3 100644
--- a/lib/stdlib/test/lists_SUITE.erl
+++ b/lib/stdlib/test/lists_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,7 +21,7 @@
%%%-----------------------------------------------------------------
-module(lists_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% Default timetrap timeout (set in init_per_testcase).
@@ -30,36 +30,37 @@
-define(default_timeout, ?t:minutes(4)).
% Test server specific exports
--export([all/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
% Test cases must be exported.
-export([member/1, reverse/1,
keymember/1, keysearch_keyfind/1,
keystore/1, keytake/1,
- append/1, append_1/1, append_2/1,
- seq/1, seq_loop/1, seq_2/1, seq_3/1, seq_2_e/1, seq_3_e/1,
- sublist/1, flatten/1,
+ append_1/1, append_2/1,
+ seq_loop/1, seq_2/1, seq_3/1, seq_2_e/1, seq_3_e/1,
+
sublist_2/1, sublist_3/1, sublist_2_e/1, sublist_3_e/1,
flatten_1/1, flatten_2/1, flatten_1_e/1, flatten_2_e/1,
dropwhile/1,
- sort/1, sort_1/1, sort_stable/1, merge/1, rmerge/1, sort_rand/1,
- usort/1, usort_1/1, usort_stable/1, umerge/1, rumerge/1,usort_rand/1,
+ sort_1/1, sort_stable/1, merge/1, rmerge/1, sort_rand/1,
+ usort_1/1, usort_stable/1, umerge/1, rumerge/1,usort_rand/1,
keymerge/1, rkeymerge/1,
- keysort/1, keysort_1/1, keysort_i/1, keysort_stable/1,
+ keysort_1/1, keysort_i/1, keysort_stable/1,
keysort_rand/1, keysort_error/1,
ukeymerge/1, rukeymerge/1,
- ukeysort/1, ukeysort_1/1, ukeysort_i/1, ukeysort_stable/1,
+ ukeysort_1/1, ukeysort_i/1, ukeysort_stable/1,
ukeysort_rand/1, ukeysort_error/1,
funmerge/1, rfunmerge/1,
- funsort/1, funsort_1/1, funsort_stable/1, funsort_rand/1,
+ funsort_1/1, funsort_stable/1, funsort_rand/1,
funsort_error/1,
ufunmerge/1, rufunmerge/1,
- ufunsort/1, ufunsort_1/1, ufunsort_stable/1, ufunsort_rand/1,
+ ufunsort_1/1, ufunsort_stable/1, ufunsort_rand/1,
ufunsort_error/1,
zip_unzip/1, zip_unzip3/1, zipwith/1, zipwith3/1,
filter_partition/1,
- tickets/1, otp_5939/1, otp_6023/1, otp_6606/1, otp_7230/1,
+ otp_5939/1, otp_6023/1, otp_6606/1, otp_7230/1,
suffix/1, subtract/1]).
%% Sort randomized lists until stopped.
@@ -76,21 +77,59 @@
%%
%% all/1
%%
-all(doc) ->
- [];
-all(suite) ->
- [append, reverse, member, keymember, keysearch_keyfind, keystore, keytake,
- dropwhile,
- sort, usort, keysort, ukeysort,
- funsort, ufunsort, sublist, flatten, seq,
- zip_unzip, zip_unzip3, zipwith, zipwith3,
- filter_partition, tickets, suffix, subtract].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, append}, reverse, member, keymember,
+ keysearch_keyfind, keystore, keytake, dropwhile, {group,sort},
+ {group, usort}, {group, keysort}, {group, ukeysort},
+ {group, funsort}, {group, ufunsort}, {group, sublist},
+ {group, flatten}, {group, seq}, zip_unzip, zip_unzip3,
+ zipwith, zipwith3, filter_partition, {group, tickets},
+ suffix, subtract].
+
+groups() ->
+ [{append, [], [append_1, append_2]},
+ {usort, [],
+ [umerge, rumerge, usort_1, usort_rand, usort_stable]},
+ {keysort, [],
+ [keymerge, rkeymerge, keysort_1, keysort_rand,
+ keysort_i, keysort_stable, keysort_error]},
+ {sort,[],[merge, rmerge, sort_1, sort_rand]},
+ {ukeysort, [],
+ [ukeymerge, rukeymerge, ukeysort_1, ukeysort_rand,
+ ukeysort_i, ukeysort_stable, ukeysort_error]},
+ {funsort, [],
+ [funmerge, rfunmerge, funsort_1, funsort_stable,
+ funsort_error, funsort_rand]},
+ {ufunsort, [],
+ [ufunmerge, rufunmerge, ufunsort_1, ufunsort_stable,
+ ufunsort_error, ufunsort_rand]},
+ {seq, [], [seq_loop, seq_2, seq_3, seq_2_e, seq_3_e]},
+ {sublist, [],
+ [sublist_2, sublist_3, sublist_2_e, sublist_3_e]},
+ {flatten, [],
+ [flatten_1, flatten_2, flatten_1_e, flatten_2_e]},
+ {tickets, [], [otp_5939, otp_6023, otp_6606, otp_7230]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -98,10 +137,6 @@ fin_per_testcase(_Case, Config) ->
%
% Test cases starts here.
%
-append(doc) ->
- ["Tests lists:append/1 & lists:append/2"];
-append(suite) ->
- [append_1, append_2].
append_1(doc) -> [];
append_1(suite) -> [];
@@ -346,12 +381,6 @@ keytake(Config) when is_list(Config) ->
?line false = lists:keytake(4, 2, L),
ok.
-sort(doc) ->
- ["Tests merge functions and lists:sort/1"];
-sort(suite) ->
- %% [merge, rmerge, sort_1, sort_rand, sort_stable].
- [merge, rmerge, sort_1, sort_rand].
-
merge(doc) -> ["merge functions"];
merge(suite) -> [];
merge(Config) when is_list(Config) ->
@@ -536,10 +565,6 @@ expl_pid([{I,F} | T], L) when is_function(F) ->
expl_pid([], L) ->
L.
-usort(doc) ->
- ["Tests unique merge functions and lists:usort/1"];
-usort(suite) ->
- [umerge, rumerge, usort_1, usort_rand, usort_stable].
usort_1(suite) -> [];
usort_1(doc) -> [""];
@@ -750,11 +775,6 @@ ucheck_stability(L) ->
U = lists:usort(L),
check_stab(L, U, S, "usort/1", "ukeysort/2").
-keysort(doc) ->
- ["Tests lists:keysort/2"];
-keysort(suite) ->
- [keymerge, rkeymerge,
- keysort_1, keysort_rand, keysort_i, keysort_stable, keysort_error].
keymerge(doc) -> ["Key merge two lists."];
keymerge(suite) -> [];
@@ -946,11 +966,6 @@ keycompare(I, J, A, B) when element(I, A) == element(I, B),
element(J, A) =< element(J, B) ->
ok.
-ukeysort(doc) ->
- ["Tests lists:ukeysort/2"];
-ukeysort(suite) ->
- [ukeymerge, rukeymerge,
- ukeysort_1, ukeysort_rand, ukeysort_i, ukeysort_stable, ukeysort_error].
ukeymerge(suite) -> [];
ukeymerge(doc) -> ["Merge two lists while removing duplicates."];
@@ -1240,11 +1255,6 @@ ukeycompare(I, J, A, B) when A =/= B,
ok.
-funsort(doc) ->
- ["Tests lists:sort/2"];
-funsort(suite) ->
- [funmerge, rfunmerge,
- funsort_1, funsort_stable, funsort_error, funsort_rand].
funmerge(doc) -> ["Merge two lists using a fun."];
funmerge(suite) -> [];
@@ -1377,11 +1387,6 @@ funsort_check(I, Input, Expected) ->
?line Expected = funsort(I, Input),
check_sorted(I, Input, Expected).
-ufunsort(doc) ->
- ["Tests lists:usort/2"];
-ufunsort(suite) ->
- [ufunmerge, rufunmerge,
- ufunsort_1, ufunsort_stable, ufunsort_error, ufunsort_rand].
ufunmerge(suite) -> [];
ufunmerge(doc) -> ["Merge two lists while removing duplicates using a fun."];
@@ -2076,12 +2081,6 @@ rkeymerge2_2(_I, T1, _E1, [], M, H1) ->
%%%------------------------------------------------------------
-seq(doc) ->
- ["Tests lists:seq/3"];
-seq(suite) ->
- [
- seq_loop,
- seq_2, seq_3, seq_2_e, seq_3_e].
seq_loop(doc) ->
["Test for infinite loop (OTP-2404)."];
@@ -2229,10 +2228,6 @@ property(From, To, Step) ->
%%%------------------------------------------------------------
-sublist(doc) ->
- ["Tests lists:sublist/[2,3]"];
-sublist(suite) ->
- [sublist_2, sublist_3, sublist_2_e, sublist_3_e].
-define(sublist_error2(X,Y), ?line {'EXIT', _} = (catch lists:sublist(X,Y))).
-define(sublist_error3(X,Y,Z), ?line {'EXIT', _} = (catch lists:sublist(X,Y,Z))).
@@ -2326,10 +2321,6 @@ sublist_3_e(Config) when is_list(Config) ->
%%%------------------------------------------------------------
-flatten(doc) ->
- ["Tests lists:flatten/[1,2]"];
-flatten(suite) ->
- [flatten_1, flatten_2, flatten_1_e, flatten_2_e].
-define(flatten_error1(X), ?line {'EXIT', _} = (catch lists:flatten(X))).
-define(flatten_error2(X,Y), ?line {'EXIT', _} = (catch lists:flatten(X,Y))).
@@ -2489,10 +2480,6 @@ filpart(F, All, Exp) ->
Other = lists:filter(fun(E) -> not F(E) end, All),
{Exp,Other} = lists:partition(F, All).
-tickets(doc) ->
- ["Ticktes."];
-tickets(suite) ->
- [otp_5939, otp_6023, otp_6606, otp_7230].
otp_5939(doc) -> ["OTP-5939. Guard tests added."];
otp_5939(suite) -> [];
diff --git a/lib/stdlib/test/log_mf_h_SUITE.erl b/lib/stdlib/test/log_mf_h_SUITE.erl
index 640261f665..688be31e64 100644
--- a/lib/stdlib/test/log_mf_h_SUITE.erl
+++ b/lib/stdlib/test/log_mf_h_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -18,12 +18,32 @@
%%
-module(log_mf_h_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
--export([all/1, test/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, test/1]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [test].
%%-----------------------------------------------------------------
diff --git a/lib/stdlib/test/ms_transform_SUITE.erl b/lib/stdlib/test/ms_transform_SUITE.erl
index 2d90d5b823..f747d09f3c 100644
--- a/lib/stdlib/test/ms_transform_SUITE.erl
+++ b/lib/stdlib/test/ms_transform_SUITE.erl
@@ -19,9 +19,10 @@
-module(ms_transform_SUITE).
-author('[email protected]').
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([basic_ets/1]).
-export([basic_dbg/1]).
-export([from_shell/1]).
@@ -38,21 +39,40 @@
-export([float_1_function/1]).
-export([action_function/1]).
-export([warnings/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
init_per_testcase(_Func, Config) ->
Dog=test_server:timetrap(test_server:seconds(360)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func, Config) ->
+end_per_testcase(_Func, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
-all(suite) -> [from_shell,basic_ets,basic_dbg,records,record_index,multipass,
- bitsyntax, record_defaults, andalso_orelse,
- float_1_function, action_function,
- warnings,
- top_match, old_guards, autoimported, semicolon].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [from_shell, basic_ets, basic_dbg, records,
+ record_index, multipass, bitsyntax, record_defaults,
+ andalso_orelse, float_1_function, action_function,
+ warnings, top_match, old_guards, autoimported,
+ semicolon].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% This may be subject to change
-define(WARN_NUMBER_SHADOW,50).
diff --git a/lib/stdlib/test/naughty_child.erl b/lib/stdlib/test/naughty_child.erl
index b56130929c..b939436bfc 100644
--- a/lib/stdlib/test/naughty_child.erl
+++ b/lib/stdlib/test/naughty_child.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/stdlib/test/proc_lib_SUITE.erl b/lib/stdlib/test/proc_lib_SUITE.erl
index 2fd7725335..25a385950e 100644
--- a/lib/stdlib/test/proc_lib_SUITE.erl
+++ b/lib/stdlib/test/proc_lib_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,10 +23,12 @@
%%
%%-define(STANDALONE,1).
--export([all/1, crash/1, sync_start/1, sync_start_nolink/1, sync_start_link/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ crash/1, sync_start_nolink/1, sync_start_link/1,
spawn_opt/1, sp1/0, sp2/0, sp3/1, sp4/2, sp5/1,
hibernate/1]).
--export([tickets/1, otp_6345/1]).
+-export([ otp_6345/1]).
-export([hib_loop/1, awaken/1]).
@@ -40,12 +42,32 @@
-ifdef(STANDALONE).
-define(line, noop, ).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-endif.
-all(suite) -> [crash, sync_start, spawn_opt, hibernate, tickets].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [crash, {group, sync_start}, spawn_opt, hibernate,
+ {group, tickets}].
+
+groups() ->
+ [{tickets, [], [otp_6345]},
+ {sync_start, [], [sync_start_nolink, sync_start_link]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-tickets(suite) -> [otp_6345].
%%-----------------------------------------------------------------
%% We don't have to test that spwn and spawn_link actually spawns
@@ -127,7 +149,6 @@ crash(Config) when is_list(Config) ->
ok
end.
-sync_start(suite) -> [sync_start_nolink, sync_start_link].
sync_start_nolink(Config) when is_list(Config) ->
_Pid = spawn_link(?MODULE, sp5, [self()]),
diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl
index e21de8770a..05d8c5f8e3 100644
--- a/lib/stdlib/test/qlc_SUITE.erl
+++ b/lib/stdlib/test/qlc_SUITE.erl
@@ -43,7 +43,7 @@
-define(testcase, current_testcase). % don't know
-define(t, test_server).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(datadir, ?config(data_dir, Config)).
-define(privdir, ?config(priv_dir, Config)).
-define(testcase, ?config(?TESTCASE, Config)).
@@ -51,36 +51,33 @@
-include_lib("stdlib/include/ms_transform.hrl").
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
--export([parse_transform/1,
- badarg/1, nested_qlc/1, unused_var/1, lc/1, fun_clauses/1,
- filter_var/1, single/1, exported_var/1, generator_vars/1,
- nomatch/1, errors/1, pattern/1,
+-export([
+ badarg/1, nested_qlc/1, unused_var/1, lc/1, fun_clauses/1,
+ filter_var/1, single/1, exported_var/1, generator_vars/1,
+ nomatch/1, errors/1, pattern/1,
- evaluation/1,
- eval/1, cursor/1, fold/1, eval_unique/1, eval_cache/1, append/1,
- evaluator/1, string_to_handle/1, table/1, process_dies/1,
- sort/1, keysort/1, filesort/1, cache/1, cache_list/1, filter/1,
- info/1, nested_info/1, lookup1/1, lookup2/1, lookup_rec/1,
- indices/1, pre_fun/1, skip_filters/1,
+ eval/1, cursor/1, fold/1, eval_unique/1, eval_cache/1, append/1,
+ evaluator/1, string_to_handle/1, table/1, process_dies/1,
+ sort/1, keysort/1, filesort/1, cache/1, cache_list/1, filter/1,
+ info/1, nested_info/1, lookup1/1, lookup2/1, lookup_rec/1,
+ indices/1, pre_fun/1, skip_filters/1,
- table_impls/1,
- ets/1, dets/1,
+ ets/1, dets/1,
- join/1,
- join_option/1, join_filter/1, join_lookup/1, join_merge/1,
- join_sort/1, join_complex/1,
+ join_option/1, join_filter/1, join_lookup/1, join_merge/1,
+ join_sort/1, join_complex/1,
- tickets/1,
- otp_5644/1, otp_5195/1, otp_6038_bug/1, otp_6359/1, otp_6562/1,
- otp_6590/1, otp_6673/1, otp_6964/1, otp_7114/1, otp_7238/1,
- otp_7232/1, otp_7552/1, otp_6674/1, otp_7714/1,
+ otp_5644/1, otp_5195/1, otp_6038_bug/1, otp_6359/1, otp_6562/1,
+ otp_6590/1, otp_6673/1, otp_6964/1, otp_7114/1, otp_7238/1,
+ otp_7232/1, otp_7552/1, otp_6674/1, otp_7714/1,
- manpage/1,
+ manpage/1,
- compat/1,
- backward/1, forward/1]).
+ backward/1, forward/1]).
%% Internal exports.
-export([bad_table_throw/1, bad_table_exit/1, default_table/1, bad_table/1,
@@ -114,17 +111,50 @@ init_per_testcase(Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{?TESTCASE, Case}, {watchdog, Dog} | Config].
-fin_per_testcase(_Case, _Config) ->
+end_per_testcase(_Case, _Config) ->
Dog = ?config(watchdog, _Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [parse_transform, evaluation, table_impls, join, tickets, manpage, compat].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, parse_transform}, {group, evaluation},
+ {group, table_impls}, {group, join}, {group, tickets},
+ manpage, {group, compat}].
+
+groups() ->
+ [{parse_transform, [],
+ [badarg, nested_qlc, unused_var, lc, fun_clauses,
+ filter_var, single, exported_var, generator_vars,
+ nomatch, errors, pattern]},
+ {evaluation, [],
+ [eval, cursor, fold, eval_unique, eval_cache, append,
+ evaluator, string_to_handle, table, process_dies, sort,
+ keysort, filesort, cache, cache_list, filter, info,
+ nested_info, lookup1, lookup2, lookup_rec, indices,
+ pre_fun, skip_filters]},
+ {table_impls, [], [ets, dets]},
+ {join, [],
+ [join_option, join_filter, join_lookup, join_merge,
+ join_sort, join_complex]},
+ {tickets, [],
+ [otp_5644, otp_5195, otp_6038_bug, otp_6359, otp_6562,
+ otp_6590, otp_6673, otp_6964, otp_7114, otp_7232,
+ otp_7238, otp_7552, otp_6674, otp_7714]},
+ {compat, [], [backward, forward]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
-parse_transform(suite) ->
- [badarg, nested_qlc, unused_var, lc, fun_clauses, filter_var,
- single, exported_var, generator_vars, nomatch, errors, pattern].
+end_per_group(_GroupName, Config) ->
+ Config.
badarg(doc) ->
"Badarg.";
@@ -461,11 +491,6 @@ pattern(Config) when is_list(Config) ->
-record(k, {t,v}).\n">>, Ts),
ok.
-evaluation(suite) ->
- [eval, cursor, fold, eval_unique, eval_cache, append, evaluator,
- string_to_handle, table, process_dies, sort, keysort, filesort, cache,
- cache_list, filter, info, nested_info, lookup1, lookup2, lookup_rec,
- indices, pre_fun, skip_filters].
eval(doc) ->
"eval/2";
@@ -4297,8 +4322,6 @@ skip_filters(Config) when is_list(Config) ->
ok.
-table_impls(suite) ->
- [ets, dets].
ets(doc) ->
"ets:table/1,2.";
@@ -4445,9 +4468,6 @@ dets(Config) when is_list(Config) ->
_ = file:delete(Fname),
ok.
-join(suite) ->
- [join_option, join_filter, join_lookup, join_merge,
- join_sort, join_complex].
join_option(doc) ->
"The 'join' option (any, lookup, merge, nested_loop). Also cache/unique.";
@@ -5729,10 +5749,6 @@ join_complex(Config) when is_list(Config) ->
ok.
-tickets(suite) ->
- [otp_5644, otp_5195, otp_6038_bug, otp_6359, otp_6562, otp_6590,
- otp_6673, otp_6964, otp_7114, otp_7232, otp_7238, otp_7552, otp_6674,
- otp_7714].
otp_5644(doc) ->
"OTP-5644. Handle the new language element M:F/A.";
@@ -7378,8 +7394,6 @@ gb_iter(I0, N, EFun) ->
end.
">>.
-compat(suite) ->
- [backward, forward].
backward(doc) ->
"OTP-6674. Join info and extra constants.";
diff --git a/lib/stdlib/test/queue_SUITE.erl b/lib/stdlib/test/queue_SUITE.erl
index 2cd6b52311..4095b62643 100644
--- a/lib/stdlib/test/queue_SUITE.erl
+++ b/lib/stdlib/test/queue_SUITE.erl
@@ -17,13 +17,14 @@
%% %CopyrightEnd%
%%
-module(queue_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([do/1, to_list/1, io_test/1, op_test/1, error/1, oops/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -31,16 +32,32 @@
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test cases for queue."];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[do, to_list, io_test, op_test, error, oops].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
do(doc) ->
[""];
do(suite) ->
diff --git a/lib/stdlib/test/random_SUITE.erl b/lib/stdlib/test/random_SUITE.erl
index 8f1c304705..6164301e38 100644
--- a/lib/stdlib/test/random_SUITE.erl
+++ b/lib/stdlib/test/random_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -17,13 +17,14 @@
%% %CopyrightEnd%
-module(random_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([interval_1/1, seed0/1, seed/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
@@ -31,16 +32,32 @@
init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
[{watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test cases for random."];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[interval_1, seed0, seed].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
seed0(doc) ->
["Test that seed is set implicitly, and always the same."];
seed0(suite) ->
diff --git a/lib/stdlib/test/random_iolist.erl b/lib/stdlib/test/random_iolist.erl
index 4bce347d9a..8f21b5a3b3 100644
--- a/lib/stdlib/test/random_iolist.erl
+++ b/lib/stdlib/test/random_iolist.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/stdlib/test/random_unicode_list.erl b/lib/stdlib/test/random_unicode_list.erl
index 3e83383b08..b8bd719b89 100644
--- a/lib/stdlib/test/random_unicode_list.erl
+++ b/lib/stdlib/test/random_unicode_list.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl
index 46a84d4e24..b82835854e 100644
--- a/lib/stdlib/test/re_SUITE.erl
+++ b/lib/stdlib/test/re_SUITE.erl
@@ -18,12 +18,41 @@
%%
-module(re_SUITE).
--export([all/1, pcre/1,compile_options/1,run_options/1,combined_options/1,replace_autogen/1,global_capture/1,replace_input_types/1,replace_return/1,split_autogen/1,split_options/1,split_specials/1,error_handling/1,pcre_cve_2008_2371/1,pcre_compile_workspace_overflow/1,re_infinite_loop/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, pcre/1,compile_options/1,
+ run_options/1,combined_options/1,replace_autogen/1,
+ global_capture/1,replace_input_types/1,replace_return/1,
+ split_autogen/1,split_options/1,split_specials/1,
+ error_handling/1,pcre_cve_2008_2371/1,
+ pcre_compile_workspace_overflow/1,re_infinite_loop/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
-all(suite) -> [pcre,compile_options,run_options,combined_options,replace_autogen,global_capture,replace_input_types,replace_return,split_autogen,split_options,split_specials,error_handling,pcre_cve_2008_2371,pcre_compile_workspace_overflow,re_infinite_loop].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [pcre, compile_options, run_options, combined_options,
+ replace_autogen, global_capture, replace_input_types,
+ replace_return, split_autogen, split_options,
+ split_specials, error_handling, pcre_cve_2008_2371,
+ pcre_compile_workspace_overflow, re_infinite_loop].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
pcre(doc) ->
["Run all applicable tests from the PCRE testsuites."];
diff --git a/lib/stdlib/test/select_SUITE.erl b/lib/stdlib/test/select_SUITE.erl
index 6900f1a8f5..af67b798b0 100644
--- a/lib/stdlib/test/select_SUITE.erl
+++ b/lib/stdlib/test/select_SUITE.erl
@@ -37,7 +37,7 @@
-export([config/2]).
-define(fmt(A,B),io:format(A,B)).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(fmt(A,B),test_server:format(A,B)).
-endif.
@@ -58,23 +58,41 @@ config(priv_dir,_) ->
".".
-else.
%% When run in test server.
--export([all/1,select_test/1,init_per_testcase/2, fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,select_test/1,
+ init_per_testcase/2, end_per_testcase/2,
return_values/1]).
init_per_testcase(_Case, Config) when is_list(Config) ->
?line Dog=test_server:timetrap(test_server:seconds(1200)),
[{watchdog, Dog}|Config].
-
-fin_per_testcase(_Case, Config) ->
+
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test ets:select"];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[return_values, select_test].
-
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
select_test(suite) ->
[];
select_test(doc) ->
diff --git a/lib/stdlib/test/sets_SUITE.erl b/lib/stdlib/test/sets_SUITE.erl
index c9f1a03598..bce23c7b12 100644
--- a/lib/stdlib/test/sets_SUITE.erl
+++ b/lib/stdlib/test/sets_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,13 +22,15 @@
-module(sets_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2,
create/1,add_element/1,del_element/1,
subtract/1,intersection/1,union/1,is_subset/1,
is_set/1,fold/1,filter/1,
take_smallest/1,take_largest/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-import(lists, [foldl/3,reverse/1]).
@@ -36,15 +38,33 @@ init_per_testcase(_Case, Config) ->
?line Dog = ?t:timetrap(?t:minutes(5)),
[{watchdog,Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
- [create,add_element,del_element,subtract,
- intersection,union,is_subset,is_set,fold,filter,
- take_smallest,take_largest].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [create, add_element, del_element, subtract,
+ intersection, union, is_subset, is_set, fold, filter,
+ take_smallest, take_largest].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
create(Config) when is_list(Config) ->
test_all(fun create_1/1).
diff --git a/lib/stdlib/test/sets_test_lib.erl b/lib/stdlib/test/sets_test_lib.erl
index 6b6fb00550..bdfb0d59d2 100644
--- a/lib/stdlib/test/sets_test_lib.erl
+++ b/lib/stdlib/test/sets_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-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
diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl
index 588342d46a..4f8c9dffd3 100644
--- a/lib/stdlib/test/shell_SUITE.erl
+++ b/lib/stdlib/test/shell_SUITE.erl
@@ -17,21 +17,22 @@
%% %CopyrightEnd%
%%
-module(shell_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
-export([forget/1, records/1, known_bugs/1, otp_5226/1, otp_5327/1,
- otp_5435/1, otp_5195/1, otp_5915/1, otp_5916/1,
- bits/1, bs_match_misc_SUITE/1, bs_match_int_SUITE/1,
- bs_match_tail_SUITE/1, bs_match_bin_SUITE/1,
- bs_construct_SUITE/1,
- refman/1, refman_bit_syntax/1,
- progex/1, progex_bit_syntax/1, progex_records/1,
- progex_lc/1, progex_funs/1,
- tickets/1, otp_5990/1, otp_6166/1, otp_6554/1, otp_6785/1,
- otp_7184/1, otp_7232/1, otp_8393/1]).
-
--export([restricted/1, start_restricted_from_shell/1,
- start_restricted_on_command_line/1,restricted_local/1]).
+ otp_5435/1, otp_5195/1, otp_5915/1, otp_5916/1,
+ bs_match_misc_SUITE/1, bs_match_int_SUITE/1,
+ bs_match_tail_SUITE/1, bs_match_bin_SUITE/1,
+ bs_construct_SUITE/1,
+ refman_bit_syntax/1,
+ progex_bit_syntax/1, progex_records/1,
+ progex_lc/1, progex_funs/1,
+ otp_5990/1, otp_6166/1, otp_6554/1, otp_6785/1,
+ otp_7184/1, otp_7232/1, otp_8393/1]).
+
+-export([ start_restricted_from_shell/1,
+ start_restricted_on_command_line/1,restricted_local/1]).
%% Internal export.
-export([otp_5435_2/0, prompt1/1, prompt2/1, prompt3/1, prompt4/1,
@@ -50,8 +51,8 @@
config(priv_dir,_) ->
".".
-else.
--include("test_server.hrl").
--export([init_per_testcase/2, fin_per_testcase/2]).
+-include_lib("test_server/include/test_server.hrl").
+-export([init_per_testcase/2, end_per_testcase/2]).
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(2)).
init_per_testcase(_Case, Config) ->
@@ -60,7 +61,7 @@ init_per_testcase(_Case, Config) ->
?line code:add_patha(?config(priv_dir,Config)),
[{orig_path,OrigPath}, {watchdog, Dog} | Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
?line Dog = ?config(watchdog, Config),
?line test_server:timetrap_cancel(Dog),
?line OrigPath = ?config(orig_path,Config),
@@ -71,18 +72,44 @@ fin_per_testcase(_Case, Config) ->
ok.
-endif.
-all(doc) ->
- ["Test cases for the 'shell' module."];
-all(suite) ->
- [forget, records, known_bugs, otp_5226, otp_5327, otp_5435, otp_5195,
- otp_5915, otp_5916, bits, refman, progex, tickets, restricted].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [forget, records, known_bugs, otp_5226, otp_5327,
+ otp_5435, otp_5195, otp_5915, otp_5916, {group, bits},
+ {group, refman}, {group, progex}, {group, tickets},
+ {group, restricted}].
+
+groups() ->
+ [{restricted, [],
+ [start_restricted_from_shell,
+ start_restricted_on_command_line, restricted_local]},
+ {bits, [],
+ [bs_match_misc_SUITE, bs_match_tail_SUITE,
+ bs_match_bin_SUITE, bs_construct_SUITE]},
+ {refman, [], [refman_bit_syntax]},
+ {progex, [],
+ [progex_bit_syntax, progex_records, progex_lc,
+ progex_funs]},
+ {tickets, [],
+ [otp_5990, otp_6166, otp_6554, otp_6785, otp_7184,
+ otp_7232, otp_8393]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
-record(state, {bin, reply, leader}).
-restricted(doc) ->
- ["Test restricted_shell"];
-restricted(suite) ->
- [start_restricted_from_shell,start_restricted_on_command_line,restricted_local].
start_restricted_from_shell(doc) ->
["Test that a restricted shell can be started from the normal shell"];
@@ -797,9 +824,6 @@ otp_5916(Config) when is_list(Config) ->
[ok] = scan(C),
ok.
-bits(suite) ->
- [bs_match_misc_SUITE, % bs_match_int_SUITE/,
- bs_match_tail_SUITE, bs_match_bin_SUITE, bs_construct_SUITE].
bs_match_misc_SUITE(doc) ->
["OTP-5327. Adopted from parts of emulator/test/bs_match_misc_SUITE.erl."];
@@ -1520,8 +1544,6 @@ evaluate(Str, Vars) ->
Result
end.
-refman(suite) ->
- [refman_bit_syntax].
refman_bit_syntax(doc) ->
["Bit syntax examples from the Reference Manual. OTP-5237."];
@@ -1564,8 +1586,6 @@ refman_bit_syntax(Config) when is_list(Config) ->
?line <<2,4,6>> = << << (X*2) >> || <<X>> <= << 1,2,3 >> >>,
ok.
-progex(suite) ->
- [progex_bit_syntax, progex_records, progex_lc, progex_funs].
-define(IP_VERSION, 4).
-define(IP_MIN_HDR_LEN, 5).
@@ -2256,8 +2276,6 @@ progex_funs(Config) when is_list(Config) ->
?line [ok] = scan(Test2_shell),
ok.
-tickets(suite) ->
- [otp_5990, otp_6166, otp_6554, otp_6785, otp_7184, otp_7232, otp_8393].
otp_5990(doc) ->
"OTP-5990. {erlang,is_record}.";
diff --git a/lib/stdlib/test/slave_SUITE.erl b/lib/stdlib/test/slave_SUITE.erl
index 5c1282fe9b..12325dcca9 100644
--- a/lib/stdlib/test/slave_SUITE.erl
+++ b/lib/stdlib/test/slave_SUITE.erl
@@ -18,18 +18,37 @@
%%
-module(slave_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1, t_start/1, t_start_link/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, t_start/1, t_start_link/1,
start_link_nodedown/1, errors/1]).
%% Internal exports.
-export([fun_init/1, test_errors/1]).
-export([timeout_test/1, auth_test/1, rsh_test/1, start_a_slave/3]).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[t_start_link, start_link_nodedown, t_start, errors].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
t_start_link(suite) -> [];
t_start_link(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(20)),
diff --git a/lib/stdlib/test/sofs_SUITE.erl b/lib/stdlib/test/sofs_SUITE.erl
index d60cfc6895..e1eaf7f8ec 100644
--- a/lib/stdlib/test/sofs_SUITE.erl
+++ b/lib/stdlib/test/sofs_SUITE.erl
@@ -26,13 +26,14 @@
-define(config(X,Y), foo).
-define(t, test_server).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(format(S, A), ok).
-endif.
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
--export([sofs/1, from_term_1/1, set_1/1, from_sets_1/1, relation_1/1,
+-export([ from_term_1/1, set_1/1, from_sets_1/1, relation_1/1,
a_function_1/1, family_1/1, projection/1,
relation_to_family_1/1, domain_1/1, range_1/1, image/1,
inverse_image/1, inverse_1/1, converse_1/1, no_elements_1/1,
@@ -47,7 +48,7 @@
multiple_relative_product/1, digraph/1, constant_function/1,
misc/1]).
--export([sofs_family/1, family_specification/1,
+-export([ family_specification/1,
family_domain_1/1, family_range_1/1,
family_to_relation_1/1,
union_of_family_1/1, intersection_of_family_1/1,
@@ -81,18 +82,56 @@
union/1, union/2, family_to_digraph/1, family_to_digraph/2,
digraph_to_family/1, digraph_to_family/2]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
-compile({inline,[{eval,2}]}).
-all(suite) ->
- [sofs, sofs_family].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, sofs}, {group, sofs_family}].
+
+groups() ->
+ [{sofs, [],
+ [from_term_1, set_1, from_sets_1, relation_1,
+ a_function_1, family_1, relation_to_family_1, domain_1,
+ range_1, image, inverse_image, inverse_1, converse_1,
+ no_elements_1, substitution, restriction, drestriction,
+ projection, strict_relation_1, extension,
+ weak_relation_1, to_sets_1, specification, union_1,
+ intersection_1, difference, symdiff,
+ symmetric_partition, is_sofs_set_1, is_set_1, is_equal,
+ is_subset, is_a_function_1, is_disjoint, join,
+ canonical, composite_1, relative_product_1,
+ relative_product_2, product_1, partition_1, partition_3,
+ multiple_relative_product, digraph, constant_function,
+ misc]},
+ {sofs_family, [],
+ [family_specification, family_domain_1, family_range_1,
+ family_to_relation_1, union_of_family_1,
+ intersection_of_family_1, family_projection,
+ family_difference, family_intersection_1,
+ family_intersection_2, family_union_1, family_union_2,
+ partition_family]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
Dog=?t:timetrap(?t:minutes(2)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -100,18 +139,6 @@ fin_per_testcase(_Case, Config) ->
%% [{2,b},{1,a,b}] == lists:sort([{2,b},{1,a,b}])
%% [{1,a,b},{2,b}] == lists:keysort(1,[{2,b},{1,a,b}])
-sofs(suite) ->
- [from_term_1, set_1, from_sets_1, relation_1, a_function_1,
- family_1, relation_to_family_1, domain_1, range_1, image,
- inverse_image, inverse_1, converse_1, no_elements_1,
- substitution, restriction, drestriction, projection,
- strict_relation_1, extension, weak_relation_1, to_sets_1,
- specification, union_1, intersection_1, difference, symdiff,
- symmetric_partition, is_sofs_set_1, is_set_1, is_equal,
- is_subset, is_a_function_1, is_disjoint, join, canonical,
- composite_1, relative_product_1, relative_product_2, product_1,
- partition_1, partition_3, multiple_relative_product, digraph,
- constant_function, misc].
from_term_1(suite) -> [];
from_term_1(doc) -> [""];
@@ -1934,12 +1961,6 @@ relational_restriction(R) ->
Fun = fun(S) -> no_elements(S) > 1 end,
family_to_relation(family_specification(Fun, relation_to_family(R))).
-sofs_family(suite) ->
- [family_specification, family_domain_1, family_range_1,
- family_to_relation_1, union_of_family_1, intersection_of_family_1,
- family_projection, family_difference,
- family_intersection_1, family_intersection_2,
- family_union_1, family_union_2, partition_family].
family_specification(suite) -> [];
family_specification(doc) -> [""];
diff --git a/lib/stdlib/test/stdlib.cover b/lib/stdlib/test/stdlib.cover
index b98d949889..61f4f064b9 100644
--- a/lib/stdlib/test/stdlib.cover
+++ b/lib/stdlib/test/stdlib.cover
@@ -1,10 +1,17 @@
%% -*- erlang -*-
-{exclude,
- [erl_parse,
- ets,
- filename,
- gen_event,
- gen_server,
- gen,
- lists,
- proc_lib]}.
+{incl_app,stdlib,details}.
+
+{excl_mods,stdlib,
+ [erl_parse,
+ erl_eval,
+ ets,
+ filename,
+ gen_event,
+ gen_server,
+ gen,
+ lists,
+ io,
+ io_lib,
+ io_lib_format,
+ io_lib_pretty,
+ proc_lib]}.
diff --git a/lib/stdlib/test/stdlib.spec b/lib/stdlib/test/stdlib.spec
index bbfb43bd15..3768e494b2 100644
--- a/lib/stdlib/test/stdlib.spec
+++ b/lib/stdlib/test/stdlib.spec
@@ -1,4 +1 @@
-{topcase, {dir, "../stdlib_test"}}.
-%{skip,{dets_SUITE,open_file_1,"Crashes Windows tests"}}.
-%{skip,{dets_SUITE,fold,"Crashes Windows tests"}}.
-%{skip,{dets_SUITE,match,"Crashes Windows tests"}}.
+{suites,"../stdlib_test",all}.
diff --git a/lib/stdlib/test/stdlib_SUITE.erl b/lib/stdlib/test/stdlib_SUITE.erl
index d46a2caf90..0cca030b3d 100644
--- a/lib/stdlib/test/stdlib_SUITE.erl
+++ b/lib/stdlib/test/stdlib_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,7 +20,7 @@
%%% Purpose:Stdlib application test suite.
%%%-----------------------------------------------------------------
-module(stdlib_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% Default timetrap timeout (set in init_per_testcase).
@@ -28,8 +28,9 @@
-define(application, stdlib).
% Test server specific exports
--export([all/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
% Test cases must be exported.
-export([app_test/1]).
@@ -38,15 +39,31 @@
%%
%% all/1
%%
-all(doc) ->
- [];
-all(suite) ->
- [?cases].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [app_test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -58,7 +75,7 @@ app_test(suite) ->
[];
app_test(doc) ->
["Application consistency test."];
-app_test(Config) when list(Config) ->
+app_test(Config) when is_list(Config) ->
?t:app_test(stdlib),
ok.
diff --git a/lib/stdlib/test/string_SUITE.erl b/lib/stdlib/test/string_SUITE.erl
index 3171b87c44..7e52441a67 100644
--- a/lib/stdlib/test/string_SUITE.erl
+++ b/lib/stdlib/test/string_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,15 +20,16 @@
%%% Purpose: string test suite.
%%%-----------------------------------------------------------------
-module(string_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
% Test server specific exports
--export([all/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
% Test cases must be exported.
-export([len/1,equal/1,concat/1,chr_rchr/1,str_rstr/1]).
@@ -40,19 +41,34 @@
%%
%% all/1
%%
-all(doc) ->
- [];
-all(suite) ->
- [len,equal,concat,chr_rchr,str_rstr,
- span_cspan,substr,tokens,chars,
- copies,words,strip,sub_word,left_right,
- sub_string,centre, join,
- to_integer,to_float,to_upper_to_lower].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [len, equal, concat, chr_rchr, str_rstr, span_cspan,
+ substr, tokens, chars, copies, words, strip, sub_word,
+ left_right, sub_string, centre, join, to_integer,
+ to_float, to_upper_to_lower].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -240,7 +256,8 @@ copies(Config) when is_list(Config) ->
?line "." = string:copies(".", 1),
?line 30 = length(string:copies("123", 10)),
%% invalid arg type
- ?line {'EXIT',_} = (catch string:chars("hej", -1)),
+ ?line {'EXIT',_} = (catch string:copies("hej", -1)),
+ ?line {'EXIT',_} = (catch string:copies("hej", 2.0)),
ok.
words(suite) ->
diff --git a/lib/stdlib/test/supervisor_1.erl b/lib/stdlib/test/supervisor_1.erl
index 297550b230..3198be0fed 100644
--- a/lib/stdlib/test/supervisor_1.erl
+++ b/lib/stdlib/test/supervisor_1.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl
index 039ea298c4..6e927da2ab 100644
--- a/lib/stdlib/test/supervisor_SUITE.erl
+++ b/lib/stdlib/test/supervisor_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,49 +20,104 @@
-module(supervisor_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Testserver specific export
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, init_per_testcase/2,
+ end_per_testcase/2]).
%% Indirect spawn export
-export([init/1]).
%% API tests
--export([sup_start/1, sup_start_normal/1, sup_start_ignore_init/1,
+-export([ sup_start_normal/1, sup_start_ignore_init/1,
sup_start_ignore_child/1, sup_start_error_return/1,
- sup_start_fail/1, sup_stop/1, sup_stop_infinity/1,
+ sup_start_fail/1, sup_stop_infinity/1,
sup_stop_timeout/1, sup_stop_brutal_kill/1, child_adm/1,
child_adm_simple/1, child_specs/1, extra_return/1]).
%% Tests concept permanent, transient and temporary
--export([normal_termination/1, permanent_normal/1, transient_normal/1,
- temporary_normal/1, abnormal_termination/1,
+-export([ permanent_normal/1, transient_normal/1,
+ temporary_normal/1,
permanent_abnormal/1, transient_abnormal/1,
temporary_abnormal/1]).
%% Restart strategy tests
--export([restart_one_for_one/1, one_for_one/1,
- one_for_one_escalation/1, restart_one_for_all/1, one_for_all/1,
- one_for_all_escalation/1, restart_simple_one_for_one/1,
+-export([ one_for_one/1,
+ one_for_one_escalation/1, one_for_all/1,
+ one_for_all_escalation/1,
simple_one_for_one/1, simple_one_for_one_escalation/1,
- restart_rest_for_one/1, rest_for_one/1, rest_for_one_escalation/1,
+ rest_for_one/1, rest_for_one_escalation/1,
simple_one_for_one_extra/1]).
%% Misc tests
--export([child_unlink/1, tree/1, count_children_memory/1]).
+-export([child_unlink/1, tree/1, count_children_memory/1,
+ do_not_save_start_parameters_for_temporary_children/1]).
%-------------------------------------------------------------------------
-all(suite) ->
- {req,[stdlib],
- [sup_start, sup_stop, child_adm,
- child_adm_simple, extra_return, child_specs,
- restart_one_for_one, restart_one_for_all,
- restart_simple_one_for_one, restart_rest_for_one,
- normal_termination, abnormal_termination, child_unlink, tree,
- count_children_memory]}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, sup_start}, {group, sup_stop}, child_adm,
+ child_adm_simple, extra_return, child_specs,
+ {group, restart_one_for_one},
+ {group, restart_one_for_all},
+ {group, restart_simple_one_for_one},
+ {group, restart_rest_for_one},
+ {group, normal_termination},
+ {group, abnormal_termination}, child_unlink, tree,
+ count_children_memory, do_not_save_start_parameters_for_temporary_children].
+
+groups() ->
+ [{sup_start, [],
+ [sup_start_normal, sup_start_ignore_init,
+ sup_start_ignore_child, sup_start_error_return,
+ sup_start_fail]},
+ {sup_stop, [],
+ [sup_stop_infinity, sup_stop_timeout,
+ sup_stop_brutal_kill]},
+ {normal_termination, [],
+ [permanent_normal, transient_normal, temporary_normal]},
+ {abnormal_termination, [],
+ [permanent_abnormal, transient_abnormal,
+ temporary_abnormal]},
+ {restart_one_for_one, [],
+ [one_for_one, one_for_one_escalation]},
+ {restart_one_for_all, [],
+ [one_for_all, one_for_all_escalation]},
+ {restart_simple_one_for_one, [],
+ [simple_one_for_one, simple_one_for_one_extra,
+ simple_one_for_one_escalation]},
+ {restart_rest_for_one, [],
+ [rest_for_one, rest_for_one_escalation]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(count_children_memory, Config) ->
+ MemoryState = erlang:system_info(allocator),
+ case count_children_allocator_test(MemoryState) of
+ true -> Config;
+ false ->
+ {skip, "+Meamin used during test; erlang:memory/1 not available"}
+ end;
+init_per_testcase(_Case, Config) ->
+ Config.
+
+end_per_testcase(_Case, _Config) ->
+ ok.
start(InitResult) ->
supervisor:start_link({local, sup_test}, ?MODULE, InitResult).
@@ -81,19 +136,8 @@ get_child_counts(Supervisor) ->
proplists:get_value(supervisors, Counts),
proplists:get_value(workers, Counts)].
-
%-------------------------------------------------------------------------
-%
% Test cases starts here.
-%
-%-------------------------------------------------------------------------
-
-sup_start(doc) ->
- ["Test start of a supervisor."];
-sup_start(suite) ->
- [sup_start_normal, sup_start_ignore_init, sup_start_ignore_child,
- sup_start_error_return, sup_start_fail].
-
%-------------------------------------------------------------------------
sup_start_normal(doc) ->
["Tests that the supervisor process starts correctly and that it "
@@ -192,12 +236,6 @@ sup_start_fail(Config) when is_list(Config) ->
end,
ok.
%-------------------------------------------------------------------------
-sup_stop(doc) ->
- ["Tests that the supervisor shoutdowns its children if it is "
- "shutdown itself."];
-sup_stop(suite) -> [sup_stop_infinity, sup_stop_timeout, sup_stop_brutal_kill].
-
-%-------------------------------------------------------------------------
sup_stop_infinity(doc) ->
["See sup_stop/1 when Shutdown = infinity, this walue is only allowed "
@@ -549,11 +587,6 @@ child_specs(Config) when is_list(Config) ->
?line ok = supervisor:check_childspecs([C3]),
?line ok = supervisor:check_childspecs([C4]),
ok.
-%-------------------------------------------------------------------------
-normal_termination(doc) ->
- ["Testes the supervisors behaviour if a child dies with reason normal"];
-normal_termination(suite) ->
- [permanent_normal, transient_normal, temporary_normal].
%-------------------------------------------------------------------------
permanent_normal(doc) ->
@@ -615,11 +648,6 @@ temporary_normal(Config) when is_list(Config) ->
?line [1,0,0,1] = get_child_counts(sup_test),
ok.
-%-------------------------------------------------------------------------
-abnormal_termination(doc) ->
- ["Testes the supervisors behaviour if a child dies with reason abnormal"];
-abnormal_termination(suite) ->
- [permanent_abnormal, transient_abnormal, temporary_abnormal].
%-------------------------------------------------------------------------
permanent_abnormal(doc) ->
@@ -688,12 +716,6 @@ temporary_abnormal(Config) when is_list(Config) ->
ok.
%-------------------------------------------------------------------------
-restart_one_for_one(doc) ->
- ["Test that the one_for_one strategy works."];
-
-restart_one_for_one(suite) -> [one_for_one, one_for_one_escalation].
-
-%-------------------------------------------------------------------------
one_for_one(doc) ->
["Test the one_for_one base case."];
one_for_one(suite) -> [];
@@ -772,13 +794,6 @@ one_for_one_escalation(Config) when is_list(Config) ->
end,
ok.
%-------------------------------------------------------------------------
-restart_one_for_all(doc) ->
- ["Test that the one_for_all strategy works."];
-
-restart_one_for_all(suite) ->
- [one_for_all, one_for_all_escalation].
-
-%-------------------------------------------------------------------------
one_for_all(doc) ->
["Test the one_for_all base case."];
one_for_all(suite) -> [];
@@ -866,14 +881,6 @@ one_for_all_escalation(Config) when is_list(Config) ->
ok.
%-------------------------------------------------------------------------
-restart_simple_one_for_one(doc) ->
- ["Test that the simple_one_for_one strategy works."];
-
-restart_simple_one_for_one(suite) ->
- [simple_one_for_one, simple_one_for_one_extra,
- simple_one_for_one_escalation].
-
-%-------------------------------------------------------------------------
simple_one_for_one(doc) ->
["Test the simple_one_for_one base case."];
simple_one_for_one(suite) -> [];
@@ -990,11 +997,6 @@ simple_one_for_one_escalation(Config) when is_list(Config) ->
end,
ok.
%-------------------------------------------------------------------------
-restart_rest_for_one(doc) ->
- ["Test that the rest_for_one strategy works."];
-restart_rest_for_one(suite) -> [rest_for_one, rest_for_one_escalation].
-
-%-------------------------------------------------------------------------
rest_for_one(doc) ->
["Test the rest_for_one base case."];
rest_for_one(suite) -> [];
@@ -1267,26 +1269,10 @@ tree(Config) when is_list(Config) ->
ok.
%-------------------------------------------------------------------------
-count_children_allocator_test(MemoryState) ->
- Allocators = [temp_alloc, eheap_alloc, binary_alloc, ets_alloc,
- driver_alloc, sl_alloc, ll_alloc, fix_alloc, std_alloc,
- sys_alloc],
- MemoryStateList = element(4, MemoryState),
- AllocTypes = [lists:keyfind(Alloc, 1, MemoryStateList)
- || Alloc <- Allocators],
- AllocStates = [lists:keyfind(e, 1, AllocValue)
- || {_Type, AllocValue} <- AllocTypes],
- lists:all(fun(State) -> State == {e, true} end, AllocStates).
-
count_children_memory(doc) ->
- ["Test that which_children eats memory, but count_children does not."];
+ ["Test that count_children does not eat memory."];
count_children_memory(suite) ->
- MemoryState = erlang:system_info(allocator),
- case count_children_allocator_test(MemoryState) of
- true -> [];
- false ->
- {skip, "+Meamin used during test; erlang:memory/1 not available"}
- end;
+ [];
count_children_memory(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child, {supervisor_1, start_child, []}, temporary, 1000,
@@ -1299,7 +1285,7 @@ count_children_memory(Config) when is_list(Config) ->
Children = supervisor:which_children(sup_test),
_Size2 = erlang:memory(processes_used),
ChildCount = get_child_counts(sup_test),
- Size3 = erlang:memory(processes_used),
+ _Size3 = erlang:memory(processes_used),
[supervisor:start_child(sup_test, []) || _Ignore2 <- lists:seq(1,1000)],
@@ -1323,8 +1309,8 @@ count_children_memory(Config) when is_list(Config) ->
?line ChildCount3 = ChildCount2,
%% count_children consumes memory using an accumulator function,
- %% but the space can be reclaimed incrementally, whereas
- %% which_children generates a return list.
+ %% but the space can be reclaimed incrementally,
+ %% which_children may generate garbage that will be reclaimed later.
case (Size5 =< Size4) of
true -> ok;
false ->
@@ -1336,19 +1322,98 @@ count_children_memory(Config) when is_list(Config) ->
?line test_server:fail({count_children, used_more_memory})
end,
- case Size4 > Size3 of
- true -> ok;
- false ->
- ?line test_server:fail({which_children, used_no_memory})
- end,
- case Size6 > Size5 of
- true -> ok;
- false ->
- ?line test_server:fail({which_children, used_no_memory})
- end,
-
[exit(Pid, kill) || {undefined, Pid, worker, _Modules} <- Children3],
test_server:sleep(100),
?line [1,0,0,0] = get_child_counts(sup_test),
-
ok.
+count_children_allocator_test(MemoryState) ->
+ Allocators = [temp_alloc, eheap_alloc, binary_alloc, ets_alloc,
+ driver_alloc, sl_alloc, ll_alloc, fix_alloc, std_alloc,
+ sys_alloc],
+ MemoryStateList = element(4, MemoryState),
+ AllocTypes = [lists:keyfind(Alloc, 1, MemoryStateList)
+ || Alloc <- Allocators],
+ AllocStates = [lists:keyfind(e, 1, AllocValue)
+ || {_Type, AllocValue} <- AllocTypes],
+ lists:all(fun(State) -> State == {e, true} end, AllocStates).
+%-------------------------------------------------------------------------
+do_not_save_start_parameters_for_temporary_children(doc) ->
+ ["Temporary children shall not be restarted so they should not "
+ "save start parameters, as it potentially can "
+ "take up a huge amount of memory for no purpose."];
+do_not_save_start_parameters_for_temporary_children(suite) ->
+ [];
+do_not_save_start_parameters_for_temporary_children(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ dont_save_start_parameters_for_temporary_children(one_for_all),
+ dont_save_start_parameters_for_temporary_children(one_for_one),
+ dont_save_start_parameters_for_temporary_children(rest_for_one),
+ dont_save_start_parameters_for_temporary_children(simple_one_for_one).
+
+dont_save_start_parameters_for_temporary_children(simple_one_for_one = Type) ->
+ Permanent = {child, {supervisor_1, start_child, []},
+ permanent, 1000, worker, []},
+ Transient = {child, {supervisor_1, start_child, []},
+ transient, 1000, worker, []},
+ Temporary = {child, {supervisor_1, start_child, []},
+ temporary, 1000, worker, []},
+ {ok, Sup1} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, [Permanent]}}),
+ {ok, Sup2} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, [Transient]}}),
+ {ok, Sup3} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, [Temporary]}}),
+
+ LargeList = lists:duplicate(10, "Potentially large"),
+
+ start_children(Sup1, [LargeList], 100),
+ start_children(Sup2, [LargeList], 100),
+ start_children(Sup3, [LargeList], 100),
+
+ [{memory,Mem1}] = process_info(Sup1, [memory]),
+ [{memory,Mem2}] = process_info(Sup2, [memory]),
+ [{memory,Mem3}] = process_info(Sup3, [memory]),
+
+ true = (Mem3 < Mem1) and (Mem3 < Mem2),
+
+ exit(Sup1, shutdown),
+ exit(Sup2, shutdown),
+ exit(Sup3, shutdown);
+
+dont_save_start_parameters_for_temporary_children(Type) ->
+ {ok, Sup1} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, []}}),
+ {ok, Sup2} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, []}}),
+ {ok, Sup3} = supervisor:start_link(?MODULE, {ok, {{Type, 2, 3600}, []}}),
+
+ LargeList = lists:duplicate(10, "Potentially large"),
+
+ Permanent = {child1, {supervisor_1, start_child, [LargeList]},
+ permanent, 1000, worker, []},
+ Transient = {child2, {supervisor_1, start_child, [LargeList]},
+ transient, 1000, worker, []},
+ Temporary = {child3, {supervisor_1, start_child, [LargeList]},
+ temporary, 1000, worker, []},
+
+ start_children(Sup1, Permanent, 100),
+ start_children(Sup2, Transient, 100),
+ start_children(Sup3, Temporary, 100),
+
+ [{memory,Mem1}] = process_info(Sup1, [memory]),
+ [{memory,Mem2}] = process_info(Sup2, [memory]),
+ [{memory,Mem3}] = process_info(Sup3, [memory]),
+
+ true = (Mem3 < Mem1) and (Mem3 < Mem2),
+
+ exit(Sup1, shutdown),
+ exit(Sup2, shutdown),
+ exit(Sup3, shutdown).
+
+start_children(_,_, 0) ->
+ ok;
+start_children(Sup, Args, N) ->
+ Spec = child_spec(Args, N),
+ {ok, _, _} = supervisor:start_child(Sup, Spec),
+ start_children(Sup, Args, N-1).
+
+child_spec([_|_] = SimpleOneForOneArgs, _) ->
+ SimpleOneForOneArgs;
+child_spec({Name, MFA, RestartType, Shutdown, Type, Modules}, N) ->
+ NewName = list_to_atom((atom_to_list(Name) ++ integer_to_list(N))),
+ {NewName, MFA, RestartType, Shutdown, Type, Modules}.
diff --git a/lib/stdlib/test/supervisor_bridge_SUITE.erl b/lib/stdlib/test/supervisor_bridge_SUITE.erl
index b23bac2d44..407968747c 100644
--- a/lib/stdlib/test/supervisor_bridge_SUITE.erl
+++ b/lib/stdlib/test/supervisor_bridge_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -17,16 +17,37 @@
%% %CopyrightEnd%
%%
-module(supervisor_bridge_SUITE).
--export([all/1,starting/1,mini_terminate/1,mini_die/1,badstart/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,starting/1,
+ mini_terminate/1,mini_die/1,badstart/1]).
-export([client/1,init/1,internal_loop_init/1,terminate/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(bridge_name,supervisor_bridge_SUITE_server).
-define(work_bridge_name,work_supervisor_bridge_SUITE_server).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all(suite) -> [starting,mini_terminate,mini_die,badstart].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [starting, mini_terminate, mini_die, badstart].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/stdlib/test/sys_SUITE.erl b/lib/stdlib/test/sys_SUITE.erl
index e44fd56403..dcb2380910 100644
--- a/lib/stdlib/test/sys_SUITE.erl
+++ b/lib/stdlib/test/sys_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -17,9 +17,11 @@
%% %CopyrightEnd%
%%
-module(sys_SUITE).
--export([all/1,log/1,log_to_file/1,stats/1,trace/1,suspend/1,install/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,log/1,log_to_file/1,
+ stats/1,trace/1,suspend/1,install/1]).
-export([handle_call/3,terminate/2,init/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(server,sys_SUITE_server).
@@ -29,7 +31,26 @@
%% system messages at all.
-all(suite) -> [log,log_to_file,stats,trace,suspend,install].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [log, log_to_file, stats, trace, suspend, install].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl
index 7646f4c249..84c3915749 100644
--- a/lib/stdlib/test/tar_SUITE.erl
+++ b/lib/stdlib/test/tar_SUITE.erl
@@ -18,21 +18,39 @@
%%
-module(tar_SUITE).
--export([all/1, borderline/1, atomic/1, long_names/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, borderline/1, atomic/1, long_names/1,
create_long_names/1, bad_tar/1, errors/1, extract_from_binary/1,
extract_from_binary_compressed/1,
extract_from_open_file/1, symlinks/1, open_add_close/1, cooked_compressed/1,
memory/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
-all(suite) -> [borderline, atomic, long_names, create_long_names,
- bad_tar, errors,
- extract_from_binary, extract_from_binary_compressed,
- extract_from_open_file,
- symlinks, open_add_close, cooked_compressed,
- memory].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [borderline, atomic, long_names, create_long_names,
+ bad_tar, errors, extract_from_binary,
+ extract_from_binary_compressed, extract_from_open_file,
+ symlinks, open_add_close, cooked_compressed, memory].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
borderline(doc) ->
["Test creating, listing and extracting one file from an archive",
diff --git a/lib/stdlib/test/timer_SUITE.erl b/lib/stdlib/test/timer_SUITE.erl
index 5f38c91c64..cc05e3d832 100644
--- a/lib/stdlib/test/timer_SUITE.erl
+++ b/lib/stdlib/test/timer_SUITE.erl
@@ -18,12 +18,12 @@
%%
-module(timer_SUITE).
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2]).
-export([do_big_test/1]).
-export([big_test/1, collect/3, i_t/3, a_t/2]).
-export([do_nrev/1, internal_watchdog/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test suite for timer module. This is a really nasty test it runs a
%% lot of timeouts and then checks in the end if any of them was
@@ -51,7 +51,26 @@
%% amount of load. The test suite should also include tests that test the
%% interface of the timer module.
-all(suite) -> [do_big_test].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [do_big_test].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% ------------------------------------------------------- %%
diff --git a/lib/stdlib/test/timer_simple_SUITE.erl b/lib/stdlib/test/timer_simple_SUITE.erl
index 6aa2b7b945..afe6699920 100644
--- a/lib/stdlib/test/timer_simple_SUITE.erl
+++ b/lib/stdlib/test/timer_simple_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,7 +21,8 @@
-module(timer_simple_SUITE).
%% external
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
init_per_testcase/2,
apply_after/1,
send_after1/1,
@@ -49,31 +50,35 @@
timer/4,
timer/5]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(MAXREF, (1 bsl 18)).
-define(REFMARG, 30).
-all(doc) -> "Test of the timer module.";
-all(suite) ->
- [apply_after,
- send_after1,
- send_after2,
- send_after3,
- exit_after1,
- exit_after2,
- kill_after1,
- kill_after2,
- apply_interval,
- send_interval1,
- send_interval2,
- send_interval3,
- send_interval4,
- cancel1,
- cancel2,
- tc,
- unique_refs,
- timer_perf].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [apply_after, send_after1, send_after2, send_after3,
+ exit_after1, exit_after2, kill_after1, kill_after2,
+ apply_interval, send_interval1, send_interval2,
+ send_interval3, send_interval4, cancel1, cancel2, tc,
+ unique_refs, timer_perf].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init_per_testcase(_, Config) when is_list(Config) ->
timer:start(),
diff --git a/lib/stdlib/test/unicode_SUITE.erl b/lib/stdlib/test/unicode_SUITE.erl
index 141ac64606..3cca1ab894 100644
--- a/lib/stdlib/test/unicode_SUITE.erl
+++ b/lib/stdlib/test/unicode_SUITE.erl
@@ -18,11 +18,12 @@
%%
-module(unicode_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
init_per_testcase/2,
- fin_per_testcase/2,
+ end_per_testcase/2,
utf8_illegal_sequences_bif/1,
utf16_illegal_sequences_bif/1,
random_lists/1,
@@ -34,12 +35,32 @@ init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog=?t:timetrap(?t:minutes(20)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog).
-all(suite) ->
- [utf8_illegal_sequences_bif,utf16_illegal_sequences_bif,random_lists,roundtrips,latin1,exceptions].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [utf8_illegal_sequences_bif,
+ utf16_illegal_sequences_bif, random_lists, roundtrips,
+ latin1, exceptions].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
exceptions(Config) when is_list(Config) ->
diff --git a/lib/stdlib/test/win32reg_SUITE.erl b/lib/stdlib/test/win32reg_SUITE.erl
index c8cc82f61e..f54cd2dcca 100644
--- a/lib/stdlib/test/win32reg_SUITE.erl
+++ b/lib/stdlib/test/win32reg_SUITE.erl
@@ -18,22 +18,34 @@
%%
-module(win32reg_SUITE).
--export([all/1,long/1,evil_write/1]).
--export([ostype/1,fini/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,long/1,evil_write/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-all(suite) ->
- [{conf,ostype,[long,evil_write],fini}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
-ostype(Config) when is_list(Config) ->
+all() ->
+ [long, evil_write].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+init_per_suite(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
Config;
_ ->
{skip,"Doesn't run on UNIX."}
end.
-fini(Config) when is_list(Config) ->
+end_per_suite(Config) when is_list(Config) ->
Config.
long(doc) -> "Test long keys and entries (OTP-3446).";
diff --git a/lib/stdlib/test/y2k_SUITE.erl b/lib/stdlib/test/y2k_SUITE.erl
index a574d5e36e..0ea51355e2 100644
--- a/lib/stdlib/test/y2k_SUITE.erl
+++ b/lib/stdlib/test/y2k_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -21,30 +21,38 @@
-module(y2k_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
date_1999_01_01/1, date_1999_02_28/1,
date_1999_09_09/1, date_2000_01_01/1,
date_2000_02_29/1, date_2001_01_01/1,
date_2001_02_29/1, date_2004_02_29/1
]).
-all(doc) ->
- "This is the test suite for year 2000. Eight dates according "
- "to Ericsson Corporate Millennium Test Specification "
- "(LME/DT-98:1097 are tested.";
-
-all(suite) ->
- [date_1999_01_01,
- date_1999_02_28,
- date_1999_09_09,
- date_2000_01_01,
- date_2000_02_29,
- date_2001_01_01,
- date_2001_02_29,
- date_2004_02_29
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [date_1999_01_01, date_1999_02_28, date_1999_09_09,
+ date_2000_01_01, date_2000_02_29, date_2001_01_01,
+ date_2001_02_29, date_2004_02_29].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
date_1999_01_01(doc) ->
"#1 : 1999-01-01: test roll-over from 1998-12-31 to 1999-01-01.";
diff --git a/lib/stdlib/test/zip_SUITE.erl b/lib/stdlib/test/zip_SUITE.erl
index 48b14396c1..895019ab96 100644
--- a/lib/stdlib/test/zip_SUITE.erl
+++ b/lib/stdlib/test/zip_SUITE.erl
@@ -18,7 +18,8 @@
%%
-module(zip_SUITE).
--export([all/1, borderline/1, atomic/1,
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, borderline/1, atomic/1,
bad_zip/1, unzip_from_binary/1, unzip_to_binary/1,
zip_to_binary/1,
unzip_options/1, zip_options/1, list_dir_options/1, aliases/1,
@@ -26,18 +27,34 @@
compress_control/1,
foldl/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("test_server_line.hrl").
-include_lib("kernel/include/file.hrl").
-include_lib("stdlib/include/zip.hrl").
-all(suite) -> [borderline, atomic, bad_zip,
- unzip_from_binary, unzip_to_binary,
- zip_to_binary,
- unzip_options, zip_options, list_dir_options, aliases,
- openzip_api, zip_api, unzip_jar,
- compress_control,
- foldl].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [borderline, atomic, bad_zip, unzip_from_binary,
+ unzip_to_binary, zip_to_binary, unzip_options,
+ zip_options, list_dir_options, aliases, openzip_api,
+ zip_api, unzip_jar, compress_control, foldl].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
borderline(doc) ->
["Test creating, listing and extracting one file from an archive "
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index db7954af04..ac02e1f359 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 1.17.2
+STDLIB_VSN = 1.17.3
diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml
index fca93a27d9..3f5eb7231e 100644
--- a/lib/syntax_tools/doc/src/notes.xml
+++ b/lib/syntax_tools/doc/src/notes.xml
@@ -31,6 +31,20 @@
<p>This document describes the changes made to the Syntax_Tools
application.</p>
+<section><title>Syntax_Tools 1.6.7</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Miscellaneous updates</p>
+ <p>
+ Own Id: OTP-8976</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Syntax_Tools 1.6.6</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl
index c2c72d1ed2..7caf0b3db6 100644
--- a/lib/syntax_tools/src/erl_prettypr.erl
+++ b/lib/syntax_tools/src/erl_prettypr.erl
@@ -50,11 +50,15 @@
-type hook() :: 'none'
| fun((erl_syntax:syntaxTree(), _, _) -> prettypr:document()).
+-type clause_t() :: 'case_expr' | 'cond_expr' | 'fun_expr'
+ | 'if_expr' | 'receive_expr' | 'try_expr'
+ | {'function', prettypr:document()}
+ | {'rule', prettypr:document()}.
-record(ctxt, {prec = 0 :: integer(),
sub_indent = 2 :: non_neg_integer(),
break_indent = 4 :: non_neg_integer(),
- clause = undefined,
+ clause = undefined :: clause_t() | 'undefined',
hook = ?NOHOOK :: hook(),
paper = ?PAPER :: integer(),
ribbon = ?RIBBON :: integer(),
@@ -599,9 +603,8 @@ lay_2(Node, Ctxt) ->
case_expr ->
Ctxt1 = reset_prec(Ctxt),
D1 = lay(erl_syntax:case_expr_argument(Node), Ctxt1),
- D2 = lay_clauses(
- erl_syntax:case_expr_clauses(Node),
- case_expr, Ctxt1),
+ D2 = lay_clauses(erl_syntax:case_expr_clauses(Node),
+ case_expr, Ctxt1),
sep([par([follow(text("case"), D1, Ctxt1#ctxt.sub_indent),
text("of")],
Ctxt1#ctxt.break_indent),
@@ -819,9 +822,8 @@ lay_2(Node, Ctxt) ->
receive_expr ->
Ctxt1 = reset_prec(Ctxt),
- D1 = lay_clauses(
- erl_syntax:receive_expr_clauses(Node),
- receive_expr, Ctxt1),
+ D1 = lay_clauses(erl_syntax:receive_expr_clauses(Node),
+ receive_expr, Ctxt1),
D2 = case erl_syntax:receive_expr_timeout(Node) of
none ->
D1;
diff --git a/lib/syntax_tools/src/erl_recomment.erl b/lib/syntax_tools/src/erl_recomment.erl
index 94e760dad7..919e9cfc5d 100644
--- a/lib/syntax_tools/src/erl_recomment.erl
+++ b/lib/syntax_tools/src/erl_recomment.erl
@@ -215,7 +215,8 @@ comment_delta(Text) ->
%% the source file itself, but have been included by preprocessing. This
%% way, comments will not be inserted into such parts by mistake.
--record(filter, {file = undefined, line = 0 :: integer()}).
+-record(filter, {file = undefined :: file:filename() | 'undefined',
+ line = 0 :: integer()}).
filter_forms(Fs) ->
filter_forms(Fs, false, #filter{}).
@@ -721,8 +722,6 @@ tree_node_attrs(#tree{attrs = Attrs}) ->
%% =====================================================================
%% General utility functions
-%% Just the generic "maximum" function
-
%% 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 a40bf83c5a..9df5f26454 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -1818,7 +1818,7 @@ char_value(Node) ->
%%
%% @see char/1
--spec char_literal(syntaxTree()) -> string().
+-spec char_literal(syntaxTree()) -> nonempty_string().
char_literal(Node) ->
io_lib:write_char(char_value(Node)).
@@ -1908,7 +1908,7 @@ string_value(Node) ->
%%
%% @see string/1
--spec string_literal(syntaxTree()) -> string().
+-spec string_literal(syntaxTree()) -> nonempty_string().
string_literal(Node) ->
io_lib:write_string(string_value(Node)).
diff --git a/lib/syntax_tools/src/erl_syntax_lib.erl b/lib/syntax_tools/src/erl_syntax_lib.erl
index 4808971a59..97dfbfd7cd 100644
--- a/lib/syntax_tools/src/erl_syntax_lib.erl
+++ b/lib/syntax_tools/src/erl_syntax_lib.erl
@@ -49,10 +49,6 @@
-export_type([info_pair/0]).
%% =====================================================================
-
--type ordset(X) :: [X]. % XXX: TAKE ME OUT
-
-%% =====================================================================
%% @spec map(Function, Tree::syntaxTree()) -> syntaxTree()
%%
%% Function = (syntaxTree()) -> syntaxTree()
@@ -480,7 +476,7 @@ new_variable_names(0, Names, _, _, _) ->
%% @see annotate_bindings/1
%% @see //stdlib/ordsets
--spec annotate_bindings(erl_syntax:syntaxTree(), ordset(atom())) ->
+-spec annotate_bindings(erl_syntax:syntaxTree(), ordsets:ordset(atom())) ->
erl_syntax:syntaxTree().
annotate_bindings(Tree, Env) ->
@@ -1134,21 +1130,21 @@ collect_attribute(_, {N, V}, Info) ->
%% Abstract datatype for collecting module information.
--record(forms, {module, exports, module_imports, imports, attributes,
- records, errors, warnings, functions, rules}).
+-record(forms, {module = none :: 'none' | {'value', atom()},
+ exports = [] :: [{atom(), arity()}],
+ module_imports = [] :: [atom()],
+ imports = [] :: [{atom(), [{atom(), arity()}]}],
+ attributes = [] :: [{atom(), term()}],
+ records = [] :: [{atom(), [{atom(), field_default()}]}],
+ errors = [] :: [term()],
+ warnings = [] :: [term()],
+ functions = [] :: [{atom(), arity()}],
+ rules = [] :: [{atom(), arity()}]}).
+
+-type field_default() :: 'none' | erl_syntax:syntaxTree().
new_finfo() ->
- #forms{module = none,
- exports = [],
- module_imports = [],
- imports = [],
- attributes = [],
- records = [],
- errors = [],
- warnings = [],
- functions = [],
- rules = []
- }.
+ #forms{}.
finfo_set_module(Name, Info) ->
case Info#forms.module of
diff --git a/lib/syntax_tools/src/erl_tidy.erl b/lib/syntax_tools/src/erl_tidy.erl
index 021ab18736..1cfdc7234a 100644
--- a/lib/syntax_tools/src/erl_tidy.erl
+++ b/lib/syntax_tools/src/erl_tidy.erl
@@ -935,12 +935,13 @@ hidden_uses_2(Tree, Used) ->
Used
end.
+-type fa() :: {atom(), arity()}.
-type context() :: 'guard_expr' | 'guard_test' | 'normal'.
-record(env, {file :: file:filename(),
- module,
- current,
- imports,
+ module :: atom(),
+ current :: fa(),
+ imports = dict:new() :: dict(),
context = normal :: context(),
verbosity = 1 :: 0 | 1 | 2,
quiet = false :: boolean(),
@@ -951,7 +952,13 @@ hidden_uses_2(Tree, Used) ->
new_guard_tests = true :: boolean(),
old_guard_tests = false :: boolean()}).
--record(st, {varc, used, imported, vars, functions, new_forms, rename}).
+-record(st, {varc :: non_neg_integer(),
+ used = sets:new() :: set(),
+ imported :: set(),
+ vars :: set(),
+ functions :: set(),
+ new_forms = [] :: [erl_syntax:syntaxTree()],
+ rename :: dict()}).
visit_used(Names, Defs, Roots, Imports, Module, Opts) ->
File = proplists:get_value(file, Opts, ""),
diff --git a/lib/syntax_tools/src/igor.erl b/lib/syntax_tools/src/igor.erl
index 702b399615..aa933eb54b 100644
--- a/lib/syntax_tools/src/igor.erl
+++ b/lib/syntax_tools/src/igor.erl
@@ -119,20 +119,16 @@
%% =====================================================================
--type ordset(X) :: [X]. % XXX: TAKE ME OUT
-
-%% =====================================================================
-
%% Data structure for module information
-record(module, {name :: atom(),
vars = none :: [atom()] | 'none',
- functions :: ordset({atom(), arity()}),
- exports :: ordset({atom(), arity()})
- | ordset({{atom(), arity()}, term()}),
- aliases :: ordset({{atom(), arity()},
- {atom(), {atom(), arity()}}}),
- attributes :: ordset({atom(), term()}),
+ functions :: ordsets:ordset({atom(), arity()}),
+ exports :: ordsets:ordset({atom(), arity()})
+ | ordsets:ordset({{atom(), arity()}, term()}),
+ aliases :: ordsets:ordset({{atom(), arity()},
+ {atom(), {atom(), arity()}}}),
+ attributes :: ordsets:ordset({atom(), term()}),
records :: [{atom(), [{atom(), term()}]}]
}).
@@ -149,7 +145,7 @@ default_printer(Tree, Options) ->
-type moduleName() :: atom().
-type functionName() :: {atom(), arity()}.
-type functionPair() :: {functionName(), {moduleName(), functionName()}}.
--type stubDescriptor() :: [{moduleName(), [functionPair()], [attribute()]}].
+-type stubDescriptor() :: {moduleName(), [functionPair()], [attribute()]}.
-type notes() :: 'always' | 'yes' | 'no'.
@@ -209,7 +205,7 @@ parse_transform(Forms, Options) ->
%% @spec merge(Name::atom(), Files::[filename()]) -> [filename()]
%% @equiv merge(Name, Files, [])
--spec merge(atom(), [file:filename()]) -> [file:filename()].
+-spec merge(atom(), [file:filename()]) -> [file:filename(),...].
merge(Name, Files) ->
merge(Name, Files, []).
@@ -343,7 +339,7 @@ merge(Name, Files) ->
{suffix, ?DEFAULT_SUFFIX},
{verbose, false}]).
--spec merge(atom(), [file:filename()], [option()]) -> [file:filename()].
+-spec merge(atom(), [file:filename()], [option()]) -> [file:filename(),...].
merge(Name, Files, Opts) ->
Opts1 = Opts ++ ?DEFAULT_MERGE_OPTS,
@@ -484,7 +480,7 @@ merge_files(Name, Trees, Files, Opts) ->
%%
%% Forms = syntaxTree() | [syntaxTree()]
%%
-%% @type stubDescriptor() = [{ModuleName, Functions, [Attribute]}]
+%% @type stubDescriptor() = {ModuleName, Functions, [Attribute]}
%% ModuleName = atom()
%% Functions = [{FunctionName, {ModuleName, FunctionName}}]
%% FunctionName = {atom(), integer()}
@@ -687,15 +683,15 @@ merge_files(Name, Trees, Files, Opts) ->
%% Data structure for merging environment.
-record(merge, {target :: atom(),
- sources :: ordset(atom()),
- export :: ordset(atom()),
- static :: ordset(atom()),
- safe :: ordset(atom()),
+ sources :: ordsets:ordset(atom()),
+ export :: ordsets:ordset(atom()),
+ static :: ordsets:ordset(atom()),
+ safe :: ordsets:ordset(atom()),
preserved :: boolean(),
no_headers :: boolean(),
notes :: notes(),
redirect :: dict(), % = dict(atom(), atom())
- no_imports :: ordset(atom()),
+ no_imports :: ordsets:ordset(atom()),
options :: [option()]
}).
@@ -1035,7 +1031,12 @@ make_stub(M, Map, Env) ->
%% Removing and/or out-commenting program forms. The returned form
%% sequence tree is not necessarily flat.
--record(filter, {records :: set(), file_attributes, attributes}).
+-type atts() :: 'delete' | 'kill'.
+-type file_atts() :: 'delete' | 'keep' | 'kill'.
+
+-record(filter, {records :: set(),
+ file_attributes :: file_atts(),
+ attributes :: atts()}).
filter_forms(Tree, Env) ->
Forms = erl_syntax:form_list_elements(
@@ -1576,6 +1577,8 @@ alias_expansions_2(Modules, Table) ->
%% ---------------------------------------------------------------------
%% Merging the source code.
+-type map_fun() :: fun(({atom(), integer()}) -> {atom(), integer()}).
+
%% Data structure for code transformation environment.
-record(code, {module :: atom(),
@@ -1586,11 +1589,10 @@ alias_expansions_2(Modules, Table) ->
preserved :: boolean(),
no_headers :: boolean(),
notes :: notes(),
- map, % = ({atom(), int()}) -> {atom(), int()}
- renaming, % = (atom()) -> ({atom(), int()}) ->
- % {atom(), int()}
- expand :: dict(), % = dict({atom(), int()},
- % {atom(), {atom(), int()}})
+ map :: map_fun(),
+ renaming :: fun((atom()) -> map_fun()),
+ expand :: dict(), % = dict({atom(), integer()},
+ % {atom(), {atom(), integer()}})
redirect :: dict() % = dict(atom(), atom())
}).
diff --git a/lib/syntax_tools/test/Makefile b/lib/syntax_tools/test/Makefile
index 621c76f5a5..e793dec566 100644
--- a/lib/syntax_tools/test/Makefile
+++ b/lib/syntax_tools/test/Makefile
@@ -59,7 +59,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
- $(INSTALL_DATA) syntax_tools.dynspec $(RELSYSDIR)
+ $(INSTALL_DATA) syntax_tools.spec syntax_tools.cover $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
release_docs_spec:
diff --git a/lib/syntax_tools/test/syntax_tools.cover b/lib/syntax_tools/test/syntax_tools.cover
new file mode 100644
index 0000000000..fd30f66cc4
--- /dev/null
+++ b/lib/syntax_tools/test/syntax_tools.cover
@@ -0,0 +1,2 @@
+{incl_app,syntax_tools,details}.
+
diff --git a/lib/syntax_tools/test/syntax_tools.dynspec b/lib/syntax_tools/test/syntax_tools.dynspec
deleted file mode 100644
index 981cb8175e..0000000000
--- a/lib/syntax_tools/test/syntax_tools.dynspec
+++ /dev/null
@@ -1,5 +0,0 @@
-%% -*- erlang -*-
-%% You can test this file using this command.
-%% file:script("syntax_tools.dynspec", [{'Os',"Unix"}]).
-
-[].
diff --git a/lib/syntax_tools/test/syntax_tools.spec b/lib/syntax_tools/test/syntax_tools.spec
new file mode 100644
index 0000000000..e7ddbf7586
--- /dev/null
+++ b/lib/syntax_tools/test/syntax_tools.spec
@@ -0,0 +1,2 @@
+%% -*- erlang -*-
+{suites,"../syntax_tools_test",all}.
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE.erl b/lib/syntax_tools/test/syntax_tools_SUITE.erl
index 16f794683b..fd381f0b25 100644
--- a/lib/syntax_tools/test/syntax_tools_SUITE.erl
+++ b/lib/syntax_tools/test/syntax_tools_SUITE.erl
@@ -17,17 +17,36 @@
%%
-module(syntax_tools_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
%% Test cases
-export([smoke_test/1]).
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[smoke_test].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%% Read and parse all source in the OTP release.
smoke_test(Config) when is_list(Config) ->
?line Dog = ?t:timetrap(?t:minutes(12)),
diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk
index 6051fb8e39..2e23f6aef9 100644
--- a/lib/syntax_tools/vsn.mk
+++ b/lib/syntax_tools/vsn.mk
@@ -1 +1 @@
-SYNTAX_TOOLS_VSN = 1.6.6
+SYNTAX_TOOLS_VSN = 1.6.7
diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml
index e0c4c28e44..ab329c399b 100644
--- a/lib/test_server/doc/src/notes.xml
+++ b/lib/test_server/doc/src/notes.xml
@@ -32,6 +32,20 @@
<file>notes.xml</file>
</header>
+<section><title>Test_Server 3.4.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Miscellaneous updates</p>
+ <p>
+ Own Id: OTP-8976</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Test_Server 3.4.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/test_server/src/Makefile b/lib/test_server/src/Makefile
index 3dca55178d..0858d24fce 100644
--- a/lib/test_server/src/Makefile
+++ b/lib/test_server/src/Makefile
@@ -57,7 +57,8 @@ TS_MODULES= \
ts_erl_config \
ts_autoconf_win32 \
ts_autoconf_vxworks \
- ts_install
+ ts_install \
+ ts_install_cth
TARGET_MODULES= $(MODULES:%=$(EBIN)/%)
TS_TARGET_MODULES= $(TS_MODULES:%=$(EBIN)/%)
@@ -71,7 +72,7 @@ C_FILES =
AUTOCONF_FILES = configure.in conf_vars.in
COVER_FILES = cross.cover
PROGRAMS = configure config.sub config.guess install-sh
-CONFIG = ts.config ts.unix.config ts.win32.config ts.vxworks.config
+CONFIG = ts.config ts.unix.config ts.win32.config
TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) \
$(APP_TARGET) $(APPUP_TARGET)
@@ -136,7 +137,7 @@ release_tests_spec: opt
$(INSTALL_DIR) $(RELEASE_PATH)/test_server
$(INSTALL_DATA) $(ERL_FILES) $(TS_ERL_FILES) \
$(HRL_FILES) $(INTERNAL_HRL_FILES) $(TS_HRL_FILES) \
- $(TARGET_FILES) $(TS_TARGET_FILES) \
+ $(TS_TARGET_FILES) \
$(AUTOCONF_FILES) $(C_FILES) $(COVER_FILES) $(CONFIG) \
$(RELEASE_PATH)/test_server
$(INSTALL_SCRIPT) $(PROGRAMS) $(RELEASE_PATH)/test_server
diff --git a/lib/test_server/src/test_server.erl b/lib/test_server/src/test_server.erl
index ee121e5bb6..2ab4e9c28a 100644
--- a/lib/test_server/src/test_server.erl
+++ b/lib/test_server/src/test_server.erl
@@ -470,7 +470,7 @@ cover_analyse(Analyse,Modules) ->
overview ->
fun(_) -> undefined end
end,
- R = lists:map(
+ R = pmap(
fun(M) ->
case cover:analyse(M,module) of
{ok,{M,{Cov,NotCov}}} ->
@@ -486,6 +486,19 @@ cover_analyse(Analyse,Modules) ->
stick_all_sticky(node(),Sticky),
R.
+pmap(Fun,List) ->
+ Collector = self(),
+ Pids = lists:map(fun(E) ->
+ spawn(fun() ->
+ Collector ! {res,self(),Fun(E)}
+ end)
+ end, List),
+ lists:map(fun(Pid) ->
+ receive
+ {res,Pid,Res} ->
+ Res
+ end
+ end, Pids).
unstick_all_sticky(Node) ->
lists:filter(
@@ -856,7 +869,7 @@ run_test_case_msgloop(Ref, Pid, CaptureStdout, Terminate, Comment, CurrConf) ->
%% a framework function failed
CB = os:getenv("TEST_SERVER_FRAMEWORK"),
Loc = case CB of
- false ->
+ FW when FW =:= false; FW =:= "undefined" ->
{test_server,Func};
_ ->
{list_to_atom(CB),Func}
@@ -935,8 +948,7 @@ spawn_fw_call(Mod,{init_per_testcase,Func},Pid,{timetrap_timeout,TVal}=Why,
Skip = {skip,{failed,{Mod,init_per_testcase,Why}}},
%% if init_per_testcase fails, the test case
%% should be skipped
- case catch test_server_sup:framework_call(
- end_tc,[?pl2a(Mod),Func,{Pid,Skip,[[]]}]) of
+ case catch do_end_tc_call(Mod,Func,{Pid,Skip,[[]]},Why) of
{'EXIT',FwEndTCErr} ->
exit({fw_notify_done,end_tc,FwEndTCErr});
_ ->
@@ -955,11 +967,9 @@ spawn_fw_call(Mod,{end_per_testcase,Func},Pid,{timetrap_timeout,TVal}=Why,
Conf = [{tc_status,ok}],
%% if end_per_testcase fails, the test case should be
%% reported successful with a warning printed as comment
- case catch test_server_sup:framework_call(end_tc,
- [?pl2a(Mod),Func,
- {Pid,
- {failed,{Mod,end_per_testcase,Why}},
- [Conf]}]) of
+ case catch do_end_tc_call(Mod,Func,{Pid,
+ {failed,{Mod,end_per_testcase,Why}},
+ [Conf]}, Why) of
{'EXIT',FwEndTCErr} ->
exit({fw_notify_done,end_tc,FwEndTCErr});
_ ->
@@ -1001,9 +1011,7 @@ spawn_fw_call(Mod,Func,Pid,Error,Loc,SendTo,Comment) ->
ok
end,
Conf = [{tc_status,{failed,timetrap_timeout}}],
- case catch test_server_sup:framework_call(end_tc,
- [?pl2a(Mod),Func,
- {Pid,Error,[Conf]}]) of
+ case catch do_end_tc_call(Mod,Func,{Pid,Error,[Conf]},Error) of
{'EXIT',FwEndTCErr} ->
exit({fw_notify_done,end_tc,FwEndTCErr});
_ ->
@@ -1069,27 +1077,27 @@ run_test_case_eval(Mod, Func, Args0, Name, Ref, RunInit,
{{Time,Value},Loc,Opts} =
case test_server_sup:framework_call(init_tc,[?pl2a(Mod),Func,Args0],
- {ok,Args0}) of
+ {ok, Args0}) of
{ok,Args} ->
run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback);
Error = {error,_Reason} ->
- test_server_sup:framework_call(end_tc,[?pl2a(Mod),Func,{Error,Args0}]),
- {{0,{skip,{failed,Error}}},{Mod,Func},[]};
+ NewResult = do_end_tc_call(Mod,Func,{Error,Args0},
+ {skip,{failed,Error}}),
+ {{0,NewResult},{Mod,Func},[]};
{fail,Reason} ->
[Conf] = Args0,
Conf1 = [{tc_status,{failed,Reason}} | Conf],
fw_error_notify(Mod, Func, Conf, Reason),
- test_server_sup:framework_call(end_tc,[?pl2a(Mod),Func,
- {{error,Reason},[Conf1]}]),
- {{0,{failed,Reason}},{Mod,Func},[]};
+ NewResult = do_end_tc_call(Mod,Func, {{error,Reason},[Conf1]},
+ {fail, Reason}),
+ {{0,NewResult},{Mod,Func},[]};
Skip = {skip,_Reason} ->
- test_server_sup:framework_call(end_tc,[?pl2a(Mod),Func,{Skip,Args0}]),
- {{0,Skip},{Mod,Func},[]};
+ NewResult = do_end_tc_call(Mod,Func,{Skip,Args0},Skip),
+ {{0,NewResult},{Mod,Func},[]};
{auto_skip,Reason} ->
- test_server_sup:framework_call(end_tc,[?pl2a(Mod),
- Func,
- {{skip,Reason},Args0}]),
- {{0,{skip,{fw_auto_skip,Reason}}},{Mod,Func},[]}
+ NewResult = do_end_tc_call(Mod, Func, {{skip,Reason},Args0},
+ {skip, {fw_auto_skip,Reason}}),
+ {{0,NewResult},{Mod,Func},[]}
end,
exit({Ref,Time,Value,Loc,Opts}).
@@ -1103,14 +1111,14 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
Skip = {skip,Reason} ->
Line = get_loc(),
Conf = [{tc_status,{skipped,Reason}}],
- test_server_sup:framework_call(end_tc,[?pl2a(Mod),Func,{Skip,[Conf]}]),
- {{0,{skip,Reason}},Line,[]};
+ NewRes = do_end_tc_call(Mod,Func,{Skip,[Conf]}, Skip),
+ {{0,NewRes},Line,[]};
{skip_and_save,Reason,SaveCfg} ->
Line = get_loc(),
Conf = [{tc_status,{skipped,Reason}},{save_config,SaveCfg}],
- test_server_sup:framework_call(end_tc,[?pl2a(Mod),Func,
- {{skip,Reason},[Conf]}]),
- {{0,{skip,Reason}},Line,[]};
+ NewRes = do_end_tc_call(Mod, Func, {{skip, Reason}, [Conf]},
+ {skip, Reason}),
+ {{0,NewRes},Line,[]};
{ok,NewConf} ->
put(test_server_init_or_end_conf,undefined),
%% call user callback function if defined
@@ -1155,13 +1163,12 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
{FWReturn,TSReturn,EndConf1}
end,
put(test_server_init_or_end_conf,undefined),
- case test_server_sup:framework_call(end_tc, [?pl2a(Mod), Func,
- {FWReturn1,[EndConf2]}]) of
- {fail,Reason} ->
- fw_error_notify(Mod, Func, EndConf2, Reason),
- {{T,{failed,Reason}},{Mod,Func},[]};
- _ ->
- {{T,TSReturn1},Loc,[]}
+ case do_end_tc_call(Mod, Func, {FWReturn1,[EndConf2]}, TSReturn1) of
+ {failed,Reason} = NewReturn ->
+ fw_error_notify(Mod,Func,EndConf2, Reason),
+ {{T,NewReturn},{Mod,Func},[]};
+ NewReturn ->
+ {{T,NewReturn},Loc,[]}
end
end;
skip_init ->
@@ -1179,10 +1186,36 @@ run_test_case_eval1(Mod, Func, Args, Name, RunInit, TCCallback) ->
{{T,Return},Loc} = {ts_tc(Mod, Func, Args2),get_loc()},
%% call user callback function if defined
Return1 = user_callback(TCCallback, Mod, Func, 'end', Return),
- {Return2,Opts} = process_return_val([Return1], Mod,Func,Args1, Loc, Return1),
+ {Return2,Opts} = process_return_val([Return1], Mod, Func,
+ Args1, Loc, Return1),
{{T,Return2},Loc,Opts}
end.
+do_end_tc_call(M,F,Res,Return) ->
+ Ref = make_ref(),
+ case test_server_sup:framework_call(
+ end_tc, [?pl2a(M),F,Res], Ref) of
+ {fail,FWReason} ->
+ {failed,FWReason};
+ Ref ->
+ case test_server_sup:framework_call(
+ end_tc, [?pl2a(M),F,Res, Return], ok) of
+ {fail,FWReason} ->
+ {failed,FWReason};
+ ok ->
+ case Return of
+ {fail,Reason} ->
+ {failed,Reason};
+ Return ->
+ Return
+ end;
+ NewReturn ->
+ NewReturn
+ end;
+ _ ->
+ Return
+ end.
+
%% the return value is a list and we have to check if it contains
%% the result of an end conf case or if it's a Config list
process_return_val([Return], M,F,A, Loc, Final) when is_list(Return) ->
@@ -1197,13 +1230,13 @@ process_return_val([Return], M,F,A, Loc, Final) when is_list(Return) ->
end, Return) of
true -> % must be return value from end conf case
process_return_val1(Return, M,F,A, Loc, Final, []);
- false -> % must be Config value from init conf case
- case test_server_sup:framework_call(end_tc, [?pl2a(M),F,{ok,A}]) of
- {fail,FWReason} ->
+ false -> % must be Config value from init conf case
+ case do_end_tc_call(M,F,{ok,A}, Return) of
+ {failed, FWReason} = Failed ->
fw_error_notify(M,F,A, FWReason),
- {{failed,FWReason},[]};
- _ ->
- {Return,[]}
+ {Failed, []};
+ NewReturn ->
+ {NewReturn, []}
end
end;
%% the return value is not a list, so it's the return value from an
@@ -1211,16 +1244,16 @@ process_return_val([Return], M,F,A, Loc, Final) when is_list(Return) ->
process_return_val(Return, M,F,A, Loc, Final) ->
process_return_val1(Return, M,F,A, Loc, Final, []).
-process_return_val1([Failed={E,TCError}|_], M,F,A=[Args], Loc, _, SaveOpts) when E=='EXIT';
- E==failed ->
+process_return_val1([Failed={E,TCError}|_], M,F,A=[Args], Loc, _, SaveOpts)
+ when E=='EXIT';
+ E==failed ->
fw_error_notify(M,F,A, TCError, mod_loc(Loc)),
- case test_server_sup:framework_call(end_tc,
- [?pl2a(M),F,{{error,TCError},
- [[{tc_status,{failed,TCError}}|Args]]}]) of
- {fail,FWReason} ->
+ case do_end_tc_call(M,F,{{error,TCError},
+ [[{tc_status,{failed,TCError}}|Args]]}, Failed) of
+ {failed,FWReason} ->
{{failed,FWReason},SaveOpts};
- _ ->
- {Failed,SaveOpts}
+ NewReturn ->
+ {NewReturn,SaveOpts}
end;
process_return_val1([SaveCfg={save_config,_}|Opts], M,F,[Args], Loc, Final, SaveOpts) ->
process_return_val1(Opts, M,F,[[SaveCfg|Args]], Loc, Final, SaveOpts);
@@ -1234,11 +1267,11 @@ process_return_val1([RetVal={Tag,_}|Opts], M,F,A, Loc, _, SaveOpts) when Tag==sk
process_return_val1([_|Opts], M,F,A, Loc, Final, SaveOpts) ->
process_return_val1(Opts, M,F,A, Loc, Final, SaveOpts);
process_return_val1([], M,F,A, _Loc, Final, SaveOpts) ->
- case test_server_sup:framework_call(end_tc, [?pl2a(M),F,{Final,A}]) of
- {fail,FWReason} ->
+ case do_end_tc_call(M,F,{Final,A}, Final) of
+ {failed,FWReason} ->
{{failed,FWReason},SaveOpts};
- _ ->
- {Final,lists:reverse(SaveOpts)}
+ NewReturn ->
+ {NewReturn,lists:reverse(SaveOpts)}
end.
user_callback(undefined, _, _, _, Args) ->
@@ -1263,7 +1296,7 @@ init_per_testcase(Mod, Func, Args) ->
false -> code:load_file(Mod);
_ -> ok
end,
- %% init_per_testcase defined, returns new configuration
+%% init_per_testcase defined, returns new configuration
case erlang:function_exported(Mod,init_per_testcase,2) of
true ->
case catch my_apply(Mod, init_per_testcase, [Func|Args]) of
@@ -1306,8 +1339,8 @@ init_per_testcase(Mod, Func, Args) ->
{skip,{failed,{Mod,init_per_testcase,Other}}}
end;
false ->
- %% Optional init_per_testcase not defined
- %% keep quiet.
+%% Optional init_per_testcase not defined
+%% keep quiet.
[Config] = Args,
{ok, Config}
end.
diff --git a/lib/test_server/src/test_server_ctrl.erl b/lib/test_server/src/test_server_ctrl.erl
index 1dc5646184..7cd58642d0 100644
--- a/lib/test_server/src/test_server_ctrl.erl
+++ b/lib/test_server/src/test_server_ctrl.erl
@@ -168,6 +168,7 @@
cross_cover_analyse/1, cross_cover_analyse/2, trc/1, stop_trace/0]).
-export([testcase_callback/1]).
-export([set_random_seed/1]).
+-export([kill_slavenodes/0]).
%%% TEST_SERVER INTERFACE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-export([output/2, print/2, print/3, print_timestamp/2]).
@@ -525,6 +526,9 @@ testcase_callback(ModFunc) ->
set_random_seed(Seed) ->
controller_call({set_random_seed,Seed}).
+kill_slavenodes() ->
+ controller_call(kill_slavenodes).
+
get_hosts() ->
get(test_server_hosts).
@@ -533,6 +537,8 @@ get_target_os_type() ->
undefined ->
%% This is probably called on the target node
os:type();
+ Pid when Pid =:= self() ->
+ os:type();
_pid ->
%% This is called on the controller, e.g. from a
%% specification clause of a test case
@@ -637,7 +643,7 @@ contact_main_target(local) ->
%% When used by a general framework, global registration of
%% test_server should not be required.
case os:getenv("TEST_SERVER_FRAMEWORK") of
- false ->
+ FW when FW =:= false; FW =:= "undefined" ->
%% Local target! The global test_server process implemented by
%% test_server.erl will not be started, so we simulate it by
%% globally registering this process instead.
@@ -1704,7 +1710,7 @@ do_test_cases(TopCases, SkipCases,
[erlang:system_info(version), code:root_dir()]),
case os:getenv("TEST_SERVER_FRAMEWORK") of
- false ->
+ FW when FW =:= false; FW =:= "undefined" ->
print(html, "<p>Target:<br>\n"),
print_who(TI#target_info.host, TI#target_info.username),
print(html, "<br>Used Erlang ~s in <tt>~s</tt>.\n",
@@ -3552,7 +3558,7 @@ run_test_case1(Ref, Num, Mod, Func, Args, RunInit, Where,
{_,{'EXIT',Reason}} ->
progress(failed, Num, Mod, Func, Loc, Reason,
Time, Comment, Style);
- {_, {failed, Reason}} ->
+ {_, {Fail, Reason}} when Fail =:= fail; Fail =:= failed ->
progress(failed, Num, Mod, Func, Loc, Reason,
Time, Comment, Style);
{_, {Skip, Reason}} when Skip==skip; Skip==skipped ->
@@ -4057,7 +4063,7 @@ get_font_style1(default) ->
format_exception(Reason={_Error,Stack}) when is_list(Stack) ->
case os:getenv("TEST_SERVER_FRAMEWORK") of
- false ->
+ FW when FW =:= false; FW =:= "undefined" ->
case application:get_env(test_server, format_exception) of
{ok,false} ->
{"~p",Reason};
@@ -4630,7 +4636,7 @@ collect_case([Case | Cases], St, Acc) ->
collect_case_invoke(Mod, Case, MFA, St) ->
case os:getenv("TEST_SERVER_FRAMEWORK") of
- false ->
+ FW when FW =:= false; FW =:= "undefined" ->
case catch apply(Mod, Case, [suite]) of
{'EXIT',_} ->
{ok,[MFA],St};
diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl
index 49025b1a3d..056d18da96 100644
--- a/lib/test_server/src/test_server_node.erl
+++ b/lib/test_server/src/test_server_node.erl
@@ -84,7 +84,7 @@ start_remote_main_target(Parameters) ->
MasterNode,MasterCookie),
Cmd =
case os:getenv("TEST_SERVER_FRAMEWORK") of
- false -> Cmd0;
+ FW when FW =:= false; FW =:= "undefined" -> Cmd0;
FW -> Cmd0 ++ " -env TEST_SERVER_FRAMEWORK " ++ FW
end,
diff --git a/lib/test_server/src/test_server_sup.erl b/lib/test_server/src/test_server_sup.erl
index 625724fbb5..4a7804a482 100644
--- a/lib/test_server/src/test_server_sup.erl
+++ b/lib/test_server/src/test_server_sup.erl
@@ -494,7 +494,8 @@ framework_call(Func,Args) ->
framework_call(Func,Args,DefaultReturn) ->
CB = os:getenv("TEST_SERVER_FRAMEWORK"),
framework_call(CB,Func,Args,DefaultReturn).
-framework_call(false,_Func,_Args,DefaultReturn) ->
+framework_call(FW,_Func,_Args,DefaultReturn)
+ when FW =:= false; FW =:= "undefined" ->
DefaultReturn;
framework_call(Callback,Func,Args,DefaultReturn) ->
Mod = list_to_atom(Callback),
diff --git a/lib/test_server/src/ts.config b/lib/test_server/src/ts.config
index 30ef25a0b8..f021f5958b 100644
--- a/lib/test_server/src/ts.config
+++ b/lib/test_server/src/ts.config
@@ -1,45 +1,46 @@
%% -*- erlang -*-
-{ipv6_hosts,[otptest06,otptest08,sauron,iluvatar]}.
-%%% Change these to suite the environment.
-%%% test_hosts are looked up using "ypmatch xx yy zz hosts"
-{test_hosts,
- [bingo, hurin, turin, gandalf, super,
- merry, nenya, sam, elrond, isildur]}.
+%%% Change these to suite the environment. See the inet_SUITE for info about
+%%% what they are used for.
+%%% test_hosts are looked up using "ypmatch xx yy zz hosts.byname"
+%{test_hosts,[my_ip4_host]}.
%% IPv4 host only - no ipv6 entry must exist!
-{test_host_ipv4_only,
- {"isildur", %Short hostname
- "isildur.du.uab.ericsson.se", %Long hostname
- "134.138.177.24", %IP string
- {134,138,177,24}, %IP tuple
- ["isildur"], %Any aliases
- "::ffff:134.138.177.24", %IPv6 string (compatibilty addr)
- {0,0,0,0,0,65535,34442,45336} %IPv6 tuple
- }}.
-
-{test_host_ipv6_only,
- {"otptest06", %Short hostname
- "otptest06.du.uab.ericsson.se", %Long hostname
- "fec0::a00:20ff:feb2:b4a9", %IPv6 string
- {65216,0,0,0,2560,8447,65202,46249}, %IPv6 tuple
- ["otptest06-ip6"] %Aliases.
- }}.
-
-
-
-{test_dummy_host, {"dummy",
- "dummy.du.uab.ericsson.se",
- "192.138.177.1",
- {192,138,177,1},
- ["dummy"],
- "::ffff:192.138.177.1",
- {0,0,0,0,0,65535,49290,45313}
- }}.
-
-{test_dummy_ipv6_host, {"dummy6",
- "dummy6.du.uab.ericsson.se",
- "fec0::a00:20ff:feb2:6666",
- {65216,0,0,0,2560,8447,65202,26214},
- ["dummy6-ip6"]
- }}.
+%{test_host_ipv4_only,
+% {"my_ip4_host", %Short hostname
+% "my_ip4_host.mydomain.com", %Long hostname
+% "10.10.0.1", %IP string
+% {10,10,0,1}, %IP tuple
+% ["my_ip4_host"], %Any aliases
+% "::ffff:10.10.0.1", %IPv6 string (compatibilty addr)
+% {0,0,0,0,0,65535,2570,1} %IPv6 tuple
+% }}.
+
+%{test_dummy_host, {"dummy",
+% "dummy.mydomain.com",
+% "192.168.0.1",
+% {192,168,0,1},
+% ["dummy"],
+% "::ffff:192.168.0.1",
+% {0,0,0,0,0,65535,49320,1}
+% }}.
+
+
+%%% test_hosts are looked up using "ypmatch xx yy zz ipnodes.byname"
+%{ipv6_hosts,[my_ip6_host]}.
+
+
+%{test_host_ipv6_only,
+% {"my_ip6_host", %Short hostname
+% "my_ip6_host.mydomain.com", %Long hostname
+% "::2eff:f2b0:1ea0", %IPv6 string
+% {0,0,0,0,0,12031,62128,7840}, %IPv6 tuple
+% ["my_ip6_host"] %Aliases.
+% }}.
+
+%{test_dummy_ipv6_host, {"dummy6",
+% "dummy6.mydomain.com",
+% "127::1",
+% {295,0,0,0,0,0,0,1},
+% ["dummy6-ip6"]
+% }}.
diff --git a/lib/test_server/src/ts.erl b/lib/test_server/src/ts.erl
index fcd955345f..3d55f41b8c 100644
--- a/lib/test_server/src/ts.erl
+++ b/lib/test_server/src/ts.erl
@@ -150,6 +150,14 @@ help(installed) ->
" TraceSpec is the name of a file containing\n",
" trace specifications or a list of trace\n",
" specification elements.\n",
+ " {config, Path} - Specify which directory ts should get it's \n"
+ " config files from. The files should follow\n"
+ " the convention lib/test_server/src/ts*.config.\n"
+ " These config files can also be specified by\n"
+ " setting the TEST_CONFIG_PATH environment\n"
+ " variable to the directory where the config\n"
+ " files are. The default location is\n"
+ " tests/test_server/.\n"
"\n",
"Supported trace information elements\n",
" {tp | tpl, Mod, [] | match_spec()}\n",
@@ -249,7 +257,7 @@ run_some([Spec|Specs], Opts) ->
run(Testspec) when is_atom(Testspec) ->
Options=check_test_get_opts(Testspec, []),
File = atom_to_list(Testspec),
- run_test(File, ["SPEC current.spec NAME ",File], Options);
+ run_test(File, [{spec,[File++".spec"]}], Options);
%% This can be used from command line, e.g.
%% erl -s ts run all_tests <config>
@@ -293,11 +301,11 @@ run(List, Opts) when is_list(List), is_list(Opts) ->
run(Testspec, Config) when is_atom(Testspec), is_list(Config) ->
Options=check_test_get_opts(Testspec, Config),
File=atom_to_list(Testspec),
- run_test(File, ["SPEC current.spec NAME ", File], Options);
+ run_test(File, [{spec,[File++".spec"]}], Options);
%% Runs one module in a spec (interactive)
run(Testspec, Mod) when is_atom(Testspec), is_atom(Mod) ->
run_test({atom_to_list(Testspec), Mod},
- ["SPEC current.spec NAME ", atom_to_list(Mod)],
+ [{suite,Mod}],
[interactive]).
%% run/3
@@ -305,20 +313,23 @@ run(Testspec, Mod) when is_atom(Testspec), is_atom(Mod) ->
run(Testspec,Mod,Config) when is_atom(Testspec), is_atom(Mod), is_list(Config) ->
Options=check_test_get_opts(Testspec, Config),
run_test({atom_to_list(Testspec), Mod},
- ["SPEC current.spec NAME ", atom_to_list(Mod)],
+ [{suite,Mod}],
Options);
%% Runs one testcase in a module.
run(Testspec, Mod, Case) when is_atom(Testspec), is_atom(Mod), is_atom(Case) ->
Options=check_test_get_opts(Testspec, []),
- Args = ["CASE ",atom_to_list(Mod)," ",atom_to_list(Case)],
+ Args = [{suite,atom_to_list(Mod)},{testcase,atom_to_list(Case)}],
run_test(atom_to_list(Testspec), Args, Options).
%% run/4
%% Run one testcase in a module with Options.
-run(Testspec, Mod, Case, Config) when is_atom(Testspec), is_atom(Mod), is_atom(Case), is_list(Config) ->
+run(Testspec, Mod, Case, Config) when is_atom(Testspec),
+ is_atom(Mod),
+ is_atom(Case),
+ is_list(Config) ->
Options=check_test_get_opts(Testspec, Config),
- Args = ["CASE ",atom_to_list(Mod), " ",atom_to_list(Case)],
+ Args = [{suite,atom_to_list(Mod)}, {testcase,atom_to_list(Case)}],
run_test(atom_to_list(Testspec), Args, Options).
%% Check testspec to be valid and get possible Options
@@ -327,10 +338,11 @@ check_test_get_opts(Testspec, Config) ->
validate_test(Testspec),
Mode = configmember(batch, {batch, interactive}, Config),
Vars = configvars(Config),
- Trace = configtrace(Config),
+ Trace = get_config(trace,Config),
+ ConfigPath = get_config(config,Config),
KeepTopcase = configmember(keep_topcase, {keep_topcase,[]}, Config),
Cover = configcover(Testspec,Config),
- lists:flatten([Vars,Mode,Trace,KeepTopcase,Cover]).
+ lists:flatten([Vars,Mode,Trace,KeepTopcase,Cover,ConfigPath]).
to_erlang_term(Atom) ->
String = atom_to_list(Atom),
@@ -398,8 +410,8 @@ special_vars(Config) ->
SpecVars1
end.
-configtrace(Config) ->
- case lists:keysearch(trace,1,Config) of
+get_config(Key,Config) ->
+ case lists:keysearch(Key,1,Config) of
{value,Value} -> Value;
false -> []
end.
diff --git a/lib/test_server/src/ts.unix.config b/lib/test_server/src/ts.unix.config
index b4325f065f..5a2580f464 100644
--- a/lib/test_server/src/ts.unix.config
+++ b/lib/test_server/src/ts.unix.config
@@ -1,4 +1,4 @@
%% -*- erlang -*-
%% Always run a (VNC) X server on host
-{xserver, "frumgar.du.uab.ericsson.se:66"}.
+%% {xserver, "xserver.example.com:66"}.
diff --git a/lib/test_server/src/ts.vxworks.config b/lib/test_server/src/ts.vxworks.config
deleted file mode 100644
index b0b66e07ad..0000000000
--- a/lib/test_server/src/ts.vxworks.config
+++ /dev/null
@@ -1,19 +0,0 @@
-%% -*- erlang -*-
-
-%%% There is no equivalent command to ypmatch on Win32... :-(
-{hardcoded_hosts,
- [{"134.138.177.74","strider"},
- {"134.138.177.72", "elrond"},
- {"134.138.177.67", "sam"},
- {"134.138.176.215", "nenya"},
- {"134.138.176.192", "merry"},
- {"134.138.177.35", "lw4"},
- {"134.138.177.35", "lw5"},
- {"134.138.176.16", "super"},
- {"134.138.177.16", "gandalf"},
- {"134.138.177.92", "turin"},
- {"134.138.177.86", "mallor"}]}.
-
-{hardcoded_ipv6_hosts,
- [{"fe80::a00:20ff:feb2:b4a9","otptest06"},
- {"fe80::a00:20ff:feb2:a621","otptest08"}]}.
diff --git a/lib/test_server/src/ts.win32.config b/lib/test_server/src/ts.win32.config
index 2802c4a75a..cae587bea8 100644
--- a/lib/test_server/src/ts.win32.config
+++ b/lib/test_server/src/ts.win32.config
@@ -1,15 +1,8 @@
%% -*- erlang -*-
%%% There is no equivalent command to ypmatch on Win32... :-(
-{hardcoded_hosts,
- [{"134.138.177.24","isildur"},
- {"134.138.177.72", "elrond"},
- {"134.138.176.215", "nenya"},
- {"134.138.176.192", "merry"},
- {"134.138.176.16", "super"},
- {"134.138.177.16", "gandalf"},
- {"134.138.177.92", "turin"}]}.
+%{hardcoded_hosts,
+% [{"127.0.0.1","localhost"}]}.
-{hardcoded_ipv6_hosts,
- [{"fe80::a00:20ff:feb2:b4a9","otptest06"},
- {"fe80::a00:20ff:feb2:a621","otptest08"}]}.
+%{hardcoded_ipv6_hosts,
+% [{"::1","localhost"}]}.
diff --git a/lib/test_server/src/ts_install.erl b/lib/test_server/src/ts_install.erl
index bbbb7883db..2ddffccf5b 100644
--- a/lib/test_server/src/ts_install.erl
+++ b/lib/test_server/src/ts_install.erl
@@ -226,9 +226,11 @@ to_upper(String) ->
String).
word_size() ->
- case erlang:system_info(wordsize) of
- 4 -> "";
- 8 -> "/64"
+ case {erlang:system_info({wordsize,external}),
+ erlang:system_info({wordsize,internal})} of
+ {4,4} -> "";
+ {8,8} -> "/64";
+ {8,4} -> "/Halfword"
end.
linux_dist() ->
diff --git a/lib/test_server/src/ts_install_cth.erl b/lib/test_server/src/ts_install_cth.erl
new file mode 100644
index 0000000000..d1a24525ab
--- /dev/null
+++ b/lib/test_server/src/ts_install_cth.erl
@@ -0,0 +1,286 @@
+%%
+%% %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%
+%%
+
+%%% @doc TS Installed SCB
+%%%
+%%% This module does what the make parts of the ts:run/x command did,
+%%% but not the Makefile.first parts! So they have to be done by ts or
+%%% manually!!
+
+-module(ts_install_cth).
+
+%% Suite Callbacks
+-export([id/1]).
+-export([init/2]).
+
+-export([pre_init_per_suite/3]).
+-export([post_init_per_suite/4]).
+-export([pre_end_per_suite/3]).
+-export([post_end_per_suite/4]).
+
+-export([pre_init_per_group/3]).
+-export([post_init_per_group/4]).
+-export([pre_end_per_group/3]).
+-export([post_end_per_group/4]).
+
+-export([pre_init_per_testcase/3]).
+-export([post_end_per_testcase/4]).
+
+-export([on_tc_fail/3]).
+-export([on_tc_skip/3]).
+
+-export([terminate/1]).
+
+-include_lib("kernel/include/file.hrl").
+
+-type proplist() :: list({atom(),term()}).
+-type config() :: proplist().
+-type reason() :: term().
+-type skip_or_fail() :: {skip, reason()} |
+ {auto_skip, reason()} |
+ {fail, reason()}.
+
+-record(state, { ts_conf_dir, target_system, install_opts, nodenames, nodes }).
+
+%% @doc The id of this SCB
+-spec id(Opts :: term()) ->
+ Id :: term().
+id(_Opts) ->
+ ?MODULE.
+
+%% @doc Always called before any other callback function.
+-spec init(Id :: term(), Opts :: proplist()) ->
+ State :: #state{}.
+init(_Id, Opts) ->
+ Nodenames = proplists:get_value(nodenames, Opts, 0),
+ Nodes = proplists:get_value(nodes, Opts, 0),
+ TSConfDir = proplists:get_value(ts_conf_dir, Opts),
+ TargetSystem = proplists:get_value(target_system, Opts, install_local),
+ InstallOpts = proplists:get_value(install_opts, Opts, []),
+ #state{ nodenames = Nodenames,
+ nodes = Nodes,
+ ts_conf_dir = TSConfDir,
+ target_system = TargetSystem,
+ install_opts = InstallOpts }.
+
+%% @doc Called before init_per_suite is called.
+-spec pre_init_per_suite(Suite :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_per_suite(Suite,Config,#state{ ts_conf_dir = undefined} = State) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ ParentDir = filename:join(
+ lists:reverse(
+ tl(lists:reverse(filename:split(DataDir))))),
+ TSConfDir = filename:join([ParentDir, "..","test_server"]),
+ pre_init_per_suite(Suite, Config, State#state{ ts_conf_dir = TSConfDir });
+pre_init_per_suite(_Suite,Config,State) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ try
+ {ok,Variables} =
+ file:consult(filename:join(State#state.ts_conf_dir,"variables")),
+
+ %% Make the stuff in all_SUITE_data if it exists
+ AllDir = filename:join(DataDir,"../all_SUITE_data"),
+ case filelib:is_dir(AllDir) of
+ true ->
+ make_non_erlang(AllDir,Variables);
+ false ->
+ ok
+ end,
+
+ make_non_erlang(DataDir, Variables),
+
+ {add_node_name(Config, State), State}
+ catch Error:Reason ->
+ Stack = erlang:get_stacktrace(),
+ ct:pal("~p failed! ~p:{~p,~p}",[?MODULE,Error,Reason,Stack]),
+ {{fail,{?MODULE,{Error,Reason, Stack}}},State}
+ end.
+
+%% @doc Called after init_per_suite.
+-spec post_init_per_suite(Suite :: atom(),
+ Config :: config(),
+ Return :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+post_init_per_suite(_Suite,_Config,Return,State) ->
+ test_server_ctrl:kill_slavenodes(),
+ {Return, State}.
+
+%% @doc Called before end_per_suite.
+-spec pre_end_per_suite(Suite :: atom(),
+ Config :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+pre_end_per_suite(_Suite,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after end_per_suite.
+-spec post_end_per_suite(Suite :: atom(),
+ Config :: config(),
+ Return :: term(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_per_suite(_Suite,_Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called before each init_per_group.
+-spec pre_init_per_group(Group :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_per_group(_Group,Config,State) ->
+ {add_node_name(Config, State), State}.
+
+%% @doc Called after each init_per_group.
+-spec post_init_per_group(Group :: atom(),
+ Config :: config(),
+ Return :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+post_init_per_group(_Group,_Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called after each end_per_group.
+-spec pre_end_per_group(Group :: atom(),
+ Config :: config() | skip_or_fail(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+pre_end_per_group(_Group,Config,State) ->
+ {Config, State}.
+
+%% @doc Called after each end_per_group.
+-spec post_end_per_group(Group :: atom(),
+ Config :: config(),
+ Return :: term(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_per_group(_Group,_Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called before each test case.
+-spec pre_init_per_testcase(TC :: atom(),
+ Config :: config(),
+ State :: #state{}) ->
+ {config() | skip_or_fail(), NewState :: #state{}}.
+pre_init_per_testcase(_TC,Config,State) ->
+ {add_node_name(Config, State), State}.
+
+%% @doc Called after each test case.
+-spec post_end_per_testcase(TC :: atom(),
+ Config :: config(),
+ Return :: term(),
+ State :: #state{}) ->
+ {ok | skip_or_fail(), NewState :: #state{}}.
+post_end_per_testcase(_TC,_Config,Return,State) ->
+ {Return, State}.
+
+%% @doc Called after a test case failed.
+-spec on_tc_fail(TC :: init_per_suite | end_per_suite |
+ init_per_group | end_per_group | atom(),
+ Reason :: term(), State :: #state{}) ->
+ NewState :: #state{}.
+on_tc_fail(_TC, _Reason, State) ->
+ State.
+
+%% @doc Called when a test case is skipped.
+-spec on_tc_skip(TC :: end_per_suite | init_per_group | end_per_group | atom(),
+ {tc_auto_skip, {failed, {Mod :: atom(), Function :: atom(),
+ Reason :: term()}}} |
+ {tc_user_skip, {skipped, Reason :: term()}},
+ State :: #state{}) ->
+ NewState :: #state{}.
+on_tc_skip(_TC, _Reason, State) ->
+ State.
+
+%% @doc Called when the scope of the SCB is done.
+-spec terminate(State :: #state{}) ->
+ term().
+terminate(_State) ->
+ ok.
+
+%%% ============================================================================
+%%% Local functions
+%%% ============================================================================
+%% Configure and run all the Makefiles in the data dirs of the suite
+%% in question
+make_non_erlang(DataDir, Variables) ->
+ {ok,CurrWD} = file:get_cwd(),
+ try
+ file:set_cwd(DataDir),
+ MakeCommand = proplists:get_value(make_command,Variables),
+
+ FirstMakefile = filename:join(DataDir,"Makefile.first"),
+ case filelib:is_regular(FirstMakefile) of
+ true ->
+ ct:log("Making ~p",[FirstMakefile]),
+ ok = ts_make:make(
+ MakeCommand, DataDir, filename:basename(FirstMakefile));
+ false ->
+ ok
+ end,
+
+ MakefileSrc = filename:join(DataDir,"Makefile.src"),
+ MakefileDest = filename:join(DataDir,"Makefile"),
+ case filelib:is_regular(MakefileSrc) of
+ true ->
+ ok = ts_lib:subst_file(MakefileSrc,MakefileDest,Variables),
+ ct:log("Making ~p",[MakefileDest]),
+ ok = ts_make:make([{makefile,"Makefile"},{data_dir,DataDir}
+ | Variables]);
+ false ->
+ ok
+ end
+ after
+ file:set_cwd(CurrWD),
+ timer:sleep(100)
+ end.
+
+%% Add a nodename to config if it does not exist
+add_node_name(Config, State) ->
+ case proplists:get_value(nodenames, Config) of
+ undefined ->
+ lists:keystore(
+ nodenames, 1, Config,
+ {nodenames,generate_nodenames(State#state.nodenames)});
+ _Else ->
+ Config
+ end.
+
+
+%% Copied from test_server_ctrl.erl
+generate_nodenames(Num) ->
+ {ok,Name} = inet:gethostname(),
+ generate_nodenames2(Num, [Name], []).
+
+generate_nodenames2(0, _Hosts, Acc) ->
+ Acc;
+generate_nodenames2(N, Hosts, Acc) ->
+ Host=lists:nth((N rem (length(Hosts)))+1, Hosts),
+ Name=list_to_atom(temp_nodename("nod", []) ++ "@" ++ Host),
+ generate_nodenames2(N-1, Hosts, [Name|Acc]).
+
+temp_nodename([], Acc) ->
+ lists:flatten(Acc);
+temp_nodename([Chr|Base], Acc) ->
+ {A,B,C} = erlang:now(),
+ New = [Chr | integer_to_list(Chr bxor A bxor B+A bxor C+B)],
+ temp_nodename(Base, [New|Acc]).
diff --git a/lib/test_server/src/ts_run.erl b/lib/test_server/src/ts_run.erl
index 888ac98973..d572b1454c 100644
--- a/lib/test_server/src/ts_run.erl
+++ b/lib/test_server/src/ts_run.erl
@@ -28,7 +28,7 @@
-include("ts.hrl").
--import(lists, [map/2,member/2,filter/2,reverse/1]).
+-import(lists, [member/2,filter/2]).
-record(state,
{file, % File given.
@@ -63,50 +63,18 @@ run(File, Args0, Options, Vars0) ->
_ ->
{false, fun run_interactive/3}
end,
- HandleTopcase = case member(keep_topcase, Options) of
- true -> [fun copy_topcase/3];
- false -> [fun remove_original_topcase/3,
- fun init_topcase/3]
- end,
- MakefileHooks = [fun make_make/3,
- fun add_make_testcase/3],
- MakeLoop = fun(V, Sp, St) -> make_loop(MakefileHooks, V, Sp, St) end,
Hooks = [fun init_state/3,
- fun read_spec_file/3] ++
- HandleTopcase ++
- [fun run_preinits/3,
- fun find_makefiles/3,
- MakeLoop,
- fun make_test_suite/3,
- fun add_topcase_to_spec/3,
- fun write_spec_file/3,
+ fun run_preinits/3,
fun make_command/3,
Runner],
- Args = make_test_server_args(Args0,Options,Vars),
+ Args = make_common_test_args(Args0,Options,Vars),
St = #state{file=File,test_server_args=Args,batch=Batch},
R = execute(Hooks, Vars, [], St),
- case Batch of
- true -> ts_reports:make_index();
- false -> ok % ts_reports:make_index() is run on the test_server node
- end,
case R of
{ok,_,_,_} -> ok;
Error -> Error
end.
-make_loop(Hooks, Vars0, Spec0, St0) ->
- case St0#state.makefiles of
- [Makefile|Rest] ->
- case execute(Hooks, Vars0, Spec0, St0#state{makefile=Makefile}) of
- {error, Reason} ->
- {error, Reason};
- {ok, Vars, Spec, St} ->
- make_loop(Hooks, Vars, Spec, St#state{makefiles=Rest})
- end;
- [] ->
- {ok, Vars0, Spec0, St0}
- end.
-
execute([Hook|Rest], Vars0, Spec0, St0) ->
case Hook(Vars0, Spec0, St0) of
ok ->
@@ -156,101 +124,6 @@ init_state(Vars, [], St0) ->
false ->
{error,{no_test_directory,TestDir}}
end.
-
-%% Read the spec file for the test suite.
-
-read_spec_file(Vars, _, St) ->
- TestDir = St#state.test_dir,
- File = St#state.file,
- {SpecFile,Res} = get_spec_filename(Vars, TestDir, File),
- case Res of
- {ok,Spec} ->
- {ok,Vars,Spec,St};
- {error,Atom} when is_atom(Atom) ->
- {error,{no_spec,SpecFile}};
- {error,Reason} ->
- {error,{bad_spec,lists:flatten(file:format_error(Reason))}}
- end.
-
-get_spec_filename(Vars, TestDir, File) ->
- DynSpec = filename:join(TestDir, File ++ ".dynspec"),
- case filelib:is_file(DynSpec) of
- true ->
- Bs0 = erl_eval:new_bindings(),
- Bs1 = erl_eval:add_binding('Target', ts_lib:var(target, Vars), Bs0),
- Bs2 = erl_eval:add_binding('Os', ts_lib:var(os, Vars), Bs1),
- TCCStr = ts_lib:var(test_c_compiler, Vars),
- TCC = try
- {ok, Toks, _} = erl_scan:string(TCCStr ++ "."),
- {ok, Tcc} = erl_parse:parse_term(Toks),
- Tcc
- catch
- _:_ -> undefined
- end,
- Bs = erl_eval:add_binding('TestCCompiler', TCC, Bs2),
- {DynSpec,file:script(DynSpec, Bs)};
- false ->
- SpecFile = get_spec_filename_1(Vars, TestDir, File),
- {SpecFile,file:consult(SpecFile)}
- end.
-
-get_spec_filename_1(Vars, TestDir, File) ->
- case ts_lib:var(os, Vars) of
- "VxWorks" ->
- check_spec_filename(TestDir, File, ".spec.vxworks");
- "Windows"++_ ->
- check_spec_filename(TestDir, File, ".spec.win");
- _Other ->
- filename:join(TestDir, File ++ ".spec")
- end.
-
-check_spec_filename(TestDir, File, Ext) ->
- Spec = filename:join(TestDir, File ++ Ext),
- case filelib:is_file(Spec) of
- true -> Spec;
- false -> filename:join(TestDir, File ++ ".spec")
- end.
-
-%% Remove the top case from the spec file. We will add our own
-%% top case later.
-
-remove_original_topcase(Vars, Spec, St) ->
- {ok,Vars,filter(fun ({topcase,_}) -> false;
- (_Other) -> true end, Spec),St}.
-
-%% Initialize our new top case. We'll keep in it the state to be
-%% able to add more to it.
-
-init_topcase(Vars, Spec, St) ->
- TestDir = St#state.test_dir,
- TopCase =
- case St#state.mod of
- Mod when is_atom(Mod) ->
- ModStr = atom_to_list(Mod),
- case filelib:is_file(filename:join(TestDir,ModStr++".erl")) of
- true -> [{Mod,all}];
- false ->
- Wc = filename:join(TestDir, ModStr ++ "*_SUITE.erl"),
- [{list_to_atom(filename:basename(M, ".erl")),all} ||
- M <- filelib:wildcard(Wc)]
- end;
- _Other ->
- %% Here we used to return {dir,TestDir}. Now we instead
- %% list all suites in TestDir, so we can add make testcases
- %% around it later (see add_make_testcase) without getting
- %% duplicates of the suite. (test_server_ctrl does no longer
- %% check for duplicates of testcases)
- Wc = filename:join(TestDir, "*_SUITE.erl"),
- [{list_to_atom(filename:basename(M, ".erl")),all} ||
- M <- filelib:wildcard(Wc)]
- end,
- {ok,Vars,Spec,St#state{topcase=TopCase}}.
-
-%% Or if option keep_topcase was given, eh... keep the topcase
-copy_topcase(Vars, Spec, St) ->
- {value,{topcase,Tc}} = lists:keysearch(topcase,1,Spec),
- {ok, Vars, lists:keydelete(topcase,1,Spec),St#state{topcase=Tc}}.
-
%% Run any "Makefile.first" files first.
%% XXX We should fake a failing test case if the make fails.
@@ -279,171 +152,14 @@ run_pre_makefile(Vars, Spec, St) ->
{error,_Reason}=Error -> Error
end.
-%% Search for `Makefile.src' in each *_SUITE_data directory.
-
-find_makefiles(Vars, Spec, St) ->
- Wc = filename:join(St#state.data_wc, "Makefile.src"),
- Makefiles = reverse(del_skipped_suite_data_dir(filelib:wildcard(Wc), Spec)),
- {ok,Vars,Spec,St#state{makefiles=Makefiles}}.
-
-%% Create "Makefile" from "Makefile.src".
-
-make_make(Vars, Spec, State) ->
- Src = State#state.makefile,
- Dest = filename:rootname(Src),
- ts_lib:progress(Vars, 1, "Making ~s...\n", [Dest]),
- case ts_lib:subst_file(Src, Dest, Vars) of
- ok ->
- {ok, Vars, Spec, State#state{makefile=Dest}};
- {error, Reason} ->
- {error, {Src, Reason}}
- end.
-
-%% Add a testcase which will do the making of the stuff in the data directory.
-
-add_make_testcase(Vars, Spec, St) ->
- Makefile = St#state.makefile,
- Dir = filename:dirname(Makefile),
- Shortname = filename:basename(Makefile),
- Suite = filename:basename(Dir, "_data"),
- Config = [{data_dir,Dir},{makefile,Shortname}],
- MakeModule = Suite ++ "_make",
- MakeModuleSrc = filename:join(filename:dirname(Dir),
- MakeModule ++ ".erl"),
- MakeMod = list_to_atom(MakeModule),
- case filelib:is_file(MakeModuleSrc) of
- true -> ok;
- false -> generate_make_module(ts_lib:var(make_command, Vars),
- MakeModuleSrc,
- MakeModule)
- end,
- case Suite of
- "all_SUITE" ->
- {ok,Vars,Spec,St#state{all={MakeMod,Config}}};
- _ ->
- %% Avoid duplicates of testcases. There is no longer
- %% a check for this in test_server_ctrl.
- TestCase = {list_to_atom(Suite),all},
- TopCase0 = case St#state.topcase of
- List when is_list(List) ->
- List -- [TestCase];
- Top ->
- [Top] -- [TestCase]
- end,
- TopCase = [{make,{MakeMod,make,[Config]},
- TestCase,
- {MakeMod,unmake,[Config]}}|TopCase0],
- {ok,Vars,Spec,St#state{topcase=TopCase}}
- end.
-
-generate_make_module(MakeCmd, Name, ModuleString) ->
- {ok,Host} = inet:gethostname(),
- file:write_file(Name,
- ["-module(",ModuleString,").\n",
- "\n",
- "-export([make/1,unmake/1]).\n",
- "\n",
- "make(Config) when is_list(Config) ->\n",
- " Mins = " ++ integer_to_list(?DEFAULT_MAKE_TIMETRAP_MINUTES) ++ ",\n"
- " test_server:format(\"=== Setting timetrap to ~p minutes ===~n\", [Mins]),\n"
- " TimeTrap = test_server:timetrap(test_server:minutes(Mins)),\n"
- " Res = ts_make:make([{make_command, \""++MakeCmd++"\"},{cross_node,\'ts@" ++ Host ++ "\'}|Config]),\n",
- " test_server:timetrap_cancel(TimeTrap),\n"
- " Res.\n"
- "\n",
- "unmake(Config) when is_list(Config) ->\n",
- " Mins = " ++ integer_to_list(?DEFAULT_UNMAKE_TIMETRAP_MINUTES) ++ ",\n"
- " test_server:format(\"=== Setting timetrap to ~p minutes ===~n\", [Mins]),\n"
- " TimeTrap = test_server:timetrap(test_server:minutes(Mins)),\n"
- " Res = ts_make:unmake([{make_command, \""++MakeCmd++"\"}|Config]),\n"
- " test_server:timetrap_cancel(TimeTrap),\n"
- " Res.\n"
- "\n"]).
-
-
-make_test_suite(Vars, _Spec, State) ->
- TestDir = State#state.test_dir,
-
- Erl_flags=[{i, "../test_server"}|ts_lib:var(erl_flags,Vars)],
-
- case code:is_loaded(test_server_line) of
- false -> code:load_file(test_server_line);
- _ -> ok
- end,
-
- {ok, Cwd} = file:get_cwd(),
- ok = file:set_cwd(TestDir),
- Result = (catch make_all(Erl_flags)),
- ok = file:set_cwd(Cwd),
- case Result of
- up_to_date ->
- ok;
- {'EXIT', Reason} ->
- %% If I return an error here, the test will be stopped
- %% and it will not show up in the top index page. Instead
- %% I return ok - the test will run for all existing suites.
- %% It might be that there are old suites that are run, but
- %% at least one suite is missing, and that is reported on the
- %% top index page.
- io:format("~s: {error,{make_crashed,~p}\n",
- [State#state.file,Reason]),
- ok;
- error ->
- %% See comment above
- io:format("~s: {error,make_of_test_suite_failed}\n",
- [State#state.file]),
- ok
- end.
-
-%% Add topcase to spec.
-
-add_topcase_to_spec(Vars, Spec, St) ->
- Tc = case St#state.all of
- {MakeMod,Config} ->
- [{make,{MakeMod,make,[Config]},
- St#state.topcase,
- {MakeMod,unmake,[Config]}}];
- undefined -> St#state.topcase
- end,
- {ok,Vars,Spec++[{topcase,Tc}],St}.
-
-%% Writes the (possibly transformed) spec file.
-
-write_spec_file(Vars, Spec, _State) ->
- F = fun(Term) -> io_lib:format("~p.~n", [Term]) end,
- SpecFile = map(F, Spec),
- Hosts =
- case lists:keysearch(hosts, 1, Vars) of
- false ->
- [];
- {value, {hosts, HostList}} ->
- io_lib:format("{hosts,~p}.~n",[HostList])
- end,
- DiskLess =
- case lists:keysearch(diskless, 1, Vars) of
- false ->
- [];
- {value, {diskless, How}} ->
- io_lib:format("{diskless, ~p}.~n",[How])
- end,
- Conf = consult_config(),
- MoreConfig = io_lib:format("~p.\n", [{config,Conf}]),
- file:write_file("current.spec", [DiskLess,Hosts,MoreConfig,SpecFile]).
-
-consult_config() ->
- {ok,Conf} = file:consult("ts.config"),
- case os:type() of
- {unix,_} -> consult_config("ts.unix.config", Conf);
- {win32,_} -> consult_config("ts.win32.config", Conf);
- vxworks -> consult_config("ts.vxworks.config", Conf);
- _ -> Conf
- end.
-
-consult_config(File, Conf0) ->
- case file:consult(File) of
- {ok,Conf} -> Conf++Conf0;
- {error,enoent} -> Conf0
- end.
+get_config_files() ->
+ TSConfig = "ts.config",
+ [TSConfig | case os:type() of
+ {unix,_} -> ["ts.unix.config"];
+ {win32,_} -> ["ts.win32.config"];
+ vxworks -> ["ts.vxworks.config"];
+ _ -> []
+ end].
%% Makes the command to start up the Erlang node to run the tests.
@@ -457,6 +173,7 @@ backslashify([]) ->
[].
make_command(Vars, Spec, State) ->
+ {ok,Cwd} = file:get_cwd(),
TestDir = State#state.test_dir,
TestPath = filename:nativename(TestDir),
Erl = case os:getenv("TS_RUN_VALGRIND") of
@@ -487,7 +204,7 @@ make_command(Vars, Spec, State) ->
{value,{erl_start_args,Args}} -> Args;
false -> ""
end,
- CrashFile = State#state.file ++ "_erl_crash.dump",
+ CrashFile = filename:join(Cwd,State#state.file ++ "_erl_crash.dump"),
case filelib:is_file(CrashFile) of
true ->
io:format("ts_run: Deleting dump: ~s\n",[CrashFile]),
@@ -495,7 +212,8 @@ make_command(Vars, Spec, State) ->
false ->
ok
end,
- Cmd = [Erl, Naming, "test_server -pa ", $", TestPath, $",
+ %% NOTE: Do not use ' in these commands as it wont work on windows
+ Cmd = [Erl, Naming, "test_server"
" -rsh ", ts_lib:var(rsh_name, Vars),
" -env PATH \"",
backslashify(lists:flatten([TestPath, path_separator(),
@@ -505,15 +223,20 @@ make_command(Vars, Spec, State) ->
%% uncomment the line below to disable exception formatting
%% " -test_server_format_exception false",
" -boot start_sasl -sasl errlog_type error",
- " -s test_server_ctrl run_test ", State#state.test_server_args,
+ " -pz ",Cwd,
+ " -eval \"file:set_cwd(\\\"",TestDir,"\\\")\" "
+ " -eval \"ct:run_test(",
+ backslashify(lists:flatten(State#state.test_server_args)),")\""
" ",
ExtraArgs],
{ok, Vars, Spec, State#state{command=lists:flatten(Cmd)}}.
+
run_batch(Vars, _Spec, State) ->
process_flag(trap_exit, true),
Command = State#state.command ++ " -noinput -s erlang halt",
ts_lib:progress(Vars, 1, "Command: ~s~n", [Command]),
+ io:format(user, "Command: ~s~n",[Command]),
Port = open_port({spawn, Command}, [stream, in, eof]),
tricky_print_data(Port).
@@ -554,7 +277,7 @@ is_testnode_dead([{"test_server",_}|_]) -> false;
is_testnode_dead([_|T]) -> is_testnode_dead(T).
run_interactive(Vars, _Spec, State) ->
- Command = State#state.command ++ " -s ts_reports make_index",
+ Command = State#state.command,
ts_lib:progress(Vars, 1, "Command: ~s~n", [Command]),
case ts_lib:var(os, Vars) of
"Windows 95" ->
@@ -604,77 +327,57 @@ path_separator() ->
end.
-make_test_server_args(Args0,Options,Vars) ->
- Parameters =
- case ts_lib:var(os, Vars) of
- "VxWorks" ->
- F = write_parameterfile(vxworks,Vars),
- " PARAMETERS " ++ F;
- _ ->
- ""
- end,
+make_common_test_args(Args0, Options, _Vars) ->
Trace =
case lists:keysearch(trace,1,Options) of
{value,{trace,TI}} when is_tuple(TI); is_tuple(hd(TI)) ->
ok = file:write_file(?tracefile,io_lib:format("~p.~n",[TI])),
- " TRACE " ++ ?tracefile;
+ [{ct_trace,?tracefile}];
{value,{trace,TIFile}} when is_atom(TIFile) ->
- " TRACE " ++ atom_to_list(TIFile);
+ [{ct_trace,atom_to_list(TIFile)}];
{value,{trace,TIFile}} ->
- " TRACE " ++ TIFile;
+ [{ct_trace,TIFile}];
false ->
- ""
+ []
end,
Cover =
case lists:keysearch(cover,1,Options) of
- {value,{cover,App,File,Analyse}} ->
- " COVER " ++ to_list(App) ++ " " ++ to_list(File) ++ " " ++
- to_list(Analyse);
+ {value,{cover, App, none, _Analyse}} ->
+ io:format("No cover file found for ~p~n",[App]),
+ [];
+ {value,{cover,_App,File,_Analyse}} ->
+ [{cover,to_list(File)}];
false ->
- ""
- end,
- TCCallback =
- case ts_lib:var(ts_testcase_callback, Vars) of
- "" ->
- "";
- {Mod,Func} ->
- io:format("Function ~w:~w/4 will be called before and "
- "after each test case.\n", [Mod,Func]),
- " TESTCASE_CALLBACK " ++ to_list(Mod) ++ " " ++ to_list(Func);
- ModFunc when is_list(ModFunc) ->
- [Mod,Func]=string:tokens(ModFunc," "),
- io:format("Function ~s:~s/4 will be called before and "
- "after each test case.\n", [Mod,Func]),
- " TESTCASE_CALLBACK " ++ ModFunc;
- _ ->
- ""
+ []
end,
- Args0 ++ Parameters ++ Trace ++ Cover ++ TCCallback.
+
+ Logdir = case lists:keysearch(logdir, 1, Options) of
+ {value,{logdir, _}} ->
+ [];
+ false ->
+ [{logdir,"../test_server"}]
+ end,
+
+ ConfigPath = case {os:getenv("TEST_CONFIG_PATH"),
+ lists:keysearch(config, 1, Options)} of
+ {false,{value, {config, Path}}} ->
+ Path;
+ {false,false} ->
+ "../test_server";
+ {Path,_} ->
+ Path
+ end,
+ ConfigFiles = [{config,[filename:join(ConfigPath,File)
+ || File <- get_config_files()]}],
+
+ io_lib:format("~100000p",[Args0++Trace++Cover++Logdir++
+ ConfigFiles++Options]).
to_list(X) when is_atom(X) ->
atom_to_list(X);
to_list(X) when is_list(X) ->
X.
-write_parameterfile(Type,Vars) ->
- Cross_host = ts_lib:var(target_host, Vars),
- SlaveTargets = case lists:keysearch(slavetargets,1,Vars) of
- {value, ST} ->
- [ST];
- _ ->
- []
- end,
- Master = case lists:keysearch(master,1,Vars) of
- {value,M} -> [M];
- false -> []
- end,
- ToWrite = [{type,Type},
- {target, list_to_atom(Cross_host)}] ++ SlaveTargets ++ Master,
-
- Crossfile = atom_to_list(Type) ++ "parameters" ++ os:getpid(),
- ok = file:write_file(Crossfile,io_lib:format("~p.~n", [ToWrite])),
- Crossfile.
-
%%
%% Paths and spaces handling for w2k and XP
%%
@@ -720,53 +423,3 @@ split_one(Path) ->
split_path(Path) ->
string:tokens(Path,";").
-
-%%
-%% Run make:all/1 if the test suite seems to be designed
-%% to be built/re-built by ts.
-%%
-make_all(Flags) ->
- case filelib:is_regular("Emakefile") of
- false ->
- make_all_no_emakefile(Flags);
- true ->
- make:all(Flags)
- end.
-
-make_all_no_emakefile(Flags) ->
- case filelib:wildcard("*.beam") of
- [] ->
- %% Since there are no *.beam files, we will assume
- %% that this test suite was designed to be built and
- %% re-built by ts. Create an Emakefile so that
- %% make:all/1 will be run the next time too
- %% (in case a test suite is being interactively
- %% developed).
- create_emakefile(Flags, "*.erl");
- [_|_] ->
- %% There is no Emakefile and there already are
- %% some *.beam files here. Assume that this test
- %% suite was not designed to be re-built by ts.
- %% Only create a Emakefile that will compile
- %% generated *_SUITE_make files (if any).
- create_emakefile(Flags, "*_SUITE_make.erl")
- end.
-
-create_emakefile(Flags, Wc) ->
- case filelib:wildcard(Wc) of
- [] ->
- %% There are no files to be built (i.e. not even any
- %% generated *_SUITE_make.erl files). We must handle
- %% this case specially, because make:all/1 will crash
- %% on Emakefile with an empty list of modules.
- io:put_chars("No Emakefile found - not running make:all/1\n"),
- up_to_date;
- [_|_]=Ms0 ->
- io:format("Creating an Emakefile for compiling files matching ~s\n",
- [Wc]),
- Ms = [list_to_atom(filename:rootname(M, ".erl")) || M <- Ms0],
- Make0 = {Ms,Flags},
- Make = io_lib:format("~p. \n", [Make0]),
- ok = file:write_file("Emakefile", Make),
- make:all(Flags)
- end.
diff --git a/lib/test_server/test/Makefile b/lib/test_server/test/Makefile
index fcb1282d16..0648c1f96a 100644
--- a/lib/test_server/test/Makefile
+++ b/lib/test_server/test/Makefile
@@ -27,11 +27,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
MODULES= \
test_server_SUITE \
test_server_line_SUITE \
- test_server_skip_SUITE \
- test_server_conf01_SUITE \
- test_server_conf02_SUITE \
- test_server_parallel01_SUITE \
- test_server_shuffle01_SUITE
+ test_server_test_lib
ERL_FILES= $(MODULES:%=%.erl)
@@ -52,6 +48,7 @@ RELSYSDIR = $(RELEASE_PATH)/test_server_test
ERL_MAKE_FLAGS += -pa $(ERL_TOP)/lib/test_server/ebin
ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/test
EBIN = .
@@ -88,7 +85,7 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(COVERFILE) $(RELSYSDIR)
- $(INSTALL_DATA) test_server.spec $(RELSYSDIR)
+ $(INSTALL_DATA) test_server.spec test_server.cover $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/test_server/test/test_server.cover b/lib/test_server/test/test_server.cover
index c2366db166..5c59bab494 100644
--- a/lib/test_server/test/test_server.cover
+++ b/lib/test_server/test/test_server.cover
@@ -1,20 +1,22 @@
-{exclude,[test_server,
- test_server_ctrl,
- ts_selftest]}.
+{incl_app,test_server,details}.
-%% Using include list here because the test_server might not find
+{excl_mods, test_server, [test_server,
+ test_server_ctrl,
+ ts_selftest]}.
+
+%% Using incl_mods list here because the test_server might not find
%% lib_dir for test_server - and so it will not find which modules to
%% compile.
-{include,[erl2html2,
- test_server_node,
- test_server_sup,
- ts,
- ts_autoconf_vxworks,
- ts_autoconf_win32,
- ts_erl_config,
- ts_install,
- ts_lib,
- ts_make,
- ts_run,
- vxworks_client]}.
+{incl_mods, test_server, [erl2html2,
+ test_server_node,
+ test_server_sup,
+ ts,
+ ts_autoconf_vxworks,
+ ts_autoconf_win32,
+ ts_erl_config,
+ ts_install,
+ ts_lib,
+ ts_make,
+ ts_run,
+ vxworks_client]}.
diff --git a/lib/test_server/test/test_server.spec b/lib/test_server/test/test_server.spec
index 23b0b71963..a3b4d01d08 100644
--- a/lib/test_server/test/test_server.spec
+++ b/lib/test_server/test/test_server.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../test_server_test"}}.
-{skip,{test_server_SUITE,skip_case7,"This case should be noted as `Skipped'"}}.
+{suites, "../test_server_test", all}.
diff --git a/lib/test_server/test/test_server_SUITE.erl b/lib/test_server/test/test_server_SUITE.erl
index 0563e1104f..f4c19eeaf9 100644
--- a/lib/test_server/test/test_server_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% 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
@@ -16,539 +16,149 @@
%%
%% %CopyrightEnd%
%%
-
-%%%------------------------------------------------------------------
-%%% Test Server self test.
-%%%------------------------------------------------------------------
+%%%-------------------------------------------------------------------
+%%% @author Lukas Larsson <[email protected]>
+%%% @copyright (C) 2011, Erlang Solutions Ltd.
+%%% @doc
+%%%
+%%% @end
+%%% Created : 15 Feb 2011 by Lukas Larsson <[email protected]>
+%%%-------------------------------------------------------------------
-module(test_server_SUITE).
--include_lib("test_server/include/test_server.hrl").
--include_lib("test_server/include/test_server_line.hrl").
--include_lib("kernel/include/file.hrl").
--export([all/1]).
--export([init_per_suite/1, end_per_suite/1]).
--export([init_per_testcase/2, end_per_testcase/2, fin_per_testcase/2]).
--export([config/1, comment/1, timetrap/1, timetrap_cancel/1, multiply_timetrap/1,
- init_per_s/1, init_per_tc/1, end_per_tc/1,
- timeconv/1, msgs/1, capture/1, timecall/1,
- do_times/1, do_times_mfa/1, do_times_fun/1,
- skip_cases/1, skip_case1/1, skip_case2/1, skip_case3/1,
- skip_case4/1, skip_case5/1, skip_case6/1, skip_case7/1,
- skip_case8/1, skip_case9/1, undefined_functions/1,
- conf_init/1, check_new_conf/1, conf_cleanup/1,
- check_old_conf/1, conf_init_fail/1, start_stop_node/1,
- cleanup_nodes_init/1, check_survive_nodes/1, cleanup_nodes_fin/1,
- commercial/1]).
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include("test_server_test_lib.hrl").
--export([dummy_function/0,dummy_function/1,doer/1]).
+%%--------------------------------------------------------------------
+%% COMMON TEST CALLBACK FUNCTIONS
+%%--------------------------------------------------------------------
-all(doc) -> ["Test Server self test"];
-all(suite) ->
- [config, comment, timetrap, timetrap_cancel, multiply_timetrap,
- init_per_s, init_per_tc, end_per_tc,
- timeconv, msgs, capture, timecall, do_times, skip_cases,
- undefined_functions, commercial,
- {conf, conf_init, [check_new_conf], conf_cleanup},
- check_old_conf,
- {conf, conf_init_fail,[conf_member_skip],conf_cleanup_skip},
- start_stop_node,
- {conf, cleanup_nodes_init,[check_survive_nodes],cleanup_nodes_fin},
- config
- ].
+%% @spec suite() -> Info
+suite() ->
+ [{ct_hooks,[ts_install_cth,test_server_test_lib]}].
+%% @spec init_per_suite(Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
init_per_suite(Config) ->
- [{init_per_suite_var,ok}|Config].
+ [{path_dirs,[proplists:get_value(data_dir,Config)]} | Config].
+%% @spec end_per_suite(Config) -> _
end_per_suite(_Config) ->
- ok.
-
-init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
- Dog = ?t:timetrap(?t:minutes(2)),
- Config1 = [{watchdog, Dog}|Config],
- case Func of
- init_per_tc ->
- [{strange_var, 1}|Config1];
- skip_case8 ->
- {skipped, "This case should be noted as `Skipped'"};
- skip_case9 ->
- {skip, "This case should be noted as `Skipped'"};
- _ ->
- Config1
- end;
-init_per_testcase(Func, Config) ->
- io:format("Func:~p",[Func]),
- io:format("Config:~p",[Config]),
- ?t:fail("Arguments to init_per_testcase not correct").
-
-end_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
- Dog=?config(watchdog, Config),
- ?t:timetrap_cancel(Dog),
- case Func of
- end_per_tc -> io:format("CLEANUP => this test case is ok\n");
- _Other -> ok
- end;
-end_per_testcase(Func, Config) ->
- io:format("Func:~p",[Func]),
- io:format("Config:~p",[Config]),
- ?t:fail("Arguments to end_per_testcase not correct").
-
-fin_per_testcase(Func, Config) ->
- io:format("Func:~p",[Func]),
- io:format("Config:~p",[Config]),
- ?t:fail("fin_per_testcase/2 called, should have called end_per_testcase/2").
+ io:format("TEST_SERVER_FRAMEWORK: ~p",[os:getenv("TEST_SERVER_FRAMEWORK")]),
+ ok.
+
+%% @spec init_per_group(GroupName, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+init_per_group(_GroupName, Config) ->
+ Config.
+
+%% @spec end_per_group(GroupName, Config0) ->
+%% void() | {save_config,Config1}
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+%% @spec init_per_testcase(TestCase, Config0) ->
+%% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1}
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+%% @spec end_per_testcase(TestCase, Config0) ->
+%% void() | {save_config,Config1} | {fail,Reason}
+end_per_testcase(_TestCase, _Config) ->
+ ok.
+
+%% @spec: groups() -> [Group]
+groups() ->
+ [].
+
+%% @spec all() -> GroupsAndTestCases | {skip,Reason}
+all() ->
+ [test_server_SUITE, test_server_parallel01_SUITE,
+ test_server_conf02_SUITE, test_server_conf01_SUITE,
+ test_server_skip_SUITE, test_server_shuffle01_SUITE].
+
+
+%%--------------------------------------------------------------------
+%% TEST CASES
+%%--------------------------------------------------------------------
+%% @spec TestCase(Config0) ->
+%% ok | exit() | {skip,Reason} | {comment,Comment} |
+%% {save_config,Config1} | {skip_and_save,Reason,Config1}
+test_server_SUITE(Config) ->
+% rpc:call(Node,dbg, tracer,[]),
+% rpc:call(Node,dbg, p,[all,c]),
+% rpc:call(Node,dbg, tpl,[test_server_ctrl,x]),
+ run_test_server_tests("test_server_SUITE", 39, 1, 31,
+ 20, 9, 1, 11, 2, 26, Config).
+
+test_server_parallel01_SUITE(Config) ->
+ run_test_server_tests("test_server_parallel01_SUITE", 37, 0, 19,
+ 19, 0, 0, 0, 0, 37, Config).
+
+test_server_shuffle01_SUITE(Config) ->
+ run_test_server_tests("test_server_shuffle01_SUITE", 130, 0, 0,
+ 76, 0, 0, 0, 0, 130, Config).
+
+test_server_skip_SUITE(Config) ->
+ run_test_server_tests("test_server_skip_SUITE", 3, 0, 1,
+ 0, 0, 1, 3, 0, 0, Config).
+
+test_server_conf01_SUITE(Config) ->
+ run_test_server_tests("test_server_conf01_SUITE", 24, 0, 12,
+ 12, 0, 0, 0, 0, 24, Config).
+
+test_server_conf02_SUITE(Config) ->
+ run_test_server_tests("test_server_conf02_SUITE", 26, 0, 12,
+ 12, 0, 0, 0, 0, 26, Config).
+
+
+run_test_server_tests(SuiteName, NCases, NFail, NExpected, NSucc,
+ NUsrSkip, NAutoSkip,
+ NActualSkip, NActualFail, NActualSucc, Config) ->
+ Node = proplists:get_value(node, Config),
+ {ok,_Pid} = rpc:call(Node,test_server_ctrl, start, []),
+ rpc:call(Node,
+ test_server_ctrl,add_dir_with_skip,
+ [SuiteName,
+ [proplists:get_value(data_dir,Config)],SuiteName,
+ [{test_server_SUITE,skip_case7,"SKIPPED!"}]]),
+
+ until(fun() ->
+ rpc:call(Node,test_server_ctrl,jobs,[]) =:= []
+ end),
-
-config(suite) -> [];
-config(doc) -> ["Test that the Config variable is decent, ",
- "and that the std config variables are correct ",
- "(check that data/priv dir exists)."
- "Also check that ?config macro works."];
-config(Config) when is_list(Config) ->
- is_tuplelist(Config),
- {value,{data_dir,Dd}}=lists:keysearch(data_dir,1,Config),
- {value,{priv_dir,Dp}}=lists:keysearch(priv_dir,1,Config),
- true=is_dir(Dd),
- {ok, _Bin}=file:read_file(filename:join(Dd, "dummy_file")),
- true=is_dir(Dp),
-
- Dd = ?config(data_dir,Config),
- Dp = ?config(priv_dir,Config),
- ok;
-config(_Config) ->
- ?t:fail("Config variable is not a list.").
-
-is_tuplelist([]) ->
- true;
-is_tuplelist([{_A,_B}|Rest]) ->
- is_tuplelist(Rest);
-is_tuplelist(_) ->
- false.
-
-is_dir(Dir) ->
- case file:read_file_info(Dir) of
- {ok, #file_info{type=directory}} ->
- true;
- _ ->
- false
- end.
-
-comment(suite) -> [];
-comment(doc) -> ["Print a comment in the HTML log"];
-comment(Config) when is_list(Config) ->
- ?t:comment("This comment should not occur in the HTML log because a later"
- " comment shall overwrite it"),
- ?t:comment("This comment is printed with the comment/1 function."
- " It should occur in the HTML log").
-
-
-
-timetrap(suite) -> [];
-timetrap(doc) -> ["Test that timetrap works."];
-timetrap(Config) when is_list(Config) ->
- TrapAfter = 3000,
- Dog=?t:timetrap(TrapAfter),
- process_flag(trap_exit, true),
- TimeOut = TrapAfter * test_server:timetrap_scale_factor() + 1000,
- receive
- {'EXIT', Dog, {timetrap_timeout, _, _}} ->
- ok;
- {'EXIT', _OtherPid, {timetrap_timeout, _, _}} ->
- ?t:fail("EXIT signal from wrong process")
- after
- TimeOut ->
- ?t:fail("Timetrap is not working.")
- end,
- ?t:timetrap_cancel(Dog),
- ok.
-
-
-timetrap_cancel(suite) -> [];
-timetrap_cancel(doc) -> ["Test that timetrap_cancel works."];
-timetrap_cancel(Config) when is_list(Config) ->
- Dog=?t:timetrap(1000),
- receive
- after
- 500 ->
- ok
- end,
- ?t:timetrap_cancel(Dog),
- receive
- after 1000 ->
- ok
- end,
- ok.
-
-multiply_timetrap(suite) -> [];
-multiply_timetrap(doc) -> ["Test multiply timetrap"];
-multiply_timetrap(Config) when is_list(Config) ->
- %% This simulates the call to test_server_ctrl:multiply_timetraps/1:
- put(test_server_multiply_timetraps,{2,true}),
-
- Dog = ?t:timetrap(500),
- timer:sleep(800),
- ?t:timetrap_cancel(Dog),
-
- %% Reset
- put(test_server_multiply_timetraps,1),
- ok.
-
-
-init_per_s(suite) -> [];
-init_per_s(doc) -> ["Test that a Config that is altered in ",
- "init_per_suite gets through to the testcases."];
-init_per_s(Config) ->
- %% Check that the config var sent from init_per_suite
- %% really exists.
- {value, {init_per_suite_var, ok}} =
- lists:keysearch(init_per_suite_var,1,Config),
-
- %% Check that the other variables still exist.
- {value,{data_dir,_Dd}}=lists:keysearch(data_dir,1,Config),
- {value,{priv_dir,_Dp}}=lists:keysearch(priv_dir,1,Config),
- ok.
-
-init_per_tc(suite) -> [];
-init_per_tc(doc) -> ["Test that a Config that is altered in ",
- "init_per_testcase gets through to the ",
- "actual testcase."];
-init_per_tc(Config) ->
- %% Check that the config var sent from init_per_testcase
- %% really exists.
- {value, {strange_var, 1}} = lists:keysearch(strange_var,1,Config),
-
- %% Check that the other variables still exist.
- {value,{data_dir,_Dd}}=lists:keysearch(data_dir,1,Config),
- {value,{priv_dir,_Dp}}=lists:keysearch(priv_dir,1,Config),
- ok.
-
-end_per_tc(suite) -> [];
-end_per_tc(doc) -> ["Test that end_per_testcase/2 is called even if"
- " test case fails"];
-end_per_tc(Config) when is_list(Config) ->
- ?t:fail("This case should fail! Check that \"CLEANUP\" is"
- " printed in the minor log file.").
-
-
-timeconv(suite) -> [];
-timeconv(doc) -> ["Test that the time unit conversion functions ",
- "works."];
-timeconv(Config) when is_list(Config) ->
- Val=2,
- Secs=Val*1000,
- Mins=Secs*60,
- Hrs=Mins*60,
- Secs=?t:seconds(2),
- Mins=?t:minutes(2),
- Hrs=?t:hours(2),
- ok.
-
-
-msgs(suite) -> [];
-msgs(doc) -> ["Tests the messages_get function."];
-msgs(Config) when is_list(Config) ->
- self() ! {hej, du},
- self() ! {lite, "data"},
- self() ! en_atom,
- [{hej, du}, {lite, "data"}, en_atom] = ?t:messages_get(),
- ok.
-
-capture(suite) -> [];
-capture(doc) -> ["Test that the capture functions work properly."];
-capture(Config) when is_list(Config) ->
- String1="abcedfghjiklmnopqrstuvwxyz",
- String2="0123456789",
- ?t:capture_start(),
- io:format(String1),
- [String1]=?t:capture_get(),
- io:format(String2),
- [String2]=?t:capture_get(),
- ?t:capture_stop(),
- []=?t:capture_get(),
- io:format(String2),
- []=?t:capture_get(),
- ok.
-
-timecall(suite) -> [];
-timecall(doc) -> ["Tests that timed calls work."];
-timecall(Config) when is_list(Config) ->
- {_Time1, liten_apa_e_oxo_farlig} = ?t:timecall(?MODULE, dummy_function, []),
- {Time2, jag_ar_en_gorilla} = ?t:timecall(?MODULE, dummy_function, [gorilla]),
- DTime=round(Time2),
- if
- DTime<1 ->
- ?t:fail("Timecall reported a too low time.");
- DTime==1 ->
+ rpc:call(Node,test_server_ctrl, stop, []),
+ {ok,#suite{ n_cases = NCases,
+ n_cases_failed = NFail,
+ n_cases_expected = NExpected,
+ n_cases_succ = NSucc,
+ n_cases_user_skip = NUsrSkip,
+ n_cases_auto_skip = NAutoSkip,
+ cases = Cases }} = Data =
+ test_server_test_lib:parse_suite(
+ hd(filelib:wildcard(
+ filename:join([proplists:get_value(priv_dir, Config),
+ SuiteName++".logs","run*","suite.log"])))),
+ {NActualSkip,NActualFail,NActualSucc} =
+ lists:foldl(fun(#tc{ result = skip },{S,F,Su}) ->
+ {S+1,F,Su};
+ (#tc{ result = ok },{S,F,Su}) ->
+ {S,F,Su+1};
+ (#tc{ result = failed },{S,F,Su}) ->
+ {S,F+1,Su}
+ end,{0,0,0},Cases),
+ Data.
+
+until(Fun) ->
+ case Fun() of
+ true ->
ok;
- DTime>1 ->
- ?t:fail("Timecall reported a too high time.")
- end,
- ok.
-
-dummy_function() ->
- liten_apa_e_oxo_farlig.
-dummy_function(gorilla) ->
- receive after 1000 -> ok end,
- jag_ar_en_gorilla.
-
-
-do_times(suite) -> [do_times_mfa, do_times_fun];
-do_times(doc) -> ["Test the do_times function."].
-
-do_times_mfa(suite) -> [];
-do_times_mfa(doc) -> ["Test the do_times function with M,F,A given."];
-do_times_mfa(Config) when is_list(Config) ->
- ?t:do_times(100, ?MODULE, doer, [self()]),
- 100=length(?t:messages_get()),
- ok.
-
-do_times_fun(suite) -> [];
-do_times_fun(doc) -> ["Test the do_times function with fun given."];
-do_times_fun(Config) when is_list(Config) ->
- Self = self(),
- ?t:do_times(100, fun() -> doer(Self) end),
- 100=length(?t:messages_get()),
- ok.
-
-doer(From) ->
- From ! a,
- ok.
-
-skip_cases(doc) -> ["Test all possible ways to skip a test case."];
-skip_cases(suite) -> [skip_case1, skip_case2, skip_case3, skip_case4,
- skip_case5, skip_case6, skip_case7, skip_case8,
- skip_case9].
-
-skip_case1(suite) -> [];
-skip_case1(doc) -> ["Test that you can return {skipped, Reason},"
- " and that Reason is in the comment field in the HTML log"];
-skip_case1(Config) when is_list(Config) ->
- %% If this comment shows, the case failed!!
- ?t:comment("ERROR: This case should have been noted as `Skipped'"),
- %% The Reason in {skipped, Reason} should overwrite a 'comment'
- {skipped, "This case should be noted as `Skipped'"}.
-
-skip_case2(suite) -> [];
-skip_case2(doc) -> ["Test that you can return {skipped, Reason},"
- " and that Reason is in the comment field in the HTML log"];
-skip_case2(Config) when is_list(Config) ->
- %% If this comment shows, the case failed!!
- ?t:comment("ERROR: This case should have been noted as `Skipped'"),
- %% The Reason in {skipped, Reason} should overwrite a 'comment'
- exit({skipped, "This case should be noted as `Skipped'"}).
-
-skip_case3(suite) -> [];
-skip_case3(doc) -> ["Test that you can return {skip, Reason},"
- " and that Reason is in the comment field in the HTML log"];
-skip_case3(Config) when is_list(Config) ->
- %% If this comment shows, the case failed!!
- ?t:comment("ERROR: This case should have been noted as `Skipped'"),
- %% The Reason in {skip, Reason} should overwrite a 'comment'
- {skip, "This case should be noted as `Skipped'"}.
-
-skip_case4(suite) -> [];
-skip_case4(doc) -> ["Test that you can return {skip, Reason},"
- " and that Reason is in the comment field in the HTML log"];
-skip_case4(Config) when is_list(Config) ->
- %% If this comment shows, the case failed!!
- ?t:comment("ERROR: This case should have been noted as `Skipped'"),
- %% The Reason in {skip, Reason} should overwrite a 'comment'
- exit({skip, "This case should be noted as `Skipped'"}).
-
-skip_case5(suite) -> {skipped, "This case should be noted as `Skipped'"};
-skip_case5(doc) -> ["Test that you can return {skipped, Reason}"
- " from the specification clause"].
-
-skip_case6(suite) -> {skip, "This case should be noted as `Skipped'"};
-skip_case6(doc) -> ["Test that you can return {skip, Reason}"
- " from the specification clause"].
-
-skip_case7(suite) -> [];
-skip_case7(doc) -> ["Test that skip works from a test specification file"];
-skip_case7(Config) when is_list(Config) ->
- %% This case shall be skipped by adding
- %% {skip, {test_server_SUITE, skip_case7, Reason}}.
- %% to the test specification file.
- ?t:fail("This case should have been Skipped by the .spec file").
-
-skip_case8(suite) -> [];
-skip_case8(doc) -> ["Test that {skipped, Reason} works from"
- " init_per_testcase/2"];
-skip_case8(Config) when is_list(Config) ->
- %% This case shall be skipped by adding a specific clause to
- %% returning {skipped, Reason} from init_per_testcase/2 for this case.
- ?t:fail("This case should have been Skipped by init_per_testcase/2").
-
-skip_case9(suite) -> [];
-skip_case9(doc) -> ["Test that {skip, Reason} works from a init_per_testcase/2"];
-skip_case9(Config) when is_list(Config) ->
- %% This case shall be skipped by adding a specific clause to
- %% returning {skip, Reason} from init_per_testcase/2 for this case.
- ?t:fail("This case should have been Skipped by init_per_testcase/2").
-
-undefined_functions(suite) -> [];
-undefined_functions(doc) -> ["Check for calls to undefined functions in"
- " test_server."
- "Skip if cover is running"];
-undefined_functions(Config) when is_list(Config) ->
- case whereis(cover_server) of
- Pid when is_pid(Pid) ->
- {skip,"Cover is running"};
- undefined ->
- undefined_functions()
- end.
-
-undefined_functions() ->
- TestServerDir = filename:dirname(code:which(test_server)),
- Res = xref:d(TestServerDir),
-
- {value,{unused,Unused}} = lists:keysearch(unused, 1, Res),
- case Unused of
- [] -> ok;
- _ ->
- lists:foreach(fun (MFA) ->
- io:format("~s unused", [format_mfa(MFA)])
- end, Unused)
- end,
-
- {value,{undefined,Undef0}} = lists:keysearch(undefined, 1, Res),
- Undef = [U || U <- Undef0, not unresolved(U)],
- case Undef of
- [] -> ok;
- _ ->
- lists:foreach(fun ({MFA1,MFA2}) ->
- io:format("~s calls undefined ~s",
- [format_mfa(MFA1),format_mfa(MFA2)])
- end, Undef),
- ?t:fail({length(Undef),undefined_functions_in_otp})
- end,
- ok.
-
-unresolved({_,{_,'$F_EXPR',_}}) -> true;
-unresolved(_) -> false.
-
-format_mfa({M,F,A}) ->
- lists:flatten(io_lib:format("~s:~s/~p", [M,F,A])).
-
-conf_init(doc) -> ["Test successful conf case: Change Config parameter"];
-conf_init(Config) when is_list(Config) ->
- [{conf_init_var,1389}|Config].
-
-check_new_conf(suite) -> [];
-check_new_conf(doc) -> ["Check that Config parameter changed by"
- " conf_init is used"];
-check_new_conf(Config) when is_list(Config) ->
- 1389 = ?config(conf_init_var,Config),
- ok.
-
-conf_cleanup(doc) -> ["Test successful conf case: Restore Config parameter"];
-conf_cleanup(Config) when is_list(Config) ->
- lists:keydelete(conf_init_var,1,Config).
-
-check_old_conf(suite) -> [];
-check_old_conf(doc) -> ["Test that the restored Config is used after a"
- " conf cleanup"];
-check_old_conf(Config) when is_list(Config) ->
- undefined = ?config(conf_init_var,Config),
- ok.
-
-conf_init_fail(doc) -> ["Test that config members are skipped if"
- " conf init function fails."];
-conf_init_fail(Config) when is_list(Config) ->
- ?t:fail("This case should fail! Check that conf_member_skip and"
- " conf_cleanup_skip are skipped.").
-
-
-
-start_stop_node(suite) -> [];
-start_stop_node(doc) -> ["Test start and stop of slave and peer nodes"];
-start_stop_node(Config) when is_list(Config) ->
- {ok,Node2} = ?t:start_node(node2,peer,[]),
- {error, _} = ?t:start_node(node2,peer,[{fail_on_error,false}]),
- true = lists:member(Node2,nodes()),
-
- {ok,Node3} = ?t:start_node(node3,slave,[]),
- {error, _} = ?t:start_node(node3,slave,[]),
- true = lists:member(Node3,nodes()),
-
- {ok,Node4} = ?t:start_node(node4,peer,[{wait,false}]),
- case lists:member(Node4,nodes()) of
- true ->
- ?t:comment("WARNING: Node started with {wait,false}"
- " is up faster than expected...");
false ->
- wait_for_node(Node4,0),
- true = lists:member(Node4,nodes())
- end,
-
- true = ?t:stop_node(Node2),
- false = lists:member(Node2,nodes()),
-
- true = ?t:stop_node(Node3),
- false = lists:member(Node3,nodes()),
-
- true = ?t:stop_node(Node4),
- false = lists:member(Node4,nodes()),
- timer:sleep(2000),
- false = ?t:stop_node(Node4),
-
- ok.
-
-
-wait_for_node(Node,Acc) ->
- case net_adm:ping(Node) of
- pang ->
timer:sleep(100),
- wait_for_node(Node,Acc+100);
- pong ->
- Acc
+ until(Fun)
end.
-
-cleanup_nodes_init(doc) -> ["Test that nodes are terminated when test case"
- " is finished unless {cleanup,false} is given."];
-cleanup_nodes_init(Config) when is_list(Config) ->
- {ok,DieSlave} = ?t:start_node(die_slave, slave, []),
- {ok,SurviveSlave} = ?t:start_node(survive_slave, slave, [{cleanup,false}]),
- {ok,DiePeer} = ?t:start_node(die_peer, peer, []),
- {ok,SurvivePeer} = ?t:start_node(survive_peer, peer, [{cleanup,false}]),
- [{die_slave,DieSlave},
- {survive_slave,SurviveSlave},
- {die_peer,DiePeer},
- {survive_peer,SurvivePeer} | Config].
-
-
-
-check_survive_nodes(suite) -> [];
-check_survive_nodes(doc) -> ["Test that nodes with {cleanup,false} survived"];
-check_survive_nodes(Config) when is_list(Config) ->
- timer:sleep(1000),
- false = lists:member(?config(die_slave,Config),nodes()),
- true = lists:member(?config(survive_slave,Config),nodes()),
- false = lists:member(?config(die_peer,Config),nodes()),
- true = lists:member(?config(survive_peer,Config),nodes()),
- ok.
-
-
-cleanup_nodes_fin(doc) -> ["Test that nodes started with {cleanup,false}"
- " can be stopped"];
-cleanup_nodes_fin(Config) when is_list(Config) ->
- Slave = ?config(survive_slave,Config),
- Peer = ?config(survive_peer,Config),
-
- true = ?t:stop_node(Slave),
- false = lists:member(Slave,nodes()),
- true = ?t:stop_node(Peer),
- false = lists:member(Peer,nodes()),
-
- C1 = lists:keydelete(die_slave,1,Config),
- C2 = lists:keydelete(survive_slave,1,C1),
- C3 = lists:keydelete(die_peer,1,C2),
- lists:keydelete(survive_peer,1,C3).
-
-commercial(Config) when is_list(Config) ->
- case ?t:is_commercial() of
- false -> {comment,"Open-source build"};
- true -> {comment,"Commercial build"}
- end.
-
-
+
diff --git a/lib/test_server/test/test_server_SUITE_data/Makefile.src b/lib/test_server/test/test_server_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..d5af919eec
--- /dev/null
+++ b/lib/test_server/test/test_server_SUITE_data/Makefile.src
@@ -0,0 +1,2 @@
+all:
+ erlc *.erl \ No newline at end of file
diff --git a/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl
new file mode 100644
index 0000000000..0563e1104f
--- /dev/null
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_SUITE.erl
@@ -0,0 +1,554 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%------------------------------------------------------------------
+%%% Test Server self test.
+%%%------------------------------------------------------------------
+-module(test_server_SUITE).
+-include_lib("test_server/include/test_server.hrl").
+-include_lib("test_server/include/test_server_line.hrl").
+-include_lib("kernel/include/file.hrl").
+-export([all/1]).
+
+-export([init_per_suite/1, end_per_suite/1]).
+-export([init_per_testcase/2, end_per_testcase/2, fin_per_testcase/2]).
+-export([config/1, comment/1, timetrap/1, timetrap_cancel/1, multiply_timetrap/1,
+ init_per_s/1, init_per_tc/1, end_per_tc/1,
+ timeconv/1, msgs/1, capture/1, timecall/1,
+ do_times/1, do_times_mfa/1, do_times_fun/1,
+ skip_cases/1, skip_case1/1, skip_case2/1, skip_case3/1,
+ skip_case4/1, skip_case5/1, skip_case6/1, skip_case7/1,
+ skip_case8/1, skip_case9/1, undefined_functions/1,
+ conf_init/1, check_new_conf/1, conf_cleanup/1,
+ check_old_conf/1, conf_init_fail/1, start_stop_node/1,
+ cleanup_nodes_init/1, check_survive_nodes/1, cleanup_nodes_fin/1,
+ commercial/1]).
+
+-export([dummy_function/0,dummy_function/1,doer/1]).
+
+all(doc) -> ["Test Server self test"];
+all(suite) ->
+ [config, comment, timetrap, timetrap_cancel, multiply_timetrap,
+ init_per_s, init_per_tc, end_per_tc,
+ timeconv, msgs, capture, timecall, do_times, skip_cases,
+ undefined_functions, commercial,
+ {conf, conf_init, [check_new_conf], conf_cleanup},
+ check_old_conf,
+ {conf, conf_init_fail,[conf_member_skip],conf_cleanup_skip},
+ start_stop_node,
+ {conf, cleanup_nodes_init,[check_survive_nodes],cleanup_nodes_fin},
+ config
+ ].
+
+
+init_per_suite(Config) ->
+ [{init_per_suite_var,ok}|Config].
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+ Dog = ?t:timetrap(?t:minutes(2)),
+ Config1 = [{watchdog, Dog}|Config],
+ case Func of
+ init_per_tc ->
+ [{strange_var, 1}|Config1];
+ skip_case8 ->
+ {skipped, "This case should be noted as `Skipped'"};
+ skip_case9 ->
+ {skip, "This case should be noted as `Skipped'"};
+ _ ->
+ Config1
+ end;
+init_per_testcase(Func, Config) ->
+ io:format("Func:~p",[Func]),
+ io:format("Config:~p",[Config]),
+ ?t:fail("Arguments to init_per_testcase not correct").
+
+end_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+ Dog=?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ case Func of
+ end_per_tc -> io:format("CLEANUP => this test case is ok\n");
+ _Other -> ok
+ end;
+end_per_testcase(Func, Config) ->
+ io:format("Func:~p",[Func]),
+ io:format("Config:~p",[Config]),
+ ?t:fail("Arguments to end_per_testcase not correct").
+
+fin_per_testcase(Func, Config) ->
+ io:format("Func:~p",[Func]),
+ io:format("Config:~p",[Config]),
+ ?t:fail("fin_per_testcase/2 called, should have called end_per_testcase/2").
+
+
+config(suite) -> [];
+config(doc) -> ["Test that the Config variable is decent, ",
+ "and that the std config variables are correct ",
+ "(check that data/priv dir exists)."
+ "Also check that ?config macro works."];
+config(Config) when is_list(Config) ->
+ is_tuplelist(Config),
+ {value,{data_dir,Dd}}=lists:keysearch(data_dir,1,Config),
+ {value,{priv_dir,Dp}}=lists:keysearch(priv_dir,1,Config),
+ true=is_dir(Dd),
+ {ok, _Bin}=file:read_file(filename:join(Dd, "dummy_file")),
+ true=is_dir(Dp),
+
+ Dd = ?config(data_dir,Config),
+ Dp = ?config(priv_dir,Config),
+ ok;
+config(_Config) ->
+ ?t:fail("Config variable is not a list.").
+
+is_tuplelist([]) ->
+ true;
+is_tuplelist([{_A,_B}|Rest]) ->
+ is_tuplelist(Rest);
+is_tuplelist(_) ->
+ false.
+
+is_dir(Dir) ->
+ case file:read_file_info(Dir) of
+ {ok, #file_info{type=directory}} ->
+ true;
+ _ ->
+ false
+ end.
+
+comment(suite) -> [];
+comment(doc) -> ["Print a comment in the HTML log"];
+comment(Config) when is_list(Config) ->
+ ?t:comment("This comment should not occur in the HTML log because a later"
+ " comment shall overwrite it"),
+ ?t:comment("This comment is printed with the comment/1 function."
+ " It should occur in the HTML log").
+
+
+
+timetrap(suite) -> [];
+timetrap(doc) -> ["Test that timetrap works."];
+timetrap(Config) when is_list(Config) ->
+ TrapAfter = 3000,
+ Dog=?t:timetrap(TrapAfter),
+ process_flag(trap_exit, true),
+ TimeOut = TrapAfter * test_server:timetrap_scale_factor() + 1000,
+ receive
+ {'EXIT', Dog, {timetrap_timeout, _, _}} ->
+ ok;
+ {'EXIT', _OtherPid, {timetrap_timeout, _, _}} ->
+ ?t:fail("EXIT signal from wrong process")
+ after
+ TimeOut ->
+ ?t:fail("Timetrap is not working.")
+ end,
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+
+timetrap_cancel(suite) -> [];
+timetrap_cancel(doc) -> ["Test that timetrap_cancel works."];
+timetrap_cancel(Config) when is_list(Config) ->
+ Dog=?t:timetrap(1000),
+ receive
+ after
+ 500 ->
+ ok
+ end,
+ ?t:timetrap_cancel(Dog),
+ receive
+ after 1000 ->
+ ok
+ end,
+ ok.
+
+multiply_timetrap(suite) -> [];
+multiply_timetrap(doc) -> ["Test multiply timetrap"];
+multiply_timetrap(Config) when is_list(Config) ->
+ %% This simulates the call to test_server_ctrl:multiply_timetraps/1:
+ put(test_server_multiply_timetraps,{2,true}),
+
+ Dog = ?t:timetrap(500),
+ timer:sleep(800),
+ ?t:timetrap_cancel(Dog),
+
+ %% Reset
+ put(test_server_multiply_timetraps,1),
+ ok.
+
+
+init_per_s(suite) -> [];
+init_per_s(doc) -> ["Test that a Config that is altered in ",
+ "init_per_suite gets through to the testcases."];
+init_per_s(Config) ->
+ %% Check that the config var sent from init_per_suite
+ %% really exists.
+ {value, {init_per_suite_var, ok}} =
+ lists:keysearch(init_per_suite_var,1,Config),
+
+ %% Check that the other variables still exist.
+ {value,{data_dir,_Dd}}=lists:keysearch(data_dir,1,Config),
+ {value,{priv_dir,_Dp}}=lists:keysearch(priv_dir,1,Config),
+ ok.
+
+init_per_tc(suite) -> [];
+init_per_tc(doc) -> ["Test that a Config that is altered in ",
+ "init_per_testcase gets through to the ",
+ "actual testcase."];
+init_per_tc(Config) ->
+ %% Check that the config var sent from init_per_testcase
+ %% really exists.
+ {value, {strange_var, 1}} = lists:keysearch(strange_var,1,Config),
+
+ %% Check that the other variables still exist.
+ {value,{data_dir,_Dd}}=lists:keysearch(data_dir,1,Config),
+ {value,{priv_dir,_Dp}}=lists:keysearch(priv_dir,1,Config),
+ ok.
+
+end_per_tc(suite) -> [];
+end_per_tc(doc) -> ["Test that end_per_testcase/2 is called even if"
+ " test case fails"];
+end_per_tc(Config) when is_list(Config) ->
+ ?t:fail("This case should fail! Check that \"CLEANUP\" is"
+ " printed in the minor log file.").
+
+
+timeconv(suite) -> [];
+timeconv(doc) -> ["Test that the time unit conversion functions ",
+ "works."];
+timeconv(Config) when is_list(Config) ->
+ Val=2,
+ Secs=Val*1000,
+ Mins=Secs*60,
+ Hrs=Mins*60,
+ Secs=?t:seconds(2),
+ Mins=?t:minutes(2),
+ Hrs=?t:hours(2),
+ ok.
+
+
+msgs(suite) -> [];
+msgs(doc) -> ["Tests the messages_get function."];
+msgs(Config) when is_list(Config) ->
+ self() ! {hej, du},
+ self() ! {lite, "data"},
+ self() ! en_atom,
+ [{hej, du}, {lite, "data"}, en_atom] = ?t:messages_get(),
+ ok.
+
+capture(suite) -> [];
+capture(doc) -> ["Test that the capture functions work properly."];
+capture(Config) when is_list(Config) ->
+ String1="abcedfghjiklmnopqrstuvwxyz",
+ String2="0123456789",
+ ?t:capture_start(),
+ io:format(String1),
+ [String1]=?t:capture_get(),
+ io:format(String2),
+ [String2]=?t:capture_get(),
+ ?t:capture_stop(),
+ []=?t:capture_get(),
+ io:format(String2),
+ []=?t:capture_get(),
+ ok.
+
+timecall(suite) -> [];
+timecall(doc) -> ["Tests that timed calls work."];
+timecall(Config) when is_list(Config) ->
+ {_Time1, liten_apa_e_oxo_farlig} = ?t:timecall(?MODULE, dummy_function, []),
+ {Time2, jag_ar_en_gorilla} = ?t:timecall(?MODULE, dummy_function, [gorilla]),
+ DTime=round(Time2),
+ if
+ DTime<1 ->
+ ?t:fail("Timecall reported a too low time.");
+ DTime==1 ->
+ ok;
+ DTime>1 ->
+ ?t:fail("Timecall reported a too high time.")
+ end,
+ ok.
+
+dummy_function() ->
+ liten_apa_e_oxo_farlig.
+dummy_function(gorilla) ->
+ receive after 1000 -> ok end,
+ jag_ar_en_gorilla.
+
+
+do_times(suite) -> [do_times_mfa, do_times_fun];
+do_times(doc) -> ["Test the do_times function."].
+
+do_times_mfa(suite) -> [];
+do_times_mfa(doc) -> ["Test the do_times function with M,F,A given."];
+do_times_mfa(Config) when is_list(Config) ->
+ ?t:do_times(100, ?MODULE, doer, [self()]),
+ 100=length(?t:messages_get()),
+ ok.
+
+do_times_fun(suite) -> [];
+do_times_fun(doc) -> ["Test the do_times function with fun given."];
+do_times_fun(Config) when is_list(Config) ->
+ Self = self(),
+ ?t:do_times(100, fun() -> doer(Self) end),
+ 100=length(?t:messages_get()),
+ ok.
+
+doer(From) ->
+ From ! a,
+ ok.
+
+skip_cases(doc) -> ["Test all possible ways to skip a test case."];
+skip_cases(suite) -> [skip_case1, skip_case2, skip_case3, skip_case4,
+ skip_case5, skip_case6, skip_case7, skip_case8,
+ skip_case9].
+
+skip_case1(suite) -> [];
+skip_case1(doc) -> ["Test that you can return {skipped, Reason},"
+ " and that Reason is in the comment field in the HTML log"];
+skip_case1(Config) when is_list(Config) ->
+ %% If this comment shows, the case failed!!
+ ?t:comment("ERROR: This case should have been noted as `Skipped'"),
+ %% The Reason in {skipped, Reason} should overwrite a 'comment'
+ {skipped, "This case should be noted as `Skipped'"}.
+
+skip_case2(suite) -> [];
+skip_case2(doc) -> ["Test that you can return {skipped, Reason},"
+ " and that Reason is in the comment field in the HTML log"];
+skip_case2(Config) when is_list(Config) ->
+ %% If this comment shows, the case failed!!
+ ?t:comment("ERROR: This case should have been noted as `Skipped'"),
+ %% The Reason in {skipped, Reason} should overwrite a 'comment'
+ exit({skipped, "This case should be noted as `Skipped'"}).
+
+skip_case3(suite) -> [];
+skip_case3(doc) -> ["Test that you can return {skip, Reason},"
+ " and that Reason is in the comment field in the HTML log"];
+skip_case3(Config) when is_list(Config) ->
+ %% If this comment shows, the case failed!!
+ ?t:comment("ERROR: This case should have been noted as `Skipped'"),
+ %% The Reason in {skip, Reason} should overwrite a 'comment'
+ {skip, "This case should be noted as `Skipped'"}.
+
+skip_case4(suite) -> [];
+skip_case4(doc) -> ["Test that you can return {skip, Reason},"
+ " and that Reason is in the comment field in the HTML log"];
+skip_case4(Config) when is_list(Config) ->
+ %% If this comment shows, the case failed!!
+ ?t:comment("ERROR: This case should have been noted as `Skipped'"),
+ %% The Reason in {skip, Reason} should overwrite a 'comment'
+ exit({skip, "This case should be noted as `Skipped'"}).
+
+skip_case5(suite) -> {skipped, "This case should be noted as `Skipped'"};
+skip_case5(doc) -> ["Test that you can return {skipped, Reason}"
+ " from the specification clause"].
+
+skip_case6(suite) -> {skip, "This case should be noted as `Skipped'"};
+skip_case6(doc) -> ["Test that you can return {skip, Reason}"
+ " from the specification clause"].
+
+skip_case7(suite) -> [];
+skip_case7(doc) -> ["Test that skip works from a test specification file"];
+skip_case7(Config) when is_list(Config) ->
+ %% This case shall be skipped by adding
+ %% {skip, {test_server_SUITE, skip_case7, Reason}}.
+ %% to the test specification file.
+ ?t:fail("This case should have been Skipped by the .spec file").
+
+skip_case8(suite) -> [];
+skip_case8(doc) -> ["Test that {skipped, Reason} works from"
+ " init_per_testcase/2"];
+skip_case8(Config) when is_list(Config) ->
+ %% This case shall be skipped by adding a specific clause to
+ %% returning {skipped, Reason} from init_per_testcase/2 for this case.
+ ?t:fail("This case should have been Skipped by init_per_testcase/2").
+
+skip_case9(suite) -> [];
+skip_case9(doc) -> ["Test that {skip, Reason} works from a init_per_testcase/2"];
+skip_case9(Config) when is_list(Config) ->
+ %% This case shall be skipped by adding a specific clause to
+ %% returning {skip, Reason} from init_per_testcase/2 for this case.
+ ?t:fail("This case should have been Skipped by init_per_testcase/2").
+
+undefined_functions(suite) -> [];
+undefined_functions(doc) -> ["Check for calls to undefined functions in"
+ " test_server."
+ "Skip if cover is running"];
+undefined_functions(Config) when is_list(Config) ->
+ case whereis(cover_server) of
+ Pid when is_pid(Pid) ->
+ {skip,"Cover is running"};
+ undefined ->
+ undefined_functions()
+ end.
+
+undefined_functions() ->
+ TestServerDir = filename:dirname(code:which(test_server)),
+ Res = xref:d(TestServerDir),
+
+ {value,{unused,Unused}} = lists:keysearch(unused, 1, Res),
+ case Unused of
+ [] -> ok;
+ _ ->
+ lists:foreach(fun (MFA) ->
+ io:format("~s unused", [format_mfa(MFA)])
+ end, Unused)
+ end,
+
+ {value,{undefined,Undef0}} = lists:keysearch(undefined, 1, Res),
+ Undef = [U || U <- Undef0, not unresolved(U)],
+ case Undef of
+ [] -> ok;
+ _ ->
+ lists:foreach(fun ({MFA1,MFA2}) ->
+ io:format("~s calls undefined ~s",
+ [format_mfa(MFA1),format_mfa(MFA2)])
+ end, Undef),
+ ?t:fail({length(Undef),undefined_functions_in_otp})
+ end,
+ ok.
+
+unresolved({_,{_,'$F_EXPR',_}}) -> true;
+unresolved(_) -> false.
+
+format_mfa({M,F,A}) ->
+ lists:flatten(io_lib:format("~s:~s/~p", [M,F,A])).
+
+conf_init(doc) -> ["Test successful conf case: Change Config parameter"];
+conf_init(Config) when is_list(Config) ->
+ [{conf_init_var,1389}|Config].
+
+check_new_conf(suite) -> [];
+check_new_conf(doc) -> ["Check that Config parameter changed by"
+ " conf_init is used"];
+check_new_conf(Config) when is_list(Config) ->
+ 1389 = ?config(conf_init_var,Config),
+ ok.
+
+conf_cleanup(doc) -> ["Test successful conf case: Restore Config parameter"];
+conf_cleanup(Config) when is_list(Config) ->
+ lists:keydelete(conf_init_var,1,Config).
+
+check_old_conf(suite) -> [];
+check_old_conf(doc) -> ["Test that the restored Config is used after a"
+ " conf cleanup"];
+check_old_conf(Config) when is_list(Config) ->
+ undefined = ?config(conf_init_var,Config),
+ ok.
+
+conf_init_fail(doc) -> ["Test that config members are skipped if"
+ " conf init function fails."];
+conf_init_fail(Config) when is_list(Config) ->
+ ?t:fail("This case should fail! Check that conf_member_skip and"
+ " conf_cleanup_skip are skipped.").
+
+
+
+start_stop_node(suite) -> [];
+start_stop_node(doc) -> ["Test start and stop of slave and peer nodes"];
+start_stop_node(Config) when is_list(Config) ->
+ {ok,Node2} = ?t:start_node(node2,peer,[]),
+ {error, _} = ?t:start_node(node2,peer,[{fail_on_error,false}]),
+ true = lists:member(Node2,nodes()),
+
+ {ok,Node3} = ?t:start_node(node3,slave,[]),
+ {error, _} = ?t:start_node(node3,slave,[]),
+ true = lists:member(Node3,nodes()),
+
+ {ok,Node4} = ?t:start_node(node4,peer,[{wait,false}]),
+ case lists:member(Node4,nodes()) of
+ true ->
+ ?t:comment("WARNING: Node started with {wait,false}"
+ " is up faster than expected...");
+ false ->
+ wait_for_node(Node4,0),
+ true = lists:member(Node4,nodes())
+ end,
+
+ true = ?t:stop_node(Node2),
+ false = lists:member(Node2,nodes()),
+
+ true = ?t:stop_node(Node3),
+ false = lists:member(Node3,nodes()),
+
+ true = ?t:stop_node(Node4),
+ false = lists:member(Node4,nodes()),
+ timer:sleep(2000),
+ false = ?t:stop_node(Node4),
+
+ ok.
+
+
+wait_for_node(Node,Acc) ->
+ case net_adm:ping(Node) of
+ pang ->
+ timer:sleep(100),
+ wait_for_node(Node,Acc+100);
+ pong ->
+ Acc
+ end.
+
+cleanup_nodes_init(doc) -> ["Test that nodes are terminated when test case"
+ " is finished unless {cleanup,false} is given."];
+cleanup_nodes_init(Config) when is_list(Config) ->
+ {ok,DieSlave} = ?t:start_node(die_slave, slave, []),
+ {ok,SurviveSlave} = ?t:start_node(survive_slave, slave, [{cleanup,false}]),
+ {ok,DiePeer} = ?t:start_node(die_peer, peer, []),
+ {ok,SurvivePeer} = ?t:start_node(survive_peer, peer, [{cleanup,false}]),
+ [{die_slave,DieSlave},
+ {survive_slave,SurviveSlave},
+ {die_peer,DiePeer},
+ {survive_peer,SurvivePeer} | Config].
+
+
+
+check_survive_nodes(suite) -> [];
+check_survive_nodes(doc) -> ["Test that nodes with {cleanup,false} survived"];
+check_survive_nodes(Config) when is_list(Config) ->
+ timer:sleep(1000),
+ false = lists:member(?config(die_slave,Config),nodes()),
+ true = lists:member(?config(survive_slave,Config),nodes()),
+ false = lists:member(?config(die_peer,Config),nodes()),
+ true = lists:member(?config(survive_peer,Config),nodes()),
+ ok.
+
+
+cleanup_nodes_fin(doc) -> ["Test that nodes started with {cleanup,false}"
+ " can be stopped"];
+cleanup_nodes_fin(Config) when is_list(Config) ->
+ Slave = ?config(survive_slave,Config),
+ Peer = ?config(survive_peer,Config),
+
+ true = ?t:stop_node(Slave),
+ false = lists:member(Slave,nodes()),
+ true = ?t:stop_node(Peer),
+ false = lists:member(Peer,nodes()),
+
+ C1 = lists:keydelete(die_slave,1,Config),
+ C2 = lists:keydelete(survive_slave,1,C1),
+ C3 = lists:keydelete(die_peer,1,C2),
+ lists:keydelete(survive_peer,1,C3).
+
+commercial(Config) when is_list(Config) ->
+ case ?t:is_commercial() of
+ false -> {comment,"Open-source build"};
+ true -> {comment,"Commercial build"}
+ end.
+
+
diff --git a/lib/test_server/test/test_server_SUITE_data/dummy_file b/lib/test_server/test/test_server_SUITE_data/test_server_SUITE_data/dummy_file
index 65c88fbd75..65c88fbd75 100644
--- a/lib/test_server/test/test_server_SUITE_data/dummy_file
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_SUITE_data/dummy_file
diff --git a/lib/test_server/test/test_server_conf01_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl
index a6d7dfe851..a6d7dfe851 100644
--- a/lib/test_server/test/test_server_conf01_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_conf01_SUITE.erl
diff --git a/lib/test_server/test/test_server_conf02_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl
index deba4660c6..deba4660c6 100644
--- a/lib/test_server/test/test_server_conf02_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_conf02_SUITE.erl
diff --git a/lib/test_server/test/test_server_parallel01_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl
index 0e7f329f89..0e7f329f89 100644
--- a/lib/test_server/test/test_server_parallel01_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_parallel01_SUITE.erl
diff --git a/lib/test_server/test/test_server_shuffle01_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl
index 7ad269501d..7ad269501d 100644
--- a/lib/test_server/test/test_server_shuffle01_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_shuffle01_SUITE.erl
diff --git a/lib/test_server/test/test_server_skip_SUITE.erl b/lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl
index 4037e1cc0e..4037e1cc0e 100644
--- a/lib/test_server/test/test_server_skip_SUITE.erl
+++ b/lib/test_server/test/test_server_SUITE_data/test_server_skip_SUITE.erl
diff --git a/lib/test_server/test/test_server_line_SUITE.erl b/lib/test_server/test/test_server_line_SUITE.erl
index 02897f164f..aa14862e5a 100644
--- a/lib/test_server/test/test_server_line_SUITE.erl
+++ b/lib/test_server/test/test_server_line_SUITE.erl
@@ -23,20 +23,29 @@
-module(test_server_line_SUITE).
-include_lib("test_server/include/test_server.hrl").
--export([all/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0,suite/0]).
+-export([init_per_suite/1,end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
-export([parse_transform/1, lines/1]).
-all(doc) -> ["Test of parse transform for collection line numbers"];
-all(suite) -> [parse_transform,lines].
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {doc,["Test of parse transform for collection line numbers"]}].
+all() -> [parse_transform,lines].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
init_per_testcase(_Case, Config) ->
?line test_server_line:clear(),
Dog = ?t:timetrap(?t:minutes(2)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
?line test_server_line:clear(),
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog),
diff --git a/lib/test_server/test/test_server_test_lib.erl b/lib/test_server/test/test_server_test_lib.erl
new file mode 100644
index 0000000000..66ff06e0ce
--- /dev/null
+++ b/lib/test_server/test/test_server_test_lib.erl
@@ -0,0 +1,191 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(test_server_test_lib).
+-export([parse_suite/1]).
+-export([init/2, pre_init_per_testcase/3, post_end_per_testcase/4]).
+
+-include("test_server_test_lib.hrl").
+
+%% The CTH hooks all tests
+init(_Id, _Opts) ->
+ [].
+
+pre_init_per_testcase(_TC,Config,State) ->
+ case os:type() of
+ {win32, _} ->
+ %% Extend timeout for windows as starting node
+ %% can take a long time there
+ test_server:timetrap( 120000 * test_server:timetrap_scale_factor());
+ _ ->
+ ok
+ end,
+ {start_slave(Config, 50),State}.
+
+start_slave(Config,_Level) ->
+ [_,Host] = string:tokens(atom_to_list(node()), "@"),
+
+ ct:log("Trying to start ~s~n",
+ ["test_server_tester@"++Host]),
+ case slave:start(Host, test_server_tester, []) of
+ {error,Reason} ->
+ test_server:fail(Reason);
+ {ok,Node} ->
+ ct:log("Node ~p started~n", [Node]),
+ IsCover = test_server:is_cover(),
+ if IsCover ->
+ cover:start(Node);
+ true->
+ ok
+ end,
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+
+ %% PrivDir as well as directory of Test Server suites
+ %% have to be in code path on Test Server node.
+ [_ | Parts] = lists:reverse(filename:split(DataDir)),
+ TSDir = filename:join(lists:reverse(Parts)),
+ AddPathDirs = case proplists:get_value(path_dirs, Config) of
+ undefined -> [];
+ Ds -> Ds
+ end,
+ PathDirs = [PrivDir,TSDir | AddPathDirs],
+ [true = rpc:call(Node, code, add_patha, [D]) || D <- PathDirs],
+ io:format("Dirs added to code path (on ~w):~n",
+ [Node]),
+ [io:format("~s~n", [D]) || D <- PathDirs],
+
+ true = rpc:call(Node, os, putenv,
+ ["TEST_SERVER_FRAMEWORK", "undefined"]),
+
+ ok = rpc:call(Node, file, set_cwd, [PrivDir]),
+ [{node,Node} | Config]
+ end.
+
+post_end_per_testcase(_TC, Config, Return, State) ->
+ Node = proplists:get_value(node, Config),
+ cover:stop(Node),
+ slave:stop(Node),
+
+ {Return, State}.
+
+%% Parse an .suite log file
+parse_suite(FileName) ->
+
+ case file:open(FileName, [read, raw, read_ahead]) of
+ {ok, Fd} ->
+ Data = parse_suite(Fd, #suite{ }),
+ file:close(Fd),
+ {ok, Data};
+ _ ->
+ error
+ end.
+
+fline(Fd) ->
+ case prim_file:read_line(Fd) of
+ eof -> eof;
+ {ok, Line} -> Line
+ end.
+
+parse_suite(Fd, S) ->
+ _Started = fline(Fd),
+ _Starting = fline(Fd),
+ "=cases" ++ NCases = fline(Fd),
+ "=user" ++ _User = fline(Fd),
+ "=host" ++ Host = fline(Fd),
+ "=hosts" ++ _Hosts = fline(Fd),
+ "=emulator_vsn" ++ Evsn = fline(Fd),
+ "=emulator" ++ Emu = fline(Fd),
+ "=otp_release" ++ OtpRel = fline(Fd),
+ "=started" ++ Start = fline(Fd),
+ NewS = parse_cases(Fd, S#suite{
+ n_cases_expected = list_to_int(clean(NCases)),
+ host = list_to_binary(clean(Host)),
+ emulator_vsn = list_to_binary(clean(Evsn)),
+ emulator = list_to_binary(clean(Emu)),
+ otp_release = list_to_binary(clean(OtpRel)),
+ started = list_to_binary(clean(Start))
+ }),
+ "=failed" ++ Failed = fline(Fd),
+ "=successful" ++ Succ = fline(Fd),
+ "=user_skipped" ++ UsrSkip = fline(Fd),
+ "=auto_skipped" ++ AutSkip = fline(Fd),
+ NewS#suite{ n_cases_failed = list_to_int(clean(Failed)),
+ n_cases_succ = list_to_int(clean(Succ)),
+ n_cases_user_skip = list_to_int(clean(UsrSkip)),
+ n_cases_auto_skip = list_to_int(clean(AutSkip)) }.
+
+
+parse_cases(Fd, #suite{ n_cases = N,
+ cases = Cases } = S) ->
+ case parse_case(Fd) of
+ finished -> S#suite{ log_ok = true };
+ {eof, Tc} ->
+ S#suite{ n_cases = N + 1,
+ cases = [Tc#tc{ result = crashed }|Cases]};
+ {ok, Case} ->
+ parse_cases(Fd, S#suite{ n_cases = N + 1,
+ cases = [Case|Cases]})
+ end.
+
+parse_case(Fd) -> parse_case(Fd, #tc{}).
+parse_case(Fd, Tc) -> parse_case(fline(Fd), Fd, Tc).
+
+parse_case(eof, _, Tc) -> {eof, Tc};
+parse_case("=case" ++ Case, Fd, Tc) ->
+ Name = list_to_binary(clean(Case)),
+ parse_case(fline(Fd), Fd, Tc#tc{ name = Name });
+parse_case("=logfile" ++ File, Fd, Tc) ->
+ Log = list_to_binary(clean(File)),
+ parse_case(fline(Fd), Fd, Tc#tc{ logfile = Log });
+parse_case("=elapsed" ++ Elapsed, Fd, Tc) ->
+ {ok, [Time], _} = io_lib:fread("~f", clean(Elapsed)),
+ parse_case(fline(Fd), Fd, Tc#tc{ elapsed = Time });
+parse_case("=result" ++ Result, _, Tc) ->
+ case clean(Result) of
+ "ok" ++ _ ->
+ {ok, Tc#tc{ result = ok } };
+ "failed" ++ _ ->
+ {ok, Tc#tc{ result = failed } };
+ "skipped" ++ _ ->
+ {ok, Tc#tc{ result = skip } }
+ end;
+parse_case("=finished" ++ _ , _Fd, #tc{ name = undefined }) ->
+ finished;
+parse_case(_, Fd, Tc) ->
+ parse_case(fline(Fd), Fd, Tc).
+
+skip([]) -> [];
+skip([$ |Ts]) -> skip(Ts);
+skip(Ts) -> Ts.
+
+%rmnl(L) -> L.
+rmnl([]) -> [];
+rmnl([$\n | Ts]) -> rmnl(Ts);
+rmnl([T|Ts]) -> [T | rmnl(Ts)].
+
+clean(L) ->
+ rmnl(skip(L)).
+
+list_to_int(L) ->
+ try
+ list_to_integer(L)
+ catch
+ _:_ ->
+ 0
+ end.
diff --git a/lib/test_server/test/test_server_test_lib.hrl b/lib/test_server/test/test_server_test_lib.hrl
new file mode 100644
index 0000000000..27b7be9618
--- /dev/null
+++ b/lib/test_server/test/test_server_test_lib.hrl
@@ -0,0 +1,23 @@
+-record(tc, {
+ name,
+ result,
+ elapsed,
+ logfile
+ }).
+
+-record(suite, {
+ application,
+ n_cases = 0,
+ n_cases_failed = 0,
+ n_cases_expected = 0,
+ n_cases_succ,
+ n_cases_user_skip,
+ n_cases_auto_skip,
+ cases = [],
+ host,
+ emulator_vsn,
+ emulator,
+ otp_release,
+ started,
+ log_ok = false
+ }).
diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk
index 4c3df28814..4e293b76a7 100644
--- a/lib/test_server/vsn.mk
+++ b/lib/test_server/vsn.mk
@@ -1,2 +1,2 @@
-TEST_SERVER_VSN = 3.4.1
+TEST_SERVER_VSN = 3.4.2
diff --git a/lib/tools/doc/src/cover.xml b/lib/tools/doc/src/cover.xml
index 323bd0dda8..0a3302bda5 100644
--- a/lib/tools/doc/src/cover.xml
+++ b/lib/tools/doc/src/cover.xml
@@ -270,6 +270,8 @@
defaults to <c>function</c>.</p>
<p>If <c>Module</c> is not Cover compiled, the function returns
<c>{error,{not_cover_compiled,Module}}</c>.</p>
+ <p>HINT: It is possible to issue multiple analyse_to_file commands at
+ the same time. </p>
</desc>
</func>
<func>
@@ -307,6 +309,33 @@
<c>.beam</c> file, or in <c>../src</c> relative to that
directory. If no source code is found,
<c>,{error,no_source_code_found}</c> is returned.</p>
+ <p>HINT: It is possible to issue multiple analyse_to_file commands at
+ the same time. </p>
+ </desc>
+ </func>
+ <func>
+ <name>async_analyse_to_file(Module) -> </name>
+ <name>async_analyse_to_file(Module,Options) -> </name>
+ <name>async_analyse_to_file(Module, OutFile) -> </name>
+ <name>async_analyse_to_file(Module, OutFile, Options) -> pid()</name>
+ <fsummary>Asynchronous call to analyse_to_file.</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ <v>OutFile = string()</v>
+ <v>Options = [Option]</v>
+ <v>Option = html</v>
+ <v>Error = {not_cover_compiled,Module} | {file,File,Reason} | no_source_code_found | not_main_node</v>
+ <v>&nbsp;File = string()</v>
+ <v>&nbsp;Reason = term()</v>
+ </type>
+ <desc>
+ <p>This function works exactly the same way as
+ <seealso marker="#analyse_to_file-1">analyse_to_file</seealso> except
+ that it is asynchronous instead of synchronous. The spawned process
+ will link with the caller when created. If an <c>Error</c> occurs
+ while doing the cover analysis the process will crash with the same
+ error reason as <seealso marker="#analyse_to_file-1">analyse_to_file</seealso>
+ would return.</p>
</desc>
</func>
<func>
diff --git a/lib/tools/doc/src/cover_chapter.xml b/lib/tools/doc/src/cover_chapter.xml
index b4f7919183..92a790c34e 100644
--- a/lib/tools/doc/src/cover_chapter.xml
+++ b/lib/tools/doc/src/cover_chapter.xml
@@ -403,6 +403,13 @@ ok
database contains information about each executable line in each
Cover compiled module, performance decreases proportionally to
the size and number of the Cover compiled modules.</p>
+ <p>To improve performance when analysing cover results it is possible
+ to do multiple calls to <seealso marker="cover#analyse-1">analyse</seealso>
+ and <seealso marker="cover#analyse_to_file-1">analyse_to_file</seealso>
+ at once. You can also use the
+ <seealso marker="cover#async_analyse_to_file-1">async_analyse_to_file</seealso>
+ convenience function.
+ </p>
</section>
<section>
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 4a71993da9..5f9cecd6e4 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -30,6 +30,26 @@
</header>
<p>This document describes the changes made to the Tools application.</p>
+<section><title>Tools 2.6.6.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>eprof: API sort mismatch has now been fixed. </p>
+ <p>
+ Own Id: OTP-8853</p>
+ </item>
+ <item>
+ <p>
+ eprof: fix division by zero in statistics</p>
+ <p>
+ Own Id: OTP-8963</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Tools 2.6.6.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index 91acfdf2b6..ed825a298f 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -1481,7 +1481,23 @@ Other commands:
erlang-font-lock-keywords-3
erlang-font-lock-keywords-4)
nil nil ((?_ . "w")) erlang-beginning-of-clause
- (font-lock-mark-block-function . erlang-mark-clause))))
+ (font-lock-mark-block-function . erlang-mark-clause)
+ (font-lock-syntactic-keywords
+ ;; A dollar sign right before the double quote that ends a
+ ;; string is not a character escape.
+ ;;
+ ;; And a "string" has with a double quote not escaped by a
+ ;; dollar sign, any number of non-backslash non-newline
+ ;; characters or escaped backslashes, a dollar sign
+ ;; (otherwise we wouldn't care) and a double quote. This
+ ;; doesn't match multi-line strings, but this is probably
+ ;; the best we can get, since while font-locking we don't
+ ;; know whether matching started inside a string: limiting
+ ;; search to a single line keeps things sane.
+ . (("\\(?:^\\|[^$]\\)\"\\(?:[^\"\n]\\|\\\\\"\\)*\\(\\$\\)\"" 1 "w")
+ ;; And the dollar sign in $\" escapes two characters, not
+ ;; just one.
+ ("\\(\\$\\)\\\\\\\"" 1 "'"))))))
diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl
index c4d1bd1d2f..ada2db45be 100644
--- a/lib/tools/src/cover.erl
+++ b/lib/tools/src/cover.erl
@@ -35,23 +35,37 @@
%% remote_process_loop/1.
%%
%% TABLES
-%% Each nodes has an ets table named 'cover_internal_data_table'
-%% (?COVER_TABLE). This table contains the coverage data and is
-%% continously updated when cover compiled code is executed.
+%% Each nodes has two tables: cover_internal_data_table (?COVER_TABLE) and.
+%% cover_internal_clause_table (?COVER_CLAUSE_TABLE).
+%% ?COVER_TABLE contains the bump data i.e. the data about which lines
+%% have been executed how many times.
+%% ?COVER_CLAUSE_TABLE contains information about which clauses in which modules
+%% cover is currently collecting statistics.
%%
-%% The main node owns a table named
-%% 'cover_collected_remote_data_table' (?COLLECTION_TABLE). This table
-%% contains data which is collected from remote nodes (either when a
-%% remote node is stopped with cover:stop/1 or when analysing. When
-%% analysing, data is even moved from the ?COVER_TABLE on the main
-%% node to the ?COLLECTION_TABLE.
+%% The main node owns tables named
+%% 'cover_collected_remote_data_table' (?COLLECTION_TABLE) and
+%% 'cover_collected_remote_clause_table' (?COLLECTION_CLAUSE_TABLE).
+%% These tables contain data which is collected from remote nodes (either when a
+%% remote node is stopped with cover:stop/1 or when analysing). When
+%% analysing, data is even moved from the COVER tables on the main
+%% node to the COLLECTION tables.
%%
%% The main node also has a table named 'cover_binary_code_table'
%% (?BINARY_TABLE). This table contains the binary code for each cover
%% compiled module. This is necessary so that the code can be loaded
%% on remote nodes that are started after the compilation.
%%
-
+%% PARELLALISM
+%% To take advantage of SMP when doing the cover analysis both the data
+%% collection and analysis has been parallelized. One process is spawned for
+%% each node when collecting data, and on the remote node when collecting data
+%% one process is spawned per module.
+%%
+%% When analyzing data it is possible to issue multiple analyse(_to_file)/X
+%% calls at once. They are however all calls (for backwardscompatability
+%% reasons) so the user of cover will have to spawn several processes to to the
+%% calls ( or use async_analyse_to_file ).
+%%
%% External exports
-export([start/0, start/1,
@@ -61,6 +75,9 @@
analyse/1, analyse/2, analyse/3, analyze/1, analyze/2, analyze/3,
analyse_to_file/1, analyse_to_file/2, analyse_to_file/3,
analyze_to_file/1, analyze_to_file/2, analyze_to_file/3,
+ async_analyse_to_file/1,async_analyse_to_file/2,
+ async_analyse_to_file/3, async_analyze_to_file/1,
+ async_analyze_to_file/2, async_analyze_to_file/3,
export/1, export/2, import/1,
modules/0, imported/0, imported_modules/0, which_nodes/0, is_compiled/1,
reset/1, reset/0,
@@ -100,8 +117,10 @@
}).
-define(COVER_TABLE, 'cover_internal_data_table').
+-define(COVER_CLAUSE_TABLE, 'cover_internal_clause_table').
-define(BINARY_TABLE, 'cover_binary_code_table').
-define(COLLECTION_TABLE, 'cover_collected_remote_data_table').
+-define(COLLECTION_CLAUSE_TABLE, 'cover_collected_remote_clause_table').
-define(TAG, cover_compiled).
-define(SERVER, cover_server).
@@ -114,6 +133,8 @@
true -> ?BLOCK(Expr)
end).
+-define(SPAWN_DBG(Tag,Value),put(Tag,Value)).
+
-include_lib("stdlib/include/ms_transform.hrl").
%%%----------------------------------------------------------------------
@@ -127,7 +148,10 @@ start() ->
case whereis(?SERVER) of
undefined ->
Starter = self(),
- Pid = spawn(fun() -> init_main(Starter) end),
+ Pid = spawn(fun() ->
+ ?SPAWN_DBG(start,[]),
+ init_main(Starter)
+ end),
Ref = erlang:monitor(process,Pid),
Return =
receive
@@ -382,6 +406,30 @@ analyze_to_file(Module, OptOrOut) -> analyse_to_file(Module, OptOrOut).
analyze_to_file(Module, OutFile, Options) ->
analyse_to_file(Module, OutFile, Options).
+async_analyse_to_file(Module) ->
+ do_spawn(?MODULE, analyse_to_file, [Module]).
+async_analyse_to_file(Module, OutFileOrOpts) ->
+ do_spawn(?MODULE, analyse_to_file, [Module, OutFileOrOpts]).
+async_analyse_to_file(Module, OutFile, Options) ->
+ do_spawn(?MODULE, analyse_to_file, [Module, OutFile, Options]).
+
+do_spawn(M,F,A) ->
+ spawn_link(fun() ->
+ case apply(M,F,A) of
+ {ok, _} ->
+ ok;
+ {error, Reason} ->
+ exit(Reason)
+ end
+ end).
+
+async_analyze_to_file(Module) ->
+ async_analyse_to_file(Module).
+async_analyze_to_file(Module, OutFileOrOpts) ->
+ async_analyse_to_file(Module, OutFileOrOpts).
+async_analyze_to_file(Module, OutFile, Options) ->
+ async_analyse_to_file(Module, OutFile, Options).
+
outfilename(Module,Opts) ->
case lists:member(html,Opts) of
true ->
@@ -500,6 +548,8 @@ remote_call(Node,Request) ->
Return
end.
+remote_reply(Proc,Reply) when is_pid(Proc) ->
+ Proc ! {?SERVER,Reply};
remote_reply(MainNode,Reply) ->
{?SERVER,MainNode} ! {?SERVER,Reply}.
@@ -509,9 +559,15 @@ remote_reply(MainNode,Reply) ->
init_main(Starter) ->
register(?SERVER,self()),
- ets:new(?COVER_TABLE, [set, public, named_table]),
+ %% Having write concurrancy here gives a 40% performance boost
+ %% when collect/1 is called.
+ ets:new(?COVER_TABLE, [set, public, named_table
+ ,{write_concurrency, true}
+ ]),
+ ets:new(?COVER_CLAUSE_TABLE, [set, public, named_table]),
ets:new(?BINARY_TABLE, [set, named_table]),
ets:new(?COLLECTION_TABLE, [set, public, named_table]),
+ ets:new(?COLLECTION_CLAUSE_TABLE, [set, public, named_table]),
process_flag(trap_exit,true),
Starter ! {?SERVER,started},
main_process_loop(#main_state{}).
@@ -593,40 +649,10 @@ main_process_loop(State) ->
end;
{From, {export,OutFile,Module}} ->
- case file:open(OutFile,[write,binary,raw]) of
- {ok,Fd} ->
- Reply =
- case Module of
- '_' ->
- export_info(State#main_state.imported),
- collect(State#main_state.nodes),
- do_export_table(State#main_state.compiled,
- State#main_state.imported,
- Fd);
- _ ->
- export_info(Module,State#main_state.imported),
- case is_loaded(Module, State) of
- {loaded, File} ->
- [{Module,Clauses}] =
- ets:lookup(?COVER_TABLE,Module),
- collect(Module, Clauses,
- State#main_state.nodes),
- do_export_table([{Module,File}],[],Fd);
- {imported, File, ImportFiles} ->
- %% don't know if I should allow this -
- %% export a module which is only imported
- Imported = [{Module,File,ImportFiles}],
- do_export_table([],Imported,Fd);
- _NotLoaded ->
- {error,{not_cover_compiled,Module}}
- end
- end,
- file:close(Fd),
- reply(From, Reply);
- {error,Reason} ->
- reply(From, {error, {cant_open_file,OutFile,Reason}})
-
- end,
+ spawn(fun() ->
+ ?SPAWN_DBG(export,{OutFile, Module}),
+ do_export(Module, OutFile, From, State)
+ end),
main_process_loop(State);
{From, {import,File}} ->
@@ -692,107 +718,73 @@ main_process_loop(State) ->
unregister(?SERVER),
reply(From, ok);
- {From, {Request, Module}} ->
- case is_loaded(Module, State) of
- {loaded, File} ->
- {Reply,State1} =
- case Request of
- {analyse, Analysis, Level} ->
- analyse_info(Module,State#main_state.imported),
- [{Module,Clauses}] =
- ets:lookup(?COVER_TABLE,Module),
- collect(Module,Clauses,State#main_state.nodes),
- R = do_analyse(Module, Analysis, Level, Clauses),
- {R,State};
-
- {analyse_to_file, OutFile, Opts} ->
- R = case find_source(File) of
- {beam,_BeamFile} ->
- {error,no_source_code_found};
- ErlFile ->
- Imported = State#main_state.imported,
- analyse_info(Module,Imported),
- [{Module,Clauses}] =
- ets:lookup(?COVER_TABLE,Module),
- collect(Module, Clauses,
- State#main_state.nodes),
- HTML = lists:member(html,Opts),
- do_analyse_to_file(Module,OutFile,
- ErlFile,HTML)
- end,
- {R,State};
-
- is_compiled ->
- {{file, File},State};
-
- reset ->
- R = do_reset_main_node(Module,
- State#main_state.nodes),
- Imported =
- remove_imported(Module,
- State#main_state.imported),
- {R,State#main_state{imported=Imported}}
- end,
- reply(From, Reply),
- main_process_loop(State1);
-
- {imported,File,_ImportFiles} ->
- {Reply,State1} =
- case Request of
- {analyse, Analysis, Level} ->
- analyse_info(Module,State#main_state.imported),
- [{Module,Clauses}] =
- ets:lookup(?COLLECTION_TABLE,Module),
- R = do_analyse(Module, Analysis, Level, Clauses),
- {R,State};
-
- {analyse_to_file, OutFile, Opts} ->
- R = case find_source(File) of
- {beam,_BeamFile} ->
- {error,no_source_code_found};
- ErlFile ->
- Imported = State#main_state.imported,
- analyse_info(Module,Imported),
- HTML = lists:member(html,Opts),
- do_analyse_to_file(Module,OutFile,
- ErlFile,HTML)
- end,
- {R,State};
-
- is_compiled ->
- {false,State};
-
- reset ->
- R = do_reset_collection_table(Module),
- Imported =
- remove_imported(Module,
- State#main_state.imported),
- {R,State#main_state{imported=Imported}}
- end,
- reply(From, Reply),
- main_process_loop(State1);
-
- NotLoaded ->
- Reply =
- case Request of
- is_compiled ->
- false;
- _ ->
- {error, {not_cover_compiled,Module}}
- end,
- Compiled =
- case NotLoaded of
- unloaded ->
- do_clear(Module),
- remote_unload(State#main_state.nodes,[Module]),
- update_compiled([Module],
- State#main_state.compiled);
- false ->
- State#main_state.compiled
+ {From, {{analyse, Analysis, Level}, Module}} ->
+ S = try
+ Loaded = is_loaded(Module, State),
+ spawn(fun() ->
+ ?SPAWN_DBG(analyse,{Module,Analysis, Level}),
+ do_parallel_analysis(
+ Module, Analysis, Level,
+ Loaded, From, State)
+ end),
+ State
+ catch throw:Reason ->
+ reply(From,{error, {not_cover_compiled,Module}}),
+ not_loaded(Module, Reason, State)
+ end,
+ main_process_loop(S);
+
+ {From, {{analyse_to_file, OutFile, Opts},Module}} ->
+ S = try
+ Loaded = is_loaded(Module, State),
+ spawn(fun() ->
+ ?SPAWN_DBG(analyse_to_file,
+ {Module,OutFile, Opts}),
+ do_parallel_analysis_to_file(
+ Module, OutFile, Opts,
+ Loaded, From, State)
+ end),
+ State
+ catch throw:Reason ->
+ reply(From,{error, {not_cover_compiled,Module}}),
+ not_loaded(Module, Reason, State)
+ end,
+ main_process_loop(S);
+
+ {From, {is_compiled, Module}} ->
+ S = try is_loaded(Module, State) of
+ {loaded, File} ->
+ reply(From,{file, File}),
+ State;
+ {imported,_File,_ImportFiles} ->
+ reply(From,false),
+ State
+ catch throw:Reason ->
+ reply(From,false),
+ not_loaded(Module, Reason, State)
+ end,
+ main_process_loop(S);
+
+ {From, {reset, Module}} ->
+ S = try
+ Loaded = is_loaded(Module,State),
+ R = case Loaded of
+ {loaded, _File} ->
+ do_reset_main_node(
+ Module, State#main_state.nodes);
+ {imported, _File, _} ->
+ do_reset_collection_table(Module)
end,
- reply(From, Reply),
- main_process_loop(State#main_state{compiled=Compiled})
- end;
+ Imported =
+ remove_imported(Module,
+ State#main_state.imported),
+ reply(From, R),
+ State#main_state{imported=Imported}
+ catch throw:Reason ->
+ reply(From,{error, {not_cover_compiled,Module}}),
+ not_loaded(Module, Reason, State)
+ end,
+ main_process_loop(S);
{'EXIT',Pid,_Reason} ->
%% Exit is trapped on the main node only, so this will only happen
@@ -807,17 +799,17 @@ main_process_loop(State) ->
main_process_loop(State)
end.
-
-
-
-
%%%----------------------------------------------------------------------
%%% cover_server on remote node
%%%----------------------------------------------------------------------
init_remote(Starter,MainNode) ->
register(?SERVER,self()),
- ets:new(?COVER_TABLE, [set, public, named_table]),
+ ets:new(?COVER_TABLE, [set, public, named_table
+ %% write_concurrency here makes otp_8270 break :(
+ %,{write_concurrency, true}
+ ]),
+ ets:new(?COVER_CLAUSE_TABLE, [set, public, named_table]),
Starter ! {self(),started},
remote_process_loop(#remote_state{main_node=MainNode}).
@@ -843,29 +835,14 @@ remote_process_loop(State) ->
remote_process_loop(State);
{remote,collect,Module,CollectorPid} ->
- MS =
- case Module of
- '_' -> ets:fun2ms(fun({M,C}) when is_atom(M) -> C end);
- _ -> ets:fun2ms(fun({M,C}) when M=:=Module -> C end)
- end,
- AllClauses = lists:flatten(ets:select(?COVER_TABLE,MS)),
-
- %% Sending clause by clause in order to avoid large lists
- lists:foreach(
- fun({M,F,A,C,_L}) ->
- Pattern =
- {#bump{module=M, function=F, arity=A, clause=C}, '_'},
- Bumps = ets:match_object(?COVER_TABLE, Pattern),
- %% Reset
- lists:foreach(fun({Bump,_N}) ->
- ets:insert(?COVER_TABLE, {Bump,0})
- end,
- Bumps),
- CollectorPid ! {chunk,Bumps}
- end,
- AllClauses),
- CollectorPid ! done,
- remote_reply(State#remote_state.main_node, ok),
+ self() ! {remote,collect,Module,CollectorPid, ?SERVER};
+
+ {remote,collect,Module,CollectorPid,From} ->
+ spawn(fun() ->
+ ?SPAWN_DBG(remote_collect,
+ {Module, CollectorPid, From}),
+ do_collect(Module, CollectorPid, From)
+ end),
remote_process_loop(State);
{remote,stop} ->
@@ -894,6 +871,33 @@ remote_process_loop(State) ->
end.
+do_collect(Module, CollectorPid, From) ->
+ AllMods =
+ case Module of
+ '_' -> ets:tab2list(?COVER_CLAUSE_TABLE);
+ _ -> ets:lookup(?COVER_CLAUSE_TABLE, Module)
+ end,
+
+ %% Sending clause by clause in order to avoid large lists
+ pmap(
+ fun({_Mod,Clauses}) ->
+ lists:map(fun(Clause) ->
+ send_collected_data(Clause, CollectorPid)
+ end,Clauses)
+ end,AllMods),
+ CollectorPid ! done,
+ remote_reply(From, ok).
+
+send_collected_data({M,F,A,C,_L}, CollectorPid) ->
+ Pattern =
+ {#bump{module=M, function=F, arity=A, clause=C}, '_'},
+ Bumps = ets:match_object(?COVER_TABLE, Pattern),
+ %% Reset
+ lists:foreach(fun({Bump,_N}) ->
+ ets:insert(?COVER_TABLE, {Bump,0})
+ end,
+ Bumps),
+ CollectorPid ! {chunk,Bumps}.
reload_originals([{Module,_File}|Compiled]) ->
do_reload_original(Module),
@@ -932,6 +936,9 @@ load_compiled([{Module,File,Binary,InitialTable}|Compiled],Acc) ->
load_compiled([],Acc) ->
Acc.
+insert_initial_data([Item|Items]) when is_atom(element(1,Item)) ->
+ ets:insert(?COVER_CLAUSE_TABLE, Item),
+ insert_initial_data(Items);
insert_initial_data([Item|Items]) ->
ets:insert(?COVER_TABLE, Item),
insert_initial_data(Items);
@@ -957,7 +964,10 @@ remote_start(MainNode) ->
case whereis(?SERVER) of
undefined ->
Starter = self(),
- Pid = spawn(fun() -> init_remote(Starter,MainNode) end),
+ Pid = spawn(fun() ->
+ ?SPAWN_DBG(remote_start,{MainNode}),
+ init_remote(Starter,MainNode)
+ end),
Ref = erlang:monitor(process,Pid),
Return =
receive
@@ -972,14 +982,25 @@ remote_start(MainNode) ->
{error,{already_started,Pid}}
end.
-%% Load a set of cover compiled modules on remote nodes
-remote_load_compiled(Nodes,Compiled0) ->
- Compiled = lists:map(fun get_data_for_remote_loading/1,Compiled0),
+%% Load a set of cover compiled modules on remote nodes,
+%% We do it ?MAX_MODS modules at a time so that we don't
+%% run out of memory on the cover_server node.
+-define(MAX_MODS, 10).
+remote_load_compiled(Nodes,Compiled) ->
+ remote_load_compiled(Nodes, Compiled, [], 0).
+remote_load_compiled(_Nodes, [], [], _ModNum) ->
+ ok;
+remote_load_compiled(Nodes, Compiled, Acc, ModNum)
+ when Compiled == []; ModNum == ?MAX_MODS ->
lists:foreach(
fun(Node) ->
- remote_call(Node,{remote,load_compiled,Compiled})
+ remote_call(Node,{remote,load_compiled,Acc})
end,
- Nodes).
+ Nodes),
+ remote_load_compiled(Nodes, Compiled, [], 0);
+remote_load_compiled(Nodes, [MF | Rest], Acc, ModNum) ->
+ remote_load_compiled(
+ Nodes, Rest, [get_data_for_remote_loading(MF) | Acc], ModNum + 1).
%% Read all data needed for loading a cover compiled module on a remote node
%% Binary is the beam code for the module and InitialTable is the initial
@@ -987,15 +1008,15 @@ remote_load_compiled(Nodes,Compiled0) ->
get_data_for_remote_loading({Module,File}) ->
[{Module,Binary}] = ets:lookup(?BINARY_TABLE,Module),
%%! The InitialTable list will be long if the module is big - what to do??
- InitialTable = ets:select(?COVER_TABLE,ms(Module)),
- {Module,File,Binary,InitialTable}.
+ InitialBumps = ets:select(?COVER_TABLE,ms(Module)),
+ InitialClauses = ets:lookup(?COVER_CLAUSE_TABLE,Module),
+
+ {Module,File,Binary,InitialBumps ++ InitialClauses}.
%% Create a match spec which returns the clause info {Module,InitInfo} and
%% all #bump keys for the given module with 0 number of calls.
ms(Module) ->
- ets:fun2ms(fun({Module,InitInfo}) ->
- {Module,InitInfo};
- ({Key,_}) when is_record(Key,bump),Key#bump.module=:=Module ->
+ ets:fun2ms(fun({Key,_}) when Key#bump.module=:=Module ->
{Key,0}
end).
@@ -1017,27 +1038,30 @@ remote_reset(Module,Nodes) ->
%% Collect data from remote nodes - used for analyse or stop(Node)
remote_collect(Module,Nodes,Stop) ->
- CollectorPid = spawn(fun() -> collector_proc(length(Nodes)) end),
- lists:foreach(
- fun(Node) ->
- remote_call(Node,{remote,collect,Module,CollectorPid}),
- if Stop -> remote_call(Node,{remote,stop});
- true -> ok
- end
- end,
- Nodes).
+ pmap(fun(Node) ->
+ ?SPAWN_DBG(remote_collect,
+ {Module, Nodes, Stop}),
+ do_collection(Node, Module, Stop)
+ end,
+ Nodes).
+
+do_collection(Node, Module, Stop) ->
+ CollectorPid = spawn(fun collector_proc/0),
+ remote_call(Node,{remote,collect,Module,CollectorPid, self()}),
+ if Stop -> remote_call(Node,{remote,stop});
+ true -> ok
+ end.
%% Process which receives chunks of data from remote nodes - either when
%% analysing or when stopping cover on the remote nodes.
-collector_proc(0) ->
- ok;
-collector_proc(N) ->
+collector_proc() ->
+ ?SPAWN_DBG(collector_proc, []),
receive
{chunk,Chunk} ->
insert_in_collection_table(Chunk),
- collector_proc(N);
+ collector_proc();
done ->
- collector_proc(N-1)
+ ok
end.
insert_in_collection_table([{Key,Val}|Chunk]) ->
@@ -1052,7 +1076,13 @@ insert_in_collection_table(Key,Val) ->
ets:update_counter(?COLLECTION_TABLE,
Key,Val);
false ->
- ets:insert(?COLLECTION_TABLE,{Key,Val})
+ %% Make sure that there are no race conditions from ets:member
+ case ets:insert_new(?COLLECTION_TABLE,{Key,Val}) of
+ false ->
+ insert_in_collection_table(Key,Val);
+ _ ->
+ ok
+ end
end.
@@ -1073,14 +1103,15 @@ analyse_info(Module,Imported) ->
export_info(_Module,[]) ->
ok;
-export_info(Module,Imported) ->
- imported_info("Export",Module,Imported).
+export_info(_Module,_Imported) ->
+ %% Do not print that the export includes imported modules
+ ok.
export_info([]) ->
ok;
-export_info(Imported) ->
- AllImportFiles = get_all_importfiles(Imported,[]),
- io:format("Export includes data from imported files\n~p\n",[AllImportFiles]).
+export_info(_Imported) ->
+ %% Do not print that the export includes imported modules
+ ok.
get_all_importfiles([{_M,_F,ImportFiles}|Imported],Acc) ->
NewAcc = do_get_all_importfiles(ImportFiles,Acc),
@@ -1153,14 +1184,14 @@ is_loaded(Module, State) ->
{ok, File} ->
case code:which(Module) of
?TAG -> {loaded, File};
- _ -> unloaded
+ _ -> throw(unloaded)
end;
false ->
case get_file(Module,State#main_state.imported) of
{ok,File,ImportFiles} ->
{imported, File, ImportFiles};
false ->
- false
+ throw(not_loaded)
end
end.
@@ -1259,7 +1290,7 @@ do_compile_beam(Module,Beam) ->
%% Store info about all function clauses in database
InitInfo = reverse(Vars#vars.init_info),
- ets:insert(?COVER_TABLE, {Module, InitInfo}),
+ ets:insert(?COVER_CLAUSE_TABLE, {Module, InitInfo}),
%% Store binary code so it can be loaded on remote nodes
ets:insert(?BINARY_TABLE, {Module, Binary}),
@@ -1793,9 +1824,8 @@ common_elems(L1, L2) ->
%% Collect data for all modules
collect(Nodes) ->
%% local node
- MS = ets:fun2ms(fun({M,C}) when is_atom(M) -> {M,C} end),
- AllClauses = ets:select(?COVER_TABLE,MS),
- move_modules(AllClauses),
+ AllClauses = ets:tab2list(?COVER_CLAUSE_TABLE),
+ pmap(fun move_modules/1,AllClauses),
%% remote nodes
remote_collect('_',Nodes,false).
@@ -1803,7 +1833,7 @@ collect(Nodes) ->
%% Collect data for one module
collect(Module,Clauses,Nodes) ->
%% local node
- move_modules([{Module,Clauses}]),
+ move_modules({Module,Clauses}),
%% remote nodes
remote_collect(Module,Nodes,false).
@@ -1811,12 +1841,9 @@ collect(Module,Clauses,Nodes) ->
%% When analysing, the data from the local ?COVER_TABLE is moved to the
%% ?COLLECTION_TABLE. Resetting data in ?COVER_TABLE
-move_modules([{Module,Clauses}|AllClauses]) ->
- ets:insert(?COLLECTION_TABLE,{Module,Clauses}),
- move_clauses(Clauses),
- move_modules(AllClauses);
-move_modules([]) ->
- ok.
+move_modules({Module,Clauses}) ->
+ ets:insert(?COLLECTION_CLAUSE_TABLE,{Module,Clauses}),
+ move_clauses(Clauses).
move_clauses([{M,F,A,C,_L}|Clauses]) ->
Pattern = {#bump{module=M, function=F, arity=A, clause=C}, '_'},
@@ -1855,6 +1882,22 @@ find_source(File0) ->
end
end.
+do_parallel_analysis(Module, Analysis, Level, Loaded, From, State) ->
+ analyse_info(Module,State#main_state.imported),
+ C = case Loaded of
+ {loaded, _File} ->
+ [{Module,Clauses}] =
+ ets:lookup(?COVER_CLAUSE_TABLE,Module),
+ collect(Module,Clauses,State#main_state.nodes),
+ Clauses;
+ _ ->
+ [{Module,Clauses}] =
+ ets:lookup(?COLLECTION_CLAUSE_TABLE,Module),
+ Clauses
+ end,
+ R = do_analyse(Module, Analysis, Level, C),
+ reply(From, R).
+
%% do_analyse(Module, Analysis, Level, Clauses)-> {ok,Answer} | {error,Error}
%% Clauses = [{Module,Function,Arity,Clause,Lines}]
do_analyse(Module, Analysis, line, _Clauses) ->
@@ -1931,6 +1974,28 @@ merge_functions([{_MFA,R}|Functions], MFun, Result) ->
merge_functions([], _MFun, Result) ->
Result.
+do_parallel_analysis_to_file(Module, OutFile, Opts, Loaded, From, State) ->
+ File = case Loaded of
+ {loaded, File0} ->
+ [{Module,Clauses}] =
+ ets:lookup(?COVER_CLAUSE_TABLE,Module),
+ collect(Module, Clauses,
+ State#main_state.nodes),
+ File0;
+ {imported, File0, _} ->
+ File0
+ end,
+ case find_source(File) of
+ {beam,_BeamFile} ->
+ reply(From, {error,no_source_code_found});
+ ErlFile ->
+ analyse_info(Module,State#main_state.imported),
+ HTML = lists:member(html,Opts),
+ R = do_analyse_to_file(Module,OutFile,
+ ErlFile,HTML),
+ reply(From, R)
+ end.
+
%% do_analyse_to_file(Module,OutFile,ErlFile) -> {ok,OutFile} | {error,Error}
%% Module = atom()
%% OutFile = ErlFile = string()
@@ -2027,6 +2092,42 @@ fill2() -> ".| ".
fill3() -> "| ".
%%%--Export--------------------------------------------------------------
+do_export(Module, OutFile, From, State) ->
+ case file:open(OutFile,[write,binary,raw]) of
+ {ok,Fd} ->
+ Reply =
+ case Module of
+ '_' ->
+ export_info(State#main_state.imported),
+ collect(State#main_state.nodes),
+ do_export_table(State#main_state.compiled,
+ State#main_state.imported,
+ Fd);
+ _ ->
+ export_info(Module,State#main_state.imported),
+ try is_loaded(Module, State) of
+ {loaded, File} ->
+ [{Module,Clauses}] =
+ ets:lookup(?COVER_CLAUSE_TABLE,Module),
+ collect(Module, Clauses,
+ State#main_state.nodes),
+ do_export_table([{Module,File}],[],Fd);
+ {imported, File, ImportFiles} ->
+ %% don't know if I should allow this -
+ %% export a module which is only imported
+ Imported = [{Module,File,ImportFiles}],
+ do_export_table([],Imported,Fd)
+ catch throw:_ ->
+ {error,{not_cover_compiled,Module}}
+ end
+ end,
+ file:close(Fd),
+ reply(From, Reply);
+ {error,Reason} ->
+ reply(From, {error, {cant_open_file,OutFile,Reason}})
+
+ end.
+
do_export_table(Compiled, Imported, Fd) ->
ModList = merge(Imported,Compiled),
write_module_data(ModList,Fd).
@@ -2043,7 +2144,7 @@ merge([],ModuleList) ->
write_module_data([{Module,File}|ModList],Fd) ->
write({file,Module,File},Fd),
- [Clauses] = ets:lookup(?COLLECTION_TABLE,Module),
+ [Clauses] = ets:lookup(?COLLECTION_CLAUSE_TABLE,Module),
write(Clauses,Fd),
ModuleData = ets:match_object(?COLLECTION_TABLE,{#bump{module=Module},'_'}),
do_write_module_data(ModuleData,Fd),
@@ -2093,7 +2194,7 @@ do_import_to_table(Fd,ImportFile,Imported,DontImport) ->
{Module,Clauses} ->
case lists:member(Module,DontImport) of
false ->
- ets:insert(?COLLECTION_TABLE,{Module,Clauses});
+ ets:insert(?COLLECTION_CLAUSE_TABLE,{Module,Clauses});
true ->
ok
end,
@@ -2127,14 +2228,14 @@ do_reset_main_node(Module,Nodes) ->
remote_reset(Module,Nodes).
do_reset_collection_table(Module) ->
- ets:delete(?COLLECTION_TABLE,Module),
+ ets:delete(?COLLECTION_CLAUSE_TABLE,Module),
ets:match_delete(?COLLECTION_TABLE, {#bump{module=Module},'_'}).
%% do_reset(Module) -> ok
%% The reset is done on a per-clause basis to avoid building
%% long lists in the case of very large modules
do_reset(Module) ->
- [{Module,Clauses}] = ets:lookup(?COVER_TABLE, Module),
+ [{Module,Clauses}] = ets:lookup(?COVER_CLAUSE_TABLE, Module),
do_reset2(Clauses).
do_reset2([{M,F,A,C,_L}|Clauses]) ->
@@ -2149,10 +2250,19 @@ do_reset2([]) ->
ok.
do_clear(Module) ->
- ets:match_delete(?COVER_TABLE, {Module,'_'}),
+ ets:match_delete(?COVER_CLAUSE_TABLE, {Module,'_'}),
ets:match_delete(?COVER_TABLE, {#bump{module=Module},'_'}),
ets:match_delete(?COLLECTION_TABLE, {#bump{module=Module},'_'}).
+not_loaded(Module, unloaded, State) ->
+ do_clear(Module),
+ remote_unload(State#main_state.nodes,[Module]),
+ Compiled = update_compiled([Module],
+ State#main_state.compiled),
+ State#main_state{ compiled = Compiled };
+not_loaded(_Module,_Else, State) ->
+ State.
+
%%%--Div-----------------------------------------------------------------
@@ -2180,3 +2290,30 @@ escape_lt_and_gt1([],Acc) ->
lists:reverse(Acc);
escape_lt_and_gt1([H|T],Acc) ->
escape_lt_and_gt1(T,[H|Acc]).
+
+pmap(Fun, List) ->
+ pmap(Fun, List, 20).
+pmap(Fun, List, Limit) ->
+ pmap(Fun, List, [], Limit, 0, []).
+pmap(Fun, [E | Rest], Pids, Limit, Cnt, Acc) when Cnt < Limit ->
+ Collector = self(),
+ Pid = spawn_link(fun() ->
+ ?SPAWN_DBG(pmap,E),
+ Collector ! {res,self(),Fun(E)}
+ end),
+ erlang:monitor(process, Pid),
+ pmap(Fun, Rest, Pids ++ [Pid], Limit, Cnt + 1, Acc);
+pmap(Fun, List, [Pid | Pids], Limit, Cnt, Acc) ->
+ receive
+ {'DOWN', _Ref, process, _, _} ->
+ pmap(Fun, List, [Pid | Pids], Limit, Cnt - 1, Acc);
+ {res, Pid, Res} ->
+ pmap(Fun, List, Pids, Limit, Cnt, [Res | Acc])
+ end;
+pmap(_Fun, [], [], _Limit, 0, Acc) ->
+ lists:reverse(Acc);
+pmap(Fun, [], [], Limit, Cnt, Acc) ->
+ receive
+ {'DOWN', _Ref, process, _, _} ->
+ pmap(Fun, [], [], Limit, Cnt - 1, Acc)
+ end.
diff --git a/lib/tools/src/eprof.erl b/lib/tools/src/eprof.erl
index f7c1b76364..87fdc1fa34 100644
--- a/lib/tools/src/eprof.erl
+++ b/lib/tools/src/eprof.erl
@@ -136,7 +136,7 @@ handle_call({analyze, procs, Opts}, _, #state{ bpd = #bpd{ p = Ps, us = Tus} = B
lists:foreach(fun
({Pid, Mfas}) ->
{Pn, Pus} = sum_bp_total_n_us(Mfas),
- format(Fd, "~n****** Process ~w -- ~s % of profiled time *** ~n", [Pid, s("~.2f", [100.0*(Pus/Tus)])]),
+ format(Fd, "~n****** Process ~w -- ~s % of profiled time *** ~n", [Pid, s("~.2f", [100.0*divide(Pus,Tus)])]),
print_bp_mfa(Mfas, {Pn,Pus}, Fd, Opts),
ok
end, gb_trees:to_list(Ps)),
@@ -415,15 +415,15 @@ sort_mfa(Bpfs, mfa) when is_list(Bpfs) ->
end, Bpfs);
sort_mfa(Bpfs, time) when is_list(Bpfs) ->
lists:sort(fun
- ({_,{A,_}}, {_,{B,_}}) when A < B -> true;
+ ({_,{_,A}}, {_,{_,B}}) when A < B -> true;
(_, _) -> false
end, Bpfs);
sort_mfa(Bpfs, calls) when is_list(Bpfs) ->
lists:sort(fun
- ({_,{_,A}}, {_,{_,B}}) when A < B -> true;
+ ({_,{A,_}}, {_,{B,_}}) when A < B -> true;
(_, _) -> false
end, Bpfs);
-sort_mfa(Bpfs, _) when is_list(Bpfs) -> sort_mfa(Bpfs, calls).
+sort_mfa(Bpfs, _) when is_list(Bpfs) -> sort_mfa(Bpfs, time).
filter_mfa(Bpfs, Ts) when is_list(Ts) ->
filter_mfa(Bpfs, [], proplists:get_value(calls, Ts, 0), proplists:get_value(time, Ts, 0));
@@ -443,8 +443,8 @@ string_bp_mfa([{Mfa, {Count, Time}}|Mfas], Tus, {MfaW, CountW, PercW, TimeW, TpC
Smfa = s(Mfa),
Scount = s(Count),
Stime = s(Time),
- Sperc = s("~.2f", [100*(Time/Tus)]),
- Stpc = s("~.2f", [Time/Count]),
+ Sperc = s("~.2f", [100*divide(Time,Tus)]),
+ Stpc = s("~.2f", [divide(Time,Count)]),
string_bp_mfa(Mfas, Tus, {
erlang:max(MfaW, length(Smfa)),
@@ -484,3 +484,6 @@ format(Fd, Format, Strings) ->
io:format(Fd, Format, Strings),
io:format(Format, Strings),
ok.
+
+divide(_,0) -> 0.0;
+divide(T,N) -> T/N.
diff --git a/lib/tools/test/Makefile b/lib/tools/test/Makefile
index 3a59be758a..826a8f3ee8 100644
--- a/lib/tools/test/Makefile
+++ b/lib/tools/test/Makefile
@@ -39,7 +39,8 @@ INSTALL_PROGS= $(TARGET_FILES)
EMAKEFILE=Emakefile
-SPEC_FILES= tools.spec tools.spec.win
+SPEC_FILES= tools.spec
+COVER_FILE = tools.cover
# ----------------------------------------------------
# Release directory specification
@@ -84,7 +85,8 @@ release_spec: opt
release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(SPEC_FILES) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SPEC_FILES) $(COVER_FILE) $(EMAKEFILE) \
+ $(ERL_FILES) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl
index b9ccd62d0b..494ef55f59 100644
--- a/lib/tools/test/cover_SUITE.erl
+++ b/lib/tools/test/cover_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %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
@@ -18,13 +18,16 @@
%%
-module(cover_SUITE).
--export([all/1]).
+-export([all/0, init_per_testcase/2, end_per_testcase/2,
+ suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+
-export([start/1, compile/1, analyse/1, misc/1, stop/1,
distribution/1, export_import/1,
otp_5031/1, eif/1, otp_5305/1, otp_5418/1, otp_6115/1, otp_7095/1,
otp_8188/1, otp_8270/1, otp_8273/1, otp_8340/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%%----------------------------------------------------------------------
%% The following directory structure is assumed:
@@ -37,18 +40,50 @@
%% y
%%----------------------------------------------------------------------
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
case whereis(cover_server) of
undefined ->
[start, compile, analyse, misc, stop, distribution,
- export_import,
- otp_5031, eif, otp_5305, otp_5418, otp_6115, otp_7095,
- otp_8188, otp_8270, otp_8273, otp_8340];
+ export_import, otp_5031, eif, otp_5305, otp_5418,
+ otp_6115, otp_7095, otp_8188, otp_8270, otp_8273,
+ otp_8340];
_pid ->
- {skip,"It looks like the test server is running cover. "
- "Can't run cover test."}
+ {skip,
+ "It looks like the test server is running "
+ "cover. Can't run cover test."}
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_testcase(TC, Config) when TC =:= misc; TC =:= compile ->
+ case code:which(crypto) of
+ Path when is_list(Path) ->
+ init_per_testcase(dummy_tc, Config);
+ _Else ->
+ {skip, "No crypto file to test with"}
+ end;
+init_per_testcase(_TestCase, Config) ->
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ %cover:stop(),
+ ok.
+
start(suite) -> [];
start(Config) when is_list(Config) ->
?line ok = file:set_cwd(?config(data_dir, Config)),
@@ -381,8 +416,8 @@ export_import(Config) when is_list(Config) ->
?line {ok,a} = cover:compile(a),
?line ?t:capture_start(),
?line ok = cover:export("all_exported"),
- ?line [Text2] = ?t:capture_get(),
- ?line "Export includes data from imported files"++_ = lists:flatten(Text2),
+ ?line [] = ?t:capture_get(),
+% ?line "Export includes data from imported files"++_ = lists:flatten(Text2),
?line ?t:capture_stop(),
?line ok = cover:stop(),
?line ok = cover:import("all_exported"),
diff --git a/lib/tools/test/cprof_SUITE.erl b/lib/tools/test/cprof_SUITE.erl
index e697cc1571..b6f786d33f 100644
--- a/lib/tools/test/cprof_SUITE.erl
+++ b/lib/tools/test/cprof_SUITE.erl
@@ -41,7 +41,7 @@
-define(config(A,B),config(A,B)).
-export([config/2]).
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-endif.
-ifdef(debug).
@@ -63,14 +63,17 @@ config(data_dir, _) ->
"cprof_SUITE_data".
-else.
%% When run in test server.
--export([all/1, init_per_testcase/2, fin_per_testcase/2, not_run/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2,
+ not_run/1]).
-export([basic/1, on_load/1, modules/1]).
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(test_server:seconds(30)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
erlang:trace_pattern({'_','_','_'}, false, [local,meta,call_count]),
erlang:trace_pattern(on_load, false, [local,meta,call_count]),
erlang:trace(all, false, [all]),
@@ -78,16 +81,30 @@ fin_per_testcase(_Case, Config) ->
test_server:timetrap_cancel(Dog),
ok.
-all(doc) ->
- ["Test the cprof profiling tool."];
-all(suite) ->
- case test_server:is_native(?MODULE) of
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:is_native(cprof_SUITE) of
true -> [not_run];
false -> [basic, on_load, modules]
-%, on_and_off, info,
-% pause_and_restart, combo]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
not_run(Config) when is_list(Config) ->
{skipped,"Native code"}.
diff --git a/lib/tools/test/emem_SUITE.erl b/lib/tools/test/emem_SUITE.erl
index 430fa86c6c..8b38e7d3a8 100644
--- a/lib/tools/test/emem_SUITE.erl
+++ b/lib/tools/test/emem_SUITE.erl
@@ -24,7 +24,8 @@
receive_and_save_trace/2, send_trace/2]).
--export([all/1, init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2]).
-export([live_node/1,
'sparc_sunos5.8_32b_emt2.0'/1,
@@ -41,7 +42,7 @@
-include_lib("kernel/include/file.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(DEFAULT_TIMEOUT, ?t:minutes(5)).
@@ -65,23 +66,32 @@
%%
%%
-all(doc) -> [];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
case is_debug_compiled() of
- true -> {skipped, "Not run when debug compiled"};
+ true -> {skip, "Not run when debug compiled"};
false -> test_cases()
end.
-
-test_cases() ->
- [live_node,
- 'sparc_sunos5.8_32b_emt2.0',
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+test_cases() ->
+ [live_node, 'sparc_sunos5.8_32b_emt2.0',
'pc_win2000_32b_emt2.0',
'pc.smp_linux2.2.19pre17_32b_emt2.0',
'powerpc_darwin7.7.0_32b_emt2.0',
'alpha_osf1v5.1_64b_emt2.0',
'sparc_sunos5.8_64b_emt2.0',
- 'sparc_sunos5.8_32b_emt1.0',
- 'pc_win2000_32b_emt1.0',
+ 'sparc_sunos5.8_32b_emt1.0', 'pc_win2000_32b_emt1.0',
'powerpc_darwin7.7.0_32b_emt1.0',
'alpha_osf1v5.1_64b_emt1.0',
'sparc_sunos5.8_64b_emt1.0'].
@@ -100,7 +110,7 @@ init_per_testcase(Case, Config) when is_list(Config) ->
[{watchdog, Dog}, {testcase, Case} | Config])
end.
-fin_per_testcase(_Case, Config) when is_list(Config) ->
+end_per_testcase(_Case, Config) when is_list(Config) ->
ignore_cores:restore(Config),
Dog = ?config(watchdog, Config),
?t:timetrap_cancel(Dog),
@@ -700,8 +710,8 @@ start_node(Name, Args) ->
% stop_node(Node) ->
% ?t:stop_node(Node).
-is_debug_compiled() ->
- is_debug_compiled(erlang:system_info(system_version)).
+is_debug_compiled() ->
+is_debug_compiled(erlang:system_info(system_version)).
is_debug_compiled([$d,$e,$b,$u,$g | _]) ->
true;
diff --git a/lib/tools/test/eprof_SUITE.erl b/lib/tools/test/eprof_SUITE.erl
index 67607c6cf2..16246d5e0b 100644
--- a/lib/tools/test/eprof_SUITE.erl
+++ b/lib/tools/test/eprof_SUITE.erl
@@ -18,11 +18,31 @@
%%
-module(eprof_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
--export([all/1,tiny/1,eed/1,basic/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,tiny/1,eed/1,basic/1]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [basic, tiny, eed].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
-all(suite) -> [basic,tiny,eed].
basic(suite) -> [];
basic(Config) when is_list(Config) ->
diff --git a/lib/tools/test/fprof_SUITE.erl b/lib/tools/test/fprof_SUITE.erl
index 1cd9ac7824..78de77526c 100644
--- a/lib/tools/test/fprof_SUITE.erl
+++ b/lib/tools/test/fprof_SUITE.erl
@@ -18,10 +18,11 @@
%%
-module(fprof_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server framework exports
--export([all/1, not_run/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, not_run/1]).
%% Test suites
-export([stack_seq/1, tail_seq/1, create_file_slow/1, spawn_simple/1,
@@ -54,18 +55,33 @@
-all(doc) ->
- ["Test the 'fprof' profiling tool."];
-all(suite) ->
- case test_server:is_native(?MODULE) of
- true ->
- [not_run];
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ case test_server:is_native(fprof_SUITE) of
+ true -> [not_run];
false ->
[stack_seq, tail_seq, create_file_slow, spawn_simple,
imm_tail_seq, imm_create_file_slow, imm_compile,
cpu_create_file_slow]
end.
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
not_run(Config) when is_list(Config) ->
{skipped, "Native code"}.
diff --git a/lib/tools/test/ignore_cores.erl b/lib/tools/test/ignore_cores.erl
index 8902a469ef..8b1ac0fe6c 120000..100644
--- a/lib/tools/test/ignore_cores.erl
+++ b/lib/tools/test/ignore_cores.erl
@@ -1 +1,158 @@
-../../../erts/test/ignore_cores.erl \ No newline at end of file
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File : ignore_cores.erl
+%%% Author : Rickard Green <[email protected]>
+%%% Description :
+%%%
+%%% Created : 11 Feb 2008 by Rickard Green <[email protected]>
+%%%-------------------------------------------------------------------
+
+-module(ignore_cores).
+
+-include_lib("test_server/include/test_server.hrl").
+
+-export([init/1, fini/1, setup/3, setup/4, restore/1, dir/1]).
+
+-record(ignore_cores, {org_cwd,
+ org_path,
+ org_pwd_env,
+ ign_dir = false,
+ cores_dir = false}).
+
+%%
+%% Takes a testcase config
+%%
+
+init(Config) ->
+ {ok, OrgCWD} = file:get_cwd(),
+ [{ignore_cores,
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = code:get_path(),
+ org_pwd_env = os:getenv("PWD")}}
+ | lists:keydelete(ignore_cores, 1, Config)].
+
+fini(Config) ->
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD} = ?config(ignore_cores, Config),
+ ok = file:set_cwd(OrgCWD),
+ true = code:set_path(OrgPath),
+ case OrgPWD of
+ false -> ok;
+ _ -> true = os:putenv("PWD", OrgPWD)
+ end,
+ lists:keydelete(ignore_cores, 1, Config).
+
+setup(Suite, Testcase, Config) ->
+ setup(Suite, Testcase, Config, false).
+
+setup(Suite, Testcase, Config, SetCwd) when is_atom(Suite),
+ is_atom(Testcase),
+ is_list(Config) ->
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD} = ?config(ignore_cores, Config),
+ Path = lists:map(fun (".") -> OrgCWD; (Dir) -> Dir end, OrgPath),
+ true = code:set_path(Path),
+ PrivDir = ?config(priv_dir, Config),
+ IgnDir = filename:join([PrivDir,
+ atom_to_list(Suite)
+ ++ "_"
+ ++ atom_to_list(Testcase)
+ ++ "_wd"]),
+ ok = file:make_dir(IgnDir),
+ case SetCwd of
+ false ->
+ ok;
+ _ ->
+ ok = file:set_cwd(IgnDir),
+ OrgPWD = case os:getenv("PWD") of
+ false -> false;
+ PWD ->
+ os:putenv("PWD", IgnDir),
+ PWD
+ end
+ end,
+ ok = file:write_file(filename:join([IgnDir, "ignore_core_files"]), <<>>),
+ %% cores are dumped in /cores on MacOS X
+ CoresDir = case {?t:os_type(), filelib:is_dir("/cores")} of
+ {{unix,darwin}, true} ->
+ filelib:fold_files("/cores",
+ "^core.*$",
+ false,
+ fun (C,Cs) -> [C|Cs] end,
+ []);
+ _ ->
+ false
+ end,
+ lists:keyreplace(ignore_cores,
+ 1,
+ Config,
+ {ignore_cores,
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD,
+ ign_dir = IgnDir,
+ cores_dir = CoresDir}}).
+
+restore(Config) ->
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD,
+ ign_dir = IgnDir,
+ cores_dir = CoresDir} = ?config(ignore_cores, Config),
+ try
+ case CoresDir of
+ false ->
+ ok;
+ _ ->
+ %% Move cores dumped by these testcases in /cores
+ %% to cwd.
+ lists:foreach(fun (C) ->
+ case lists:member(C, CoresDir) of
+ true -> ok;
+ _ ->
+ Dst = filename:join(
+ [IgnDir,
+ filename:basename(C)]),
+ {ok, _} = file:copy(C, Dst),
+ file:delete(C)
+ end
+ end,
+ filelib:fold_files("/cores",
+ "^core.*$",
+ false,
+ fun (C,Cs) -> [C|Cs] end,
+ []))
+ end
+ after
+ catch file:set_cwd(OrgCWD),
+ catch code:set_path(OrgPath),
+ case OrgPWD of
+ false -> ok;
+ _ -> catch os:putenv("PWD", OrgPWD)
+ end
+ end.
+
+
+dir(Config) ->
+ #ignore_cores{ign_dir = Dir} = ?config(ignore_cores, Config),
+ Dir.
diff --git a/lib/tools/test/instrument_SUITE.erl b/lib/tools/test/instrument_SUITE.erl
index da5930e015..6800a94f94 100644
--- a/lib/tools/test/instrument_SUITE.erl
+++ b/lib/tools/test/instrument_SUITE.erl
@@ -18,22 +18,43 @@
%%
-module(instrument_SUITE).
--export([all/1,init_per_testcase/2,fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ init_per_testcase/2,end_per_testcase/2]).
-export(['+Mim true'/1, '+Mis true'/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
init_per_testcase(_Case, Config) ->
?line Dog=?t:timetrap(10000),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
?t:timetrap_cancel(Dog),
ok.
-all(suite) -> ['+Mim true', '+Mis true'].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ ['+Mim true', '+Mis true'].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
'+Mim true'(doc) -> ["Check that memory data can be read and processed"];
'+Mim true'(suite) -> [];
diff --git a/lib/tools/test/lcnt_SUITE.erl b/lib/tools/test/lcnt_SUITE.erl
index e6866f721d..21383fa544 100644
--- a/lib/tools/test/lcnt_SUITE.erl
+++ b/lib/tools/test/lcnt_SUITE.erl
@@ -18,10 +18,10 @@
%%
-module(lcnt_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Test server specific exports
--export([all/1]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
-export([init_per_suite/1, end_per_suite/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -51,10 +51,21 @@ end_per_testcase(_Case, Config) ->
?t:timetrap_cancel(Dog),
ok.
-all(suite) ->
- % Test cases
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[load_v1, conflicts, locations, swap_keys].
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%%----------------------------------------------------------------------
%% Tests
%%----------------------------------------------------------------------
diff --git a/lib/tools/test/make_SUITE.erl b/lib/tools/test/make_SUITE.erl
index 72dccdb465..524ed04af4 100644
--- a/lib/tools/test/make_SUITE.erl
+++ b/lib/tools/test/make_SUITE.erl
@@ -18,12 +18,13 @@
%%
-module(make_SUITE).
--export([all/1, make_all/1, make_files/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, make_all/1, make_files/1]).
-export([otp_6057_init/1,
otp_6057_a/1, otp_6057_b/1, otp_6057_c/1,
otp_6057_end/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
@@ -35,9 +36,27 @@
%% that the file :"test5.erl" shall be compiled with the 'S' option,
%% i.e. produce "test5.S" instead of "test5.<objext>"
-all(suite) -> [make_all, make_files,
- {conf, otp_6057_init,
- [otp_6057_a,otp_6057_b,otp_6057_c], otp_6057_end}].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [make_all, make_files, {group, otp_6057}].
+
+groups() ->
+ [{otp_6057,[],[otp_6057_a, otp_6057_b,
+ otp_6057_c]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ otp_6057_init(Config).
+
+end_per_group(_GroupName, Config) ->
+ otp_6057_end(Config).
+
test_files() -> ["test1", "test2", "test3", "test4"].
@@ -146,7 +165,7 @@ otp_6057_init(Config) when is_list(Config) ->
otp_6057_a(suite) ->
[];
otp_6057_a(doc) ->
- ["Test that make:all/0 looks for object file in correct place"];
+ ["Test that make:all/0, suite/0 looks for object file in correct place"];
otp_6057_a(Config) when is_list(Config) ->
?line PrivDir = ?config(priv_dir, Config),
diff --git a/lib/tools/test/tools.cover b/lib/tools/test/tools.cover
new file mode 100644
index 0000000000..1053be4f0f
--- /dev/null
+++ b/lib/tools/test/tools.cover
@@ -0,0 +1,2 @@
+{incl_app,tools,details}.
+
diff --git a/lib/tools/test/tools.spec b/lib/tools/test/tools.spec
index 93d5930472..1b07cf1cb6 100644
--- a/lib/tools/test/tools.spec
+++ b/lib/tools/test/tools.spec
@@ -1 +1 @@
-{topcase, {dir, "../tools_test"}}.
+{suites,"../tools_test",all}.
diff --git a/lib/tools/test/tools_SUITE.erl b/lib/tools/test/tools_SUITE.erl
index 6b952f10ab..69dfab8fe7 100644
--- a/lib/tools/test/tools_SUITE.erl
+++ b/lib/tools/test/tools_SUITE.erl
@@ -18,28 +18,45 @@
%%
-module(tools_SUITE).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% Default timetrap timeout (set in init_per_testcase).
-define(default_timeout, ?t:minutes(1)).
-define(application, tools).
%% Test server specific exports
--export([all/1]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%% Test cases must be exported.
-export([app_test/1]).
-all(doc) ->
- [];
-all(suite) ->
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
[app_test].
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
init_per_testcase(_Case, Config) ->
?line Dog=test_server:timetrap(?default_timeout),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, Config) ->
+end_per_testcase(_Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index f9d062ef85..1fad070b67 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -29,28 +29,29 @@
-define(privdir, "xref_SUITE_priv").
-define(copydir, "xref_SUITE_priv/datacopy").
-else.
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(format(S, A), ok).
-define(datadir, ?config(data_dir, Conf)).
-define(privdir, ?config(priv_dir, Conf)).
-define(copydir, ?config(copy_dir, Conf)).
-endif.
--export([all/1, init/1, fini/1]).
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2, init/1, fini/1]).
--export([xref/1,
+-export([
addrem/1, convert/1, intergraph/1, lines/1, loops/1,
no_data/1, modules/1]).
--export([files/1,
+-export([
add/1, default/1, info/1, lib/1, read/1, read2/1, remove/1,
replace/1, update/1, deprecated/1, trycatch/1,
abstract_modules/1, fun_mfa/1, qlc/1]).
--export([analyses/1,
+-export([
analyze/1, basic/1, md/1, q/1, variables/1, unused_locals/1]).
--export([misc/1,
+-export([
format_error/1, otp_7423/1, otp_7831/1]).
-import(lists, [append/2, flatten/1, keysearch/3, member/2, sort/1, usort/1]).
@@ -59,7 +60,7 @@
range/1, relation_to_family/1, set/1, to_external/1,
union/2]).
--export([init_per_testcase/2, fin_per_testcase/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
%% Checks some info counters of a server and some relations that should hold.
-export([check_count/1, check_state/1]).
@@ -68,8 +69,36 @@
-include_lib("tools/src/xref.hrl").
-all(suite) ->
- {conf, init, [xref, files, analyses, misc], fini}.
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group, xref}, {group, files}, {group, analyses},
+ {group, misc}].
+
+groups() ->
+ [{xref, [],
+ [addrem, convert, intergraph, lines, loops, no_data,
+ modules]},
+ {files, [],
+ [add, default, info, lib, read, read2, remove, replace,
+ update, deprecated, trycatch, abstract_modules, fun_mfa,
+ qlc]},
+ {analyses, [],
+ [analyze, basic, md, q, variables, unused_locals]},
+ {misc, [], [format_error, otp_7423, otp_7831]}].
+
+init_per_suite(Config) ->
+ init(Config).
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
init(Conf) when is_list(Conf) ->
DataDir = ?datadir,
@@ -91,13 +120,11 @@ init_per_testcase(_Case, Config) ->
Dog=?t:timetrap(?t:minutes(2)),
[{watchdog, Dog}|Config].
-fin_per_testcase(_Case, _Config) ->
+end_per_testcase(_Case, _Config) ->
Dog=?config(watchdog, _Config),
test_server:timetrap_cancel(Dog),
ok.
-xref(suite) ->
- [addrem, convert, intergraph, lines, loops, no_data, modules].
%% Seems a bit short...
addrem(suite) -> [];
@@ -680,9 +707,6 @@ modules(Conf) when is_list(Conf) ->
?line ok = xref_base:delete(S),
ok.
-files(suite) ->
- [add, default, info, lib, read, read2, remove, replace, update,
- deprecated, trycatch, abstract_modules, fun_mfa, qlc].
add(suite) -> [];
add(doc) -> ["Add modules, applications, releases, directories"];
@@ -1788,8 +1812,6 @@ qlc(Conf) when is_list(Conf) ->
ok.
-analyses(suite) ->
- [analyze, basic, md, q, variables, unused_locals].
analyze(suite) -> [];
analyze(doc) -> ["Simple analyses"];
@@ -2312,8 +2334,6 @@ unused_locals(Conf) when is_list(Conf) ->
?line ok = file:delete(Beam2),
ok.
-misc(suite) ->
- [format_error, otp_7423, otp_7831].
format_error(suite) -> [];
format_error(doc) -> ["Format error messages"];
diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk
index 77b5254eaa..0c89b18065 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -1 +1 @@
-TOOLS_VSN = 2.6.6.1
+TOOLS_VSN = 2.6.6.2
diff --git a/lib/wx/Makefile b/lib/wx/Makefile
index 83f545b662..0bc89e08ad 100644
--- a/lib/wx/Makefile
+++ b/lib/wx/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2008-2009. All Rights Reserved.
+# Copyright Ericsson AB 2008-2010. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -23,7 +23,7 @@ SUBDIRS = src
ifeq ($(CAN_BUILD_DRIVER), true)
SUBDIRS += c_src
endif
-SUBDIRS += examples demos doc/src
+SUBDIRS += examples doc/src
CLEANDIRS = $(SUBDIRS) api_gen
ifeq ($(INSIDE_ERLSRC),true)
diff --git a/lib/wx/api_gen/Makefile b/lib/wx/api_gen/Makefile
index c6b65b60bc..756ec598ce 100644
--- a/lib/wx/api_gen/Makefile
+++ b/lib/wx/api_gen/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2008-2009. All Rights Reserved.
+# Copyright Ericsson AB 2008-2010. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -39,14 +39,14 @@ TARGET_CDIR = ../c_src/gen
C_TARGETS = wxe_funcs.cpp
GL_C_TARGETS = gl_funcs.cpp
-WX = $(TARGET_CDIR)/$(C_TARGETS)
+WX = wx_code_generated
-GL = $(TARGET_CDIR)/$(GL_C_TARGETS)
+GL = gl_code_generated
opt: $(WX) $(GL)
$(WX): wxxml_generated $(COMPILER_T) wxapi.conf $(wildcard wx_extra/wx*.c_src) $(wildcard wx_extra/wx*.erl)
- erl -noshell -run wx_gen code
+ erl -noshell -run wx_gen code && touch wx_code_generated
wxxml_generated: wx_doxygen.conf wx_extra/bugs.h wx_extra/wxe_evth.h
sed -e 's|@WXGTK_DIR@|$(WXGTK_DIR)|g' wx_doxygen.conf > wx_doxygen
@@ -56,9 +56,8 @@ glxml_generated: gl_doxygen.conf
sed -e 's|@GL_DIR@|$(GL_DIR)|g' gl_doxygen.conf > gl_doxygen
doxygen gl_doxygen && touch glxml_generated
-
$(GL): glxml_generated $(GL_COMP_T) glapi.conf
- erl -noshell -run gl_gen code
+ erl -noshell -run gl_gen code && touch gl_code_generated
%.beam: %.erl wx_gen.hrl gl_gen.hrl
$(ERLC) -W $(ERL_FLAGS) $(ERL_COMPILE_FLAGS) $< -o$(EBIN)
@@ -66,7 +65,7 @@ $(GL): glxml_generated $(GL_COMP_T) glapi.conf
# TODO split cleans into separate targets?
complete_clean:
rm -f gl_doxygen wx_doxygen wx_xml/*.x* gl_xml/*.x*
- rm -f glxml_generated wxxml_generated
+ rm -f *_generated
$(MAKE) clean
clean:
rm -f *~
diff --git a/lib/wx/api_gen/gen_util.erl b/lib/wx/api_gen/gen_util.erl
index 859317bdef..b53f817ce0 100644
--- a/lib/wx/api_gen/gen_util.erl
+++ b/lib/wx/api_gen/gen_util.erl
@@ -40,6 +40,10 @@ strip_name([H|R1],[H|R2]) ->
strip_name(R1,R2);
strip_name(String,[]) -> String.
+
+get_hook(_Type, undefined) -> ignore;
+get_hook(Type, List) -> proplists:get_value(Type, List, ignore).
+
open_write(File) ->
%% io:format("Generating ~s~n",[File]),
{ok, Fd} = file:open(File++".temp", [write]),
@@ -58,10 +62,10 @@ close() ->
[] ->
ok = file:delete(File ++ ".temp"),
%% So that make understands that we have made this
- case os:getenv("CLEARCASE_ROOT") of
- false -> os:cmd("touch " ++ File);
- _ -> ignore
- end,
+ %% case os:getenv("CLEARCASE_ROOT") of
+ %% false -> os:cmd("touch " ++ File);
+ %% _ -> ignore
+ %% end,
ok;
Diff ->
case check_diff(Diff) of
diff --git a/lib/wx/api_gen/gl_gen.erl b/lib/wx/api_gen/gl_gen.erl
index 42802c6de7..374e0bd12b 100644
--- a/lib/wx/api_gen/gl_gen.erl
+++ b/lib/wx/api_gen/gl_gen.erl
@@ -67,7 +67,7 @@ gen_code() ->
gl_gen_erl:gl_defines(GLDefines),
gl_gen_erl:gl_api(GLFuncs),
- gl_gen_erl:gen_debug(GLFuncs,GLUFuncs),
+ %%gl_gen_erl:gen_debug(GLFuncs,GLUFuncs),
gl_gen_c:gen(GLFuncs,GLUFuncs),
ok.
@@ -206,10 +206,10 @@ parse_define([], D, _Opts) ->
parse_func(Xml, Opts) ->
{Func,_} = foldl(fun(X,Acc) -> parse_func(X,Acc,Opts) end, {#func{},1}, Xml),
+ put(current_func, Func#func.name),
#func{params=Args0,type=Type0} = Func,
Args = filter(fun(#arg{type=void}) -> false; (_) -> true end, Args0),
- #arg{type=Type} =
- patch_param(Func#func.name,#arg{name="result",type=Type0},Opts),
+ #arg{type=Type} = patch_param(Func#func.name,#arg{name="result",type=Type0},Opts),
Func#func{params=reverse(Args), type=Type}.
parse_func(#xmlElement{name=type, content=C}, {F,AC}, Os) ->
@@ -220,6 +220,7 @@ parse_func(#xmlElement{name=name, content=[#xmlText{value=C}]},{F,AC},Os) ->
put(current_func, Func),
{F#func{name=name(Func,Os)},AC};
parse_func(#xmlElement{name=param, content=C},{F,AC},Os) ->
+ put(current_func, F#func.name),
Parse = fun(Con, Ac) -> parse_param(Con, Ac, Os) end,
Param0 = foldl(Parse, #arg{}, drop_empty(C)),
Param = fix_param_name(Param0, F, AC),
@@ -314,11 +315,17 @@ handle_arg_opt(both, P) -> P#arg{in=both};
handle_arg_opt(binary, P=#arg{type=T}) ->
P#arg{type=T#type{size=undefined,base=binary}};
handle_arg_opt({binary,Sz}, P=#arg{type=T}) ->
- P#arg{type=T#type{size=Sz,base=binary}};
+ P#arg{type=T#type{size={Sz, Sz},base=binary}};
+handle_arg_opt({binary,Max, Sz}, P=#arg{type=T}) ->
+ P#arg{type=T#type{size={Max, Sz},base=binary}};
handle_arg_opt({type,Type}, P=#arg{type=T}) -> P#arg{type=T#type{name=Type}};
handle_arg_opt({single,Opt},P=#arg{type=T}) -> P#arg{type=T#type{single=Opt}};
+handle_arg_opt({base,{Opt, Sz}}, P=#arg{type=T}) -> P#arg{type=T#type{base=Opt, size=Sz}};
handle_arg_opt({base,Opt}, P=#arg{type=T}) -> P#arg{type=T#type{base=Opt}};
-handle_arg_opt({c_only,Opt},P) -> P#arg{where=c, alt=Opt}.
+handle_arg_opt({c_only,Opt},P) -> P#arg{where=c, alt=Opt};
+handle_arg_opt(string, P=#arg{type=T}) -> P#arg{type=T#type{base=string}};
+handle_arg_opt({string,Max,Sz}, P=#arg{type=T}) ->
+ P#arg{type=T#type{base=string, size={Max,Sz}}}.
parse_type([], _Os) -> void;
parse_type(C, Os) ->
@@ -367,6 +374,8 @@ parse_type2([N="GLbitfield"|R],T,Opts) ->
parse_type2(R,T#type{name=N, size=4, base=int},Opts);
parse_type2([N="GLvoid"|R],T,Opts) ->
parse_type2(R,T#type{name=N, base=idx_binary},Opts);
+parse_type2([N="GLsync"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, base=int, size=8},Opts);
parse_type2([N="GLbyte"|R],T,Opts) ->
parse_type2(R,T#type{name=N, size=1, base=int},Opts);
@@ -378,6 +387,11 @@ parse_type2([N="GLushort"|R],T,Opts) ->
parse_type2(R,T#type{name=N, size=2, base=int},Opts);
parse_type2([N="GLint"|R],T,Opts) ->
parse_type2(R,T#type{name=N, size=4, base=int},Opts);
+parse_type2([N="GLint64"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=8, base=int},Opts);
+parse_type2([N="GLuint64"|R],T,Opts) ->
+ parse_type2(R,T#type{name=N, size=8, base=int},Opts);
+
parse_type2([N="GLuint"|R],T,Opts) ->
parse_type2(R,T#type{name=N, size=4, base=int},Opts);
parse_type2([N="GLsizei"|R],T,Opts) ->
@@ -548,8 +562,10 @@ setup_idx_binary(Name,Ext,_Opts) ->
%% Ok warn if single is undefined
lists:foreach(fun(#arg{type=#type{base=memory}}) -> ok;
+ (#arg{type=#type{base=string}}) -> ok;
(#arg{type=#type{base=idx_binary}}) -> ok;
(#arg{type=#type{name="GLUquadric"}}) -> ok;
+ (#arg{type=#type{base=binary, size=Sz}}) when Sz =/= undefined -> ok;
(A=#arg{type=#type{single=undefined}}) ->
?warning("~p Unknown size of~n ~p~n",
[get(current_func),A]),
diff --git a/lib/wx/api_gen/gl_gen_c.erl b/lib/wx/api_gen/gl_gen_c.erl
index 3293050ab9..0f5cb0e1f4 100644
--- a/lib/wx/api_gen/gl_gen_c.erl
+++ b/lib/wx/api_gen/gl_gen_c.erl
@@ -47,34 +47,29 @@ gen(GLFuncs, GLUFuncs) ->
w("/***** This file is generated do not edit ****/~n~n", []),
w("#include <stdio.h>~n", []),
w("#include <string.h>~n", []),
- w("#include \"../wxe_impl.h\"~n", []),
- w("#include \"../wxe_gl.h\"~n", []),
- w("#include \"gl_fdefs.h\"~n", []),
+ w("#include \"../egl_impl.h\"~n", []),
+ w("#include \"gl_fdefs.h\"~n~n", []),
+ w("extern gl_fns_t gl_fns[];~n~n", []),
- w("~nint gl_error_op;~n", []),
- w("void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){~n",
+ w("void egl_dispatch(int op, char *bp, ErlDrvPort port, "
+ "ErlDrvTermData caller, char *bins[], int bins_sz[]){~n",
[]),
- w(" gl_error_op = op;~n", []),
- w(" if(caller != gl_active) {~n", []),
- w(" wxGLCanvas * current = glc[caller];~n", []),
- w(" if(current) { gl_active = caller; current->SetCurrent();}~n", []),
- w(" else {~n "
- " ErlDrvTermData rt[] = // Error msg~n"
- " {ERL_DRV_ATOM, driver_mk_atom((char *) \"_wxe_error_\"),~n"
- " ERL_DRV_INT, op,~n"
- " ERL_DRV_ATOM, driver_mk_atom((char *) \"no_gl_context\"),~n"
- " ERL_DRV_TUPLE,3};~n"
- " driver_send_term(WXE_DRV_PORT,caller,rt,8);~n"
- " return ;~n }~n };~n~n", []),
-
+ w(" try {~n",[]),
w(" switch(op)~n{~n",[]),
- w(" case 5000:~n wxe_tess_impl(bp, caller);~n break;~n", []),
- w(" case WXE_BIN_INCR:~n driver_binary_inc_refc(bins[0]->bin);~n break;~n",[]),
- w(" case WXE_BIN_DECR:~n driver_binary_dec_refc(bins[0]->bin);~n break;~n",[]),
+ w(" case 5000:~n erl_tess_impl(bp, port, caller);~n break;~n", []),
[funcs(F) || F <- GLUFuncs],
[funcs(F) || F <- GLFuncs],
+ w("}} catch (char *err_msg) {\n"
+ "int AP = 0; ErlDrvTermData rt[12];\n"
+ "rt[AP++] = ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) \"_egl_error_\");\n"
+ "rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) op;\n"
+ "rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *) err_msg);\n"
+ "// rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *) gl_fns[op-GLE_GL_FUNC_START].name);\n"
+ "// rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;\n"
+ "rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3;\n"
+ "driver_send_term(port,caller,rt,AP);\n", []),
w("}} /* The End */~n~n",[]),
close().
@@ -123,25 +118,53 @@ declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=B,single={tuple,Sz}}})
true = is_number(Sz), %% Assert
w(" ~s ~s[~p] = {~s};~n", [T,N,Sz,args(fun zero/1,",",lists:duplicate(Sz,B))]),
A;
-declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=B,single={list,Sz}}}) when is_number(Sz) ->
+declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=B,single={list,Sz}}})
+ when is_number(Sz) ->
w(" ~s ~s[~p] = {~s};~n", [T,N,Sz,args(fun zero/1,",",lists:duplicate(Sz,B))]),
A;
+declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=string,size={Max,_}, single=Single}}) ->
+ case is_integer(Max) of
+ true ->
+ w(" ~s ~s[~p];~n", [T,N,Max]);
+ false ->
+ %% w(" ~s ~s[*~s];~n", [T,N,Max]),
+ w(" ~s *~s;~n", [T,N]),
+ w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~s);~n", [N,T,T,Max]),
+ store_free(N)
+ %% case Single of
+ %% {list, _, _} ->
+ %% w(" ~s *~s_p = ~s;~n", [T,N,N]);
+ %% _ -> ok
+ %% end
+ end,
+ A;
+declare_var(A=#arg{name=N,in=false,type=#type{base=binary,size={MaxSz, _}}}) ->
+ MaxSz == undefined andalso error({assert, A}),
+ case is_integer(MaxSz) of
+ true ->
+ w(" ErlDrvBinary *~s = driver_alloc_binary(~p);~n", [N,MaxSz]);
+ false ->
+ w(" ErlDrvBinary *~s = driver_alloc_binary(*~s);~n", [N,MaxSz])
+ end,
+ A;
declare_var(A=#arg{name=N,in=false,type=#type{name=T,single={list,ASz,_USz},mod=[]}}) ->
true = is_list(ASz), %% Assert
w(" ~s *~s;~n", [T,N]),
w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~s);~n", [N,T,T,ASz]),
store_free(N),
- A;
-declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=binary,size=Sz}}) ->
- true = is_number(Sz), %% Assert
- w(" ~s ~s[~p];~n", [T,N,Sz]),
+ %% w(" ~s ~s[*~s];~n", [T,N,ASz]),
A;
declare_var(A=#arg{in=false, type=#type{name="GLUquadric",by_val=false,single=true}}) ->
A;
+declare_var(A=#arg{in=false, type=#type{base=string,by_val=false,single=true}}) ->
+ A;
declare_var(A=#arg{name=N,in=false,
type=#type{name=T,base=B,by_val=false,single=true}}) ->
w(" ~s ~s[1] = {~s};~n", [T,N,zero(B)]),
A;
+declare_var(A=#arg{where=c, type=#type{name=T}, alt={size,Var}}) ->
+ w(" ~s ~s_size = bins_sz[~p];~n", [T, Var, get(bin_count)]),
+ A;
declare_var(A=#arg{where=_}) ->
A.
@@ -171,10 +194,10 @@ decode_arg(P=#arg{where=c},A) -> {P,A};
decode_arg(P=#arg{in=false},A) -> {P,A};
decode_arg(P=#arg{name=Name,type=#type{name=Type,base=binary}},A0) ->
- w(" ~s *~s = (~s *) bins[~p]->base;~n", [Type,Name,Type,next_id(bin_count)]),
+ w(" ~s *~s = (~s *) bins[~p];~n", [Type,Name,Type,next_id(bin_count)]),
{P, A0};
decode_arg(P=#arg{name=Name,type=#type{name=Type,base=memory}},A0) ->
- w(" ~s *~s = (~s *) bins[~p]->base;~n", [Type,Name,Type,next_id(bin_count)]),
+ w(" ~s *~s = (~s *) bins[~p];~n", [Type,Name,Type,next_id(bin_count)]),
{P, A0};
decode_arg(P=#arg{name=Name,type=#type{name=T,base=string,single=list}},A0) ->
A = align(4,A0),
@@ -219,7 +242,7 @@ decode_arg(P=#arg{name=Name,type=#type{name=Type,base=guard_int}},A0) ->
{P, A};
decode_arg(P=#arg{name=Name,type=#type{name=Type,base=string,single=true}},A0) ->
w(" ~s *~s = (~s *) bp;~n", [Type,Name,Type]),
- w(" int ~sLen = strlen((char *)~s); bp += ~sLen+1+((8-((1+~sLen+~p)%8))%8);~n",
+ w(" int ~sLen[1] = {strlen((char *)~s)}; bp += ~sLen[0]+1+((8-((1+~sLen[0]+~p)%8))%8);~n",
[Name,Name,Name,Name,A0]),
{P, 0};
decode_arg(P=#arg{name=Name,
@@ -288,6 +311,8 @@ result_type(#type{name=T, ref=undefined}) -> T;
result_type(#type{name=T, ref={pointer,1}, mod=Mods}) ->
mod(Mods) ++ T ++ " * ".
+call_arg(#arg{alt={size,Alt},type=#type{}}) ->
+ Alt ++ "_size";
call_arg(#arg{alt={length,Alt},type=#type{}}) ->
"*" ++ Alt ++ "Len";
call_arg(#arg{alt={constant,Alt},type=#type{}}) ->
@@ -298,6 +323,8 @@ call_arg(#arg{name=Name,type=#type{single={list, _}}}) ->
Name;
call_arg(#arg{name=Name,type=#type{size=8,base=int,ref=undefined}}) ->
Name;
+call_arg(#arg{name=Name,in=false,type=#type{name=T, base=binary}}) ->
+ "(" ++ T ++ "*) " ++ Name ++ "->orig_bytes";
call_arg(#arg{name=Name,type=#type{ref=undefined}}) ->
"*" ++ Name;
call_arg(#arg{name=Name,type=#type{base=guard_int}}) ->
@@ -318,27 +345,27 @@ build_return_vals(Type,As) ->
true ->
w(" int AP = 0; ErlDrvTermData rt[6];~n",[]),
w(" rt[AP++]=ERL_DRV_ATOM;"
- " rt[AP++]=driver_mk_atom((char *) \"_wxe_result_\");~n",[]),
+ " rt[AP++]=driver_mk_atom((char *) \"_egl_result_\");~n",[]),
w(" rt[AP++]=ERL_DRV_ATOM;"
" rt[AP++]=driver_mk_atom((char *) \"ok\");~n",[]),
w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;~n",[]),
- w(" driver_send_term(WXE_DRV_PORT,caller,rt,AP);~n",[]),
+ w(" driver_send_term(port,caller,rt,AP);~n",[]),
ok
end;
{Val,Vars,Cnt} ->
ExtraTuple = if Cnt > 1 -> 2; true -> 0 end,
- CSize = if Vars =:= none ->
- Sz = integer_to_list(Val+4+ExtraTuple),
- w(" int AP = 0; ErlDrvTermData rt[~s];~n",[Sz]),
- Sz;
- true ->
- Sz = integer_to_list(Val+4+ExtraTuple) ++ " + " ++ Vars,
- w(" int AP = 0; ErlDrvTermData *rt;~n",[]),
- w(" rt = (ErlDrvTermData *) "
- "driver_alloc(sizeof(ErlDrvTermData)*(~s));~n", [Sz]),
- Sz
- end,
- w(" rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) \"_wxe_result_\");~n",[]),
+ if Vars =:= none ->
+ Sz = integer_to_list(Val+4+ExtraTuple),
+ w(" int AP = 0; ErlDrvTermData rt[~s];~n",[Sz]),
+ Sz;
+ true ->
+ Sz = integer_to_list(Val+4+ExtraTuple) ++ " + " ++ Vars,
+ w(" int AP = 0; ErlDrvTermData *rt;~n",[]),
+ w(" rt = (ErlDrvTermData *) "
+ "driver_alloc(sizeof(ErlDrvTermData)*(~s));~n", [Sz]),
+ Sz
+ end,
+ w(" rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) \"_egl_result_\");~n",[]),
FreeList = build_ret_types(Type,As),
case Cnt of
1 -> ok;
@@ -346,9 +373,9 @@ build_return_vals(Type,As) ->
w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = ~p;~n",[Cnt])
end,
w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;~n",[]),
- w(" if (AP != ~s ) fprintf(stderr, \"%d: ERROR AP mismatch %d %d\\r\\n\",__LINE__,AP,~s);~n",
- [CSize,CSize]),
- w(" driver_send_term(WXE_DRV_PORT,caller,rt,AP);~n",[]),
+ %%w(" if (AP != ~s ) fprintf(stderr, \"%d: ERROR AP mismatch %d %d\\r\\n\",__LINE__,AP,~s);~n",
+ %% [CSize,CSize]),
+ w(" driver_send_term(port,caller,rt,AP);~n",[]),
case Vars of
none -> ignore;
_ ->
@@ -371,7 +398,7 @@ calc_sizes(Type,As) ->
{Val, none} -> {Sz+Val, Vars, Cnt+1};
{Val, Var} when Vars =:= none ->
{Sz+Val, Var,Cnt+1};
- {Val, Var} when Vars =:= none ->
+ {Val, Var} ->
{Sz+Val, Var ++ " + " ++ Vars,Cnt+1}
end;
(_,Acc) -> Acc
@@ -379,13 +406,16 @@ calc_sizes(Type,As) ->
foldl(Calc, TSz, As).
return_size(_N,void) -> {0, none};
-return_size(_N,#type{base=binary}) -> {4, none};
-return_size(_N,#type{single=true}) -> {2,none};
return_size(_N,#type{single={tuple,Sz}}) -> {Sz*2+2, none};
-return_size(_N,#type{name="GLubyte",single={list,null}}) ->{3, none};
return_size(_N,#type{single={list,Sz}}) -> {Sz*2+3, none};
-return_size(_N,#type{base=string,single={list,_,_}}) -> {3, none};
-return_size(_N,#type{single={list,_,Sz}}) -> {3, "(*" ++Sz++")*2"}.
+return_size(_N,#type{base=string,single=true}) -> {3, none};
+return_size(_N,#type{base=string,single=undefined}) -> {3, none};
+return_size(_N,#type{base=string,single={list,_,"result"}}) -> {3, "result*3"};
+return_size(_N,#type{base=string,single={list,_,Sz}}) -> {3, "(*" ++Sz++")*3"};
+return_size(_N,#type{single={list,_,"result"}}) -> {3, "result*2"};
+return_size(_N,#type{single={list,_,Sz}}) -> {3, "(*" ++Sz++")*2"};
+return_size(_N,#type{base=binary}) -> {4, none};
+return_size(_N,#type{single=true}) -> {2, none}.
build_ret_types(void,Ps) ->
@@ -444,17 +474,27 @@ build_ret(Name,_Q,#type{name=T,base=_,single={tuple,Sz}}) ->
[w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *~s++;~n", [Temp])
|| _ <- lists:seq(1,Sz)],
w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = ~p;~n",[Sz]);
-build_ret(Name,_Q,#type{name="GLubyte",single={list,null}}) ->
+build_ret(Name,_Q,#type{base=string,size=1,single=true}) ->
w(" rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) ~s;"
" rt[AP++] = strlen((char *) ~s);\n", [Name, Name]);
-build_ret(Name,_Q,#type{base=string,single={list,_,Sz}}) ->
+build_ret(Name,_Q,#type{base=string, size={_Max,Sz}, single=S})
+ when S == true; S == undefined ->
w(" rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) ~s;"
" rt[AP++] = *~s;\n", [Name, Sz]);
+build_ret(Name,_Q,#type{name=_T,base=string,size={_, SSz}, single={list,_,Sz}}) ->
+ P = if Sz == "result" -> ["(int) "]; true -> "*" end,
+ w(" for(int i=0; i < ~s~s; i++) {\n", [P,Sz]),
+ w(" rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) ~s;"
+ " rt[AP++] = ~s[i]-1;\n", [Name, SSz]),
+ w(" ~s += ~s[i]; }~n", [Name, SSz]),
+ w(" rt[AP++] = ERL_DRV_NIL;", []),
+ w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = (~s~s)+1;~n",[P,Sz]);
build_ret(Name,_Q,#type{name=_T,base=B,single={list,_,Sz}}) when B =/= float ->
- w(" for(int i=0; i < *~s; i++) {\n", [Sz]),
+ P = if Sz == "result" -> ["(int) "]; true -> "*" end,
+ w(" for(int i=0; i < ~s~s; i++) {\n", [P,Sz]),
w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ~s[i];}~n", [Name]),
w(" rt[AP++] = ERL_DRV_NIL;", []),
- w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*~s)+1;~n",[Sz]);
+ w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = (~s~s)+1;~n",[P,Sz]);
build_ret(Name,_Q,#type{name=_T,size=FSz,base=float,single={list,Sz}}) ->
Temp = Name ++ "Tmp",
case FSz of
@@ -475,12 +515,14 @@ build_ret(Name,_Q,#type{name=T,base=_,single={list,Sz}}) ->
|| _ <- lists:seq(1,Sz)],
w(" rt[AP++] = ERL_DRV_NIL;", []),
w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = ~p+1;~n",[Sz]);
-build_ret(Name,_Q,#type{name="GLubyte",base=binary,size=Sz}) ->
- w(" ErlDrvBinary * BinCopy = driver_alloc_binary(~p);~n", [Sz]),
- w(" memcpy(BinCopy->orig_bytes, ~s, ~p);~n", [Name,Sz]),
- w(" rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) BinCopy;", []),
- w(" rt[AP++] = ~p; rt[AP++] = 0;~n", [Sz]),
- "driver_free_binary(BinCopy);";
+build_ret(Name,_Q,#type{base=binary,size={_,Sz}}) ->
+ w(" rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) ~s;", [Name]),
+ if is_integer(Sz) ->
+ w(" rt[AP++] = ~p; rt[AP++] = 0;~n", [Sz]);
+ is_list(Sz) ->
+ w(" rt[AP++] = *~s; rt[AP++] = 0;~n", [Sz])
+ end,
+ "driver_free_binary(" ++ Name ++ ");";
build_ret(Name,_Q,T=#type{}) ->
io:format("{~p, {~p, {single,{tuple,X}}}}.~n", [get(current_func),Name]),
io:format(" ~p~n",[T]).
@@ -496,6 +538,19 @@ gen_defines(GLFuncs,GLUFuncs) ->
w("# define WXE_EXTERN~n", []),
w("#else~n# define WXE_EXTERN extern~n", []),
w("#endif~n~n", []),
+
+ w("typedef struct {\n"
+ " const char * name;\n"
+ " const char * alt;\n"
+ " void * func;\n"
+ "} gl_fns_t;\n\n", []),
+
+ GLFirst = case hd(GLFuncs) of
+ [First|_] when is_list(First) -> get(First);
+ First -> get(First)
+ end,
+ w("#define GLE_GL_FUNC_START ~p~n", [GLFirst#func.id]),
+
[fdefs(F) || F <- GLFuncs],
[fdefs(F) || F <- GLUFuncs],
close().
@@ -543,11 +598,7 @@ gl_gen_init(Funcs) ->
open_write("../c_src/gen/gl_finit.h"),
c_copyright(),
w("/***** This file is generated do not edit ****/~n~n", []),
- w("static struct {\n"
- " const char * name;\n"
- " const char * alt;\n"
- " void * func;\n"
- "} gl_fns[] = \n"
+ w("gl_fns_t gl_fns[] = \n"
"{\n", []),
[finits(F) || F <- Funcs],
w(" { NULL, NULL, NULL}};\n",[]),
diff --git a/lib/wx/api_gen/gl_gen_erl.erl b/lib/wx/api_gen/gl_gen_erl.erl
index ce35484561..f292c8723e 100644
--- a/lib/wx/api_gen/gl_gen_erl.erl
+++ b/lib/wx/api_gen/gl_gen_erl.erl
@@ -49,7 +49,7 @@ glu_defines(Defs) ->
w("~n%% GLU DEFINITIONS~n~n", []),
w("%% This file is generated DO NOT EDIT~n~n", []),
[gen_define(Def) || Def=#def{} <- Defs],
- close(),
+ close(),
ok.
gen_define(#def{name=N, val=Val, type=int}) ->
@@ -78,7 +78,11 @@ types() ->
{"GLsizeiptr","64/native-unsigned"}, % 64 bits int, convert on c-side
{"GLintptr", "64/native-unsigned"}, % 64 bits int, convert on c-sidew
{"GLUquadric", "64/native-unsigned"},% Handle 32bits aargh 64bits on mac64
- {"GLhandleARB","64/native-unsigned"} % Handle 32bits aargh 64bits on mac64
+ {"GLhandleARB","64/native-unsigned"},% Handle 32bits aargh 64bits on mac64
+
+ {"GLsync", "64/native-unsigned"}, % Pointer to record
+ {"GLuint64", "64/native-unsigned"},
+ {"GLint64", "64/native-signed"}
].
gl_api(Fs) ->
@@ -90,22 +94,53 @@ gl_api(Fs) ->
w("%% See <a href=\"http://www.opengl.org/sdk/docs/man/\">www.opengl.org</a>~n",[]),
w("%%~n", []),
w("%% Booleans are represented by integers 0 and 1.~n~n", []),
- w("%% @type wx_mem(). see wx.erl on memory allocation functions~n", []),
+ w("%% @type mem(). memory block~n", []),
w("%% @type enum(). An integer defined in gl.hrl~n", []),
w("%% @type offset(). An integer which is an offset in an array~n", []),
w("%% @type clamp(). A float clamped between 0.0 - 1.0~n", []),
w("-module(gl).~n~n",[]),
w("-compile(inline).~n", []),
- %% w("-compile(export_all).~n~n", []),
- %% w("-compile(binary_comprehension).~n~n", []),
- w("-include(\"wxe.hrl\").~n", []),
+%% w("-include(\"wxe.hrl\").~n", []),
[w("-define(~s,~s).~n", [GL,Erl]) || {GL,Erl} <- types()],
-
+
+ gen_types(gl),
+
Exp = fun(F) -> gen_export(F) end,
ExportList = lists:map(Exp,Fs),
w("~n-export([~s]).~n~n", [args(fun(EF) -> EF end, ",", ExportList, 60)]),
-
+ w("-export([call/2, cast/2, send_bin/1]).~n",[]),
+ w("%% @hidden~n", []),
+ w("call(Op, Args) ->~n", []),
+ w(" Port = get(opengl_port), ~n", []),
+ w(" _ = erlang:port_control(Port,Op,Args),~n", []),
+ w(" rec().~n", []),
+ w(" ~n", []),
+ w("%% @hidden~n", []),
+ w("cast(Op, Args) ->~n", []),
+ w(" Port = get(opengl_port), ~n", []),
+ w(" _ = erlang:port_control(Port,Op,Args),~n", []),
+ w(" ok.~n", []),
+ w(" ~n", []),
+ w("%% @hidden~n", []),
+ w("rec() ->~n", []),
+ w(" receive ~n", []),
+ w(" {'_egl_result_', Res} -> Res;~n", []),
+ w(" {'_egl_error_', Op, Res} -> error({error,Res,Op})~n", []),
+ w(" end. ~n", []),
+ w("~n", []),
+ w("%% @hidden~n", []),
+ w("send_bin(Bin) when is_binary(Bin) ->~n", []),
+ w(" Port = get(opengl_port), ~n", []),
+ w(" erlang:port_command(Port,Bin);~n", []),
+ w("send_bin(Tuple) when is_tuple(Tuple) ->~n", []),
+ w(" Port = get(opengl_port), ~n", []),
+ w(" case element(2, Tuple) of~n", []),
+ w(" Bin when is_binary(Bin) ->~n", []),
+ w(" erlang:port_command(Port,Bin)~n", []),
+ w(" end.~n", []),
+ w("~n", []),
+
w("~n%% API~n~n", []),
[gen_funcs(F) || F <- Fs],
close(),
@@ -120,20 +155,22 @@ glu_api(Fs) ->
w("%% See <a href=\"http://www.opengl.org/sdk/docs/man/\">www.opengl.org</a>~n",[]),
w("%%~n", []),
w("%% Booleans are represented by integers 0 and 1.~n~n", []),
- w("%% @type wx_mem(). see wx.erl on memory allocation functions~n", []),
+ w("%% @type mem(). memory block~n", []),
w("%% @type enum(). An integer defined in gl.hrl~n", []),
w("%% @type offset(). An integer which is an offset in an array~n", []),
w("%% @type clamp(). A float clamped between 0.0 - 1.0~n~n", []),
w("-module(glu).~n",[]),
w("-compile(inline).~n", []),
- w("-include(\"wxe.hrl\").~n", []),
+ %%w("-include(\"wxe.hrl\").~n", []),
[w("-define(~s,~s).~n", [GL,Erl]) || {GL,Erl} <- types()],
+ gen_types(glu),
+
Exp = fun(F) -> gen_export(F) end,
ExportList = ["tesselate/2" | lists:map(Exp,Fs)],
w("~n-export([~s]).~n~n", [args(fun(EF) -> EF end, ",", ExportList, 60)]),
-
+ w("-import(gl, [call/2,cast/2,send_bin/1]).", []),
w("~n%% API~n~n", []),
w("%% @spec (Vec3, [Vec3]) -> {Triangles, VertexPos}~n",[]),
@@ -148,13 +185,13 @@ glu_api(Fs) ->
"%% may contain newly created vertices in the end.~n", []),
w("tesselate({Nx,Ny,Nz}, Vs) ->~n",[]),
- w(" wxe_util:call(5000, <<(length(Vs)):32/native,0:32,~n"
+ w(" call(5000, <<(length(Vs)):32/native,0:32,~n"
" Nx:?GLdouble,Ny:?GLdouble,Nz:?GLdouble,~n"
" (<< <<Vx:?GLdouble,Vy:?GLdouble,Vz:?GLdouble >>~n"
" || {Vx,Vy,Vz} <- Vs>>)/binary >>).~n~n", []),
[gen_funcs(F) || F <- Fs],
- close(),
+ close(),
ok.
gen_funcs([F]) when is_list(F) ->
@@ -178,6 +215,17 @@ gen_funcs(F) ->
erase(current_func),
w(".~n~n",[]).
+gen_types(Where) ->
+ case Where of
+ glu -> ignore;
+ gl ->
+ w("-type clamp() :: float().~n", []),
+ w("-type offset() :: non_neg_integer().~n", [])
+ end,
+ w("-type enum() :: non_neg_integer().~n", []),
+ w("-type mem() :: binary() | tuple().~n", []),
+ ok.
+
gen_export(F) ->
try gen_export_1(F)
catch E:R ->
@@ -199,19 +247,27 @@ gen_export2(#func{name=Name,params=As0}) ->
Args = lists:filter(fun(Arg) -> func_arg(Arg) =/= skip end, As0),
erl_func_name(Name) ++ "/" ++ integer_to_list(length(Args)).
-
-gen_doc([#func{alt={vector,VecPos,Vec}}]) ->
+gen_doc([#func{name=Name, alt={vector,VecPos,Vec}}]) ->
#func{type=T,params=As} = get(Vec),
{As1,As2} = lists:split(VecPos, As),
Args1 = case args(fun func_arg/1, ",", As1) of [] -> []; Else -> Else++"," end,
Args2 = args(fun func_arg/1, ",", As2),
- w("%% @spec (~s{~s}) -> ~s~n",[Args1,Args2,doc_return_types(T,As)]),
- w("%% @equiv ~s(~s)~n",[erl_func_name(Vec), Args1++Args2]);
+ w("%% @spec (~s{~s}) -> ~s~n",[Args1,Args2,doc_return_types(T,As, doc)]),
+ w("%% @equiv ~s(~s)~n",[erl_func_name(Vec), Args1++Args2]),
+ SA1 = case doc_arg_types(As1, spec) of [] -> []; E -> E++"," end,
+ SA2 = doc_arg_types(As2, spec),
+ w("-spec ~s(~s{~s}) -> ~s.~n",
+ [erl_func_name(Name), SA1, SA2,
+ doc_return_types(T,As, spec)]);
+
gen_doc([#func{name=Name,type=T,params=As,alt=Alt}|_]) ->
- w("%% @spec (~s) -> ~s~n", [doc_arg_types(As),doc_return_types(T,As)]),
+ w("%% @spec (~s) -> ~s~n", [doc_arg_types(As, doc),doc_return_types(T,As, doc)]),
GLDoc = "http://www.opengl.org/sdk/docs/man/xhtml/",
w("%% @doc See <a href=\"~s~s.xml\">external</a> documentation.~n",
- [GLDoc, doc_name(Name,Alt)]).
+ [GLDoc, doc_name(Name,Alt)]),
+ w("-spec ~s(~s) -> ~s.~n",
+ [erl_func_name(Name), doc_arg_types(As, spec), doc_return_types(T,As, spec)]).
+
gen_func(#func{name=Name,alt={vector,VecPos,Vec}}) ->
#func{params=As} = get(Vec),
@@ -229,9 +285,9 @@ gen_func(_F=#func{name=Name,type=T,params=As,id=MId}) ->
{StrArgs,_} = marshal_args(PreAs),
case have_return_vals(T,As) of
true ->
- w(" wxe_util:call(~p, <<~s>>)", [MId, StrArgs]);
+ w(" call(~p, <<~s>>)", [MId, StrArgs]);
false ->
- w(" wxe_util:cast(~p, <<~s>>)", [MId, StrArgs])
+ w(" cast(~p, <<~s>>)", [MId, StrArgs])
end.
func_arg(#arg{in=In,where=W,name=Name,type=Type})
@@ -249,60 +305,65 @@ func_arg(#arg{in=In,where=W,name=Name,type=Type})
end;
func_arg(_) -> skip.
-doc_arg_types(Ps0) ->
+doc_arg_types(Ps0, Type) ->
Ps = [P || P=#arg{in=In, where=Where} <- Ps0,In =/= false, Where =/= c],
- args(fun doc_arg_type/1, ",", Ps).
+ args(fun(Arg) -> doc_arg_type(Arg, Type) end, ",", Ps).
-doc_return_types(T, Ps0) ->
+doc_return_types(T, Ps0, Type) ->
Ps = [P || P=#arg{in=In, where=Where} <- Ps0,In =/= true, Where =/= c],
- doc_return_types2(T, Ps).
-
-doc_return_types2(void, []) -> "ok";
-doc_return_types2(void, [#arg{type=T}]) -> doc_arg_type2(T);
-doc_return_types2(T, []) -> doc_arg_type2(T);
-doc_return_types2(void, Ps) ->
- "{" ++ args(fun doc_arg_type/1,",",Ps) ++ "}";
-doc_return_types2(T, Ps) ->
- "{" ++ doc_arg_type2(T) ++ "," ++ args(fun doc_arg_type/1,",",Ps) ++ "}".
-
-doc_arg_type(#arg{name=Name,type=T}) ->
+ doc_return_types2(T, Ps, Type).
+
+doc_return_types2(void, [], _) -> "ok";
+doc_return_types2(void, [#arg{type=T}], _) -> doc_arg_type2(T);
+doc_return_types2(T, [], _) -> doc_arg_type2(T);
+doc_return_types2(void, Ps, Type) ->
+ "{" ++ args(fun(Arg) -> doc_arg_type(Arg, Type) end,",",Ps) ++ "}";
+doc_return_types2(T, Ps, Type) ->
+ "{" ++ doc_arg_type2(T) ++ "," ++
+ args(fun(Arg) -> doc_arg_type(Arg, Type) end,",",Ps) ++ "}".
+
+doc_arg_type(#arg{name=Name,type=T}, doc) ->
try
erl_arg_name(Name) ++ "::" ++ doc_arg_type2(T)
catch _:Error ->
io:format("Error: ~p ~p~n~p~n",[Name, Error, erlang:get_stacktrace()]),
exit(error)
+ end;
+doc_arg_type(#arg{name=Name,type=T}, spec) ->
+ try
+ doc_arg_type2(T)
+ catch _:Error ->
+ io:format("Error spec: ~p ~p~n~p~n",[Name, Error, erlang:get_stacktrace()]),
+ exit(error)
end.
+
doc_arg_type2(T=#type{single=true}) ->
doc_arg_type3(T);
doc_arg_type2(T=#type{single=undefined}) ->
doc_arg_type3(T);
doc_arg_type2(T=#type{single={tuple,undefined}}) ->
"{" ++ doc_arg_type3(T) ++ "}";
-doc_arg_type2(T=#type{single={tuple,_Sz}}) ->
- "{" ++ doc_arg_type3(T) ++ "}";
+doc_arg_type2(T=#type{single={tuple,Sz}}) ->
+ "{" ++ args(fun doc_arg_type3/1, ",", lists:duplicate(Sz,T)) ++ "}";
doc_arg_type2(T=#type{single=list}) ->
"[" ++ doc_arg_type3(T) ++ "]";
-doc_arg_type2(T=#type{single={list, Max}}) when is_integer(Max) ->
+doc_arg_type2(T=#type{single={list, _Max}}) ->
"[" ++ doc_arg_type3(T) ++ "]";
-doc_arg_type2(_T=#type{single={list,null}}) ->
- "string()";
-doc_arg_type2(T=#type{base=string}) ->
- doc_arg_type3(T);
doc_arg_type2(T=#type{single={list,_,_}}) ->
"[" ++ doc_arg_type3(T) ++ "]";
-doc_arg_type2(T=#type{single={tuple_list,_TSz}}) ->
- "[{" ++ doc_arg_type3(T) ++ "}]".
+doc_arg_type2(T=#type{single={tuple_list,Sz}}) ->
+ "[{" ++ args(fun doc_arg_type3/1, ",", lists:duplicate(Sz,T)) ++ "}]".
doc_arg_type3(#type{name="GLenum"}) -> "enum()";
doc_arg_type3(#type{name="GLclamp"++_}) -> "clamp()";
doc_arg_type3(#type{base=int}) -> "integer()";
doc_arg_type3(#type{base=float}) -> "float()";
-doc_arg_type3(#type{base=guard_int}) -> "offset()|binary()";
+doc_arg_type3(#type{base=guard_int}) -> "offset()|mem()";
doc_arg_type3(#type{base=string}) -> "string()";
doc_arg_type3(#type{base=bool}) -> "0|1";
doc_arg_type3(#type{base=binary}) -> "binary()";
-doc_arg_type3(#type{base=memory}) -> "wx:wx_mem()".
+doc_arg_type3(#type{base=memory}) -> "mem()".
guard_test(As) ->
Str = args(fun(#arg{name=N,type=#type{base=guard_int}}) ->
@@ -316,10 +377,10 @@ guard_test(As) ->
end.
pre_marshal([#arg{name=N,in=true,type=#type{base=binary}}|R]) ->
- w(" wxe_util:send_bin(~s),~n", [erl_arg_name(N)]),
+ w(" send_bin(~s),~n", [erl_arg_name(N)]),
pre_marshal(R);
pre_marshal([#arg{name=N,type=#type{base=memory}}|R]) ->
- w(" wxe_util:send_bin(~s#wx_mem.bin),~n", [erl_arg_name(N)]),
+ w(" send_bin(~s),~n", [erl_arg_name(N)]),
pre_marshal(R);
pre_marshal([A=#arg{name=N,type=#type{base=string,single=list}}|R]) ->
%% With null terminations
@@ -595,6 +656,7 @@ gen_debug(GL, GLU) ->
w("].~n~n", []),
close().
+
printd([F|R],Mod) when is_list(F) ->
printd(F,Mod),
printd(R,Mod);
diff --git a/lib/wx/api_gen/glapi.conf b/lib/wx/api_gen/glapi.conf
index f9ed7a1065..525ccf8b68 100644
--- a/lib/wx/api_gen/glapi.conf
+++ b/lib/wx/api_gen/glapi.conf
@@ -29,8 +29,35 @@
"glMatrixIndexPointerARB",
"glPixelTransformParameter",
%% OpengGL 3.0
- %"glGetTransformFeedbackVarying", %% Jobbiga
- %"glTransformFeedbackVaryings",
+
+ %% ARB
+ "glCreateSyncFromCLeventARB", % _cl_context _cl_event ??
+ "glDebugMessageCallbackARB",
+
+ "glGetn", %*
+ "glReadnPixels", %*
+
+ "glVertexP2", %*
+ "glVertexP3", %*
+ "glVertexP4", %*
+ "glTexCoordP1", %*
+ "glTexCoordP2", %*
+ "glTexCoordP3", %*
+ "glTexCoordP4", %*
+ "glMultiTexCoordP1", %*
+ "glMultiTexCoordP2", %*
+ "glMultiTexCoordP3", %*
+ "glMultiTexCoordP4", %*
+ "glNormalP3", %*
+ "glColorP3", %*
+ "glColorP4", %*
+ "glSecondaryColorP3", %*
+ "glVertexAttribP1", %*
+ "glVertexAttribP2", %*
+ "glVertexAttribP3", %*
+ "glVertexAttribP4", %*
+
+ "glGetActiveSubroutineUniformiv", %% Bad API don't know what to allocate needs to ask
%% EXT
%% By default skip these extensions
@@ -136,11 +163,12 @@
{"glRect", [{"v1", {single,{tuple,2}}},{"v2", {single,{tuple,2}}}]}.
-{"glGetString", {"result", {single,{list,null}}}}.
+{"glGetString", {"result", string}}.
{"glGetBooleanv", {"params", {single,{list,16}}}}.
{"glGetDoublev", {"params", {single,{list,16}}}}.
{"glGetFloatv", {"params", {single,{list,16}}}}.
{"glGetIntegerv", {"params", {single,{list,16}}}}.
+{"glGetInteger64v", {"params", {single,{list,16}}}}.
{"glFeedbackBuffer", {"buffer", [{base,memory}, in]}}.
{"glSelectBuffer", {"buffer", [{base,memory}, in]}}.
@@ -174,24 +202,24 @@
{"glGetActiveAttribARB", [{"length",[skip,{single, true}]},
{"size", {single, true}},
{"type", {single, true}},
- {"name", {single, {list,"maxLength","length"}}}
+ {"name", {string,"maxLength","length"}}
]}.
{"glGetActiveAttrib", [{"length",[skip,{single, true}]},
{"size", {single, true}},
{"type", {single, true}},
- {"name", {single, {list,"bufSize","length"}}}
+ {"name", {string,"bufSize","length"}}
]}.
{"glGetActiveUniformARB", [{"length",[skip,{single, true}]},
{"size", {single, true}},
{"type", {single, true}},
- {"name", {single, {list,"maxLength","length"}}}
+ {"name", {string,"maxLength","length"}}
]}.
{"glGetActiveUniform", [{"length",[skip,{single, true}]},
{"size", {single, true}},
{"type", {single, true}},
- {"name", {single, {list,"bufSize","length"}}}
+ {"name", {string,"bufSize","length"}}
]}.
{"glGetAttachedShaders", [{"count", [skip,{single,true}]},
@@ -201,18 +229,18 @@
{"glGetProgramiv", {"params", {single,true}}}.
{"glGetProgramInfoLog", [{"length", [skip,{single,true}]},
- {"infoLog", {single, {list,"bufSize","length"}}}
+ {"infoLog", {string,"bufSize","length"}}
]}.
{"glGetShaderiv", {"params", {single,true}}}.
{"glGetShaderInfoLog", [{"length", [skip,{single,true}]},
- {"infoLog", {single, {list,"bufSize","length"}}}
+ {"infoLog", {string,"bufSize","length"}}
]}.
{"glGetShaderSourceARB", [{"length", [skip,{single,true}]},
- {"source", {single, {list,"maxLength","length"}}}
+ {"source", {string,"maxLength","length"}}
]}.
{"glGetShaderSource", [{"length", [skip,{single,true}]},
- {"source", {single, {list,"bufSize","length"}}}
+ {"source", {string,"bufSize","length"}}
]}.
@@ -239,7 +267,7 @@
{"glMatrixIndex", [{"size",{c_only,{length,"indices"}}}, {"indices", {single,list}}]}.
-{"glProgramStringARB", [{"len",{c_only,{constant,"stringLen"}}},
+{"glProgramStringARB", [{"len",{c_only,{length,"string"}}},
{"string",[{base,string},{single,true}]}]}.
{"glGetProgramStringARB", {"string", [in,{base,memory}]}}.
{"glGenProgramsARB", {"programs", {single,{list,"n","n"}}}}.
@@ -250,7 +278,7 @@
{"glGetProgramLocalParameter", {"params", {single,{tuple,4}}}}.
{"glGetObjectParameter", {"params", {single,true}}}.
{"glGetInfoLogARB", [{"length", [skip,{single,true}]},
- {"infoLog", {single, {list,"maxLength","length"}}}
+ {"infoLog", {string,"maxLength","length"}}
]}.
{"glGetAttachedObjectsARB", [{"count", [skip,{single,true}]},
{"obj", {single, {list,"maxCount","count"}}}
@@ -280,9 +308,10 @@
{"objW",[{single,true},out]}]}.
{"gluBuild", {"data", [binary]}}.
{"gluScaleImage", [{"dataIn", [in, binary]}, {"dataOut", [in, {base, memory}]}]}.
-{"gluCheckExtension", [{"extName", {single, list}}, {"extString", {single, list}}]}.
-{"gluErrorString", {"result", {single, {list,null}}}}.
-{"gluGetString", {"result", {single, {list,null}}}}.
+{"gluCheckExtension", [{"extName", string},
+ {"extString", string}]}.
+{"gluErrorString", {"result", string}}.
+{"gluGetString", {"result", string}}.
{"gluDeleteQuadric", {"quad", in}}.
{"gluQuadric", {"quad", in}}.
@@ -291,15 +320,21 @@
{"gluDisk", {"quad", in}}.
{"gluCylinder", {"quad", in}}.
-%% OpenGL 3.0
+%% OpenGL 3.0 and later
{"glGetBooleani_v", {"data", {single,{list,16}}}}.
{"glGetIntegeri_v", {"data", {single,{list,16}}}}.
+{"glGetFloati_v", {"data", {single,{list,16}}}}.
+{"glGetDoublei_v", {"data", {single,{list,16}}}}.
+{"glGetInteger64i_v", {"data", {single,{list,16}}}}.
+
+{"glGetBufferParameteriv", {"params", {single,{list,16}}}}.
+{"glGetBufferParameteri64v", {"params", {single,{list,16}}}}.
{"glTransformFeedbackVaryings", [{"count", {c_only,{length,"varyings"}}},
{"varyings", [{base,string}, {single,list}]}]}.
-{"glGetTransformFeedbackVarying", [{"size", {single, true}},{"type", {single, true}},
+{"glGetTransformFeedbackVarying", [{"size", {single, true}},{"type", {single, true}},
{"length", [skip, {single, true}]},
- {"name", {single, {list,"bufSize","length"}}}]}.
+ {"name", {string,"bufSize","length"}}]}.
{"glGenRenderbuffers", {"renderbuffers", {single,{list,"n","n"}}}}.
@@ -327,7 +362,133 @@
{"params", [out, {single, {list, "uniformIndicesLen", "uniformIndicesLen"}}]}]}.
{"glGetActiveUniformName", [{"length",[skip,{single, true}]},
- {"uniformName", {single, {list,"bufSize","length"}}}]}.
+ {"uniformName", {string,"bufSize","length"}}]}.
{"glGetActiveUniformBlockName", [{"length",[skip,{single, true}]},
- {"uniformBlockName", {single, {list,"bufSize","length"}}}]}.
+ {"uniformBlockName", {string,"bufSize","length"}}]}.
{"glGetActiveUniformBlockiv", {"params", [in, {base,memory}]}}.
+
+
+{"glGetSynciv", [{"values", {single, {list, "bufSize","length"}}},
+ {"length", [skip,{single, true}]}]}.
+
+{"glGetMultisamplefv", {"val", [out, {single, {tuple,2}}]}}.
+
+
+{"glNamedStringARB", [{"stringlen", {c_only, {length, "string"}}},
+ {"namelen", {c_only, {length, "name"}}}]}.
+{"glDeleteNamedStringARB", [{"namelen", {c_only, {length, "name"}}}]}.
+{"glIsNamedStringARB", [{"namelen", {c_only, {length, "name"}}}]}.
+{"glGetNamedStringARB",[{"namelen", {c_only, {length, "name"}}},
+ {"stringlen",[skip,{single, true}]},
+ {"string", {string,"bufSize","stringlen"}}]}.
+{"glGetNamedStringivARB",[{"namelen", {c_only, {length, "name"}}},
+ {"params", [out, {single, true}]}]}.
+{"glCompileShaderIncludeARB", [{"length", {c_only,{constant,"NULL"}}},
+ {"count", {c_only,{length,"path"}}},
+ {"path", {single,list}}]}.
+
+
+{"glGenSamplers", {"samplers", {single, {list,"count","count"}}}}.
+{"glDeleteSamplers", [{"count", {c_only, {length, "samplers"}}},
+ {"samplers", {single, list}}]}.
+{"glGetSamplerParameter", {"params", {single, {list, 4}}}}.
+{"glSamplerParameterI", {"param", {single, list}}}.
+{"glSamplerParameterfv", {"param", {single, list}}}.
+{"glSamplerParameteriv", {"param", {single, list}}}.
+
+%{"glGetActiveSubroutineUniformiv", {"values", }}.
+{"glGetActiveSubroutineUniformName", [{"length",[skip,{single, true}]},
+ {"name", {string,"bufsize","length"}}]}.
+{"glGetActiveSubroutineName", [{"length",[skip,{single, true}]},
+ {"name", {string,"bufsize","length"}}]}.
+{"glGetProgramStageiv", {"values", {single, true}}}.
+{"glUniformSubroutinesuiv", [{"count",{c_only,{length,"indices"}}},{"indices", {single, list}}]}.
+
+{"glGenTransformFeedbacks", {"ids", {single, {list,"n","n"}}}}.
+{"glDeleteTransformFeedbacks", [{"n", {c_only, {length, "ids"}}},
+ {"ids", {single, list}}]}.
+
+{"glPatchParameterfv", {"values", {single, list}}}.
+
+
+{"glGetQueryIndexediv", {"params", {single, true} }}.
+{"glShaderBinary", [{"count", {c_only, {length, "shaders"}}},
+ {"length", {c_only, {size, "binary"}}},
+ {"shaders", {single, list}},
+ {"binary", binary}
+ ]}.
+{"glGetShaderPrecisionFormat", [{"range", {single, {tuple, 2}}},
+ {"precision", {single, true}}]}.
+
+{"glGetProgramBinary", [{"length",[skip,{single, true}]},
+ {"binary", [out, {binary, "bufSize", "length"}]},
+ {"binaryFormat", {single, true}}]}.
+{"glProgramBinary", [{"binary", binary}, {"length", {c_only, {size, "binary"}}}]}.
+
+{"glGenProgramPipelines", {"pipelines", {single, {list,"n","n"}}}}.
+{"glDeleteProgramPipelines", [{"n", {c_only, {length, "pipelines"}}},
+ {"pipelines", {single, list}}]}.
+
+{"glCreateShaderProgramv", [{"count", {c_only, {length, "strings"}}},
+ {"strings", {single, list}}]}.
+{"glGetProgramPipelineInfoLog", [{"length", [skip,{single, true}]},
+ {"infoLog", {string,"bufSize","length"}}]}.
+{"glGetProgramPipelineiv", {"params", {single, true}}}.
+
+
+%% {"glCreateSyncFromCLeventARB", {"context", }}.
+
+{"glDebugMessageControlARB", [{"count", {c_only, {length, "ids"}}},
+ {"ids", {single, list}}]}.
+{"glDebugMessageInsertARB", {"length", {c_only, {length, "buf"}}}}.
+{"glGetDebugMessageLogARB", [{"sources", {single, {list, "count", "result"}}},
+ {"types", {single, {list, "count", "result"}}},
+ {"ids", {single, {list, "count", "result"}}},
+ {"severities", {single, {list, "count", "result"}}},
+ {"lengths", [{c_only, undefined}, {single, {list, "count", "result"}}]},
+ {"messageLog", [{string, "bufsize", "lengths"},
+ {single, {list, "bufsize", "result"}}]}]}.
+
+
+{"glUniformMatrix2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,4}}]}]}.
+{"glUniformMatrix3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,9}}]}]}.
+{"glUniformMatrix4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,16}}]}]}.
+{"glUniformMatrix2x3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}.
+{"glUniformMatrix3x2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}.
+{"glUniformMatrix2x4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}.
+{"glUniformMatrix4x2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}.
+{"glUniformMatrix3x4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}.
+{"glUniformMatrix4x3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}.
+
+{"glProgramUniform1", [{"count",{c_only,{length,"value"}}}, {"value", [{single,list}]}]}.
+{"glProgramUniform2", [{"count",{c_only,{length,"value"}}}, {"value", [{single,{tuple_list,2}}]}]}.
+{"glProgramUniform3", [{"count",{c_only,{length,"value"}}}, {"value", [{single,{tuple_list,3}}]}]}.
+{"glProgramUniform4", [{"count",{c_only,{length,"value"}}}, {"value", [{single,{tuple_list,4}}]}]}.
+
+{"glProgramUniformMatrix2fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,4}}]}]}.
+{"glProgramUniformMatrix2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,4}}]}]}.
+{"glProgramUniformMatrix3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,9}}]}]}.
+{"glProgramUniformMatrix3fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,9}}]}]}.
+{"glProgramUniformMatrix4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,16}}]}]}.
+{"glProgramUniformMatrix4fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,16}}]}]}.
+{"glProgramUniformMatrix2x3fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}.
+{"glProgramUniformMatrix3x2fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}.
+{"glProgramUniformMatrix2x4fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}.
+{"glProgramUniformMatrix4x2fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}.
+{"glProgramUniformMatrix3x4fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}.
+{"glProgramUniformMatrix4x3fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}.
+
+{"glProgramUniformMatrix2x3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}.
+{"glProgramUniformMatrix3x2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}.
+{"glProgramUniformMatrix2x4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}.
+{"glProgramUniformMatrix4x2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}.
+{"glProgramUniformMatrix3x4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}.
+{"glProgramUniformMatrix4x3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}.
+
+{"glViewportArrayv", [{"count",{c_only,{length,"v"}}}, {"v", [{single,{tuple_list,4}}]}]}.
+{"glViewportIndexedfv", {"v", {single,{tuple,4}}}}.
+{"glScissorArrayv", [{"count",{c_only,{length,"v"}}}, {"v", [{single,{tuple_list,4}}]}]}.
+{"glScissorIndexedv", {"v", {single,{tuple,4}}}}.
+{"glDepthRangeArrayv", [{"count",{c_only,{length,"v"}}}, {"v", [{single,{tuple_list,2}}]}]}.
+
+
diff --git a/lib/wx/api_gen/wx_gen.erl b/lib/wx/api_gen/wx_gen.erl
index c075324c1f..2f20c42a5d 100644
--- a/lib/wx/api_gen/wx_gen.erl
+++ b/lib/wx/api_gen/wx_gen.erl
@@ -887,7 +887,7 @@ add_method2(M0=#method{name=Name,params=Ps0,type=T0},#class{name=CName,parent=Pa
id = next_id(func_id),
pre_hook = get_opt(pre_hook, Name, length(Ps), Opts),
post_hook = get_opt(post_hook, Name, length(Ps), Opts),
- doc = get_opt(doc, Name, length(Ps), Opts)
+ doc = get_opt(doc, Name, length(Ps), Opts)
},
M = case Name of
CName ->
diff --git a/lib/wx/api_gen/wx_gen.hrl b/lib/wx/api_gen/wx_gen.hrl
index 17265a2842..426e3adfae 100644
--- a/lib/wx/api_gen/wx_gen.hrl
+++ b/lib/wx/api_gen/wx_gen.hrl
@@ -43,9 +43,9 @@
id = undefined, % Id (integer)
doc, % Extra documentation
virtual, % Is virtual?
- pre_hook, % Pre hook before call in c-code
- post_hook % Post hook after call in c-code
- }
+ pre_hook = [], % Pre hook before call in c-code
+ post_hook = [] % Post hook after call in c-code
+ }
).
-record(param,
diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl
index 846cec46c4..4b33068d8f 100644
--- a/lib/wx/api_gen/wx_gen_cpp.erl
+++ b/lib/wx/api_gen/wx_gen_cpp.erl
@@ -152,6 +152,7 @@ gen_funcs(Defs) ->
w("#include \"../wxe_impl.h\"~n"),
w("#include \"../wxe_events.h\"~n"),
w("#include \"../wxe_return.h\"~n"),
+ w("#include \"../wxe_gl.h\"~n"),
w("#include \"wxe_macros.h\"~n"),
w("#include \"wxe_derived_dest.h\"~n~n"),
@@ -176,6 +177,9 @@ gen_funcs(Defs) ->
" rt.addAtom(\"ok\");~n"
" break;~n"
" }~n"),
+ w(" case WXE_BIN_INCR:~n driver_binary_inc_refc(Ecmd.bin[0]->bin);~n break;~n",[]),
+ w(" case WXE_BIN_DECR:~n driver_binary_dec_refc(Ecmd.bin[0]->bin);~n break;~n",[]),
+ w(" case WXE_INIT_OPENGL:~n wxe_initOpenGL(rt, bp);~n break;~n",[]),
Res = [gen_class(Class) || Class <- Defs],
@@ -265,13 +269,13 @@ gen_method(CName, M=#method{name=N,params=Ps0,type=T,method_type=MT,id=MethodId
Opts = [Opt || Opt = #param{def=Def,in=In,where=Where} <- Ps2,
Def =/= none, In =/= false, Where =/= c],
decode_options(Opts, Align),
- case M#method.pre_hook of
- undefined -> skip;
+ case gen_util:get_hook(c, M#method.pre_hook) of
+ ignore -> skip;
Pre -> w(" ~s;~n", [Pre])
end,
Ps3 = call_wx(N,{MT,CName},T,Ps2),
- case M#method.post_hook of
- undefined -> skip;
+ case gen_util:get_hook(c, M#method.post_hook) of
+ ignore -> skip;
Post -> w(" ~s;~n", [Post])
end,
free_args(),
diff --git a/lib/wx/api_gen/wx_gen_erl.erl b/lib/wx/api_gen/wx_gen_erl.erl
index 7962dd9fbf..e1201ab0d4 100644
--- a/lib/wx/api_gen/wx_gen_erl.erl
+++ b/lib/wx/api_gen/wx_gen_erl.erl
@@ -270,6 +270,16 @@ gen_method2(M=#method{name=N,alias=A,params=Ps,type=T,method_type=MT,id=MethodId
MId = arg_type_tests(Args, "?" ++ get_unique_name(MethodId)),
{MArgs,Align} = marshal_args(Args),
MOpts = marshal_opts(Optional, Align, Args),
+ case gen_util:get_hook(erl, M#method.pre_hook) of
+ ignore -> skip;
+ Pre -> w(" ~s~n", [Pre])
+ end,
+
+ case gen_util:get_hook(erl, M#method.post_hook) of
+ ignore -> skip;
+ _ -> w(" _Result =", [])
+ end,
+
case have_return_vals(T, Ps) of
_ when MT =:= constructor ->
w(" wxe_util:construct(~s,~n <<~s~s>>)", [MId, MArgs,MOpts]);
@@ -278,6 +288,13 @@ gen_method2(M=#method{name=N,alias=A,params=Ps,type=T,method_type=MT,id=MethodId
false ->
w(" wxe_util:cast(~s,~n <<~s~s>>)", [MId, MArgs,MOpts])
end,
+ case gen_util:get_hook(erl, M#method.post_hook) of
+ ignore -> skip;
+ Post ->
+ w(",~n ~s~n", [Post]),
+ w(" _Result", [])
+ end,
+
erase(current_func),
M.
diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf
index 6bafda5b9d..aec8a4944a 100644
--- a/lib/wx/api_gen/wxapi.conf
+++ b/lib/wx/api_gen/wxapi.conf
@@ -505,15 +505,15 @@
{"data",[in,{base,binary}]},
{"alpha",[in,{base,binary}]},
{{4,pre_hook},
- "if(!static_data) {"
- "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"},
+ [{c, "if(!static_data) {"
+ "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]},
{{5,pre_hook},
- "if(!static_data) {"
- " data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);"
- " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);"
- " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"}
+ [{c, "if(!static_data) {"
+ " data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);"
+ " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);"
+ " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"}]}
]},
'~wxImage',%'AddHandler',
'Blur','BlurHorizontal','BlurVertical',
@@ -524,15 +524,15 @@
{"data",[in,{base,binary}]},
{"alpha",[in,{base,binary}]},
{{4,pre_hook},
- "if(!static_data) {"
- "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"},
+ [{c, "if(!static_data) {"
+ "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]},
{{5,pre_hook},
- "if(!static_data) {"
- " data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);"
- " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);"
- " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"}
+ [{c, "if(!static_data) {"
+ " data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);"
+ " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);"
+ " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"}]}
]},
'Destroy','FindFirstUnusedColour', % 'FindHandler',
'GetImageExtWildcard',
@@ -551,15 +551,15 @@
'Rotate90','SaveFile','Scale','Size',
{'SetAlpha', [{{2,"alpha"},[in,{base,binary}, {def, none}]},
{{2,pre_hook},
- "if(!static_data) {"
- "alpha = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- "memcpy(alpha,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}
+ [{c, "if(!static_data) {"
+ "alpha = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ "memcpy(alpha,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]}
]},
{'SetData', [{"data",[in,{base,binary}]},
{pre_hook,
- "if(!static_data) {"
- "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
- "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}
+ [{c, "if(!static_data) {"
+ "data = (unsigned char *) malloc(Ecmd.bin[0]->size);"
+ "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]}
]},
'SetMask','SetMaskColour','SetMaskFromImage','SetOption',
'SetPalette',
@@ -1148,7 +1148,8 @@
[{skip, [{'SetCurrent', 2}]}], %% NA MAC
[{'wxGLCanvas', [{"attribList", [in, {single,array}]}]},
'GetContext',
- {'SetCurrent', [{post_hook,"if(This->GetContext()) setActiveGL(Ecmd.caller,This)"}]},
+ {'SetCurrent', [{post_hook,[{c, "if(This->GetContext()) setActiveGL(Ecmd.caller,This)"},
+ {erl, "{ok, _} = wxe_master:init_opengl(),"}]}]},
%%{'SetColour', [{"colour", [in, {single,array}]}]},
'SwapBuffers']}.
diff --git a/lib/wx/c_src/Makefile.in b/lib/wx/c_src/Makefile.in
index 8710641b57..69418f62ef 100644
--- a/lib/wx/c_src/Makefile.in
+++ b/lib/wx/c_src/Makefile.in
@@ -32,14 +32,16 @@ endif
SO_EXT = @SO_EXT@
-GENERAL = wxe_driver wxe_ps_init wxe_impl wxePrintout wxe_return
+GENERAL = wxe_driver wxe_ps_init wxe_impl wxePrintout wxe_return wxe_gl
GENERAL_H = wxe_driver.h wxe_impl.h wxe_return.h
GENERATED_F = wxe_funcs wxe_events wxe_init
-GENERATED_H = gen/wxe_macros.h gen/glu_finit.h gen/gl_finit.h gen/gl_fdefs.h
+GENERATED_H = gen/wxe_macros.h
+
+GL_H = egl_impl.h gen/glu_finit.h gen/gl_finit.h gen/gl_fdefs.h
HAVE_OPENGL = true
-OPENGL_F = gl_funcs wxe_gl
+OPENGL_F = gl_funcs egl_impl
ifneq ($(INSIDE_ERLSRC),true)
@@ -60,9 +62,9 @@ SYS_TYPE = @WXERL_SYS_TYPE@
GENERAL_O = $(GENERAL:%=$(SYS_TYPE)/%.o)
GENERATED_O = $(GENERATED_F:%=$(SYS_TYPE)/%.o)
ifeq ($(HAVE_OPENGL), true)
- OPENGL_O = $(OPENGL_F:%=$(SYS_TYPE)/%.o)
+ GL_OBJECTS = $(OPENGL_F:%=$(SYS_TYPE)/%.o)
else
- OPENGL_O =
+ GL_OBJECTS =
endif
RC_FILE_EXT = @RC_FILE_TYPE@
@@ -72,10 +74,12 @@ else
RC_FILE =
endif
-OBJECTS = $(GENERAL_O) $(GENERATED_O) $(OPENGL_O) $(RC_FILE)
+WX_OBJECTS = $(GENERAL_O) $(GENERATED_O) $(RC_FILE)
+
+OBJECTS = $(WX_OBJECTS) $(GL_OBJECTS)
-TARGET_API = wxe_driver
-TARGET_DIR = ../priv/$(SYS_TYPE)
+TARGET_APIS = wxe_driver erl_gl
+TARGET_DIR = ../priv
# -O2 -funroll-loops -ffast-math -fomit-frame-pointer
@@ -87,31 +91,36 @@ LD = $(CPP)
LDFLAGS = @LDFLAGS@
RESCOMP = @WX_RESCOMP@
-
ifeq (@WX_HAVE_STATIC_LIBS@,true)
-WX_LIBS = @WX_LIBS_STATIC@
+OPT_WX_LIBS = @WX_LIBS_STATIC@
DEBUG_WX_LIBS = @DEBUG_WX_LIBS_STATIC@
else
-WX_LIBS = @WX_LIBS@
+OPT_WX_LIBS = @WX_LIBS@
DEBUG_WX_LIBS = @DEBUG_WX_LIBS@
endif
ifeq ($(TYPE),debug)
-CFLAGS = @DEBUG_WX_CFLAGS@ @DEBUG_CFLAGS@
-CPP_FLAGS = @DEBUG_WX_CXXFLAGS@ @DEBUG_CXXFLAGS@
-LIBS = $(DEBUG_WX_LIBS)
+WX_CFLAGS = @DEBUG_WX_CFLAGS@
+CFLAGS = @DEBUG_CFLAGS@
+WX_CXX_FLAGS = @DEBUG_WX_CXXFLAGS@
+CXX_FLAGS = @DEBUG_CXXFLAGS@
+WX_LIBS = $(DEBUG_WX_LIBS)
else
-CFLAGS = @WX_CFLAGS@ @CFLAGS@
-CPP_FLAGS = @WX_CXXFLAGS@ @CXXFLAGS@
-LIBS = $(WX_LIBS)
+WX_CFLAGS = @WX_CFLAGS@
+CFLAGS = @CFLAGS@
+WX_CXX_FLAGS = @WX_CXXFLAGS@
+CXX_FLAGS = @CXXFLAGS@
+WX_LIBS = $(OPT_WX_LIBS)
endif
-CC_O = $(CC) -c $(CFLAGS) $(COMMON_CFLAGS)
-CPP_O = $(CPP) -c $(CPP_FLAGS) $(COMMON_CFLAGS)
+GL_LIBS = @GL_LIBS@
+
+CC_O = $(CC) -c $(CFLAGS) $(WX_CFLAGS) $(COMMON_CFLAGS)
+CPP_O = $(CPP) -c $(CXX_FLAGS) $(WX_CXX_FLAGS) $(COMMON_CFLAGS)
# Targets
-opt: $(TARGET_DIR)/$(TARGET_API)$(SO_EXT)
+opt: $(TARGET_DIR)/wxe_driver$(SO_EXT) $(TARGET_DIR)/erl_gl$(SO_EXT)
debug:
@${MAKE} TYPE=debug
@@ -132,20 +141,22 @@ complete_clean:
docs:
+$(GL_OBJECTS): $(GL_H)
+$(WX_OBJECTS): $(GENERATED_H) $(GENERAL_H)
-$(SYS_TYPE)/%.o: %.cpp $(GENERATED_H) $(GENERAL_H)
+$(SYS_TYPE)/%.o: %.cpp
mkdir -p $(SYS_TYPE)
$(CPP_O) $< -o $@
-$(SYS_TYPE)/%.o: %.c $(GENERATED_H) $(GENERAL_H)
+$(SYS_TYPE)/%.o: %.c
mkdir -p $(SYS_TYPE)
$(CC_O) $< -o $@
-$(SYS_TYPE)/%.o: gen/%.cpp $(GENERATED_H) $(GENERAL_H)
+$(SYS_TYPE)/%.o: gen/%.cpp
mkdir -p $(SYS_TYPE)
$(CPP_O) $< -o $@
-$(SYS_TYPE)/%.o: gen/%.c $(GENERATED_H) $(GENERAL_H)
+$(SYS_TYPE)/%.o: gen/%.c
mkdir -p $(SYS_TYPE)
$(CC_O) $< -o $@
@@ -153,9 +164,13 @@ $(SYS_TYPE)/wxe_win32.$(RC_FILE_EXT): wxe_win32.rc
mkdir -p $(SYS_TYPE)
$(RESCOMP) -o $@ $<
-$(TARGET_DIR)/$(TARGET_API)$(SO_EXT): $(OBJECTS)
+$(TARGET_DIR)/wxe_driver$(SO_EXT): $(WX_OBJECTS)
+ mkdir -p $(TARGET_DIR)
+ $(LD) $(LDFLAGS) $(WX_OBJECTS) $(WX_LIBS) -o $@
+
+$(TARGET_DIR)/erl_gl$(SO_EXT): $(GL_OBJECTS)
mkdir -p $(TARGET_DIR)
- $(LD) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
+ $(CC) $(LDFLAGS) $(GL_OBJECTS) $(GL_LIBS) -o $@
# ----------------------------------------------------
@@ -164,10 +179,11 @@ $(TARGET_DIR)/$(TARGET_API)$(SO_EXT): $(OBJECTS)
ifeq ($(INSIDE_ERLSRC),true)
include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
- $(INSTALL_DIR) $(RELSYSDIR)/priv/$(SYS_TYPE)
+ $(INSTALL_DIR) $(RELSYSDIR)/priv
$(INSTALL_DATA) ../priv/erlang-logo32.png $(RELSYSDIR)/priv/
$(INSTALL_DATA) ../priv/erlang-logo64.png $(RELSYSDIR)/priv/
- $(INSTALL_PROGRAM) $(TARGET_DIR)/$(TARGET_API)$(SO_EXT) $(RELSYSDIR)/priv/$(SYS_TYPE)
+ $(INSTALL_PROGRAM) $(TARGET_DIR)/wxe_driver$(SO_EXT) $(RELSYSDIR)/priv/
+ $(INSTALL_PROGRAM) $(TARGET_DIR)/erl_gl$(SO_EXT) $(RELSYSDIR)/priv/
release_docs_spec:
diff --git a/lib/wx/c_src/egl_impl.cpp b/lib/wx/c_src/egl_impl.cpp
new file mode 100644
index 0000000000..e2dbbb73c4
--- /dev/null
+++ b/lib/wx/c_src/egl_impl.cpp
@@ -0,0 +1,306 @@
+/*
+ * %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%
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#include "egl_impl.h"
+
+#define WX_DEF_EXTS
+#include "gen/gl_fdefs.h"
+#include "gen/gl_finit.h"
+#include "gen/glu_finit.h"
+
+void init_tess();
+void exit_tess();
+int load_gl_functions();
+
+/* ****************************************************************************
+ * OPENGL INITIALIZATION
+ *****************************************************************************/
+
+int egl_initiated = 0;
+
+#ifdef _WIN32
+#define RTLD_LAZY 0
+#define OPENGL_LIB L"opengl32.dll"
+#define OPENGLU_LIB L"glu32.dll"
+typedef HMODULE DL_LIB_P;
+typedef WCHAR DL_CHAR;
+void * dlsym(HMODULE Lib, const char *func) {
+ void * funcp;
+ if((funcp = (void *) GetProcAddress(Lib, func)))
+ return funcp;
+ else
+ return (void *) wglGetProcAddress(func);
+}
+
+HMODULE dlopen(const WCHAR *DLL, int unused) {
+ return LoadLibrary(DLL);
+}
+
+void dlclose(HMODULE Lib) {
+ FreeLibrary(Lib);
+}
+
+#else
+typedef void * DL_LIB_P;
+typedef char DL_CHAR;
+# ifdef _MACOSX
+# define OPENGL_LIB "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"
+# define OPENGLU_LIB "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib"
+# else
+# define OPENGL_LIB "libGL.so"
+# define OPENGLU_LIB "libGLU.so"
+# endif
+#endif
+extern "C" {
+DRIVER_INIT(EGL_DRIVER) {
+ return NULL;
+}
+}
+
+int egl_init_opengl(void *erlCallbacks)
+{
+#ifdef _WIN32
+ driver_init((TWinDynDriverCallbacks *) erlCallbacks);
+#endif
+ if(egl_initiated == 0) {
+ if(load_gl_functions()) {
+ init_tess();
+ egl_initiated = 1;
+ }
+ }
+ return 1;
+}
+
+int load_gl_functions() {
+ DL_CHAR * DLName = OPENGL_LIB;
+ DL_LIB_P LIBhandle = dlopen(DLName, RTLD_LAZY);
+ //fprintf(stderr, "Loading GL: %s\r\n", (const char*)DLName);
+ void * func = NULL;
+ int i;
+
+ if(LIBhandle) {
+ for(i=0; gl_fns[i].name != NULL; i++) {
+ if((func = dlsym(LIBhandle, gl_fns[i].name))) {
+ * (void **) (gl_fns[i].func) = func;
+ // fprintf(stderr, "GL LOADED %s \r\n", gl_fns[i].name);
+ } else {
+ if(gl_fns[i].alt != NULL) {
+ if((func = dlsym(LIBhandle, gl_fns[i].alt))) {
+ * (void **) (gl_fns[i].func) = func;
+ // fprintf(stderr, "GL LOADED %s \r\n", gl_fns[i].alt);
+ } else {
+ * (void **) (gl_fns[i].func) = (void *) &gl_error;
+ // fprintf(stderr, "GL Skipped %s and %s \r\n", gl_fns[i].name, gl_fns[i].alt);
+ };
+ } else {
+ * (void **) (gl_fns[i].func) = (void *) &gl_error;
+ // fprintf(stderr, "GL Skipped %s \r\n", gl_fns[i].name);
+ }
+ }
+ }
+ dlclose(LIBhandle);
+ // fprintf(stderr, "OPENGL library is loaded\r\n");
+ } else {
+ fprintf(stderr, "Could NOT load OpenGL library: %s\r\n", DLName);
+ };
+
+ DLName = OPENGLU_LIB;
+ LIBhandle = dlopen(DLName, RTLD_LAZY);
+ // fprintf(stderr, "Loading GLU: %s\r\n", (const char*)DLName);
+ func = NULL;
+
+ if(LIBhandle) {
+ for(i=0; glu_fns[i].name != NULL; i++) {
+ if((func = dlsym(LIBhandle, glu_fns[i].name))) {
+ * (void **) (glu_fns[i].func) = func;
+ } else {
+ if(glu_fns[i].alt != NULL) {
+ if((func = dlsym(LIBhandle, glu_fns[i].alt))) {
+ * (void **) (glu_fns[i].func) = func;
+ } else {
+ * (void **) (glu_fns[i].func) = (void *) &gl_error;
+ // fprintf(stderr, "GLU Skipped %s\r\n", glu_fns[i].alt);
+ };
+ } else {
+ * (void **) (glu_fns[i].func) = (void *) &gl_error;
+ // fprintf(stderr, "GLU Skipped %s\r\n", glu_fns[i].name);
+ }
+ }
+ }
+ dlclose(LIBhandle);
+ // fprintf(stderr, "GLU library is loaded\r\n");
+ } else {
+ fprintf(stderr, "Could NOT load OpenGL GLU library: %s\r\n", DLName);
+ };
+
+ return 1;
+}
+
+void gl_error() {
+ // fprintf(stderr, "OpenGL Extension not available \r\n");
+ throw "undef_extension";
+}
+
+/* *******************************************************************************
+ * GLU Tesselation special
+ * ******************************************************************************/
+
+static GLUtesselator* tess;
+static GLdouble* tess_coords;
+static GLdouble* tess_alloc_vertex;
+static int* tess_vertices;
+
+void CALLBACK
+egl_ogla_vertex(GLdouble* coords)
+{
+ /* fprintf(stderr, "%d\r\n", (int) (coords - tess_coords) / 3); */
+
+ *tess_vertices++ = (int) (coords - tess_coords) / 3;
+}
+
+void CALLBACK
+egl_ogla_edge_flag(GLboolean flag)
+{
+}
+
+void CALLBACK
+egl_ogla_error(GLenum errorCode)
+{
+ const GLubyte *err;
+ err = gluErrorString(errorCode);
+ // wxString msg;
+ // msg.Printf(wxT("Tesselation error: %d: "), (int)errorCode);
+ // msg += wxString::FromAscii((char *) err);
+ // send_msg("error", &msg);
+ fprintf(stderr, "Tesselation error: %d\r\n", (int) errorCode);
+}
+
+void CALLBACK
+egl_ogla_combine(GLdouble coords[3],
+ void* vertex_data[4],
+ GLfloat w[4],
+ void **dataOut)
+{
+ GLdouble* vertex = tess_alloc_vertex;
+
+ tess_alloc_vertex += 3;
+
+#if 0
+ fprintf(stderr, "combine: ");
+ int i;
+ for (i = 0; i < 4; i++) {
+ if (w[i] > 0.0) {
+ fprintf(stderr, "%d(%g) ", (int) vertex_data[i], w[i]);
+ }
+ }
+ fprintf(stderr, "\r\n");
+ fprintf(stderr, "%g %g %g\r\n", vertex[0], vertex[1], vertex[2]);
+#endif
+
+ vertex[0] = coords[0];
+ vertex[1] = coords[1];
+ vertex[2] = coords[2];
+ *dataOut = vertex;
+}
+
+void init_tess()
+{
+ tess = gluNewTess();
+
+ gluTessCallback(tess, GLU_TESS_VERTEX, (GLUfuncptr) egl_ogla_vertex);
+ gluTessCallback(tess, GLU_TESS_EDGE_FLAG, (GLUfuncptr) egl_ogla_edge_flag);
+ gluTessCallback(tess, GLU_TESS_COMBINE, (GLUfuncptr) egl_ogla_combine);
+ gluTessCallback(tess, GLU_TESS_ERROR, (GLUfuncptr) egl_ogla_error);
+
+}
+
+void exit_tess()
+{
+ gluDeleteTess(tess);
+}
+
+int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller)
+{
+ ErlDrvBinary* bin;
+ int i;
+ GLdouble* new_vertices;
+ int *vertices;
+ int num_vertices;
+ GLdouble *n;
+ int n_pos, AP, res;
+
+ num_vertices = * (int *) buff; buff += 8; /* Align */
+ n = (double *) buff; buff += 8*3;
+
+ bin = driver_alloc_binary(num_vertices*6*sizeof(GLdouble));
+ new_vertices = tess_coords = (double *) bin->orig_bytes;
+ memcpy(tess_coords,buff,num_vertices*3*sizeof(GLdouble));
+ tess_alloc_vertex = tess_coords + num_vertices*3;
+
+#if 0
+ fprintf(stderr, "n=%d\r\n", num_vertices);
+#endif
+ vertices = (int *) driver_alloc(sizeof(int) * 16*num_vertices);
+
+ tess_vertices = vertices;
+
+ gluTessNormal(tess, n[0], n[1], n[2]);
+ gluTessBeginPolygon(tess, 0);
+ gluTessBeginContour(tess);
+ for (i = 0; i < num_vertices; i++) {
+ gluTessVertex(tess, tess_coords+3*i, tess_coords+3*i);
+ }
+ gluTessEndContour(tess);
+ gluTessEndPolygon(tess);
+
+ n_pos = (tess_vertices - vertices);
+
+ AP = 0; ErlDrvTermData *rt;
+ rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+n_pos*2));
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+
+ for(i=0; i < n_pos; i++) {
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) vertices[i];
+ };
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = n_pos+1;
+
+ rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) bin;
+ rt[AP++] = (tess_alloc_vertex-new_vertices)*sizeof(GLdouble); rt[AP++] = 0;
+
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin}
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple
+
+ res = driver_send_term(port,caller,rt,AP);
+ /* fprintf(stderr, "List %d: %d %d %d \r\n", */
+ /* res, */
+ /* n_pos, */
+ /* (tess_alloc_vertex-new_vertices)*sizeof(GLdouble), */
+ /* num_vertices*6*sizeof(GLdouble)); */
+ driver_free_binary(bin);
+ driver_free(vertices);
+ driver_free(rt);
+ return 0;
+}
diff --git a/lib/wx/c_src/egl_impl.h b/lib/wx/c_src/egl_impl.h
new file mode 100644
index 0000000000..e93e4caefd
--- /dev/null
+++ b/lib/wx/c_src/egl_impl.h
@@ -0,0 +1,149 @@
+/*
+ * %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%
+ */
+
+#include "erl_driver.h"
+
+/* Wrap everything from glext.h so we are not dependent on the user version of it */
+
+#ifndef _WIN32
+# include <dlfcn.h>
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#include <gl/gl.h>
+#include <gl/glu.h>
+#elif defined(HAVE_GL_GL_H)
+#include <GL/gl.h>
+# include <GL/glu.h>
+#elif defined(HAVE_OPENGL_GL_H)
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+
+#ifndef CALLBACK
+# define CALLBACK
+#endif
+
+#ifdef _WIN32
+# ifndef _GLUfuncptr
+// Visual studio CPP ++ compiler
+# define _GLUfuncptr void (_stdcall *)()
+# endif
+#endif
+
+#ifdef _GLUfuncptr
+# define GLUfuncptr _GLUfuncptr
+#elif defined(TESS_CB_TIGER_STYLE)
+# define GLUfuncptr GLvoid (*)(...)
+#else
+# define GLUfuncptr GLvoid (*)()
+#endif
+
+/* Some new GL types (eliminates the need for glext.h) */
+
+#ifndef HAVE_GLINTPTR
+#ifndef HAVE_GLINTPTRARB
+# include <stddef.h>
+/* GL types for handling large vertex buffer objects */
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+#endif /* HAVE_GLINTPTRARB */
+typedef GLintptrARB GLintptr;
+typedef GLsizeiptrARB GLsizeiptr;
+#endif /* HAVE_GLINTPTR */
+
+#ifndef HAVE_GLCHAR
+# ifndef HAVE_GLCHARARB
+/* GL types for handling shader object handles and characters */
+typedef char GLcharARB; /* native character */
+typedef unsigned int GLhandleARB; /* shader object handle */
+#endif /* HAVE_GLCHARARB */
+typedef GLcharARB GLchar;
+#endif
+
+#ifndef HAVE_GLHALFARB
+/* GL types for "half" precision (s10e5) float data in host memory */
+typedef unsigned short GLhalfARB;
+#endif
+
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GLX_OML_sync_control extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+#elif defined(__sun__)
+#include <inttypes.h>
+#if defined(__STDC__)
+#if defined(__arch64__)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS )
+#include <inttypes.h>
+#elif defined(__SCO__) || defined(__USLC__)
+#include <stdint.h>
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(WIN32) && defined(_MSC_VER)
+typedef long int int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#elif defined(WIN32) && defined(__GNUC__)
+#include <stdint.h>
+#else
+#include <inttypes.h> /* Fallback option */
+#endif
+
+#ifndef HAVE_GLINT64EXT
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+#endif
+
+#ifndef GL_ARB_sync
+typedef int64_t GLint64;
+typedef uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+#endif
+
+/* External Api */
+
+#ifdef _WIN32
+extern "C" __declspec(dllexport) int egl_init_opengl(void *);
+extern "C" __declspec(dllexport) void egl_dispatch(int, char *, ErlDrvPort, ErlDrvTermData, char **, int *);
+#else
+extern "C" int egl_init_opengl(void *);
+extern "C" void egl_dispatch(int, char *, ErlDrvPort, ErlDrvTermData, char **, int *);
+#endif
+
+/* internal */
+int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller);
+void gl_error();
+extern int gl_error_op;
+extern ErlDrvTermData gl_active;
+
diff --git a/lib/wx/c_src/gen/gl_fdefs.h b/lib/wx/c_src/gen/gl_fdefs.h
index 2096f7a413..a45896d30d 100644
--- a/lib/wx/c_src/gen/gl_fdefs.h
+++ b/lib/wx/c_src/gen/gl_fdefs.h
@@ -24,6 +24,13 @@
# define WXE_EXTERN extern
#endif
+typedef struct {
+ const char * name;
+ const char * alt;
+ void * func;
+} gl_fns_t;
+
+#define GLE_GL_FUNC_START 5037
typedef void (APIENTRY * WXEGLACCUM)(GLenum,GLfloat);
WXE_EXTERN WXEGLACCUM weglAccum;
typedef void (APIENTRY * WXEGLALPHAFUNC)(GLenum,GLclampf);
@@ -684,7 +691,7 @@ typedef void (APIENTRY * WXEGLMULTTRANSPOSEMATRIXD)(const GLdouble *);
WXE_EXTERN WXEGLMULTTRANSPOSEMATRIXD weglMultTransposeMatrixd;
typedef void (APIENTRY * WXEGLBLENDFUNCSEPARATE)(GLenum,GLenum,GLenum,GLenum);
WXE_EXTERN WXEGLBLENDFUNCSEPARATE weglBlendFuncSeparate;
-typedef void (APIENTRY * WXEGLMULTIDRAWARRAYS)(GLenum,GLint *,GLsizei *,GLsizei);
+typedef void (APIENTRY * WXEGLMULTIDRAWARRAYS)(GLenum,const GLint *,const GLsizei *,GLsizei);
WXE_EXTERN WXEGLMULTIDRAWARRAYS weglMultiDrawArrays;
typedef void (APIENTRY * WXEGLPOINTPARAMETERF)(GLenum,GLfloat);
WXE_EXTERN WXEGLPOINTPARAMETERF weglPointParameterf;
@@ -972,6 +979,30 @@ typedef void (APIENTRY * WXEGLGETVERTEXATTRIBIIV)(GLuint,GLenum,GLint *);
WXE_EXTERN WXEGLGETVERTEXATTRIBIIV weglGetVertexAttribIiv;
typedef void (APIENTRY * WXEGLGETVERTEXATTRIBIUIV)(GLuint,GLenum,GLuint *);
WXE_EXTERN WXEGLGETVERTEXATTRIBIUIV weglGetVertexAttribIuiv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI1IV)(GLuint,const GLint *);
+WXE_EXTERN WXEGLVERTEXATTRIBI1IV weglVertexAttribI1iv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI2IV)(GLuint,const GLint *);
+WXE_EXTERN WXEGLVERTEXATTRIBI2IV weglVertexAttribI2iv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI3IV)(GLuint,const GLint *);
+WXE_EXTERN WXEGLVERTEXATTRIBI3IV weglVertexAttribI3iv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI4IV)(GLuint,const GLint *);
+WXE_EXTERN WXEGLVERTEXATTRIBI4IV weglVertexAttribI4iv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI1UIV)(GLuint,const GLuint *);
+WXE_EXTERN WXEGLVERTEXATTRIBI1UIV weglVertexAttribI1uiv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI2UIV)(GLuint,const GLuint *);
+WXE_EXTERN WXEGLVERTEXATTRIBI2UIV weglVertexAttribI2uiv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI3UIV)(GLuint,const GLuint *);
+WXE_EXTERN WXEGLVERTEXATTRIBI3UIV weglVertexAttribI3uiv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI4UIV)(GLuint,const GLuint *);
+WXE_EXTERN WXEGLVERTEXATTRIBI4UIV weglVertexAttribI4uiv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI4BV)(GLuint,const GLbyte *);
+WXE_EXTERN WXEGLVERTEXATTRIBI4BV weglVertexAttribI4bv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI4SV)(GLuint,const GLshort *);
+WXE_EXTERN WXEGLVERTEXATTRIBI4SV weglVertexAttribI4sv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI4UBV)(GLuint,const GLubyte *);
+WXE_EXTERN WXEGLVERTEXATTRIBI4UBV weglVertexAttribI4ubv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBI4USV)(GLuint,const GLushort *);
+WXE_EXTERN WXEGLVERTEXATTRIBI4USV weglVertexAttribI4usv;
typedef void (APIENTRY * WXEGLGETUNIFORMUIV)(GLuint,GLint,GLuint *);
WXE_EXTERN WXEGLGETUNIFORMUIV weglGetUniformuiv;
typedef void (APIENTRY * WXEGLBINDFRAGDATALOCATION)(GLuint,GLuint,const GLchar *);
@@ -1012,30 +1043,6 @@ typedef void (APIENTRY * WXEGLCLEARBUFFERFI)(GLenum,GLint,GLfloat,GLint);
WXE_EXTERN WXEGLCLEARBUFFERFI weglClearBufferfi;
typedef const GLubyte * (APIENTRY * WXEGLGETSTRINGI)(GLenum,GLuint);
WXE_EXTERN WXEGLGETSTRINGI weglGetStringi;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI1IV)(GLuint,const GLint *);
-WXE_EXTERN WXEGLVERTEXATTRIBI1IV weglVertexAttribI1iv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI2IV)(GLuint,const GLint *);
-WXE_EXTERN WXEGLVERTEXATTRIBI2IV weglVertexAttribI2iv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI3IV)(GLuint,const GLint *);
-WXE_EXTERN WXEGLVERTEXATTRIBI3IV weglVertexAttribI3iv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI4IV)(GLuint,const GLint *);
-WXE_EXTERN WXEGLVERTEXATTRIBI4IV weglVertexAttribI4iv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI1UIV)(GLuint,const GLuint *);
-WXE_EXTERN WXEGLVERTEXATTRIBI1UIV weglVertexAttribI1uiv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI2UIV)(GLuint,const GLuint *);
-WXE_EXTERN WXEGLVERTEXATTRIBI2UIV weglVertexAttribI2uiv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI3UIV)(GLuint,const GLuint *);
-WXE_EXTERN WXEGLVERTEXATTRIBI3UIV weglVertexAttribI3uiv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI4UIV)(GLuint,const GLuint *);
-WXE_EXTERN WXEGLVERTEXATTRIBI4UIV weglVertexAttribI4uiv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI4BV)(GLuint,const GLbyte *);
-WXE_EXTERN WXEGLVERTEXATTRIBI4BV weglVertexAttribI4bv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI4SV)(GLuint,const GLshort *);
-WXE_EXTERN WXEGLVERTEXATTRIBI4SV weglVertexAttribI4sv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI4UBV)(GLuint,const GLubyte *);
-WXE_EXTERN WXEGLVERTEXATTRIBI4UBV weglVertexAttribI4ubv;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBI4USV)(GLuint,const GLushort *);
-WXE_EXTERN WXEGLVERTEXATTRIBI4USV weglVertexAttribI4usv;
typedef void (APIENTRY * WXEGLDRAWARRAYSINSTANCED)(GLenum,GLint,GLsizei,GLsizei);
WXE_EXTERN WXEGLDRAWARRAYSINSTANCED weglDrawArraysInstanced;
typedef void (APIENTRY * WXEGLDRAWELEMENTSINSTANCED)(GLenum,GLsizei,GLenum,const GLvoid *,GLsizei);
@@ -1044,6 +1051,24 @@ typedef void (APIENTRY * WXEGLTEXBUFFER)(GLenum,GLenum,GLuint);
WXE_EXTERN WXEGLTEXBUFFER weglTexBuffer;
typedef void (APIENTRY * WXEGLPRIMITIVERESTARTINDEX)(GLuint);
WXE_EXTERN WXEGLPRIMITIVERESTARTINDEX weglPrimitiveRestartIndex;
+typedef void (APIENTRY * WXEGLGETINTEGER64I_V)(GLenum,GLuint,GLint64 *);
+WXE_EXTERN WXEGLGETINTEGER64I_V weglGetInteger64i_v;
+typedef void (APIENTRY * WXEGLGETBUFFERPARAMETERI64V)(GLenum,GLenum,GLint64 *);
+WXE_EXTERN WXEGLGETBUFFERPARAMETERI64V weglGetBufferParameteri64v;
+typedef void (APIENTRY * WXEGLFRAMEBUFFERTEXTURE)(GLenum,GLenum,GLuint,GLint);
+WXE_EXTERN WXEGLFRAMEBUFFERTEXTURE weglFramebufferTexture;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBDIVISOR)(GLuint,GLuint);
+WXE_EXTERN WXEGLVERTEXATTRIBDIVISOR weglVertexAttribDivisor;
+typedef void (APIENTRY * WXEGLMINSAMPLESHADING)(GLclampf);
+WXE_EXTERN WXEGLMINSAMPLESHADING weglMinSampleShading;
+typedef void (APIENTRY * WXEGLBLENDEQUATIONI)(GLuint,GLenum);
+WXE_EXTERN WXEGLBLENDEQUATIONI weglBlendEquationi;
+typedef void (APIENTRY * WXEGLBLENDEQUATIONSEPARATEI)(GLuint,GLenum,GLenum);
+WXE_EXTERN WXEGLBLENDEQUATIONSEPARATEI weglBlendEquationSeparatei;
+typedef void (APIENTRY * WXEGLBLENDFUNCI)(GLuint,GLenum,GLenum);
+WXE_EXTERN WXEGLBLENDFUNCI weglBlendFunci;
+typedef void (APIENTRY * WXEGLBLENDFUNCSEPARATEI)(GLuint,GLenum,GLenum,GLenum,GLenum);
+WXE_EXTERN WXEGLBLENDFUNCSEPARATEI weglBlendFuncSeparatei;
typedef void (APIENTRY * WXEGLLOADTRANSPOSEMATRIXFARB)(const GLfloat *);
WXE_EXTERN WXEGLLOADTRANSPOSEMATRIXFARB weglLoadTransposeMatrixfARB;
typedef void (APIENTRY * WXEGLLOADTRANSPOSEMATRIXDARB)(const GLdouble *);
@@ -1112,6 +1137,8 @@ typedef void (APIENTRY * WXEGLGETPROGRAMLOCALPARAMETERFVARB)(GLenum,GLuint,GLflo
WXE_EXTERN WXEGLGETPROGRAMLOCALPARAMETERFVARB weglGetProgramLocalParameterfvARB;
typedef void (APIENTRY * WXEGLGETPROGRAMSTRINGARB)(GLenum,GLenum,GLvoid *);
WXE_EXTERN WXEGLGETPROGRAMSTRINGARB weglGetProgramStringARB;
+typedef void (APIENTRY * WXEGLGETBUFFERPARAMETERIVARB)(GLenum,GLenum,GLint *);
+WXE_EXTERN WXEGLGETBUFFERPARAMETERIVARB weglGetBufferParameterivARB;
typedef void (APIENTRY * WXEGLDELETEOBJECTARB)(GLhandleARB);
WXE_EXTERN WXEGLDELETEOBJECTARB weglDeleteObjectARB;
typedef GLhandleARB (APIENTRY * WXEGLGETHANDLEARB)(GLenum);
@@ -1198,14 +1225,8 @@ typedef void (APIENTRY * WXEGLRENDERBUFFERSTORAGEMULTISAMPLE)(GLenum,GLsizei,GLe
WXE_EXTERN WXEGLRENDERBUFFERSTORAGEMULTISAMPLE weglRenderbufferStorageMultisample;
typedef void (APIENTRY * WXEGLFRAMEBUFFERTEXTURELAYER)(GLenum,GLenum,GLuint,GLint,GLint);
WXE_EXTERN WXEGLFRAMEBUFFERTEXTURELAYER weglFramebufferTextureLayer;
-typedef void (APIENTRY * WXEGLPROGRAMPARAMETERIARB)(GLuint,GLenum,GLint);
-WXE_EXTERN WXEGLPROGRAMPARAMETERIARB weglProgramParameteriARB;
-typedef void (APIENTRY * WXEGLFRAMEBUFFERTEXTUREARB)(GLenum,GLenum,GLuint,GLint);
-WXE_EXTERN WXEGLFRAMEBUFFERTEXTUREARB weglFramebufferTextureARB;
typedef void (APIENTRY * WXEGLFRAMEBUFFERTEXTUREFACEARB)(GLenum,GLenum,GLuint,GLint,GLenum);
WXE_EXTERN WXEGLFRAMEBUFFERTEXTUREFACEARB weglFramebufferTextureFaceARB;
-typedef void (APIENTRY * WXEGLVERTEXATTRIBDIVISORARB)(GLuint,GLuint);
-WXE_EXTERN WXEGLVERTEXATTRIBDIVISORARB weglVertexAttribDivisorARB;
typedef void (APIENTRY * WXEGLFLUSHMAPPEDBUFFERRANGE)(GLenum,GLintptr,GLsizeiptr);
WXE_EXTERN WXEGLFLUSHMAPPEDBUFFERRANGE weglFlushMappedBufferRange;
typedef void (APIENTRY * WXEGLBINDVERTEXARRAY)(GLuint);
@@ -1232,6 +1253,342 @@ typedef void (APIENTRY * WXEGLUNIFORMBLOCKBINDING)(GLuint,GLuint,GLuint);
WXE_EXTERN WXEGLUNIFORMBLOCKBINDING weglUniformBlockBinding;
typedef void (APIENTRY * WXEGLCOPYBUFFERSUBDATA)(GLenum,GLenum,GLintptr,GLintptr,GLsizeiptr);
WXE_EXTERN WXEGLCOPYBUFFERSUBDATA weglCopyBufferSubData;
+typedef void (APIENTRY * WXEGLDRAWELEMENTSBASEVERTEX)(GLenum,GLsizei,GLenum,const GLvoid *,GLint);
+WXE_EXTERN WXEGLDRAWELEMENTSBASEVERTEX weglDrawElementsBaseVertex;
+typedef void (APIENTRY * WXEGLDRAWRANGEELEMENTSBASEVERTEX)(GLenum,GLuint,GLuint,GLsizei,GLenum,const GLvoid *,GLint);
+WXE_EXTERN WXEGLDRAWRANGEELEMENTSBASEVERTEX weglDrawRangeElementsBaseVertex;
+typedef void (APIENTRY * WXEGLDRAWELEMENTSINSTANCEDBASEVERTEX)(GLenum,GLsizei,GLenum,const GLvoid *,GLsizei,GLint);
+WXE_EXTERN WXEGLDRAWELEMENTSINSTANCEDBASEVERTEX weglDrawElementsInstancedBaseVertex;
+typedef void (APIENTRY * WXEGLPROVOKINGVERTEX)(GLenum);
+WXE_EXTERN WXEGLPROVOKINGVERTEX weglProvokingVertex;
+typedef GLsync (APIENTRY * WXEGLFENCESYNC)(GLenum,GLbitfield);
+WXE_EXTERN WXEGLFENCESYNC weglFenceSync;
+typedef GLboolean (APIENTRY * WXEGLISSYNC)(GLsync);
+WXE_EXTERN WXEGLISSYNC weglIsSync;
+typedef void (APIENTRY * WXEGLDELETESYNC)(GLsync);
+WXE_EXTERN WXEGLDELETESYNC weglDeleteSync;
+typedef GLenum (APIENTRY * WXEGLCLIENTWAITSYNC)(GLsync,GLbitfield,GLuint64);
+WXE_EXTERN WXEGLCLIENTWAITSYNC weglClientWaitSync;
+typedef void (APIENTRY * WXEGLWAITSYNC)(GLsync,GLbitfield,GLuint64);
+WXE_EXTERN WXEGLWAITSYNC weglWaitSync;
+typedef void (APIENTRY * WXEGLGETINTEGER64V)(GLenum,GLint64 *);
+WXE_EXTERN WXEGLGETINTEGER64V weglGetInteger64v;
+typedef void (APIENTRY * WXEGLGETSYNCIV)(GLsync,GLenum,GLsizei,GLsizei *,GLint *);
+WXE_EXTERN WXEGLGETSYNCIV weglGetSynciv;
+typedef void (APIENTRY * WXEGLTEXIMAGE2DMULTISAMPLE)(GLenum,GLsizei,GLint,GLsizei,GLsizei,GLboolean);
+WXE_EXTERN WXEGLTEXIMAGE2DMULTISAMPLE weglTexImage2DMultisample;
+typedef void (APIENTRY * WXEGLTEXIMAGE3DMULTISAMPLE)(GLenum,GLsizei,GLint,GLsizei,GLsizei,GLsizei,GLboolean);
+WXE_EXTERN WXEGLTEXIMAGE3DMULTISAMPLE weglTexImage3DMultisample;
+typedef void (APIENTRY * WXEGLGETMULTISAMPLEFV)(GLenum,GLuint,GLfloat *);
+WXE_EXTERN WXEGLGETMULTISAMPLEFV weglGetMultisamplefv;
+typedef void (APIENTRY * WXEGLSAMPLEMASKI)(GLuint,GLbitfield);
+WXE_EXTERN WXEGLSAMPLEMASKI weglSampleMaski;
+typedef void (APIENTRY * WXEGLNAMEDSTRINGARB)(GLenum,GLint,const GLchar *,GLint,const GLchar *);
+WXE_EXTERN WXEGLNAMEDSTRINGARB weglNamedStringARB;
+typedef void (APIENTRY * WXEGLDELETENAMEDSTRINGARB)(GLint,const GLchar *);
+WXE_EXTERN WXEGLDELETENAMEDSTRINGARB weglDeleteNamedStringARB;
+typedef void (APIENTRY * WXEGLCOMPILESHADERINCLUDEARB)(GLuint,GLsizei,const GLchar **,const GLint *);
+WXE_EXTERN WXEGLCOMPILESHADERINCLUDEARB weglCompileShaderIncludeARB;
+typedef GLboolean (APIENTRY * WXEGLISNAMEDSTRINGARB)(GLint,const GLchar *);
+WXE_EXTERN WXEGLISNAMEDSTRINGARB weglIsNamedStringARB;
+typedef void (APIENTRY * WXEGLGETNAMEDSTRINGARB)(GLint,const GLchar *,GLsizei,GLint *,GLchar *);
+WXE_EXTERN WXEGLGETNAMEDSTRINGARB weglGetNamedStringARB;
+typedef void (APIENTRY * WXEGLGETNAMEDSTRINGIVARB)(GLint,const GLchar *,GLenum,GLint *);
+WXE_EXTERN WXEGLGETNAMEDSTRINGIVARB weglGetNamedStringivARB;
+typedef void (APIENTRY * WXEGLBINDFRAGDATALOCATIONINDEXED)(GLuint,GLuint,GLuint,const GLchar *);
+WXE_EXTERN WXEGLBINDFRAGDATALOCATIONINDEXED weglBindFragDataLocationIndexed;
+typedef GLint (APIENTRY * WXEGLGETFRAGDATAINDEX)(GLuint,const GLchar *);
+WXE_EXTERN WXEGLGETFRAGDATAINDEX weglGetFragDataIndex;
+typedef void (APIENTRY * WXEGLGENSAMPLERS)(GLsizei,GLuint *);
+WXE_EXTERN WXEGLGENSAMPLERS weglGenSamplers;
+typedef void (APIENTRY * WXEGLDELETESAMPLERS)(GLsizei,const GLuint *);
+WXE_EXTERN WXEGLDELETESAMPLERS weglDeleteSamplers;
+typedef GLboolean (APIENTRY * WXEGLISSAMPLER)(GLuint);
+WXE_EXTERN WXEGLISSAMPLER weglIsSampler;
+typedef void (APIENTRY * WXEGLBINDSAMPLER)(GLuint,GLuint);
+WXE_EXTERN WXEGLBINDSAMPLER weglBindSampler;
+typedef void (APIENTRY * WXEGLSAMPLERPARAMETERI)(GLuint,GLenum,GLint);
+WXE_EXTERN WXEGLSAMPLERPARAMETERI weglSamplerParameteri;
+typedef void (APIENTRY * WXEGLSAMPLERPARAMETERIV)(GLuint,GLenum,const GLint *);
+WXE_EXTERN WXEGLSAMPLERPARAMETERIV weglSamplerParameteriv;
+typedef void (APIENTRY * WXEGLSAMPLERPARAMETERF)(GLuint,GLenum,GLfloat);
+WXE_EXTERN WXEGLSAMPLERPARAMETERF weglSamplerParameterf;
+typedef void (APIENTRY * WXEGLSAMPLERPARAMETERFV)(GLuint,GLenum,const GLfloat *);
+WXE_EXTERN WXEGLSAMPLERPARAMETERFV weglSamplerParameterfv;
+typedef void (APIENTRY * WXEGLSAMPLERPARAMETERIIV)(GLuint,GLenum,const GLint *);
+WXE_EXTERN WXEGLSAMPLERPARAMETERIIV weglSamplerParameterIiv;
+typedef void (APIENTRY * WXEGLSAMPLERPARAMETERIUIV)(GLuint,GLenum,const GLuint *);
+WXE_EXTERN WXEGLSAMPLERPARAMETERIUIV weglSamplerParameterIuiv;
+typedef void (APIENTRY * WXEGLGETSAMPLERPARAMETERIV)(GLuint,GLenum,GLint *);
+WXE_EXTERN WXEGLGETSAMPLERPARAMETERIV weglGetSamplerParameteriv;
+typedef void (APIENTRY * WXEGLGETSAMPLERPARAMETERIIV)(GLuint,GLenum,GLint *);
+WXE_EXTERN WXEGLGETSAMPLERPARAMETERIIV weglGetSamplerParameterIiv;
+typedef void (APIENTRY * WXEGLGETSAMPLERPARAMETERFV)(GLuint,GLenum,GLfloat *);
+WXE_EXTERN WXEGLGETSAMPLERPARAMETERFV weglGetSamplerParameterfv;
+typedef void (APIENTRY * WXEGLGETSAMPLERPARAMETERIUIV)(GLuint,GLenum,GLuint *);
+WXE_EXTERN WXEGLGETSAMPLERPARAMETERIUIV weglGetSamplerParameterIuiv;
+typedef void (APIENTRY * WXEGLQUERYCOUNTER)(GLuint,GLenum);
+WXE_EXTERN WXEGLQUERYCOUNTER weglQueryCounter;
+typedef void (APIENTRY * WXEGLGETQUERYOBJECTI64V)(GLuint,GLenum,GLint64 *);
+WXE_EXTERN WXEGLGETQUERYOBJECTI64V weglGetQueryObjecti64v;
+typedef void (APIENTRY * WXEGLGETQUERYOBJECTUI64V)(GLuint,GLenum,GLuint64 *);
+WXE_EXTERN WXEGLGETQUERYOBJECTUI64V weglGetQueryObjectui64v;
+typedef void (APIENTRY * WXEGLDRAWARRAYSINDIRECT)(GLenum,const GLvoid *);
+WXE_EXTERN WXEGLDRAWARRAYSINDIRECT weglDrawArraysIndirect;
+typedef void (APIENTRY * WXEGLDRAWELEMENTSINDIRECT)(GLenum,GLenum,const GLvoid *);
+WXE_EXTERN WXEGLDRAWELEMENTSINDIRECT weglDrawElementsIndirect;
+typedef void (APIENTRY * WXEGLUNIFORM1D)(GLint,GLdouble);
+WXE_EXTERN WXEGLUNIFORM1D weglUniform1d;
+typedef void (APIENTRY * WXEGLUNIFORM2D)(GLint,GLdouble,GLdouble);
+WXE_EXTERN WXEGLUNIFORM2D weglUniform2d;
+typedef void (APIENTRY * WXEGLUNIFORM3D)(GLint,GLdouble,GLdouble,GLdouble);
+WXE_EXTERN WXEGLUNIFORM3D weglUniform3d;
+typedef void (APIENTRY * WXEGLUNIFORM4D)(GLint,GLdouble,GLdouble,GLdouble,GLdouble);
+WXE_EXTERN WXEGLUNIFORM4D weglUniform4d;
+typedef void (APIENTRY * WXEGLUNIFORM1DV)(GLint,GLsizei,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORM1DV weglUniform1dv;
+typedef void (APIENTRY * WXEGLUNIFORM2DV)(GLint,GLsizei,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORM2DV weglUniform2dv;
+typedef void (APIENTRY * WXEGLUNIFORM3DV)(GLint,GLsizei,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORM3DV weglUniform3dv;
+typedef void (APIENTRY * WXEGLUNIFORM4DV)(GLint,GLsizei,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORM4DV weglUniform4dv;
+typedef void (APIENTRY * WXEGLUNIFORMMATRIX2DV)(GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORMMATRIX2DV weglUniformMatrix2dv;
+typedef void (APIENTRY * WXEGLUNIFORMMATRIX3DV)(GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORMMATRIX3DV weglUniformMatrix3dv;
+typedef void (APIENTRY * WXEGLUNIFORMMATRIX4DV)(GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORMMATRIX4DV weglUniformMatrix4dv;
+typedef void (APIENTRY * WXEGLUNIFORMMATRIX2X3DV)(GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORMMATRIX2X3DV weglUniformMatrix2x3dv;
+typedef void (APIENTRY * WXEGLUNIFORMMATRIX2X4DV)(GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORMMATRIX2X4DV weglUniformMatrix2x4dv;
+typedef void (APIENTRY * WXEGLUNIFORMMATRIX3X2DV)(GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORMMATRIX3X2DV weglUniformMatrix3x2dv;
+typedef void (APIENTRY * WXEGLUNIFORMMATRIX3X4DV)(GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORMMATRIX3X4DV weglUniformMatrix3x4dv;
+typedef void (APIENTRY * WXEGLUNIFORMMATRIX4X2DV)(GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORMMATRIX4X2DV weglUniformMatrix4x2dv;
+typedef void (APIENTRY * WXEGLUNIFORMMATRIX4X3DV)(GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLUNIFORMMATRIX4X3DV weglUniformMatrix4x3dv;
+typedef void (APIENTRY * WXEGLGETUNIFORMDV)(GLuint,GLint,GLdouble *);
+WXE_EXTERN WXEGLGETUNIFORMDV weglGetUniformdv;
+typedef GLint (APIENTRY * WXEGLGETSUBROUTINEUNIFORMLOCATION)(GLuint,GLenum,const GLchar *);
+WXE_EXTERN WXEGLGETSUBROUTINEUNIFORMLOCATION weglGetSubroutineUniformLocation;
+typedef GLuint (APIENTRY * WXEGLGETSUBROUTINEINDEX)(GLuint,GLenum,const GLchar *);
+WXE_EXTERN WXEGLGETSUBROUTINEINDEX weglGetSubroutineIndex;
+typedef void (APIENTRY * WXEGLGETACTIVESUBROUTINEUNIFORMNAME)(GLuint,GLenum,GLuint,GLsizei,GLsizei *,GLchar *);
+WXE_EXTERN WXEGLGETACTIVESUBROUTINEUNIFORMNAME weglGetActiveSubroutineUniformName;
+typedef void (APIENTRY * WXEGLGETACTIVESUBROUTINENAME)(GLuint,GLenum,GLuint,GLsizei,GLsizei *,GLchar *);
+WXE_EXTERN WXEGLGETACTIVESUBROUTINENAME weglGetActiveSubroutineName;
+typedef void (APIENTRY * WXEGLUNIFORMSUBROUTINESUIV)(GLenum,GLsizei,const GLuint *);
+WXE_EXTERN WXEGLUNIFORMSUBROUTINESUIV weglUniformSubroutinesuiv;
+typedef void (APIENTRY * WXEGLGETUNIFORMSUBROUTINEUIV)(GLenum,GLint,GLuint *);
+WXE_EXTERN WXEGLGETUNIFORMSUBROUTINEUIV weglGetUniformSubroutineuiv;
+typedef void (APIENTRY * WXEGLGETPROGRAMSTAGEIV)(GLuint,GLenum,GLenum,GLint *);
+WXE_EXTERN WXEGLGETPROGRAMSTAGEIV weglGetProgramStageiv;
+typedef void (APIENTRY * WXEGLPATCHPARAMETERI)(GLenum,GLint);
+WXE_EXTERN WXEGLPATCHPARAMETERI weglPatchParameteri;
+typedef void (APIENTRY * WXEGLPATCHPARAMETERFV)(GLenum,const GLfloat *);
+WXE_EXTERN WXEGLPATCHPARAMETERFV weglPatchParameterfv;
+typedef void (APIENTRY * WXEGLBINDTRANSFORMFEEDBACK)(GLenum,GLuint);
+WXE_EXTERN WXEGLBINDTRANSFORMFEEDBACK weglBindTransformFeedback;
+typedef void (APIENTRY * WXEGLDELETETRANSFORMFEEDBACKS)(GLsizei,const GLuint *);
+WXE_EXTERN WXEGLDELETETRANSFORMFEEDBACKS weglDeleteTransformFeedbacks;
+typedef void (APIENTRY * WXEGLGENTRANSFORMFEEDBACKS)(GLsizei,GLuint *);
+WXE_EXTERN WXEGLGENTRANSFORMFEEDBACKS weglGenTransformFeedbacks;
+typedef GLboolean (APIENTRY * WXEGLISTRANSFORMFEEDBACK)(GLuint);
+WXE_EXTERN WXEGLISTRANSFORMFEEDBACK weglIsTransformFeedback;
+typedef void (APIENTRY * WXEGLPAUSETRANSFORMFEEDBACK)();
+WXE_EXTERN WXEGLPAUSETRANSFORMFEEDBACK weglPauseTransformFeedback;
+typedef void (APIENTRY * WXEGLRESUMETRANSFORMFEEDBACK)();
+WXE_EXTERN WXEGLRESUMETRANSFORMFEEDBACK weglResumeTransformFeedback;
+typedef void (APIENTRY * WXEGLDRAWTRANSFORMFEEDBACK)(GLenum,GLuint);
+WXE_EXTERN WXEGLDRAWTRANSFORMFEEDBACK weglDrawTransformFeedback;
+typedef void (APIENTRY * WXEGLDRAWTRANSFORMFEEDBACKSTREAM)(GLenum,GLuint,GLuint);
+WXE_EXTERN WXEGLDRAWTRANSFORMFEEDBACKSTREAM weglDrawTransformFeedbackStream;
+typedef void (APIENTRY * WXEGLBEGINQUERYINDEXED)(GLenum,GLuint,GLuint);
+WXE_EXTERN WXEGLBEGINQUERYINDEXED weglBeginQueryIndexed;
+typedef void (APIENTRY * WXEGLENDQUERYINDEXED)(GLenum,GLuint);
+WXE_EXTERN WXEGLENDQUERYINDEXED weglEndQueryIndexed;
+typedef void (APIENTRY * WXEGLGETQUERYINDEXEDIV)(GLenum,GLuint,GLenum,GLint *);
+WXE_EXTERN WXEGLGETQUERYINDEXEDIV weglGetQueryIndexediv;
+typedef void (APIENTRY * WXEGLRELEASESHADERCOMPILER)();
+WXE_EXTERN WXEGLRELEASESHADERCOMPILER weglReleaseShaderCompiler;
+typedef void (APIENTRY * WXEGLSHADERBINARY)(GLsizei,const GLuint *,GLenum,const GLvoid *,GLsizei);
+WXE_EXTERN WXEGLSHADERBINARY weglShaderBinary;
+typedef void (APIENTRY * WXEGLGETSHADERPRECISIONFORMAT)(GLenum,GLenum,GLint *,GLint *);
+WXE_EXTERN WXEGLGETSHADERPRECISIONFORMAT weglGetShaderPrecisionFormat;
+typedef void (APIENTRY * WXEGLDEPTHRANGEF)(GLclampf,GLclampf);
+WXE_EXTERN WXEGLDEPTHRANGEF weglDepthRangef;
+typedef void (APIENTRY * WXEGLCLEARDEPTHF)(GLclampf);
+WXE_EXTERN WXEGLCLEARDEPTHF weglClearDepthf;
+typedef void (APIENTRY * WXEGLGETPROGRAMBINARY)(GLuint,GLsizei,GLsizei *,GLenum *,GLvoid *);
+WXE_EXTERN WXEGLGETPROGRAMBINARY weglGetProgramBinary;
+typedef void (APIENTRY * WXEGLPROGRAMBINARY)(GLuint,GLenum,const GLvoid *,GLsizei);
+WXE_EXTERN WXEGLPROGRAMBINARY weglProgramBinary;
+typedef void (APIENTRY * WXEGLPROGRAMPARAMETERI)(GLuint,GLenum,GLint);
+WXE_EXTERN WXEGLPROGRAMPARAMETERI weglProgramParameteri;
+typedef void (APIENTRY * WXEGLUSEPROGRAMSTAGES)(GLuint,GLbitfield,GLuint);
+WXE_EXTERN WXEGLUSEPROGRAMSTAGES weglUseProgramStages;
+typedef void (APIENTRY * WXEGLACTIVESHADERPROGRAM)(GLuint,GLuint);
+WXE_EXTERN WXEGLACTIVESHADERPROGRAM weglActiveShaderProgram;
+typedef GLuint (APIENTRY * WXEGLCREATESHADERPROGRAMV)(GLenum,GLsizei,const GLchar **);
+WXE_EXTERN WXEGLCREATESHADERPROGRAMV weglCreateShaderProgramv;
+typedef void (APIENTRY * WXEGLBINDPROGRAMPIPELINE)(GLuint);
+WXE_EXTERN WXEGLBINDPROGRAMPIPELINE weglBindProgramPipeline;
+typedef void (APIENTRY * WXEGLDELETEPROGRAMPIPELINES)(GLsizei,const GLuint *);
+WXE_EXTERN WXEGLDELETEPROGRAMPIPELINES weglDeleteProgramPipelines;
+typedef void (APIENTRY * WXEGLGENPROGRAMPIPELINES)(GLsizei,GLuint *);
+WXE_EXTERN WXEGLGENPROGRAMPIPELINES weglGenProgramPipelines;
+typedef GLboolean (APIENTRY * WXEGLISPROGRAMPIPELINE)(GLuint);
+WXE_EXTERN WXEGLISPROGRAMPIPELINE weglIsProgramPipeline;
+typedef void (APIENTRY * WXEGLGETPROGRAMPIPELINEIV)(GLuint,GLenum,GLint *);
+WXE_EXTERN WXEGLGETPROGRAMPIPELINEIV weglGetProgramPipelineiv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1I)(GLuint,GLint,GLint);
+WXE_EXTERN WXEGLPROGRAMUNIFORM1I weglProgramUniform1i;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1IV)(GLuint,GLint,GLsizei,const GLint *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM1IV weglProgramUniform1iv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1F)(GLuint,GLint,GLfloat);
+WXE_EXTERN WXEGLPROGRAMUNIFORM1F weglProgramUniform1f;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1FV)(GLuint,GLint,GLsizei,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM1FV weglProgramUniform1fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1D)(GLuint,GLint,GLdouble);
+WXE_EXTERN WXEGLPROGRAMUNIFORM1D weglProgramUniform1d;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1DV)(GLuint,GLint,GLsizei,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM1DV weglProgramUniform1dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1UI)(GLuint,GLint,GLuint);
+WXE_EXTERN WXEGLPROGRAMUNIFORM1UI weglProgramUniform1ui;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1UIV)(GLuint,GLint,GLsizei,const GLuint *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM1UIV weglProgramUniform1uiv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2I)(GLuint,GLint,GLint,GLint);
+WXE_EXTERN WXEGLPROGRAMUNIFORM2I weglProgramUniform2i;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2IV)(GLuint,GLint,GLsizei,const GLint *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM2IV weglProgramUniform2iv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2F)(GLuint,GLint,GLfloat,GLfloat);
+WXE_EXTERN WXEGLPROGRAMUNIFORM2F weglProgramUniform2f;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2FV)(GLuint,GLint,GLsizei,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM2FV weglProgramUniform2fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2D)(GLuint,GLint,GLdouble,GLdouble);
+WXE_EXTERN WXEGLPROGRAMUNIFORM2D weglProgramUniform2d;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2DV)(GLuint,GLint,GLsizei,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM2DV weglProgramUniform2dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2UI)(GLuint,GLint,GLuint,GLuint);
+WXE_EXTERN WXEGLPROGRAMUNIFORM2UI weglProgramUniform2ui;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2UIV)(GLuint,GLint,GLsizei,const GLuint *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM2UIV weglProgramUniform2uiv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3I)(GLuint,GLint,GLint,GLint,GLint);
+WXE_EXTERN WXEGLPROGRAMUNIFORM3I weglProgramUniform3i;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3IV)(GLuint,GLint,GLsizei,const GLint *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM3IV weglProgramUniform3iv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3F)(GLuint,GLint,GLfloat,GLfloat,GLfloat);
+WXE_EXTERN WXEGLPROGRAMUNIFORM3F weglProgramUniform3f;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3FV)(GLuint,GLint,GLsizei,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM3FV weglProgramUniform3fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3D)(GLuint,GLint,GLdouble,GLdouble,GLdouble);
+WXE_EXTERN WXEGLPROGRAMUNIFORM3D weglProgramUniform3d;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3DV)(GLuint,GLint,GLsizei,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM3DV weglProgramUniform3dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3UI)(GLuint,GLint,GLuint,GLuint,GLuint);
+WXE_EXTERN WXEGLPROGRAMUNIFORM3UI weglProgramUniform3ui;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3UIV)(GLuint,GLint,GLsizei,const GLuint *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM3UIV weglProgramUniform3uiv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4I)(GLuint,GLint,GLint,GLint,GLint,GLint);
+WXE_EXTERN WXEGLPROGRAMUNIFORM4I weglProgramUniform4i;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4IV)(GLuint,GLint,GLsizei,const GLint *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM4IV weglProgramUniform4iv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4F)(GLuint,GLint,GLfloat,GLfloat,GLfloat,GLfloat);
+WXE_EXTERN WXEGLPROGRAMUNIFORM4F weglProgramUniform4f;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4FV)(GLuint,GLint,GLsizei,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM4FV weglProgramUniform4fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4D)(GLuint,GLint,GLdouble,GLdouble,GLdouble,GLdouble);
+WXE_EXTERN WXEGLPROGRAMUNIFORM4D weglProgramUniform4d;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4DV)(GLuint,GLint,GLsizei,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM4DV weglProgramUniform4dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4UI)(GLuint,GLint,GLuint,GLuint,GLuint,GLuint);
+WXE_EXTERN WXEGLPROGRAMUNIFORM4UI weglProgramUniform4ui;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4UIV)(GLuint,GLint,GLsizei,const GLuint *);
+WXE_EXTERN WXEGLPROGRAMUNIFORM4UIV weglProgramUniform4uiv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2FV weglProgramUniformMatrix2fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3FV weglProgramUniformMatrix3fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4FV weglProgramUniformMatrix4fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2DV weglProgramUniformMatrix2dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3DV weglProgramUniformMatrix3dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4DV weglProgramUniformMatrix4dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2X3FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2X3FV weglProgramUniformMatrix2x3fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3X2FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3X2FV weglProgramUniformMatrix3x2fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2X4FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2X4FV weglProgramUniformMatrix2x4fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4X2FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4X2FV weglProgramUniformMatrix4x2fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3X4FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3X4FV weglProgramUniformMatrix3x4fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4X3FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4X3FV weglProgramUniformMatrix4x3fv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2X3DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2X3DV weglProgramUniformMatrix2x3dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3X2DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3X2DV weglProgramUniformMatrix3x2dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2X4DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2X4DV weglProgramUniformMatrix2x4dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4X2DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4X2DV weglProgramUniformMatrix4x2dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3X4DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3X4DV weglProgramUniformMatrix3x4dv;
+typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4X3DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *);
+WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4X3DV weglProgramUniformMatrix4x3dv;
+typedef void (APIENTRY * WXEGLVALIDATEPROGRAMPIPELINE)(GLuint);
+WXE_EXTERN WXEGLVALIDATEPROGRAMPIPELINE weglValidateProgramPipeline;
+typedef void (APIENTRY * WXEGLGETPROGRAMPIPELINEINFOLOG)(GLuint,GLsizei,GLsizei *,GLchar *);
+WXE_EXTERN WXEGLGETPROGRAMPIPELINEINFOLOG weglGetProgramPipelineInfoLog;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBL1DV)(GLuint,const GLdouble *);
+WXE_EXTERN WXEGLVERTEXATTRIBL1DV weglVertexAttribL1dv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBL2DV)(GLuint,const GLdouble *);
+WXE_EXTERN WXEGLVERTEXATTRIBL2DV weglVertexAttribL2dv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBL3DV)(GLuint,const GLdouble *);
+WXE_EXTERN WXEGLVERTEXATTRIBL3DV weglVertexAttribL3dv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBL4DV)(GLuint,const GLdouble *);
+WXE_EXTERN WXEGLVERTEXATTRIBL4DV weglVertexAttribL4dv;
+typedef void (APIENTRY * WXEGLVERTEXATTRIBLPOINTER)(GLuint,GLint,GLenum,GLsizei,const GLvoid *);
+WXE_EXTERN WXEGLVERTEXATTRIBLPOINTER weglVertexAttribLPointer;
+typedef void (APIENTRY * WXEGLGETVERTEXATTRIBLDV)(GLuint,GLenum,GLdouble *);
+WXE_EXTERN WXEGLGETVERTEXATTRIBLDV weglGetVertexAttribLdv;
+typedef void (APIENTRY * WXEGLVIEWPORTARRAYV)(GLuint,GLsizei,const GLfloat *);
+WXE_EXTERN WXEGLVIEWPORTARRAYV weglViewportArrayv;
+typedef void (APIENTRY * WXEGLVIEWPORTINDEXEDF)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat);
+WXE_EXTERN WXEGLVIEWPORTINDEXEDF weglViewportIndexedf;
+typedef void (APIENTRY * WXEGLVIEWPORTINDEXEDFV)(GLuint,const GLfloat *);
+WXE_EXTERN WXEGLVIEWPORTINDEXEDFV weglViewportIndexedfv;
+typedef void (APIENTRY * WXEGLSCISSORARRAYV)(GLuint,GLsizei,const GLint *);
+WXE_EXTERN WXEGLSCISSORARRAYV weglScissorArrayv;
+typedef void (APIENTRY * WXEGLSCISSORINDEXED)(GLuint,GLint,GLint,GLsizei,GLsizei);
+WXE_EXTERN WXEGLSCISSORINDEXED weglScissorIndexed;
+typedef void (APIENTRY * WXEGLSCISSORINDEXEDV)(GLuint,const GLint *);
+WXE_EXTERN WXEGLSCISSORINDEXEDV weglScissorIndexedv;
+typedef void (APIENTRY * WXEGLDEPTHRANGEARRAYV)(GLuint,GLsizei,const GLclampd *);
+WXE_EXTERN WXEGLDEPTHRANGEARRAYV weglDepthRangeArrayv;
+typedef void (APIENTRY * WXEGLDEPTHRANGEINDEXED)(GLuint,GLclampd,GLclampd);
+WXE_EXTERN WXEGLDEPTHRANGEINDEXED weglDepthRangeIndexed;
+typedef void (APIENTRY * WXEGLGETFLOATI_V)(GLenum,GLuint,GLfloat *);
+WXE_EXTERN WXEGLGETFLOATI_V weglGetFloati_v;
+typedef void (APIENTRY * WXEGLGETDOUBLEI_V)(GLenum,GLuint,GLdouble *);
+WXE_EXTERN WXEGLGETDOUBLEI_V weglGetDoublei_v;
+typedef void (APIENTRY * WXEGLDEBUGMESSAGECONTROLARB)(GLenum,GLenum,GLenum,GLsizei,const GLuint *,GLboolean);
+WXE_EXTERN WXEGLDEBUGMESSAGECONTROLARB weglDebugMessageControlARB;
+typedef void (APIENTRY * WXEGLDEBUGMESSAGEINSERTARB)(GLenum,GLenum,GLuint,GLenum,GLsizei,const GLchar *);
+WXE_EXTERN WXEGLDEBUGMESSAGEINSERTARB weglDebugMessageInsertARB;
+typedef GLuint (APIENTRY * WXEGLGETDEBUGMESSAGELOGARB)(GLuint,GLsizei,GLenum *,GLenum *,GLuint *,GLenum *,GLsizei *,GLchar *);
+WXE_EXTERN WXEGLGETDEBUGMESSAGELOGARB weglGetDebugMessageLogARB;
+typedef GLenum (APIENTRY * WXEGLGETGRAPHICSRESETSTATUSARB)();
+WXE_EXTERN WXEGLGETGRAPHICSRESETSTATUSARB weglGetGraphicsResetStatusARB;
typedef void (APIENTRY * WXEGLRESIZEBUFFERSMESA)();
WXE_EXTERN WXEGLRESIZEBUFFERSMESA weglResizeBuffersMESA;
typedef void (APIENTRY * WXEGLWINDOWPOS4DVMESA)(const GLdouble *);
diff --git a/lib/wx/c_src/gen/gl_finit.h b/lib/wx/c_src/gen/gl_finit.h
index ef29f05c4d..583e36faf7 100644
--- a/lib/wx/c_src/gen/gl_finit.h
+++ b/lib/wx/c_src/gen/gl_finit.h
@@ -18,11 +18,7 @@
*/
/***** This file is generated do not edit ****/
-static struct {
- const char * name;
- const char * alt;
- void * func;
-} gl_fns[] =
+gl_fns_t gl_fns[] =
{
{"glAccum", NULL, &weglAccum},
{"glAlphaFunc", NULL, &weglAlphaFunc},
@@ -394,7 +390,7 @@ static struct {
{"glBufferData", "glBufferDataARB", &weglBufferData},
{"glBufferSubData", "glBufferSubDataARB", &weglBufferSubData},
{"glGetBufferSubData", "glGetBufferSubDataARB", &weglGetBufferSubData},
- {"glGetBufferParameteriv", "glGetBufferParameterivARB", &weglGetBufferParameteriv},
+ {"glGetBufferParameteriv", NULL, &weglGetBufferParameteriv},
{"glBlendEquationSeparate", "glBlendEquationSeparateEXT", &weglBlendEquationSeparate},
{"glDrawBuffers", "glDrawBuffersARB", &weglDrawBuffers},
{"glStencilOpSeparate", "glStencilOpSeparateATI", &weglStencilOpSeparate},
@@ -498,6 +494,18 @@ static struct {
{"glVertexAttribIPointer", NULL, &weglVertexAttribIPointer},
{"glGetVertexAttribIiv", NULL, &weglGetVertexAttribIiv},
{"glGetVertexAttribIuiv", NULL, &weglGetVertexAttribIuiv},
+ {"glVertexAttribI1iv", NULL, &weglVertexAttribI1iv},
+ {"glVertexAttribI2iv", NULL, &weglVertexAttribI2iv},
+ {"glVertexAttribI3iv", NULL, &weglVertexAttribI3iv},
+ {"glVertexAttribI4iv", NULL, &weglVertexAttribI4iv},
+ {"glVertexAttribI1uiv", NULL, &weglVertexAttribI1uiv},
+ {"glVertexAttribI2uiv", NULL, &weglVertexAttribI2uiv},
+ {"glVertexAttribI3uiv", NULL, &weglVertexAttribI3uiv},
+ {"glVertexAttribI4uiv", NULL, &weglVertexAttribI4uiv},
+ {"glVertexAttribI4bv", NULL, &weglVertexAttribI4bv},
+ {"glVertexAttribI4sv", NULL, &weglVertexAttribI4sv},
+ {"glVertexAttribI4ubv", NULL, &weglVertexAttribI4ubv},
+ {"glVertexAttribI4usv", NULL, &weglVertexAttribI4usv},
{"glGetUniformuiv", NULL, &weglGetUniformuiv},
{"glBindFragDataLocation", NULL, &weglBindFragDataLocation},
{"glGetFragDataLocation", NULL, &weglGetFragDataLocation},
@@ -518,22 +526,19 @@ static struct {
{"glClearBufferfv", NULL, &weglClearBufferfv},
{"glClearBufferfi", NULL, &weglClearBufferfi},
{"glGetStringi", NULL, &weglGetStringi},
- {"glVertexAttribI1iv", NULL, &weglVertexAttribI1iv},
- {"glVertexAttribI2iv", NULL, &weglVertexAttribI2iv},
- {"glVertexAttribI3iv", NULL, &weglVertexAttribI3iv},
- {"glVertexAttribI4iv", NULL, &weglVertexAttribI4iv},
- {"glVertexAttribI1uiv", NULL, &weglVertexAttribI1uiv},
- {"glVertexAttribI2uiv", NULL, &weglVertexAttribI2uiv},
- {"glVertexAttribI3uiv", NULL, &weglVertexAttribI3uiv},
- {"glVertexAttribI4uiv", NULL, &weglVertexAttribI4uiv},
- {"glVertexAttribI4bv", NULL, &weglVertexAttribI4bv},
- {"glVertexAttribI4sv", NULL, &weglVertexAttribI4sv},
- {"glVertexAttribI4ubv", NULL, &weglVertexAttribI4ubv},
- {"glVertexAttribI4usv", NULL, &weglVertexAttribI4usv},
{"glDrawArraysInstanced", "glDrawArraysInstancedARB", &weglDrawArraysInstanced},
{"glDrawElementsInstanced", "glDrawElementsInstancedARB", &weglDrawElementsInstanced},
{"glTexBuffer", "glTexBufferARB", &weglTexBuffer},
{"glPrimitiveRestartIndex", NULL, &weglPrimitiveRestartIndex},
+ {"glGetInteger64i_v", NULL, &weglGetInteger64i_v},
+ {"glGetBufferParameteri64v", NULL, &weglGetBufferParameteri64v},
+ {"glFramebufferTexture", "glFramebufferTextureARB", &weglFramebufferTexture},
+ {"glVertexAttribDivisor", "glVertexAttribDivisorARB", &weglVertexAttribDivisor},
+ {"glMinSampleShading", "glMinSampleShadingARB", &weglMinSampleShading},
+ {"glBlendEquationi", "glBlendEquationiARB", &weglBlendEquationi},
+ {"glBlendEquationSeparatei", "glBlendEquationSeparateiARB", &weglBlendEquationSeparatei},
+ {"glBlendFunci", "glBlendFunciARB", &weglBlendFunci},
+ {"glBlendFuncSeparatei", "glBlendFuncSeparateiARB", &weglBlendFuncSeparatei},
{"glLoadTransposeMatrixfARB", NULL, &weglLoadTransposeMatrixfARB},
{"glLoadTransposeMatrixdARB", NULL, &weglLoadTransposeMatrixdARB},
{"glMultTransposeMatrixfARB", NULL, &weglMultTransposeMatrixfARB},
@@ -568,6 +573,7 @@ static struct {
{"glGetProgramLocalParameterdvARB", NULL, &weglGetProgramLocalParameterdvARB},
{"glGetProgramLocalParameterfvARB", NULL, &weglGetProgramLocalParameterfvARB},
{"glGetProgramStringARB", NULL, &weglGetProgramStringARB},
+ {"glGetBufferParameterivARB", NULL, &weglGetBufferParameterivARB},
{"glDeleteObjectARB", NULL, &weglDeleteObjectARB},
{"glGetHandleARB", NULL, &weglGetHandleARB},
{"glDetachObjectARB", NULL, &weglDetachObjectARB},
@@ -611,10 +617,7 @@ static struct {
{"glBlitFramebuffer", "glBlitFramebufferEXT", &weglBlitFramebuffer},
{"glRenderbufferStorageMultisample", "glRenderbufferStorageMultisampleEXT", &weglRenderbufferStorageMultisample},
{"glFramebufferTextureLayer", "glFramebufferTextureLayerARB", &weglFramebufferTextureLayer},
- {"glProgramParameteriARB", NULL, &weglProgramParameteriARB},
- {"glFramebufferTextureARB", NULL, &weglFramebufferTextureARB},
{"glFramebufferTextureFaceARB", NULL, &weglFramebufferTextureFaceARB},
- {"glVertexAttribDivisorARB", NULL, &weglVertexAttribDivisorARB},
{"glFlushMappedBufferRange", NULL, &weglFlushMappedBufferRange},
{"glBindVertexArray", NULL, &weglBindVertexArray},
{"glDeleteVertexArrays", NULL, &weglDeleteVertexArrays},
@@ -628,6 +631,174 @@ static struct {
{"glGetActiveUniformBlockName", NULL, &weglGetActiveUniformBlockName},
{"glUniformBlockBinding", NULL, &weglUniformBlockBinding},
{"glCopyBufferSubData", NULL, &weglCopyBufferSubData},
+ {"glDrawElementsBaseVertex", NULL, &weglDrawElementsBaseVertex},
+ {"glDrawRangeElementsBaseVertex", NULL, &weglDrawRangeElementsBaseVertex},
+ {"glDrawElementsInstancedBaseVertex", NULL, &weglDrawElementsInstancedBaseVertex},
+ {"glProvokingVertex", NULL, &weglProvokingVertex},
+ {"glFenceSync", NULL, &weglFenceSync},
+ {"glIsSync", NULL, &weglIsSync},
+ {"glDeleteSync", NULL, &weglDeleteSync},
+ {"glClientWaitSync", NULL, &weglClientWaitSync},
+ {"glWaitSync", NULL, &weglWaitSync},
+ {"glGetInteger64v", NULL, &weglGetInteger64v},
+ {"glGetSynciv", NULL, &weglGetSynciv},
+ {"glTexImage2DMultisample", NULL, &weglTexImage2DMultisample},
+ {"glTexImage3DMultisample", NULL, &weglTexImage3DMultisample},
+ {"glGetMultisamplefv", NULL, &weglGetMultisamplefv},
+ {"glSampleMaski", NULL, &weglSampleMaski},
+ {"glNamedStringARB", NULL, &weglNamedStringARB},
+ {"glDeleteNamedStringARB", NULL, &weglDeleteNamedStringARB},
+ {"glCompileShaderIncludeARB", NULL, &weglCompileShaderIncludeARB},
+ {"glIsNamedStringARB", NULL, &weglIsNamedStringARB},
+ {"glGetNamedStringARB", NULL, &weglGetNamedStringARB},
+ {"glGetNamedStringivARB", NULL, &weglGetNamedStringivARB},
+ {"glBindFragDataLocationIndexed", NULL, &weglBindFragDataLocationIndexed},
+ {"glGetFragDataIndex", NULL, &weglGetFragDataIndex},
+ {"glGenSamplers", NULL, &weglGenSamplers},
+ {"glDeleteSamplers", NULL, &weglDeleteSamplers},
+ {"glIsSampler", NULL, &weglIsSampler},
+ {"glBindSampler", NULL, &weglBindSampler},
+ {"glSamplerParameteri", NULL, &weglSamplerParameteri},
+ {"glSamplerParameteriv", NULL, &weglSamplerParameteriv},
+ {"glSamplerParameterf", NULL, &weglSamplerParameterf},
+ {"glSamplerParameterfv", NULL, &weglSamplerParameterfv},
+ {"glSamplerParameterIiv", NULL, &weglSamplerParameterIiv},
+ {"glSamplerParameterIuiv", NULL, &weglSamplerParameterIuiv},
+ {"glGetSamplerParameteriv", NULL, &weglGetSamplerParameteriv},
+ {"glGetSamplerParameterIiv", NULL, &weglGetSamplerParameterIiv},
+ {"glGetSamplerParameterfv", NULL, &weglGetSamplerParameterfv},
+ {"glGetSamplerParameterIuiv", NULL, &weglGetSamplerParameterIuiv},
+ {"glQueryCounter", NULL, &weglQueryCounter},
+ {"glGetQueryObjecti64v", NULL, &weglGetQueryObjecti64v},
+ {"glGetQueryObjectui64v", NULL, &weglGetQueryObjectui64v},
+ {"glDrawArraysIndirect", NULL, &weglDrawArraysIndirect},
+ {"glDrawElementsIndirect", NULL, &weglDrawElementsIndirect},
+ {"glUniform1d", NULL, &weglUniform1d},
+ {"glUniform2d", NULL, &weglUniform2d},
+ {"glUniform3d", NULL, &weglUniform3d},
+ {"glUniform4d", NULL, &weglUniform4d},
+ {"glUniform1dv", NULL, &weglUniform1dv},
+ {"glUniform2dv", NULL, &weglUniform2dv},
+ {"glUniform3dv", NULL, &weglUniform3dv},
+ {"glUniform4dv", NULL, &weglUniform4dv},
+ {"glUniformMatrix2dv", NULL, &weglUniformMatrix2dv},
+ {"glUniformMatrix3dv", NULL, &weglUniformMatrix3dv},
+ {"glUniformMatrix4dv", NULL, &weglUniformMatrix4dv},
+ {"glUniformMatrix2x3dv", NULL, &weglUniformMatrix2x3dv},
+ {"glUniformMatrix2x4dv", NULL, &weglUniformMatrix2x4dv},
+ {"glUniformMatrix3x2dv", NULL, &weglUniformMatrix3x2dv},
+ {"glUniformMatrix3x4dv", NULL, &weglUniformMatrix3x4dv},
+ {"glUniformMatrix4x2dv", NULL, &weglUniformMatrix4x2dv},
+ {"glUniformMatrix4x3dv", NULL, &weglUniformMatrix4x3dv},
+ {"glGetUniformdv", NULL, &weglGetUniformdv},
+ {"glGetSubroutineUniformLocation", NULL, &weglGetSubroutineUniformLocation},
+ {"glGetSubroutineIndex", NULL, &weglGetSubroutineIndex},
+ {"glGetActiveSubroutineUniformName", NULL, &weglGetActiveSubroutineUniformName},
+ {"glGetActiveSubroutineName", NULL, &weglGetActiveSubroutineName},
+ {"glUniformSubroutinesuiv", NULL, &weglUniformSubroutinesuiv},
+ {"glGetUniformSubroutineuiv", NULL, &weglGetUniformSubroutineuiv},
+ {"glGetProgramStageiv", NULL, &weglGetProgramStageiv},
+ {"glPatchParameteri", NULL, &weglPatchParameteri},
+ {"glPatchParameterfv", NULL, &weglPatchParameterfv},
+ {"glBindTransformFeedback", NULL, &weglBindTransformFeedback},
+ {"glDeleteTransformFeedbacks", NULL, &weglDeleteTransformFeedbacks},
+ {"glGenTransformFeedbacks", NULL, &weglGenTransformFeedbacks},
+ {"glIsTransformFeedback", NULL, &weglIsTransformFeedback},
+ {"glPauseTransformFeedback", NULL, &weglPauseTransformFeedback},
+ {"glResumeTransformFeedback", NULL, &weglResumeTransformFeedback},
+ {"glDrawTransformFeedback", NULL, &weglDrawTransformFeedback},
+ {"glDrawTransformFeedbackStream", NULL, &weglDrawTransformFeedbackStream},
+ {"glBeginQueryIndexed", NULL, &weglBeginQueryIndexed},
+ {"glEndQueryIndexed", NULL, &weglEndQueryIndexed},
+ {"glGetQueryIndexediv", NULL, &weglGetQueryIndexediv},
+ {"glReleaseShaderCompiler", NULL, &weglReleaseShaderCompiler},
+ {"glShaderBinary", NULL, &weglShaderBinary},
+ {"glGetShaderPrecisionFormat", NULL, &weglGetShaderPrecisionFormat},
+ {"glDepthRangef", NULL, &weglDepthRangef},
+ {"glClearDepthf", NULL, &weglClearDepthf},
+ {"glGetProgramBinary", NULL, &weglGetProgramBinary},
+ {"glProgramBinary", NULL, &weglProgramBinary},
+ {"glProgramParameteri", "glProgramParameteriARB", &weglProgramParameteri},
+ {"glUseProgramStages", NULL, &weglUseProgramStages},
+ {"glActiveShaderProgram", NULL, &weglActiveShaderProgram},
+ {"glCreateShaderProgramv", NULL, &weglCreateShaderProgramv},
+ {"glBindProgramPipeline", NULL, &weglBindProgramPipeline},
+ {"glDeleteProgramPipelines", NULL, &weglDeleteProgramPipelines},
+ {"glGenProgramPipelines", NULL, &weglGenProgramPipelines},
+ {"glIsProgramPipeline", NULL, &weglIsProgramPipeline},
+ {"glGetProgramPipelineiv", NULL, &weglGetProgramPipelineiv},
+ {"glProgramUniform1i", NULL, &weglProgramUniform1i},
+ {"glProgramUniform1iv", NULL, &weglProgramUniform1iv},
+ {"glProgramUniform1f", NULL, &weglProgramUniform1f},
+ {"glProgramUniform1fv", NULL, &weglProgramUniform1fv},
+ {"glProgramUniform1d", NULL, &weglProgramUniform1d},
+ {"glProgramUniform1dv", NULL, &weglProgramUniform1dv},
+ {"glProgramUniform1ui", NULL, &weglProgramUniform1ui},
+ {"glProgramUniform1uiv", NULL, &weglProgramUniform1uiv},
+ {"glProgramUniform2i", NULL, &weglProgramUniform2i},
+ {"glProgramUniform2iv", NULL, &weglProgramUniform2iv},
+ {"glProgramUniform2f", NULL, &weglProgramUniform2f},
+ {"glProgramUniform2fv", NULL, &weglProgramUniform2fv},
+ {"glProgramUniform2d", NULL, &weglProgramUniform2d},
+ {"glProgramUniform2dv", NULL, &weglProgramUniform2dv},
+ {"glProgramUniform2ui", NULL, &weglProgramUniform2ui},
+ {"glProgramUniform2uiv", NULL, &weglProgramUniform2uiv},
+ {"glProgramUniform3i", NULL, &weglProgramUniform3i},
+ {"glProgramUniform3iv", NULL, &weglProgramUniform3iv},
+ {"glProgramUniform3f", NULL, &weglProgramUniform3f},
+ {"glProgramUniform3fv", NULL, &weglProgramUniform3fv},
+ {"glProgramUniform3d", NULL, &weglProgramUniform3d},
+ {"glProgramUniform3dv", NULL, &weglProgramUniform3dv},
+ {"glProgramUniform3ui", NULL, &weglProgramUniform3ui},
+ {"glProgramUniform3uiv", NULL, &weglProgramUniform3uiv},
+ {"glProgramUniform4i", NULL, &weglProgramUniform4i},
+ {"glProgramUniform4iv", NULL, &weglProgramUniform4iv},
+ {"glProgramUniform4f", NULL, &weglProgramUniform4f},
+ {"glProgramUniform4fv", NULL, &weglProgramUniform4fv},
+ {"glProgramUniform4d", NULL, &weglProgramUniform4d},
+ {"glProgramUniform4dv", NULL, &weglProgramUniform4dv},
+ {"glProgramUniform4ui", NULL, &weglProgramUniform4ui},
+ {"glProgramUniform4uiv", NULL, &weglProgramUniform4uiv},
+ {"glProgramUniformMatrix2fv", NULL, &weglProgramUniformMatrix2fv},
+ {"glProgramUniformMatrix3fv", NULL, &weglProgramUniformMatrix3fv},
+ {"glProgramUniformMatrix4fv", NULL, &weglProgramUniformMatrix4fv},
+ {"glProgramUniformMatrix2dv", NULL, &weglProgramUniformMatrix2dv},
+ {"glProgramUniformMatrix3dv", NULL, &weglProgramUniformMatrix3dv},
+ {"glProgramUniformMatrix4dv", NULL, &weglProgramUniformMatrix4dv},
+ {"glProgramUniformMatrix2x3fv", NULL, &weglProgramUniformMatrix2x3fv},
+ {"glProgramUniformMatrix3x2fv", NULL, &weglProgramUniformMatrix3x2fv},
+ {"glProgramUniformMatrix2x4fv", NULL, &weglProgramUniformMatrix2x4fv},
+ {"glProgramUniformMatrix4x2fv", NULL, &weglProgramUniformMatrix4x2fv},
+ {"glProgramUniformMatrix3x4fv", NULL, &weglProgramUniformMatrix3x4fv},
+ {"glProgramUniformMatrix4x3fv", NULL, &weglProgramUniformMatrix4x3fv},
+ {"glProgramUniformMatrix2x3dv", NULL, &weglProgramUniformMatrix2x3dv},
+ {"glProgramUniformMatrix3x2dv", NULL, &weglProgramUniformMatrix3x2dv},
+ {"glProgramUniformMatrix2x4dv", NULL, &weglProgramUniformMatrix2x4dv},
+ {"glProgramUniformMatrix4x2dv", NULL, &weglProgramUniformMatrix4x2dv},
+ {"glProgramUniformMatrix3x4dv", NULL, &weglProgramUniformMatrix3x4dv},
+ {"glProgramUniformMatrix4x3dv", NULL, &weglProgramUniformMatrix4x3dv},
+ {"glValidateProgramPipeline", NULL, &weglValidateProgramPipeline},
+ {"glGetProgramPipelineInfoLog", NULL, &weglGetProgramPipelineInfoLog},
+ {"glVertexAttribL1dv", NULL, &weglVertexAttribL1dv},
+ {"glVertexAttribL2dv", NULL, &weglVertexAttribL2dv},
+ {"glVertexAttribL3dv", NULL, &weglVertexAttribL3dv},
+ {"glVertexAttribL4dv", NULL, &weglVertexAttribL4dv},
+ {"glVertexAttribLPointer", NULL, &weglVertexAttribLPointer},
+ {"glGetVertexAttribLdv", NULL, &weglGetVertexAttribLdv},
+ {"glViewportArrayv", NULL, &weglViewportArrayv},
+ {"glViewportIndexedf", NULL, &weglViewportIndexedf},
+ {"glViewportIndexedfv", NULL, &weglViewportIndexedfv},
+ {"glScissorArrayv", NULL, &weglScissorArrayv},
+ {"glScissorIndexed", NULL, &weglScissorIndexed},
+ {"glScissorIndexedv", NULL, &weglScissorIndexedv},
+ {"glDepthRangeArrayv", NULL, &weglDepthRangeArrayv},
+ {"glDepthRangeIndexed", NULL, &weglDepthRangeIndexed},
+ {"glGetFloati_v", NULL, &weglGetFloati_v},
+ {"glGetDoublei_v", NULL, &weglGetDoublei_v},
+ {"glDebugMessageControlARB", NULL, &weglDebugMessageControlARB},
+ {"glDebugMessageInsertARB", NULL, &weglDebugMessageInsertARB},
+ {"glGetDebugMessageLogARB", NULL, &weglGetDebugMessageLogARB},
+ {"glGetGraphicsResetStatusARB", NULL, &weglGetGraphicsResetStatusARB},
{"glResizeBuffersMESA", NULL, &weglResizeBuffersMESA},
{"glWindowPos4dvMESA", NULL, &weglWindowPos4dvMESA},
{"glWindowPos4fvMESA", NULL, &weglWindowPos4fvMESA},
diff --git a/lib/wx/c_src/gen/gl_funcs.cpp b/lib/wx/c_src/gen/gl_funcs.cpp
index 95d3c23b23..30542a0f02 100644
--- a/lib/wx/c_src/gen/gl_funcs.cpp
+++ b/lib/wx/c_src/gen/gl_funcs.cpp
@@ -20,37 +20,17 @@
#include <stdio.h>
#include <string.h>
-#include "../wxe_impl.h"
-#include "../wxe_gl.h"
+#include "../egl_impl.h"
#include "gl_fdefs.h"
-int gl_error_op;
-void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){
- gl_error_op = op;
- if(caller != gl_active) {
- wxGLCanvas * current = glc[caller];
- if(current) { gl_active = caller; current->SetCurrent();}
- else {
- ErlDrvTermData rt[] = // Error msg
- {ERL_DRV_ATOM, driver_mk_atom((char *) "_wxe_error_"),
- ERL_DRV_INT, op,
- ERL_DRV_ATOM, driver_mk_atom((char *) "no_gl_context"),
- ERL_DRV_TUPLE,3};
- driver_send_term(WXE_DRV_PORT,caller,rt,8);
- return ;
- }
- };
+extern gl_fns_t gl_fns[];
+void egl_dispatch(int op, char *bp, ErlDrvPort port, ErlDrvTermData caller, char *bins[], int bins_sz[]){
+ try {
switch(op)
{
case 5000:
- wxe_tess_impl(bp, caller);
- break;
- case WXE_BIN_INCR:
- driver_binary_inc_refc(bins[0]->bin);
- break;
- case WXE_BIN_DECR:
- driver_binary_dec_refc(bins[0]->bin);
+ erl_tess_impl(bp, port, caller);
break;
case 5010: { // gluBuild1DMipmapLevels
GLenum *target = (GLenum *) bp; bp += 4;
@@ -61,14 +41,13 @@ case 5010: { // gluBuild1DMipmapLevels
GLint *level = (GLint *) bp; bp += 4;
GLint *base = (GLint *) bp; bp += 4;
GLint *max = (GLint *) bp; bp += 4;
- void *data = (void *) bins[0]->base;
+ void *data = (void *) bins[0];
GLint result = wegluBuild1DMipmapLevels(*target,*internalFormat,*width,*format,*type,*level,*base,*max,data);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5011: { // gluBuild1DMipmaps
GLenum *target = (GLenum *) bp; bp += 4;
@@ -76,14 +55,13 @@ case 5011: { // gluBuild1DMipmaps
GLsizei *width = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- void *data = (void *) bins[0]->base;
+ void *data = (void *) bins[0];
GLint result = wegluBuild1DMipmaps(*target,*internalFormat,*width,*format,*type,data);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5012: { // gluBuild2DMipmapLevels
GLenum *target = (GLenum *) bp; bp += 4;
@@ -95,14 +73,13 @@ case 5012: { // gluBuild2DMipmapLevels
GLint *level = (GLint *) bp; bp += 4;
GLint *base = (GLint *) bp; bp += 4;
GLint *max = (GLint *) bp; bp += 4;
- void *data = (void *) bins[0]->base;
+ void *data = (void *) bins[0];
GLint result = wegluBuild2DMipmapLevels(*target,*internalFormat,*width,*height,*format,*type,*level,*base,*max,data);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5013: { // gluBuild2DMipmaps
GLenum *target = (GLenum *) bp; bp += 4;
@@ -111,14 +88,13 @@ case 5013: { // gluBuild2DMipmaps
GLsizei *height = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- void *data = (void *) bins[0]->base;
+ void *data = (void *) bins[0];
GLint result = wegluBuild2DMipmaps(*target,*internalFormat,*width,*height,*format,*type,data);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5014: { // gluBuild3DMipmapLevels
GLenum *target = (GLenum *) bp; bp += 4;
@@ -131,14 +107,13 @@ case 5014: { // gluBuild3DMipmapLevels
GLint *level = (GLint *) bp; bp += 4;
GLint *base = (GLint *) bp; bp += 4;
GLint *max = (GLint *) bp; bp += 4;
- void *data = (void *) bins[0]->base;
+ void *data = (void *) bins[0];
GLint result = wegluBuild3DMipmapLevels(*target,*internalFormat,*width,*height,*depth,*format,*type,*level,*base,*max,data);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5015: { // gluBuild3DMipmaps
GLenum *target = (GLenum *) bp; bp += 4;
@@ -148,27 +123,25 @@ case 5015: { // gluBuild3DMipmaps
GLsizei *depth = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- void *data = (void *) bins[0]->base;
+ void *data = (void *) bins[0];
GLint result = wegluBuild3DMipmaps(*target,*internalFormat,*width,*height,*depth,*format,*type,data);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5016: { // gluCheckExtension
- int * extNameLen = (int *) bp; bp += 4;
- GLubyte * extName = (GLubyte *) bp; bp += (8-((*extNameLen*1+4)%8))%8;
- int * extStringLen = (int *) bp; bp += 4;
- GLubyte * extString = (GLubyte *) bp; bp += (8-((*extStringLen*1+4)%8))%8;
+ GLubyte *extName = (GLubyte *) bp;
+ int extNameLen[1] = {strlen((char *)extName)}; bp += extNameLen[0]+1+((8-((1+extNameLen[0]+0)%8))%8);
+ GLubyte *extString = (GLubyte *) bp;
+ int extStringLen[1] = {strlen((char *)extString)}; bp += extStringLen[0]+1+((8-((1+extStringLen[0]+0)%8))%8);
GLboolean result = wegluCheckExtension(extName,extString);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5017: { // gluCylinder
GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8;
@@ -195,21 +168,19 @@ case 5020: { // gluErrorString
GLenum *error = (GLenum *) bp; bp += 4;
const GLubyte * result = wegluErrorString(*error);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) result; rt[AP++] = strlen((char *) result);
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5021: { // gluGetString
GLenum *name = (GLenum *) bp; bp += 4;
const GLubyte * result = wegluGetString(*name);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) result; rt[AP++] = strlen((char *) result);
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5022: { // gluLookAt
GLdouble *eyeX = (GLdouble *) bp; bp += 8;
@@ -226,11 +197,10 @@ case 5022: { // gluLookAt
case 5023: { // gluNewQuadric
GLUquadric * result = wegluNewQuadric();
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5024: { // gluOrtho2D
GLdouble *left = (GLdouble *) bp; bp += 8;
@@ -276,15 +246,14 @@ case 5028: { // gluProject
GLdouble winZ[1] = {0.0};
GLint result = wegluProject(*objX,*objY,*objZ,model,proj,view,winX,winY,winZ);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) winX;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) winY;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) winZ;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5029: { // gluQuadricDrawStyle
GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8;
@@ -311,18 +280,17 @@ case 5033: { // gluScaleImage
GLsizei *wIn = (GLsizei *) bp; bp += 4;
GLsizei *hIn = (GLsizei *) bp; bp += 4;
GLenum *typeIn = (GLenum *) bp; bp += 4;
- void *dataIn = (void *) bins[0]->base;
+ void *dataIn = (void *) bins[0];
GLsizei *wOut = (GLsizei *) bp; bp += 4;
GLsizei *hOut = (GLsizei *) bp; bp += 4;
GLenum *typeOut = (GLenum *) bp; bp += 4;
- GLvoid *dataOut = (GLvoid *) bins[1]->base;
+ GLvoid *dataOut = (GLvoid *) bins[1];
GLint result = wegluScaleImage(*format,*wIn,*hIn,*typeIn,dataIn,*wOut,*hOut,*typeOut,dataOut);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5034: { // gluSphere
GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8;
@@ -343,15 +311,14 @@ case 5035: { // gluUnProject
GLdouble objZ[1] = {0.0};
GLint result = wegluUnProject(*winX,*winY,*winZ,model,proj,view,objX,objY,objZ);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objX;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objY;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objZ;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5036: { // gluUnProject4
GLdouble *winX = (GLdouble *) bp; bp += 8;
@@ -369,7 +336,7 @@ case 5036: { // gluUnProject4
GLdouble objW[1] = {0.0};
GLint result = wegluUnProject4(*winX,*winY,*winZ,*clipW,model,proj,view,*nearVal,*farVal,objX,objY,objZ,objW);
int AP = 0; ErlDrvTermData rt[16];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objX;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objY;
@@ -377,8 +344,7 @@ case 5036: { // gluUnProject4
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objW;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 5;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 16 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,16);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5037: { // glAccum
GLenum *op = (GLenum *) bp; bp += 4;
@@ -398,15 +364,14 @@ case 5039: { // glAreTexturesResident
GLboolean result = weglAreTexturesResident(*texturesLen,textures,residences);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(11 + (*texturesLen)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
for(int i=0; i < *texturesLen; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) residences[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*texturesLen)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 11 + (*texturesLen)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,11 + (*texturesLen)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(residences);
}; break;
@@ -440,7 +405,7 @@ case 5044: { // glBitmap
GLfloat *yorig = (GLfloat *) bp; bp += 4;
GLfloat *xmove = (GLfloat *) bp; bp += 4;
GLfloat *ymove = (GLfloat *) bp; bp += 4;
- GLubyte *bitmap = (GLubyte *) bins[0]->base;
+ GLubyte *bitmap = (GLubyte *) bins[0];
weglBitmap(*width,*height,*xorig,*yorig,*xmove,*ymove,bitmap);
}; break;
case 5045: { // glBlendFunc
@@ -580,7 +545,7 @@ case 5074: { // glColorPointer
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglColorPointer(*size,*type,*stride,pointer);
}; break;
case 5075: { // glCopyPixels
@@ -688,7 +653,7 @@ case 5091: { // glDrawElements
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *indices = (GLvoid *) bins[0]->base;
+ GLvoid *indices = (GLvoid *) bins[0];
weglDrawElements(*mode,*count,*type,indices);
}; break;
case 5092: { // glDrawPixels
@@ -704,7 +669,7 @@ case 5093: { // glDrawPixels
GLsizei *height = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *pixels = (GLvoid *) bins[0]->base;
+ GLvoid *pixels = (GLvoid *) bins[0];
weglDrawPixels(*width,*height,*format,*type,pixels);
}; break;
case 5094: { // glEdgeFlagv
@@ -718,7 +683,7 @@ case 5095: { // glEdgeFlagPointer
}; break;
case 5096: { // glEdgeFlagPointer
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglEdgeFlagPointer(*stride,pointer);
}; break;
case 5097: { // glEnable
@@ -777,13 +742,13 @@ case 5108: { // glEvalPoint2
case 5109: { // glFeedbackBuffer
GLsizei *size = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLfloat *buffer = (GLfloat *) bins[0]->base;
+ GLfloat *buffer = (GLfloat *) bins[0];
weglFeedbackBuffer(*size,*type,buffer);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5110: { // glFinish
weglFinish();
@@ -830,11 +795,10 @@ case 5118: { // glGenLists
GLsizei *range = (GLsizei *) bp; bp += 4;
GLuint result = weglGenLists(*range);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5119: { // glGenTextures
GLsizei *n = (GLsizei *) bp; bp += 4;
@@ -843,13 +807,12 @@ case 5119: { // glGenTextures
weglGenTextures(*n,textures);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *n; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) textures[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(textures);
}; break;
@@ -858,7 +821,7 @@ case 5120: { // glGetBooleanv
GLboolean params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
weglGetBooleanv(*pname,params);
int AP = 0; ErlDrvTermData rt[39];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLboolean *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -878,15 +841,14 @@ case 5120: { // glGetBooleanv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5121: { // glGetClipPlane
GLenum *plane = (GLenum *) bp; bp += 4;
GLdouble equation[4] = {0.0,0.0,0.0,0.0};
weglGetClipPlane(*plane,equation);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble *equationTmp = equation;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) equationTmp++;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) equationTmp++;
@@ -894,15 +856,14 @@ case 5121: { // glGetClipPlane
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) equationTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5122: { // glGetDoublev
GLenum *pname = (GLenum *) bp; bp += 4;
GLdouble params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
weglGetDoublev(*pname,params);
int AP = 0; ErlDrvTermData rt[39];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble *paramsTmp = params;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -922,24 +883,22 @@ case 5122: { // glGetDoublev
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5123: { // glGetError
GLenum result = weglGetError();
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5124: { // glGetFloatv
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
weglGetFloatv(*pname,params);
int AP = 0; ErlDrvTermData rt[39];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[16], *paramsTmp = paramsConv;
for(int i=0; i < 16; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -960,15 +919,14 @@ case 5124: { // glGetFloatv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5125: { // glGetIntegerv
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
weglGetIntegerv(*pname,params);
int AP = 0; ErlDrvTermData rt[39];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -988,8 +946,7 @@ case 5125: { // glGetIntegerv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5126: { // glGetLightfv
GLenum *light = (GLenum *) bp; bp += 4;
@@ -997,7 +954,7 @@ case 5126: { // glGetLightfv
GLfloat params[4] = {0.0,0.0,0.0,0.0};
weglGetLightfv(*light,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[4], *paramsTmp = paramsConv;
for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -1006,8 +963,7 @@ case 5126: { // glGetLightfv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5127: { // glGetLightiv
GLenum *light = (GLenum *) bp; bp += 4;
@@ -1015,7 +971,7 @@ case 5127: { // glGetLightiv
GLint params[4] = {0,0,0,0};
weglGetLightiv(*light,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -1023,41 +979,40 @@ case 5127: { // glGetLightiv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5128: { // glGetMapdv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *query = (GLenum *) bp; bp += 4;
- GLdouble *v = (GLdouble *) bins[0]->base;
+ GLdouble *v = (GLdouble *) bins[0];
weglGetMapdv(*target,*query,v);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5129: { // glGetMapfv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *query = (GLenum *) bp; bp += 4;
- GLfloat *v = (GLfloat *) bins[0]->base;
+ GLfloat *v = (GLfloat *) bins[0];
weglGetMapfv(*target,*query,v);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5130: { // glGetMapiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *query = (GLenum *) bp; bp += 4;
- GLint *v = (GLint *) bins[0]->base;
+ GLint *v = (GLint *) bins[0];
weglGetMapiv(*target,*query,v);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5131: { // glGetMaterialfv
GLenum *face = (GLenum *) bp; bp += 4;
@@ -1065,7 +1020,7 @@ case 5131: { // glGetMaterialfv
GLfloat params[4] = {0.0,0.0,0.0,0.0};
weglGetMaterialfv(*face,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[4], *paramsTmp = paramsConv;
for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -1074,8 +1029,7 @@ case 5131: { // glGetMaterialfv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5132: { // glGetMaterialiv
GLenum *face = (GLenum *) bp; bp += 4;
@@ -1083,7 +1037,7 @@ case 5132: { // glGetMaterialiv
GLint params[4] = {0,0,0,0};
weglGetMaterialiv(*face,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -1091,61 +1045,56 @@ case 5132: { // glGetMaterialiv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5133: { // glGetPixelMapfv
GLenum *map = (GLenum *) bp; bp += 4;
- GLfloat *values = (GLfloat *) bins[0]->base;
+ GLfloat *values = (GLfloat *) bins[0];
weglGetPixelMapfv(*map,values);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5134: { // glGetPixelMapuiv
GLenum *map = (GLenum *) bp; bp += 4;
- GLuint *values = (GLuint *) bins[0]->base;
+ GLuint *values = (GLuint *) bins[0];
weglGetPixelMapuiv(*map,values);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5135: { // glGetPixelMapusv
GLenum *map = (GLenum *) bp; bp += 4;
- GLushort *values = (GLushort *) bins[0]->base;
+ GLushort *values = (GLushort *) bins[0];
weglGetPixelMapusv(*map,values);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5136: { // glGetPolygonStipple
- GLubyte mask[128];
- weglGetPolygonStipple(mask);
+ ErlDrvBinary *mask = driver_alloc_binary(128);
+ weglGetPolygonStipple((GLubyte*) mask->orig_bytes);
int AP = 0; ErlDrvTermData rt[8];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
- ErlDrvBinary * BinCopy = driver_alloc_binary(128);
- memcpy(BinCopy->orig_bytes, mask, 128);
- rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) BinCopy; rt[AP++] = 128; rt[AP++] = 0;
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) mask; rt[AP++] = 128; rt[AP++] = 0;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
- driver_free_binary(BinCopy);
+ driver_send_term(port,caller,rt,AP);
+ driver_free_binary(mask);
}; break;
case 5137: { // glGetString
GLenum *name = (GLenum *) bp; bp += 4;
const GLubyte * result = weglGetString(*name);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) result; rt[AP++] = strlen((char *) result);
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5138: { // glGetTexEnvfv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -1153,7 +1102,7 @@ case 5138: { // glGetTexEnvfv
GLfloat params[4] = {0.0,0.0,0.0,0.0};
weglGetTexEnvfv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[4], *paramsTmp = paramsConv;
for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -1162,8 +1111,7 @@ case 5138: { // glGetTexEnvfv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5139: { // glGetTexEnviv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -1171,7 +1119,7 @@ case 5139: { // glGetTexEnviv
GLint params[4] = {0,0,0,0};
weglGetTexEnviv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -1179,8 +1127,7 @@ case 5139: { // glGetTexEnviv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5140: { // glGetTexGendv
GLenum *coord = (GLenum *) bp; bp += 4;
@@ -1188,7 +1135,7 @@ case 5140: { // glGetTexGendv
GLdouble params[4] = {0.0,0.0,0.0,0.0};
weglGetTexGendv(*coord,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble *paramsTmp = params;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -1196,8 +1143,7 @@ case 5140: { // glGetTexGendv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5141: { // glGetTexGenfv
GLenum *coord = (GLenum *) bp; bp += 4;
@@ -1205,7 +1151,7 @@ case 5141: { // glGetTexGenfv
GLfloat params[4] = {0.0,0.0,0.0,0.0};
weglGetTexGenfv(*coord,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[4], *paramsTmp = paramsConv;
for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -1214,8 +1160,7 @@ case 5141: { // glGetTexGenfv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5142: { // glGetTexGeniv
GLenum *coord = (GLenum *) bp; bp += 4;
@@ -1223,7 +1168,7 @@ case 5142: { // glGetTexGeniv
GLint params[4] = {0,0,0,0};
weglGetTexGeniv(*coord,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -1231,21 +1176,20 @@ case 5142: { // glGetTexGeniv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5143: { // glGetTexImage
GLenum *target = (GLenum *) bp; bp += 4;
GLint *level = (GLint *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *pixels = (GLvoid *) bins[0]->base;
+ GLvoid *pixels = (GLvoid *) bins[0];
weglGetTexImage(*target,*level,*format,*type,pixels);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5144: { // glGetTexLevelParameterfv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -1254,14 +1198,13 @@ case 5144: { // glGetTexLevelParameterfv
GLfloat params[1] = {0.0};
weglGetTexLevelParameterfv(*target,*level,*pname,params);
int AP = 0; ErlDrvTermData rt[8];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[1], *paramsTmp = paramsConv;
for(int i=0; i < 1; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5145: { // glGetTexLevelParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -1270,13 +1213,12 @@ case 5145: { // glGetTexLevelParameteriv
GLint params[1] = {0};
weglGetTexLevelParameteriv(*target,*level,*pname,params);
int AP = 0; ErlDrvTermData rt[8];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5146: { // glGetTexParameterfv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -1284,7 +1226,7 @@ case 5146: { // glGetTexParameterfv
GLfloat params[4] = {0.0,0.0,0.0,0.0};
weglGetTexParameterfv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[4], *paramsTmp = paramsConv;
for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -1293,8 +1235,7 @@ case 5146: { // glGetTexParameterfv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5147: { // glGetTexParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -1302,7 +1243,7 @@ case 5147: { // glGetTexParameteriv
GLint params[4] = {0,0,0,0};
weglGetTexParameteriv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -1310,8 +1251,7 @@ case 5147: { // glGetTexParameteriv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5148: { // glHint
GLenum *target = (GLenum *) bp; bp += 4;
@@ -1331,7 +1271,7 @@ case 5150: { // glIndexPointer
case 5151: { // glIndexPointer
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglIndexPointer(*type,*stride,pointer);
}; break;
case 5152: { // glIndexdv
@@ -1366,38 +1306,35 @@ case 5158: { // glInterleavedArrays
case 5159: { // glInterleavedArrays
GLenum *format = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglInterleavedArrays(*format,*stride,pointer);
}; break;
case 5160: { // glIsEnabled
GLenum *cap = (GLenum *) bp; bp += 4;
GLboolean result = weglIsEnabled(*cap);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5161: { // glIsList
GLuint *list = (GLuint *) bp; bp += 4;
GLboolean result = weglIsList(*list);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5162: { // glIsTexture
GLuint *texture = (GLuint *) bp; bp += 4;
GLboolean result = weglIsTexture(*texture);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5163: { // glLightModelf
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -1486,7 +1423,7 @@ case 5179: { // glMap1d
GLdouble *u2 = (GLdouble *) bp; bp += 8;
GLint *stride = (GLint *) bp; bp += 4;
GLint *order = (GLint *) bp; bp += 4;
- GLdouble *points = (GLdouble *) bins[0]->base;
+ GLdouble *points = (GLdouble *) bins[0];
weglMap1d(*target,*u1,*u2,*stride,*order,points);
}; break;
case 5180: { // glMap1f
@@ -1495,7 +1432,7 @@ case 5180: { // glMap1f
GLfloat *u2 = (GLfloat *) bp; bp += 4;
GLint *stride = (GLint *) bp; bp += 4;
GLint *order = (GLint *) bp; bp += 4;
- GLfloat *points = (GLfloat *) bins[0]->base;
+ GLfloat *points = (GLfloat *) bins[0];
weglMap1f(*target,*u1,*u2,*stride,*order,points);
}; break;
case 5181: { // glMap2d
@@ -1509,7 +1446,7 @@ case 5181: { // glMap2d
GLdouble *v2 = (GLdouble *) bp; bp += 8;
GLint *vstride = (GLint *) bp; bp += 4;
GLint *vorder = (GLint *) bp; bp += 4;
- GLdouble *points = (GLdouble *) bins[0]->base;
+ GLdouble *points = (GLdouble *) bins[0];
weglMap2d(*target,*u1,*u2,*ustride,*uorder,*v1,*v2,*vstride,*vorder,points);
}; break;
case 5182: { // glMap2f
@@ -1522,7 +1459,7 @@ case 5182: { // glMap2f
GLfloat *v2 = (GLfloat *) bp; bp += 4;
GLint *vstride = (GLint *) bp; bp += 4;
GLint *vorder = (GLint *) bp; bp += 4;
- GLfloat *points = (GLfloat *) bins[0]->base;
+ GLfloat *points = (GLfloat *) bins[0];
weglMap2f(*target,*u1,*u2,*ustride,*uorder,*v1,*v2,*vstride,*vorder,points);
}; break;
case 5183: { // glMapGrid1d
@@ -1630,7 +1567,7 @@ case 5200: { // glNormalPointer
case 5201: { // glNormalPointer
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglNormalPointer(*type,*stride,pointer);
}; break;
case 5202: { // glOrtho
@@ -1649,19 +1586,19 @@ case 5203: { // glPassThrough
case 5204: { // glPixelMapfv
GLenum *map = (GLenum *) bp; bp += 4;
GLsizei *mapsize = (GLsizei *) bp; bp += 4;
- GLfloat *values = (GLfloat *) bins[0]->base;
+ GLfloat *values = (GLfloat *) bins[0];
weglPixelMapfv(*map,*mapsize,values);
}; break;
case 5205: { // glPixelMapuiv
GLenum *map = (GLenum *) bp; bp += 4;
GLsizei *mapsize = (GLsizei *) bp; bp += 4;
- GLuint *values = (GLuint *) bins[0]->base;
+ GLuint *values = (GLuint *) bins[0];
weglPixelMapuiv(*map,*mapsize,values);
}; break;
case 5206: { // glPixelMapusv
GLenum *map = (GLenum *) bp; bp += 4;
GLsizei *mapsize = (GLsizei *) bp; bp += 4;
- GLushort *values = (GLushort *) bins[0]->base;
+ GLushort *values = (GLushort *) bins[0];
weglPixelMapusv(*map,*mapsize,values);
}; break;
case 5207: { // glPixelStoref
@@ -1704,7 +1641,7 @@ case 5214: { // glPolygonOffset
weglPolygonOffset(*factor,*units);
}; break;
case 5215: { // glPolygonStipple
- GLubyte *mask = (GLubyte *) bins[0]->base;
+ GLubyte *mask = (GLubyte *) bins[0];
weglPolygonStipple(mask);
}; break;
case 5216: { // glPopAttrib
@@ -1800,13 +1737,13 @@ case 5238: { // glReadPixels
GLsizei *height = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *pixels = (GLvoid *) bins[0]->base;
+ GLvoid *pixels = (GLvoid *) bins[0];
weglReadPixels(*x,*y,*width,*height,*format,*type,pixels);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5239: { // glRectd
GLdouble *x1 = (GLdouble *) bp; bp += 8;
@@ -1860,11 +1797,10 @@ case 5247: { // glRenderMode
GLenum *mode = (GLenum *) bp; bp += 4;
GLint result = weglRenderMode(*mode);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5248: { // glRotated
GLdouble *angle = (GLdouble *) bp; bp += 8;
@@ -1901,13 +1837,13 @@ case 5252: { // glScissor
}; break;
case 5253: { // glSelectBuffer
GLsizei *size = (GLsizei *) bp; bp += 4;
- GLuint *buffer = (GLuint *) bins[0]->base;
+ GLuint *buffer = (GLuint *) bins[0];
weglSelectBuffer(*size,buffer);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5254: { // glShadeModel
GLenum *mode = (GLenum *) bp; bp += 4;
@@ -2004,7 +1940,7 @@ case 5275: { // glTexCoordPointer
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglTexCoordPointer(*size,*type,*stride,pointer);
}; break;
case 5276: { // glTexEnvf
@@ -2091,7 +2027,7 @@ case 5287: { // glTexImage1D
GLint *border = (GLint *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *pixels = (GLvoid *) bins[0]->base;
+ GLvoid *pixels = (GLvoid *) bins[0];
weglTexImage1D(*target,*level,*internalformat,*width,*border,*format,*type,pixels);
}; break;
case 5288: { // glTexImage2D
@@ -2115,7 +2051,7 @@ case 5289: { // glTexImage2D
GLint *border = (GLint *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *pixels = (GLvoid *) bins[0]->base;
+ GLvoid *pixels = (GLvoid *) bins[0];
weglTexImage2D(*target,*level,*internalformat,*width,*height,*border,*format,*type,pixels);
}; break;
case 5290: { // glTexParameterf
@@ -2161,7 +2097,7 @@ case 5295: { // glTexSubImage1D
GLsizei *width = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *pixels = (GLvoid *) bins[0]->base;
+ GLvoid *pixels = (GLvoid *) bins[0];
weglTexSubImage1D(*target,*level,*xoffset,*width,*format,*type,pixels);
}; break;
case 5296: { // glTexSubImage2D
@@ -2185,7 +2121,7 @@ case 5297: { // glTexSubImage2D
GLsizei *height = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *pixels = (GLvoid *) bins[0]->base;
+ GLvoid *pixels = (GLvoid *) bins[0];
weglTexSubImage2D(*target,*level,*xoffset,*yoffset,*width,*height,*format,*type,pixels);
}; break;
case 5298: { // glTranslated
@@ -2259,7 +2195,7 @@ case 5313: { // glVertexPointer
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglVertexPointer(*size,*type,*stride,pointer);
}; break;
case 5314: { // glViewport
@@ -2295,7 +2231,7 @@ case 5318: { // glDrawRangeElements
GLuint *end = (GLuint *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *indices = (GLvoid *) bins[0]->base;
+ GLvoid *indices = (GLvoid *) bins[0];
weglDrawRangeElements(*mode,*start,*end,*count,*type,indices);
}; break;
case 5319: { // glTexImage3D
@@ -2321,7 +2257,7 @@ case 5320: { // glTexImage3D
GLint *border = (GLint *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *pixels = (GLvoid *) bins[0]->base;
+ GLvoid *pixels = (GLvoid *) bins[0];
weglTexImage3D(*target,*level,*internalformat,*width,*height,*depth,*border,*format,*type,pixels);
}; break;
case 5321: { // glTexSubImage3D
@@ -2349,7 +2285,7 @@ case 5322: { // glTexSubImage3D
GLsizei *depth = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *pixels = (GLvoid *) bins[0]->base;
+ GLvoid *pixels = (GLvoid *) bins[0];
weglTexSubImage3D(*target,*level,*xoffset,*yoffset,*zoffset,*width,*height,*depth,*format,*type,pixels);
}; break;
case 5323: { // glCopyTexSubImage3D
@@ -2379,7 +2315,7 @@ case 5325: { // glColorTable
GLsizei *width = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *table = (GLvoid *) bins[0]->base;
+ GLvoid *table = (GLvoid *) bins[0];
weglColorTable(*target,*internalformat,*width,*format,*type,table);
}; break;
case 5326: { // glColorTableParameterfv
@@ -2406,13 +2342,13 @@ case 5329: { // glGetColorTable
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *table = (GLvoid *) bins[0]->base;
+ GLvoid *table = (GLvoid *) bins[0];
weglGetColorTable(*target,*format,*type,table);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5330: { // glGetColorTableParameterfv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2420,7 +2356,7 @@ case 5330: { // glGetColorTableParameterfv
GLfloat params[4] = {0.0,0.0,0.0,0.0};
weglGetColorTableParameterfv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[4], *paramsTmp = paramsConv;
for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -2429,8 +2365,7 @@ case 5330: { // glGetColorTableParameterfv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5331: { // glGetColorTableParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2438,7 +2373,7 @@ case 5331: { // glGetColorTableParameteriv
GLint params[4] = {0,0,0,0};
weglGetColorTableParameteriv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -2446,8 +2381,7 @@ case 5331: { // glGetColorTableParameteriv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5332: { // glColorSubTable
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2464,7 +2398,7 @@ case 5333: { // glColorSubTable
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *data = (GLvoid *) bins[0]->base;
+ GLvoid *data = (GLvoid *) bins[0];
weglColorSubTable(*target,*start,*count,*format,*type,data);
}; break;
case 5334: { // glCopyColorSubTable
@@ -2490,7 +2424,7 @@ case 5336: { // glConvolutionFilter1D
GLsizei *width = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *image = (GLvoid *) bins[0]->base;
+ GLvoid *image = (GLvoid *) bins[0];
weglConvolutionFilter1D(*target,*internalformat,*width,*format,*type,image);
}; break;
case 5337: { // glConvolutionFilter2D
@@ -2510,7 +2444,7 @@ case 5338: { // glConvolutionFilter2D
GLsizei *height = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *image = (GLvoid *) bins[0]->base;
+ GLvoid *image = (GLvoid *) bins[0];
weglConvolutionFilter2D(*target,*internalformat,*width,*height,*format,*type,image);
}; break;
case 5339: { // glConvolutionParameterfv
@@ -2548,13 +2482,13 @@ case 5343: { // glGetConvolutionFilter
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *image = (GLvoid *) bins[0]->base;
+ GLvoid *image = (GLvoid *) bins[0];
weglGetConvolutionFilter(*target,*format,*type,image);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5344: { // glGetConvolutionParameterfv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2562,7 +2496,7 @@ case 5344: { // glGetConvolutionParameterfv
GLfloat params[4] = {0.0,0.0,0.0,0.0};
weglGetConvolutionParameterfv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[4], *paramsTmp = paramsConv;
for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -2571,8 +2505,7 @@ case 5344: { // glGetConvolutionParameterfv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5345: { // glGetConvolutionParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2580,7 +2513,7 @@ case 5345: { // glGetConvolutionParameteriv
GLint params[4] = {0,0,0,0};
weglGetConvolutionParameteriv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -2588,8 +2521,7 @@ case 5345: { // glGetConvolutionParameteriv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5346: { // glSeparableFilter2D
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2609,8 +2541,8 @@ case 5347: { // glSeparableFilter2D
GLsizei *height = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *row = (GLvoid *) bins[0]->base;
- GLvoid *column = (GLvoid *) bins[1]->base;
+ GLvoid *row = (GLvoid *) bins[0];
+ GLvoid *column = (GLvoid *) bins[1];
weglSeparableFilter2D(*target,*internalformat,*width,*height,*format,*type,row,column);
}; break;
case 5348: { // glGetHistogram
@@ -2619,13 +2551,13 @@ case 5348: { // glGetHistogram
bp += 3;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *values = (GLvoid *) bins[0]->base;
+ GLvoid *values = (GLvoid *) bins[0];
weglGetHistogram(*target,*reset,*format,*type,values);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5349: { // glGetHistogramParameterfv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2633,14 +2565,13 @@ case 5349: { // glGetHistogramParameterfv
GLfloat params[1] = {0.0};
weglGetHistogramParameterfv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[8];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[1], *paramsTmp = paramsConv;
for(int i=0; i < 1; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5350: { // glGetHistogramParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2648,13 +2579,12 @@ case 5350: { // glGetHistogramParameteriv
GLint params[1] = {0};
weglGetHistogramParameteriv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[8];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5351: { // glGetMinmax
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2662,13 +2592,13 @@ case 5351: { // glGetMinmax
bp += 3;
GLenum *format = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *values = (GLvoid *) bins[0]->base;
+ GLvoid *values = (GLvoid *) bins[0];
weglGetMinmax(*target,*reset,*format,*type,values);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5352: { // glGetMinmaxParameterfv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2676,14 +2606,13 @@ case 5352: { // glGetMinmaxParameterfv
GLfloat params[1] = {0.0};
weglGetMinmaxParameterfv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[8];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[1], *paramsTmp = paramsConv;
for(int i=0; i < 1; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5353: { // glGetMinmaxParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2691,13 +2620,12 @@ case 5353: { // glGetMinmaxParameteriv
GLint params[1] = {0};
weglGetMinmaxParameteriv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[8];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5354: { // glHistogram
GLenum *target = (GLenum *) bp; bp += 4;
@@ -2750,7 +2678,7 @@ case 5361: { // glCompressedTexImage3D
GLsizei *depth = (GLsizei *) bp; bp += 4;
GLint *border = (GLint *) bp; bp += 4;
GLsizei *imageSize = (GLsizei *) bp; bp += 4;
- GLvoid *data = (GLvoid *) bins[0]->base;
+ GLvoid *data = (GLvoid *) bins[0];
weglCompressedTexImage3D(*target,*level,*internalformat,*width,*height,*depth,*border,*imageSize,data);
}; break;
case 5362: { // glCompressedTexImage2D
@@ -2772,7 +2700,7 @@ case 5363: { // glCompressedTexImage2D
GLsizei *height = (GLsizei *) bp; bp += 4;
GLint *border = (GLint *) bp; bp += 4;
GLsizei *imageSize = (GLsizei *) bp; bp += 4;
- GLvoid *data = (GLvoid *) bins[0]->base;
+ GLvoid *data = (GLvoid *) bins[0];
weglCompressedTexImage2D(*target,*level,*internalformat,*width,*height,*border,*imageSize,data);
}; break;
case 5364: { // glCompressedTexImage1D
@@ -2792,7 +2720,7 @@ case 5365: { // glCompressedTexImage1D
GLsizei *width = (GLsizei *) bp; bp += 4;
GLint *border = (GLint *) bp; bp += 4;
GLsizei *imageSize = (GLsizei *) bp; bp += 4;
- GLvoid *data = (GLvoid *) bins[0]->base;
+ GLvoid *data = (GLvoid *) bins[0];
weglCompressedTexImage1D(*target,*level,*internalformat,*width,*border,*imageSize,data);
}; break;
case 5366: { // glCompressedTexSubImage3D
@@ -2820,7 +2748,7 @@ case 5367: { // glCompressedTexSubImage3D
GLsizei *depth = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLsizei *imageSize = (GLsizei *) bp; bp += 4;
- GLvoid *data = (GLvoid *) bins[0]->base;
+ GLvoid *data = (GLvoid *) bins[0];
weglCompressedTexSubImage3D(*target,*level,*xoffset,*yoffset,*zoffset,*width,*height,*depth,*format,*imageSize,data);
}; break;
case 5368: { // glCompressedTexSubImage2D
@@ -2844,7 +2772,7 @@ case 5369: { // glCompressedTexSubImage2D
GLsizei *height = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLsizei *imageSize = (GLsizei *) bp; bp += 4;
- GLvoid *data = (GLvoid *) bins[0]->base;
+ GLvoid *data = (GLvoid *) bins[0];
weglCompressedTexSubImage2D(*target,*level,*xoffset,*yoffset,*width,*height,*format,*imageSize,data);
}; break;
case 5370: { // glCompressedTexSubImage1D
@@ -2864,19 +2792,19 @@ case 5371: { // glCompressedTexSubImage1D
GLsizei *width = (GLsizei *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLsizei *imageSize = (GLsizei *) bp; bp += 4;
- GLvoid *data = (GLvoid *) bins[0]->base;
+ GLvoid *data = (GLvoid *) bins[0];
weglCompressedTexSubImage1D(*target,*level,*xoffset,*width,*format,*imageSize,data);
}; break;
case 5372: { // glGetCompressedTexImage
GLenum *target = (GLenum *) bp; bp += 4;
GLint *level = (GLint *) bp; bp += 4;
- GLvoid *img = (GLvoid *) bins[0]->base;
+ GLvoid *img = (GLvoid *) bins[0];
weglGetCompressedTexImage(*target,*level,img);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5373: { // glClientActiveTexture
GLenum *texture = (GLenum *) bp; bp += 4;
@@ -3036,7 +2964,7 @@ case 5402: { // glFogCoordPointer
case 5403: { // glFogCoordPointer
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglFogCoordPointer(*type,*stride,pointer);
}; break;
case 5404: { // glSecondaryColor3bv
@@ -3082,7 +3010,7 @@ case 5413: { // glSecondaryColorPointer
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglSecondaryColorPointer(*size,*type,*stride,pointer);
}; break;
case 5414: { // glWindowPos2dv
@@ -3124,13 +3052,12 @@ case 5422: { // glGenQueries
weglGenQueries(*n,ids);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *n; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ids[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(ids);
}; break;
@@ -3143,11 +3070,10 @@ case 5424: { // glIsQuery
GLuint *id = (GLuint *) bp; bp += 4;
GLboolean result = weglIsQuery(*id);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5425: { // glBeginQuery
GLenum *target = (GLenum *) bp; bp += 4;
@@ -3164,11 +3090,10 @@ case 5427: { // glGetQueryiv
GLint params[1] = {0};
weglGetQueryiv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5428: { // glGetQueryObjectiv
GLuint *id = (GLuint *) bp; bp += 4;
@@ -3176,11 +3101,10 @@ case 5428: { // glGetQueryObjectiv
GLint params[1] = {0};
weglGetQueryObjectiv(*id,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5429: { // glGetQueryObjectuiv
GLuint *id = (GLuint *) bp; bp += 4;
@@ -3188,11 +3112,10 @@ case 5429: { // glGetQueryObjectuiv
GLuint params[1] = {0};
weglGetQueryObjectuiv(*id,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5430: { // glBindBuffer
GLenum *target = (GLenum *) bp; bp += 4;
@@ -3211,13 +3134,12 @@ case 5432: { // glGenBuffers
weglGenBuffers(*n,buffers);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *n; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) buffers[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(buffers);
}; break;
@@ -3225,11 +3147,10 @@ case 5433: { // glIsBuffer
GLuint *buffer = (GLuint *) bp; bp += 4;
GLboolean result = weglIsBuffer(*buffer);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5434: { // glBufferData
GLenum *target = (GLenum *) bp; bp += 4;
@@ -3243,7 +3164,7 @@ case 5435: { // glBufferData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
- GLvoid *data = (GLvoid *) bins[0]->base;
+ GLvoid *data = (GLvoid *) bins[0];
GLenum *usage = (GLenum *) bp; bp += 4;
weglBufferData(*target,size,data,*usage);
}; break;
@@ -3260,7 +3181,7 @@ case 5437: { // glBufferSubData
bp += 4;
GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
- GLvoid *data = (GLvoid *) bins[0]->base;
+ GLvoid *data = (GLvoid *) bins[0];
weglBufferSubData(*target,offset,size,data);
}; break;
case 5438: { // glGetBufferSubData
@@ -3268,13 +3189,13 @@ case 5438: { // glGetBufferSubData
bp += 4;
GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
- GLvoid *data = (GLvoid *) bins[0]->base;
+ GLvoid *data = (GLvoid *) bins[0];
weglGetBufferSubData(*target,offset,size,data);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5439: { // glGetBufferParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
@@ -3282,11 +3203,10 @@ case 5439: { // glGetBufferParameteriv
GLint params[1] = {0};
weglGetBufferParameteriv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5440: { // glBlendEquationSeparate
GLenum *modeRGB = (GLenum *) bp; bp += 4;
@@ -3306,11 +3226,11 @@ case 5442: { // glStencilOpSeparate
weglStencilOpSeparate(*face,*sfail,*dpfail,*dppass);
}; break;
case 5443: { // glStencilFuncSeparate
- GLenum *frontfunc = (GLenum *) bp; bp += 4;
- GLenum *backfunc = (GLenum *) bp; bp += 4;
+ GLenum *face = (GLenum *) bp; bp += 4;
+ GLenum *func = (GLenum *) bp; bp += 4;
GLint *ref = (GLint *) bp; bp += 4;
GLuint *mask = (GLuint *) bp; bp += 4;
- weglStencilFuncSeparate(*frontfunc,*backfunc,*ref,*mask);
+ weglStencilFuncSeparate(*face,*func,*ref,*mask);
}; break;
case 5444: { // glStencilMaskSeparate
GLenum *face = (GLenum *) bp; bp += 4;
@@ -3326,7 +3246,7 @@ case 5446: { // glBindAttribLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
- int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8);
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
weglBindAttribLocation(*program,*index,name);
}; break;
case 5447: { // glCompileShader
@@ -3336,21 +3256,19 @@ case 5447: { // glCompileShader
case 5448: { // glCreateProgram
GLuint result = weglCreateProgram();
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5449: { // glCreateShader
GLenum *type = (GLenum *) bp; bp += 4;
GLuint result = weglCreateShader(*type);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5450: { // glDeleteProgram
GLuint *program = (GLuint *) bp; bp += 4;
@@ -3384,14 +3302,13 @@ case 5455: { // glGetActiveAttrib
name = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize);
weglGetActiveAttrib(*program,*index,*bufSize,length,size,type,name);
int AP = 0; ErlDrvTermData rt[13];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *size;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *type;
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
case 5456: { // glGetActiveUniform
@@ -3405,14 +3322,13 @@ case 5456: { // glGetActiveUniform
name = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize);
weglGetActiveUniform(*program,*index,*bufSize,length,size,type,name);
int AP = 0; ErlDrvTermData rt[13];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *size;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *type;
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
case 5457: { // glGetAttachedShaders
@@ -3424,27 +3340,25 @@ case 5457: { // glGetAttachedShaders
weglGetAttachedShaders(*program,*maxCount,count,obj);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*count)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *count; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) obj[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*count)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*count)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*count)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(obj);
}; break;
case 5458: { // glGetAttribLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
- int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8);
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
GLint result = weglGetAttribLocation(*program,name);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5459: { // glGetProgramiv
GLuint *program = (GLuint *) bp; bp += 4;
@@ -3452,11 +3366,10 @@ case 5459: { // glGetProgramiv
GLint params[1] = {0};
weglGetProgramiv(*program,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5460: { // glGetProgramInfoLog
GLuint *program = (GLuint *) bp; bp += 4;
@@ -3466,11 +3379,10 @@ case 5460: { // glGetProgramInfoLog
infoLog = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize);
weglGetProgramInfoLog(*program,*bufSize,length,infoLog);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) infoLog; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
case 5461: { // glGetShaderiv
@@ -3479,11 +3391,10 @@ case 5461: { // glGetShaderiv
GLint params[1] = {0};
weglGetShaderiv(*shader,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5462: { // glGetShaderInfoLog
GLuint *shader = (GLuint *) bp; bp += 4;
@@ -3493,11 +3404,10 @@ case 5462: { // glGetShaderInfoLog
infoLog = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize);
weglGetShaderInfoLog(*shader,*bufSize,length,infoLog);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) infoLog; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
case 5463: { // glGetShaderSource
@@ -3508,24 +3418,22 @@ case 5463: { // glGetShaderSource
source = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize);
weglGetShaderSource(*shader,*bufSize,length,source);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) source; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(source);
}; break;
case 5464: { // glGetUniformLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
- int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8);
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
GLint result = weglGetUniformLocation(*program,name);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5465: { // glGetUniformfv
GLuint *program = (GLuint *) bp; bp += 4;
@@ -3533,7 +3441,7 @@ case 5465: { // glGetUniformfv
GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
weglGetUniformfv(*program,*location,params);
int AP = 0; ErlDrvTermData rt[38];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[16], *paramsTmp = paramsConv;
for(int i=0; i < 16; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -3554,8 +3462,7 @@ case 5465: { // glGetUniformfv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5466: { // glGetUniformiv
GLuint *program = (GLuint *) bp; bp += 4;
@@ -3563,7 +3470,7 @@ case 5466: { // glGetUniformiv
GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
weglGetUniformiv(*program,*location,params);
int AP = 0; ErlDrvTermData rt[38];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -3583,8 +3490,7 @@ case 5466: { // glGetUniformiv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5467: { // glGetVertexAttribdv
GLuint *index = (GLuint *) bp; bp += 4;
@@ -3592,7 +3498,7 @@ case 5467: { // glGetVertexAttribdv
GLdouble params[4] = {0.0,0.0,0.0,0.0};
weglGetVertexAttribdv(*index,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble *paramsTmp = params;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -3600,8 +3506,7 @@ case 5467: { // glGetVertexAttribdv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5468: { // glGetVertexAttribfv
GLuint *index = (GLuint *) bp; bp += 4;
@@ -3609,7 +3514,7 @@ case 5468: { // glGetVertexAttribfv
GLfloat params[4] = {0.0,0.0,0.0,0.0};
weglGetVertexAttribfv(*index,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[4], *paramsTmp = paramsConv;
for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -3618,8 +3523,7 @@ case 5468: { // glGetVertexAttribfv
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5469: { // glGetVertexAttribiv
GLuint *index = (GLuint *) bp; bp += 4;
@@ -3627,7 +3531,7 @@ case 5469: { // glGetVertexAttribiv
GLint params[4] = {0,0,0,0};
weglGetVertexAttribiv(*index,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -3635,28 +3539,25 @@ case 5469: { // glGetVertexAttribiv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5470: { // glIsProgram
GLuint *program = (GLuint *) bp; bp += 4;
GLboolean result = weglIsProgram(*program);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5471: { // glIsShader
GLuint *shader = (GLuint *) bp; bp += 4;
GLboolean result = weglIsShader(*shader);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5472: { // glLinkProgram
GLuint *program = (GLuint *) bp; bp += 4;
@@ -3942,7 +3843,7 @@ case 5519: { // glVertexAttribPointer
GLboolean *normalized = (GLboolean *) bp; bp += 1;
bp += 3;
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglVertexAttribPointer(*index,*size,*type,*normalized,*stride,pointer);
}; break;
case 5520: { // glUniformMatrix2x3fv
@@ -4007,7 +3908,7 @@ case 5527: { // glGetBooleani_v
GLboolean data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
weglGetBooleani_v(*target,*index,data);
int AP = 0; ErlDrvTermData rt[39];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLboolean *dataTmp = data;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
@@ -4027,8 +3928,7 @@ case 5527: { // glGetBooleani_v
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5528: { // glGetIntegeri_v
GLenum *target = (GLenum *) bp; bp += 4;
@@ -4036,7 +3936,7 @@ case 5528: { // glGetIntegeri_v
GLint data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
weglGetIntegeri_v(*target,*index,data);
int AP = 0; ErlDrvTermData rt[39];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *dataTmp = data;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
@@ -4056,8 +3956,7 @@ case 5528: { // glGetIntegeri_v
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5529: { // glEnablei
GLenum *target = (GLenum *) bp; bp += 4;
@@ -4074,11 +3973,10 @@ case 5531: { // glIsEnabledi
GLuint *index = (GLuint *) bp; bp += 4;
GLboolean result = weglIsEnabledi(*target,*index);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5532: { // glBeginTransformFeedback
GLenum *primitiveMode = (GLenum *) bp; bp += 4;
@@ -4126,14 +4024,13 @@ case 5537: { // glGetTransformFeedbackVarying
name = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize);
weglGetTransformFeedbackVarying(*program,*index,*bufSize,length,size,type,name);
int AP = 0; ErlDrvTermData rt[13];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *size;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *type;
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
case 5538: { // glClampColor
@@ -4162,7 +4059,7 @@ case 5542: { // glVertexAttribIPointer
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
- GLvoid *pointer = (GLvoid *) bins[0]->base;
+ GLvoid *pointer = (GLvoid *) bins[0];
weglVertexAttribIPointer(*index,*size,*type,*stride,pointer);
}; break;
case 5543: { // glGetVertexAttribIiv
@@ -4171,7 +4068,7 @@ case 5543: { // glGetVertexAttribIiv
GLint params[4] = {0,0,0,0};
weglGetVertexAttribIiv(*index,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -4179,8 +4076,7 @@ case 5543: { // glGetVertexAttribIiv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5544: { // glGetVertexAttribIuiv
GLuint *index = (GLuint *) bp; bp += 4;
@@ -4188,7 +4084,7 @@ case 5544: { // glGetVertexAttribIuiv
GLuint params[4] = {0,0,0,0};
weglGetVertexAttribIuiv(*index,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLuint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -4196,16 +4092,75 @@ case 5544: { // glGetVertexAttribIuiv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5545: { // glVertexAttribI1iv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLint *v = (GLint *) bp; bp += 4;
+ weglVertexAttribI1iv(*index,v);
+}; break;
+case 5546: { // glVertexAttribI2iv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLint *v = (GLint *) bp; bp += 4;
+ weglVertexAttribI2iv(*index,v);
+}; break;
+case 5547: { // glVertexAttribI3iv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLint *v = (GLint *) bp; bp += 4;
+ weglVertexAttribI3iv(*index,v);
+}; break;
+case 5548: { // glVertexAttribI4iv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLint * v = (GLint *) bp; bp += 16;
+ weglVertexAttribI4iv(*index,v);
+}; break;
+case 5549: { // glVertexAttribI1uiv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLuint *v = (GLuint *) bp; bp += 4;
+ weglVertexAttribI1uiv(*index,v);
+}; break;
+case 5550: { // glVertexAttribI2uiv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLuint *v = (GLuint *) bp; bp += 4;
+ weglVertexAttribI2uiv(*index,v);
+}; break;
+case 5551: { // glVertexAttribI3uiv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLuint *v = (GLuint *) bp; bp += 4;
+ weglVertexAttribI3uiv(*index,v);
}; break;
-case 5545: { // glGetUniformuiv
+case 5552: { // glVertexAttribI4uiv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLuint * v = (GLuint *) bp; bp += 16;
+ weglVertexAttribI4uiv(*index,v);
+}; break;
+case 5553: { // glVertexAttribI4bv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLbyte * v = (GLbyte *) bp; bp += 4;
+ weglVertexAttribI4bv(*index,v);
+}; break;
+case 5554: { // glVertexAttribI4sv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLshort * v = (GLshort *) bp; bp += 8;
+ weglVertexAttribI4sv(*index,v);
+}; break;
+case 5555: { // glVertexAttribI4ubv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLubyte * v = (GLubyte *) bp; bp += 4;
+ weglVertexAttribI4ubv(*index,v);
+}; break;
+case 5556: { // glVertexAttribI4usv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLushort * v = (GLushort *) bp; bp += 8;
+ weglVertexAttribI4usv(*index,v);
+}; break;
+case 5557: { // glGetUniformuiv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLuint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
weglGetUniformuiv(*program,*location,params);
int AP = 0; ErlDrvTermData rt[38];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLuint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -4225,47 +4180,45 @@ case 5545: { // glGetUniformuiv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5546: { // glBindFragDataLocation
+case 5558: { // glBindFragDataLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *color = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
- int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8);
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
weglBindFragDataLocation(*program,*color,name);
}; break;
-case 5547: { // glGetFragDataLocation
+case 5559: { // glGetFragDataLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
- int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8);
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
GLint result = weglGetFragDataLocation(*program,name);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5548: { // glUniform1ui
+case 5560: { // glUniform1ui
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
weglUniform1ui(*location,*v0);
}; break;
-case 5549: { // glUniform2ui
+case 5561: { // glUniform2ui
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
GLuint *v1 = (GLuint *) bp; bp += 4;
weglUniform2ui(*location,*v0,*v1);
}; break;
-case 5550: { // glUniform3ui
+case 5562: { // glUniform3ui
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
GLuint *v1 = (GLuint *) bp; bp += 4;
GLuint *v2 = (GLuint *) bp; bp += 4;
weglUniform3ui(*location,*v0,*v1,*v2);
}; break;
-case 5551: { // glUniform4ui
+case 5563: { // glUniform4ui
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
GLuint *v1 = (GLuint *) bp; bp += 4;
@@ -4273,51 +4226,51 @@ case 5551: { // glUniform4ui
GLuint *v3 = (GLuint *) bp; bp += 4;
weglUniform4ui(*location,*v0,*v1,*v2,*v3);
}; break;
-case 5552: { // glUniform1uiv
+case 5564: { // glUniform1uiv
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 4;
GLuint * value = (GLuint *) bp; bp += (8-((*valueLen*4+0)%8))%8;
weglUniform1uiv(*location,*valueLen,value);
}; break;
-case 5553: { // glUniform2uiv
+case 5565: { // glUniform2uiv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint * value = (GLuint *) bp; bp += *valueLen*8;
weglUniform2uiv(*location,*valueLen,value);
}; break;
-case 5554: { // glUniform3uiv
+case 5566: { // glUniform3uiv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint * value = (GLuint *) bp; bp += *valueLen*12;
weglUniform3uiv(*location,*valueLen,value);
}; break;
-case 5555: { // glUniform4uiv
+case 5567: { // glUniform4uiv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint * value = (GLuint *) bp; bp += *valueLen*16;
weglUniform4uiv(*location,*valueLen,value);
}; break;
-case 5556: { // glTexParameterIiv
+case 5568: { // glTexParameterIiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
int *paramsLen = (int *) bp; bp += 4;
GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4;
weglTexParameterIiv(*target,*pname,params);
}; break;
-case 5557: { // glTexParameterIuiv
+case 5569: { // glTexParameterIuiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
int *paramsLen = (int *) bp; bp += 4;
GLuint *params = (GLuint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4;
weglTexParameterIuiv(*target,*pname,params);
}; break;
-case 5558: { // glGetTexParameterIiv
+case 5570: { // glGetTexParameterIiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
weglGetTexParameterIiv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -4325,16 +4278,15 @@ case 5558: { // glGetTexParameterIiv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5559: { // glGetTexParameterIuiv
+case 5571: { // glGetTexParameterIuiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint params[4] = {0,0,0,0};
weglGetTexParameterIuiv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLuint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -4342,107 +4294,45 @@ case 5559: { // glGetTexParameterIuiv
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5560: { // glClearBufferiv
+case 5572: { // glClearBufferiv
GLenum *buffer = (GLenum *) bp; bp += 4;
GLint *drawbuffer = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint *value = (GLint *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4;
weglClearBufferiv(*buffer,*drawbuffer,value);
}; break;
-case 5561: { // glClearBufferuiv
+case 5573: { // glClearBufferuiv
GLenum *buffer = (GLenum *) bp; bp += 4;
GLint *drawbuffer = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLuint *value = (GLuint *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4;
weglClearBufferuiv(*buffer,*drawbuffer,value);
}; break;
-case 5562: { // glClearBufferfv
+case 5574: { // glClearBufferfv
GLenum *buffer = (GLenum *) bp; bp += 4;
GLint *drawbuffer = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat *value = (GLfloat *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4;
weglClearBufferfv(*buffer,*drawbuffer,value);
}; break;
-case 5563: { // glClearBufferfi
+case 5575: { // glClearBufferfi
GLenum *buffer = (GLenum *) bp; bp += 4;
GLint *drawbuffer = (GLint *) bp; bp += 4;
GLfloat *depth = (GLfloat *) bp; bp += 4;
GLint *stencil = (GLint *) bp; bp += 4;
weglClearBufferfi(*buffer,*drawbuffer,*depth,*stencil);
}; break;
-case 5564: { // glGetStringi
+case 5576: { // glGetStringi
GLenum *name = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
const GLubyte * result = weglGetStringi(*name,*index);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) result; rt[AP++] = strlen((char *) result);
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
-}; break;
-case 5565: { // glVertexAttribI1iv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLint *v = (GLint *) bp; bp += 4;
- weglVertexAttribI1iv(*index,v);
-}; break;
-case 5566: { // glVertexAttribI2iv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLint *v = (GLint *) bp; bp += 4;
- weglVertexAttribI2iv(*index,v);
-}; break;
-case 5567: { // glVertexAttribI3iv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLint *v = (GLint *) bp; bp += 4;
- weglVertexAttribI3iv(*index,v);
-}; break;
-case 5568: { // glVertexAttribI4iv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLint * v = (GLint *) bp; bp += 16;
- weglVertexAttribI4iv(*index,v);
-}; break;
-case 5569: { // glVertexAttribI1uiv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLuint *v = (GLuint *) bp; bp += 4;
- weglVertexAttribI1uiv(*index,v);
-}; break;
-case 5570: { // glVertexAttribI2uiv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLuint *v = (GLuint *) bp; bp += 4;
- weglVertexAttribI2uiv(*index,v);
-}; break;
-case 5571: { // glVertexAttribI3uiv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLuint *v = (GLuint *) bp; bp += 4;
- weglVertexAttribI3uiv(*index,v);
-}; break;
-case 5572: { // glVertexAttribI4uiv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLuint * v = (GLuint *) bp; bp += 16;
- weglVertexAttribI4uiv(*index,v);
-}; break;
-case 5573: { // glVertexAttribI4bv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLbyte * v = (GLbyte *) bp; bp += 4;
- weglVertexAttribI4bv(*index,v);
-}; break;
-case 5574: { // glVertexAttribI4sv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLshort * v = (GLshort *) bp; bp += 8;
- weglVertexAttribI4sv(*index,v);
-}; break;
-case 5575: { // glVertexAttribI4ubv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLubyte * v = (GLubyte *) bp; bp += 4;
- weglVertexAttribI4ubv(*index,v);
-}; break;
-case 5576: { // glVertexAttribI4usv
- GLuint *index = (GLuint *) bp; bp += 4;
- GLushort * v = (GLushort *) bp; bp += 8;
- weglVertexAttribI4usv(*index,v);
+ driver_send_term(port,caller,rt,AP);
}; break;
case 5577: { // glDrawArraysInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
@@ -4463,7 +4353,7 @@ case 5579: { // glDrawElementsInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
- GLvoid *indices = (GLvoid *) bins[0]->base;
+ GLvoid *indices = (GLvoid *) bins[0];
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawElementsInstanced(*mode,*count,*type,indices,*primcount);
}; break;
@@ -4477,120 +4367,216 @@ case 5581: { // glPrimitiveRestartIndex
GLuint *index = (GLuint *) bp; bp += 4;
weglPrimitiveRestartIndex(*index);
}; break;
-case 5582: { // glLoadTransposeMatrixfARB
+case 5582: { // glGetInteger64i_v
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLint64 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ weglGetInteger64i_v(*target,*index,data);
+ int AP = 0; ErlDrvTermData rt[39];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLint64 *dataTmp = data;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5583: { // glGetBufferParameteri64v
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint64 params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ weglGetBufferParameteri64v(*target,*pname,params);
+ int AP = 0; ErlDrvTermData rt[39];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLint64 *paramsTmp = params;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5584: { // glFramebufferTexture
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLenum *attachment = (GLenum *) bp; bp += 4;
+ GLuint *texture = (GLuint *) bp; bp += 4;
+ GLint *level = (GLint *) bp; bp += 4;
+ weglFramebufferTexture(*target,*attachment,*texture,*level);
+}; break;
+case 5585: { // glVertexAttribDivisor
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLuint *divisor = (GLuint *) bp; bp += 4;
+ weglVertexAttribDivisor(*index,*divisor);
+}; break;
+case 5586: { // glMinSampleShading
+ GLclampf *value = (GLclampf *) bp; bp += 4;
+ weglMinSampleShading(*value);
+}; break;
+case 5587: { // glBlendEquationi
+ GLuint *buf = (GLuint *) bp; bp += 4;
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ weglBlendEquationi(*buf,*mode);
+}; break;
+case 5588: { // glBlendEquationSeparatei
+ GLuint *buf = (GLuint *) bp; bp += 4;
+ GLenum *modeRGB = (GLenum *) bp; bp += 4;
+ GLenum *modeAlpha = (GLenum *) bp; bp += 4;
+ weglBlendEquationSeparatei(*buf,*modeRGB,*modeAlpha);
+}; break;
+case 5589: { // glBlendFunci
+ GLuint *buf = (GLuint *) bp; bp += 4;
+ GLenum *src = (GLenum *) bp; bp += 4;
+ GLenum *dst = (GLenum *) bp; bp += 4;
+ weglBlendFunci(*buf,*src,*dst);
+}; break;
+case 5590: { // glBlendFuncSeparatei
+ GLuint *buf = (GLuint *) bp; bp += 4;
+ GLenum *srcRGB = (GLenum *) bp; bp += 4;
+ GLenum *dstRGB = (GLenum *) bp; bp += 4;
+ GLenum *srcAlpha = (GLenum *) bp; bp += 4;
+ GLenum *dstAlpha = (GLenum *) bp; bp += 4;
+ weglBlendFuncSeparatei(*buf,*srcRGB,*dstRGB,*srcAlpha,*dstAlpha);
+}; break;
+case 5591: { // glLoadTransposeMatrixfARB
GLfloat * m = (GLfloat *) bp; bp += 64;
weglLoadTransposeMatrixfARB(m);
}; break;
-case 5583: { // glLoadTransposeMatrixdARB
+case 5592: { // glLoadTransposeMatrixdARB
GLdouble * m = (GLdouble *) bp; bp += 128;
weglLoadTransposeMatrixdARB(m);
}; break;
-case 5584: { // glMultTransposeMatrixfARB
+case 5593: { // glMultTransposeMatrixfARB
GLfloat * m = (GLfloat *) bp; bp += 64;
weglMultTransposeMatrixfARB(m);
}; break;
-case 5585: { // glMultTransposeMatrixdARB
+case 5594: { // glMultTransposeMatrixdARB
GLdouble * m = (GLdouble *) bp; bp += 128;
weglMultTransposeMatrixdARB(m);
}; break;
-case 5586: { // glWeightbvARB
+case 5595: { // glWeightbvARB
int * weightsLen = (int *) bp; bp += 4;
GLbyte * weights = (GLbyte *) bp; bp += (8-((*weightsLen*1+4)%8))%8;
weglWeightbvARB(*weightsLen,weights);
}; break;
-case 5587: { // glWeightsvARB
+case 5596: { // glWeightsvARB
int * weightsLen = (int *) bp; bp += 4;
GLshort * weights = (GLshort *) bp; bp += (8-((*weightsLen*2+4)%8))%8;
weglWeightsvARB(*weightsLen,weights);
}; break;
-case 5588: { // glWeightivARB
+case 5597: { // glWeightivARB
int * weightsLen = (int *) bp; bp += 4;
GLint * weights = (GLint *) bp; bp += (8-((*weightsLen*4+4)%8))%8;
weglWeightivARB(*weightsLen,weights);
}; break;
-case 5589: { // glWeightfvARB
+case 5598: { // glWeightfvARB
int * weightsLen = (int *) bp; bp += 4;
GLfloat * weights = (GLfloat *) bp; bp += (8-((*weightsLen*4+4)%8))%8;
weglWeightfvARB(*weightsLen,weights);
}; break;
-case 5590: { // glWeightdvARB
+case 5599: { // glWeightdvARB
int * weightsLen = (int *) bp; bp += 8;
GLdouble * weights = (GLdouble *) bp; bp += (8-((*weightsLen*8+0)%8))%8;
weglWeightdvARB(*weightsLen,weights);
}; break;
-case 5591: { // glWeightubvARB
+case 5600: { // glWeightubvARB
int * weightsLen = (int *) bp; bp += 4;
GLubyte * weights = (GLubyte *) bp; bp += (8-((*weightsLen*1+4)%8))%8;
weglWeightubvARB(*weightsLen,weights);
}; break;
-case 5592: { // glWeightusvARB
+case 5601: { // glWeightusvARB
int * weightsLen = (int *) bp; bp += 4;
GLushort * weights = (GLushort *) bp; bp += (8-((*weightsLen*2+4)%8))%8;
weglWeightusvARB(*weightsLen,weights);
}; break;
-case 5593: { // glWeightuivARB
+case 5602: { // glWeightuivARB
int * weightsLen = (int *) bp; bp += 4;
GLuint * weights = (GLuint *) bp; bp += (8-((*weightsLen*4+4)%8))%8;
weglWeightuivARB(*weightsLen,weights);
}; break;
-case 5594: { // glVertexBlendARB
+case 5603: { // glVertexBlendARB
GLint *count = (GLint *) bp; bp += 4;
weglVertexBlendARB(*count);
}; break;
-case 5595: { // glCurrentPaletteMatrixARB
+case 5604: { // glCurrentPaletteMatrixARB
GLint *index = (GLint *) bp; bp += 4;
weglCurrentPaletteMatrixARB(*index);
}; break;
-case 5596: { // glMatrixIndexubvARB
+case 5605: { // glMatrixIndexubvARB
int * indicesLen = (int *) bp; bp += 4;
GLubyte * indices = (GLubyte *) bp; bp += (8-((*indicesLen*1+4)%8))%8;
weglMatrixIndexubvARB(*indicesLen,indices);
}; break;
-case 5597: { // glMatrixIndexusvARB
+case 5606: { // glMatrixIndexusvARB
int * indicesLen = (int *) bp; bp += 4;
GLushort * indices = (GLushort *) bp; bp += (8-((*indicesLen*2+4)%8))%8;
weglMatrixIndexusvARB(*indicesLen,indices);
}; break;
-case 5598: { // glMatrixIndexuivARB
+case 5607: { // glMatrixIndexuivARB
int * indicesLen = (int *) bp; bp += 4;
GLuint * indices = (GLuint *) bp; bp += (8-((*indicesLen*4+4)%8))%8;
weglMatrixIndexuivARB(*indicesLen,indices);
}; break;
-case 5599: { // glProgramStringARB
+case 5608: { // glProgramStringARB
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLvoid *string = (GLvoid *) bp;
- int stringLen = strlen((char *)string); bp += stringLen+1+((8-((1+stringLen+0)%8))%8);
- weglProgramStringARB(*target,*format,stringLen,string);
+ int stringLen[1] = {strlen((char *)string)}; bp += stringLen[0]+1+((8-((1+stringLen[0]+0)%8))%8);
+ weglProgramStringARB(*target,*format,*stringLen,string);
}; break;
-case 5600: { // glBindProgramARB
+case 5609: { // glBindProgramARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *program = (GLuint *) bp; bp += 4;
weglBindProgramARB(*target,*program);
}; break;
-case 5601: { // glDeleteProgramsARB
+case 5610: { // glDeleteProgramsARB
int * programsLen = (int *) bp; bp += 4;
GLuint * programs = (GLuint *) bp; bp += (8-((*programsLen*4+4)%8))%8;
weglDeleteProgramsARB(*programsLen,programs);
}; break;
-case 5602: { // glGenProgramsARB
+case 5611: { // glGenProgramsARB
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *programs;
programs = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
weglGenProgramsARB(*n,programs);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *n; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) programs[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(programs);
}; break;
-case 5603: { // glProgramEnvParameter4dARB
+case 5612: { // glProgramEnvParameter4dARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
@@ -4599,13 +4585,13 @@ case 5603: { // glProgramEnvParameter4dARB
GLdouble *w = (GLdouble *) bp; bp += 8;
weglProgramEnvParameter4dARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5604: { // glProgramEnvParameter4dvARB
+case 5613: { // glProgramEnvParameter4dvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble * params = (GLdouble *) bp; bp += 32;
weglProgramEnvParameter4dvARB(*target,*index,params);
}; break;
-case 5605: { // glProgramEnvParameter4fARB
+case 5614: { // glProgramEnvParameter4fARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *x = (GLfloat *) bp; bp += 4;
@@ -4614,13 +4600,13 @@ case 5605: { // glProgramEnvParameter4fARB
GLfloat *w = (GLfloat *) bp; bp += 4;
weglProgramEnvParameter4fARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5606: { // glProgramEnvParameter4fvARB
+case 5615: { // glProgramEnvParameter4fvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat * params = (GLfloat *) bp; bp += 16;
weglProgramEnvParameter4fvARB(*target,*index,params);
}; break;
-case 5607: { // glProgramLocalParameter4dARB
+case 5616: { // glProgramLocalParameter4dARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
@@ -4629,13 +4615,13 @@ case 5607: { // glProgramLocalParameter4dARB
GLdouble *w = (GLdouble *) bp; bp += 8;
weglProgramLocalParameter4dARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5608: { // glProgramLocalParameter4dvARB
+case 5617: { // glProgramLocalParameter4dvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble * params = (GLdouble *) bp; bp += 32;
weglProgramLocalParameter4dvARB(*target,*index,params);
}; break;
-case 5609: { // glProgramLocalParameter4fARB
+case 5618: { // glProgramLocalParameter4fARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *x = (GLfloat *) bp; bp += 4;
@@ -4644,19 +4630,19 @@ case 5609: { // glProgramLocalParameter4fARB
GLfloat *w = (GLfloat *) bp; bp += 4;
weglProgramLocalParameter4fARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5610: { // glProgramLocalParameter4fvARB
+case 5619: { // glProgramLocalParameter4fvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat * params = (GLfloat *) bp; bp += 16;
weglProgramLocalParameter4fvARB(*target,*index,params);
}; break;
-case 5611: { // glGetProgramEnvParameterdvARB
+case 5620: { // glGetProgramEnvParameterdvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble params[4] = {0.0,0.0,0.0,0.0};
weglGetProgramEnvParameterdvARB(*target,*index,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble *paramsTmp = params;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -4664,16 +4650,15 @@ case 5611: { // glGetProgramEnvParameterdvARB
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5612: { // glGetProgramEnvParameterfvARB
+case 5621: { // glGetProgramEnvParameterfvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat params[4] = {0.0,0.0,0.0,0.0};
weglGetProgramEnvParameterfvARB(*target,*index,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[4], *paramsTmp = paramsConv;
for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -4682,16 +4667,15 @@ case 5612: { // glGetProgramEnvParameterfvARB
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5613: { // glGetProgramLocalParameterdvARB
+case 5622: { // glGetProgramLocalParameterdvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble params[4] = {0.0,0.0,0.0,0.0};
weglGetProgramLocalParameterdvARB(*target,*index,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble *paramsTmp = params;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -4699,16 +4683,15 @@ case 5613: { // glGetProgramLocalParameterdvARB
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5614: { // glGetProgramLocalParameterfvARB
+case 5623: { // glGetProgramLocalParameterfvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat params[4] = {0.0,0.0,0.0,0.0};
weglGetProgramLocalParameterfvARB(*target,*index,params);
int AP = 0; ErlDrvTermData rt[14];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[4], *paramsTmp = paramsConv;
for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -4717,50 +4700,75 @@ case 5614: { // glGetProgramLocalParameterfvARB
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5615: { // glGetProgramStringARB
+case 5624: { // glGetProgramStringARB
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
- GLvoid *string = (GLvoid *) bins[0]->base;
+ GLvoid *string = (GLvoid *) bins[0];
weglGetProgramStringARB(*target,*pname,string);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5625: { // glGetBufferParameterivARB
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ weglGetBufferParameterivARB(*target,*pname,params);
+ int AP = 0; ErlDrvTermData rt[39];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLint *paramsTmp = params;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5616: { // glDeleteObjectARB
+case 5626: { // glDeleteObjectARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglDeleteObjectARB(obj);
}; break;
-case 5617: { // glGetHandleARB
+case 5627: { // glGetHandleARB
GLenum *pname = (GLenum *) bp; bp += 4;
GLhandleARB result = weglGetHandleARB(*pname);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5618: { // glDetachObjectARB
+case 5628: { // glDetachObjectARB
GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLhandleARB attachedObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglDetachObjectARB(containerObj,attachedObj);
}; break;
-case 5619: { // glCreateShaderObjectARB
+case 5629: { // glCreateShaderObjectARB
GLenum *shaderType = (GLenum *) bp; bp += 4;
GLhandleARB result = weglCreateShaderObjectARB(*shaderType);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5620: { // glShaderSourceARB
+case 5630: { // glShaderSourceARB
GLhandleARB shaderObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
int * stringLen = (int *) bp; bp += 4;
int * stringTotSize = (int *) bp; bp += 4;
@@ -4772,62 +4780,59 @@ case 5620: { // glShaderSourceARB
weglShaderSourceARB(shaderObj,*stringLen,(const GLchar **) string,NULL);
driver_free(string);
}; break;
-case 5621: { // glCompileShaderARB
+case 5631: { // glCompileShaderARB
GLhandleARB shaderObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglCompileShaderARB(shaderObj);
}; break;
-case 5622: { // glCreateProgramObjectARB
+case 5632: { // glCreateProgramObjectARB
GLhandleARB result = weglCreateProgramObjectARB();
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5623: { // glAttachObjectARB
+case 5633: { // glAttachObjectARB
GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglAttachObjectARB(containerObj,obj);
}; break;
-case 5624: { // glLinkProgramARB
+case 5634: { // glLinkProgramARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglLinkProgramARB(programObj);
}; break;
-case 5625: { // glUseProgramObjectARB
+case 5635: { // glUseProgramObjectARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglUseProgramObjectARB(programObj);
}; break;
-case 5626: { // glValidateProgramARB
+case 5636: { // glValidateProgramARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglValidateProgramARB(programObj);
}; break;
-case 5627: { // glGetObjectParameterfvARB
+case 5637: { // glGetObjectParameterfvARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat params[1] = {0.0};
weglGetObjectParameterfvARB(obj,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv = (double) *params;
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) &paramsConv;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5628: { // glGetObjectParameterivARB
+case 5638: { // glGetObjectParameterivARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
weglGetObjectParameterivARB(obj,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5629: { // glGetInfoLogARB
+case 5639: { // glGetInfoLogARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -4835,14 +4840,13 @@ case 5629: { // glGetInfoLogARB
infoLog = (GLchar *) driver_alloc(sizeof(GLchar) * *maxLength);
weglGetInfoLogARB(obj,*maxLength,length,infoLog);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) infoLog; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
-case 5630: { // glGetAttachedObjectsARB
+case 5640: { // glGetAttachedObjectsARB
GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLsizei *maxCount = (GLsizei *) bp; bp += 4;
GLsizei count[1] = {0};
@@ -4851,29 +4855,27 @@ case 5630: { // glGetAttachedObjectsARB
weglGetAttachedObjectsARB(containerObj,*maxCount,count,obj);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*count)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *count; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) obj[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*count)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*count)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*count)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(obj);
}; break;
-case 5631: { // glGetUniformLocationARB
+case 5641: { // glGetUniformLocationARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLchar *name = (GLchar *) bp;
- int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8);
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
GLint result = weglGetUniformLocationARB(programObj,name);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5632: { // glGetActiveUniformARB
+case 5642: { // glGetActiveUniformARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
@@ -4884,23 +4886,22 @@ case 5632: { // glGetActiveUniformARB
name = (GLchar *) driver_alloc(sizeof(GLchar) * *maxLength);
weglGetActiveUniformARB(programObj,*index,*maxLength,length,size,type,name);
int AP = 0; ErlDrvTermData rt[13];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *size;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *type;
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5633: { // glGetUniformfvARB
+case 5643: { // glGetUniformfvARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLint *location = (GLint *) bp; bp += 4;
GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
weglGetUniformfvARB(programObj,*location,params);
int AP = 0; ErlDrvTermData rt[38];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLdouble paramsConv[16], *paramsTmp = paramsConv;
for(int i=0; i < 16; i++) paramsConv[i] = (GLdouble) params[i];
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
@@ -4921,16 +4922,15 @@ case 5633: { // glGetUniformfvARB
rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5634: { // glGetUniformivARB
+case 5644: { // glGetUniformivARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLint *location = (GLint *) bp; bp += 4;
GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
weglGetUniformivARB(programObj,*location,params);
int AP = 0; ErlDrvTermData rt[38];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
GLint *paramsTmp = params;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
@@ -4950,10 +4950,9 @@ case 5634: { // glGetUniformivARB
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5635: { // glGetShaderSourceARB
+case 5645: { // glGetShaderSourceARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -4961,21 +4960,20 @@ case 5635: { // glGetShaderSourceARB
source = (GLchar *) driver_alloc(sizeof(GLchar) * *maxLength);
weglGetShaderSourceARB(obj,*maxLength,length,source);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) source; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(source);
}; break;
-case 5636: { // glBindAttribLocationARB
+case 5646: { // glBindAttribLocationARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLuint *index = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
- int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8);
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
weglBindAttribLocationARB(programObj,*index,name);
}; break;
-case 5637: { // glGetActiveAttribARB
+case 5647: { // glGetActiveAttribARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
@@ -4986,132 +4984,124 @@ case 5637: { // glGetActiveAttribARB
name = (GLchar *) driver_alloc(sizeof(GLchar) * *maxLength);
weglGetActiveAttribARB(programObj,*index,*maxLength,length,size,type,name);
int AP = 0; ErlDrvTermData rt[13];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *size;
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *type;
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5638: { // glGetAttribLocationARB
+case 5648: { // glGetAttribLocationARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLchar *name = (GLchar *) bp;
- int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8);
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
GLint result = weglGetAttribLocationARB(programObj,name);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5639: { // glIsRenderbuffer
+case 5649: { // glIsRenderbuffer
GLuint *renderbuffer = (GLuint *) bp; bp += 4;
GLboolean result = weglIsRenderbuffer(*renderbuffer);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5640: { // glBindRenderbuffer
+case 5650: { // glBindRenderbuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *renderbuffer = (GLuint *) bp; bp += 4;
weglBindRenderbuffer(*target,*renderbuffer);
}; break;
-case 5641: { // glDeleteRenderbuffers
+case 5651: { // glDeleteRenderbuffers
int * renderbuffersLen = (int *) bp; bp += 4;
GLuint * renderbuffers = (GLuint *) bp; bp += (8-((*renderbuffersLen*4+4)%8))%8;
weglDeleteRenderbuffers(*renderbuffersLen,renderbuffers);
}; break;
-case 5642: { // glGenRenderbuffers
+case 5652: { // glGenRenderbuffers
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *renderbuffers;
renderbuffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
weglGenRenderbuffers(*n,renderbuffers);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *n; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) renderbuffers[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(renderbuffers);
}; break;
-case 5643: { // glRenderbufferStorage
+case 5653: { // glRenderbufferStorage
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
GLsizei *width = (GLsizei *) bp; bp += 4;
GLsizei *height = (GLsizei *) bp; bp += 4;
weglRenderbufferStorage(*target,*internalformat,*width,*height);
}; break;
-case 5644: { // glGetRenderbufferParameteriv
+case 5654: { // glGetRenderbufferParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
weglGetRenderbufferParameteriv(*target,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5645: { // glIsFramebuffer
+case 5655: { // glIsFramebuffer
GLuint *framebuffer = (GLuint *) bp; bp += 4;
GLboolean result = weglIsFramebuffer(*framebuffer);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5646: { // glBindFramebuffer
+case 5656: { // glBindFramebuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *framebuffer = (GLuint *) bp; bp += 4;
weglBindFramebuffer(*target,*framebuffer);
}; break;
-case 5647: { // glDeleteFramebuffers
+case 5657: { // glDeleteFramebuffers
int * framebuffersLen = (int *) bp; bp += 4;
GLuint * framebuffers = (GLuint *) bp; bp += (8-((*framebuffersLen*4+4)%8))%8;
weglDeleteFramebuffers(*framebuffersLen,framebuffers);
}; break;
-case 5648: { // glGenFramebuffers
+case 5658: { // glGenFramebuffers
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *framebuffers;
framebuffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
weglGenFramebuffers(*n,framebuffers);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *n; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) framebuffers[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(framebuffers);
}; break;
-case 5649: { // glCheckFramebufferStatus
+case 5659: { // glCheckFramebufferStatus
GLenum *target = (GLenum *) bp; bp += 4;
GLenum result = weglCheckFramebufferStatus(*target);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5650: { // glFramebufferTexture1D
+case 5660: { // glFramebufferTexture1D
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *textarget = (GLenum *) bp; bp += 4;
@@ -5119,7 +5109,7 @@ case 5650: { // glFramebufferTexture1D
GLint *level = (GLint *) bp; bp += 4;
weglFramebufferTexture1D(*target,*attachment,*textarget,*texture,*level);
}; break;
-case 5651: { // glFramebufferTexture2D
+case 5661: { // glFramebufferTexture2D
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *textarget = (GLenum *) bp; bp += 4;
@@ -5127,7 +5117,7 @@ case 5651: { // glFramebufferTexture2D
GLint *level = (GLint *) bp; bp += 4;
weglFramebufferTexture2D(*target,*attachment,*textarget,*texture,*level);
}; break;
-case 5652: { // glFramebufferTexture3D
+case 5662: { // glFramebufferTexture3D
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *textarget = (GLenum *) bp; bp += 4;
@@ -5136,31 +5126,30 @@ case 5652: { // glFramebufferTexture3D
GLint *zoffset = (GLint *) bp; bp += 4;
weglFramebufferTexture3D(*target,*attachment,*textarget,*texture,*level,*zoffset);
}; break;
-case 5653: { // glFramebufferRenderbuffer
+case 5663: { // glFramebufferRenderbuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *renderbuffertarget = (GLenum *) bp; bp += 4;
GLuint *renderbuffer = (GLuint *) bp; bp += 4;
weglFramebufferRenderbuffer(*target,*attachment,*renderbuffertarget,*renderbuffer);
}; break;
-case 5654: { // glGetFramebufferAttachmentParameteriv
+case 5664: { // glGetFramebufferAttachmentParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
weglGetFramebufferAttachmentParameteriv(*target,*attachment,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5655: { // glGenerateMipmap
+case 5665: { // glGenerateMipmap
GLenum *target = (GLenum *) bp; bp += 4;
weglGenerateMipmap(*target);
}; break;
-case 5656: { // glBlitFramebuffer
+case 5666: { // glBlitFramebuffer
GLint *srcX0 = (GLint *) bp; bp += 4;
GLint *srcY0 = (GLint *) bp; bp += 4;
GLint *srcX1 = (GLint *) bp; bp += 4;
@@ -5173,7 +5162,7 @@ case 5656: { // glBlitFramebuffer
GLenum *filter = (GLenum *) bp; bp += 4;
weglBlitFramebuffer(*srcX0,*srcY0,*srcX1,*srcY1,*dstX0,*dstY0,*dstX1,*dstY1,*mask,*filter);
}; break;
-case 5657: { // glRenderbufferStorageMultisample
+case 5667: { // glRenderbufferStorageMultisample
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *samples = (GLsizei *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
@@ -5181,7 +5170,7 @@ case 5657: { // glRenderbufferStorageMultisample
GLsizei *height = (GLsizei *) bp; bp += 4;
weglRenderbufferStorageMultisample(*target,*samples,*internalformat,*width,*height);
}; break;
-case 5658: { // glFramebufferTextureLayer
+case 5668: { // glFramebufferTextureLayer
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLuint *texture = (GLuint *) bp; bp += 4;
@@ -5189,20 +5178,7 @@ case 5658: { // glFramebufferTextureLayer
GLint *layer = (GLint *) bp; bp += 4;
weglFramebufferTextureLayer(*target,*attachment,*texture,*level,*layer);
}; break;
-case 5659: { // glProgramParameteriARB
- GLuint *program = (GLuint *) bp; bp += 4;
- GLenum *pname = (GLenum *) bp; bp += 4;
- GLint *value = (GLint *) bp; bp += 4;
- weglProgramParameteriARB(*program,*pname,*value);
-}; break;
-case 5660: { // glFramebufferTextureARB
- GLenum *target = (GLenum *) bp; bp += 4;
- GLenum *attachment = (GLenum *) bp; bp += 4;
- GLuint *texture = (GLuint *) bp; bp += 4;
- GLint *level = (GLint *) bp; bp += 4;
- weglFramebufferTextureARB(*target,*attachment,*texture,*level);
-}; break;
-case 5661: { // glFramebufferTextureFaceARB
+case 5669: { // glFramebufferTextureFaceARB
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLuint *texture = (GLuint *) bp; bp += 4;
@@ -5210,55 +5186,48 @@ case 5661: { // glFramebufferTextureFaceARB
GLenum *face = (GLenum *) bp; bp += 4;
weglFramebufferTextureFaceARB(*target,*attachment,*texture,*level,*face);
}; break;
-case 5662: { // glVertexAttribDivisorARB
- GLuint *index = (GLuint *) bp; bp += 4;
- GLuint *divisor = (GLuint *) bp; bp += 4;
- weglVertexAttribDivisorARB(*index,*divisor);
-}; break;
-case 5663: { // glFlushMappedBufferRange
+case 5670: { // glFlushMappedBufferRange
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
GLsizeiptr length = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
weglFlushMappedBufferRange(*target,offset,length);
}; break;
-case 5664: { // glBindVertexArray
+case 5671: { // glBindVertexArray
GLuint *array = (GLuint *) bp; bp += 4;
weglBindVertexArray(*array);
}; break;
-case 5665: { // glDeleteVertexArrays
+case 5672: { // glDeleteVertexArrays
int * arraysLen = (int *) bp; bp += 4;
GLuint * arrays = (GLuint *) bp; bp += (8-((*arraysLen*4+4)%8))%8;
weglDeleteVertexArrays(*arraysLen,arrays);
}; break;
-case 5666: { // glGenVertexArrays
+case 5673: { // glGenVertexArrays
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *arrays;
arrays = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
weglGenVertexArrays(*n,arrays);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *n; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) arrays[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(arrays);
}; break;
-case 5667: { // glIsVertexArray
+case 5674: { // glIsVertexArray
GLuint *array = (GLuint *) bp; bp += 4;
GLboolean result = weglIsVertexArray(*array);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5668: { // glGetUniformIndices
+case 5675: { // glGetUniformIndices
GLuint *program = (GLuint *) bp; bp += 4;
int * uniformNamesLen = (int *) bp; bp += 4;
int * uniformNamesTotSize = (int *) bp; bp += 4;
@@ -5272,18 +5241,17 @@ case 5668: { // glGetUniformIndices
weglGetUniformIndices(*program,*uniformNamesLen,(const GLchar **) uniformNames,uniformIndices);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*uniformNamesLen)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *uniformNamesLen; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) uniformIndices[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*uniformNamesLen)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*uniformNamesLen)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*uniformNamesLen)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(uniformIndices);
driver_free(uniformNames);
}; break;
-case 5669: { // glGetActiveUniformsiv
+case 5676: { // glGetActiveUniformsiv
GLuint *program = (GLuint *) bp; bp += 4;
int * uniformIndicesLen = (int *) bp; bp += 4;
GLuint * uniformIndices = (GLuint *) bp; bp += (8-((*uniformIndicesLen*4+0)%8))%8;
@@ -5293,17 +5261,16 @@ case 5669: { // glGetActiveUniformsiv
weglGetActiveUniformsiv(*program,*uniformIndicesLen,uniformIndices,*pname,params);
int AP = 0; ErlDrvTermData *rt;
rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*uniformIndicesLen)*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
for(int i=0; i < *uniformIndicesLen; i++) {
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) params[i];}
rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*uniformIndicesLen)+1;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 + (*uniformIndicesLen)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*uniformIndicesLen)*2);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(rt);
driver_free(params);
}; break;
-case 5670: { // glGetActiveUniformName
+case 5677: { // glGetActiveUniformName
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformIndex = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -5312,38 +5279,36 @@ case 5670: { // glGetActiveUniformName
uniformName = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize);
weglGetActiveUniformName(*program,*uniformIndex,*bufSize,length,uniformName);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) uniformName; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(uniformName);
}; break;
-case 5671: { // glGetUniformBlockIndex
+case 5678: { // glGetUniformBlockIndex
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *uniformBlockName = (GLchar *) bp;
- int uniformBlockNameLen = strlen((char *)uniformBlockName); bp += uniformBlockNameLen+1+((8-((1+uniformBlockNameLen+4)%8))%8);
+ int uniformBlockNameLen[1] = {strlen((char *)uniformBlockName)}; bp += uniformBlockNameLen[0]+1+((8-((1+uniformBlockNameLen[0]+4)%8))%8);
GLuint result = weglGetUniformBlockIndex(*program,uniformBlockName);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5672: { // glGetActiveUniformBlockiv
+case 5679: { // glGetActiveUniformBlockiv
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
- GLint *params = (GLint *) bins[0]->base;
+ GLint *params = (GLint *) bins[0];
weglGetActiveUniformBlockiv(*program,*uniformBlockIndex,*pname,params);
int AP = 0; ErlDrvTermData rt[6];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok");
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
}; break;
-case 5673: { // glGetActiveUniformBlockName
+case 5680: { // glGetActiveUniformBlockName
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -5352,20 +5317,19 @@ case 5673: { // glGetActiveUniformBlockName
uniformBlockName = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize);
weglGetActiveUniformBlockName(*program,*uniformBlockIndex,*bufSize,length,uniformBlockName);
int AP = 0; ErlDrvTermData rt[7];
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) uniformBlockName; rt[AP++] = *length;
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
- if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7);
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
+ driver_send_term(port,caller,rt,AP);
driver_free(uniformBlockName);
}; break;
-case 5674: { // glUniformBlockBinding
+case 5681: { // glUniformBlockBinding
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4;
GLuint *uniformBlockBinding = (GLuint *) bp; bp += 4;
weglUniformBlockBinding(*program,*uniformBlockIndex,*uniformBlockBinding);
}; break;
-case 5675: { // glCopyBufferSubData
+case 5682: { // glCopyBufferSubData
GLenum *readTarget = (GLenum *) bp; bp += 4;
GLenum *writeTarget = (GLenum *) bp; bp += 4;
GLintptr readOffset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
@@ -5373,34 +5337,1633 @@ case 5675: { // glCopyBufferSubData
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
weglCopyBufferSubData(*readTarget,*writeTarget,readOffset,writeOffset,size);
}; break;
-case 5676: { // glResizeBuffersMESA
+case 5683: { // glDrawElementsBaseVertex
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLsizei *count = (GLsizei *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLvoid *indices = (GLvoid *) * (int *) bp; bp += 4;
+ GLint *basevertex = (GLint *) bp; bp += 4;
+ weglDrawElementsBaseVertex(*mode,*count,*type,indices,*basevertex);
+}; break;
+case 5684: { // glDrawElementsBaseVertex
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLsizei *count = (GLsizei *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLvoid *indices = (GLvoid *) bins[0];
+ GLint *basevertex = (GLint *) bp; bp += 4;
+ weglDrawElementsBaseVertex(*mode,*count,*type,indices,*basevertex);
+}; break;
+case 5685: { // glDrawRangeElementsBaseVertex
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLuint *start = (GLuint *) bp; bp += 4;
+ GLuint *end = (GLuint *) bp; bp += 4;
+ GLsizei *count = (GLsizei *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLvoid *indices = (GLvoid *) * (int *) bp; bp += 4;
+ GLint *basevertex = (GLint *) bp; bp += 4;
+ weglDrawRangeElementsBaseVertex(*mode,*start,*end,*count,*type,indices,*basevertex);
+}; break;
+case 5686: { // glDrawRangeElementsBaseVertex
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLuint *start = (GLuint *) bp; bp += 4;
+ GLuint *end = (GLuint *) bp; bp += 4;
+ GLsizei *count = (GLsizei *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLvoid *indices = (GLvoid *) bins[0];
+ GLint *basevertex = (GLint *) bp; bp += 4;
+ weglDrawRangeElementsBaseVertex(*mode,*start,*end,*count,*type,indices,*basevertex);
+}; break;
+case 5687: { // glDrawElementsInstancedBaseVertex
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLsizei *count = (GLsizei *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLvoid *indices = (GLvoid *) * (int *) bp; bp += 4;
+ GLsizei *primcount = (GLsizei *) bp; bp += 4;
+ GLint *basevertex = (GLint *) bp; bp += 4;
+ weglDrawElementsInstancedBaseVertex(*mode,*count,*type,indices,*primcount,*basevertex);
+}; break;
+case 5688: { // glDrawElementsInstancedBaseVertex
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLsizei *count = (GLsizei *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLvoid *indices = (GLvoid *) bins[0];
+ GLsizei *primcount = (GLsizei *) bp; bp += 4;
+ GLint *basevertex = (GLint *) bp; bp += 4;
+ weglDrawElementsInstancedBaseVertex(*mode,*count,*type,indices,*primcount,*basevertex);
+}; break;
+case 5689: { // glProvokingVertex
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ weglProvokingVertex(*mode);
+}; break;
+case 5690: { // glFenceSync
+ GLenum *condition = (GLenum *) bp; bp += 4;
+ GLbitfield *flags = (GLbitfield *) bp; bp += 4;
+ GLsync result = weglFenceSync(*condition,*flags);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5691: { // glIsSync
+ GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
+ GLboolean result = weglIsSync(sync);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5692: { // glDeleteSync
+ GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
+ weglDeleteSync(sync);
+}; break;
+case 5693: { // glClientWaitSync
+ GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
+ GLbitfield *flags = (GLbitfield *) bp; bp += 4;
+ bp += 4;
+ GLuint64 timeout = (GLuint64) * (GLuint64EXT *) bp; bp += 8;
+ GLenum result = weglClientWaitSync(sync,*flags,timeout);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5694: { // glWaitSync
+ GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
+ GLbitfield *flags = (GLbitfield *) bp; bp += 4;
+ bp += 4;
+ GLuint64 timeout = (GLuint64) * (GLuint64EXT *) bp; bp += 8;
+ weglWaitSync(sync,*flags,timeout);
+}; break;
+case 5695: { // glGetInteger64v
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint64 params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ weglGetInteger64v(*pname,params);
+ int AP = 0; ErlDrvTermData rt[39];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLint64 *paramsTmp = params;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5696: { // glGetSynciv
+ GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLsizei *bufSize = (GLsizei *) bp; bp += 4;
+ GLsizei length[1] = {0};
+ GLint *values;
+ values = (GLint *) driver_alloc(sizeof(GLint) * *bufSize);
+ weglGetSynciv(sync,*pname,*bufSize,length,values);
+ int AP = 0; ErlDrvTermData *rt;
+ rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*length)*2));
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ for(int i=0; i < *length; i++) {
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) values[i];}
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*length)+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free(rt);
+ driver_free(values);
+}; break;
+case 5697: { // glTexImage2DMultisample
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLsizei *samples = (GLsizei *) bp; bp += 4;
+ GLint *internalformat = (GLint *) bp; bp += 4;
+ GLsizei *width = (GLsizei *) bp; bp += 4;
+ GLsizei *height = (GLsizei *) bp; bp += 4;
+ GLboolean *fixedsamplelocations = (GLboolean *) bp; bp += 1;
+ weglTexImage2DMultisample(*target,*samples,*internalformat,*width,*height,*fixedsamplelocations);
+}; break;
+case 5698: { // glTexImage3DMultisample
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLsizei *samples = (GLsizei *) bp; bp += 4;
+ GLint *internalformat = (GLint *) bp; bp += 4;
+ GLsizei *width = (GLsizei *) bp; bp += 4;
+ GLsizei *height = (GLsizei *) bp; bp += 4;
+ GLsizei *depth = (GLsizei *) bp; bp += 4;
+ GLboolean *fixedsamplelocations = (GLboolean *) bp; bp += 1;
+ weglTexImage3DMultisample(*target,*samples,*internalformat,*width,*height,*depth,*fixedsamplelocations);
+}; break;
+case 5699: { // glGetMultisamplefv
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLfloat val[2] = {0.0,0.0};
+ weglGetMultisamplefv(*pname,*index,val);
+ int AP = 0; ErlDrvTermData rt[10];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLdouble valConv[2], *valTmp = valConv;
+ for(int i=0; i < 2; i++) valConv[i] = (GLdouble) val[i];
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) valTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) valTmp++;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5700: { // glSampleMaski
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLbitfield *mask = (GLbitfield *) bp; bp += 4;
+ weglSampleMaski(*index,*mask);
+}; break;
+case 5701: { // glNamedStringARB
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLchar *name = (GLchar *) bp;
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
+ GLchar *string = (GLchar *) bp;
+ int stringLen[1] = {strlen((char *)string)}; bp += stringLen[0]+1+((8-((1+stringLen[0]+0)%8))%8);
+ weglNamedStringARB(*type,*nameLen,name,*stringLen,string);
+}; break;
+case 5702: { // glDeleteNamedStringARB
+ GLchar *name = (GLchar *) bp;
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
+ weglDeleteNamedStringARB(*nameLen,name);
+}; break;
+case 5703: { // glCompileShaderIncludeARB
+ GLuint *shader = (GLuint *) bp; bp += 4;
+ int * pathLen = (int *) bp; bp += 4;
+ int * pathTotSize = (int *) bp; bp += 4;
+ GLchar **path;
+ path = (GLchar **) driver_alloc(sizeof(GLchar *) * *pathLen);
+ for(int i=0;i<*pathLen;i++) {
+ path[i] = (GLchar *) bp; bp += 1+strlen(bp);};
+ bp += (8 - ((0 + *pathTotSize) % 8)) % 8;
+ weglCompileShaderIncludeARB(*shader,*pathLen,(const GLchar **) path,NULL);
+ driver_free(path);
+}; break;
+case 5704: { // glIsNamedStringARB
+ GLchar *name = (GLchar *) bp;
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
+ GLboolean result = weglIsNamedStringARB(*nameLen,name);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5705: { // glGetNamedStringARB
+ GLchar *name = (GLchar *) bp;
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
+ GLsizei *bufSize = (GLsizei *) bp; bp += 4;
+ GLint stringlen[1] = {0};
+ GLchar *string;
+ string = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize);
+ weglGetNamedStringARB(*nameLen,name,*bufSize,stringlen,string);
+ int AP = 0; ErlDrvTermData rt[7];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) string; rt[AP++] = *stringlen;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free(string);
+}; break;
+case 5706: { // glGetNamedStringivARB
+ GLchar *name = (GLchar *) bp;
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint params[1] = {0};
+ weglGetNamedStringivARB(*nameLen,name,*pname,params);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5707: { // glBindFragDataLocationIndexed
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLuint *colorNumber = (GLuint *) bp; bp += 4;
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLchar *name = (GLchar *) bp;
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
+ weglBindFragDataLocationIndexed(*program,*colorNumber,*index,name);
+}; break;
+case 5708: { // glGetFragDataIndex
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLchar *name = (GLchar *) bp;
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
+ GLint result = weglGetFragDataIndex(*program,name);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5709: { // glGenSamplers
+ GLsizei *count = (GLsizei *) bp; bp += 4;
+ GLuint *samplers;
+ samplers = (GLuint *) driver_alloc(sizeof(GLuint) * *count);
+ weglGenSamplers(*count,samplers);
+ int AP = 0; ErlDrvTermData *rt;
+ rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*count)*2));
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ for(int i=0; i < *count; i++) {
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) samplers[i];}
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*count)+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free(rt);
+ driver_free(samplers);
+}; break;
+case 5710: { // glDeleteSamplers
+ int * samplersLen = (int *) bp; bp += 4;
+ GLuint * samplers = (GLuint *) bp; bp += (8-((*samplersLen*4+4)%8))%8;
+ weglDeleteSamplers(*samplersLen,samplers);
+}; break;
+case 5711: { // glIsSampler
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLboolean result = weglIsSampler(*sampler);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5712: { // glBindSampler
+ GLuint *unit = (GLuint *) bp; bp += 4;
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ weglBindSampler(*unit,*sampler);
+}; break;
+case 5713: { // glSamplerParameteri
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint *param = (GLint *) bp; bp += 4;
+ weglSamplerParameteri(*sampler,*pname,*param);
+}; break;
+case 5714: { // glSamplerParameteriv
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ int * paramLen = (int *) bp; bp += 4;
+ GLint * param = (GLint *) bp; bp += (8-((*paramLen*4+4)%8))%8;
+ weglSamplerParameteriv(*sampler,*pname,param);
+}; break;
+case 5715: { // glSamplerParameterf
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLfloat *param = (GLfloat *) bp; bp += 4;
+ weglSamplerParameterf(*sampler,*pname,*param);
+}; break;
+case 5716: { // glSamplerParameterfv
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ int * paramLen = (int *) bp; bp += 4;
+ GLfloat * param = (GLfloat *) bp; bp += (8-((*paramLen*4+4)%8))%8;
+ weglSamplerParameterfv(*sampler,*pname,param);
+}; break;
+case 5717: { // glSamplerParameterIiv
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ int * paramLen = (int *) bp; bp += 4;
+ GLint * param = (GLint *) bp; bp += (8-((*paramLen*4+4)%8))%8;
+ weglSamplerParameterIiv(*sampler,*pname,param);
+}; break;
+case 5718: { // glSamplerParameterIuiv
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ int * paramLen = (int *) bp; bp += 4;
+ GLuint * param = (GLuint *) bp; bp += (8-((*paramLen*4+4)%8))%8;
+ weglSamplerParameterIuiv(*sampler,*pname,param);
+}; break;
+case 5719: { // glGetSamplerParameteriv
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint params[4] = {0,0,0,0};
+ weglGetSamplerParameteriv(*sampler,*pname,params);
+ int AP = 0; ErlDrvTermData rt[15];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLint *paramsTmp = params;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 4+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5720: { // glGetSamplerParameterIiv
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint params[4] = {0,0,0,0};
+ weglGetSamplerParameterIiv(*sampler,*pname,params);
+ int AP = 0; ErlDrvTermData rt[15];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLint *paramsTmp = params;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 4+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5721: { // glGetSamplerParameterfv
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLfloat params[4] = {0.0,0.0,0.0,0.0};
+ weglGetSamplerParameterfv(*sampler,*pname,params);
+ int AP = 0; ErlDrvTermData rt[15];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLdouble paramsConv[4], *paramsTmp = paramsConv;
+ for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i];
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 4+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5722: { // glGetSamplerParameterIuiv
+ GLuint *sampler = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLuint params[4] = {0,0,0,0};
+ weglGetSamplerParameterIuiv(*sampler,*pname,params);
+ int AP = 0; ErlDrvTermData rt[15];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLuint *paramsTmp = params;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 4+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5723: { // glQueryCounter
+ GLuint *id = (GLuint *) bp; bp += 4;
+ GLenum *target = (GLenum *) bp; bp += 4;
+ weglQueryCounter(*id,*target);
+}; break;
+case 5724: { // glGetQueryObjecti64v
+ GLuint *id = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint64 params[1] = {0};
+ weglGetQueryObjecti64v(*id,*pname,params);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5725: { // glGetQueryObjectui64v
+ GLuint *id = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLuint64 params[1] = {0};
+ weglGetQueryObjectui64v(*id,*pname,params);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5726: { // glDrawArraysIndirect
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLvoid *indirect = (GLvoid *) * (int *) bp; bp += 4;
+ weglDrawArraysIndirect(*mode,indirect);
+}; break;
+case 5727: { // glDrawArraysIndirect
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLvoid *indirect = (GLvoid *) bins[0];
+ weglDrawArraysIndirect(*mode,indirect);
+}; break;
+case 5728: { // glDrawElementsIndirect
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLvoid *indirect = (GLvoid *) * (int *) bp; bp += 4;
+ weglDrawElementsIndirect(*mode,*type,indirect);
+}; break;
+case 5729: { // glDrawElementsIndirect
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLvoid *indirect = (GLvoid *) bins[0];
+ weglDrawElementsIndirect(*mode,*type,indirect);
+}; break;
+case 5730: { // glUniform1d
+ GLint *location = (GLint *) bp; bp += 4;
+ bp += 4;
+ GLdouble *x = (GLdouble *) bp; bp += 8;
+ weglUniform1d(*location,*x);
+}; break;
+case 5731: { // glUniform2d
+ GLint *location = (GLint *) bp; bp += 4;
+ bp += 4;
+ GLdouble *x = (GLdouble *) bp; bp += 8;
+ GLdouble *y = (GLdouble *) bp; bp += 8;
+ weglUniform2d(*location,*x,*y);
+}; break;
+case 5732: { // glUniform3d
+ GLint *location = (GLint *) bp; bp += 4;
+ bp += 4;
+ GLdouble *x = (GLdouble *) bp; bp += 8;
+ GLdouble *y = (GLdouble *) bp; bp += 8;
+ GLdouble *z = (GLdouble *) bp; bp += 8;
+ weglUniform3d(*location,*x,*y,*z);
+}; break;
+case 5733: { // glUniform4d
+ GLint *location = (GLint *) bp; bp += 4;
+ bp += 4;
+ GLdouble *x = (GLdouble *) bp; bp += 8;
+ GLdouble *y = (GLdouble *) bp; bp += 8;
+ GLdouble *z = (GLdouble *) bp; bp += 8;
+ GLdouble *w = (GLdouble *) bp; bp += 8;
+ weglUniform4d(*location,*x,*y,*z,*w);
+}; break;
+case 5734: { // glUniform1dv
+ GLint *location = (GLint *) bp; bp += 4;
+ bp += 4;
+ int * valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += (8-((*valueLen*8+0)%8))%8;
+ weglUniform1dv(*location,*valueLen,value);
+}; break;
+case 5735: { // glUniform2dv
+ GLint *location = (GLint *) bp; bp += 4;
+ bp += 4;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*16;
+ weglUniform2dv(*location,*valueLen,value);
+}; break;
+case 5736: { // glUniform3dv
+ GLint *location = (GLint *) bp; bp += 4;
+ bp += 4;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*24;
+ weglUniform3dv(*location,*valueLen,value);
+}; break;
+case 5737: { // glUniform4dv
+ GLint *location = (GLint *) bp; bp += 4;
+ bp += 4;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*32;
+ weglUniform4dv(*location,*valueLen,value);
+}; break;
+case 5738: { // glUniformMatrix2dv
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*32;
+ weglUniformMatrix2dv(*location,*valueLen,*transpose,value);
+}; break;
+case 5739: { // glUniformMatrix3dv
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*72;
+ weglUniformMatrix3dv(*location,*valueLen,*transpose,value);
+}; break;
+case 5740: { // glUniformMatrix4dv
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*128;
+ weglUniformMatrix4dv(*location,*valueLen,*transpose,value);
+}; break;
+case 5741: { // glUniformMatrix2x3dv
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
+ weglUniformMatrix2x3dv(*location,*valueLen,*transpose,value);
+}; break;
+case 5742: { // glUniformMatrix2x4dv
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
+ weglUniformMatrix2x4dv(*location,*valueLen,*transpose,value);
+}; break;
+case 5743: { // glUniformMatrix3x2dv
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
+ weglUniformMatrix3x2dv(*location,*valueLen,*transpose,value);
+}; break;
+case 5744: { // glUniformMatrix3x4dv
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
+ weglUniformMatrix3x4dv(*location,*valueLen,*transpose,value);
+}; break;
+case 5745: { // glUniformMatrix4x2dv
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
+ weglUniformMatrix4x2dv(*location,*valueLen,*transpose,value);
+}; break;
+case 5746: { // glUniformMatrix4x3dv
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
+ weglUniformMatrix4x3dv(*location,*valueLen,*transpose,value);
+}; break;
+case 5747: { // glGetUniformdv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLdouble params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
+ weglGetUniformdv(*program,*location,params);
+ int AP = 0; ErlDrvTermData rt[38];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLdouble *paramsTmp = params;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5748: { // glGetSubroutineUniformLocation
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLenum *shadertype = (GLenum *) bp; bp += 4;
+ GLchar *name = (GLchar *) bp;
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
+ GLint result = weglGetSubroutineUniformLocation(*program,*shadertype,name);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5749: { // glGetSubroutineIndex
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLenum *shadertype = (GLenum *) bp; bp += 4;
+ GLchar *name = (GLchar *) bp;
+ int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
+ GLuint result = weglGetSubroutineIndex(*program,*shadertype,name);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5750: { // glGetActiveSubroutineUniformName
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLenum *shadertype = (GLenum *) bp; bp += 4;
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLsizei *bufsize = (GLsizei *) bp; bp += 4;
+ GLsizei length[1] = {0};
+ GLchar *name;
+ name = (GLchar *) driver_alloc(sizeof(GLchar) * *bufsize);
+ weglGetActiveSubroutineUniformName(*program,*shadertype,*index,*bufsize,length,name);
+ int AP = 0; ErlDrvTermData rt[7];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free(name);
+}; break;
+case 5751: { // glGetActiveSubroutineName
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLenum *shadertype = (GLenum *) bp; bp += 4;
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLsizei *bufsize = (GLsizei *) bp; bp += 4;
+ GLsizei length[1] = {0};
+ GLchar *name;
+ name = (GLchar *) driver_alloc(sizeof(GLchar) * *bufsize);
+ weglGetActiveSubroutineName(*program,*shadertype,*index,*bufsize,length,name);
+ int AP = 0; ErlDrvTermData rt[7];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free(name);
+}; break;
+case 5752: { // glUniformSubroutinesuiv
+ GLenum *shadertype = (GLenum *) bp; bp += 4;
+ int * indicesLen = (int *) bp; bp += 4;
+ GLuint * indices = (GLuint *) bp; bp += (8-((*indicesLen*4+0)%8))%8;
+ weglUniformSubroutinesuiv(*shadertype,*indicesLen,indices);
+}; break;
+case 5753: { // glGetUniformSubroutineuiv
+ GLenum *shadertype = (GLenum *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLuint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ weglGetUniformSubroutineuiv(*shadertype,*location,params);
+ int AP = 0; ErlDrvTermData rt[38];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLuint *paramsTmp = params;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5754: { // glGetProgramStageiv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLenum *shadertype = (GLenum *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint values[1] = {0};
+ weglGetProgramStageiv(*program,*shadertype,*pname,values);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *values;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5755: { // glPatchParameteri
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint *value = (GLint *) bp; bp += 4;
+ weglPatchParameteri(*pname,*value);
+}; break;
+case 5756: { // glPatchParameterfv
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ int * valuesLen = (int *) bp; bp += 4;
+ GLfloat * values = (GLfloat *) bp; bp += (8-((*valuesLen*4+0)%8))%8;
+ weglPatchParameterfv(*pname,values);
+}; break;
+case 5757: { // glBindTransformFeedback
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLuint *id = (GLuint *) bp; bp += 4;
+ weglBindTransformFeedback(*target,*id);
+}; break;
+case 5758: { // glDeleteTransformFeedbacks
+ int * idsLen = (int *) bp; bp += 4;
+ GLuint * ids = (GLuint *) bp; bp += (8-((*idsLen*4+4)%8))%8;
+ weglDeleteTransformFeedbacks(*idsLen,ids);
+}; break;
+case 5759: { // glGenTransformFeedbacks
+ GLsizei *n = (GLsizei *) bp; bp += 4;
+ GLuint *ids;
+ ids = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
+ weglGenTransformFeedbacks(*n,ids);
+ int AP = 0; ErlDrvTermData *rt;
+ rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2));
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ for(int i=0; i < *n; i++) {
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ids[i];}
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free(rt);
+ driver_free(ids);
+}; break;
+case 5760: { // glIsTransformFeedback
+ GLuint *id = (GLuint *) bp; bp += 4;
+ GLboolean result = weglIsTransformFeedback(*id);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5761: { // glPauseTransformFeedback
+ weglPauseTransformFeedback();
+}; break;
+case 5762: { // glResumeTransformFeedback
+ weglResumeTransformFeedback();
+}; break;
+case 5763: { // glDrawTransformFeedback
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLuint *id = (GLuint *) bp; bp += 4;
+ weglDrawTransformFeedback(*mode,*id);
+}; break;
+case 5764: { // glDrawTransformFeedbackStream
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLuint *id = (GLuint *) bp; bp += 4;
+ GLuint *stream = (GLuint *) bp; bp += 4;
+ weglDrawTransformFeedbackStream(*mode,*id,*stream);
+}; break;
+case 5765: { // glBeginQueryIndexed
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLuint *id = (GLuint *) bp; bp += 4;
+ weglBeginQueryIndexed(*target,*index,*id);
+}; break;
+case 5766: { // glEndQueryIndexed
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLuint *index = (GLuint *) bp; bp += 4;
+ weglEndQueryIndexed(*target,*index);
+}; break;
+case 5767: { // glGetQueryIndexediv
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint params[1] = {0};
+ weglGetQueryIndexediv(*target,*index,*pname,params);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5768: { // glReleaseShaderCompiler
+ weglReleaseShaderCompiler();
+}; break;
+case 5769: { // glShaderBinary
+ int * shadersLen = (int *) bp; bp += 4;
+ GLuint * shaders = (GLuint *) bp; bp += (8-((*shadersLen*4+4)%8))%8;
+ GLenum *binaryformat = (GLenum *) bp; bp += 4;
+ GLvoid *binary = (GLvoid *) bins[0];
+ GLsizei binary_size = bins_sz[0];
+ weglShaderBinary(*shadersLen,shaders,*binaryformat,binary,binary_size);
+}; break;
+case 5770: { // glGetShaderPrecisionFormat
+ GLenum *shadertype = (GLenum *) bp; bp += 4;
+ GLenum *precisiontype = (GLenum *) bp; bp += 4;
+ GLint range[2] = {0,0};
+ GLint precision[1] = {0};
+ weglGetShaderPrecisionFormat(*shadertype,*precisiontype,range,precision);
+ int AP = 0; ErlDrvTermData rt[14];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLint *rangeTmp = range;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *rangeTmp++;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *rangeTmp++;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *precision;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5771: { // glDepthRangef
+ GLclampf *n = (GLclampf *) bp; bp += 4;
+ GLclampf *f = (GLclampf *) bp; bp += 4;
+ weglDepthRangef(*n,*f);
+}; break;
+case 5772: { // glClearDepthf
+ GLclampf *d = (GLclampf *) bp; bp += 4;
+ weglClearDepthf(*d);
+}; break;
+case 5773: { // glGetProgramBinary
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLsizei *bufSize = (GLsizei *) bp; bp += 4;
+ GLsizei length[1] = {0};
+ GLenum binaryFormat[1] = {0};
+ ErlDrvBinary *binary = driver_alloc_binary(*bufSize);
+ weglGetProgramBinary(*program,*bufSize,length,binaryFormat,(GLvoid*) binary->orig_bytes);
+ int AP = 0; ErlDrvTermData rt[12];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *binaryFormat;
+ rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) binary; rt[AP++] = *length; rt[AP++] = 0;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free_binary(binary);
+}; break;
+case 5774: { // glProgramBinary
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLenum *binaryFormat = (GLenum *) bp; bp += 4;
+ GLvoid *binary = (GLvoid *) bins[0];
+ GLsizei binary_size = bins_sz[0];
+ weglProgramBinary(*program,*binaryFormat,binary,binary_size);
+}; break;
+case 5775: { // glProgramParameteri
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint *value = (GLint *) bp; bp += 4;
+ weglProgramParameteri(*program,*pname,*value);
+}; break;
+case 5776: { // glUseProgramStages
+ GLuint *pipeline = (GLuint *) bp; bp += 4;
+ GLbitfield *stages = (GLbitfield *) bp; bp += 4;
+ GLuint *program = (GLuint *) bp; bp += 4;
+ weglUseProgramStages(*pipeline,*stages,*program);
+}; break;
+case 5777: { // glActiveShaderProgram
+ GLuint *pipeline = (GLuint *) bp; bp += 4;
+ GLuint *program = (GLuint *) bp; bp += 4;
+ weglActiveShaderProgram(*pipeline,*program);
+}; break;
+case 5778: { // glCreateShaderProgramv
+ GLenum *type = (GLenum *) bp; bp += 4;
+ int * stringsLen = (int *) bp; bp += 4;
+ int * stringsTotSize = (int *) bp; bp += 4;
+ GLchar **strings;
+ strings = (GLchar **) driver_alloc(sizeof(GLchar *) * *stringsLen);
+ for(int i=0;i<*stringsLen;i++) {
+ strings[i] = (GLchar *) bp; bp += 1+strlen(bp);};
+ bp += (8 - ((0 + *stringsTotSize) % 8)) % 8;
+ GLuint result = weglCreateShaderProgramv(*type,*stringsLen,(const GLchar **) strings);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free(strings);
+}; break;
+case 5779: { // glBindProgramPipeline
+ GLuint *pipeline = (GLuint *) bp; bp += 4;
+ weglBindProgramPipeline(*pipeline);
+}; break;
+case 5780: { // glDeleteProgramPipelines
+ int * pipelinesLen = (int *) bp; bp += 4;
+ GLuint * pipelines = (GLuint *) bp; bp += (8-((*pipelinesLen*4+4)%8))%8;
+ weglDeleteProgramPipelines(*pipelinesLen,pipelines);
+}; break;
+case 5781: { // glGenProgramPipelines
+ GLsizei *n = (GLsizei *) bp; bp += 4;
+ GLuint *pipelines;
+ pipelines = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
+ weglGenProgramPipelines(*n,pipelines);
+ int AP = 0; ErlDrvTermData *rt;
+ rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2));
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ for(int i=0; i < *n; i++) {
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) pipelines[i];}
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free(rt);
+ driver_free(pipelines);
+}; break;
+case 5782: { // glIsProgramPipeline
+ GLuint *pipeline = (GLuint *) bp; bp += 4;
+ GLboolean result = weglIsProgramPipeline(*pipeline);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5783: { // glGetProgramPipelineiv
+ GLuint *pipeline = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLint params[1] = {0};
+ weglGetProgramPipelineiv(*pipeline,*pname,params);
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5784: { // glProgramUniform1i
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLint *v0 = (GLint *) bp; bp += 4;
+ weglProgramUniform1i(*program,*location,*v0);
+}; break;
+case 5785: { // glProgramUniform1iv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int * valueLen = (int *) bp; bp += 4;
+ GLint * value = (GLint *) bp; bp += (8-((*valueLen*4+4)%8))%8;
+ weglProgramUniform1iv(*program,*location,*valueLen,value);
+}; break;
+case 5786: { // glProgramUniform1f
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLfloat *v0 = (GLfloat *) bp; bp += 4;
+ weglProgramUniform1f(*program,*location,*v0);
+}; break;
+case 5787: { // glProgramUniform1fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int * valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += (8-((*valueLen*4+4)%8))%8;
+ weglProgramUniform1fv(*program,*location,*valueLen,value);
+}; break;
+case 5788: { // glProgramUniform1d
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLdouble *v0 = (GLdouble *) bp; bp += 8;
+ weglProgramUniform1d(*program,*location,*v0);
+}; break;
+case 5789: { // glProgramUniform1dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int * valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += (8-((*valueLen*8+0)%8))%8;
+ weglProgramUniform1dv(*program,*location,*valueLen,value);
+}; break;
+case 5790: { // glProgramUniform1ui
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLuint *v0 = (GLuint *) bp; bp += 4;
+ weglProgramUniform1ui(*program,*location,*v0);
+}; break;
+case 5791: { // glProgramUniform1uiv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int * valueLen = (int *) bp; bp += 4;
+ GLuint * value = (GLuint *) bp; bp += (8-((*valueLen*4+4)%8))%8;
+ weglProgramUniform1uiv(*program,*location,*valueLen,value);
+}; break;
+case 5792: { // glProgramUniform2i
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLint *v0 = (GLint *) bp; bp += 4;
+ GLint *v1 = (GLint *) bp; bp += 4;
+ weglProgramUniform2i(*program,*location,*v0,*v1);
+}; break;
+case 5793: { // glProgramUniform2iv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 4;
+ GLint * value = (GLint *) bp; bp += *valueLen*8;
+ weglProgramUniform2iv(*program,*location,*valueLen,value);
+}; break;
+case 5794: { // glProgramUniform2f
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLfloat *v0 = (GLfloat *) bp; bp += 4;
+ GLfloat *v1 = (GLfloat *) bp; bp += 4;
+ weglProgramUniform2f(*program,*location,*v0,*v1);
+}; break;
+case 5795: { // glProgramUniform2fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*8;
+ weglProgramUniform2fv(*program,*location,*valueLen,value);
+}; break;
+case 5796: { // glProgramUniform2d
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLdouble *v0 = (GLdouble *) bp; bp += 8;
+ GLdouble *v1 = (GLdouble *) bp; bp += 8;
+ weglProgramUniform2d(*program,*location,*v0,*v1);
+}; break;
+case 5797: { // glProgramUniform2dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*16;
+ weglProgramUniform2dv(*program,*location,*valueLen,value);
+}; break;
+case 5798: { // glProgramUniform2ui
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLuint *v0 = (GLuint *) bp; bp += 4;
+ GLuint *v1 = (GLuint *) bp; bp += 4;
+ weglProgramUniform2ui(*program,*location,*v0,*v1);
+}; break;
+case 5799: { // glProgramUniform2uiv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 4;
+ GLuint * value = (GLuint *) bp; bp += *valueLen*8;
+ weglProgramUniform2uiv(*program,*location,*valueLen,value);
+}; break;
+case 5800: { // glProgramUniform3i
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLint *v0 = (GLint *) bp; bp += 4;
+ GLint *v1 = (GLint *) bp; bp += 4;
+ GLint *v2 = (GLint *) bp; bp += 4;
+ weglProgramUniform3i(*program,*location,*v0,*v1,*v2);
+}; break;
+case 5801: { // glProgramUniform3iv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 4;
+ GLint * value = (GLint *) bp; bp += *valueLen*12;
+ weglProgramUniform3iv(*program,*location,*valueLen,value);
+}; break;
+case 5802: { // glProgramUniform3f
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLfloat *v0 = (GLfloat *) bp; bp += 4;
+ GLfloat *v1 = (GLfloat *) bp; bp += 4;
+ GLfloat *v2 = (GLfloat *) bp; bp += 4;
+ weglProgramUniform3f(*program,*location,*v0,*v1,*v2);
+}; break;
+case 5803: { // glProgramUniform3fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*12;
+ weglProgramUniform3fv(*program,*location,*valueLen,value);
+}; break;
+case 5804: { // glProgramUniform3d
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLdouble *v0 = (GLdouble *) bp; bp += 8;
+ GLdouble *v1 = (GLdouble *) bp; bp += 8;
+ GLdouble *v2 = (GLdouble *) bp; bp += 8;
+ weglProgramUniform3d(*program,*location,*v0,*v1,*v2);
+}; break;
+case 5805: { // glProgramUniform3dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*24;
+ weglProgramUniform3dv(*program,*location,*valueLen,value);
+}; break;
+case 5806: { // glProgramUniform3ui
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLuint *v0 = (GLuint *) bp; bp += 4;
+ GLuint *v1 = (GLuint *) bp; bp += 4;
+ GLuint *v2 = (GLuint *) bp; bp += 4;
+ weglProgramUniform3ui(*program,*location,*v0,*v1,*v2);
+}; break;
+case 5807: { // glProgramUniform3uiv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 4;
+ GLuint * value = (GLuint *) bp; bp += *valueLen*12;
+ weglProgramUniform3uiv(*program,*location,*valueLen,value);
+}; break;
+case 5808: { // glProgramUniform4i
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLint *v0 = (GLint *) bp; bp += 4;
+ GLint *v1 = (GLint *) bp; bp += 4;
+ GLint *v2 = (GLint *) bp; bp += 4;
+ GLint *v3 = (GLint *) bp; bp += 4;
+ weglProgramUniform4i(*program,*location,*v0,*v1,*v2,*v3);
+}; break;
+case 5809: { // glProgramUniform4iv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 4;
+ GLint * value = (GLint *) bp; bp += *valueLen*16;
+ weglProgramUniform4iv(*program,*location,*valueLen,value);
+}; break;
+case 5810: { // glProgramUniform4f
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLfloat *v0 = (GLfloat *) bp; bp += 4;
+ GLfloat *v1 = (GLfloat *) bp; bp += 4;
+ GLfloat *v2 = (GLfloat *) bp; bp += 4;
+ GLfloat *v3 = (GLfloat *) bp; bp += 4;
+ weglProgramUniform4f(*program,*location,*v0,*v1,*v2,*v3);
+}; break;
+case 5811: { // glProgramUniform4fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*16;
+ weglProgramUniform4fv(*program,*location,*valueLen,value);
+}; break;
+case 5812: { // glProgramUniform4d
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLdouble *v0 = (GLdouble *) bp; bp += 8;
+ GLdouble *v1 = (GLdouble *) bp; bp += 8;
+ GLdouble *v2 = (GLdouble *) bp; bp += 8;
+ GLdouble *v3 = (GLdouble *) bp; bp += 8;
+ weglProgramUniform4d(*program,*location,*v0,*v1,*v2,*v3);
+}; break;
+case 5813: { // glProgramUniform4dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*32;
+ weglProgramUniform4dv(*program,*location,*valueLen,value);
+}; break;
+case 5814: { // glProgramUniform4ui
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLuint *v0 = (GLuint *) bp; bp += 4;
+ GLuint *v1 = (GLuint *) bp; bp += 4;
+ GLuint *v2 = (GLuint *) bp; bp += 4;
+ GLuint *v3 = (GLuint *) bp; bp += 4;
+ weglProgramUniform4ui(*program,*location,*v0,*v1,*v2,*v3);
+}; break;
+case 5815: { // glProgramUniform4uiv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ int *valueLen = (int *) bp; bp += 4;
+ GLuint * value = (GLuint *) bp; bp += *valueLen*16;
+ weglProgramUniform4uiv(*program,*location,*valueLen,value);
+}; break;
+case 5816: { // glProgramUniformMatrix2fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*16;
+ weglProgramUniformMatrix2fv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5817: { // glProgramUniformMatrix3fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*36;
+ weglProgramUniformMatrix3fv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5818: { // glProgramUniformMatrix4fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*64;
+ weglProgramUniformMatrix4fv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5819: { // glProgramUniformMatrix2dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 7;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*32;
+ weglProgramUniformMatrix2dv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5820: { // glProgramUniformMatrix3dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 7;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*72;
+ weglProgramUniformMatrix3dv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5821: { // glProgramUniformMatrix4dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 7;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*128;
+ weglProgramUniformMatrix4dv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5822: { // glProgramUniformMatrix2x3fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*24;
+ weglProgramUniformMatrix2x3fv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5823: { // glProgramUniformMatrix3x2fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*24;
+ weglProgramUniformMatrix3x2fv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5824: { // glProgramUniformMatrix2x4fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*32;
+ weglProgramUniformMatrix2x4fv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5825: { // glProgramUniformMatrix4x2fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*32;
+ weglProgramUniformMatrix4x2fv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5826: { // glProgramUniformMatrix3x4fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*48;
+ weglProgramUniformMatrix3x4fv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5827: { // glProgramUniformMatrix4x3fv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 3;
+ int *valueLen = (int *) bp; bp += 4;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*48;
+ weglProgramUniformMatrix4x3fv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5828: { // glProgramUniformMatrix2x3dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 7;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
+ weglProgramUniformMatrix2x3dv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5829: { // glProgramUniformMatrix3x2dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 7;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
+ weglProgramUniformMatrix3x2dv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5830: { // glProgramUniformMatrix2x4dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 7;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
+ weglProgramUniformMatrix2x4dv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5831: { // glProgramUniformMatrix4x2dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 7;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
+ weglProgramUniformMatrix4x2dv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5832: { // glProgramUniformMatrix3x4dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 7;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
+ weglProgramUniformMatrix3x4dv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5833: { // glProgramUniformMatrix4x3dv
+ GLuint *program = (GLuint *) bp; bp += 4;
+ GLint *location = (GLint *) bp; bp += 4;
+ GLboolean *transpose = (GLboolean *) bp; bp += 1;
+ bp += 7;
+ int *valueLen = (int *) bp; bp += 8;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
+ weglProgramUniformMatrix4x3dv(*program,*location,*valueLen,*transpose,value);
+}; break;
+case 5834: { // glValidateProgramPipeline
+ GLuint *pipeline = (GLuint *) bp; bp += 4;
+ weglValidateProgramPipeline(*pipeline);
+}; break;
+case 5835: { // glGetProgramPipelineInfoLog
+ GLuint *pipeline = (GLuint *) bp; bp += 4;
+ GLsizei *bufSize = (GLsizei *) bp; bp += 4;
+ GLsizei length[1] = {0};
+ GLchar *infoLog;
+ infoLog = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize);
+ weglGetProgramPipelineInfoLog(*pipeline,*bufSize,length,infoLog);
+ int AP = 0; ErlDrvTermData rt[7];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) infoLog; rt[AP++] = *length;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free(infoLog);
+}; break;
+case 5836: { // glVertexAttribL1dv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ bp += 4;
+ GLdouble *v = (GLdouble *) bp; bp += 8;
+ weglVertexAttribL1dv(*index,v);
+}; break;
+case 5837: { // glVertexAttribL2dv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ bp += 4;
+ GLdouble *v = (GLdouble *) bp; bp += 8;
+ weglVertexAttribL2dv(*index,v);
+}; break;
+case 5838: { // glVertexAttribL3dv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ bp += 4;
+ GLdouble *v = (GLdouble *) bp; bp += 8;
+ weglVertexAttribL3dv(*index,v);
+}; break;
+case 5839: { // glVertexAttribL4dv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ bp += 4;
+ GLdouble *v = (GLdouble *) bp; bp += 8;
+ weglVertexAttribL4dv(*index,v);
+}; break;
+case 5840: { // glVertexAttribLPointer
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLint *size = (GLint *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLsizei *stride = (GLsizei *) bp; bp += 4;
+ GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4;
+ weglVertexAttribLPointer(*index,*size,*type,*stride,pointer);
+}; break;
+case 5841: { // glVertexAttribLPointer
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLint *size = (GLint *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLsizei *stride = (GLsizei *) bp; bp += 4;
+ GLvoid *pointer = (GLvoid *) bins[0];
+ weglVertexAttribLPointer(*index,*size,*type,*stride,pointer);
+}; break;
+case 5842: { // glGetVertexAttribLdv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLenum *pname = (GLenum *) bp; bp += 4;
+ GLdouble params[4] = {0.0,0.0,0.0,0.0};
+ weglGetVertexAttribLdv(*index,*pname,params);
+ int AP = 0; ErlDrvTermData rt[14];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLdouble *paramsTmp = params;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5843: { // glViewportArrayv
+ GLuint *first = (GLuint *) bp; bp += 4;
+ int *vLen = (int *) bp; bp += 4;
+ GLfloat * v = (GLfloat *) bp; bp += *vLen*16;
+ weglViewportArrayv(*first,*vLen,v);
+}; break;
+case 5844: { // glViewportIndexedf
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLfloat *x = (GLfloat *) bp; bp += 4;
+ GLfloat *y = (GLfloat *) bp; bp += 4;
+ GLfloat *w = (GLfloat *) bp; bp += 4;
+ GLfloat *h = (GLfloat *) bp; bp += 4;
+ weglViewportIndexedf(*index,*x,*y,*w,*h);
+}; break;
+case 5845: { // glViewportIndexedfv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLfloat * v = (GLfloat *) bp; bp += 16;
+ weglViewportIndexedfv(*index,v);
+}; break;
+case 5846: { // glScissorArrayv
+ GLuint *first = (GLuint *) bp; bp += 4;
+ int *vLen = (int *) bp; bp += 4;
+ GLint * v = (GLint *) bp; bp += *vLen*16;
+ weglScissorArrayv(*first,*vLen,v);
+}; break;
+case 5847: { // glScissorIndexed
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLint *left = (GLint *) bp; bp += 4;
+ GLint *bottom = (GLint *) bp; bp += 4;
+ GLsizei *width = (GLsizei *) bp; bp += 4;
+ GLsizei *height = (GLsizei *) bp; bp += 4;
+ weglScissorIndexed(*index,*left,*bottom,*width,*height);
+}; break;
+case 5848: { // glScissorIndexedv
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLint * v = (GLint *) bp; bp += 16;
+ weglScissorIndexedv(*index,v);
+}; break;
+case 5849: { // glDepthRangeArrayv
+ GLuint *first = (GLuint *) bp; bp += 4;
+ bp += 4;
+ int *vLen = (int *) bp; bp += 8;
+ GLclampd * v = (GLclampd *) bp; bp += *vLen*16;
+ weglDepthRangeArrayv(*first,*vLen,v);
+}; break;
+case 5850: { // glDepthRangeIndexed
+ GLuint *index = (GLuint *) bp; bp += 4;
+ bp += 4;
+ GLclampd *n = (GLclampd *) bp; bp += 8;
+ GLclampd *f = (GLclampd *) bp; bp += 8;
+ weglDepthRangeIndexed(*index,*n,*f);
+}; break;
+case 5851: { // glGetFloati_v
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLfloat data[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
+ weglGetFloati_v(*target,*index,data);
+ int AP = 0; ErlDrvTermData rt[39];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLdouble dataConv[16], *dataTmp = dataConv;
+ for(int i=0; i < 16; i++) dataConv[i] = (GLdouble) data[i];
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5852: { // glGetDoublei_v
+ GLenum *target = (GLenum *) bp; bp += 4;
+ GLuint *index = (GLuint *) bp; bp += 4;
+ GLdouble data[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
+ weglGetDoublei_v(*target,*index,data);
+ int AP = 0; ErlDrvTermData rt[39];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ GLdouble *dataTmp = data;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++;
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5853: { // glDebugMessageControlARB
+ GLenum *source = (GLenum *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLenum *severity = (GLenum *) bp; bp += 4;
+ int * idsLen = (int *) bp; bp += 4;
+ GLuint * ids = (GLuint *) bp; bp += (8-((*idsLen*4+0)%8))%8;
+ GLboolean *enabled = (GLboolean *) bp; bp += 1;
+ weglDebugMessageControlARB(*source,*type,*severity,*idsLen,ids,*enabled);
+}; break;
+case 5854: { // glDebugMessageInsertARB
+ GLenum *source = (GLenum *) bp; bp += 4;
+ GLenum *type = (GLenum *) bp; bp += 4;
+ GLuint *id = (GLuint *) bp; bp += 4;
+ GLenum *severity = (GLenum *) bp; bp += 4;
+ GLchar *buf = (GLchar *) bp;
+ int bufLen[1] = {strlen((char *)buf)}; bp += bufLen[0]+1+((8-((1+bufLen[0]+0)%8))%8);
+ weglDebugMessageInsertARB(*source,*type,*id,*severity,*bufLen,buf);
+}; break;
+case 5855: { // glGetDebugMessageLogARB
+ GLuint *count = (GLuint *) bp; bp += 4;
+ GLsizei *bufsize = (GLsizei *) bp; bp += 4;
+ GLenum *sources;
+ sources = (GLenum *) driver_alloc(sizeof(GLenum) * *count);
+ GLenum *types;
+ types = (GLenum *) driver_alloc(sizeof(GLenum) * *count);
+ GLuint *ids;
+ ids = (GLuint *) driver_alloc(sizeof(GLuint) * *count);
+ GLenum *severities;
+ severities = (GLenum *) driver_alloc(sizeof(GLenum) * *count);
+ GLsizei *lengths;
+ lengths = (GLsizei *) driver_alloc(sizeof(GLsizei) * *count);
+ GLchar *messageLog;
+ messageLog = (GLchar *) driver_alloc(sizeof(GLchar) * *bufsize);
+ GLuint result = weglGetDebugMessageLogARB(*count,*bufsize,sources,types,ids,severities,lengths,messageLog);
+ int AP = 0; ErlDrvTermData *rt;
+ rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(23 + result*3 + result*2 + result*2 + result*2 + result*2));
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ for(int i=0; i < (int) result; i++) {
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) sources[i];}
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = ((int) result)+1;
+ for(int i=0; i < (int) result; i++) {
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) types[i];}
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = ((int) result)+1;
+ for(int i=0; i < (int) result; i++) {
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ids[i];}
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = ((int) result)+1;
+ for(int i=0; i < (int) result; i++) {
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) severities[i];}
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = ((int) result)+1;
+ for(int i=0; i < (int) result; i++) {
+ rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) messageLog; rt[AP++] = lengths[i]-1;
+ messageLog += lengths[i]; }
+ rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = ((int) result)+1;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 6;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+ driver_free(rt);
+ driver_free(messageLog);
+ driver_free(lengths);
+ driver_free(severities);
+ driver_free(ids);
+ driver_free(types);
+ driver_free(sources);
+}; break;
+case 5856: { // glGetGraphicsResetStatusARB
+ GLenum result = weglGetGraphicsResetStatusARB();
+ int AP = 0; ErlDrvTermData rt[6];
+ rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
+ rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result;
+ rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+ driver_send_term(port,caller,rt,AP);
+}; break;
+case 5857: { // glResizeBuffersMESA
weglResizeBuffersMESA();
}; break;
-case 5677: { // glWindowPos4dvMESA
+case 5858: { // glWindowPos4dvMESA
GLdouble *v = (GLdouble *) bp; bp += 8;
weglWindowPos4dvMESA(v);
}; break;
-case 5678: { // glWindowPos4fvMESA
+case 5859: { // glWindowPos4fvMESA
GLfloat *v = (GLfloat *) bp; bp += 4;
weglWindowPos4fvMESA(v);
}; break;
-case 5679: { // glWindowPos4ivMESA
+case 5860: { // glWindowPos4ivMESA
GLint *v = (GLint *) bp; bp += 4;
weglWindowPos4ivMESA(v);
}; break;
-case 5680: { // glWindowPos4svMESA
+case 5861: { // glWindowPos4svMESA
GLshort *v = (GLshort *) bp; bp += 2;
weglWindowPos4svMESA(v);
}; break;
-case 5681: { // glDepthBoundsEXT
+case 5862: { // glDepthBoundsEXT
GLclampd *zmin = (GLclampd *) bp; bp += 8;
GLclampd *zmax = (GLclampd *) bp; bp += 8;
weglDepthBoundsEXT(*zmin,*zmax);
}; break;
-case 5682: { // glStencilClearTagEXT
+case 5863: { // glStencilClearTagEXT
GLsizei *stencilTagBits = (GLsizei *) bp; bp += 4;
GLuint *stencilClearTag = (GLuint *) bp; bp += 4;
weglStencilClearTagEXT(*stencilTagBits,*stencilClearTag);
}; break;
+}} catch (char *err_msg) {
+int AP = 0; ErlDrvTermData rt[12];
+rt[AP++] = ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_error_");
+rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) op;
+rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *) err_msg);
+// rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *) gl_fns[op-GLE_GL_FUNC_START].name);
+// rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
+rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3;
+driver_send_term(port,caller,rt,AP);
}} /* The End */
diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp
index 8c056bbb91..479d7679a4 100644
--- a/lib/wx/c_src/gen/wxe_funcs.cpp
+++ b/lib/wx/c_src/gen/wxe_funcs.cpp
@@ -23,6 +23,7 @@
#include "../wxe_impl.h"
#include "../wxe_events.h"
#include "../wxe_return.h"
+#include "../wxe_gl.h"
#include "wxe_macros.h"
#include "wxe_derived_dest.h"
@@ -43,6 +44,15 @@ void WxeApp::wxe_dispatch(wxeCommand& Ecmd)
rt.addAtom("ok");
break;
}
+ case WXE_BIN_INCR:
+ driver_binary_inc_refc(Ecmd.bin[0]->bin);
+ break;
+ case WXE_BIN_DECR:
+ driver_binary_dec_refc(Ecmd.bin[0]->bin);
+ break;
+ case WXE_INIT_OPENGL:
+ wxe_initOpenGL(rt, bp);
+ break;
case 98: { // wxeEvtListener::wxeEvtListener
wxeEvtListener *Result = new wxeEvtListener(Ecmd.port);
rt.addRef(getRef((void *)Result,memenv), "wxeEvtListener");
diff --git a/lib/wx/c_src/wxe_driver.c b/lib/wx/c_src/wxe_driver.c
index 310325ea26..2404b13cc3 100644
--- a/lib/wx/c_src/wxe_driver.c
+++ b/lib/wx/c_src/wxe_driver.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -117,8 +117,7 @@ wxe_driver_start(ErlDrvPort port, char *buff)
if(WXE_DRV_PORT == 0) {
for(; *buff != 32; buff++);
buff++;
- erl_wx_privdir = malloc(strlen(buff));
- strcpy(erl_wx_privdir, buff);
+ erl_wx_privdir = strdup(buff);
WXE_DRV_PORT = port;
wxe_master = data;
@@ -146,7 +145,6 @@ static void
wxe_driver_unload(void)
{
// fprintf(stderr, "%s:%d: UNLOAD \r\n", __FILE__,__LINE__);
- meta_command(WXE_SHUTDOWN, wxe_master);
stop_native_gui(wxe_master);
unload_native_gui();
free(wxe_master);
diff --git a/lib/wx/c_src/wxe_driver.h b/lib/wx/c_src/wxe_driver.h
index 13a17e356f..5c5b8614ed 100644
--- a/lib/wx/c_src/wxe_driver.h
+++ b/lib/wx/c_src/wxe_driver.h
@@ -83,8 +83,9 @@ extern char * erl_wx_privdir;
#define WXE_CB_START 8
#define WXE_DEBUG_DRIVER 9
#define WXE_DEBUG_PING 10
-#define WXE_BIN_INCR 5001
-#define WXE_BIN_DECR 5002
+#define WXE_BIN_INCR 11
+#define WXE_BIN_DECR 12
+#define WXE_INIT_OPENGL 13
#define OPENGL_START 5000
diff --git a/lib/wx/c_src/wxe_gl.cpp b/lib/wx/c_src/wxe_gl.cpp
index 63dd68fa5e..e947a1bc6e 100644
--- a/lib/wx/c_src/wxe_gl.cpp
+++ b/lib/wx/c_src/wxe_gl.cpp
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -19,303 +19,142 @@
#include <stdio.h>
#include <string.h>
+#ifndef _WIN32
+#include <dlfcn.h>
+#else
+#include <windows.h>
+#endif
#include "wxe_impl.h"
-
-#include "wxe_gl.h"
-
-#define WX_DEF_EXTS
-#include "gen/gl_fdefs.h"
-#include "gen/gl_finit.h"
-#include "gen/glu_finit.h"
+#include "wxe_return.h"
/* ****************************************************************************
* Opengl context management *
* ****************************************************************************/
-int gl_initiated = FALSE;
+int erl_gl_initiated = FALSE;
ErlDrvTermData gl_active = 0;
wxeGLC glc;
-void setActiveGL(ErlDrvTermData caller, wxGLCanvas *canvas)
-{
- if(gl_initiated == FALSE) {
- initOpenGL();
- init_tess();
- gl_initiated = TRUE;
- }
- gl_active = caller;
- glc[caller] = canvas;
-}
-
-void deleteActiveGL(wxGLCanvas *canvas)
-{
- gl_active = 0;
- wxeGLC::iterator it;
- for(it = glc.begin(); it != glc.end(); ++it) {
- if(it->second == canvas) {
- it->second = (wxGLCanvas *) 0;
- }
- }
-}
-
-/* ****************************************************************************
- * OPENGL INITIALIZATION
- *****************************************************************************/
+typedef void (*WXE_GL_DISPATCH) (int, char *, ErlDrvPort, ErlDrvTermData, char **, int *);
+WXE_GL_DISPATCH wxe_gl_dispatch;
#ifdef _WIN32
+#define RTLD_LAZY 0
+typedef HMODULE DL_LIB_P;
void * dlsym(HMODULE Lib, const char *func) {
void * funcp;
- if((funcp = (void *) GetProcAddress(Lib, func)))
+ if((funcp = (void *) GetProcAddress(Lib, func)))
return funcp;
- else
+ else
return (void *) wglGetProcAddress(func);
}
-#endif
-int initOpenGL()
-{
-#ifdef _MACOSX
- char * DLName = "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib";
- void * LIBhandle = dlopen(DLName, RTLD_LAZY);
-#elif defined(_WIN32)
- WCHAR * DLName = wxT("opengl32.dll");
- HMODULE LIBhandle = LoadLibrary(DLName);
-#else
- char * DLName = (char *) "libGL.so";
- void * LIBhandle = dlopen(DLName, RTLD_LAZY);
-#endif
- // fprintf(stderr, "Loading GL: %s\r\n", (const char*)DLName);
- void * func = NULL;
- int i;
+HMODULE dlopen(const char *path, int unused) {
+ WCHAR * DLL;
+ int len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
+ DLL = (WCHAR *) malloc(len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, path, -1, DLL, len);
+ HMODULE lib = LoadLibrary(DLL);
+ free(DLL);
+ return lib;
+}
- if(LIBhandle) {
- for(i=0; gl_fns[i].name != NULL; i++) {
- if((func = dlsym(LIBhandle, gl_fns[i].name))) {
- * (void **) (gl_fns[i].func) = func;
- // fprintf(stderr, "GL LOADED %s \r\n", gl_fns[i].name);
- } else {
- if(gl_fns[i].alt != NULL) {
- if((func = dlsym(LIBhandle, gl_fns[i].alt))) {
- * (void **) (gl_fns[i].func) = func;
- // fprintf(stderr, "GL LOADED %s \r\n", gl_fns[i].alt);
- } else {
- * (void **) (gl_fns[i].func) = (void *) &gl_error;
- // fprintf(stderr, "GL Skipped %s and %s \r\n", gl_fns[i].name, gl_fns[i].alt);
- };
- } else {
- * (void **) (gl_fns[i].func) = (void *) &gl_error;
- // fprintf(stderr, "GL Skipped %s \r\n", gl_fns[i].name);
- }
- }
- }
-#ifdef _WIN32
- FreeLibrary(LIBhandle);
-#else
- dlclose(LIBhandle);
-#endif
- // fprintf(stderr, "OPENGL library is loaded\r\n");
- } else {
- wxString msg;
- msg.Printf(wxT("Could NOT load OpenGL library: "));
-#ifdef _WIN32
- msg += DLName;
+void dlclose(HMODULE Lib) {
+ FreeLibrary(Lib);
+}
#else
- msg += wxString::FromAscii((char *)DLName);
+typedef void * DL_LIB_P;
#endif
- send_msg("error", &msg);
- };
-#ifdef _MACOSX
- DLName = "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib";
- LIBhandle = dlopen(DLName, RTLD_LAZY);
-#elif defined(_WIN32)
- DLName = wxT("glu32.dll");
- LIBhandle = LoadLibrary(DLName);
+void wxe_initOpenGL(wxeReturn rt, char *bp) {
+ DL_LIB_P LIBhandle;
+ int (*init_opengl)(void *);
+#ifdef _WIN32
+ void * erlCallbacks = &WinDynDriverCallbacks;
#else
- DLName = (char *) "libGLU.so";
- LIBhandle = dlopen(DLName, RTLD_LAZY);
+ void * erlCallbacks = NULL;
#endif
- // fprintf(stderr, "Loading GL: %s\r\n", (const char*)DLName);
- func = NULL;
-
- if(LIBhandle) {
- for(i=0; glu_fns[i].name != NULL; i++) {
- if((func = dlsym(LIBhandle, glu_fns[i].name))) {
- * (void **) (glu_fns[i].func) = func;
+
+ if(erl_gl_initiated == FALSE) {
+ if((LIBhandle = dlopen(bp, RTLD_LAZY))) {
+ *(void **) (&init_opengl) = dlsym(LIBhandle, "egl_init_opengl");
+ wxe_gl_dispatch = (WXE_GL_DISPATCH) dlsym(LIBhandle, "egl_dispatch");
+ if(init_opengl && wxe_gl_dispatch) {
+ (*init_opengl)(erlCallbacks);
+ rt.addAtom((char *) "ok");
+ rt.add(wxString::FromAscii("initiated"));
+ rt.addTupleCount(2);
+ erl_gl_initiated = TRUE;
} else {
- if(glu_fns[i].alt != NULL) {
- if((func = dlsym(LIBhandle, glu_fns[i].alt))) {
- * (void **) (glu_fns[i].func) = func;
- } else {
- * (void **) (glu_fns[i].func) = (void *) &gl_error;
- // fprintf(stderr, "GLU Skipped %s\r\n", glu_fns[i].alt);
- };
- } else {
- * (void **) (glu_fns[i].func) = (void *) &gl_error;
- // fprintf(stderr, "GLU Skipped %s\r\n", glu_fns[i].name);
- }
+ wxString msg;
+ msg.Printf(wxT("In library: "));
+ msg += wxString::FromAscii(bp);
+ msg += wxT(" functions: ");
+ if(!init_opengl)
+ msg += wxT("egl_init_opengl ");
+ if(!wxe_gl_dispatch)
+ msg += wxT("egl_dispatch ");
+ rt.addAtom((char *) "error");
+ rt.add(msg);
+ rt.addTupleCount(2);
}
+ } else {
+ wxString msg;
+ msg.Printf(wxT("Could not load dll: "));
+ msg += wxString::FromAscii(bp);
+ rt.addAtom((char *) "error");
+ rt.add(msg);
+ rt.addTupleCount(2);
}
-#ifdef _WIN32
- FreeLibrary(LIBhandle);
-#else
- dlclose(LIBhandle);
-#endif
- // fprintf(stderr, "GLU library is loaded\r\n");
} else {
- wxString msg;
- msg.Printf(wxT("Could NOT load OpenGL GLU library: "));
-#ifdef _WIN32
- msg += DLName;
-#else
- msg += wxString::FromAscii((char *)DLName);
-#endif
- send_msg("error", &msg);
- };
- return 0;
-}
-
-void gl_error() {
- int AP = 0; ErlDrvTermData rt[8];
- rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *)"_wxe_error_");
- rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) gl_error_op;
- rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *)"undef");
- rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3;
- driver_send_term(WXE_DRV_PORT,gl_active,rt,AP);
-}
-
-/* *******************************************************************************
- * GLU Tesselation special
- * ******************************************************************************/
-
-static GLUtesselator* tess;
-static GLdouble* tess_coords;
-static GLdouble* tess_alloc_vertex;
-static int* tess_vertices;
-
-void CALLBACK
-wxe_ogla_vertex(GLdouble* coords)
-{
- /* fprintf(stderr, "%d\r\n", (int) (coords - tess_coords) / 3); */
-
- *tess_vertices++ = (int) (coords - tess_coords) / 3;
-}
-
-void CALLBACK
-wxe_ogla_edge_flag(GLboolean flag)
-{
+ rt.addAtom((char *) "ok");
+ rt.add(wxString::FromAscii("already initilized"));
+ rt.addTupleCount(2);
+ }
+ rt.send();
}
-void CALLBACK
-wxe_ogla_error(GLenum errorCode)
+void setActiveGL(ErlDrvTermData caller, wxGLCanvas *canvas)
{
- const GLubyte *err;
- err = gluErrorString(errorCode);
- wxString msg;
- msg.Printf(wxT("Tesselation error: %d: "), (int)errorCode);
- msg += wxString::FromAscii((char *) err);
- send_msg("error", &msg);
+ gl_active = caller;
+ glc[caller] = canvas;
}
-void CALLBACK
-wxe_ogla_combine(GLdouble coords[3],
- void* vertex_data[4],
- GLfloat w[4],
- void **dataOut)
+void deleteActiveGL(wxGLCanvas *canvas)
{
- GLdouble* vertex = tess_alloc_vertex;
-
- tess_alloc_vertex += 3;
-
-#if 0
- fprintf(stderr, "combine: ");
- int i;
- for (i = 0; i < 4; i++) {
- if (w[i] > 0.0) {
- fprintf(stderr, "%d(%g) ", (int) vertex_data[i], w[i]);
+ gl_active = 0;
+ wxeGLC::iterator it;
+ for(it = glc.begin(); it != glc.end(); ++it) {
+ if(it->second == canvas) {
+ it->second = (wxGLCanvas *) 0;
}
}
- fprintf(stderr, "\r\n");
- fprintf(stderr, "%g %g %g\r\n", vertex[0], vertex[1], vertex[2]);
-#endif
-
- vertex[0] = coords[0];
- vertex[1] = coords[1];
- vertex[2] = coords[2];
- *dataOut = vertex;
-}
-
-void init_tess()
-{
- tess = gluNewTess();
-
- gluTessCallback(tess, GLU_TESS_VERTEX, (GLUfuncptr) wxe_ogla_vertex);
- gluTessCallback(tess, GLU_TESS_EDGE_FLAG, (GLUfuncptr) wxe_ogla_edge_flag);
- gluTessCallback(tess, GLU_TESS_COMBINE, (GLUfuncptr) wxe_ogla_combine);
- gluTessCallback(tess, GLU_TESS_ERROR, (GLUfuncptr) wxe_ogla_error);
-
}
-void exit_tess()
-{
- gluDeleteTess(tess);
-}
-
-int wxe_tess_impl(char* buff, ErlDrvTermData caller)
-{
- ErlDrvBinary* bin;
- int i;
- int num_vertices = * (int *) buff; buff += 8; // Align
- GLdouble *n = (double *) buff; buff += 8*3;
-
- GLdouble* new_vertices;
- bin = driver_alloc_binary(num_vertices*6*sizeof(GLdouble));
- new_vertices = tess_coords = (double *) bin->orig_bytes;
- memcpy(tess_coords,buff,num_vertices*3*sizeof(GLdouble));
- tess_alloc_vertex = tess_coords + num_vertices*3;
-
-#if 0
- fprintf(stderr, "n=%d\r\n", num_vertices);
-#endif
- int *vertices;
- vertices = (int *) driver_alloc(sizeof(int) * 16*num_vertices);
-
- tess_vertices = vertices;
-
- gluTessNormal(tess, n[0], n[1], n[2]);
- gluTessBeginPolygon(tess, 0);
- gluTessBeginContour(tess);
- for (i = 0; i < num_vertices; i++) {
- gluTessVertex(tess, tess_coords+3*i, tess_coords+3*i);
- }
- gluTessEndContour(tess);
- gluTessEndPolygon(tess);
-
- int n_pos = (tess_vertices - vertices);
-
- int AP = 0; ErlDrvTermData *rt;
- rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+n_pos*2));
- rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_");
-
- for(i=0; i < n_pos; i++) {
- rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) vertices[i];
+void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){
+ if(caller != gl_active) {
+ wxGLCanvas * current = glc[caller];
+ if(current) { gl_active = caller; current->SetCurrent();}
+ else {
+ ErlDrvTermData rt[] = // Error msg
+ {ERL_DRV_ATOM, driver_mk_atom((char *) "_egl_error_"),
+ ERL_DRV_INT, op,
+ ERL_DRV_ATOM, driver_mk_atom((char *) "no_gl_context"),
+ ERL_DRV_TUPLE,3};
+ driver_send_term(WXE_DRV_PORT,caller,rt,8);
+ return ;
+ }
};
- rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = n_pos+1;
-
- rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) bin;
- rt[AP++] = (tess_alloc_vertex-new_vertices)*sizeof(GLdouble); rt[AP++] = 0;
-
- rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin}
- rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple
-
- driver_send_term(WXE_DRV_PORT,caller,rt,AP);
-// fprintf(stderr, "List %d %d %d \r\n",
-// n_pos,
-// (tess_alloc_vertex-new_vertices)*sizeof(GLdouble),
-// num_vertices*6*sizeof(GLdouble));
- driver_free_binary(bin);
- driver_free(vertices);
- driver_free(rt);
- return 0;
+ char * bs[3];
+ int bs_sz[3];
+ for(int i=0; i<3; i++) {
+ if(bins[i]) {
+ bs[i] = bins[i]->base;
+ bs_sz[i] = bins[i]->size;
+ }
+ else
+ bs[i] = NULL;
+ }
+ wxe_gl_dispatch(op, bp, WXE_DRV_PORT, caller, bs, bs_sz);
}
diff --git a/lib/wx/c_src/wxe_gl.h b/lib/wx/c_src/wxe_gl.h
index 3a47b3c1bd..1b556ff4ec 100644
--- a/lib/wx/c_src/wxe_gl.h
+++ b/lib/wx/c_src/wxe_gl.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -17,119 +17,6 @@
* %CopyrightEnd%
*/
+#include "egl_impl.h"
-#ifndef _WIN32
-# include <dlfcn.h>
-#endif
-
-#ifndef __WXMAC__
-# include <GL/gl.h>
-# include <GL/glu.h> /* Header File For The OpenGL Library */
-#else
-# include <OpenGL/glu.h> /* Header File For The OpenGL Library */
-#endif
-
-#ifndef CALLBACK
-# define CALLBACK
-#endif
-
-#ifdef _WIN32
-# ifndef _GLUfuncptr
-// Visual studio CPP ++ compiler
-# define _GLUfuncptr void (_stdcall *)()
-# endif
-#endif
-
-#ifdef _GLUfuncptr
-# define GLUfuncptr _GLUfuncptr
-#elif defined(TESS_CB_TIGER_STYLE)
-# define GLUfuncptr GLvoid (*)(...)
-#else
-# define GLUfuncptr GLvoid (*)()
-#endif
-
-#ifdef WIN32
-#include <windows.h>
-#include <gl/gl.h>
-#elif defined(HAVE_GL_GL_H)
-#include <GL/gl.h>
-#elif defined(HAVE_OPENGL_GL_H)
-#endif
-
-#ifndef APIENTRY
-#define APIENTRY
-#endif
-
-int initOpenGL();
-void gl_error();
-extern int gl_error_op;
-extern ErlDrvTermData gl_active;
-
-/* Some new GL types (eliminates the need for glext.h) */
-
-#ifndef HAVE_GLINTPTR
-#ifndef HAVE_GLINTPTRARB
-# include <stddef.h>
-/* GL types for handling large vertex buffer objects */
-typedef ptrdiff_t GLintptrARB;
-typedef ptrdiff_t GLsizeiptrARB;
-#endif /* HAVE_GLINTPTRARB */
-typedef GLintptrARB GLintptr;
-typedef GLsizeiptrARB GLsizeiptr;
-#endif /* HAVE_GLINTPTR */
-
-#ifndef HAVE_GLCHAR
-# ifndef HAVE_GLCHARARB
-/* GL types for handling shader object handles and characters */
-typedef char GLcharARB; /* native character */
-typedef unsigned int GLhandleARB; /* shader object handle */
-#endif /* HAVE_GLCHARARB */
-typedef GLcharARB GLchar;
-#endif
-
-#ifndef HAVE_GLHALFARB
-/* GL types for "half" precision (s10e5) float data in host memory */
-typedef unsigned short GLhalfARB;
-#endif
-
-/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
-/* (as used in the GLX_OML_sync_control extension). */
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#include <inttypes.h>
-#elif defined(__sun__)
-#include <inttypes.h>
-#if defined(__STDC__)
-#if defined(__arch64__)
-typedef long int int64_t;
-typedef unsigned long int uint64_t;
-#else
-typedef long long int int64_t;
-typedef unsigned long long int uint64_t;
-#endif /* __arch64__ */
-#endif /* __STDC__ */
-#elif defined( __VMS )
-#include <inttypes.h>
-#elif defined(__SCO__) || defined(__USLC__)
-#include <stdint.h>
-#elif defined(__UNIXOS2__) || defined(__SOL64__)
-typedef long int int32_t;
-typedef long long int int64_t;
-typedef unsigned long long int uint64_t;
-#elif defined(WIN32) && defined(_MSC_VER)
-typedef long int int32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-#elif defined(WIN32) && defined(__GNUC__)
-#include <stdint.h>
-#else
-#include <inttypes.h> /* Fallback option */
-#endif
-
-#ifndef HAVE_GLINT64EXT
-typedef int64_t GLint64EXT;
-typedef uint64_t GLuint64EXT;
-#endif
-
-void init_tess();
-void exit_tess();
-int wxe_tess_impl(char* buff, ErlDrvTermData caller);
+void wxe_initOpenGL(wxeReturn, char*);
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
index 6d2926ce4e..365fb691a1 100644
--- a/lib/wx/c_src/wxe_impl.cpp
+++ b/lib/wx/c_src/wxe_impl.cpp
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -68,7 +68,6 @@ ErlDrvTermData wxe_batch_caller = 0;
ErlDrvTermData init_caller = 0;
// extern opengl
-extern int gl_initiated;
void gl_dispatch(int op, char *bp, ErlDrvTermData caller, WXEBinRef *bins[]);
@@ -79,6 +78,21 @@ extern void erts_thread_disable_fpe(void);
}
#endif
+#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__)
+#define __DARWIN__ 1
+#endif
+
+#ifdef __DARWIN__
+extern "C" {
+ int erl_drv_stolen_main_thread_join(ErlDrvTid tid, void **respp);
+ int erl_drv_steal_main_thread(char *name,
+ ErlDrvTid *dtid,
+ void* (*func)(void*),
+ void* arg,
+ ErlDrvThreadOpts *opts);
+}
+#endif
+
void *wxe_main_loop(void * );
/* ************************************************************
@@ -100,8 +114,14 @@ int start_native_gui(wxe_data *sd)
wxe_batch_locker_c = erl_drv_cond_create((char *)"wxe_batch_locker_c");
init_caller = driver_connected(sd->port);
- if((res = erl_drv_thread_create((char *)"wxwidgets",
- &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL)) == 0) {
+#ifdef __DARWIN__
+ res = erl_drv_steal_main_thread((char *)"wxwidgets",
+ &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL);
+#else
+ res = erl_drv_thread_create((char *)"wxwidgets",
+ &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL);
+#endif
+ if(res == 0) {
erl_drv_mutex_lock(wxe_status_m);
for(;wxe_status == WXE_NOT_INITIATED;) {
erl_drv_cond_wait(wxe_status_c, wxe_status_m);
@@ -118,7 +138,14 @@ int start_native_gui(wxe_data *sd)
void stop_native_gui(wxe_data *sd)
{
+ if(wxe_status == WXE_INITIATED) {
+ meta_command(WXE_SHUTDOWN, sd);
+ }
+#ifdef __DARWIN__
+ erl_drv_stolen_main_thread_join(wxe_thread, NULL);
+#else
erl_drv_thread_join(wxe_thread, NULL);
+#endif
erl_drv_mutex_destroy(wxe_status_m);
erl_drv_cond_destroy(wxe_status_c);
erl_drv_mutex_destroy(wxe_batch_locker_m);
@@ -183,8 +210,8 @@ void *wxe_main_loop(void *vpdl)
{
int result;
int argc = 1;
- char * temp = (char *) "Erlang\0";
- char ** argv = &temp;
+ char * temp = (char *) "Erlang";
+ char * argv[] = {temp,NULL};
ErlDrvPDL pdl = (ErlDrvPDL) vpdl;
driver_pdl_inc_refc(pdl);
@@ -203,7 +230,9 @@ void *wxe_main_loop(void *vpdl)
/* We are done try to make a clean exit */
wxe_status = WXE_EXITED;
driver_pdl_dec_refc(pdl);
+#ifndef __DARWIN__
erl_drv_thread_exit(NULL);
+#endif
return NULL;
} else {
erl_drv_mutex_lock(wxe_status_m);
@@ -265,7 +294,6 @@ bool WxeApp::OnInit()
init_nonconsts(global_me, init_caller);
erl_drv_mutex_lock(wxe_status_m);
wxe_status = WXE_INITIATED;
- gl_initiated = FALSE;
erl_drv_cond_signal(wxe_status_c);
erl_drv_mutex_unlock(wxe_status_m);
return TRUE;
diff --git a/lib/wx/c_src/wxe_ps_init.c b/lib/wx/c_src/wxe_ps_init.c
index e787c214bd..a85f751024 100644
--- a/lib/wx/c_src/wxe_ps_init.c
+++ b/lib/wx/c_src/wxe_ps_init.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/wx/c_src/wxe_return.cpp b/lib/wx/c_src/wxe_return.cpp
index 2c4f7541e7..9fd627829e 100644
--- a/lib/wx/c_src/wxe_return.cpp
+++ b/lib/wx/c_src/wxe_return.cpp
@@ -64,11 +64,14 @@ int wxeReturn::send() {
int res = driver_send_term(port, caller, rtData, rtLength);
driver_free(rtData);
+#ifdef DEBUG
if(res == -1) {
wxString msg;
msg.Printf(wxT("Failed to send return or event msg"));
send_msg("internal_error", &msg);
}
+#endif
+
reset();
return res;
}
diff --git a/lib/wx/configure.in b/lib/wx/configure.in
index 855c0c975e..f7128db23a 100755
--- a/lib/wx/configure.in
+++ b/lib/wx/configure.in
@@ -162,16 +162,20 @@ esac
case $host_os in
darwin*)
CFLAGS="-no-cpp-precomp $CFLAGS"
- LDFLAGS="-bundle -flat_namespace -undefined warning -fPIC -framework OpenGL $LDFLAGS"
+ LDFLAGS="-bundle -flat_namespace -undefined warning -fPIC $LDFLAGS"
+ GL_LIBS="-framework OpenGL"
;;
win32)
LDFLAGS="-dll $LDFLAGS"
+ GL_LIBS="-lglu32 -lOpengl32"
;;
mingw32)
LDFLAGS="-shared -fPIC $LDFLAGS"
+ GL_LIBS="-lglu32 -lOpengl32"
;;
*)
LDFLAGS="-shared -fPIC $LDFLAGS"
+ GL_LIBS="-lGL -lGLU"
;;
esac
@@ -194,6 +198,42 @@ case $host_os in
;;
esac
+dnl
+dnl Opengl tests
+dnl
+
+if test X"$host_os" != X"win32" ; then
+ AC_CHECK_HEADERS([GL/gl.h], [],
+ [AC_CHECK_HEADERS([OpenGL/gl.h])])
+ if test X"$ac_cv_header_GL_gl_h" != Xyes &&
+ test X"$ac_cv_header_OpenGL_gl_h" != Xyes
+ then
+ saved_CPPFLAGS="$CPPFLAGS"
+ AC_MSG_NOTICE(Checking for OpenGL headers in /usr/X11R6)
+ CPPFLAGS="-isystem /usr/X11R6/include $CPPFLAGS"
+ $as_unset ac_cv_header_GL_gl_h
+ AC_CHECK_HEADERS([GL/gl.h])
+ if test X"$ac_cv_header_GL_gl_h" != Xyes ; then
+ AC_MSG_NOTICE(Checking for OpenGL headers in /usr/local)
+ CPPFLAGS="-isystem /usr/local/include $saved_CPPFLAGS"
+ $as_unset ac_cv_header_GL_gl_h
+ AC_CHECK_HEADERS([GL/gl.h])
+ if test X"$ac_cv_header_GL_gl_h" != Xyes ; then
+ AC_MSG_WARN([No OpenGL headers found, wx will NOT be usable])
+ CPPFLAGS="$saved_CPPFLAGS"
+ else
+ GL_LIBS="-L/usr/local/lib $GL_LIBS"
+ fi
+ else
+ GL_LIBS="-L/usr/X11R6/lib $GL_LIBS"
+ fi
+ fi
+else
+ AC_CHECK_HEADERS([gl/gl.h],[],[],[#include <windows.h>])
+fi
+
+AC_SUBST(GL_LIBS)
+
CXXFLAGS="$CFLAGS $CPPFLAGS"
CFLAGS="$CFLAGS $CPPFLAGS $C_ONLY_FLAGS"
@@ -386,17 +426,6 @@ if test "$WXERL_CAN_BUILD_DRIVER" != "false"; then
AC_SUBST(WX_HAVE_STATIC_LIBS)
AC_SUBST(RC_FILE_TYPE)
-dnl
-dnl Opengl tests
-dnl
-
-if test X"$host_os" != X"win32" ; then
- AC_CHECK_HEADERS([GL/gl.h])
- AC_CHECK_HEADERS([OpenGL/gl.h])
-else
- AC_CHECK_HEADERS([gl/gl.h],[],[],[#include <windows.h>])
-fi
-
AC_MSG_CHECKING(if wxwidgets have opengl support)
AC_LANG_PUSH(C++)
saved_CXXFLAGS=$CXXFLAGS
diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml
index 8414028106..1493501ea4 100644
--- a/lib/wx/doc/src/notes.xml
+++ b/lib/wx/doc/src/notes.xml
@@ -31,6 +31,25 @@
<p>This document describes the changes made to the wxErlang
application.</p>
+<section><title>Wx 0.98.8</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Add wxSystemSettings which was missing in the previous
+ release, despite previous comments.</p> <p>Fix an
+ external loop when stopping erlang nicely.</p>
+ <p>Separate OpenGL to it's own dynamic loaded library, so
+ other graphic libraries can reuse the gl module and it
+ will not waste memory if not used.</p>
+ <p>
+ Own Id: OTP-8951</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Wx 0.98.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/wx/include/gl.hrl b/lib/wx/include/gl.hrl
index 2fa0d72a59..52f2635af9 100644
--- a/lib/wx/include/gl.hrl
+++ b/lib/wx/include/gl.hrl
@@ -782,7 +782,7 @@
-define(GL_TEXTURE_COMPARE_MODE, 16#884C).
-define(GL_TEXTURE_COMPARE_FUNC, 16#884D).
-define(GL_COMPARE_R_TO_TEXTURE, 16#884E).
--define(GL_GLEXT_VERSION, 52).
+-define(GL_GLEXT_VERSION, 65).
-define(GL_CONSTANT_COLOR, 16#8001).
-define(GL_ONE_MINUS_CONSTANT_COLOR, 16#8002).
-define(GL_CONSTANT_ALPHA, 16#8003).
@@ -1021,6 +1021,8 @@
-define(GL_CLIP_DISTANCE3, 16#3003).
-define(GL_CLIP_DISTANCE4, 16#3004).
-define(GL_CLIP_DISTANCE5, 16#3005).
+-define(GL_CLIP_DISTANCE6, 16#3006).
+-define(GL_CLIP_DISTANCE7, 16#3007).
-define(GL_MAX_CLIP_DISTANCES, 16#D32).
-define(GL_MAJOR_VERSION, 16#821B).
-define(GL_MINOR_VERSION, 16#821C).
@@ -1111,6 +1113,9 @@
-define(GL_QUERY_NO_WAIT, 16#8E14).
-define(GL_QUERY_BY_REGION_WAIT, 16#8E15).
-define(GL_QUERY_BY_REGION_NO_WAIT, 16#8E16).
+-define(GL_BUFFER_ACCESS_FLAGS, 16#911F).
+-define(GL_BUFFER_MAP_LENGTH, 16#9120).
+-define(GL_BUFFER_MAP_OFFSET, 16#9121).
-define(GL_CLAMP_VERTEX_COLOR, 16#891A).
-define(GL_CLAMP_FRAGMENT_COLOR, 16#891B).
-define(GL_ALPHA_INTEGER, 16#8D97).
@@ -1145,6 +1150,40 @@
-define(GL_SIGNED_NORMALIZED, 16#8F9C).
-define(GL_PRIMITIVE_RESTART, 16#8F9D).
-define(GL_PRIMITIVE_RESTART_INDEX, 16#8F9E).
+-define(GL_CONTEXT_CORE_PROFILE_BIT, 16#1).
+-define(GL_CONTEXT_COMPATIBILITY_PROFILE_BIT, 16#2).
+-define(GL_LINES_ADJACENCY, 16#A).
+-define(GL_LINE_STRIP_ADJACENCY, 16#B).
+-define(GL_TRIANGLES_ADJACENCY, 16#C).
+-define(GL_TRIANGLE_STRIP_ADJACENCY, 16#D).
+-define(GL_PROGRAM_POINT_SIZE, 16#8642).
+-define(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, 16#8C29).
+-define(GL_FRAMEBUFFER_ATTACHMENT_LAYERED, 16#8DA7).
+-define(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS, 16#8DA8).
+-define(GL_GEOMETRY_SHADER, 16#8DD9).
+-define(GL_GEOMETRY_VERTICES_OUT, 16#8916).
+-define(GL_GEOMETRY_INPUT_TYPE, 16#8917).
+-define(GL_GEOMETRY_OUTPUT_TYPE, 16#8918).
+-define(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, 16#8DDF).
+-define(GL_MAX_GEOMETRY_OUTPUT_VERTICES, 16#8DE0).
+-define(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, 16#8DE1).
+-define(GL_MAX_VERTEX_OUTPUT_COMPONENTS, 16#9122).
+-define(GL_MAX_GEOMETRY_INPUT_COMPONENTS, 16#9123).
+-define(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, 16#9124).
+-define(GL_MAX_FRAGMENT_INPUT_COMPONENTS, 16#9125).
+-define(GL_CONTEXT_PROFILE_MASK, 16#9126).
+-define(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 16#88FE).
+-define(GL_SAMPLE_SHADING, 16#8C36).
+-define(GL_MIN_SAMPLE_SHADING_VALUE, 16#8C37).
+-define(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, 16#8E5E).
+-define(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, 16#8E5F).
+-define(GL_TEXTURE_CUBE_MAP_ARRAY, 16#9009).
+-define(GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, 16#900A).
+-define(GL_PROXY_TEXTURE_CUBE_MAP_ARRAY, 16#900B).
+-define(GL_SAMPLER_CUBE_MAP_ARRAY, 16#900C).
+-define(GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW, 16#900D).
+-define(GL_INT_SAMPLER_CUBE_MAP_ARRAY, 16#900E).
+-define(GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY, 16#900F).
-define(GL_TEXTURE0_ARB, 16#84C0).
-define(GL_TEXTURE1_ARB, 16#84C1).
-define(GL_TEXTURE2_ARB, 16#84C2).
@@ -1712,6 +1751,211 @@
-define(GL_INVALID_INDEX, 16#FFFFFFFF).
-define(GL_COPY_READ_BUFFER, 16#8F36).
-define(GL_COPY_WRITE_BUFFER, 16#8F37).
+-define(GL_DEPTH_CLAMP, 16#864F).
+-define(GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION, 16#8E4C).
+-define(GL_FIRST_VERTEX_CONVENTION, 16#8E4D).
+-define(GL_LAST_VERTEX_CONVENTION, 16#8E4E).
+-define(GL_PROVOKING_VERTEX, 16#8E4F).
+-define(GL_TEXTURE_CUBE_MAP_SEAMLESS, 16#884F).
+-define(GL_MAX_SERVER_WAIT_TIMEOUT, 16#9111).
+-define(GL_OBJECT_TYPE, 16#9112).
+-define(GL_SYNC_CONDITION, 16#9113).
+-define(GL_SYNC_STATUS, 16#9114).
+-define(GL_SYNC_FLAGS, 16#9115).
+-define(GL_SYNC_FENCE, 16#9116).
+-define(GL_SYNC_GPU_COMMANDS_COMPLETE, 16#9117).
+-define(GL_UNSIGNALED, 16#9118).
+-define(GL_SIGNALED, 16#9119).
+-define(GL_ALREADY_SIGNALED, 16#911A).
+-define(GL_TIMEOUT_EXPIRED, 16#911B).
+-define(GL_CONDITION_SATISFIED, 16#911C).
+-define(GL_WAIT_FAILED, 16#911D).
+-define(GL_SYNC_FLUSH_COMMANDS_BIT, 16#1).
+-define(GL_TIMEOUT_IGNORED, 16#FFFFFFFFFFFFFFFF).
+-define(GL_SAMPLE_POSITION, 16#8E50).
+-define(GL_SAMPLE_MASK, 16#8E51).
+-define(GL_SAMPLE_MASK_VALUE, 16#8E52).
+-define(GL_MAX_SAMPLE_MASK_WORDS, 16#8E59).
+-define(GL_TEXTURE_2D_MULTISAMPLE, 16#9100).
+-define(GL_PROXY_TEXTURE_2D_MULTISAMPLE, 16#9101).
+-define(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 16#9102).
+-define(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY, 16#9103).
+-define(GL_TEXTURE_BINDING_2D_MULTISAMPLE, 16#9104).
+-define(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, 16#9105).
+-define(GL_TEXTURE_SAMPLES, 16#9106).
+-define(GL_TEXTURE_FIXED_SAMPLE_LOCATIONS, 16#9107).
+-define(GL_SAMPLER_2D_MULTISAMPLE, 16#9108).
+-define(GL_INT_SAMPLER_2D_MULTISAMPLE, 16#9109).
+-define(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, 16#910A).
+-define(GL_SAMPLER_2D_MULTISAMPLE_ARRAY, 16#910B).
+-define(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, 16#910C).
+-define(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, 16#910D).
+-define(GL_MAX_COLOR_TEXTURE_SAMPLES, 16#910E).
+-define(GL_MAX_DEPTH_TEXTURE_SAMPLES, 16#910F).
+-define(GL_MAX_INTEGER_SAMPLES, 16#9110).
+-define(GL_SAMPLE_SHADING_ARB, 16#8C36).
+-define(GL_MIN_SAMPLE_SHADING_VALUE_ARB, 16#8C37).
+-define(GL_TEXTURE_CUBE_MAP_ARRAY_ARB, 16#9009).
+-define(GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB, 16#900A).
+-define(GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB, 16#900B).
+-define(GL_SAMPLER_CUBE_MAP_ARRAY_ARB, 16#900C).
+-define(GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB, 16#900D).
+-define(GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB, 16#900E).
+-define(GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB, 16#900F).
+-define(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB, 16#8E5E).
+-define(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB, 16#8E5F).
+-define(GL_SHADER_INCLUDE_ARB, 16#8DAE).
+-define(GL_NAMED_STRING_LENGTH_ARB, 16#8DE9).
+-define(GL_NAMED_STRING_TYPE_ARB, 16#8DEA).
+-define(GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, 16#8E8C).
+-define(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB, 16#8E8D).
+-define(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, 16#8E8E).
+-define(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, 16#8E8F).
+-define(GL_SRC1_COLOR, 16#88F9).
+-define(GL_ONE_MINUS_SRC1_COLOR, 16#88FA).
+-define(GL_ONE_MINUS_SRC1_ALPHA, 16#88FB).
+-define(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, 16#88FC).
+-define(GL_ANY_SAMPLES_PASSED, 16#8C2F).
+-define(GL_SAMPLER_BINDING, 16#8919).
+-define(GL_RGB10_A2UI, 16#906F).
+-define(GL_TEXTURE_SWIZZLE_R, 16#8E42).
+-define(GL_TEXTURE_SWIZZLE_G, 16#8E43).
+-define(GL_TEXTURE_SWIZZLE_B, 16#8E44).
+-define(GL_TEXTURE_SWIZZLE_A, 16#8E45).
+-define(GL_TEXTURE_SWIZZLE_RGBA, 16#8E46).
+-define(GL_TIME_ELAPSED, 16#88BF).
+-define(GL_TIMESTAMP, 16#8E28).
+-define(GL_INT_2_10_10_10_REV, 16#8D9F).
+-define(GL_DRAW_INDIRECT_BUFFER, 16#8F3F).
+-define(GL_DRAW_INDIRECT_BUFFER_BINDING, 16#8F43).
+-define(GL_GEOMETRY_SHADER_INVOCATIONS, 16#887F).
+-define(GL_MAX_GEOMETRY_SHADER_INVOCATIONS, 16#8E5A).
+-define(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, 16#8E5B).
+-define(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, 16#8E5C).
+-define(GL_FRAGMENT_INTERPOLATION_OFFSET_BITS, 16#8E5D).
+-define(GL_DOUBLE_VEC2, 16#8FFC).
+-define(GL_DOUBLE_VEC3, 16#8FFD).
+-define(GL_DOUBLE_VEC4, 16#8FFE).
+-define(GL_DOUBLE_MAT2, 16#8F46).
+-define(GL_DOUBLE_MAT3, 16#8F47).
+-define(GL_DOUBLE_MAT4, 16#8F48).
+-define(GL_DOUBLE_MAT2x3, 16#8F49).
+-define(GL_DOUBLE_MAT2x4, 16#8F4A).
+-define(GL_DOUBLE_MAT3x2, 16#8F4B).
+-define(GL_DOUBLE_MAT3x4, 16#8F4C).
+-define(GL_DOUBLE_MAT4x2, 16#8F4D).
+-define(GL_DOUBLE_MAT4x3, 16#8F4E).
+-define(GL_ACTIVE_SUBROUTINES, 16#8DE5).
+-define(GL_ACTIVE_SUBROUTINE_UNIFORMS, 16#8DE6).
+-define(GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, 16#8E47).
+-define(GL_ACTIVE_SUBROUTINE_MAX_LENGTH, 16#8E48).
+-define(GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH, 16#8E49).
+-define(GL_MAX_SUBROUTINES, 16#8DE7).
+-define(GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS, 16#8DE8).
+-define(GL_NUM_COMPATIBLE_SUBROUTINES, 16#8E4A).
+-define(GL_COMPATIBLE_SUBROUTINES, 16#8E4B).
+-define(GL_PATCHES, 16#E).
+-define(GL_PATCH_VERTICES, 16#8E72).
+-define(GL_PATCH_DEFAULT_INNER_LEVEL, 16#8E73).
+-define(GL_PATCH_DEFAULT_OUTER_LEVEL, 16#8E74).
+-define(GL_TESS_CONTROL_OUTPUT_VERTICES, 16#8E75).
+-define(GL_TESS_GEN_MODE, 16#8E76).
+-define(GL_TESS_GEN_SPACING, 16#8E77).
+-define(GL_TESS_GEN_VERTEX_ORDER, 16#8E78).
+-define(GL_TESS_GEN_POINT_MODE, 16#8E79).
+-define(GL_ISOLINES, 16#8E7A).
+-define(GL_FRACTIONAL_ODD, 16#8E7B).
+-define(GL_FRACTIONAL_EVEN, 16#8E7C).
+-define(GL_MAX_PATCH_VERTICES, 16#8E7D).
+-define(GL_MAX_TESS_GEN_LEVEL, 16#8E7E).
+-define(GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS, 16#8E7F).
+-define(GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS, 16#8E80).
+-define(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, 16#8E81).
+-define(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, 16#8E82).
+-define(GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS, 16#8E83).
+-define(GL_MAX_TESS_PATCH_COMPONENTS, 16#8E84).
+-define(GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS, 16#8E85).
+-define(GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS, 16#8E86).
+-define(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, 16#8E89).
+-define(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, 16#8E8A).
+-define(GL_MAX_TESS_CONTROL_INPUT_COMPONENTS, 16#886C).
+-define(GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS, 16#886D).
+-define(GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS, 16#8E1E).
+-define(GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS, 16#8E1F).
+-define(GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER, 16#84F0).
+-define(GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER, 16#84F1).
+-define(GL_TESS_EVALUATION_SHADER, 16#8E87).
+-define(GL_TESS_CONTROL_SHADER, 16#8E88).
+-define(GL_TRANSFORM_FEEDBACK, 16#8E22).
+-define(GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED, 16#8E23).
+-define(GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE, 16#8E24).
+-define(GL_TRANSFORM_FEEDBACK_BINDING, 16#8E25).
+-define(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, 16#8E70).
+-define(GL_MAX_VERTEX_STREAMS, 16#8E71).
+-define(GL_FIXED, 16#140C).
+-define(GL_IMPLEMENTATION_COLOR_READ_TYPE, 16#8B9A).
+-define(GL_IMPLEMENTATION_COLOR_READ_FORMAT, 16#8B9B).
+-define(GL_LOW_FLOAT, 16#8DF0).
+-define(GL_MEDIUM_FLOAT, 16#8DF1).
+-define(GL_HIGH_FLOAT, 16#8DF2).
+-define(GL_LOW_INT, 16#8DF3).
+-define(GL_MEDIUM_INT, 16#8DF4).
+-define(GL_HIGH_INT, 16#8DF5).
+-define(GL_SHADER_COMPILER, 16#8DFA).
+-define(GL_NUM_SHADER_BINARY_FORMATS, 16#8DF9).
+-define(GL_MAX_VERTEX_UNIFORM_VECTORS, 16#8DFB).
+-define(GL_MAX_VARYING_VECTORS, 16#8DFC).
+-define(GL_MAX_FRAGMENT_UNIFORM_VECTORS, 16#8DFD).
+-define(GL_PROGRAM_BINARY_RETRIEVABLE_HINT, 16#8257).
+-define(GL_PROGRAM_BINARY_LENGTH, 16#8741).
+-define(GL_NUM_PROGRAM_BINARY_FORMATS, 16#87FE).
+-define(GL_PROGRAM_BINARY_FORMATS, 16#87FF).
+-define(GL_VERTEX_SHADER_BIT, 16#1).
+-define(GL_FRAGMENT_SHADER_BIT, 16#2).
+-define(GL_GEOMETRY_SHADER_BIT, 16#4).
+-define(GL_TESS_CONTROL_SHADER_BIT, 16#8).
+-define(GL_TESS_EVALUATION_SHADER_BIT, 16#10).
+-define(GL_ALL_SHADER_BITS, 16#FFFFFFFF).
+-define(GL_PROGRAM_SEPARABLE, 16#8258).
+-define(GL_ACTIVE_PROGRAM, 16#8259).
+-define(GL_PROGRAM_PIPELINE_BINDING, 16#825A).
+-define(GL_MAX_VIEWPORTS, 16#825B).
+-define(GL_VIEWPORT_SUBPIXEL_BITS, 16#825C).
+-define(GL_VIEWPORT_BOUNDS_RANGE, 16#825D).
+-define(GL_LAYER_PROVOKING_VERTEX, 16#825E).
+-define(GL_VIEWPORT_INDEX_PROVOKING_VERTEX, 16#825F).
+-define(GL_UNDEFINED_VERTEX, 16#8260).
+-define(GL_SYNC_CL_EVENT_ARB, 16#8240).
+-define(GL_SYNC_CL_EVENT_COMPLETE_ARB, 16#8241).
+-define(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB, 16#8242).
+-define(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB, 16#8243).
+-define(GL_DEBUG_CALLBACK_FUNCTION_ARB, 16#8244).
+-define(GL_DEBUG_CALLBACK_USER_PARAM_ARB, 16#8245).
+-define(GL_DEBUG_SOURCE_API_ARB, 16#8246).
+-define(GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, 16#8247).
+-define(GL_DEBUG_SOURCE_SHADER_COMPILER_ARB, 16#8248).
+-define(GL_DEBUG_SOURCE_THIRD_PARTY_ARB, 16#8249).
+-define(GL_DEBUG_SOURCE_APPLICATION_ARB, 16#824A).
+-define(GL_DEBUG_SOURCE_OTHER_ARB, 16#824B).
+-define(GL_DEBUG_TYPE_ERROR_ARB, 16#824C).
+-define(GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, 16#824D).
+-define(GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, 16#824E).
+-define(GL_DEBUG_TYPE_PORTABILITY_ARB, 16#824F).
+-define(GL_DEBUG_TYPE_PERFORMANCE_ARB, 16#8250).
+-define(GL_DEBUG_TYPE_OTHER_ARB, 16#8251).
+-define(GL_MAX_DEBUG_MESSAGE_LENGTH_ARB, 16#9143).
+-define(GL_MAX_DEBUG_LOGGED_MESSAGES_ARB, 16#9144).
+-define(GL_DEBUG_LOGGED_MESSAGES_ARB, 16#9145).
+-define(GL_DEBUG_SEVERITY_HIGH_ARB, 16#9146).
+-define(GL_DEBUG_SEVERITY_MEDIUM_ARB, 16#9147).
+-define(GL_DEBUG_SEVERITY_LOW_ARB, 16#9148).
+-define(GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB, 16#4).
+-define(GL_LOSE_CONTEXT_ON_RESET_ARB, 16#8252).
+-define(GL_GUILTY_CONTEXT_RESET_ARB, 16#8253).
+-define(GL_INNOCENT_CONTEXT_RESET_ARB, 16#8254).
+-define(GL_UNKNOWN_CONTEXT_RESET_ARB, 16#8255).
+-define(GL_RESET_NOTIFICATION_STRATEGY_ARB, 16#8256).
+-define(GL_NO_RESET_NOTIFICATION_ARB, 16#8261).
-define(GL_CONSTANT_COLOR_EXT, 16#8001).
-define(GL_ONE_MINUS_CONSTANT_COLOR_EXT, 16#8002).
-define(GL_CONSTANT_ALPHA_EXT, 16#8003).
@@ -2921,9 +3165,9 @@
-define(GL_ACTIVE_STENCIL_FACE_EXT, 16#8911).
-define(GL_TEXT_FRAGMENT_SHADER_ATI, 16#8200).
-define(GL_UNPACK_CLIENT_STORAGE_APPLE, 16#85B2).
--define(GL_ELEMENT_ARRAY_APPLE, 16#8768).
--define(GL_ELEMENT_ARRAY_TYPE_APPLE, 16#8769).
--define(GL_ELEMENT_ARRAY_POINTER_APPLE, 16#876A).
+-define(GL_ELEMENT_ARRAY_APPLE, 16#8A0C).
+-define(GL_ELEMENT_ARRAY_TYPE_APPLE, 16#8A0D).
+-define(GL_ELEMENT_ARRAY_POINTER_APPLE, 16#8A0E).
-define(GL_DRAW_PIXELS_APPLE, 16#8A0A).
-define(GL_FENCE_APPLE, 16#8A0B).
-define(GL_VERTEX_ARRAY_BINDING_APPLE, 16#85B5).
@@ -2931,6 +3175,7 @@
-define(GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE, 16#851E).
-define(GL_VERTEX_ARRAY_STORAGE_HINT_APPLE, 16#851F).
-define(GL_VERTEX_ARRAY_RANGE_POINTER_APPLE, 16#8521).
+-define(GL_STORAGE_CLIENT_APPLE, 16#85B4).
-define(GL_STORAGE_CACHED_APPLE, 16#85BE).
-define(GL_STORAGE_SHARED_APPLE, 16#85BF).
-define(GL_YCBCR_422_APPLE, 16#85B9).
@@ -3244,6 +3489,12 @@
-define(GL_SEPARATE_ATTRIBS_NV, 16#8C8D).
-define(GL_TRANSFORM_FEEDBACK_BUFFER_NV, 16#8C8E).
-define(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV, 16#8C8F).
+-define(GL_LAYER_NV, 16#8DAA).
+-define(GL_NEXT_BUFFER_NV, -2).
+-define(GL_SKIP_COMPONENTS4_NV, -3).
+-define(GL_SKIP_COMPONENTS3_NV, -4).
+-define(GL_SKIP_COMPONENTS2_NV, -5).
+-define(GL_SKIP_COMPONENTS1_NV, -6).
-define(GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT, 16#8DE2).
-define(GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT, 16#8DE3).
-define(GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT, 16#8DE4).
@@ -3335,11 +3586,11 @@
-define(GL_SAMPLE_MASK_VALUE_NV, 16#8E52).
-define(GL_TEXTURE_BINDING_RENDERBUFFER_NV, 16#8E53).
-define(GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV, 16#8E54).
--define(GL_MAX_SAMPLE_MASK_WORDS_NV, 16#8E59).
-define(GL_TEXTURE_RENDERBUFFER_NV, 16#8E55).
-define(GL_SAMPLER_RENDERBUFFER_NV, 16#8E56).
-define(GL_INT_SAMPLER_RENDERBUFFER_NV, 16#8E57).
-define(GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV, 16#8E58).
+-define(GL_MAX_SAMPLE_MASK_WORDS_NV, 16#8E59).
-define(GL_TRANSFORM_FEEDBACK_NV, 16#8E22).
-define(GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV, 16#8E23).
-define(GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV, 16#8E24).
@@ -3365,6 +3616,247 @@
-define(GL_FIRST_VERTEX_CONVENTION_EXT, 16#8E4D).
-define(GL_LAST_VERTEX_CONVENTION_EXT, 16#8E4E).
-define(GL_PROVOKING_VERTEX_EXT, 16#8E4F).
+-define(GL_ALPHA_SNORM, 16#9010).
+-define(GL_LUMINANCE_SNORM, 16#9011).
+-define(GL_LUMINANCE_ALPHA_SNORM, 16#9012).
+-define(GL_INTENSITY_SNORM, 16#9013).
+-define(GL_ALPHA8_SNORM, 16#9014).
+-define(GL_LUMINANCE8_SNORM, 16#9015).
+-define(GL_LUMINANCE8_ALPHA8_SNORM, 16#9016).
+-define(GL_INTENSITY8_SNORM, 16#9017).
+-define(GL_ALPHA16_SNORM, 16#9018).
+-define(GL_LUMINANCE16_SNORM, 16#9019).
+-define(GL_LUMINANCE16_ALPHA16_SNORM, 16#901A).
+-define(GL_INTENSITY16_SNORM, 16#901B).
+-define(GL_TEXTURE_RANGE_LENGTH_APPLE, 16#85B7).
+-define(GL_TEXTURE_RANGE_POINTER_APPLE, 16#85B8).
+-define(GL_TEXTURE_STORAGE_HINT_APPLE, 16#85BC).
+-define(GL_STORAGE_PRIVATE_APPLE, 16#85BD).
+-define(GL_HALF_APPLE, 16#140B).
+-define(GL_RGBA_FLOAT32_APPLE, 16#8814).
+-define(GL_RGB_FLOAT32_APPLE, 16#8815).
+-define(GL_ALPHA_FLOAT32_APPLE, 16#8816).
+-define(GL_INTENSITY_FLOAT32_APPLE, 16#8817).
+-define(GL_LUMINANCE_FLOAT32_APPLE, 16#8818).
+-define(GL_LUMINANCE_ALPHA_FLOAT32_APPLE, 16#8819).
+-define(GL_RGBA_FLOAT16_APPLE, 16#881A).
+-define(GL_RGB_FLOAT16_APPLE, 16#881B).
+-define(GL_ALPHA_FLOAT16_APPLE, 16#881C).
+-define(GL_INTENSITY_FLOAT16_APPLE, 16#881D).
+-define(GL_LUMINANCE_FLOAT16_APPLE, 16#881E).
+-define(GL_LUMINANCE_ALPHA_FLOAT16_APPLE, 16#881F).
+-define(GL_COLOR_FLOAT_APPLE, 16#8A0F).
+-define(GL_VERTEX_ATTRIB_MAP1_APPLE, 16#8A00).
+-define(GL_VERTEX_ATTRIB_MAP2_APPLE, 16#8A01).
+-define(GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE, 16#8A02).
+-define(GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE, 16#8A03).
+-define(GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE, 16#8A04).
+-define(GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE, 16#8A05).
+-define(GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE, 16#8A06).
+-define(GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE, 16#8A07).
+-define(GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE, 16#8A08).
+-define(GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE, 16#8A09).
+-define(GL_AUX_DEPTH_STENCIL_APPLE, 16#8A14).
+-define(GL_BUFFER_OBJECT_APPLE, 16#85B3).
+-define(GL_RELEASED_APPLE, 16#8A19).
+-define(GL_VOLATILE_APPLE, 16#8A1A).
+-define(GL_RETAINED_APPLE, 16#8A1B).
+-define(GL_UNDEFINED_APPLE, 16#8A1C).
+-define(GL_PURGEABLE_APPLE, 16#8A1D).
+-define(GL_PACK_ROW_BYTES_APPLE, 16#8A15).
+-define(GL_UNPACK_ROW_BYTES_APPLE, 16#8A16).
+-define(GL_RGB_422_APPLE, 16#8A1F).
+-define(GL_VIDEO_BUFFER_NV, 16#9020).
+-define(GL_VIDEO_BUFFER_BINDING_NV, 16#9021).
+-define(GL_FIELD_UPPER_NV, 16#9022).
+-define(GL_FIELD_LOWER_NV, 16#9023).
+-define(GL_NUM_VIDEO_CAPTURE_STREAMS_NV, 16#9024).
+-define(GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV, 16#9025).
+-define(GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV, 16#9026).
+-define(GL_LAST_VIDEO_CAPTURE_STATUS_NV, 16#9027).
+-define(GL_VIDEO_BUFFER_PITCH_NV, 16#9028).
+-define(GL_VIDEO_COLOR_CONVERSION_MATRIX_NV, 16#9029).
+-define(GL_VIDEO_COLOR_CONVERSION_MAX_NV, 16#902A).
+-define(GL_VIDEO_COLOR_CONVERSION_MIN_NV, 16#902B).
+-define(GL_VIDEO_COLOR_CONVERSION_OFFSET_NV, 16#902C).
+-define(GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV, 16#902D).
+-define(GL_PARTIAL_SUCCESS_NV, 16#902E).
+-define(GL_SUCCESS_NV, 16#902F).
+-define(GL_FAILURE_NV, 16#9030).
+-define(GL_YCBYCR8_422_NV, 16#9031).
+-define(GL_YCBAYCR8A_4224_NV, 16#9032).
+-define(GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV, 16#9033).
+-define(GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV, 16#9034).
+-define(GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV, 16#9035).
+-define(GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV, 16#9036).
+-define(GL_Z4Y12Z4CB12Z4CR12_444_NV, 16#9037).
+-define(GL_VIDEO_CAPTURE_FRAME_WIDTH_NV, 16#9038).
+-define(GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV, 16#9039).
+-define(GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV, 16#903A).
+-define(GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV, 16#903B).
+-define(GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV, 16#903C).
+-define(GL_ACTIVE_PROGRAM_EXT, 16#8B8D).
+-define(GL_BUFFER_GPU_ADDRESS_NV, 16#8F1D).
+-define(GL_GPU_ADDRESS_NV, 16#8F34).
+-define(GL_MAX_SHADER_BUFFER_ADDRESS_NV, 16#8F35).
+-define(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV, 16#8F1E).
+-define(GL_ELEMENT_ARRAY_UNIFIED_NV, 16#8F1F).
+-define(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 16#8F20).
+-define(GL_VERTEX_ARRAY_ADDRESS_NV, 16#8F21).
+-define(GL_NORMAL_ARRAY_ADDRESS_NV, 16#8F22).
+-define(GL_COLOR_ARRAY_ADDRESS_NV, 16#8F23).
+-define(GL_INDEX_ARRAY_ADDRESS_NV, 16#8F24).
+-define(GL_TEXTURE_COORD_ARRAY_ADDRESS_NV, 16#8F25).
+-define(GL_EDGE_FLAG_ARRAY_ADDRESS_NV, 16#8F26).
+-define(GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV, 16#8F27).
+-define(GL_FOG_COORD_ARRAY_ADDRESS_NV, 16#8F28).
+-define(GL_ELEMENT_ARRAY_ADDRESS_NV, 16#8F29).
+-define(GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV, 16#8F2A).
+-define(GL_VERTEX_ARRAY_LENGTH_NV, 16#8F2B).
+-define(GL_NORMAL_ARRAY_LENGTH_NV, 16#8F2C).
+-define(GL_COLOR_ARRAY_LENGTH_NV, 16#8F2D).
+-define(GL_INDEX_ARRAY_LENGTH_NV, 16#8F2E).
+-define(GL_TEXTURE_COORD_ARRAY_LENGTH_NV, 16#8F2F).
+-define(GL_EDGE_FLAG_ARRAY_LENGTH_NV, 16#8F30).
+-define(GL_SECONDARY_COLOR_ARRAY_LENGTH_NV, 16#8F31).
+-define(GL_FOG_COORD_ARRAY_LENGTH_NV, 16#8F32).
+-define(GL_ELEMENT_ARRAY_LENGTH_NV, 16#8F33).
+-define(GL_DRAW_INDIRECT_UNIFIED_NV, 16#8F40).
+-define(GL_DRAW_INDIRECT_ADDRESS_NV, 16#8F41).
+-define(GL_DRAW_INDIRECT_LENGTH_NV, 16#8F42).
+-define(GL_MAX_IMAGE_UNITS_EXT, 16#8F38).
+-define(GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT, 16#8F39).
+-define(GL_IMAGE_BINDING_NAME_EXT, 16#8F3A).
+-define(GL_IMAGE_BINDING_LEVEL_EXT, 16#8F3B).
+-define(GL_IMAGE_BINDING_LAYERED_EXT, 16#8F3C).
+-define(GL_IMAGE_BINDING_LAYER_EXT, 16#8F3D).
+-define(GL_IMAGE_BINDING_ACCESS_EXT, 16#8F3E).
+-define(GL_IMAGE_1D_EXT, 16#904C).
+-define(GL_IMAGE_2D_EXT, 16#904D).
+-define(GL_IMAGE_3D_EXT, 16#904E).
+-define(GL_IMAGE_2D_RECT_EXT, 16#904F).
+-define(GL_IMAGE_CUBE_EXT, 16#9050).
+-define(GL_IMAGE_BUFFER_EXT, 16#9051).
+-define(GL_IMAGE_1D_ARRAY_EXT, 16#9052).
+-define(GL_IMAGE_2D_ARRAY_EXT, 16#9053).
+-define(GL_IMAGE_CUBE_MAP_ARRAY_EXT, 16#9054).
+-define(GL_IMAGE_2D_MULTISAMPLE_EXT, 16#9055).
+-define(GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT, 16#9056).
+-define(GL_INT_IMAGE_1D_EXT, 16#9057).
+-define(GL_INT_IMAGE_2D_EXT, 16#9058).
+-define(GL_INT_IMAGE_3D_EXT, 16#9059).
+-define(GL_INT_IMAGE_2D_RECT_EXT, 16#905A).
+-define(GL_INT_IMAGE_CUBE_EXT, 16#905B).
+-define(GL_INT_IMAGE_BUFFER_EXT, 16#905C).
+-define(GL_INT_IMAGE_1D_ARRAY_EXT, 16#905D).
+-define(GL_INT_IMAGE_2D_ARRAY_EXT, 16#905E).
+-define(GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT, 16#905F).
+-define(GL_INT_IMAGE_2D_MULTISAMPLE_EXT, 16#9060).
+-define(GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT, 16#9061).
+-define(GL_UNSIGNED_INT_IMAGE_1D_EXT, 16#9062).
+-define(GL_UNSIGNED_INT_IMAGE_2D_EXT, 16#9063).
+-define(GL_UNSIGNED_INT_IMAGE_3D_EXT, 16#9064).
+-define(GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT, 16#9065).
+-define(GL_UNSIGNED_INT_IMAGE_CUBE_EXT, 16#9066).
+-define(GL_UNSIGNED_INT_IMAGE_BUFFER_EXT, 16#9067).
+-define(GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT, 16#9068).
+-define(GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT, 16#9069).
+-define(GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT, 16#906A).
+-define(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT, 16#906B).
+-define(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT, 16#906C).
+-define(GL_MAX_IMAGE_SAMPLES_EXT, 16#906D).
+-define(GL_IMAGE_BINDING_FORMAT_EXT, 16#906E).
+-define(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT, 16#1).
+-define(GL_ELEMENT_ARRAY_BARRIER_BIT_EXT, 16#2).
+-define(GL_UNIFORM_BARRIER_BIT_EXT, 16#4).
+-define(GL_TEXTURE_FETCH_BARRIER_BIT_EXT, 16#8).
+-define(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT, 16#20).
+-define(GL_COMMAND_BARRIER_BIT_EXT, 16#40).
+-define(GL_PIXEL_BUFFER_BARRIER_BIT_EXT, 16#80).
+-define(GL_TEXTURE_UPDATE_BARRIER_BIT_EXT, 16#100).
+-define(GL_BUFFER_UPDATE_BARRIER_BIT_EXT, 16#200).
+-define(GL_FRAMEBUFFER_BARRIER_BIT_EXT, 16#400).
+-define(GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT, 16#800).
+-define(GL_ATOMIC_COUNTER_BARRIER_BIT_EXT, 16#1000).
+-define(GL_ALL_BARRIER_BITS_EXT, 16#FFFFFFFF).
+-define(GL_DOUBLE_VEC2_EXT, 16#8FFC).
+-define(GL_DOUBLE_VEC3_EXT, 16#8FFD).
+-define(GL_DOUBLE_VEC4_EXT, 16#8FFE).
+-define(GL_DOUBLE_MAT2_EXT, 16#8F46).
+-define(GL_DOUBLE_MAT3_EXT, 16#8F47).
+-define(GL_DOUBLE_MAT4_EXT, 16#8F48).
+-define(GL_DOUBLE_MAT2x3_EXT, 16#8F49).
+-define(GL_DOUBLE_MAT2x4_EXT, 16#8F4A).
+-define(GL_DOUBLE_MAT3x2_EXT, 16#8F4B).
+-define(GL_DOUBLE_MAT3x4_EXT, 16#8F4C).
+-define(GL_DOUBLE_MAT4x2_EXT, 16#8F4D).
+-define(GL_DOUBLE_MAT4x3_EXT, 16#8F4E).
+-define(GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV, 16#8E5A).
+-define(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV, 16#8E5B).
+-define(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV, 16#8E5C).
+-define(GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV, 16#8E5D).
+-define(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV, 16#8E5E).
+-define(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV, 16#8E5F).
+-define(GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV, 16#8F44).
+-define(GL_MAX_PROGRAM_SUBROUTINE_NUM_NV, 16#8F45).
+-define(GL_INT64_NV, 16#140E).
+-define(GL_UNSIGNED_INT64_NV, 16#140F).
+-define(GL_INT8_NV, 16#8FE0).
+-define(GL_INT8_VEC2_NV, 16#8FE1).
+-define(GL_INT8_VEC3_NV, 16#8FE2).
+-define(GL_INT8_VEC4_NV, 16#8FE3).
+-define(GL_INT16_NV, 16#8FE4).
+-define(GL_INT16_VEC2_NV, 16#8FE5).
+-define(GL_INT16_VEC3_NV, 16#8FE6).
+-define(GL_INT16_VEC4_NV, 16#8FE7).
+-define(GL_INT64_VEC2_NV, 16#8FE9).
+-define(GL_INT64_VEC3_NV, 16#8FEA).
+-define(GL_INT64_VEC4_NV, 16#8FEB).
+-define(GL_UNSIGNED_INT8_NV, 16#8FEC).
+-define(GL_UNSIGNED_INT8_VEC2_NV, 16#8FED).
+-define(GL_UNSIGNED_INT8_VEC3_NV, 16#8FEE).
+-define(GL_UNSIGNED_INT8_VEC4_NV, 16#8FEF).
+-define(GL_UNSIGNED_INT16_NV, 16#8FF0).
+-define(GL_UNSIGNED_INT16_VEC2_NV, 16#8FF1).
+-define(GL_UNSIGNED_INT16_VEC3_NV, 16#8FF2).
+-define(GL_UNSIGNED_INT16_VEC4_NV, 16#8FF3).
+-define(GL_UNSIGNED_INT64_VEC2_NV, 16#8FF5).
+-define(GL_UNSIGNED_INT64_VEC3_NV, 16#8FF6).
+-define(GL_UNSIGNED_INT64_VEC4_NV, 16#8FF7).
+-define(GL_FLOAT16_NV, 16#8FF8).
+-define(GL_FLOAT16_VEC2_NV, 16#8FF9).
+-define(GL_FLOAT16_VEC3_NV, 16#8FFA).
+-define(GL_FLOAT16_VEC4_NV, 16#8FFB).
+-define(GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV, 16#10).
+-define(GL_MAX_PROGRAM_PATCH_ATTRIBS_NV, 16#86D8).
+-define(GL_TESS_CONTROL_PROGRAM_NV, 16#891E).
+-define(GL_TESS_EVALUATION_PROGRAM_NV, 16#891F).
+-define(GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV, 16#8C74).
+-define(GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV, 16#8C75).
+-define(GL_COVERAGE_SAMPLES_NV, 16#80A9).
+-define(GL_COLOR_SAMPLES_NV, 16#8E20).
+-define(GL_DATA_BUFFER_AMD, 16#9151).
+-define(GL_PERFORMANCE_MONITOR_AMD, 16#9152).
+-define(GL_QUERY_OBJECT_AMD, 16#9153).
+-define(GL_VERTEX_ARRAY_OBJECT_AMD, 16#9154).
+-define(GL_SAMPLER_OBJECT_AMD, 16#9155).
+-define(GL_MAX_DEBUG_LOGGED_MESSAGES_AMD, 16#9144).
+-define(GL_DEBUG_LOGGED_MESSAGES_AMD, 16#9145).
+-define(GL_DEBUG_SEVERITY_HIGH_AMD, 16#9146).
+-define(GL_DEBUG_SEVERITY_MEDIUM_AMD, 16#9147).
+-define(GL_DEBUG_SEVERITY_LOW_AMD, 16#9148).
+-define(GL_DEBUG_CATEGORY_API_ERROR_AMD, 16#9149).
+-define(GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD, 16#914A).
+-define(GL_DEBUG_CATEGORY_DEPRECATION_AMD, 16#914B).
+-define(GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD, 16#914C).
+-define(GL_DEBUG_CATEGORY_PERFORMANCE_AMD, 16#914D).
+-define(GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD, 16#914E).
+-define(GL_DEBUG_CATEGORY_APPLICATION_AMD, 16#914F).
+-define(GL_DEBUG_CATEGORY_OTHER_AMD, 16#9150).
+-define(GL_SURFACE_STATE_NV, 16#86EB).
+-define(GL_SURFACE_REGISTERED_NV, 16#86FD).
+-define(GL_SURFACE_MAPPED_NV, 16#8700).
+-define(GL_WRITE_DISCARD_NV, 16#88BE).
-define(GL_VERSION_1_2, 1).
-define(GL_VERSION_1_2_DEPRECATED, 1).
-define(GL_VERSION_1_3, 1).
@@ -3375,8 +3867,11 @@
-define(GL_VERSION_2_0, 1).
-define(GL_VERSION_2_1, 1).
-define(GL_VERSION_3_0, 1).
--define(GL_VERSION_3_0_DEPRECATED, 1).
-define(GL_VERSION_3_1, 1).
+-define(GL_VERSION_3_2, 1).
+-define(GL_VERSION_3_3, 1).
+-define(GL_VERSION_4_0, 1).
+-define(GL_VERSION_4_1, 1).
-define(GL_ARB_multitexture, 1).
-define(GL_ARB_transpose_matrix, 1).
-define(GL_ARB_multisample, 1).
@@ -3428,6 +3923,46 @@
-define(GL_ARB_compatibility, 1).
-define(GL_ARB_copy_buffer, 1).
-define(GL_ARB_shader_texture_lod, 1).
+-define(GL_ARB_depth_clamp, 1).
+-define(GL_ARB_draw_elements_base_vertex, 1).
+-define(GL_ARB_fragment_coord_conventions, 1).
+-define(GL_ARB_provoking_vertex, 1).
+-define(GL_ARB_seamless_cube_map, 1).
+-define(GL_ARB_sync, 1).
+-define(GL_ARB_texture_multisample, 1).
+-define(GL_ARB_vertex_array_bgra, 1).
+-define(GL_ARB_draw_buffers_blend, 1).
+-define(GL_ARB_sample_shading, 1).
+-define(GL_ARB_texture_cube_map_array, 1).
+-define(GL_ARB_texture_gather, 1).
+-define(GL_ARB_texture_query_lod, 1).
+-define(GL_ARB_shading_language_include, 1).
+-define(GL_ARB_texture_compression_bptc, 1).
+-define(GL_ARB_blend_func_extended, 1).
+-define(GL_ARB_explicit_attrib_location, 1).
+-define(GL_ARB_occlusion_query2, 1).
+-define(GL_ARB_sampler_objects, 1).
+-define(GL_ARB_texture_rgb10_a2ui, 1).
+-define(GL_ARB_texture_swizzle, 1).
+-define(GL_ARB_timer_query, 1).
+-define(GL_ARB_vertex_type_2_10_10_10_rev, 1).
+-define(GL_ARB_draw_indirect, 1).
+-define(GL_ARB_gpu_shader5, 1).
+-define(GL_ARB_gpu_shader_fp64, 1).
+-define(GL_ARB_shader_subroutine, 1).
+-define(GL_ARB_tessellation_shader, 1).
+-define(GL_ARB_texture_buffer_object_rgb32, 1).
+-define(GL_ARB_transform_feedback2, 1).
+-define(GL_ARB_transform_feedback3, 1).
+-define(GL_ARB_ES2_compatibility, 1).
+-define(GL_ARB_get_program_binary, 1).
+-define(GL_ARB_separate_shader_objects, 1).
+-define(GL_ARB_vertex_attrib_64bit, 1).
+-define(GL_ARB_viewport_array, 1).
+-define(GL_ARB_cl_event, 1).
+-define(GL_ARB_debug_output, 1).
+-define(GL_ARB_robustness, 1).
+-define(GL_ARB_shader_stencil_export, 1).
-define(GL_EXT_abgr, 1).
-define(GL_EXT_blend_color, 1).
-define(GL_EXT_polygon_offset, 1).
@@ -3684,3 +4219,34 @@
-define(GL_AMD_texture_texture4, 1).
-define(GL_AMD_vertex_shader_tesselator, 1).
-define(GL_EXT_provoking_vertex, 1).
+-define(GL_EXT_texture_snorm, 1).
+-define(GL_AMD_draw_buffers_blend, 1).
+-define(GL_APPLE_texture_range, 1).
+-define(GL_APPLE_float_pixels, 1).
+-define(GL_APPLE_vertex_program_evaluators, 1).
+-define(GL_APPLE_aux_depth_stencil, 1).
+-define(GL_APPLE_object_purgeable, 1).
+-define(GL_APPLE_row_bytes, 1).
+-define(GL_APPLE_rgb_422, 1).
+-define(GL_NV_video_capture, 1).
+-define(GL_NV_copy_image, 1).
+-define(GL_EXT_separate_shader_objects, 1).
+-define(GL_NV_parameter_buffer_object2, 1).
+-define(GL_NV_shader_buffer_load, 1).
+-define(GL_NV_vertex_buffer_unified_memory, 1).
+-define(GL_NV_texture_barrier, 1).
+-define(GL_AMD_shader_stencil_export, 1).
+-define(GL_AMD_seamless_cubemap_per_texture, 1).
+-define(GL_AMD_conservative_depth, 1).
+-define(GL_EXT_shader_image_load_store, 1).
+-define(GL_EXT_vertex_attrib_64bit, 1).
+-define(GL_NV_gpu_program5, 1).
+-define(GL_NV_gpu_shader5, 1).
+-define(GL_NV_shader_buffer_store, 1).
+-define(GL_NV_tessellation_program5, 1).
+-define(GL_NV_vertex_attrib_integer_64bit, 1).
+-define(GL_NV_multisample_coverage, 1).
+-define(GL_AMD_name_gen_delete, 1).
+-define(GL_AMD_debug_output, 1).
+-define(GL_NV_vdpau_interop, 1).
+-define(GL_AMD_transform_feedback3_lines_triangles, 1).
diff --git a/lib/wx/src/Makefile b/lib/wx/src/Makefile
index a9fd468959..3cc668375f 100644
--- a/lib/wx/src/Makefile
+++ b/lib/wx/src/Makefile
@@ -47,7 +47,6 @@ GEN_FILES = $(wildcard gen/wx*.erl) \
GEN_MODS = $(GEN_FILES:gen/%.erl= %,\n )
GEN_HRL = \
- $(EGEN)/gl_debug.hrl \
$(EGEN)/wxe_debug.hrl \
$(EGEN)/wxe_funcs.hrl
diff --git a/lib/wx/src/gen/gl.erl b/lib/wx/src/gen/gl.erl
index 62d0ff6aed..0ebf51d28a 100644
--- a/lib/wx/src/gen/gl.erl
+++ b/lib/wx/src/gen/gl.erl
@@ -25,14 +25,13 @@
%%
%% Booleans are represented by integers 0 and 1.
-%% @type wx_mem(). see wx.erl on memory allocation functions
+%% @type mem(). memory block
%% @type enum(). An integer defined in gl.hrl
%% @type offset(). An integer which is an offset in an array
%% @type clamp(). A float clamped between 0.0 - 1.0
-module(gl).
-compile(inline).
--include("wxe.hrl").
-define(GLenum,32/native-unsigned).
-define(GLboolean,8/native-unsigned).
-define(GLbitfield,32/native-unsigned).
@@ -51,6 +50,13 @@
-define(GLintptr,64/native-unsigned).
-define(GLUquadric,64/native-unsigned).
-define(GLhandleARB,64/native-unsigned).
+-define(GLsync,64/native-unsigned).
+-define(GLuint64,64/native-unsigned).
+-define(GLint64,64/native-signed).
+-type clamp() :: float().
+-type offset() :: non_neg_integer().
+-type enum() :: non_neg_integer().
+-type mem() :: binary() | tuple().
-export([accum/2,alphaFunc/2,areTexturesResident/1,arrayElement/1,'begin'/1,
bindTexture/2,bitmap/7,blendFunc/2,callList/1,callLists/1,clear/1,clearAccum/4,
@@ -173,3862 +179,5840 @@
enablei/2,disablei/2,isEnabledi/2,beginTransformFeedback/1,endTransformFeedback/0,
bindBufferRange/5,bindBufferBase/3,transformFeedbackVaryings/3,getTransformFeedbackVarying/3,
clampColor/2,beginConditionalRender/2,endConditionalRender/0,vertexAttribIPointer/5,
- getVertexAttribIiv/2,getVertexAttribIuiv/2,getUniformuiv/2,bindFragDataLocation/3,
+ getVertexAttribIiv/2,getVertexAttribIuiv/2,vertexAttribI1i/2,vertexAttribI2i/3,
+ vertexAttribI3i/4,vertexAttribI4i/5,vertexAttribI1ui/2,vertexAttribI2ui/3,
+ vertexAttribI3ui/4,vertexAttribI4ui/5,vertexAttribI1iv/2,vertexAttribI2iv/2,
+ vertexAttribI3iv/2,vertexAttribI4iv/2,vertexAttribI1uiv/2,vertexAttribI2uiv/2,
+ vertexAttribI3uiv/2,vertexAttribI4uiv/2,vertexAttribI4bv/2,vertexAttribI4sv/2,
+ vertexAttribI4ubv/2,vertexAttribI4usv/2,getUniformuiv/2,bindFragDataLocation/3,
getFragDataLocation/2,uniform1ui/2,uniform2ui/3,uniform3ui/4,uniform4ui/5,
uniform1uiv/2,uniform2uiv/2,uniform3uiv/2,uniform4uiv/2,texParameterIiv/3,
texParameterIuiv/3,getTexParameterIiv/2,getTexParameterIuiv/2,clearBufferiv/3,
- clearBufferuiv/3,clearBufferfv/3,clearBufferfi/4,getStringi/2,vertexAttribI1i/2,
- vertexAttribI2i/3,vertexAttribI3i/4,vertexAttribI4i/5,vertexAttribI1ui/2,
- vertexAttribI2ui/3,vertexAttribI3ui/4,vertexAttribI4ui/5,vertexAttribI1iv/2,
- vertexAttribI2iv/2,vertexAttribI3iv/2,vertexAttribI4iv/2,vertexAttribI1uiv/2,
- vertexAttribI2uiv/2,vertexAttribI3uiv/2,vertexAttribI4uiv/2,vertexAttribI4bv/2,
- vertexAttribI4sv/2,vertexAttribI4ubv/2,vertexAttribI4usv/2,drawArraysInstanced/4,
- drawElementsInstanced/5,texBuffer/3,primitiveRestartIndex/1,loadTransposeMatrixfARB/1,
- loadTransposeMatrixdARB/1,multTransposeMatrixfARB/1,multTransposeMatrixdARB/1,
- weightbvARB/1,weightsvARB/1,weightivARB/1,weightfvARB/1,weightdvARB/1,
- weightubvARB/1,weightusvARB/1,weightuivARB/1,vertexBlendARB/1,currentPaletteMatrixARB/1,
+ clearBufferuiv/3,clearBufferfv/3,clearBufferfi/4,getStringi/2,drawArraysInstanced/4,
+ drawElementsInstanced/5,texBuffer/3,primitiveRestartIndex/1,getInteger64i_v/2,
+ getBufferParameteri64v/2,framebufferTexture/4,vertexAttribDivisor/2,
+ minSampleShading/1,blendEquationi/2,blendEquationSeparatei/3,blendFunci/3,
+ blendFuncSeparatei/5,loadTransposeMatrixfARB/1,loadTransposeMatrixdARB/1,
+ multTransposeMatrixfARB/1,multTransposeMatrixdARB/1,weightbvARB/1,
+ weightsvARB/1,weightivARB/1,weightfvARB/1,weightdvARB/1,weightubvARB/1,
+ weightusvARB/1,weightuivARB/1,vertexBlendARB/1,currentPaletteMatrixARB/1,
matrixIndexubvARB/1,matrixIndexusvARB/1,matrixIndexuivARB/1,programStringARB/3,
bindProgramARB/2,deleteProgramsARB/1,genProgramsARB/1,programEnvParameter4dARB/6,
programEnvParameter4dvARB/3,programEnvParameter4fARB/6,programEnvParameter4fvARB/3,
programLocalParameter4dARB/6,programLocalParameter4dvARB/3,programLocalParameter4fARB/6,
programLocalParameter4fvARB/3,getProgramEnvParameterdvARB/2,getProgramEnvParameterfvARB/2,
getProgramLocalParameterdvARB/2,getProgramLocalParameterfvARB/2,
- getProgramStringARB/3,deleteObjectARB/1,getHandleARB/1,detachObjectARB/2,
- createShaderObjectARB/1,shaderSourceARB/2,compileShaderARB/1,createProgramObjectARB/0,
- attachObjectARB/2,linkProgramARB/1,useProgramObjectARB/1,validateProgramARB/1,
- getObjectParameterfvARB/2,getObjectParameterivARB/2,getInfoLogARB/2,
- getAttachedObjectsARB/2,getUniformLocationARB/2,getActiveUniformARB/3,
- getUniformfvARB/2,getUniformivARB/2,getShaderSourceARB/2,bindAttribLocationARB/3,
- getActiveAttribARB/3,getAttribLocationARB/2,isRenderbuffer/1,bindRenderbuffer/2,
- deleteRenderbuffers/1,genRenderbuffers/1,renderbufferStorage/4,getRenderbufferParameteriv/2,
+ getProgramStringARB/3,getBufferParameterivARB/2,deleteObjectARB/1,
+ getHandleARB/1,detachObjectARB/2,createShaderObjectARB/1,shaderSourceARB/2,
+ compileShaderARB/1,createProgramObjectARB/0,attachObjectARB/2,linkProgramARB/1,
+ useProgramObjectARB/1,validateProgramARB/1,getObjectParameterfvARB/2,
+ getObjectParameterivARB/2,getInfoLogARB/2,getAttachedObjectsARB/2,
+ getUniformLocationARB/2,getActiveUniformARB/3,getUniformfvARB/2,
+ getUniformivARB/2,getShaderSourceARB/2,bindAttribLocationARB/3,getActiveAttribARB/3,
+ getAttribLocationARB/2,isRenderbuffer/1,bindRenderbuffer/2,deleteRenderbuffers/1,
+ genRenderbuffers/1,renderbufferStorage/4,getRenderbufferParameteriv/2,
isFramebuffer/1,bindFramebuffer/2,deleteFramebuffers/1,genFramebuffers/1,
checkFramebufferStatus/1,framebufferTexture1D/5,framebufferTexture2D/5,
framebufferTexture3D/6,framebufferRenderbuffer/4,getFramebufferAttachmentParameteriv/3,
generateMipmap/1,blitFramebuffer/10,renderbufferStorageMultisample/5,
- framebufferTextureLayer/5,programParameteriARB/3,framebufferTextureARB/4,
- framebufferTextureFaceARB/5,vertexAttribDivisorARB/2,flushMappedBufferRange/3,
+ framebufferTextureLayer/5,framebufferTextureFaceARB/5,flushMappedBufferRange/3,
bindVertexArray/1,deleteVertexArrays/1,genVertexArrays/1,isVertexArray/1,
getUniformIndices/2,getActiveUniformsiv/3,getActiveUniformName/3,
getUniformBlockIndex/2,getActiveUniformBlockiv/4,getActiveUniformBlockName/3,
- uniformBlockBinding/3,copyBufferSubData/5,resizeBuffersMESA/0,windowPos4dMESA/4,
+ uniformBlockBinding/3,copyBufferSubData/5,drawElementsBaseVertex/5,
+ drawRangeElementsBaseVertex/7,drawElementsInstancedBaseVertex/6,
+ provokingVertex/1,fenceSync/2,isSync/1,deleteSync/1,clientWaitSync/3,
+ waitSync/3,getInteger64v/1,getSynciv/3,texImage2DMultisample/6,texImage3DMultisample/7,
+ getMultisamplefv/2,sampleMaski/2,namedStringARB/3,deleteNamedStringARB/1,
+ compileShaderIncludeARB/2,isNamedStringARB/1,getNamedStringARB/2,
+ getNamedStringivARB/2,bindFragDataLocationIndexed/4,getFragDataIndex/2,
+ genSamplers/1,deleteSamplers/1,isSampler/1,bindSampler/2,samplerParameteri/3,
+ samplerParameteriv/3,samplerParameterf/3,samplerParameterfv/3,samplerParameterIiv/3,
+ samplerParameterIuiv/3,getSamplerParameteriv/2,getSamplerParameterIiv/2,
+ getSamplerParameterfv/2,getSamplerParameterIuiv/2,queryCounter/2,
+ getQueryObjecti64v/2,getQueryObjectui64v/2,drawArraysIndirect/2,
+ drawElementsIndirect/3,uniform1d/2,uniform2d/3,uniform3d/4,uniform4d/5,
+ uniform1dv/2,uniform2dv/2,uniform3dv/2,uniform4dv/2,uniformMatrix2dv/3,
+ uniformMatrix3dv/3,uniformMatrix4dv/3,uniformMatrix2x3dv/3,uniformMatrix2x4dv/3,
+ uniformMatrix3x2dv/3,uniformMatrix3x4dv/3,uniformMatrix4x2dv/3,uniformMatrix4x3dv/3,
+ getUniformdv/2,getSubroutineUniformLocation/3,getSubroutineIndex/3,
+ getActiveSubroutineUniformName/4,getActiveSubroutineName/4,uniformSubroutinesuiv/2,
+ getUniformSubroutineuiv/2,getProgramStageiv/3,patchParameteri/2,
+ patchParameterfv/2,bindTransformFeedback/2,deleteTransformFeedbacks/1,
+ genTransformFeedbacks/1,isTransformFeedback/1,pauseTransformFeedback/0,
+ resumeTransformFeedback/0,drawTransformFeedback/2,drawTransformFeedbackStream/3,
+ beginQueryIndexed/3,endQueryIndexed/2,getQueryIndexediv/3,releaseShaderCompiler/0,
+ shaderBinary/3,getShaderPrecisionFormat/2,depthRangef/2,clearDepthf/1,
+ getProgramBinary/2,programBinary/3,programParameteri/3,useProgramStages/3,
+ activeShaderProgram/2,createShaderProgramv/2,bindProgramPipeline/1,
+ deleteProgramPipelines/1,genProgramPipelines/1,isProgramPipeline/1,
+ getProgramPipelineiv/2,programUniform1i/3,programUniform1iv/3,programUniform1f/3,
+ programUniform1fv/3,programUniform1d/3,programUniform1dv/3,programUniform1ui/3,
+ programUniform1uiv/3,programUniform2i/4,programUniform2iv/3,programUniform2f/4,
+ programUniform2fv/3,programUniform2d/4,programUniform2dv/3,programUniform2ui/4,
+ programUniform2uiv/3,programUniform3i/5,programUniform3iv/3,programUniform3f/5,
+ programUniform3fv/3,programUniform3d/5,programUniform3dv/3,programUniform3ui/5,
+ programUniform3uiv/3,programUniform4i/6,programUniform4iv/3,programUniform4f/6,
+ programUniform4fv/3,programUniform4d/6,programUniform4dv/3,programUniform4ui/6,
+ programUniform4uiv/3,programUniformMatrix2fv/4,programUniformMatrix3fv/4,
+ programUniformMatrix4fv/4,programUniformMatrix2dv/4,programUniformMatrix3dv/4,
+ programUniformMatrix4dv/4,programUniformMatrix2x3fv/4,programUniformMatrix3x2fv/4,
+ programUniformMatrix2x4fv/4,programUniformMatrix4x2fv/4,programUniformMatrix3x4fv/4,
+ programUniformMatrix4x3fv/4,programUniformMatrix2x3dv/4,programUniformMatrix3x2dv/4,
+ programUniformMatrix2x4dv/4,programUniformMatrix4x2dv/4,programUniformMatrix3x4dv/4,
+ programUniformMatrix4x3dv/4,validateProgramPipeline/1,getProgramPipelineInfoLog/2,
+ vertexAttribL1d/2,vertexAttribL2d/3,vertexAttribL3d/4,vertexAttribL4d/5,
+ vertexAttribL1dv/2,vertexAttribL2dv/2,vertexAttribL3dv/2,vertexAttribL4dv/2,
+ vertexAttribLPointer/5,getVertexAttribLdv/2,viewportArrayv/2,viewportIndexedf/5,
+ viewportIndexedfv/2,scissorArrayv/2,scissorIndexed/5,scissorIndexedv/2,
+ depthRangeArrayv/2,depthRangeIndexed/3,getFloati_v/2,getDoublei_v/2,
+ debugMessageControlARB/5,debugMessageInsertARB/5,getDebugMessageLogARB/2,
+ getGraphicsResetStatusARB/0,resizeBuffersMESA/0,windowPos4dMESA/4,
windowPos4dvMESA/1,windowPos4fMESA/4,windowPos4fvMESA/1,windowPos4iMESA/4,
windowPos4ivMESA/1,windowPos4sMESA/4,windowPos4svMESA/1,depthBoundsEXT/2,
stencilClearTagEXT/2]).
+-export([call/2, cast/2, send_bin/1]).
+%% @hidden
+call(Op, Args) ->
+ Port = get(opengl_port),
+ _ = erlang:port_control(Port,Op,Args),
+ rec().
+
+%% @hidden
+cast(Op, Args) ->
+ Port = get(opengl_port),
+ _ = erlang:port_control(Port,Op,Args),
+ ok.
+
+%% @hidden
+rec() ->
+ receive
+ {'_egl_result_', Res} -> Res;
+ {'_egl_error_', Op, Res} -> error({error,Res,Op})
+ end.
+
+%% @hidden
+send_bin(Bin) when is_binary(Bin) ->
+ Port = get(opengl_port),
+ erlang:port_command(Port,Bin);
+send_bin(Tuple) when is_tuple(Tuple) ->
+ Port = get(opengl_port),
+ case element(2, Tuple) of
+ Bin when is_binary(Bin) ->
+ erlang:port_command(Port,Bin)
+ end.
+
%% API
%% @spec (Op::enum(),Value::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAccum.xml">external</a> documentation.
+-spec accum(enum(),float()) -> ok.
accum(Op,Value) ->
- wxe_util:cast(5037, <<Op:?GLenum,Value:?GLfloat>>).
+ cast(5037, <<Op:?GLenum,Value:?GLfloat>>).
%% @spec (Func::enum(),Ref::clamp()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAlphaFunc.xml">external</a> documentation.
+-spec alphaFunc(enum(),clamp()) -> ok.
alphaFunc(Func,Ref) ->
- wxe_util:cast(5038, <<Func:?GLenum,Ref:?GLclampf>>).
+ cast(5038, <<Func:?GLenum,Ref:?GLclampf>>).
%% @spec (Textures::[integer()]) -> {0|1,Residences::[0|1]}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAreTexturesResident.xml">external</a> documentation.
+-spec areTexturesResident([integer()]) -> {0|1,[0|1]}.
areTexturesResident(Textures) ->
- wxe_util:call(5039, <<(length(Textures)):?GLuint,
+ call(5039, <<(length(Textures)):?GLuint,
(<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32)>>).
%% @spec (I::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glArrayElement.xml">external</a> documentation.
+-spec arrayElement(integer()) -> ok.
arrayElement(I) ->
- wxe_util:cast(5040, <<I:?GLint>>).
+ cast(5040, <<I:?GLint>>).
%% @spec (Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBegin.xml">external</a> documentation.
+-spec 'begin'(enum()) -> ok.
'begin'(Mode) ->
- wxe_util:cast(5041, <<Mode:?GLenum>>).
+ cast(5041, <<Mode:?GLenum>>).
%% @spec (Target::enum(),Texture::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindTexture.xml">external</a> documentation.
+-spec bindTexture(enum(),integer()) -> ok.
bindTexture(Target,Texture) ->
- wxe_util:cast(5042, <<Target:?GLenum,Texture:?GLuint>>).
+ cast(5042, <<Target:?GLenum,Texture:?GLuint>>).
-%% @spec (Width::integer(),Height::integer(),Xorig::float(),Yorig::float(),Xmove::float(),Ymove::float(),Bitmap::offset()|binary()) -> ok
+%% @spec (Width::integer(),Height::integer(),Xorig::float(),Yorig::float(),Xmove::float(),Ymove::float(),Bitmap::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBitmap.xml">external</a> documentation.
+-spec bitmap(integer(),integer(),float(),float(),float(),float(),offset()|mem()) -> ok.
bitmap(Width,Height,Xorig,Yorig,Xmove,Ymove,Bitmap) when is_integer(Bitmap) ->
- wxe_util:cast(5043, <<Width:?GLsizei,Height:?GLsizei,Xorig:?GLfloat,Yorig:?GLfloat,Xmove:?GLfloat,Ymove:?GLfloat,Bitmap:?GLuint>>);
+ cast(5043, <<Width:?GLsizei,Height:?GLsizei,Xorig:?GLfloat,Yorig:?GLfloat,Xmove:?GLfloat,Ymove:?GLfloat,Bitmap:?GLuint>>);
bitmap(Width,Height,Xorig,Yorig,Xmove,Ymove,Bitmap) ->
- wxe_util:send_bin(Bitmap),
- wxe_util:cast(5044, <<Width:?GLsizei,Height:?GLsizei,Xorig:?GLfloat,Yorig:?GLfloat,Xmove:?GLfloat,Ymove:?GLfloat>>).
+ send_bin(Bitmap),
+ cast(5044, <<Width:?GLsizei,Height:?GLsizei,Xorig:?GLfloat,Yorig:?GLfloat,Xmove:?GLfloat,Ymove:?GLfloat>>).
%% @spec (Sfactor::enum(),Dfactor::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunc.xml">external</a> documentation.
+-spec blendFunc(enum(),enum()) -> ok.
blendFunc(Sfactor,Dfactor) ->
- wxe_util:cast(5045, <<Sfactor:?GLenum,Dfactor:?GLenum>>).
+ cast(5045, <<Sfactor:?GLenum,Dfactor:?GLenum>>).
%% @spec (List::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCallList.xml">external</a> documentation.
+-spec callList(integer()) -> ok.
callList(List) ->
- wxe_util:cast(5046, <<List:?GLuint>>).
+ cast(5046, <<List:?GLuint>>).
%% @spec (Lists::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCallLists.xml">external</a> documentation.
+-spec callLists([integer()]) -> ok.
callLists(Lists) ->
- wxe_util:cast(5047, <<(length(Lists)):?GLuint,
+ cast(5047, <<(length(Lists)):?GLuint,
(<< <<C:?GLuint>> || C <- Lists>>)/binary,0:(((1+length(Lists)) rem 2)*32)>>).
%% @spec (Mask::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClear.xml">external</a> documentation.
+-spec clear(integer()) -> ok.
clear(Mask) ->
- wxe_util:cast(5048, <<Mask:?GLbitfield>>).
+ cast(5048, <<Mask:?GLbitfield>>).
%% @spec (Red::float(),Green::float(),Blue::float(),Alpha::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearAccum.xml">external</a> documentation.
+-spec clearAccum(float(),float(),float(),float()) -> ok.
clearAccum(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5049, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat,Alpha:?GLfloat>>).
+ cast(5049, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat,Alpha:?GLfloat>>).
%% @spec (Red::clamp(),Green::clamp(),Blue::clamp(),Alpha::clamp()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearColor.xml">external</a> documentation.
+-spec clearColor(clamp(),clamp(),clamp(),clamp()) -> ok.
clearColor(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5050, <<Red:?GLclampf,Green:?GLclampf,Blue:?GLclampf,Alpha:?GLclampf>>).
+ cast(5050, <<Red:?GLclampf,Green:?GLclampf,Blue:?GLclampf,Alpha:?GLclampf>>).
%% @spec (Depth::clamp()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearDepth.xml">external</a> documentation.
+-spec clearDepth(clamp()) -> ok.
clearDepth(Depth) ->
- wxe_util:cast(5051, <<Depth:?GLclampd>>).
+ cast(5051, <<Depth:?GLclampd>>).
%% @spec (C::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearIndex.xml">external</a> documentation.
+-spec clearIndex(float()) -> ok.
clearIndex(C) ->
- wxe_util:cast(5052, <<C:?GLfloat>>).
+ cast(5052, <<C:?GLfloat>>).
%% @spec (S::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearStencil.xml">external</a> documentation.
+-spec clearStencil(integer()) -> ok.
clearStencil(S) ->
- wxe_util:cast(5053, <<S:?GLint>>).
+ cast(5053, <<S:?GLint>>).
-%% @spec (Plane::enum(),Equation::{float()}) -> ok
+%% @spec (Plane::enum(),Equation::{float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClipPlane.xml">external</a> documentation.
+-spec clipPlane(enum(),{float(),float(),float(),float()}) -> ok.
clipPlane(Plane,{E1,E2,E3,E4}) ->
- wxe_util:cast(5054, <<Plane:?GLenum,0:32,E1:?GLdouble,E2:?GLdouble,E3:?GLdouble,E4:?GLdouble>>).
+ cast(5054, <<Plane:?GLenum,0:32,E1:?GLdouble,E2:?GLdouble,E3:?GLdouble,E4:?GLdouble>>).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color3b(integer(),integer(),integer()) -> ok.
color3b(Red,Green,Blue) ->
- wxe_util:cast(5055, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>).
+ cast(5055, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv color3b(Red,Green,Blue)
+-spec color3bv({integer(),integer(),integer()}) -> ok.
color3bv({Red,Green,Blue}) -> color3b(Red,Green,Blue).
%% @spec (Red::float(),Green::float(),Blue::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color3d(float(),float(),float()) -> ok.
color3d(Red,Green,Blue) ->
- wxe_util:cast(5056, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>).
+ cast(5056, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv color3d(Red,Green,Blue)
+-spec color3dv({float(),float(),float()}) -> ok.
color3dv({Red,Green,Blue}) -> color3d(Red,Green,Blue).
%% @spec (Red::float(),Green::float(),Blue::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color3f(float(),float(),float()) -> ok.
color3f(Red,Green,Blue) ->
- wxe_util:cast(5057, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>).
+ cast(5057, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv color3f(Red,Green,Blue)
+-spec color3fv({float(),float(),float()}) -> ok.
color3fv({Red,Green,Blue}) -> color3f(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color3i(integer(),integer(),integer()) -> ok.
color3i(Red,Green,Blue) ->
- wxe_util:cast(5058, <<Red:?GLint,Green:?GLint,Blue:?GLint>>).
+ cast(5058, <<Red:?GLint,Green:?GLint,Blue:?GLint>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv color3i(Red,Green,Blue)
+-spec color3iv({integer(),integer(),integer()}) -> ok.
color3iv({Red,Green,Blue}) -> color3i(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color3s(integer(),integer(),integer()) -> ok.
color3s(Red,Green,Blue) ->
- wxe_util:cast(5059, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>).
+ cast(5059, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv color3s(Red,Green,Blue)
+-spec color3sv({integer(),integer(),integer()}) -> ok.
color3sv({Red,Green,Blue}) -> color3s(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color3ub(integer(),integer(),integer()) -> ok.
color3ub(Red,Green,Blue) ->
- wxe_util:cast(5060, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>).
+ cast(5060, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv color3ub(Red,Green,Blue)
+-spec color3ubv({integer(),integer(),integer()}) -> ok.
color3ubv({Red,Green,Blue}) -> color3ub(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color3ui(integer(),integer(),integer()) -> ok.
color3ui(Red,Green,Blue) ->
- wxe_util:cast(5061, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>).
+ cast(5061, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv color3ui(Red,Green,Blue)
+-spec color3uiv({integer(),integer(),integer()}) -> ok.
color3uiv({Red,Green,Blue}) -> color3ui(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color3us(integer(),integer(),integer()) -> ok.
color3us(Red,Green,Blue) ->
- wxe_util:cast(5062, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>).
+ cast(5062, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv color3us(Red,Green,Blue)
+-spec color3usv({integer(),integer(),integer()}) -> ok.
color3usv({Red,Green,Blue}) -> color3us(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color4b(integer(),integer(),integer(),integer()) -> ok.
color4b(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5063, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte,Alpha:?GLbyte>>).
+ cast(5063, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte,Alpha:?GLbyte>>).
%% @spec ({Red,Green,Blue,Alpha}) -> ok
%% @equiv color4b(Red,Green,Blue,Alpha)
+-spec color4bv({integer(),integer(),integer(),integer()}) -> ok.
color4bv({Red,Green,Blue,Alpha}) -> color4b(Red,Green,Blue,Alpha).
%% @spec (Red::float(),Green::float(),Blue::float(),Alpha::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color4d(float(),float(),float(),float()) -> ok.
color4d(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5064, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble,Alpha:?GLdouble>>).
+ cast(5064, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble,Alpha:?GLdouble>>).
%% @spec ({Red,Green,Blue,Alpha}) -> ok
%% @equiv color4d(Red,Green,Blue,Alpha)
+-spec color4dv({float(),float(),float(),float()}) -> ok.
color4dv({Red,Green,Blue,Alpha}) -> color4d(Red,Green,Blue,Alpha).
%% @spec (Red::float(),Green::float(),Blue::float(),Alpha::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color4f(float(),float(),float(),float()) -> ok.
color4f(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5065, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat,Alpha:?GLfloat>>).
+ cast(5065, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat,Alpha:?GLfloat>>).
%% @spec ({Red,Green,Blue,Alpha}) -> ok
%% @equiv color4f(Red,Green,Blue,Alpha)
+-spec color4fv({float(),float(),float(),float()}) -> ok.
color4fv({Red,Green,Blue,Alpha}) -> color4f(Red,Green,Blue,Alpha).
%% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color4i(integer(),integer(),integer(),integer()) -> ok.
color4i(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5066, <<Red:?GLint,Green:?GLint,Blue:?GLint,Alpha:?GLint>>).
+ cast(5066, <<Red:?GLint,Green:?GLint,Blue:?GLint,Alpha:?GLint>>).
%% @spec ({Red,Green,Blue,Alpha}) -> ok
%% @equiv color4i(Red,Green,Blue,Alpha)
+-spec color4iv({integer(),integer(),integer(),integer()}) -> ok.
color4iv({Red,Green,Blue,Alpha}) -> color4i(Red,Green,Blue,Alpha).
%% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color4s(integer(),integer(),integer(),integer()) -> ok.
color4s(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5067, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort,Alpha:?GLshort>>).
+ cast(5067, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort,Alpha:?GLshort>>).
%% @spec ({Red,Green,Blue,Alpha}) -> ok
%% @equiv color4s(Red,Green,Blue,Alpha)
+-spec color4sv({integer(),integer(),integer(),integer()}) -> ok.
color4sv({Red,Green,Blue,Alpha}) -> color4s(Red,Green,Blue,Alpha).
%% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color4ub(integer(),integer(),integer(),integer()) -> ok.
color4ub(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5068, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte,Alpha:?GLubyte>>).
+ cast(5068, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte,Alpha:?GLubyte>>).
%% @spec ({Red,Green,Blue,Alpha}) -> ok
%% @equiv color4ub(Red,Green,Blue,Alpha)
+-spec color4ubv({integer(),integer(),integer(),integer()}) -> ok.
color4ubv({Red,Green,Blue,Alpha}) -> color4ub(Red,Green,Blue,Alpha).
%% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color4ui(integer(),integer(),integer(),integer()) -> ok.
color4ui(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5069, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint,Alpha:?GLuint>>).
+ cast(5069, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint,Alpha:?GLuint>>).
%% @spec ({Red,Green,Blue,Alpha}) -> ok
%% @equiv color4ui(Red,Green,Blue,Alpha)
+-spec color4uiv({integer(),integer(),integer(),integer()}) -> ok.
color4uiv({Red,Green,Blue,Alpha}) -> color4ui(Red,Green,Blue,Alpha).
%% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation.
+-spec color4us(integer(),integer(),integer(),integer()) -> ok.
color4us(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5070, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort,Alpha:?GLushort>>).
+ cast(5070, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort,Alpha:?GLushort>>).
%% @spec ({Red,Green,Blue,Alpha}) -> ok
%% @equiv color4us(Red,Green,Blue,Alpha)
+-spec color4usv({integer(),integer(),integer(),integer()}) -> ok.
color4usv({Red,Green,Blue,Alpha}) -> color4us(Red,Green,Blue,Alpha).
%% @spec (Red::0|1,Green::0|1,Blue::0|1,Alpha::0|1) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorMask.xml">external</a> documentation.
+-spec colorMask(0|1,0|1,0|1,0|1) -> ok.
colorMask(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5071, <<Red:?GLboolean,Green:?GLboolean,Blue:?GLboolean,Alpha:?GLboolean>>).
+ cast(5071, <<Red:?GLboolean,Green:?GLboolean,Blue:?GLboolean,Alpha:?GLboolean>>).
%% @spec (Face::enum(),Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorMaterial.xml">external</a> documentation.
+-spec colorMaterial(enum(),enum()) -> ok.
colorMaterial(Face,Mode) ->
- wxe_util:cast(5072, <<Face:?GLenum,Mode:?GLenum>>).
+ cast(5072, <<Face:?GLenum,Mode:?GLenum>>).
-%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorPointer.xml">external</a> documentation.
+-spec colorPointer(integer(),enum(),integer(),offset()|mem()) -> ok.
colorPointer(Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5073, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5073, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
colorPointer(Size,Type,Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5074, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5074, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
%% @spec (X::integer(),Y::integer(),Width::integer(),Height::integer(),Type::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyPixels.xml">external</a> documentation.
+-spec copyPixels(integer(),integer(),integer(),integer(),enum()) -> ok.
copyPixels(X,Y,Width,Height,Type) ->
- wxe_util:cast(5075, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Type:?GLenum>>).
+ cast(5075, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Type:?GLenum>>).
%% @spec (Target::enum(),Level::integer(),InternalFormat::enum(),X::integer(),Y::integer(),Width::integer(),Border::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyTexImage1D.xml">external</a> documentation.
+-spec copyTexImage1D(enum(),integer(),enum(),integer(),integer(),integer(),integer()) -> ok.
copyTexImage1D(Target,Level,InternalFormat,X,Y,Width,Border) ->
- wxe_util:cast(5076, <<Target:?GLenum,Level:?GLint,InternalFormat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Border:?GLint>>).
+ cast(5076, <<Target:?GLenum,Level:?GLint,InternalFormat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Border:?GLint>>).
%% @spec (Target::enum(),Level::integer(),InternalFormat::enum(),X::integer(),Y::integer(),Width::integer(),Height::integer(),Border::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyTexImage2D.xml">external</a> documentation.
+-spec copyTexImage2D(enum(),integer(),enum(),integer(),integer(),integer(),integer(),integer()) -> ok.
copyTexImage2D(Target,Level,InternalFormat,X,Y,Width,Height,Border) ->
- wxe_util:cast(5077, <<Target:?GLenum,Level:?GLint,InternalFormat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint>>).
+ cast(5077, <<Target:?GLenum,Level:?GLint,InternalFormat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint>>).
%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),X::integer(),Y::integer(),Width::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyTexSubImage1D.xml">external</a> documentation.
+-spec copyTexSubImage1D(enum(),integer(),integer(),integer(),integer(),integer()) -> ok.
copyTexSubImage1D(Target,Level,Xoffset,X,Y,Width) ->
- wxe_util:cast(5078, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei>>).
+ cast(5078, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei>>).
%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),X::integer(),Y::integer(),Width::integer(),Height::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyTexSubImage2D.xml">external</a> documentation.
+-spec copyTexSubImage2D(enum(),integer(),integer(),integer(),integer(),integer(),integer(),integer()) -> ok.
copyTexSubImage2D(Target,Level,Xoffset,Yoffset,X,Y,Width,Height) ->
- wxe_util:cast(5079, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5079, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>).
%% @spec (Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCullFace.xml">external</a> documentation.
+-spec cullFace(enum()) -> ok.
cullFace(Mode) ->
- wxe_util:cast(5080, <<Mode:?GLenum>>).
+ cast(5080, <<Mode:?GLenum>>).
%% @spec (List::integer(),Range::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteLists.xml">external</a> documentation.
+-spec deleteLists(integer(),integer()) -> ok.
deleteLists(List,Range) ->
- wxe_util:cast(5081, <<List:?GLuint,Range:?GLsizei>>).
+ cast(5081, <<List:?GLuint,Range:?GLsizei>>).
%% @spec (Textures::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTextures.xml">external</a> documentation.
+-spec deleteTextures([integer()]) -> ok.
deleteTextures(Textures) ->
- wxe_util:cast(5082, <<(length(Textures)):?GLuint,
+ cast(5082, <<(length(Textures)):?GLuint,
(<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32)>>).
%% @spec (Func::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthFunc.xml">external</a> documentation.
+-spec depthFunc(enum()) -> ok.
depthFunc(Func) ->
- wxe_util:cast(5083, <<Func:?GLenum>>).
+ cast(5083, <<Func:?GLenum>>).
%% @spec (Flag::0|1) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthMask.xml">external</a> documentation.
+-spec depthMask(0|1) -> ok.
depthMask(Flag) ->
- wxe_util:cast(5084, <<Flag:?GLboolean>>).
+ cast(5084, <<Flag:?GLboolean>>).
%% @spec (ZNear::clamp(),ZFar::clamp()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRange.xml">external</a> documentation.
+-spec depthRange(clamp(),clamp()) -> ok.
depthRange(ZNear,ZFar) ->
- wxe_util:cast(5085, <<ZNear:?GLclampd,ZFar:?GLclampd>>).
+ cast(5085, <<ZNear:?GLclampd,ZFar:?GLclampd>>).
%% @spec (Cap::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDisable.xml">external</a> documentation.
+-spec disable(enum()) -> ok.
disable(Cap) ->
- wxe_util:cast(5086, <<Cap:?GLenum>>).
+ cast(5086, <<Cap:?GLenum>>).
%% @spec (Array::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDisableClientState.xml">external</a> documentation.
+-spec disableClientState(enum()) -> ok.
disableClientState(Array) ->
- wxe_util:cast(5087, <<Array:?GLenum>>).
+ cast(5087, <<Array:?GLenum>>).
%% @spec (Mode::enum(),First::integer(),Count::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArrays.xml">external</a> documentation.
+-spec drawArrays(enum(),integer(),integer()) -> ok.
drawArrays(Mode,First,Count) ->
- wxe_util:cast(5088, <<Mode:?GLenum,First:?GLint,Count:?GLsizei>>).
+ cast(5088, <<Mode:?GLenum,First:?GLint,Count:?GLsizei>>).
%% @spec (Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawBuffer.xml">external</a> documentation.
+-spec drawBuffer(enum()) -> ok.
drawBuffer(Mode) ->
- wxe_util:cast(5089, <<Mode:?GLenum>>).
+ cast(5089, <<Mode:?GLenum>>).
-%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|binary()) -> ok
+%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElements.xml">external</a> documentation.
+-spec drawElements(enum(),integer(),enum(),offset()|mem()) -> ok.
drawElements(Mode,Count,Type,Indices) when is_integer(Indices) ->
- wxe_util:cast(5090, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint>>);
+ cast(5090, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint>>);
drawElements(Mode,Count,Type,Indices) ->
- wxe_util:send_bin(Indices),
- wxe_util:cast(5091, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum>>).
+ send_bin(Indices),
+ cast(5091, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum>>).
-%% @spec (Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok
+%% @spec (Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawPixels.xml">external</a> documentation.
+-spec drawPixels(integer(),integer(),enum(),enum(),offset()|mem()) -> ok.
drawPixels(Width,Height,Format,Type,Pixels) when is_integer(Pixels) ->
- wxe_util:cast(5092, <<Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
+ cast(5092, <<Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
drawPixels(Width,Height,Format,Type,Pixels) ->
- wxe_util:send_bin(Pixels),
- wxe_util:cast(5093, <<Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Pixels),
+ cast(5093, <<Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
%% @spec (Flag::0|1) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEdgeFlag.xml">external</a> documentation.
+-spec edgeFlag(0|1) -> ok.
edgeFlag(Flag) ->
- wxe_util:cast(5094, <<Flag:?GLboolean>>).
+ cast(5094, <<Flag:?GLboolean>>).
-%% @spec (Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEdgeFlagPointer.xml">external</a> documentation.
+-spec edgeFlagPointer(integer(),offset()|mem()) -> ok.
edgeFlagPointer(Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5095, <<Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5095, <<Stride:?GLsizei,Pointer:?GLuint>>);
edgeFlagPointer(Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5096, <<Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5096, <<Stride:?GLsizei>>).
%% @spec ({Flag}) -> ok
%% @equiv edgeFlag(Flag)
+-spec edgeFlagv({0|1}) -> ok.
edgeFlagv({Flag}) -> edgeFlag(Flag).
%% @spec (Cap::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml">external</a> documentation.
+-spec enable(enum()) -> ok.
enable(Cap) ->
- wxe_util:cast(5097, <<Cap:?GLenum>>).
+ cast(5097, <<Cap:?GLenum>>).
%% @spec (Array::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnableClientState.xml">external</a> documentation.
+-spec enableClientState(enum()) -> ok.
enableClientState(Array) ->
- wxe_util:cast(5098, <<Array:?GLenum>>).
+ cast(5098, <<Array:?GLenum>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnd.xml">external</a> documentation.
+-spec 'end'() -> ok.
'end'() ->
- wxe_util:cast(5099, <<>>).
+ cast(5099, <<>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEndList.xml">external</a> documentation.
+-spec endList() -> ok.
endList() ->
- wxe_util:cast(5100, <<>>).
+ cast(5100, <<>>).
%% @spec (U::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalCoord.xml">external</a> documentation.
+-spec evalCoord1d(float()) -> ok.
evalCoord1d(U) ->
- wxe_util:cast(5101, <<U:?GLdouble>>).
+ cast(5101, <<U:?GLdouble>>).
%% @spec ({U}) -> ok
%% @equiv evalCoord1d(U)
+-spec evalCoord1dv({float()}) -> ok.
evalCoord1dv({U}) -> evalCoord1d(U).
%% @spec (U::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalCoord.xml">external</a> documentation.
+-spec evalCoord1f(float()) -> ok.
evalCoord1f(U) ->
- wxe_util:cast(5102, <<U:?GLfloat>>).
+ cast(5102, <<U:?GLfloat>>).
%% @spec ({U}) -> ok
%% @equiv evalCoord1f(U)
+-spec evalCoord1fv({float()}) -> ok.
evalCoord1fv({U}) -> evalCoord1f(U).
%% @spec (U::float(),V::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalCoord.xml">external</a> documentation.
+-spec evalCoord2d(float(),float()) -> ok.
evalCoord2d(U,V) ->
- wxe_util:cast(5103, <<U:?GLdouble,V:?GLdouble>>).
+ cast(5103, <<U:?GLdouble,V:?GLdouble>>).
%% @spec ({U,V}) -> ok
%% @equiv evalCoord2d(U,V)
+-spec evalCoord2dv({float(),float()}) -> ok.
evalCoord2dv({U,V}) -> evalCoord2d(U,V).
%% @spec (U::float(),V::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalCoord.xml">external</a> documentation.
+-spec evalCoord2f(float(),float()) -> ok.
evalCoord2f(U,V) ->
- wxe_util:cast(5104, <<U:?GLfloat,V:?GLfloat>>).
+ cast(5104, <<U:?GLfloat,V:?GLfloat>>).
%% @spec ({U,V}) -> ok
%% @equiv evalCoord2f(U,V)
+-spec evalCoord2fv({float(),float()}) -> ok.
evalCoord2fv({U,V}) -> evalCoord2f(U,V).
%% @spec (Mode::enum(),I1::integer(),I2::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalMesh.xml">external</a> documentation.
+-spec evalMesh1(enum(),integer(),integer()) -> ok.
evalMesh1(Mode,I1,I2) ->
- wxe_util:cast(5105, <<Mode:?GLenum,I1:?GLint,I2:?GLint>>).
+ cast(5105, <<Mode:?GLenum,I1:?GLint,I2:?GLint>>).
%% @spec (Mode::enum(),I1::integer(),I2::integer(),J1::integer(),J2::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalMesh.xml">external</a> documentation.
+-spec evalMesh2(enum(),integer(),integer(),integer(),integer()) -> ok.
evalMesh2(Mode,I1,I2,J1,J2) ->
- wxe_util:cast(5106, <<Mode:?GLenum,I1:?GLint,I2:?GLint,J1:?GLint,J2:?GLint>>).
+ cast(5106, <<Mode:?GLenum,I1:?GLint,I2:?GLint,J1:?GLint,J2:?GLint>>).
%% @spec (I::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalPoint.xml">external</a> documentation.
+-spec evalPoint1(integer()) -> ok.
evalPoint1(I) ->
- wxe_util:cast(5107, <<I:?GLint>>).
+ cast(5107, <<I:?GLint>>).
%% @spec (I::integer(),J::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalPoint.xml">external</a> documentation.
+-spec evalPoint2(integer(),integer()) -> ok.
evalPoint2(I,J) ->
- wxe_util:cast(5108, <<I:?GLint,J:?GLint>>).
+ cast(5108, <<I:?GLint,J:?GLint>>).
-%% @spec (Size::integer(),Type::enum(),Buffer::wx:wx_mem()) -> ok
+%% @spec (Size::integer(),Type::enum(),Buffer::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFeedbackBuffer.xml">external</a> documentation.
+-spec feedbackBuffer(integer(),enum(),mem()) -> ok.
feedbackBuffer(Size,Type,Buffer) ->
- wxe_util:send_bin(Buffer#wx_mem.bin),
- wxe_util:call(5109, <<Size:?GLsizei,Type:?GLenum>>).
+ send_bin(Buffer),
+ call(5109, <<Size:?GLsizei,Type:?GLenum>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFinish.xml">external</a> documentation.
+-spec finish() -> ok.
finish() ->
- wxe_util:cast(5110, <<>>).
+ cast(5110, <<>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFlush.xml">external</a> documentation.
+-spec flush() -> ok.
flush() ->
- wxe_util:cast(5111, <<>>).
+ cast(5111, <<>>).
%% @spec (Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFog.xml">external</a> documentation.
+-spec fogf(enum(),float()) -> ok.
fogf(Pname,Param) ->
- wxe_util:cast(5112, <<Pname:?GLenum,Param:?GLfloat>>).
+ cast(5112, <<Pname:?GLenum,Param:?GLfloat>>).
%% @spec (Pname::enum(),Params::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFog.xml">external</a> documentation.
+-spec fogfv(enum(),{float()}) -> ok.
fogfv(Pname,Params) ->
- wxe_util:cast(5113, <<Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5113, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @spec (Pname::enum(),Param::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFog.xml">external</a> documentation.
+-spec fogi(enum(),integer()) -> ok.
fogi(Pname,Param) ->
- wxe_util:cast(5114, <<Pname:?GLenum,Param:?GLint>>).
+ cast(5114, <<Pname:?GLenum,Param:?GLint>>).
%% @spec (Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFog.xml">external</a> documentation.
+-spec fogiv(enum(),{integer()}) -> ok.
fogiv(Pname,Params) ->
- wxe_util:cast(5115, <<Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5115, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @spec (Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFrontFace.xml">external</a> documentation.
+-spec frontFace(enum()) -> ok.
frontFace(Mode) ->
- wxe_util:cast(5116, <<Mode:?GLenum>>).
+ cast(5116, <<Mode:?GLenum>>).
%% @spec (Left::float(),Right::float(),Bottom::float(),Top::float(),ZNear::float(),ZFar::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFrustum.xml">external</a> documentation.
+-spec frustum(float(),float(),float(),float(),float(),float()) -> ok.
frustum(Left,Right,Bottom,Top,ZNear,ZFar) ->
- wxe_util:cast(5117, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>).
+ cast(5117, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>).
%% @spec (Range::integer()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenLists.xml">external</a> documentation.
+-spec genLists(integer()) -> integer().
genLists(Range) ->
- wxe_util:call(5118, <<Range:?GLsizei>>).
+ call(5118, <<Range:?GLsizei>>).
%% @spec (N::integer()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenTextures.xml">external</a> documentation.
+-spec genTextures(integer()) -> [integer()].
genTextures(N) ->
- wxe_util:call(5119, <<N:?GLsizei>>).
+ call(5119, <<N:?GLsizei>>).
%% @spec (Pname::enum()) -> [0|1]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBooleanv.xml">external</a> documentation.
+-spec getBooleanv(enum()) -> [0|1].
getBooleanv(Pname) ->
- wxe_util:call(5120, <<Pname:?GLenum>>).
+ call(5120, <<Pname:?GLenum>>).
-%% @spec (Plane::enum()) -> {float()}
+%% @spec (Plane::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetClipPlane.xml">external</a> documentation.
+-spec getClipPlane(enum()) -> {float(),float(),float(),float()}.
getClipPlane(Plane) ->
- wxe_util:call(5121, <<Plane:?GLenum>>).
+ call(5121, <<Plane:?GLenum>>).
%% @spec (Pname::enum()) -> [float()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetDoublev.xml">external</a> documentation.
+-spec getDoublev(enum()) -> [float()].
getDoublev(Pname) ->
- wxe_util:call(5122, <<Pname:?GLenum>>).
+ call(5122, <<Pname:?GLenum>>).
%% @spec () -> enum()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetError.xml">external</a> documentation.
+-spec getError() -> enum().
getError() ->
- wxe_util:call(5123, <<>>).
+ call(5123, <<>>).
%% @spec (Pname::enum()) -> [float()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFloatv.xml">external</a> documentation.
+-spec getFloatv(enum()) -> [float()].
getFloatv(Pname) ->
- wxe_util:call(5124, <<Pname:?GLenum>>).
+ call(5124, <<Pname:?GLenum>>).
%% @spec (Pname::enum()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetIntegerv.xml">external</a> documentation.
+-spec getIntegerv(enum()) -> [integer()].
getIntegerv(Pname) ->
- wxe_util:call(5125, <<Pname:?GLenum>>).
+ call(5125, <<Pname:?GLenum>>).
-%% @spec (Light::enum(),Pname::enum()) -> {float()}
+%% @spec (Light::enum(),Pname::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetLight.xml">external</a> documentation.
+-spec getLightfv(enum(),enum()) -> {float(),float(),float(),float()}.
getLightfv(Light,Pname) ->
- wxe_util:call(5126, <<Light:?GLenum,Pname:?GLenum>>).
+ call(5126, <<Light:?GLenum,Pname:?GLenum>>).
-%% @spec (Light::enum(),Pname::enum()) -> {integer()}
+%% @spec (Light::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetLight.xml">external</a> documentation.
+-spec getLightiv(enum(),enum()) -> {integer(),integer(),integer(),integer()}.
getLightiv(Light,Pname) ->
- wxe_util:call(5127, <<Light:?GLenum,Pname:?GLenum>>).
+ call(5127, <<Light:?GLenum,Pname:?GLenum>>).
-%% @spec (Target::enum(),Query::enum(),V::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Query::enum(),V::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMap.xml">external</a> documentation.
+-spec getMapdv(enum(),enum(),mem()) -> ok.
getMapdv(Target,Query,V) ->
- wxe_util:send_bin(V#wx_mem.bin),
- wxe_util:call(5128, <<Target:?GLenum,Query:?GLenum>>).
+ send_bin(V),
+ call(5128, <<Target:?GLenum,Query:?GLenum>>).
-%% @spec (Target::enum(),Query::enum(),V::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Query::enum(),V::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMap.xml">external</a> documentation.
+-spec getMapfv(enum(),enum(),mem()) -> ok.
getMapfv(Target,Query,V) ->
- wxe_util:send_bin(V#wx_mem.bin),
- wxe_util:call(5129, <<Target:?GLenum,Query:?GLenum>>).
+ send_bin(V),
+ call(5129, <<Target:?GLenum,Query:?GLenum>>).
-%% @spec (Target::enum(),Query::enum(),V::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Query::enum(),V::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMap.xml">external</a> documentation.
+-spec getMapiv(enum(),enum(),mem()) -> ok.
getMapiv(Target,Query,V) ->
- wxe_util:send_bin(V#wx_mem.bin),
- wxe_util:call(5130, <<Target:?GLenum,Query:?GLenum>>).
+ send_bin(V),
+ call(5130, <<Target:?GLenum,Query:?GLenum>>).
-%% @spec (Face::enum(),Pname::enum()) -> {float()}
+%% @spec (Face::enum(),Pname::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMaterial.xml">external</a> documentation.
+-spec getMaterialfv(enum(),enum()) -> {float(),float(),float(),float()}.
getMaterialfv(Face,Pname) ->
- wxe_util:call(5131, <<Face:?GLenum,Pname:?GLenum>>).
+ call(5131, <<Face:?GLenum,Pname:?GLenum>>).
-%% @spec (Face::enum(),Pname::enum()) -> {integer()}
+%% @spec (Face::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMaterial.xml">external</a> documentation.
+-spec getMaterialiv(enum(),enum()) -> {integer(),integer(),integer(),integer()}.
getMaterialiv(Face,Pname) ->
- wxe_util:call(5132, <<Face:?GLenum,Pname:?GLenum>>).
+ call(5132, <<Face:?GLenum,Pname:?GLenum>>).
-%% @spec (Map::enum(),Values::wx:wx_mem()) -> ok
+%% @spec (Map::enum(),Values::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetPixelMap.xml">external</a> documentation.
+-spec getPixelMapfv(enum(),mem()) -> ok.
getPixelMapfv(Map,Values) ->
- wxe_util:send_bin(Values#wx_mem.bin),
- wxe_util:call(5133, <<Map:?GLenum>>).
+ send_bin(Values),
+ call(5133, <<Map:?GLenum>>).
-%% @spec (Map::enum(),Values::wx:wx_mem()) -> ok
+%% @spec (Map::enum(),Values::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetPixelMap.xml">external</a> documentation.
+-spec getPixelMapuiv(enum(),mem()) -> ok.
getPixelMapuiv(Map,Values) ->
- wxe_util:send_bin(Values#wx_mem.bin),
- wxe_util:call(5134, <<Map:?GLenum>>).
+ send_bin(Values),
+ call(5134, <<Map:?GLenum>>).
-%% @spec (Map::enum(),Values::wx:wx_mem()) -> ok
+%% @spec (Map::enum(),Values::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetPixelMap.xml">external</a> documentation.
+-spec getPixelMapusv(enum(),mem()) -> ok.
getPixelMapusv(Map,Values) ->
- wxe_util:send_bin(Values#wx_mem.bin),
- wxe_util:call(5135, <<Map:?GLenum>>).
+ send_bin(Values),
+ call(5135, <<Map:?GLenum>>).
%% @spec () -> binary()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetPolygonStipple.xml">external</a> documentation.
+-spec getPolygonStipple() -> binary().
getPolygonStipple() ->
- wxe_util:call(5136, <<>>).
+ call(5136, <<>>).
%% @spec (Name::enum()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetString.xml">external</a> documentation.
+-spec getString(enum()) -> string().
getString(Name) ->
- wxe_util:call(5137, <<Name:?GLenum>>).
+ call(5137, <<Name:?GLenum>>).
-%% @spec (Target::enum(),Pname::enum()) -> {float()}
+%% @spec (Target::enum(),Pname::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexEnv.xml">external</a> documentation.
+-spec getTexEnvfv(enum(),enum()) -> {float(),float(),float(),float()}.
getTexEnvfv(Target,Pname) ->
- wxe_util:call(5138, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5138, <<Target:?GLenum,Pname:?GLenum>>).
-%% @spec (Target::enum(),Pname::enum()) -> {integer()}
+%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexEnv.xml">external</a> documentation.
+-spec getTexEnviv(enum(),enum()) -> {integer(),integer(),integer(),integer()}.
getTexEnviv(Target,Pname) ->
- wxe_util:call(5139, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5139, <<Target:?GLenum,Pname:?GLenum>>).
-%% @spec (Coord::enum(),Pname::enum()) -> {float()}
+%% @spec (Coord::enum(),Pname::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexGen.xml">external</a> documentation.
+-spec getTexGendv(enum(),enum()) -> {float(),float(),float(),float()}.
getTexGendv(Coord,Pname) ->
- wxe_util:call(5140, <<Coord:?GLenum,Pname:?GLenum>>).
+ call(5140, <<Coord:?GLenum,Pname:?GLenum>>).
-%% @spec (Coord::enum(),Pname::enum()) -> {float()}
+%% @spec (Coord::enum(),Pname::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexGen.xml">external</a> documentation.
+-spec getTexGenfv(enum(),enum()) -> {float(),float(),float(),float()}.
getTexGenfv(Coord,Pname) ->
- wxe_util:call(5141, <<Coord:?GLenum,Pname:?GLenum>>).
+ call(5141, <<Coord:?GLenum,Pname:?GLenum>>).
-%% @spec (Coord::enum(),Pname::enum()) -> {integer()}
+%% @spec (Coord::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexGen.xml">external</a> documentation.
+-spec getTexGeniv(enum(),enum()) -> {integer(),integer(),integer(),integer()}.
getTexGeniv(Coord,Pname) ->
- wxe_util:call(5142, <<Coord:?GLenum,Pname:?GLenum>>).
+ call(5142, <<Coord:?GLenum,Pname:?GLenum>>).
-%% @spec (Target::enum(),Level::integer(),Format::enum(),Type::enum(),Pixels::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Level::integer(),Format::enum(),Type::enum(),Pixels::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexImage.xml">external</a> documentation.
+-spec getTexImage(enum(),integer(),enum(),enum(),mem()) -> ok.
getTexImage(Target,Level,Format,Type,Pixels) ->
- wxe_util:send_bin(Pixels#wx_mem.bin),
- wxe_util:call(5143, <<Target:?GLenum,Level:?GLint,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Pixels),
+ call(5143, <<Target:?GLenum,Level:?GLint,Format:?GLenum,Type:?GLenum>>).
%% @spec (Target::enum(),Level::integer(),Pname::enum()) -> {float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexLevelParameter.xml">external</a> documentation.
+-spec getTexLevelParameterfv(enum(),integer(),enum()) -> {float()}.
getTexLevelParameterfv(Target,Level,Pname) ->
- wxe_util:call(5144, <<Target:?GLenum,Level:?GLint,Pname:?GLenum>>).
+ call(5144, <<Target:?GLenum,Level:?GLint,Pname:?GLenum>>).
%% @spec (Target::enum(),Level::integer(),Pname::enum()) -> {integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexLevelParameter.xml">external</a> documentation.
+-spec getTexLevelParameteriv(enum(),integer(),enum()) -> {integer()}.
getTexLevelParameteriv(Target,Level,Pname) ->
- wxe_util:call(5145, <<Target:?GLenum,Level:?GLint,Pname:?GLenum>>).
+ call(5145, <<Target:?GLenum,Level:?GLint,Pname:?GLenum>>).
-%% @spec (Target::enum(),Pname::enum()) -> {float()}
+%% @spec (Target::enum(),Pname::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameter.xml">external</a> documentation.
+-spec getTexParameterfv(enum(),enum()) -> {float(),float(),float(),float()}.
getTexParameterfv(Target,Pname) ->
- wxe_util:call(5146, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5146, <<Target:?GLenum,Pname:?GLenum>>).
-%% @spec (Target::enum(),Pname::enum()) -> {integer()}
+%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameter.xml">external</a> documentation.
+-spec getTexParameteriv(enum(),enum()) -> {integer(),integer(),integer(),integer()}.
getTexParameteriv(Target,Pname) ->
- wxe_util:call(5147, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5147, <<Target:?GLenum,Pname:?GLenum>>).
%% @spec (Target::enum(),Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glHint.xml">external</a> documentation.
+-spec hint(enum(),enum()) -> ok.
hint(Target,Mode) ->
- wxe_util:cast(5148, <<Target:?GLenum,Mode:?GLenum>>).
+ cast(5148, <<Target:?GLenum,Mode:?GLenum>>).
%% @spec (Mask::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndexMask.xml">external</a> documentation.
+-spec indexMask(integer()) -> ok.
indexMask(Mask) ->
- wxe_util:cast(5149, <<Mask:?GLuint>>).
+ cast(5149, <<Mask:?GLuint>>).
-%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndexPointer.xml">external</a> documentation.
+-spec indexPointer(enum(),integer(),offset()|mem()) -> ok.
indexPointer(Type,Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5150, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5150, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
indexPointer(Type,Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5151, <<Type:?GLenum,Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5151, <<Type:?GLenum,Stride:?GLsizei>>).
%% @spec (C::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml">external</a> documentation.
+-spec indexd(float()) -> ok.
indexd(C) ->
- wxe_util:cast(5152, <<C:?GLdouble>>).
+ cast(5152, <<C:?GLdouble>>).
%% @spec ({C}) -> ok
%% @equiv indexd(C)
+-spec indexdv({float()}) -> ok.
indexdv({C}) -> indexd(C).
%% @spec (C::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml">external</a> documentation.
+-spec indexf(float()) -> ok.
indexf(C) ->
- wxe_util:cast(5153, <<C:?GLfloat>>).
+ cast(5153, <<C:?GLfloat>>).
%% @spec ({C}) -> ok
%% @equiv indexf(C)
+-spec indexfv({float()}) -> ok.
indexfv({C}) -> indexf(C).
%% @spec (C::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml">external</a> documentation.
+-spec indexi(integer()) -> ok.
indexi(C) ->
- wxe_util:cast(5154, <<C:?GLint>>).
+ cast(5154, <<C:?GLint>>).
%% @spec ({C}) -> ok
%% @equiv indexi(C)
+-spec indexiv({integer()}) -> ok.
indexiv({C}) -> indexi(C).
%% @spec (C::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml">external</a> documentation.
+-spec indexs(integer()) -> ok.
indexs(C) ->
- wxe_util:cast(5155, <<C:?GLshort>>).
+ cast(5155, <<C:?GLshort>>).
%% @spec ({C}) -> ok
%% @equiv indexs(C)
+-spec indexsv({integer()}) -> ok.
indexsv({C}) -> indexs(C).
%% @spec (C::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml">external</a> documentation.
+-spec indexub(integer()) -> ok.
indexub(C) ->
- wxe_util:cast(5156, <<C:?GLubyte>>).
+ cast(5156, <<C:?GLubyte>>).
%% @spec ({C}) -> ok
%% @equiv indexub(C)
+-spec indexubv({integer()}) -> ok.
indexubv({C}) -> indexub(C).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glInitNames.xml">external</a> documentation.
+-spec initNames() -> ok.
initNames() ->
- wxe_util:cast(5157, <<>>).
+ cast(5157, <<>>).
-%% @spec (Format::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Format::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glInterleavedArrays.xml">external</a> documentation.
+-spec interleavedArrays(enum(),integer(),offset()|mem()) -> ok.
interleavedArrays(Format,Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5158, <<Format:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5158, <<Format:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
interleavedArrays(Format,Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5159, <<Format:?GLenum,Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5159, <<Format:?GLenum,Stride:?GLsizei>>).
%% @spec (Cap::enum()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsEnabled.xml">external</a> documentation.
+-spec isEnabled(enum()) -> 0|1.
isEnabled(Cap) ->
- wxe_util:call(5160, <<Cap:?GLenum>>).
+ call(5160, <<Cap:?GLenum>>).
%% @spec (List::integer()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsList.xml">external</a> documentation.
+-spec isList(integer()) -> 0|1.
isList(List) ->
- wxe_util:call(5161, <<List:?GLuint>>).
+ call(5161, <<List:?GLuint>>).
%% @spec (Texture::integer()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsTexture.xml">external</a> documentation.
+-spec isTexture(integer()) -> 0|1.
isTexture(Texture) ->
- wxe_util:call(5162, <<Texture:?GLuint>>).
+ call(5162, <<Texture:?GLuint>>).
%% @spec (Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml">external</a> documentation.
+-spec lightModelf(enum(),float()) -> ok.
lightModelf(Pname,Param) ->
- wxe_util:cast(5163, <<Pname:?GLenum,Param:?GLfloat>>).
+ cast(5163, <<Pname:?GLenum,Param:?GLfloat>>).
%% @spec (Pname::enum(),Params::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml">external</a> documentation.
+-spec lightModelfv(enum(),{float()}) -> ok.
lightModelfv(Pname,Params) ->
- wxe_util:cast(5164, <<Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5164, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @spec (Pname::enum(),Param::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml">external</a> documentation.
+-spec lightModeli(enum(),integer()) -> ok.
lightModeli(Pname,Param) ->
- wxe_util:cast(5165, <<Pname:?GLenum,Param:?GLint>>).
+ cast(5165, <<Pname:?GLenum,Param:?GLint>>).
%% @spec (Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml">external</a> documentation.
+-spec lightModeliv(enum(),{integer()}) -> ok.
lightModeliv(Pname,Params) ->
- wxe_util:cast(5166, <<Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5166, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @spec (Light::enum(),Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml">external</a> documentation.
+-spec lightf(enum(),enum(),float()) -> ok.
lightf(Light,Pname,Param) ->
- wxe_util:cast(5167, <<Light:?GLenum,Pname:?GLenum,Param:?GLfloat>>).
+ cast(5167, <<Light:?GLenum,Pname:?GLenum,Param:?GLfloat>>).
%% @spec (Light::enum(),Pname::enum(),Params::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml">external</a> documentation.
+-spec lightfv(enum(),enum(),{float()}) -> ok.
lightfv(Light,Pname,Params) ->
- wxe_util:cast(5168, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5168, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Light::enum(),Pname::enum(),Param::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml">external</a> documentation.
+-spec lighti(enum(),enum(),integer()) -> ok.
lighti(Light,Pname,Param) ->
- wxe_util:cast(5169, <<Light:?GLenum,Pname:?GLenum,Param:?GLint>>).
+ cast(5169, <<Light:?GLenum,Pname:?GLenum,Param:?GLint>>).
%% @spec (Light::enum(),Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml">external</a> documentation.
+-spec lightiv(enum(),enum(),{integer()}) -> ok.
lightiv(Light,Pname,Params) ->
- wxe_util:cast(5170, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5170, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Factor::integer(),Pattern::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLineStipple.xml">external</a> documentation.
+-spec lineStipple(integer(),integer()) -> ok.
lineStipple(Factor,Pattern) ->
- wxe_util:cast(5171, <<Factor:?GLint,Pattern:?GLushort>>).
+ cast(5171, <<Factor:?GLint,Pattern:?GLushort>>).
%% @spec (Width::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLineWidth.xml">external</a> documentation.
+-spec lineWidth(float()) -> ok.
lineWidth(Width) ->
- wxe_util:cast(5172, <<Width:?GLfloat>>).
+ cast(5172, <<Width:?GLfloat>>).
%% @spec (Base::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glListBase.xml">external</a> documentation.
+-spec listBase(integer()) -> ok.
listBase(Base) ->
- wxe_util:cast(5173, <<Base:?GLuint>>).
+ cast(5173, <<Base:?GLuint>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadIdentity.xml">external</a> documentation.
+-spec loadIdentity() -> ok.
loadIdentity() ->
- wxe_util:cast(5174, <<>>).
+ cast(5174, <<>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadMatrix.xml">external</a> documentation.
+-spec loadMatrixd({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
loadMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5175, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
+ cast(5175, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
loadMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5175, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
+ cast(5175, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadMatrix.xml">external</a> documentation.
+-spec loadMatrixf({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
loadMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5176, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
+ cast(5176, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
loadMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5176, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
+ cast(5176, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
%% @spec (Name::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadName.xml">external</a> documentation.
+-spec loadName(integer()) -> ok.
loadName(Name) ->
- wxe_util:cast(5177, <<Name:?GLuint>>).
+ cast(5177, <<Name:?GLuint>>).
%% @spec (Opcode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLogicOp.xml">external</a> documentation.
+-spec logicOp(enum()) -> ok.
logicOp(Opcode) ->
- wxe_util:cast(5178, <<Opcode:?GLenum>>).
+ cast(5178, <<Opcode:?GLenum>>).
%% @spec (Target::enum(),U1::float(),U2::float(),Stride::integer(),Order::integer(),Points::binary()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMap.xml">external</a> documentation.
+-spec map1d(enum(),float(),float(),integer(),integer(),binary()) -> ok.
map1d(Target,U1,U2,Stride,Order,Points) ->
- wxe_util:send_bin(Points),
- wxe_util:cast(5179, <<Target:?GLenum,0:32,U1:?GLdouble,U2:?GLdouble,Stride:?GLint,Order:?GLint>>).
+ send_bin(Points),
+ cast(5179, <<Target:?GLenum,0:32,U1:?GLdouble,U2:?GLdouble,Stride:?GLint,Order:?GLint>>).
%% @spec (Target::enum(),U1::float(),U2::float(),Stride::integer(),Order::integer(),Points::binary()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMap.xml">external</a> documentation.
+-spec map1f(enum(),float(),float(),integer(),integer(),binary()) -> ok.
map1f(Target,U1,U2,Stride,Order,Points) ->
- wxe_util:send_bin(Points),
- wxe_util:cast(5180, <<Target:?GLenum,U1:?GLfloat,U2:?GLfloat,Stride:?GLint,Order:?GLint>>).
+ send_bin(Points),
+ cast(5180, <<Target:?GLenum,U1:?GLfloat,U2:?GLfloat,Stride:?GLint,Order:?GLint>>).
%% @spec (Target::enum(),U1::float(),U2::float(),Ustride::integer(),Uorder::integer(),V1::float(),V2::float(),Vstride::integer(),Vorder::integer(),Points::binary()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMap.xml">external</a> documentation.
+-spec map2d(enum(),float(),float(),integer(),integer(),float(),float(),integer(),integer(),binary()) -> ok.
map2d(Target,U1,U2,Ustride,Uorder,V1,V2,Vstride,Vorder,Points) ->
- wxe_util:send_bin(Points),
- wxe_util:cast(5181, <<Target:?GLenum,0:32,U1:?GLdouble,U2:?GLdouble,Ustride:?GLint,Uorder:?GLint,V1:?GLdouble,V2:?GLdouble,Vstride:?GLint,Vorder:?GLint>>).
+ send_bin(Points),
+ cast(5181, <<Target:?GLenum,0:32,U1:?GLdouble,U2:?GLdouble,Ustride:?GLint,Uorder:?GLint,V1:?GLdouble,V2:?GLdouble,Vstride:?GLint,Vorder:?GLint>>).
%% @spec (Target::enum(),U1::float(),U2::float(),Ustride::integer(),Uorder::integer(),V1::float(),V2::float(),Vstride::integer(),Vorder::integer(),Points::binary()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMap.xml">external</a> documentation.
+-spec map2f(enum(),float(),float(),integer(),integer(),float(),float(),integer(),integer(),binary()) -> ok.
map2f(Target,U1,U2,Ustride,Uorder,V1,V2,Vstride,Vorder,Points) ->
- wxe_util:send_bin(Points),
- wxe_util:cast(5182, <<Target:?GLenum,U1:?GLfloat,U2:?GLfloat,Ustride:?GLint,Uorder:?GLint,V1:?GLfloat,V2:?GLfloat,Vstride:?GLint,Vorder:?GLint>>).
+ send_bin(Points),
+ cast(5182, <<Target:?GLenum,U1:?GLfloat,U2:?GLfloat,Ustride:?GLint,Uorder:?GLint,V1:?GLfloat,V2:?GLfloat,Vstride:?GLint,Vorder:?GLint>>).
%% @spec (Un::integer(),U1::float(),U2::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMapGrid.xml">external</a> documentation.
+-spec mapGrid1d(integer(),float(),float()) -> ok.
mapGrid1d(Un,U1,U2) ->
- wxe_util:cast(5183, <<Un:?GLint,0:32,U1:?GLdouble,U2:?GLdouble>>).
+ cast(5183, <<Un:?GLint,0:32,U1:?GLdouble,U2:?GLdouble>>).
%% @spec (Un::integer(),U1::float(),U2::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMapGrid.xml">external</a> documentation.
+-spec mapGrid1f(integer(),float(),float()) -> ok.
mapGrid1f(Un,U1,U2) ->
- wxe_util:cast(5184, <<Un:?GLint,U1:?GLfloat,U2:?GLfloat>>).
+ cast(5184, <<Un:?GLint,U1:?GLfloat,U2:?GLfloat>>).
%% @spec (Un::integer(),U1::float(),U2::float(),Vn::integer(),V1::float(),V2::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMapGrid.xml">external</a> documentation.
+-spec mapGrid2d(integer(),float(),float(),integer(),float(),float()) -> ok.
mapGrid2d(Un,U1,U2,Vn,V1,V2) ->
- wxe_util:cast(5185, <<Un:?GLint,0:32,U1:?GLdouble,U2:?GLdouble,Vn:?GLint,0:32,V1:?GLdouble,V2:?GLdouble>>).
+ cast(5185, <<Un:?GLint,0:32,U1:?GLdouble,U2:?GLdouble,Vn:?GLint,0:32,V1:?GLdouble,V2:?GLdouble>>).
%% @spec (Un::integer(),U1::float(),U2::float(),Vn::integer(),V1::float(),V2::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMapGrid.xml">external</a> documentation.
+-spec mapGrid2f(integer(),float(),float(),integer(),float(),float()) -> ok.
mapGrid2f(Un,U1,U2,Vn,V1,V2) ->
- wxe_util:cast(5186, <<Un:?GLint,U1:?GLfloat,U2:?GLfloat,Vn:?GLint,V1:?GLfloat,V2:?GLfloat>>).
+ cast(5186, <<Un:?GLint,U1:?GLfloat,U2:?GLfloat,Vn:?GLint,V1:?GLfloat,V2:?GLfloat>>).
%% @spec (Face::enum(),Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMaterial.xml">external</a> documentation.
+-spec materialf(enum(),enum(),float()) -> ok.
materialf(Face,Pname,Param) ->
- wxe_util:cast(5187, <<Face:?GLenum,Pname:?GLenum,Param:?GLfloat>>).
+ cast(5187, <<Face:?GLenum,Pname:?GLenum,Param:?GLfloat>>).
%% @spec (Face::enum(),Pname::enum(),Params::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMaterial.xml">external</a> documentation.
+-spec materialfv(enum(),enum(),{float()}) -> ok.
materialfv(Face,Pname,Params) ->
- wxe_util:cast(5188, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5188, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Face::enum(),Pname::enum(),Param::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMaterial.xml">external</a> documentation.
+-spec materiali(enum(),enum(),integer()) -> ok.
materiali(Face,Pname,Param) ->
- wxe_util:cast(5189, <<Face:?GLenum,Pname:?GLenum,Param:?GLint>>).
+ cast(5189, <<Face:?GLenum,Pname:?GLenum,Param:?GLint>>).
%% @spec (Face::enum(),Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMaterial.xml">external</a> documentation.
+-spec materialiv(enum(),enum(),{integer()}) -> ok.
materialiv(Face,Pname,Params) ->
- wxe_util:cast(5190, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5190, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixMode.xml">external</a> documentation.
+-spec matrixMode(enum()) -> ok.
matrixMode(Mode) ->
- wxe_util:cast(5191, <<Mode:?GLenum>>).
+ cast(5191, <<Mode:?GLenum>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultMatrix.xml">external</a> documentation.
+-spec multMatrixd({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
multMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5192, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
+ cast(5192, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
multMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5192, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
+ cast(5192, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultMatrix.xml">external</a> documentation.
+-spec multMatrixf({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
multMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5193, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
+ cast(5193, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
multMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5193, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
+ cast(5193, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
%% @spec (List::integer(),Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNewList.xml">external</a> documentation.
+-spec newList(integer(),enum()) -> ok.
newList(List,Mode) ->
- wxe_util:cast(5194, <<List:?GLuint,Mode:?GLenum>>).
+ cast(5194, <<List:?GLuint,Mode:?GLenum>>).
%% @spec (Nx::integer(),Ny::integer(),Nz::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml">external</a> documentation.
+-spec normal3b(integer(),integer(),integer()) -> ok.
normal3b(Nx,Ny,Nz) ->
- wxe_util:cast(5195, <<Nx:?GLbyte,Ny:?GLbyte,Nz:?GLbyte>>).
+ cast(5195, <<Nx:?GLbyte,Ny:?GLbyte,Nz:?GLbyte>>).
%% @spec ({Nx,Ny,Nz}) -> ok
%% @equiv normal3b(Nx,Ny,Nz)
+-spec normal3bv({integer(),integer(),integer()}) -> ok.
normal3bv({Nx,Ny,Nz}) -> normal3b(Nx,Ny,Nz).
%% @spec (Nx::float(),Ny::float(),Nz::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml">external</a> documentation.
+-spec normal3d(float(),float(),float()) -> ok.
normal3d(Nx,Ny,Nz) ->
- wxe_util:cast(5196, <<Nx:?GLdouble,Ny:?GLdouble,Nz:?GLdouble>>).
+ cast(5196, <<Nx:?GLdouble,Ny:?GLdouble,Nz:?GLdouble>>).
%% @spec ({Nx,Ny,Nz}) -> ok
%% @equiv normal3d(Nx,Ny,Nz)
+-spec normal3dv({float(),float(),float()}) -> ok.
normal3dv({Nx,Ny,Nz}) -> normal3d(Nx,Ny,Nz).
%% @spec (Nx::float(),Ny::float(),Nz::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml">external</a> documentation.
+-spec normal3f(float(),float(),float()) -> ok.
normal3f(Nx,Ny,Nz) ->
- wxe_util:cast(5197, <<Nx:?GLfloat,Ny:?GLfloat,Nz:?GLfloat>>).
+ cast(5197, <<Nx:?GLfloat,Ny:?GLfloat,Nz:?GLfloat>>).
%% @spec ({Nx,Ny,Nz}) -> ok
%% @equiv normal3f(Nx,Ny,Nz)
+-spec normal3fv({float(),float(),float()}) -> ok.
normal3fv({Nx,Ny,Nz}) -> normal3f(Nx,Ny,Nz).
%% @spec (Nx::integer(),Ny::integer(),Nz::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml">external</a> documentation.
+-spec normal3i(integer(),integer(),integer()) -> ok.
normal3i(Nx,Ny,Nz) ->
- wxe_util:cast(5198, <<Nx:?GLint,Ny:?GLint,Nz:?GLint>>).
+ cast(5198, <<Nx:?GLint,Ny:?GLint,Nz:?GLint>>).
%% @spec ({Nx,Ny,Nz}) -> ok
%% @equiv normal3i(Nx,Ny,Nz)
+-spec normal3iv({integer(),integer(),integer()}) -> ok.
normal3iv({Nx,Ny,Nz}) -> normal3i(Nx,Ny,Nz).
%% @spec (Nx::integer(),Ny::integer(),Nz::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml">external</a> documentation.
+-spec normal3s(integer(),integer(),integer()) -> ok.
normal3s(Nx,Ny,Nz) ->
- wxe_util:cast(5199, <<Nx:?GLshort,Ny:?GLshort,Nz:?GLshort>>).
+ cast(5199, <<Nx:?GLshort,Ny:?GLshort,Nz:?GLshort>>).
%% @spec ({Nx,Ny,Nz}) -> ok
%% @equiv normal3s(Nx,Ny,Nz)
+-spec normal3sv({integer(),integer(),integer()}) -> ok.
normal3sv({Nx,Ny,Nz}) -> normal3s(Nx,Ny,Nz).
-%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormalPointer.xml">external</a> documentation.
+-spec normalPointer(enum(),integer(),offset()|mem()) -> ok.
normalPointer(Type,Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5200, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5200, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
normalPointer(Type,Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5201, <<Type:?GLenum,Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5201, <<Type:?GLenum,Stride:?GLsizei>>).
%% @spec (Left::float(),Right::float(),Bottom::float(),Top::float(),ZNear::float(),ZFar::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml">external</a> documentation.
+-spec ortho(float(),float(),float(),float(),float(),float()) -> ok.
ortho(Left,Right,Bottom,Top,ZNear,ZFar) ->
- wxe_util:cast(5202, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>).
+ cast(5202, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>).
%% @spec (Token::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPassThrough.xml">external</a> documentation.
+-spec passThrough(float()) -> ok.
passThrough(Token) ->
- wxe_util:cast(5203, <<Token:?GLfloat>>).
+ cast(5203, <<Token:?GLfloat>>).
%% @spec (Map::enum(),Mapsize::integer(),Values::binary()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelMap.xml">external</a> documentation.
+-spec pixelMapfv(enum(),integer(),binary()) -> ok.
pixelMapfv(Map,Mapsize,Values) ->
- wxe_util:send_bin(Values),
- wxe_util:cast(5204, <<Map:?GLenum,Mapsize:?GLsizei>>).
+ send_bin(Values),
+ cast(5204, <<Map:?GLenum,Mapsize:?GLsizei>>).
%% @spec (Map::enum(),Mapsize::integer(),Values::binary()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelMap.xml">external</a> documentation.
+-spec pixelMapuiv(enum(),integer(),binary()) -> ok.
pixelMapuiv(Map,Mapsize,Values) ->
- wxe_util:send_bin(Values),
- wxe_util:cast(5205, <<Map:?GLenum,Mapsize:?GLsizei>>).
+ send_bin(Values),
+ cast(5205, <<Map:?GLenum,Mapsize:?GLsizei>>).
%% @spec (Map::enum(),Mapsize::integer(),Values::binary()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelMap.xml">external</a> documentation.
+-spec pixelMapusv(enum(),integer(),binary()) -> ok.
pixelMapusv(Map,Mapsize,Values) ->
- wxe_util:send_bin(Values),
- wxe_util:cast(5206, <<Map:?GLenum,Mapsize:?GLsizei>>).
+ send_bin(Values),
+ cast(5206, <<Map:?GLenum,Mapsize:?GLsizei>>).
%% @spec (Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelStore.xml">external</a> documentation.
+-spec pixelStoref(enum(),float()) -> ok.
pixelStoref(Pname,Param) ->
- wxe_util:cast(5207, <<Pname:?GLenum,Param:?GLfloat>>).
+ cast(5207, <<Pname:?GLenum,Param:?GLfloat>>).
%% @spec (Pname::enum(),Param::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelStore.xml">external</a> documentation.
+-spec pixelStorei(enum(),integer()) -> ok.
pixelStorei(Pname,Param) ->
- wxe_util:cast(5208, <<Pname:?GLenum,Param:?GLint>>).
+ cast(5208, <<Pname:?GLenum,Param:?GLint>>).
%% @spec (Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelTransfer.xml">external</a> documentation.
+-spec pixelTransferf(enum(),float()) -> ok.
pixelTransferf(Pname,Param) ->
- wxe_util:cast(5209, <<Pname:?GLenum,Param:?GLfloat>>).
+ cast(5209, <<Pname:?GLenum,Param:?GLfloat>>).
%% @spec (Pname::enum(),Param::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelTransfer.xml">external</a> documentation.
+-spec pixelTransferi(enum(),integer()) -> ok.
pixelTransferi(Pname,Param) ->
- wxe_util:cast(5210, <<Pname:?GLenum,Param:?GLint>>).
+ cast(5210, <<Pname:?GLenum,Param:?GLint>>).
%% @spec (Xfactor::float(),Yfactor::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelZoom.xml">external</a> documentation.
+-spec pixelZoom(float(),float()) -> ok.
pixelZoom(Xfactor,Yfactor) ->
- wxe_util:cast(5211, <<Xfactor:?GLfloat,Yfactor:?GLfloat>>).
+ cast(5211, <<Xfactor:?GLfloat,Yfactor:?GLfloat>>).
%% @spec (Size::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointSize.xml">external</a> documentation.
+-spec pointSize(float()) -> ok.
pointSize(Size) ->
- wxe_util:cast(5212, <<Size:?GLfloat>>).
+ cast(5212, <<Size:?GLfloat>>).
%% @spec (Face::enum(),Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPolygonMode.xml">external</a> documentation.
+-spec polygonMode(enum(),enum()) -> ok.
polygonMode(Face,Mode) ->
- wxe_util:cast(5213, <<Face:?GLenum,Mode:?GLenum>>).
+ cast(5213, <<Face:?GLenum,Mode:?GLenum>>).
%% @spec (Factor::float(),Units::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPolygonOffset.xml">external</a> documentation.
+-spec polygonOffset(float(),float()) -> ok.
polygonOffset(Factor,Units) ->
- wxe_util:cast(5214, <<Factor:?GLfloat,Units:?GLfloat>>).
+ cast(5214, <<Factor:?GLfloat,Units:?GLfloat>>).
%% @spec (Mask::binary()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPolygonStipple.xml">external</a> documentation.
+-spec polygonStipple(binary()) -> ok.
polygonStipple(Mask) ->
- wxe_util:send_bin(Mask),
- wxe_util:cast(5215, <<>>).
+ send_bin(Mask),
+ cast(5215, <<>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPopAttrib.xml">external</a> documentation.
+-spec popAttrib() -> ok.
popAttrib() ->
- wxe_util:cast(5216, <<>>).
+ cast(5216, <<>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPopClientAttrib.xml">external</a> documentation.
+-spec popClientAttrib() -> ok.
popClientAttrib() ->
- wxe_util:cast(5217, <<>>).
+ cast(5217, <<>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPopMatrix.xml">external</a> documentation.
+-spec popMatrix() -> ok.
popMatrix() ->
- wxe_util:cast(5218, <<>>).
+ cast(5218, <<>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPopName.xml">external</a> documentation.
+-spec popName() -> ok.
popName() ->
- wxe_util:cast(5219, <<>>).
+ cast(5219, <<>>).
%% @spec (Textures::[integer()],Priorities::[clamp()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPrioritizeTextures.xml">external</a> documentation.
+-spec prioritizeTextures([integer()],[clamp()]) -> ok.
prioritizeTextures(Textures,Priorities) ->
- wxe_util:cast(5220, <<(length(Textures)):?GLuint,
+ cast(5220, <<(length(Textures)):?GLuint,
(<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32),(length(Priorities)):?GLuint,
(<< <<C:?GLclampf>> || C <- Priorities>>)/binary,0:(((1+length(Priorities)) rem 2)*32)>>).
%% @spec (Mask::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPushAttrib.xml">external</a> documentation.
+-spec pushAttrib(integer()) -> ok.
pushAttrib(Mask) ->
- wxe_util:cast(5221, <<Mask:?GLbitfield>>).
+ cast(5221, <<Mask:?GLbitfield>>).
%% @spec (Mask::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPushClientAttrib.xml">external</a> documentation.
+-spec pushClientAttrib(integer()) -> ok.
pushClientAttrib(Mask) ->
- wxe_util:cast(5222, <<Mask:?GLbitfield>>).
+ cast(5222, <<Mask:?GLbitfield>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPushMatrix.xml">external</a> documentation.
+-spec pushMatrix() -> ok.
pushMatrix() ->
- wxe_util:cast(5223, <<>>).
+ cast(5223, <<>>).
%% @spec (Name::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPushName.xml">external</a> documentation.
+-spec pushName(integer()) -> ok.
pushName(Name) ->
- wxe_util:cast(5224, <<Name:?GLuint>>).
+ cast(5224, <<Name:?GLuint>>).
%% @spec (X::float(),Y::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos2d(float(),float()) -> ok.
rasterPos2d(X,Y) ->
- wxe_util:cast(5225, <<X:?GLdouble,Y:?GLdouble>>).
+ cast(5225, <<X:?GLdouble,Y:?GLdouble>>).
%% @spec ({X,Y}) -> ok
%% @equiv rasterPos2d(X,Y)
+-spec rasterPos2dv({float(),float()}) -> ok.
rasterPos2dv({X,Y}) -> rasterPos2d(X,Y).
%% @spec (X::float(),Y::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos2f(float(),float()) -> ok.
rasterPos2f(X,Y) ->
- wxe_util:cast(5226, <<X:?GLfloat,Y:?GLfloat>>).
+ cast(5226, <<X:?GLfloat,Y:?GLfloat>>).
%% @spec ({X,Y}) -> ok
%% @equiv rasterPos2f(X,Y)
+-spec rasterPos2fv({float(),float()}) -> ok.
rasterPos2fv({X,Y}) -> rasterPos2f(X,Y).
%% @spec (X::integer(),Y::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos2i(integer(),integer()) -> ok.
rasterPos2i(X,Y) ->
- wxe_util:cast(5227, <<X:?GLint,Y:?GLint>>).
+ cast(5227, <<X:?GLint,Y:?GLint>>).
%% @spec ({X,Y}) -> ok
%% @equiv rasterPos2i(X,Y)
+-spec rasterPos2iv({integer(),integer()}) -> ok.
rasterPos2iv({X,Y}) -> rasterPos2i(X,Y).
%% @spec (X::integer(),Y::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos2s(integer(),integer()) -> ok.
rasterPos2s(X,Y) ->
- wxe_util:cast(5228, <<X:?GLshort,Y:?GLshort>>).
+ cast(5228, <<X:?GLshort,Y:?GLshort>>).
%% @spec ({X,Y}) -> ok
%% @equiv rasterPos2s(X,Y)
+-spec rasterPos2sv({integer(),integer()}) -> ok.
rasterPos2sv({X,Y}) -> rasterPos2s(X,Y).
%% @spec (X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos3d(float(),float(),float()) -> ok.
rasterPos3d(X,Y,Z) ->
- wxe_util:cast(5229, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5229, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv rasterPos3d(X,Y,Z)
+-spec rasterPos3dv({float(),float(),float()}) -> ok.
rasterPos3dv({X,Y,Z}) -> rasterPos3d(X,Y,Z).
%% @spec (X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos3f(float(),float(),float()) -> ok.
rasterPos3f(X,Y,Z) ->
- wxe_util:cast(5230, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5230, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv rasterPos3f(X,Y,Z)
+-spec rasterPos3fv({float(),float(),float()}) -> ok.
rasterPos3fv({X,Y,Z}) -> rasterPos3f(X,Y,Z).
%% @spec (X::integer(),Y::integer(),Z::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos3i(integer(),integer(),integer()) -> ok.
rasterPos3i(X,Y,Z) ->
- wxe_util:cast(5231, <<X:?GLint,Y:?GLint,Z:?GLint>>).
+ cast(5231, <<X:?GLint,Y:?GLint,Z:?GLint>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv rasterPos3i(X,Y,Z)
+-spec rasterPos3iv({integer(),integer(),integer()}) -> ok.
rasterPos3iv({X,Y,Z}) -> rasterPos3i(X,Y,Z).
%% @spec (X::integer(),Y::integer(),Z::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos3s(integer(),integer(),integer()) -> ok.
rasterPos3s(X,Y,Z) ->
- wxe_util:cast(5232, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>).
+ cast(5232, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv rasterPos3s(X,Y,Z)
+-spec rasterPos3sv({integer(),integer(),integer()}) -> ok.
rasterPos3sv({X,Y,Z}) -> rasterPos3s(X,Y,Z).
%% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos4d(float(),float(),float(),float()) -> ok.
rasterPos4d(X,Y,Z,W) ->
- wxe_util:cast(5233, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5233, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv rasterPos4d(X,Y,Z,W)
+-spec rasterPos4dv({float(),float(),float(),float()}) -> ok.
rasterPos4dv({X,Y,Z,W}) -> rasterPos4d(X,Y,Z,W).
%% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos4f(float(),float(),float(),float()) -> ok.
rasterPos4f(X,Y,Z,W) ->
- wxe_util:cast(5234, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5234, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv rasterPos4f(X,Y,Z,W)
+-spec rasterPos4fv({float(),float(),float(),float()}) -> ok.
rasterPos4fv({X,Y,Z,W}) -> rasterPos4f(X,Y,Z,W).
%% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos4i(integer(),integer(),integer(),integer()) -> ok.
rasterPos4i(X,Y,Z,W) ->
- wxe_util:cast(5235, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
+ cast(5235, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv rasterPos4i(X,Y,Z,W)
+-spec rasterPos4iv({integer(),integer(),integer(),integer()}) -> ok.
rasterPos4iv({X,Y,Z,W}) -> rasterPos4i(X,Y,Z,W).
%% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation.
+-spec rasterPos4s(integer(),integer(),integer(),integer()) -> ok.
rasterPos4s(X,Y,Z,W) ->
- wxe_util:cast(5236, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
+ cast(5236, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv rasterPos4s(X,Y,Z,W)
+-spec rasterPos4sv({integer(),integer(),integer(),integer()}) -> ok.
rasterPos4sv({X,Y,Z,W}) -> rasterPos4s(X,Y,Z,W).
%% @spec (Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glReadBuffer.xml">external</a> documentation.
+-spec readBuffer(enum()) -> ok.
readBuffer(Mode) ->
- wxe_util:cast(5237, <<Mode:?GLenum>>).
+ cast(5237, <<Mode:?GLenum>>).
-%% @spec (X::integer(),Y::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::wx:wx_mem()) -> ok
+%% @spec (X::integer(),Y::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml">external</a> documentation.
+-spec readPixels(integer(),integer(),integer(),integer(),enum(),enum(),mem()) -> ok.
readPixels(X,Y,Width,Height,Format,Type,Pixels) ->
- wxe_util:send_bin(Pixels#wx_mem.bin),
- wxe_util:call(5238, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Pixels),
+ call(5238, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
%% @spec (X1::float(),Y1::float(),X2::float(),Y2::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation.
+-spec rectd(float(),float(),float(),float()) -> ok.
rectd(X1,Y1,X2,Y2) ->
- wxe_util:cast(5239, <<X1:?GLdouble,Y1:?GLdouble,X2:?GLdouble,Y2:?GLdouble>>).
+ cast(5239, <<X1:?GLdouble,Y1:?GLdouble,X2:?GLdouble,Y2:?GLdouble>>).
-%% @spec (V1::{float()},V2::{float()}) -> ok
+%% @spec (V1::{float(),float()},V2::{float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation.
+-spec rectdv({float(),float()},{float(),float()}) -> ok.
rectdv({V1,V2},{V1,V2}) ->
- wxe_util:cast(5240, <<V1:?GLdouble,V2:?GLdouble,V1:?GLdouble,V2:?GLdouble>>).
+ cast(5240, <<V1:?GLdouble,V2:?GLdouble,V1:?GLdouble,V2:?GLdouble>>).
%% @spec (X1::float(),Y1::float(),X2::float(),Y2::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation.
+-spec rectf(float(),float(),float(),float()) -> ok.
rectf(X1,Y1,X2,Y2) ->
- wxe_util:cast(5241, <<X1:?GLfloat,Y1:?GLfloat,X2:?GLfloat,Y2:?GLfloat>>).
+ cast(5241, <<X1:?GLfloat,Y1:?GLfloat,X2:?GLfloat,Y2:?GLfloat>>).
-%% @spec (V1::{float()},V2::{float()}) -> ok
+%% @spec (V1::{float(),float()},V2::{float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation.
+-spec rectfv({float(),float()},{float(),float()}) -> ok.
rectfv({V1,V2},{V1,V2}) ->
- wxe_util:cast(5242, <<V1:?GLfloat,V2:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
+ cast(5242, <<V1:?GLfloat,V2:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
%% @spec (X1::integer(),Y1::integer(),X2::integer(),Y2::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation.
+-spec recti(integer(),integer(),integer(),integer()) -> ok.
recti(X1,Y1,X2,Y2) ->
- wxe_util:cast(5243, <<X1:?GLint,Y1:?GLint,X2:?GLint,Y2:?GLint>>).
+ cast(5243, <<X1:?GLint,Y1:?GLint,X2:?GLint,Y2:?GLint>>).
-%% @spec (V1::{integer()},V2::{integer()}) -> ok
+%% @spec (V1::{integer(),integer()},V2::{integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation.
+-spec rectiv({integer(),integer()},{integer(),integer()}) -> ok.
rectiv({V1,V2},{V1,V2}) ->
- wxe_util:cast(5244, <<V1:?GLint,V2:?GLint,V1:?GLint,V2:?GLint>>).
+ cast(5244, <<V1:?GLint,V2:?GLint,V1:?GLint,V2:?GLint>>).
%% @spec (X1::integer(),Y1::integer(),X2::integer(),Y2::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation.
+-spec rects(integer(),integer(),integer(),integer()) -> ok.
rects(X1,Y1,X2,Y2) ->
- wxe_util:cast(5245, <<X1:?GLshort,Y1:?GLshort,X2:?GLshort,Y2:?GLshort>>).
+ cast(5245, <<X1:?GLshort,Y1:?GLshort,X2:?GLshort,Y2:?GLshort>>).
-%% @spec (V1::{integer()},V2::{integer()}) -> ok
+%% @spec (V1::{integer(),integer()},V2::{integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation.
+-spec rectsv({integer(),integer()},{integer(),integer()}) -> ok.
rectsv({V1,V2},{V1,V2}) ->
- wxe_util:cast(5246, <<V1:?GLshort,V2:?GLshort,V1:?GLshort,V2:?GLshort>>).
+ cast(5246, <<V1:?GLshort,V2:?GLshort,V1:?GLshort,V2:?GLshort>>).
%% @spec (Mode::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRenderMode.xml">external</a> documentation.
+-spec renderMode(enum()) -> integer().
renderMode(Mode) ->
- wxe_util:call(5247, <<Mode:?GLenum>>).
+ call(5247, <<Mode:?GLenum>>).
%% @spec (Angle::float(),X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRotate.xml">external</a> documentation.
+-spec rotated(float(),float(),float(),float()) -> ok.
rotated(Angle,X,Y,Z) ->
- wxe_util:cast(5248, <<Angle:?GLdouble,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5248, <<Angle:?GLdouble,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @spec (Angle::float(),X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRotate.xml">external</a> documentation.
+-spec rotatef(float(),float(),float(),float()) -> ok.
rotatef(Angle,X,Y,Z) ->
- wxe_util:cast(5249, <<Angle:?GLfloat,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5249, <<Angle:?GLfloat,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @spec (X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScale.xml">external</a> documentation.
+-spec scaled(float(),float(),float()) -> ok.
scaled(X,Y,Z) ->
- wxe_util:cast(5250, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5250, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @spec (X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScale.xml">external</a> documentation.
+-spec scalef(float(),float(),float()) -> ok.
scalef(X,Y,Z) ->
- wxe_util:cast(5251, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5251, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @spec (X::integer(),Y::integer(),Width::integer(),Height::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissor.xml">external</a> documentation.
+-spec scissor(integer(),integer(),integer(),integer()) -> ok.
scissor(X,Y,Width,Height) ->
- wxe_util:cast(5252, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5252, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>).
-%% @spec (Size::integer(),Buffer::wx:wx_mem()) -> ok
+%% @spec (Size::integer(),Buffer::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSelectBuffer.xml">external</a> documentation.
+-spec selectBuffer(integer(),mem()) -> ok.
selectBuffer(Size,Buffer) ->
- wxe_util:send_bin(Buffer#wx_mem.bin),
- wxe_util:call(5253, <<Size:?GLsizei>>).
+ send_bin(Buffer),
+ call(5253, <<Size:?GLsizei>>).
%% @spec (Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShadeModel.xml">external</a> documentation.
+-spec shadeModel(enum()) -> ok.
shadeModel(Mode) ->
- wxe_util:cast(5254, <<Mode:?GLenum>>).
+ cast(5254, <<Mode:?GLenum>>).
%% @spec (Func::enum(),Ref::integer(),Mask::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilFunc.xml">external</a> documentation.
+-spec stencilFunc(enum(),integer(),integer()) -> ok.
stencilFunc(Func,Ref,Mask) ->
- wxe_util:cast(5255, <<Func:?GLenum,Ref:?GLint,Mask:?GLuint>>).
+ cast(5255, <<Func:?GLenum,Ref:?GLint,Mask:?GLuint>>).
%% @spec (Mask::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilMask.xml">external</a> documentation.
+-spec stencilMask(integer()) -> ok.
stencilMask(Mask) ->
- wxe_util:cast(5256, <<Mask:?GLuint>>).
+ cast(5256, <<Mask:?GLuint>>).
%% @spec (Fail::enum(),Zfail::enum(),Zpass::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilOp.xml">external</a> documentation.
+-spec stencilOp(enum(),enum(),enum()) -> ok.
stencilOp(Fail,Zfail,Zpass) ->
- wxe_util:cast(5257, <<Fail:?GLenum,Zfail:?GLenum,Zpass:?GLenum>>).
+ cast(5257, <<Fail:?GLenum,Zfail:?GLenum,Zpass:?GLenum>>).
%% @spec (S::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord1d(float()) -> ok.
texCoord1d(S) ->
- wxe_util:cast(5258, <<S:?GLdouble>>).
+ cast(5258, <<S:?GLdouble>>).
%% @spec ({S}) -> ok
%% @equiv texCoord1d(S)
+-spec texCoord1dv({float()}) -> ok.
texCoord1dv({S}) -> texCoord1d(S).
%% @spec (S::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord1f(float()) -> ok.
texCoord1f(S) ->
- wxe_util:cast(5259, <<S:?GLfloat>>).
+ cast(5259, <<S:?GLfloat>>).
%% @spec ({S}) -> ok
%% @equiv texCoord1f(S)
+-spec texCoord1fv({float()}) -> ok.
texCoord1fv({S}) -> texCoord1f(S).
%% @spec (S::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord1i(integer()) -> ok.
texCoord1i(S) ->
- wxe_util:cast(5260, <<S:?GLint>>).
+ cast(5260, <<S:?GLint>>).
%% @spec ({S}) -> ok
%% @equiv texCoord1i(S)
+-spec texCoord1iv({integer()}) -> ok.
texCoord1iv({S}) -> texCoord1i(S).
%% @spec (S::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord1s(integer()) -> ok.
texCoord1s(S) ->
- wxe_util:cast(5261, <<S:?GLshort>>).
+ cast(5261, <<S:?GLshort>>).
%% @spec ({S}) -> ok
%% @equiv texCoord1s(S)
+-spec texCoord1sv({integer()}) -> ok.
texCoord1sv({S}) -> texCoord1s(S).
%% @spec (S::float(),T::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord2d(float(),float()) -> ok.
texCoord2d(S,T) ->
- wxe_util:cast(5262, <<S:?GLdouble,T:?GLdouble>>).
+ cast(5262, <<S:?GLdouble,T:?GLdouble>>).
%% @spec ({S,T}) -> ok
%% @equiv texCoord2d(S,T)
+-spec texCoord2dv({float(),float()}) -> ok.
texCoord2dv({S,T}) -> texCoord2d(S,T).
%% @spec (S::float(),T::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord2f(float(),float()) -> ok.
texCoord2f(S,T) ->
- wxe_util:cast(5263, <<S:?GLfloat,T:?GLfloat>>).
+ cast(5263, <<S:?GLfloat,T:?GLfloat>>).
%% @spec ({S,T}) -> ok
%% @equiv texCoord2f(S,T)
+-spec texCoord2fv({float(),float()}) -> ok.
texCoord2fv({S,T}) -> texCoord2f(S,T).
%% @spec (S::integer(),T::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord2i(integer(),integer()) -> ok.
texCoord2i(S,T) ->
- wxe_util:cast(5264, <<S:?GLint,T:?GLint>>).
+ cast(5264, <<S:?GLint,T:?GLint>>).
%% @spec ({S,T}) -> ok
%% @equiv texCoord2i(S,T)
+-spec texCoord2iv({integer(),integer()}) -> ok.
texCoord2iv({S,T}) -> texCoord2i(S,T).
%% @spec (S::integer(),T::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord2s(integer(),integer()) -> ok.
texCoord2s(S,T) ->
- wxe_util:cast(5265, <<S:?GLshort,T:?GLshort>>).
+ cast(5265, <<S:?GLshort,T:?GLshort>>).
%% @spec ({S,T}) -> ok
%% @equiv texCoord2s(S,T)
+-spec texCoord2sv({integer(),integer()}) -> ok.
texCoord2sv({S,T}) -> texCoord2s(S,T).
%% @spec (S::float(),T::float(),R::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord3d(float(),float(),float()) -> ok.
texCoord3d(S,T,R) ->
- wxe_util:cast(5266, <<S:?GLdouble,T:?GLdouble,R:?GLdouble>>).
+ cast(5266, <<S:?GLdouble,T:?GLdouble,R:?GLdouble>>).
%% @spec ({S,T,R}) -> ok
%% @equiv texCoord3d(S,T,R)
+-spec texCoord3dv({float(),float(),float()}) -> ok.
texCoord3dv({S,T,R}) -> texCoord3d(S,T,R).
%% @spec (S::float(),T::float(),R::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord3f(float(),float(),float()) -> ok.
texCoord3f(S,T,R) ->
- wxe_util:cast(5267, <<S:?GLfloat,T:?GLfloat,R:?GLfloat>>).
+ cast(5267, <<S:?GLfloat,T:?GLfloat,R:?GLfloat>>).
%% @spec ({S,T,R}) -> ok
%% @equiv texCoord3f(S,T,R)
+-spec texCoord3fv({float(),float(),float()}) -> ok.
texCoord3fv({S,T,R}) -> texCoord3f(S,T,R).
%% @spec (S::integer(),T::integer(),R::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord3i(integer(),integer(),integer()) -> ok.
texCoord3i(S,T,R) ->
- wxe_util:cast(5268, <<S:?GLint,T:?GLint,R:?GLint>>).
+ cast(5268, <<S:?GLint,T:?GLint,R:?GLint>>).
%% @spec ({S,T,R}) -> ok
%% @equiv texCoord3i(S,T,R)
+-spec texCoord3iv({integer(),integer(),integer()}) -> ok.
texCoord3iv({S,T,R}) -> texCoord3i(S,T,R).
%% @spec (S::integer(),T::integer(),R::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord3s(integer(),integer(),integer()) -> ok.
texCoord3s(S,T,R) ->
- wxe_util:cast(5269, <<S:?GLshort,T:?GLshort,R:?GLshort>>).
+ cast(5269, <<S:?GLshort,T:?GLshort,R:?GLshort>>).
%% @spec ({S,T,R}) -> ok
%% @equiv texCoord3s(S,T,R)
+-spec texCoord3sv({integer(),integer(),integer()}) -> ok.
texCoord3sv({S,T,R}) -> texCoord3s(S,T,R).
%% @spec (S::float(),T::float(),R::float(),Q::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord4d(float(),float(),float(),float()) -> ok.
texCoord4d(S,T,R,Q) ->
- wxe_util:cast(5270, <<S:?GLdouble,T:?GLdouble,R:?GLdouble,Q:?GLdouble>>).
+ cast(5270, <<S:?GLdouble,T:?GLdouble,R:?GLdouble,Q:?GLdouble>>).
%% @spec ({S,T,R,Q}) -> ok
%% @equiv texCoord4d(S,T,R,Q)
+-spec texCoord4dv({float(),float(),float(),float()}) -> ok.
texCoord4dv({S,T,R,Q}) -> texCoord4d(S,T,R,Q).
%% @spec (S::float(),T::float(),R::float(),Q::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord4f(float(),float(),float(),float()) -> ok.
texCoord4f(S,T,R,Q) ->
- wxe_util:cast(5271, <<S:?GLfloat,T:?GLfloat,R:?GLfloat,Q:?GLfloat>>).
+ cast(5271, <<S:?GLfloat,T:?GLfloat,R:?GLfloat,Q:?GLfloat>>).
%% @spec ({S,T,R,Q}) -> ok
%% @equiv texCoord4f(S,T,R,Q)
+-spec texCoord4fv({float(),float(),float(),float()}) -> ok.
texCoord4fv({S,T,R,Q}) -> texCoord4f(S,T,R,Q).
%% @spec (S::integer(),T::integer(),R::integer(),Q::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord4i(integer(),integer(),integer(),integer()) -> ok.
texCoord4i(S,T,R,Q) ->
- wxe_util:cast(5272, <<S:?GLint,T:?GLint,R:?GLint,Q:?GLint>>).
+ cast(5272, <<S:?GLint,T:?GLint,R:?GLint,Q:?GLint>>).
%% @spec ({S,T,R,Q}) -> ok
%% @equiv texCoord4i(S,T,R,Q)
+-spec texCoord4iv({integer(),integer(),integer(),integer()}) -> ok.
texCoord4iv({S,T,R,Q}) -> texCoord4i(S,T,R,Q).
%% @spec (S::integer(),T::integer(),R::integer(),Q::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation.
+-spec texCoord4s(integer(),integer(),integer(),integer()) -> ok.
texCoord4s(S,T,R,Q) ->
- wxe_util:cast(5273, <<S:?GLshort,T:?GLshort,R:?GLshort,Q:?GLshort>>).
+ cast(5273, <<S:?GLshort,T:?GLshort,R:?GLshort,Q:?GLshort>>).
%% @spec ({S,T,R,Q}) -> ok
%% @equiv texCoord4s(S,T,R,Q)
+-spec texCoord4sv({integer(),integer(),integer(),integer()}) -> ok.
texCoord4sv({S,T,R,Q}) -> texCoord4s(S,T,R,Q).
-%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoordPointer.xml">external</a> documentation.
+-spec texCoordPointer(integer(),enum(),integer(),offset()|mem()) -> ok.
texCoordPointer(Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5274, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5274, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
texCoordPointer(Size,Type,Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5275, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5275, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
%% @spec (Target::enum(),Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexEnvf.xml">external</a> documentation.
+-spec texEnvf(enum(),enum(),float()) -> ok.
texEnvf(Target,Pname,Param) ->
- wxe_util:cast(5276, <<Target:?GLenum,Pname:?GLenum,Param:?GLfloat>>).
+ cast(5276, <<Target:?GLenum,Pname:?GLenum,Param:?GLfloat>>).
%% @spec (Target::enum(),Pname::enum(),Params::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml">external</a> documentation.
+-spec texEnvfv(enum(),enum(),{float()}) -> ok.
texEnvfv(Target,Pname,Params) ->
- wxe_util:cast(5277, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5277, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Target::enum(),Pname::enum(),Param::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexEnvi.xml">external</a> documentation.
+-spec texEnvi(enum(),enum(),integer()) -> ok.
texEnvi(Target,Pname,Param) ->
- wxe_util:cast(5278, <<Target:?GLenum,Pname:?GLenum,Param:?GLint>>).
+ cast(5278, <<Target:?GLenum,Pname:?GLenum,Param:?GLint>>).
%% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml">external</a> documentation.
+-spec texEnviv(enum(),enum(),{integer()}) -> ok.
texEnviv(Target,Pname,Params) ->
- wxe_util:cast(5279, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5279, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Coord::enum(),Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation.
+-spec texGend(enum(),enum(),float()) -> ok.
texGend(Coord,Pname,Param) ->
- wxe_util:cast(5280, <<Coord:?GLenum,Pname:?GLenum,Param:?GLdouble>>).
+ cast(5280, <<Coord:?GLenum,Pname:?GLenum,Param:?GLdouble>>).
%% @spec (Coord::enum(),Pname::enum(),Params::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation.
+-spec texGendv(enum(),enum(),{float()}) -> ok.
texGendv(Coord,Pname,Params) ->
- wxe_util:cast(5281, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,0:32,
+ cast(5281, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,0:32,
(<< <<C:?GLdouble>> ||C <- tuple_to_list(Params)>>)/binary>>).
%% @spec (Coord::enum(),Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation.
+-spec texGenf(enum(),enum(),float()) -> ok.
texGenf(Coord,Pname,Param) ->
- wxe_util:cast(5282, <<Coord:?GLenum,Pname:?GLenum,Param:?GLfloat>>).
+ cast(5282, <<Coord:?GLenum,Pname:?GLenum,Param:?GLfloat>>).
%% @spec (Coord::enum(),Pname::enum(),Params::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation.
+-spec texGenfv(enum(),enum(),{float()}) -> ok.
texGenfv(Coord,Pname,Params) ->
- wxe_util:cast(5283, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5283, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Coord::enum(),Pname::enum(),Param::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation.
+-spec texGeni(enum(),enum(),integer()) -> ok.
texGeni(Coord,Pname,Param) ->
- wxe_util:cast(5284, <<Coord:?GLenum,Pname:?GLenum,Param:?GLint>>).
+ cast(5284, <<Coord:?GLenum,Pname:?GLenum,Param:?GLint>>).
%% @spec (Coord::enum(),Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation.
+-spec texGeniv(enum(),enum(),{integer()}) -> ok.
texGeniv(Coord,Pname,Params) ->
- wxe_util:cast(5285, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5285, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
-%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage1D.xml">external</a> documentation.
+-spec texImage1D(enum(),integer(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok.
texImage1D(Target,Level,Internalformat,Width,Border,Format,Type,Pixels) when is_integer(Pixels) ->
- wxe_util:cast(5286, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
+ cast(5286, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
texImage1D(Target,Level,Internalformat,Width,Border,Format,Type,Pixels) ->
- wxe_util:send_bin(Pixels),
- wxe_util:cast(5287, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Pixels),
+ cast(5287, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>).
-%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml">external</a> documentation.
+-spec texImage2D(enum(),integer(),integer(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok.
texImage2D(Target,Level,Internalformat,Width,Height,Border,Format,Type,Pixels) when is_integer(Pixels) ->
- wxe_util:cast(5288, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
+ cast(5288, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
texImage2D(Target,Level,Internalformat,Width,Height,Border,Format,Type,Pixels) ->
- wxe_util:send_bin(Pixels),
- wxe_util:cast(5289, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Pixels),
+ cast(5289, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>).
%% @spec (Target::enum(),Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml">external</a> documentation.
+-spec texParameterf(enum(),enum(),float()) -> ok.
texParameterf(Target,Pname,Param) ->
- wxe_util:cast(5290, <<Target:?GLenum,Pname:?GLenum,Param:?GLfloat>>).
+ cast(5290, <<Target:?GLenum,Pname:?GLenum,Param:?GLfloat>>).
%% @spec (Target::enum(),Pname::enum(),Params::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml">external</a> documentation.
+-spec texParameterfv(enum(),enum(),{float()}) -> ok.
texParameterfv(Target,Pname,Params) ->
- wxe_util:cast(5291, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5291, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Target::enum(),Pname::enum(),Param::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml">external</a> documentation.
+-spec texParameteri(enum(),enum(),integer()) -> ok.
texParameteri(Target,Pname,Param) ->
- wxe_util:cast(5292, <<Target:?GLenum,Pname:?GLenum,Param:?GLint>>).
+ cast(5292, <<Target:?GLenum,Pname:?GLenum,Param:?GLint>>).
%% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml">external</a> documentation.
+-spec texParameteriv(enum(),enum(),{integer()}) -> ok.
texParameteriv(Target,Pname,Params) ->
- wxe_util:cast(5293, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5293, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
-%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Width::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Width::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage1D.xml">external</a> documentation.
+-spec texSubImage1D(enum(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok.
texSubImage1D(Target,Level,Xoffset,Width,Format,Type,Pixels) when is_integer(Pixels) ->
- wxe_util:cast(5294, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
+ cast(5294, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
texSubImage1D(Target,Level,Xoffset,Width,Format,Type,Pixels) ->
- wxe_util:send_bin(Pixels),
- wxe_util:cast(5295, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Pixels),
+ cast(5295, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>).
-%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage2D.xml">external</a> documentation.
+-spec texSubImage2D(enum(),integer(),integer(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok.
texSubImage2D(Target,Level,Xoffset,Yoffset,Width,Height,Format,Type,Pixels) when is_integer(Pixels) ->
- wxe_util:cast(5296, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
+ cast(5296, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
texSubImage2D(Target,Level,Xoffset,Yoffset,Width,Height,Format,Type,Pixels) ->
- wxe_util:send_bin(Pixels),
- wxe_util:cast(5297, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Pixels),
+ cast(5297, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
%% @spec (X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTranslate.xml">external</a> documentation.
+-spec translated(float(),float(),float()) -> ok.
translated(X,Y,Z) ->
- wxe_util:cast(5298, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5298, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @spec (X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTranslate.xml">external</a> documentation.
+-spec translatef(float(),float(),float()) -> ok.
translatef(X,Y,Z) ->
- wxe_util:cast(5299, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5299, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @spec (X::float(),Y::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex2d(float(),float()) -> ok.
vertex2d(X,Y) ->
- wxe_util:cast(5300, <<X:?GLdouble,Y:?GLdouble>>).
+ cast(5300, <<X:?GLdouble,Y:?GLdouble>>).
%% @spec ({X,Y}) -> ok
%% @equiv vertex2d(X,Y)
+-spec vertex2dv({float(),float()}) -> ok.
vertex2dv({X,Y}) -> vertex2d(X,Y).
%% @spec (X::float(),Y::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex2f(float(),float()) -> ok.
vertex2f(X,Y) ->
- wxe_util:cast(5301, <<X:?GLfloat,Y:?GLfloat>>).
+ cast(5301, <<X:?GLfloat,Y:?GLfloat>>).
%% @spec ({X,Y}) -> ok
%% @equiv vertex2f(X,Y)
+-spec vertex2fv({float(),float()}) -> ok.
vertex2fv({X,Y}) -> vertex2f(X,Y).
%% @spec (X::integer(),Y::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex2i(integer(),integer()) -> ok.
vertex2i(X,Y) ->
- wxe_util:cast(5302, <<X:?GLint,Y:?GLint>>).
+ cast(5302, <<X:?GLint,Y:?GLint>>).
%% @spec ({X,Y}) -> ok
%% @equiv vertex2i(X,Y)
+-spec vertex2iv({integer(),integer()}) -> ok.
vertex2iv({X,Y}) -> vertex2i(X,Y).
%% @spec (X::integer(),Y::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex2s(integer(),integer()) -> ok.
vertex2s(X,Y) ->
- wxe_util:cast(5303, <<X:?GLshort,Y:?GLshort>>).
+ cast(5303, <<X:?GLshort,Y:?GLshort>>).
%% @spec ({X,Y}) -> ok
%% @equiv vertex2s(X,Y)
+-spec vertex2sv({integer(),integer()}) -> ok.
vertex2sv({X,Y}) -> vertex2s(X,Y).
%% @spec (X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex3d(float(),float(),float()) -> ok.
vertex3d(X,Y,Z) ->
- wxe_util:cast(5304, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5304, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv vertex3d(X,Y,Z)
+-spec vertex3dv({float(),float(),float()}) -> ok.
vertex3dv({X,Y,Z}) -> vertex3d(X,Y,Z).
%% @spec (X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex3f(float(),float(),float()) -> ok.
vertex3f(X,Y,Z) ->
- wxe_util:cast(5305, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5305, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv vertex3f(X,Y,Z)
+-spec vertex3fv({float(),float(),float()}) -> ok.
vertex3fv({X,Y,Z}) -> vertex3f(X,Y,Z).
%% @spec (X::integer(),Y::integer(),Z::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex3i(integer(),integer(),integer()) -> ok.
vertex3i(X,Y,Z) ->
- wxe_util:cast(5306, <<X:?GLint,Y:?GLint,Z:?GLint>>).
+ cast(5306, <<X:?GLint,Y:?GLint,Z:?GLint>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv vertex3i(X,Y,Z)
+-spec vertex3iv({integer(),integer(),integer()}) -> ok.
vertex3iv({X,Y,Z}) -> vertex3i(X,Y,Z).
%% @spec (X::integer(),Y::integer(),Z::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex3s(integer(),integer(),integer()) -> ok.
vertex3s(X,Y,Z) ->
- wxe_util:cast(5307, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>).
+ cast(5307, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv vertex3s(X,Y,Z)
+-spec vertex3sv({integer(),integer(),integer()}) -> ok.
vertex3sv({X,Y,Z}) -> vertex3s(X,Y,Z).
%% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex4d(float(),float(),float(),float()) -> ok.
vertex4d(X,Y,Z,W) ->
- wxe_util:cast(5308, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5308, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv vertex4d(X,Y,Z,W)
+-spec vertex4dv({float(),float(),float(),float()}) -> ok.
vertex4dv({X,Y,Z,W}) -> vertex4d(X,Y,Z,W).
%% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex4f(float(),float(),float(),float()) -> ok.
vertex4f(X,Y,Z,W) ->
- wxe_util:cast(5309, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5309, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv vertex4f(X,Y,Z,W)
+-spec vertex4fv({float(),float(),float(),float()}) -> ok.
vertex4fv({X,Y,Z,W}) -> vertex4f(X,Y,Z,W).
%% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex4i(integer(),integer(),integer(),integer()) -> ok.
vertex4i(X,Y,Z,W) ->
- wxe_util:cast(5310, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
+ cast(5310, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv vertex4i(X,Y,Z,W)
+-spec vertex4iv({integer(),integer(),integer(),integer()}) -> ok.
vertex4iv({X,Y,Z,W}) -> vertex4i(X,Y,Z,W).
%% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation.
+-spec vertex4s(integer(),integer(),integer(),integer()) -> ok.
vertex4s(X,Y,Z,W) ->
- wxe_util:cast(5311, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
+ cast(5311, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv vertex4s(X,Y,Z,W)
+-spec vertex4sv({integer(),integer(),integer(),integer()}) -> ok.
vertex4sv({X,Y,Z,W}) -> vertex4s(X,Y,Z,W).
-%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexPointer.xml">external</a> documentation.
+-spec vertexPointer(integer(),enum(),integer(),offset()|mem()) -> ok.
vertexPointer(Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5312, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5312, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
vertexPointer(Size,Type,Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5313, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5313, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
%% @spec (X::integer(),Y::integer(),Width::integer(),Height::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewport.xml">external</a> documentation.
+-spec viewport(integer(),integer(),integer(),integer()) -> ok.
viewport(X,Y,Width,Height) ->
- wxe_util:cast(5314, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5314, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>).
%% @spec (Red::clamp(),Green::clamp(),Blue::clamp(),Alpha::clamp()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendColor.xml">external</a> documentation.
+-spec blendColor(clamp(),clamp(),clamp(),clamp()) -> ok.
blendColor(Red,Green,Blue,Alpha) ->
- wxe_util:cast(5315, <<Red:?GLclampf,Green:?GLclampf,Blue:?GLclampf,Alpha:?GLclampf>>).
+ cast(5315, <<Red:?GLclampf,Green:?GLclampf,Blue:?GLclampf,Alpha:?GLclampf>>).
%% @spec (Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquation.xml">external</a> documentation.
+-spec blendEquation(enum()) -> ok.
blendEquation(Mode) ->
- wxe_util:cast(5316, <<Mode:?GLenum>>).
+ cast(5316, <<Mode:?GLenum>>).
-%% @spec (Mode::enum(),Start::integer(),End::integer(),Count::integer(),Type::enum(),Indices::offset()|binary()) -> ok
+%% @spec (Mode::enum(),Start::integer(),End::integer(),Count::integer(),Type::enum(),Indices::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawRangeElements.xml">external</a> documentation.
+-spec drawRangeElements(enum(),integer(),integer(),integer(),enum(),offset()|mem()) -> ok.
drawRangeElements(Mode,Start,End,Count,Type,Indices) when is_integer(Indices) ->
- wxe_util:cast(5317, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Indices:?GLuint>>);
+ cast(5317, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Indices:?GLuint>>);
drawRangeElements(Mode,Start,End,Count,Type,Indices) ->
- wxe_util:send_bin(Indices),
- wxe_util:cast(5318, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum>>).
+ send_bin(Indices),
+ cast(5318, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum>>).
-%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Depth::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Depth::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3D.xml">external</a> documentation.
+-spec texImage3D(enum(),integer(),integer(),integer(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok.
texImage3D(Target,Level,Internalformat,Width,Height,Depth,Border,Format,Type,Pixels) when is_integer(Pixels) ->
- wxe_util:cast(5319, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
+ cast(5319, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
texImage3D(Target,Level,Internalformat,Width,Height,Depth,Border,Format,Type,Pixels) ->
- wxe_util:send_bin(Pixels),
- wxe_util:cast(5320, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Pixels),
+ cast(5320, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>).
-%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Zoffset::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Zoffset::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage3D.xml">external</a> documentation.
+-spec texSubImage3D(enum(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok.
texSubImage3D(Target,Level,Xoffset,Yoffset,Zoffset,Width,Height,Depth,Format,Type,Pixels) when is_integer(Pixels) ->
- wxe_util:cast(5321, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
+ cast(5321, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>);
texSubImage3D(Target,Level,Xoffset,Yoffset,Zoffset,Width,Height,Depth,Format,Type,Pixels) ->
- wxe_util:send_bin(Pixels),
- wxe_util:cast(5322, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Pixels),
+ cast(5322, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum>>).
%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Zoffset::integer(),X::integer(),Y::integer(),Width::integer(),Height::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyTexSubImage3D.xml">external</a> documentation.
+-spec copyTexSubImage3D(enum(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()) -> ok.
copyTexSubImage3D(Target,Level,Xoffset,Yoffset,Zoffset,X,Y,Width,Height) ->
- wxe_util:cast(5323, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5323, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>).
-%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Format::enum(),Type::enum(),Table::offset()|binary()) -> ok
+%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Format::enum(),Type::enum(),Table::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorTable.xml">external</a> documentation.
+-spec colorTable(enum(),enum(),integer(),enum(),enum(),offset()|mem()) -> ok.
colorTable(Target,Internalformat,Width,Format,Type,Table) when is_integer(Table) ->
- wxe_util:cast(5324, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Table:?GLuint>>);
+ cast(5324, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Table:?GLuint>>);
colorTable(Target,Internalformat,Width,Format,Type,Table) ->
- wxe_util:send_bin(Table),
- wxe_util:cast(5325, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Table),
+ cast(5325, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>).
-%% @spec (Target::enum(),Pname::enum(),Params::{float()}) -> ok
+%% @spec (Target::enum(),Pname::enum(),Params::{float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorTableParameter.xml">external</a> documentation.
+-spec colorTableParameterfv(enum(),enum(),{float(),float(),float(),float()}) -> ok.
colorTableParameterfv(Target,Pname,{P1,P2,P3,P4}) ->
- wxe_util:cast(5326, <<Target:?GLenum,Pname:?GLenum,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
+ cast(5326, <<Target:?GLenum,Pname:?GLenum,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
-%% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok
+%% @spec (Target::enum(),Pname::enum(),Params::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorTableParameter.xml">external</a> documentation.
+-spec colorTableParameteriv(enum(),enum(),{integer(),integer(),integer(),integer()}) -> ok.
colorTableParameteriv(Target,Pname,{P1,P2,P3,P4}) ->
- wxe_util:cast(5327, <<Target:?GLenum,Pname:?GLenum,P1:?GLint,P2:?GLint,P3:?GLint,P4:?GLint>>).
+ cast(5327, <<Target:?GLenum,Pname:?GLenum,P1:?GLint,P2:?GLint,P3:?GLint,P4:?GLint>>).
%% @spec (Target::enum(),Internalformat::enum(),X::integer(),Y::integer(),Width::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyColorTable.xml">external</a> documentation.
+-spec copyColorTable(enum(),enum(),integer(),integer(),integer()) -> ok.
copyColorTable(Target,Internalformat,X,Y,Width) ->
- wxe_util:cast(5328, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei>>).
+ cast(5328, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei>>).
-%% @spec (Target::enum(),Format::enum(),Type::enum(),Table::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Format::enum(),Type::enum(),Table::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetColorTable.xml">external</a> documentation.
+-spec getColorTable(enum(),enum(),enum(),mem()) -> ok.
getColorTable(Target,Format,Type,Table) ->
- wxe_util:send_bin(Table#wx_mem.bin),
- wxe_util:call(5329, <<Target:?GLenum,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Table),
+ call(5329, <<Target:?GLenum,Format:?GLenum,Type:?GLenum>>).
-%% @spec (Target::enum(),Pname::enum()) -> {float()}
+%% @spec (Target::enum(),Pname::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetColorTableParameter.xml">external</a> documentation.
+-spec getColorTableParameterfv(enum(),enum()) -> {float(),float(),float(),float()}.
getColorTableParameterfv(Target,Pname) ->
- wxe_util:call(5330, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5330, <<Target:?GLenum,Pname:?GLenum>>).
-%% @spec (Target::enum(),Pname::enum()) -> {integer()}
+%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetColorTableParameter.xml">external</a> documentation.
+-spec getColorTableParameteriv(enum(),enum()) -> {integer(),integer(),integer(),integer()}.
getColorTableParameteriv(Target,Pname) ->
- wxe_util:call(5331, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5331, <<Target:?GLenum,Pname:?GLenum>>).
-%% @spec (Target::enum(),Start::integer(),Count::integer(),Format::enum(),Type::enum(),Data::offset()|binary()) -> ok
+%% @spec (Target::enum(),Start::integer(),Count::integer(),Format::enum(),Type::enum(),Data::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorSubTable.xml">external</a> documentation.
+-spec colorSubTable(enum(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok.
colorSubTable(Target,Start,Count,Format,Type,Data) when is_integer(Data) ->
- wxe_util:cast(5332, <<Target:?GLenum,Start:?GLsizei,Count:?GLsizei,Format:?GLenum,Type:?GLenum,Data:?GLuint>>);
+ cast(5332, <<Target:?GLenum,Start:?GLsizei,Count:?GLsizei,Format:?GLenum,Type:?GLenum,Data:?GLuint>>);
colorSubTable(Target,Start,Count,Format,Type,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:cast(5333, <<Target:?GLenum,Start:?GLsizei,Count:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Data),
+ cast(5333, <<Target:?GLenum,Start:?GLsizei,Count:?GLsizei,Format:?GLenum,Type:?GLenum>>).
%% @spec (Target::enum(),Start::integer(),X::integer(),Y::integer(),Width::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyColorSubTable.xml">external</a> documentation.
+-spec copyColorSubTable(enum(),integer(),integer(),integer(),integer()) -> ok.
copyColorSubTable(Target,Start,X,Y,Width) ->
- wxe_util:cast(5334, <<Target:?GLenum,Start:?GLsizei,X:?GLint,Y:?GLint,Width:?GLsizei>>).
+ cast(5334, <<Target:?GLenum,Start:?GLsizei,X:?GLint,Y:?GLint,Width:?GLsizei>>).
-%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Format::enum(),Type::enum(),Image::offset()|binary()) -> ok
+%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Format::enum(),Type::enum(),Image::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glConvolutionFilter1D.xml">external</a> documentation.
+-spec convolutionFilter1D(enum(),enum(),integer(),enum(),enum(),offset()|mem()) -> ok.
convolutionFilter1D(Target,Internalformat,Width,Format,Type,Image) when is_integer(Image) ->
- wxe_util:cast(5335, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Image:?GLuint>>);
+ cast(5335, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Image:?GLuint>>);
convolutionFilter1D(Target,Internalformat,Width,Format,Type,Image) ->
- wxe_util:send_bin(Image),
- wxe_util:cast(5336, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Image),
+ cast(5336, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>).
-%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Image::offset()|binary()) -> ok
+%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Image::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glConvolutionFilter2D.xml">external</a> documentation.
+-spec convolutionFilter2D(enum(),enum(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok.
convolutionFilter2D(Target,Internalformat,Width,Height,Format,Type,Image) when is_integer(Image) ->
- wxe_util:cast(5337, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Image:?GLuint>>);
+ cast(5337, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Image:?GLuint>>);
convolutionFilter2D(Target,Internalformat,Width,Height,Format,Type,Image) ->
- wxe_util:send_bin(Image),
- wxe_util:cast(5338, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Image),
+ cast(5338, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
%% @spec (Target::enum(),Pname::enum(),Params::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glConvolutionParameter.xml">external</a> documentation.
+-spec convolutionParameterf(enum(),enum(),{float()}) -> ok.
convolutionParameterf(Target,Pname,Params) ->
- wxe_util:cast(5339, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5339, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Target,Pname,{Params}) -> ok
%% @equiv convolutionParameterf(Target,Pname,Params)
+-spec convolutionParameterfv(enum(),enum(),{{float()}}) -> ok.
convolutionParameterfv(Target,Pname,{Params}) -> convolutionParameterf(Target,Pname,Params).
%% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glConvolutionParameter.xml">external</a> documentation.
+-spec convolutionParameteri(enum(),enum(),{integer()}) -> ok.
convolutionParameteri(Target,Pname,Params) ->
- wxe_util:cast(5340, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5340, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Target,Pname,{Params}) -> ok
%% @equiv convolutionParameteri(Target,Pname,Params)
+-spec convolutionParameteriv(enum(),enum(),{{integer()}}) -> ok.
convolutionParameteriv(Target,Pname,{Params}) -> convolutionParameteri(Target,Pname,Params).
%% @spec (Target::enum(),Internalformat::enum(),X::integer(),Y::integer(),Width::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyConvolutionFilter1D.xml">external</a> documentation.
+-spec copyConvolutionFilter1D(enum(),enum(),integer(),integer(),integer()) -> ok.
copyConvolutionFilter1D(Target,Internalformat,X,Y,Width) ->
- wxe_util:cast(5341, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei>>).
+ cast(5341, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei>>).
%% @spec (Target::enum(),Internalformat::enum(),X::integer(),Y::integer(),Width::integer(),Height::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyConvolutionFilter2D.xml">external</a> documentation.
+-spec copyConvolutionFilter2D(enum(),enum(),integer(),integer(),integer(),integer()) -> ok.
copyConvolutionFilter2D(Target,Internalformat,X,Y,Width,Height) ->
- wxe_util:cast(5342, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5342, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>).
-%% @spec (Target::enum(),Format::enum(),Type::enum(),Image::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Format::enum(),Type::enum(),Image::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetConvolutionFilter.xml">external</a> documentation.
+-spec getConvolutionFilter(enum(),enum(),enum(),mem()) -> ok.
getConvolutionFilter(Target,Format,Type,Image) ->
- wxe_util:send_bin(Image#wx_mem.bin),
- wxe_util:call(5343, <<Target:?GLenum,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Image),
+ call(5343, <<Target:?GLenum,Format:?GLenum,Type:?GLenum>>).
-%% @spec (Target::enum(),Pname::enum()) -> {float()}
+%% @spec (Target::enum(),Pname::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetConvolutionParameter.xml">external</a> documentation.
+-spec getConvolutionParameterfv(enum(),enum()) -> {float(),float(),float(),float()}.
getConvolutionParameterfv(Target,Pname) ->
- wxe_util:call(5344, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5344, <<Target:?GLenum,Pname:?GLenum>>).
-%% @spec (Target::enum(),Pname::enum()) -> {integer()}
+%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetConvolutionParameter.xml">external</a> documentation.
+-spec getConvolutionParameteriv(enum(),enum()) -> {integer(),integer(),integer(),integer()}.
getConvolutionParameteriv(Target,Pname) ->
- wxe_util:call(5345, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5345, <<Target:?GLenum,Pname:?GLenum>>).
-%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Row::offset()|binary(),Column::offset()|binary()) -> ok
+%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Row::offset()|mem(),Column::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSeparableFilter2D.xml">external</a> documentation.
+-spec separableFilter2D(enum(),enum(),integer(),integer(),enum(),enum(),offset()|mem(),offset()|mem()) -> ok.
separableFilter2D(Target,Internalformat,Width,Height,Format,Type,Row,Column) when is_integer(Row), is_integer(Column) ->
- wxe_util:cast(5346, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Row:?GLuint,Column:?GLuint>>);
+ cast(5346, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Row:?GLuint,Column:?GLuint>>);
separableFilter2D(Target,Internalformat,Width,Height,Format,Type,Row,Column) ->
- wxe_util:send_bin(Row),
- wxe_util:send_bin(Column),
- wxe_util:cast(5347, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Row),
+ send_bin(Column),
+ cast(5347, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
-%% @spec (Target::enum(),Reset::0|1,Format::enum(),Type::enum(),Values::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Reset::0|1,Format::enum(),Type::enum(),Values::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetHistogram.xml">external</a> documentation.
+-spec getHistogram(enum(),0|1,enum(),enum(),mem()) -> ok.
getHistogram(Target,Reset,Format,Type,Values) ->
- wxe_util:send_bin(Values#wx_mem.bin),
- wxe_util:call(5348, <<Target:?GLenum,Reset:?GLboolean,0:24,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Values),
+ call(5348, <<Target:?GLenum,Reset:?GLboolean,0:24,Format:?GLenum,Type:?GLenum>>).
%% @spec (Target::enum(),Pname::enum()) -> {float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetHistogramParameter.xml">external</a> documentation.
+-spec getHistogramParameterfv(enum(),enum()) -> {float()}.
getHistogramParameterfv(Target,Pname) ->
- wxe_util:call(5349, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5349, <<Target:?GLenum,Pname:?GLenum>>).
%% @spec (Target::enum(),Pname::enum()) -> {integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetHistogramParameter.xml">external</a> documentation.
+-spec getHistogramParameteriv(enum(),enum()) -> {integer()}.
getHistogramParameteriv(Target,Pname) ->
- wxe_util:call(5350, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5350, <<Target:?GLenum,Pname:?GLenum>>).
-%% @spec (Target::enum(),Reset::0|1,Format::enum(),Type::enum(),Values::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Reset::0|1,Format::enum(),Type::enum(),Values::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMinmax.xml">external</a> documentation.
+-spec getMinmax(enum(),0|1,enum(),enum(),mem()) -> ok.
getMinmax(Target,Reset,Format,Type,Values) ->
- wxe_util:send_bin(Values#wx_mem.bin),
- wxe_util:call(5351, <<Target:?GLenum,Reset:?GLboolean,0:24,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Values),
+ call(5351, <<Target:?GLenum,Reset:?GLboolean,0:24,Format:?GLenum,Type:?GLenum>>).
%% @spec (Target::enum(),Pname::enum()) -> {float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMinmaxParameter.xml">external</a> documentation.
+-spec getMinmaxParameterfv(enum(),enum()) -> {float()}.
getMinmaxParameterfv(Target,Pname) ->
- wxe_util:call(5352, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5352, <<Target:?GLenum,Pname:?GLenum>>).
%% @spec (Target::enum(),Pname::enum()) -> {integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMinmaxParameter.xml">external</a> documentation.
+-spec getMinmaxParameteriv(enum(),enum()) -> {integer()}.
getMinmaxParameteriv(Target,Pname) ->
- wxe_util:call(5353, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5353, <<Target:?GLenum,Pname:?GLenum>>).
%% @spec (Target::enum(),Width::integer(),Internalformat::enum(),Sink::0|1) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glHistogram.xml">external</a> documentation.
+-spec histogram(enum(),integer(),enum(),0|1) -> ok.
histogram(Target,Width,Internalformat,Sink) ->
- wxe_util:cast(5354, <<Target:?GLenum,Width:?GLsizei,Internalformat:?GLenum,Sink:?GLboolean>>).
+ cast(5354, <<Target:?GLenum,Width:?GLsizei,Internalformat:?GLenum,Sink:?GLboolean>>).
%% @spec (Target::enum(),Internalformat::enum(),Sink::0|1) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMinmax.xml">external</a> documentation.
+-spec minmax(enum(),enum(),0|1) -> ok.
minmax(Target,Internalformat,Sink) ->
- wxe_util:cast(5355, <<Target:?GLenum,Internalformat:?GLenum,Sink:?GLboolean>>).
+ cast(5355, <<Target:?GLenum,Internalformat:?GLenum,Sink:?GLboolean>>).
%% @spec (Target::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glResetHistogram.xml">external</a> documentation.
+-spec resetHistogram(enum()) -> ok.
resetHistogram(Target) ->
- wxe_util:cast(5356, <<Target:?GLenum>>).
+ cast(5356, <<Target:?GLenum>>).
%% @spec (Target::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glResetMinmax.xml">external</a> documentation.
+-spec resetMinmax(enum()) -> ok.
resetMinmax(Target) ->
- wxe_util:cast(5357, <<Target:?GLenum>>).
+ cast(5357, <<Target:?GLenum>>).
%% @spec (Texture::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glActiveTexture.xml">external</a> documentation.
+-spec activeTexture(enum()) -> ok.
activeTexture(Texture) ->
- wxe_util:cast(5358, <<Texture:?GLenum>>).
+ cast(5358, <<Texture:?GLenum>>).
%% @spec (Value::clamp(),Invert::0|1) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSampleCoverage.xml">external</a> documentation.
+-spec sampleCoverage(clamp(),0|1) -> ok.
sampleCoverage(Value,Invert) ->
- wxe_util:cast(5359, <<Value:?GLclampf,Invert:?GLboolean>>).
+ cast(5359, <<Value:?GLclampf,Invert:?GLboolean>>).
-%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Height::integer(),Depth::integer(),Border::integer(),ImageSize::integer(),Data::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Height::integer(),Depth::integer(),Border::integer(),ImageSize::integer(),Data::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexImage3D.xml">external</a> documentation.
+-spec compressedTexImage3D(enum(),integer(),enum(),integer(),integer(),integer(),integer(),integer(),offset()|mem()) -> ok.
compressedTexImage3D(Target,Level,Internalformat,Width,Height,Depth,Border,ImageSize,Data) when is_integer(Data) ->
- wxe_util:cast(5360, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>);
+ cast(5360, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>);
compressedTexImage3D(Target,Level,Internalformat,Width,Height,Depth,Border,ImageSize,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:cast(5361, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>).
+ send_bin(Data),
+ cast(5361, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>).
-%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Height::integer(),Border::integer(),ImageSize::integer(),Data::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Height::integer(),Border::integer(),ImageSize::integer(),Data::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexImage2D.xml">external</a> documentation.
+-spec compressedTexImage2D(enum(),integer(),enum(),integer(),integer(),integer(),integer(),offset()|mem()) -> ok.
compressedTexImage2D(Target,Level,Internalformat,Width,Height,Border,ImageSize,Data) when is_integer(Data) ->
- wxe_util:cast(5362, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>);
+ cast(5362, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>);
compressedTexImage2D(Target,Level,Internalformat,Width,Height,Border,ImageSize,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:cast(5363, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>).
+ send_bin(Data),
+ cast(5363, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>).
-%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Border::integer(),ImageSize::integer(),Data::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Border::integer(),ImageSize::integer(),Data::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexImage1D.xml">external</a> documentation.
+-spec compressedTexImage1D(enum(),integer(),enum(),integer(),integer(),integer(),offset()|mem()) -> ok.
compressedTexImage1D(Target,Level,Internalformat,Width,Border,ImageSize,Data) when is_integer(Data) ->
- wxe_util:cast(5364, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>);
+ cast(5364, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>);
compressedTexImage1D(Target,Level,Internalformat,Width,Border,ImageSize,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:cast(5365, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>).
+ send_bin(Data),
+ cast(5365, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>).
-%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Zoffset::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),ImageSize::integer(),Data::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Zoffset::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),ImageSize::integer(),Data::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexSubImage3D.xml">external</a> documentation.
+-spec compressedTexSubImage3D(enum(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),enum(),integer(),offset()|mem()) -> ok.
compressedTexSubImage3D(Target,Level,Xoffset,Yoffset,Zoffset,Width,Height,Depth,Format,ImageSize,Data) when is_integer(Data) ->
- wxe_util:cast(5366, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>);
+ cast(5366, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>);
compressedTexSubImage3D(Target,Level,Xoffset,Yoffset,Zoffset,Width,Height,Depth,Format,ImageSize,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:cast(5367, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>).
+ send_bin(Data),
+ cast(5367, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>).
-%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Width::integer(),Height::integer(),Format::enum(),ImageSize::integer(),Data::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Width::integer(),Height::integer(),Format::enum(),ImageSize::integer(),Data::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexSubImage2D.xml">external</a> documentation.
+-spec compressedTexSubImage2D(enum(),integer(),integer(),integer(),integer(),integer(),enum(),integer(),offset()|mem()) -> ok.
compressedTexSubImage2D(Target,Level,Xoffset,Yoffset,Width,Height,Format,ImageSize,Data) when is_integer(Data) ->
- wxe_util:cast(5368, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>);
+ cast(5368, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>);
compressedTexSubImage2D(Target,Level,Xoffset,Yoffset,Width,Height,Format,ImageSize,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:cast(5369, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>).
+ send_bin(Data),
+ cast(5369, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>).
-%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Width::integer(),Format::enum(),ImageSize::integer(),Data::offset()|binary()) -> ok
+%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Width::integer(),Format::enum(),ImageSize::integer(),Data::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexSubImage1D.xml">external</a> documentation.
+-spec compressedTexSubImage1D(enum(),integer(),integer(),integer(),enum(),integer(),offset()|mem()) -> ok.
compressedTexSubImage1D(Target,Level,Xoffset,Width,Format,ImageSize,Data) when is_integer(Data) ->
- wxe_util:cast(5370, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>);
+ cast(5370, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>);
compressedTexSubImage1D(Target,Level,Xoffset,Width,Format,ImageSize,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:cast(5371, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>).
+ send_bin(Data),
+ cast(5371, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>).
-%% @spec (Target::enum(),Level::integer(),Img::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Level::integer(),Img::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetCompressedTexImage.xml">external</a> documentation.
+-spec getCompressedTexImage(enum(),integer(),mem()) -> ok.
getCompressedTexImage(Target,Level,Img) ->
- wxe_util:send_bin(Img#wx_mem.bin),
- wxe_util:call(5372, <<Target:?GLenum,Level:?GLint>>).
+ send_bin(Img),
+ call(5372, <<Target:?GLenum,Level:?GLint>>).
%% @spec (Texture::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClientActiveTexture.xml">external</a> documentation.
+-spec clientActiveTexture(enum()) -> ok.
clientActiveTexture(Texture) ->
- wxe_util:cast(5373, <<Texture:?GLenum>>).
+ cast(5373, <<Texture:?GLenum>>).
%% @spec (Target::enum(),S::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord1d(enum(),float()) -> ok.
multiTexCoord1d(Target,S) ->
- wxe_util:cast(5374, <<Target:?GLenum,0:32,S:?GLdouble>>).
+ cast(5374, <<Target:?GLenum,0:32,S:?GLdouble>>).
%% @spec (Target,{S}) -> ok
%% @equiv multiTexCoord1d(Target,S)
+-spec multiTexCoord1dv(enum(),{float()}) -> ok.
multiTexCoord1dv(Target,{S}) -> multiTexCoord1d(Target,S).
%% @spec (Target::enum(),S::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord1f(enum(),float()) -> ok.
multiTexCoord1f(Target,S) ->
- wxe_util:cast(5375, <<Target:?GLenum,S:?GLfloat>>).
+ cast(5375, <<Target:?GLenum,S:?GLfloat>>).
%% @spec (Target,{S}) -> ok
%% @equiv multiTexCoord1f(Target,S)
+-spec multiTexCoord1fv(enum(),{float()}) -> ok.
multiTexCoord1fv(Target,{S}) -> multiTexCoord1f(Target,S).
%% @spec (Target::enum(),S::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord1i(enum(),integer()) -> ok.
multiTexCoord1i(Target,S) ->
- wxe_util:cast(5376, <<Target:?GLenum,S:?GLint>>).
+ cast(5376, <<Target:?GLenum,S:?GLint>>).
%% @spec (Target,{S}) -> ok
%% @equiv multiTexCoord1i(Target,S)
+-spec multiTexCoord1iv(enum(),{integer()}) -> ok.
multiTexCoord1iv(Target,{S}) -> multiTexCoord1i(Target,S).
%% @spec (Target::enum(),S::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord1s(enum(),integer()) -> ok.
multiTexCoord1s(Target,S) ->
- wxe_util:cast(5377, <<Target:?GLenum,S:?GLshort>>).
+ cast(5377, <<Target:?GLenum,S:?GLshort>>).
%% @spec (Target,{S}) -> ok
%% @equiv multiTexCoord1s(Target,S)
+-spec multiTexCoord1sv(enum(),{integer()}) -> ok.
multiTexCoord1sv(Target,{S}) -> multiTexCoord1s(Target,S).
%% @spec (Target::enum(),S::float(),T::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord2d(enum(),float(),float()) -> ok.
multiTexCoord2d(Target,S,T) ->
- wxe_util:cast(5378, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble>>).
+ cast(5378, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble>>).
%% @spec (Target,{S,T}) -> ok
%% @equiv multiTexCoord2d(Target,S,T)
+-spec multiTexCoord2dv(enum(),{float(),float()}) -> ok.
multiTexCoord2dv(Target,{S,T}) -> multiTexCoord2d(Target,S,T).
%% @spec (Target::enum(),S::float(),T::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord2f(enum(),float(),float()) -> ok.
multiTexCoord2f(Target,S,T) ->
- wxe_util:cast(5379, <<Target:?GLenum,S:?GLfloat,T:?GLfloat>>).
+ cast(5379, <<Target:?GLenum,S:?GLfloat,T:?GLfloat>>).
%% @spec (Target,{S,T}) -> ok
%% @equiv multiTexCoord2f(Target,S,T)
+-spec multiTexCoord2fv(enum(),{float(),float()}) -> ok.
multiTexCoord2fv(Target,{S,T}) -> multiTexCoord2f(Target,S,T).
%% @spec (Target::enum(),S::integer(),T::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord2i(enum(),integer(),integer()) -> ok.
multiTexCoord2i(Target,S,T) ->
- wxe_util:cast(5380, <<Target:?GLenum,S:?GLint,T:?GLint>>).
+ cast(5380, <<Target:?GLenum,S:?GLint,T:?GLint>>).
%% @spec (Target,{S,T}) -> ok
%% @equiv multiTexCoord2i(Target,S,T)
+-spec multiTexCoord2iv(enum(),{integer(),integer()}) -> ok.
multiTexCoord2iv(Target,{S,T}) -> multiTexCoord2i(Target,S,T).
%% @spec (Target::enum(),S::integer(),T::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord2s(enum(),integer(),integer()) -> ok.
multiTexCoord2s(Target,S,T) ->
- wxe_util:cast(5381, <<Target:?GLenum,S:?GLshort,T:?GLshort>>).
+ cast(5381, <<Target:?GLenum,S:?GLshort,T:?GLshort>>).
%% @spec (Target,{S,T}) -> ok
%% @equiv multiTexCoord2s(Target,S,T)
+-spec multiTexCoord2sv(enum(),{integer(),integer()}) -> ok.
multiTexCoord2sv(Target,{S,T}) -> multiTexCoord2s(Target,S,T).
%% @spec (Target::enum(),S::float(),T::float(),R::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord3d(enum(),float(),float(),float()) -> ok.
multiTexCoord3d(Target,S,T,R) ->
- wxe_util:cast(5382, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble,R:?GLdouble>>).
+ cast(5382, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble,R:?GLdouble>>).
%% @spec (Target,{S,T,R}) -> ok
%% @equiv multiTexCoord3d(Target,S,T,R)
+-spec multiTexCoord3dv(enum(),{float(),float(),float()}) -> ok.
multiTexCoord3dv(Target,{S,T,R}) -> multiTexCoord3d(Target,S,T,R).
%% @spec (Target::enum(),S::float(),T::float(),R::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord3f(enum(),float(),float(),float()) -> ok.
multiTexCoord3f(Target,S,T,R) ->
- wxe_util:cast(5383, <<Target:?GLenum,S:?GLfloat,T:?GLfloat,R:?GLfloat>>).
+ cast(5383, <<Target:?GLenum,S:?GLfloat,T:?GLfloat,R:?GLfloat>>).
%% @spec (Target,{S,T,R}) -> ok
%% @equiv multiTexCoord3f(Target,S,T,R)
+-spec multiTexCoord3fv(enum(),{float(),float(),float()}) -> ok.
multiTexCoord3fv(Target,{S,T,R}) -> multiTexCoord3f(Target,S,T,R).
%% @spec (Target::enum(),S::integer(),T::integer(),R::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord3i(enum(),integer(),integer(),integer()) -> ok.
multiTexCoord3i(Target,S,T,R) ->
- wxe_util:cast(5384, <<Target:?GLenum,S:?GLint,T:?GLint,R:?GLint>>).
+ cast(5384, <<Target:?GLenum,S:?GLint,T:?GLint,R:?GLint>>).
%% @spec (Target,{S,T,R}) -> ok
%% @equiv multiTexCoord3i(Target,S,T,R)
+-spec multiTexCoord3iv(enum(),{integer(),integer(),integer()}) -> ok.
multiTexCoord3iv(Target,{S,T,R}) -> multiTexCoord3i(Target,S,T,R).
%% @spec (Target::enum(),S::integer(),T::integer(),R::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord3s(enum(),integer(),integer(),integer()) -> ok.
multiTexCoord3s(Target,S,T,R) ->
- wxe_util:cast(5385, <<Target:?GLenum,S:?GLshort,T:?GLshort,R:?GLshort>>).
+ cast(5385, <<Target:?GLenum,S:?GLshort,T:?GLshort,R:?GLshort>>).
%% @spec (Target,{S,T,R}) -> ok
%% @equiv multiTexCoord3s(Target,S,T,R)
+-spec multiTexCoord3sv(enum(),{integer(),integer(),integer()}) -> ok.
multiTexCoord3sv(Target,{S,T,R}) -> multiTexCoord3s(Target,S,T,R).
%% @spec (Target::enum(),S::float(),T::float(),R::float(),Q::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord4d(enum(),float(),float(),float(),float()) -> ok.
multiTexCoord4d(Target,S,T,R,Q) ->
- wxe_util:cast(5386, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble,R:?GLdouble,Q:?GLdouble>>).
+ cast(5386, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble,R:?GLdouble,Q:?GLdouble>>).
%% @spec (Target,{S,T,R,Q}) -> ok
%% @equiv multiTexCoord4d(Target,S,T,R,Q)
+-spec multiTexCoord4dv(enum(),{float(),float(),float(),float()}) -> ok.
multiTexCoord4dv(Target,{S,T,R,Q}) -> multiTexCoord4d(Target,S,T,R,Q).
%% @spec (Target::enum(),S::float(),T::float(),R::float(),Q::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord4f(enum(),float(),float(),float(),float()) -> ok.
multiTexCoord4f(Target,S,T,R,Q) ->
- wxe_util:cast(5387, <<Target:?GLenum,S:?GLfloat,T:?GLfloat,R:?GLfloat,Q:?GLfloat>>).
+ cast(5387, <<Target:?GLenum,S:?GLfloat,T:?GLfloat,R:?GLfloat,Q:?GLfloat>>).
%% @spec (Target,{S,T,R,Q}) -> ok
%% @equiv multiTexCoord4f(Target,S,T,R,Q)
+-spec multiTexCoord4fv(enum(),{float(),float(),float(),float()}) -> ok.
multiTexCoord4fv(Target,{S,T,R,Q}) -> multiTexCoord4f(Target,S,T,R,Q).
%% @spec (Target::enum(),S::integer(),T::integer(),R::integer(),Q::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord4i(enum(),integer(),integer(),integer(),integer()) -> ok.
multiTexCoord4i(Target,S,T,R,Q) ->
- wxe_util:cast(5388, <<Target:?GLenum,S:?GLint,T:?GLint,R:?GLint,Q:?GLint>>).
+ cast(5388, <<Target:?GLenum,S:?GLint,T:?GLint,R:?GLint,Q:?GLint>>).
%% @spec (Target,{S,T,R,Q}) -> ok
%% @equiv multiTexCoord4i(Target,S,T,R,Q)
+-spec multiTexCoord4iv(enum(),{integer(),integer(),integer(),integer()}) -> ok.
multiTexCoord4iv(Target,{S,T,R,Q}) -> multiTexCoord4i(Target,S,T,R,Q).
%% @spec (Target::enum(),S::integer(),T::integer(),R::integer(),Q::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation.
+-spec multiTexCoord4s(enum(),integer(),integer(),integer(),integer()) -> ok.
multiTexCoord4s(Target,S,T,R,Q) ->
- wxe_util:cast(5389, <<Target:?GLenum,S:?GLshort,T:?GLshort,R:?GLshort,Q:?GLshort>>).
+ cast(5389, <<Target:?GLenum,S:?GLshort,T:?GLshort,R:?GLshort,Q:?GLshort>>).
%% @spec (Target,{S,T,R,Q}) -> ok
%% @equiv multiTexCoord4s(Target,S,T,R,Q)
+-spec multiTexCoord4sv(enum(),{integer(),integer(),integer(),integer()}) -> ok.
multiTexCoord4sv(Target,{S,T,R,Q}) -> multiTexCoord4s(Target,S,T,R,Q).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrix.xml">external</a> documentation.
+-spec loadTransposeMatrixf({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
loadTransposeMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5390, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
+ cast(5390, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
loadTransposeMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5390, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
+ cast(5390, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrix.xml">external</a> documentation.
+-spec loadTransposeMatrixd({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
loadTransposeMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5391, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
+ cast(5391, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
loadTransposeMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5391, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
+ cast(5391, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrix.xml">external</a> documentation.
+-spec multTransposeMatrixf({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
multTransposeMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5392, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
+ cast(5392, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
multTransposeMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5392, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
+ cast(5392, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrix.xml">external</a> documentation.
+-spec multTransposeMatrixd({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
multTransposeMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5393, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
+ cast(5393, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
multTransposeMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5393, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
+ cast(5393, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
%% @spec (SfactorRGB::enum(),DfactorRGB::enum(),SfactorAlpha::enum(),DfactorAlpha::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendFuncSeparate.xml">external</a> documentation.
+-spec blendFuncSeparate(enum(),enum(),enum(),enum()) -> ok.
blendFuncSeparate(SfactorRGB,DfactorRGB,SfactorAlpha,DfactorAlpha) ->
- wxe_util:cast(5394, <<SfactorRGB:?GLenum,DfactorRGB:?GLenum,SfactorAlpha:?GLenum,DfactorAlpha:?GLenum>>).
+ cast(5394, <<SfactorRGB:?GLenum,DfactorRGB:?GLenum,SfactorAlpha:?GLenum,DfactorAlpha:?GLenum>>).
%% @spec (Mode::enum(),First::[integer()],Count::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiDrawArrays.xml">external</a> documentation.
+-spec multiDrawArrays(enum(),[integer()],[integer()]) -> ok.
multiDrawArrays(Mode,First,Count) ->
- wxe_util:cast(5395, <<Mode:?GLenum,(length(First)):?GLuint,
+ cast(5395, <<Mode:?GLenum,(length(First)):?GLuint,
(<< <<C:?GLint>> || C <- First>>)/binary,0:(((length(First)) rem 2)*32),(length(Count)):?GLuint,
(<< <<C:?GLsizei>> || C <- Count>>)/binary,0:(((1+length(Count)) rem 2)*32)>>).
%% @spec (Pname::enum(),Param::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml">external</a> documentation.
+-spec pointParameterf(enum(),float()) -> ok.
pointParameterf(Pname,Param) ->
- wxe_util:cast(5396, <<Pname:?GLenum,Param:?GLfloat>>).
+ cast(5396, <<Pname:?GLenum,Param:?GLfloat>>).
%% @spec (Pname::enum(),Params::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml">external</a> documentation.
+-spec pointParameterfv(enum(),{float()}) -> ok.
pointParameterfv(Pname,Params) ->
- wxe_util:cast(5397, <<Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5397, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @spec (Pname::enum(),Param::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml">external</a> documentation.
+-spec pointParameteri(enum(),integer()) -> ok.
pointParameteri(Pname,Param) ->
- wxe_util:cast(5398, <<Pname:?GLenum,Param:?GLint>>).
+ cast(5398, <<Pname:?GLenum,Param:?GLint>>).
%% @spec (Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml">external</a> documentation.
+-spec pointParameteriv(enum(),{integer()}) -> ok.
pointParameteriv(Pname,Params) ->
- wxe_util:cast(5399, <<Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5399, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @spec (Coord::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFogCoord.xml">external</a> documentation.
+-spec fogCoordf(float()) -> ok.
fogCoordf(Coord) ->
- wxe_util:cast(5400, <<Coord:?GLfloat>>).
+ cast(5400, <<Coord:?GLfloat>>).
%% @spec ({Coord}) -> ok
%% @equiv fogCoordf(Coord)
+-spec fogCoordfv({float()}) -> ok.
fogCoordfv({Coord}) -> fogCoordf(Coord).
%% @spec (Coord::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFogCoord.xml">external</a> documentation.
+-spec fogCoordd(float()) -> ok.
fogCoordd(Coord) ->
- wxe_util:cast(5401, <<Coord:?GLdouble>>).
+ cast(5401, <<Coord:?GLdouble>>).
%% @spec ({Coord}) -> ok
%% @equiv fogCoordd(Coord)
+-spec fogCoorddv({float()}) -> ok.
fogCoorddv({Coord}) -> fogCoordd(Coord).
-%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFogCoordPointer.xml">external</a> documentation.
+-spec fogCoordPointer(enum(),integer(),offset()|mem()) -> ok.
fogCoordPointer(Type,Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5402, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5402, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
fogCoordPointer(Type,Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5403, <<Type:?GLenum,Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5403, <<Type:?GLenum,Stride:?GLsizei>>).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation.
+-spec secondaryColor3b(integer(),integer(),integer()) -> ok.
secondaryColor3b(Red,Green,Blue) ->
- wxe_util:cast(5404, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>).
+ cast(5404, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv secondaryColor3b(Red,Green,Blue)
+-spec secondaryColor3bv({integer(),integer(),integer()}) -> ok.
secondaryColor3bv({Red,Green,Blue}) -> secondaryColor3b(Red,Green,Blue).
%% @spec (Red::float(),Green::float(),Blue::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation.
+-spec secondaryColor3d(float(),float(),float()) -> ok.
secondaryColor3d(Red,Green,Blue) ->
- wxe_util:cast(5405, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>).
+ cast(5405, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv secondaryColor3d(Red,Green,Blue)
+-spec secondaryColor3dv({float(),float(),float()}) -> ok.
secondaryColor3dv({Red,Green,Blue}) -> secondaryColor3d(Red,Green,Blue).
%% @spec (Red::float(),Green::float(),Blue::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation.
+-spec secondaryColor3f(float(),float(),float()) -> ok.
secondaryColor3f(Red,Green,Blue) ->
- wxe_util:cast(5406, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>).
+ cast(5406, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv secondaryColor3f(Red,Green,Blue)
+-spec secondaryColor3fv({float(),float(),float()}) -> ok.
secondaryColor3fv({Red,Green,Blue}) -> secondaryColor3f(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation.
+-spec secondaryColor3i(integer(),integer(),integer()) -> ok.
secondaryColor3i(Red,Green,Blue) ->
- wxe_util:cast(5407, <<Red:?GLint,Green:?GLint,Blue:?GLint>>).
+ cast(5407, <<Red:?GLint,Green:?GLint,Blue:?GLint>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv secondaryColor3i(Red,Green,Blue)
+-spec secondaryColor3iv({integer(),integer(),integer()}) -> ok.
secondaryColor3iv({Red,Green,Blue}) -> secondaryColor3i(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation.
+-spec secondaryColor3s(integer(),integer(),integer()) -> ok.
secondaryColor3s(Red,Green,Blue) ->
- wxe_util:cast(5408, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>).
+ cast(5408, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv secondaryColor3s(Red,Green,Blue)
+-spec secondaryColor3sv({integer(),integer(),integer()}) -> ok.
secondaryColor3sv({Red,Green,Blue}) -> secondaryColor3s(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation.
+-spec secondaryColor3ub(integer(),integer(),integer()) -> ok.
secondaryColor3ub(Red,Green,Blue) ->
- wxe_util:cast(5409, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>).
+ cast(5409, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv secondaryColor3ub(Red,Green,Blue)
+-spec secondaryColor3ubv({integer(),integer(),integer()}) -> ok.
secondaryColor3ubv({Red,Green,Blue}) -> secondaryColor3ub(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation.
+-spec secondaryColor3ui(integer(),integer(),integer()) -> ok.
secondaryColor3ui(Red,Green,Blue) ->
- wxe_util:cast(5410, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>).
+ cast(5410, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv secondaryColor3ui(Red,Green,Blue)
+-spec secondaryColor3uiv({integer(),integer(),integer()}) -> ok.
secondaryColor3uiv({Red,Green,Blue}) -> secondaryColor3ui(Red,Green,Blue).
%% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation.
+-spec secondaryColor3us(integer(),integer(),integer()) -> ok.
secondaryColor3us(Red,Green,Blue) ->
- wxe_util:cast(5411, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>).
+ cast(5411, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>).
%% @spec ({Red,Green,Blue}) -> ok
%% @equiv secondaryColor3us(Red,Green,Blue)
+-spec secondaryColor3usv({integer(),integer(),integer()}) -> ok.
secondaryColor3usv({Red,Green,Blue}) -> secondaryColor3us(Red,Green,Blue).
-%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColorPointer.xml">external</a> documentation.
+-spec secondaryColorPointer(integer(),enum(),integer(),offset()|mem()) -> ok.
secondaryColorPointer(Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5412, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5412, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
secondaryColorPointer(Size,Type,Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5413, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5413, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
%% @spec (X::float(),Y::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation.
+-spec windowPos2d(float(),float()) -> ok.
windowPos2d(X,Y) ->
- wxe_util:cast(5414, <<X:?GLdouble,Y:?GLdouble>>).
+ cast(5414, <<X:?GLdouble,Y:?GLdouble>>).
%% @spec ({X,Y}) -> ok
%% @equiv windowPos2d(X,Y)
+-spec windowPos2dv({float(),float()}) -> ok.
windowPos2dv({X,Y}) -> windowPos2d(X,Y).
%% @spec (X::float(),Y::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation.
+-spec windowPos2f(float(),float()) -> ok.
windowPos2f(X,Y) ->
- wxe_util:cast(5415, <<X:?GLfloat,Y:?GLfloat>>).
+ cast(5415, <<X:?GLfloat,Y:?GLfloat>>).
%% @spec ({X,Y}) -> ok
%% @equiv windowPos2f(X,Y)
+-spec windowPos2fv({float(),float()}) -> ok.
windowPos2fv({X,Y}) -> windowPos2f(X,Y).
%% @spec (X::integer(),Y::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation.
+-spec windowPos2i(integer(),integer()) -> ok.
windowPos2i(X,Y) ->
- wxe_util:cast(5416, <<X:?GLint,Y:?GLint>>).
+ cast(5416, <<X:?GLint,Y:?GLint>>).
%% @spec ({X,Y}) -> ok
%% @equiv windowPos2i(X,Y)
+-spec windowPos2iv({integer(),integer()}) -> ok.
windowPos2iv({X,Y}) -> windowPos2i(X,Y).
%% @spec (X::integer(),Y::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation.
+-spec windowPos2s(integer(),integer()) -> ok.
windowPos2s(X,Y) ->
- wxe_util:cast(5417, <<X:?GLshort,Y:?GLshort>>).
+ cast(5417, <<X:?GLshort,Y:?GLshort>>).
%% @spec ({X,Y}) -> ok
%% @equiv windowPos2s(X,Y)
+-spec windowPos2sv({integer(),integer()}) -> ok.
windowPos2sv({X,Y}) -> windowPos2s(X,Y).
%% @spec (X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation.
+-spec windowPos3d(float(),float(),float()) -> ok.
windowPos3d(X,Y,Z) ->
- wxe_util:cast(5418, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5418, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv windowPos3d(X,Y,Z)
+-spec windowPos3dv({float(),float(),float()}) -> ok.
windowPos3dv({X,Y,Z}) -> windowPos3d(X,Y,Z).
%% @spec (X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation.
+-spec windowPos3f(float(),float(),float()) -> ok.
windowPos3f(X,Y,Z) ->
- wxe_util:cast(5419, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5419, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv windowPos3f(X,Y,Z)
+-spec windowPos3fv({float(),float(),float()}) -> ok.
windowPos3fv({X,Y,Z}) -> windowPos3f(X,Y,Z).
%% @spec (X::integer(),Y::integer(),Z::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation.
+-spec windowPos3i(integer(),integer(),integer()) -> ok.
windowPos3i(X,Y,Z) ->
- wxe_util:cast(5420, <<X:?GLint,Y:?GLint,Z:?GLint>>).
+ cast(5420, <<X:?GLint,Y:?GLint,Z:?GLint>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv windowPos3i(X,Y,Z)
+-spec windowPos3iv({integer(),integer(),integer()}) -> ok.
windowPos3iv({X,Y,Z}) -> windowPos3i(X,Y,Z).
%% @spec (X::integer(),Y::integer(),Z::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation.
+-spec windowPos3s(integer(),integer(),integer()) -> ok.
windowPos3s(X,Y,Z) ->
- wxe_util:cast(5421, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>).
+ cast(5421, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>).
%% @spec ({X,Y,Z}) -> ok
%% @equiv windowPos3s(X,Y,Z)
+-spec windowPos3sv({integer(),integer(),integer()}) -> ok.
windowPos3sv({X,Y,Z}) -> windowPos3s(X,Y,Z).
%% @spec (N::integer()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenQueries.xml">external</a> documentation.
+-spec genQueries(integer()) -> [integer()].
genQueries(N) ->
- wxe_util:call(5422, <<N:?GLsizei>>).
+ call(5422, <<N:?GLsizei>>).
%% @spec (Ids::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteQueries.xml">external</a> documentation.
+-spec deleteQueries([integer()]) -> ok.
deleteQueries(Ids) ->
- wxe_util:cast(5423, <<(length(Ids)):?GLuint,
+ cast(5423, <<(length(Ids)):?GLuint,
(<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+length(Ids)) rem 2)*32)>>).
%% @spec (Id::integer()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsQuery.xml">external</a> documentation.
+-spec isQuery(integer()) -> 0|1.
isQuery(Id) ->
- wxe_util:call(5424, <<Id:?GLuint>>).
+ call(5424, <<Id:?GLuint>>).
%% @spec (Target::enum(),Id::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginQuery.xml">external</a> documentation.
+-spec beginQuery(enum(),integer()) -> ok.
beginQuery(Target,Id) ->
- wxe_util:cast(5425, <<Target:?GLenum,Id:?GLuint>>).
+ cast(5425, <<Target:?GLenum,Id:?GLuint>>).
%% @spec (Target::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEndQuery.xml">external</a> documentation.
+-spec endQuery(enum()) -> ok.
endQuery(Target) ->
- wxe_util:cast(5426, <<Target:?GLenum>>).
+ cast(5426, <<Target:?GLenum>>).
%% @spec (Target::enum(),Pname::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQuery.xml">external</a> documentation.
+-spec getQueryiv(enum(),enum()) -> integer().
getQueryiv(Target,Pname) ->
- wxe_util:call(5427, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5427, <<Target:?GLenum,Pname:?GLenum>>).
%% @spec (Id::integer(),Pname::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObject.xml">external</a> documentation.
+-spec getQueryObjectiv(integer(),enum()) -> integer().
getQueryObjectiv(Id,Pname) ->
- wxe_util:call(5428, <<Id:?GLuint,Pname:?GLenum>>).
+ call(5428, <<Id:?GLuint,Pname:?GLenum>>).
%% @spec (Id::integer(),Pname::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObject.xml">external</a> documentation.
+-spec getQueryObjectuiv(integer(),enum()) -> integer().
getQueryObjectuiv(Id,Pname) ->
- wxe_util:call(5429, <<Id:?GLuint,Pname:?GLenum>>).
+ call(5429, <<Id:?GLuint,Pname:?GLenum>>).
%% @spec (Target::enum(),Buffer::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml">external</a> documentation.
+-spec bindBuffer(enum(),integer()) -> ok.
bindBuffer(Target,Buffer) ->
- wxe_util:cast(5430, <<Target:?GLenum,Buffer:?GLuint>>).
+ cast(5430, <<Target:?GLenum,Buffer:?GLuint>>).
%% @spec (Buffers::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteBuffers.xml">external</a> documentation.
+-spec deleteBuffers([integer()]) -> ok.
deleteBuffers(Buffers) ->
- wxe_util:cast(5431, <<(length(Buffers)):?GLuint,
+ cast(5431, <<(length(Buffers)):?GLuint,
(<< <<C:?GLuint>> || C <- Buffers>>)/binary,0:(((1+length(Buffers)) rem 2)*32)>>).
%% @spec (N::integer()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenBuffers.xml">external</a> documentation.
+-spec genBuffers(integer()) -> [integer()].
genBuffers(N) ->
- wxe_util:call(5432, <<N:?GLsizei>>).
+ call(5432, <<N:?GLsizei>>).
%% @spec (Buffer::integer()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsBuffer.xml">external</a> documentation.
+-spec isBuffer(integer()) -> 0|1.
isBuffer(Buffer) ->
- wxe_util:call(5433, <<Buffer:?GLuint>>).
+ call(5433, <<Buffer:?GLuint>>).
-%% @spec (Target::enum(),Size::integer(),Data::offset()|binary(),Usage::enum()) -> ok
+%% @spec (Target::enum(),Size::integer(),Data::offset()|mem(),Usage::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBufferData.xml">external</a> documentation.
+-spec bufferData(enum(),integer(),offset()|mem(),enum()) -> ok.
bufferData(Target,Size,Data,Usage) when is_integer(Data) ->
- wxe_util:cast(5434, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Data:?GLuint,Usage:?GLenum>>);
+ cast(5434, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Data:?GLuint,Usage:?GLenum>>);
bufferData(Target,Size,Data,Usage) ->
- wxe_util:send_bin(Data),
- wxe_util:cast(5435, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Usage:?GLenum>>).
+ send_bin(Data),
+ cast(5435, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Usage:?GLenum>>).
-%% @spec (Target::enum(),Offset::integer(),Size::integer(),Data::offset()|binary()) -> ok
+%% @spec (Target::enum(),Offset::integer(),Size::integer(),Data::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBufferSubData.xml">external</a> documentation.
+-spec bufferSubData(enum(),integer(),integer(),offset()|mem()) -> ok.
bufferSubData(Target,Offset,Size,Data) when is_integer(Data) ->
- wxe_util:cast(5436, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr,Data:?GLuint>>);
+ cast(5436, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr,Data:?GLuint>>);
bufferSubData(Target,Offset,Size,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:cast(5437, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
+ send_bin(Data),
+ cast(5437, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
-%% @spec (Target::enum(),Offset::integer(),Size::integer(),Data::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Offset::integer(),Size::integer(),Data::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferSubData.xml">external</a> documentation.
+-spec getBufferSubData(enum(),integer(),integer(),mem()) -> ok.
getBufferSubData(Target,Offset,Size,Data) ->
- wxe_util:send_bin(Data#wx_mem.bin),
- wxe_util:call(5438, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
+ send_bin(Data),
+ call(5438, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
%% @spec (Target::enum(),Pname::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameteriv.xml">external</a> documentation.
+-spec getBufferParameteriv(enum(),enum()) -> integer().
getBufferParameteriv(Target,Pname) ->
- wxe_util:call(5439, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5439, <<Target:?GLenum,Pname:?GLenum>>).
%% @spec (ModeRGB::enum(),ModeAlpha::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquationSeparate.xml">external</a> documentation.
+-spec blendEquationSeparate(enum(),enum()) -> ok.
blendEquationSeparate(ModeRGB,ModeAlpha) ->
- wxe_util:cast(5440, <<ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
+ cast(5440, <<ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
%% @spec (Bufs::[enum()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawBuffers.xml">external</a> documentation.
+-spec drawBuffers([enum()]) -> ok.
drawBuffers(Bufs) ->
- wxe_util:cast(5441, <<(length(Bufs)):?GLuint,
+ cast(5441, <<(length(Bufs)):?GLuint,
(<< <<C:?GLenum>> || C <- Bufs>>)/binary,0:(((1+length(Bufs)) rem 2)*32)>>).
%% @spec (Face::enum(),Sfail::enum(),Dpfail::enum(),Dppass::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilOpSeparate.xml">external</a> documentation.
+-spec stencilOpSeparate(enum(),enum(),enum(),enum()) -> ok.
stencilOpSeparate(Face,Sfail,Dpfail,Dppass) ->
- wxe_util:cast(5442, <<Face:?GLenum,Sfail:?GLenum,Dpfail:?GLenum,Dppass:?GLenum>>).
+ cast(5442, <<Face:?GLenum,Sfail:?GLenum,Dpfail:?GLenum,Dppass:?GLenum>>).
-%% @spec (Frontfunc::enum(),Backfunc::enum(),Ref::integer(),Mask::integer()) -> ok
+%% @spec (Face::enum(),Func::enum(),Ref::integer(),Mask::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilFuncSeparate.xml">external</a> documentation.
-stencilFuncSeparate(Frontfunc,Backfunc,Ref,Mask) ->
- wxe_util:cast(5443, <<Frontfunc:?GLenum,Backfunc:?GLenum,Ref:?GLint,Mask:?GLuint>>).
+-spec stencilFuncSeparate(enum(),enum(),integer(),integer()) -> ok.
+stencilFuncSeparate(Face,Func,Ref,Mask) ->
+ cast(5443, <<Face:?GLenum,Func:?GLenum,Ref:?GLint,Mask:?GLuint>>).
%% @spec (Face::enum(),Mask::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilMaskSeparate.xml">external</a> documentation.
+-spec stencilMaskSeparate(enum(),integer()) -> ok.
stencilMaskSeparate(Face,Mask) ->
- wxe_util:cast(5444, <<Face:?GLenum,Mask:?GLuint>>).
+ cast(5444, <<Face:?GLenum,Mask:?GLuint>>).
%% @spec (Program::integer(),Shader::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAttachShader.xml">external</a> documentation.
+-spec attachShader(integer(),integer()) -> ok.
attachShader(Program,Shader) ->
- wxe_util:cast(5445, <<Program:?GLuint,Shader:?GLuint>>).
+ cast(5445, <<Program:?GLuint,Shader:?GLuint>>).
%% @spec (Program::integer(),Index::integer(),Name::string()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocation.xml">external</a> documentation.
+-spec bindAttribLocation(integer(),integer(),string()) -> ok.
bindAttribLocation(Program,Index,Name) ->
- wxe_util:cast(5446, <<Program:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ cast(5446, <<Program:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
%% @spec (Shader::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShader.xml">external</a> documentation.
+-spec compileShader(integer()) -> ok.
compileShader(Shader) ->
- wxe_util:cast(5447, <<Shader:?GLuint>>).
+ cast(5447, <<Shader:?GLuint>>).
%% @spec () -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateProgram.xml">external</a> documentation.
+-spec createProgram() -> integer().
createProgram() ->
- wxe_util:call(5448, <<>>).
+ call(5448, <<>>).
%% @spec (Type::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShader.xml">external</a> documentation.
+-spec createShader(enum()) -> integer().
createShader(Type) ->
- wxe_util:call(5449, <<Type:?GLenum>>).
+ call(5449, <<Type:?GLenum>>).
%% @spec (Program::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgram.xml">external</a> documentation.
+-spec deleteProgram(integer()) -> ok.
deleteProgram(Program) ->
- wxe_util:cast(5450, <<Program:?GLuint>>).
+ cast(5450, <<Program:?GLuint>>).
%% @spec (Shader::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteShader.xml">external</a> documentation.
+-spec deleteShader(integer()) -> ok.
deleteShader(Shader) ->
- wxe_util:cast(5451, <<Shader:?GLuint>>).
+ cast(5451, <<Shader:?GLuint>>).
%% @spec (Program::integer(),Shader::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDetachShader.xml">external</a> documentation.
+-spec detachShader(integer(),integer()) -> ok.
detachShader(Program,Shader) ->
- wxe_util:cast(5452, <<Program:?GLuint,Shader:?GLuint>>).
+ cast(5452, <<Program:?GLuint,Shader:?GLuint>>).
%% @spec (Index::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDisableVertexAttribArray.xml">external</a> documentation.
+-spec disableVertexAttribArray(integer()) -> ok.
disableVertexAttribArray(Index) ->
- wxe_util:cast(5453, <<Index:?GLuint>>).
+ cast(5453, <<Index:?GLuint>>).
%% @spec (Index::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml">external</a> documentation.
+-spec enableVertexAttribArray(integer()) -> ok.
enableVertexAttribArray(Index) ->
- wxe_util:cast(5454, <<Index:?GLuint>>).
+ cast(5454, <<Index:?GLuint>>).
%% @spec (Program::integer(),Index::integer(),BufSize::integer()) -> {Size::integer(),Type::enum(),Name::string()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveAttrib.xml">external</a> documentation.
+-spec getActiveAttrib(integer(),integer(),integer()) -> {integer(),enum(),string()}.
getActiveAttrib(Program,Index,BufSize) ->
- wxe_util:call(5455, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
+ call(5455, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
%% @spec (Program::integer(),Index::integer(),BufSize::integer()) -> {Size::integer(),Type::enum(),Name::string()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniform.xml">external</a> documentation.
+-spec getActiveUniform(integer(),integer(),integer()) -> {integer(),enum(),string()}.
getActiveUniform(Program,Index,BufSize) ->
- wxe_util:call(5456, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
+ call(5456, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
%% @spec (Program::integer(),MaxCount::integer()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttachedShaders.xml">external</a> documentation.
+-spec getAttachedShaders(integer(),integer()) -> [integer()].
getAttachedShaders(Program,MaxCount) ->
- wxe_util:call(5457, <<Program:?GLuint,MaxCount:?GLsizei>>).
+ call(5457, <<Program:?GLuint,MaxCount:?GLsizei>>).
%% @spec (Program::integer(),Name::string()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml">external</a> documentation.
+-spec getAttribLocation(integer(),string()) -> integer().
getAttribLocation(Program,Name) ->
- wxe_util:call(5458, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ call(5458, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
%% @spec (Program::integer(),Pname::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgram.xml">external</a> documentation.
+-spec getProgramiv(integer(),enum()) -> integer().
getProgramiv(Program,Pname) ->
- wxe_util:call(5459, <<Program:?GLuint,Pname:?GLenum>>).
+ call(5459, <<Program:?GLuint,Pname:?GLenum>>).
%% @spec (Program::integer(),BufSize::integer()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramInfoLog.xml">external</a> documentation.
+-spec getProgramInfoLog(integer(),integer()) -> string().
getProgramInfoLog(Program,BufSize) ->
- wxe_util:call(5460, <<Program:?GLuint,BufSize:?GLsizei>>).
+ call(5460, <<Program:?GLuint,BufSize:?GLsizei>>).
%% @spec (Shader::integer(),Pname::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShader.xml">external</a> documentation.
+-spec getShaderiv(integer(),enum()) -> integer().
getShaderiv(Shader,Pname) ->
- wxe_util:call(5461, <<Shader:?GLuint,Pname:?GLenum>>).
+ call(5461, <<Shader:?GLuint,Pname:?GLenum>>).
%% @spec (Shader::integer(),BufSize::integer()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderInfoLog.xml">external</a> documentation.
+-spec getShaderInfoLog(integer(),integer()) -> string().
getShaderInfoLog(Shader,BufSize) ->
- wxe_util:call(5462, <<Shader:?GLuint,BufSize:?GLsizei>>).
+ call(5462, <<Shader:?GLuint,BufSize:?GLsizei>>).
%% @spec (Shader::integer(),BufSize::integer()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderSource.xml">external</a> documentation.
+-spec getShaderSource(integer(),integer()) -> string().
getShaderSource(Shader,BufSize) ->
- wxe_util:call(5463, <<Shader:?GLuint,BufSize:?GLsizei>>).
+ call(5463, <<Shader:?GLuint,BufSize:?GLsizei>>).
%% @spec (Program::integer(),Name::string()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocation.xml">external</a> documentation.
+-spec getUniformLocation(integer(),string()) -> integer().
getUniformLocation(Program,Name) ->
- wxe_util:call(5464, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ call(5464, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
-%% @spec (Program::integer(),Location::integer()) -> {float()}
+%% @spec (Program::integer(),Location::integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml">external</a> documentation.
+-spec getUniformfv(integer(),integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}.
getUniformfv(Program,Location) ->
- wxe_util:call(5465, <<Program:?GLuint,Location:?GLint>>).
+ call(5465, <<Program:?GLuint,Location:?GLint>>).
-%% @spec (Program::integer(),Location::integer()) -> {integer()}
+%% @spec (Program::integer(),Location::integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml">external</a> documentation.
+-spec getUniformiv(integer(),integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}.
getUniformiv(Program,Location) ->
- wxe_util:call(5466, <<Program:?GLuint,Location:?GLint>>).
+ call(5466, <<Program:?GLuint,Location:?GLint>>).
-%% @spec (Index::integer(),Pname::enum()) -> {float()}
+%% @spec (Index::integer(),Pname::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttrib.xml">external</a> documentation.
+-spec getVertexAttribdv(integer(),enum()) -> {float(),float(),float(),float()}.
getVertexAttribdv(Index,Pname) ->
- wxe_util:call(5467, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5467, <<Index:?GLuint,Pname:?GLenum>>).
-%% @spec (Index::integer(),Pname::enum()) -> {float()}
+%% @spec (Index::integer(),Pname::enum()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttrib.xml">external</a> documentation.
+-spec getVertexAttribfv(integer(),enum()) -> {float(),float(),float(),float()}.
getVertexAttribfv(Index,Pname) ->
- wxe_util:call(5468, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5468, <<Index:?GLuint,Pname:?GLenum>>).
-%% @spec (Index::integer(),Pname::enum()) -> {integer()}
+%% @spec (Index::integer(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttrib.xml">external</a> documentation.
+-spec getVertexAttribiv(integer(),enum()) -> {integer(),integer(),integer(),integer()}.
getVertexAttribiv(Index,Pname) ->
- wxe_util:call(5469, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5469, <<Index:?GLuint,Pname:?GLenum>>).
%% @spec (Program::integer()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsProgram.xml">external</a> documentation.
+-spec isProgram(integer()) -> 0|1.
isProgram(Program) ->
- wxe_util:call(5470, <<Program:?GLuint>>).
+ call(5470, <<Program:?GLuint>>).
%% @spec (Shader::integer()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsShader.xml">external</a> documentation.
+-spec isShader(integer()) -> 0|1.
isShader(Shader) ->
- wxe_util:call(5471, <<Shader:?GLuint>>).
+ call(5471, <<Shader:?GLuint>>).
%% @spec (Program::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgram.xml">external</a> documentation.
+-spec linkProgram(integer()) -> ok.
linkProgram(Program) ->
- wxe_util:cast(5472, <<Program:?GLuint>>).
+ cast(5472, <<Program:?GLuint>>).
%% @spec (Shader::integer(),String::[string()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderSource.xml">external</a> documentation.
+-spec shaderSource(integer(),[string()]) -> ok.
shaderSource(Shader,String) ->
StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
- wxe_util:cast(5473, <<Shader:?GLuint,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+0) rem 8)) rem 8)>>).
+ cast(5473, <<Shader:?GLuint,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+0) rem 8)) rem 8)>>).
%% @spec (Program::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgram.xml">external</a> documentation.
+-spec useProgram(integer()) -> ok.
useProgram(Program) ->
- wxe_util:cast(5474, <<Program:?GLuint>>).
+ cast(5474, <<Program:?GLuint>>).
%% @spec (Location::integer(),V0::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform1f(integer(),float()) -> ok.
uniform1f(Location,V0) ->
- wxe_util:cast(5475, <<Location:?GLint,V0:?GLfloat>>).
+ cast(5475, <<Location:?GLint,V0:?GLfloat>>).
%% @spec (Location::integer(),V0::float(),V1::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform2f(integer(),float(),float()) -> ok.
uniform2f(Location,V0,V1) ->
- wxe_util:cast(5476, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
+ cast(5476, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
%% @spec (Location::integer(),V0::float(),V1::float(),V2::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform3f(integer(),float(),float(),float()) -> ok.
uniform3f(Location,V0,V1,V2) ->
- wxe_util:cast(5477, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
+ cast(5477, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
%% @spec (Location::integer(),V0::float(),V1::float(),V2::float(),V3::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform4f(integer(),float(),float(),float(),float()) -> ok.
uniform4f(Location,V0,V1,V2,V3) ->
- wxe_util:cast(5478, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
+ cast(5478, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
%% @spec (Location::integer(),V0::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform1i(integer(),integer()) -> ok.
uniform1i(Location,V0) ->
- wxe_util:cast(5479, <<Location:?GLint,V0:?GLint>>).
+ cast(5479, <<Location:?GLint,V0:?GLint>>).
%% @spec (Location::integer(),V0::integer(),V1::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform2i(integer(),integer(),integer()) -> ok.
uniform2i(Location,V0,V1) ->
- wxe_util:cast(5480, <<Location:?GLint,V0:?GLint,V1:?GLint>>).
+ cast(5480, <<Location:?GLint,V0:?GLint,V1:?GLint>>).
%% @spec (Location::integer(),V0::integer(),V1::integer(),V2::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform3i(integer(),integer(),integer(),integer()) -> ok.
uniform3i(Location,V0,V1,V2) ->
- wxe_util:cast(5481, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
+ cast(5481, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
%% @spec (Location::integer(),V0::integer(),V1::integer(),V2::integer(),V3::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform4i(integer(),integer(),integer(),integer(),integer()) -> ok.
uniform4i(Location,V0,V1,V2,V3) ->
- wxe_util:cast(5482, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
+ cast(5482, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
%% @spec (Location::integer(),Value::[float()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform1fv(integer(),[float()]) -> ok.
uniform1fv(Location,Value) ->
- wxe_util:cast(5483, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5483, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>).
-%% @spec (Location::integer(),Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Value::[{float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform2fv(integer(),[{float(),float()}]) -> ok.
uniform2fv(Location,Value) ->
- wxe_util:cast(5484, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5484, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat>> || {V1,V2} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Value::[{float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform3fv(integer(),[{float(),float(),float()}]) -> ok.
uniform3fv(Location,Value) ->
- wxe_util:cast(5485, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5485, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>> || {V1,V2,V3} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Value::[{float(),float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform4fv(integer(),[{float(),float(),float(),float()}]) -> ok.
uniform4fv(Location,Value) ->
- wxe_util:cast(5486, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5486, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @spec (Location::integer(),Value::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform1iv(integer(),[integer()]) -> ok.
uniform1iv(Location,Value) ->
- wxe_util:cast(5487, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5487, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<C:?GLint>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>).
-%% @spec (Location::integer(),Value::[{integer()}]) -> ok
+%% @spec (Location::integer(),Value::[{integer(),integer()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform2iv(integer(),[{integer(),integer()}]) -> ok.
uniform2iv(Location,Value) ->
- wxe_util:cast(5488, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5488, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<V1:?GLint,V2:?GLint>> || {V1,V2} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Value::[{integer()}]) -> ok
+%% @spec (Location::integer(),Value::[{integer(),integer(),integer()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform3iv(integer(),[{integer(),integer(),integer()}]) -> ok.
uniform3iv(Location,Value) ->
- wxe_util:cast(5489, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5489, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint>> || {V1,V2,V3} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Value::[{integer()}]) -> ok
+%% @spec (Location::integer(),Value::[{integer(),integer(),integer(),integer()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform4iv(integer(),[{integer(),integer(),integer(),integer()}]) -> ok.
uniform4iv(Location,Value) ->
- wxe_util:cast(5490, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5490, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation.
+-spec uniformMatrix2fv(integer(),0|1,[{float(),float(),float(),float()}]) -> ok.
uniformMatrix2fv(Location,Transpose,Value) ->
- wxe_util:cast(5491, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ cast(5491, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation.
+-spec uniformMatrix3fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
uniformMatrix3fv(Location,Transpose,Value) ->
- wxe_util:cast(5492, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ cast(5492, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation.
+-spec uniformMatrix4fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
uniformMatrix4fv(Location,Transpose,Value) ->
- wxe_util:cast(5493, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ cast(5493, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat,V13:?GLfloat,V14:?GLfloat,V15:?GLfloat,V16:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>).
%% @spec (Program::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgram.xml">external</a> documentation.
+-spec validateProgram(integer()) -> ok.
validateProgram(Program) ->
- wxe_util:cast(5494, <<Program:?GLuint>>).
+ cast(5494, <<Program:?GLuint>>).
%% @spec (Index::integer(),X::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib1d(integer(),float()) -> ok.
vertexAttrib1d(Index,X) ->
- wxe_util:cast(5495, <<Index:?GLuint,0:32,X:?GLdouble>>).
+ cast(5495, <<Index:?GLuint,0:32,X:?GLdouble>>).
%% @spec (Index,{X}) -> ok
%% @equiv vertexAttrib1d(Index,X)
+-spec vertexAttrib1dv(integer(),{float()}) -> ok.
vertexAttrib1dv(Index,{X}) -> vertexAttrib1d(Index,X).
%% @spec (Index::integer(),X::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib1f(integer(),float()) -> ok.
vertexAttrib1f(Index,X) ->
- wxe_util:cast(5496, <<Index:?GLuint,X:?GLfloat>>).
+ cast(5496, <<Index:?GLuint,X:?GLfloat>>).
%% @spec (Index,{X}) -> ok
%% @equiv vertexAttrib1f(Index,X)
+-spec vertexAttrib1fv(integer(),{float()}) -> ok.
vertexAttrib1fv(Index,{X}) -> vertexAttrib1f(Index,X).
%% @spec (Index::integer(),X::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib1s(integer(),integer()) -> ok.
vertexAttrib1s(Index,X) ->
- wxe_util:cast(5497, <<Index:?GLuint,X:?GLshort>>).
+ cast(5497, <<Index:?GLuint,X:?GLshort>>).
%% @spec (Index,{X}) -> ok
%% @equiv vertexAttrib1s(Index,X)
+-spec vertexAttrib1sv(integer(),{integer()}) -> ok.
vertexAttrib1sv(Index,{X}) -> vertexAttrib1s(Index,X).
%% @spec (Index::integer(),X::float(),Y::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib2d(integer(),float(),float()) -> ok.
vertexAttrib2d(Index,X,Y) ->
- wxe_util:cast(5498, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
+ cast(5498, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
%% @spec (Index,{X,Y}) -> ok
%% @equiv vertexAttrib2d(Index,X,Y)
+-spec vertexAttrib2dv(integer(),{float(),float()}) -> ok.
vertexAttrib2dv(Index,{X,Y}) -> vertexAttrib2d(Index,X,Y).
%% @spec (Index::integer(),X::float(),Y::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib2f(integer(),float(),float()) -> ok.
vertexAttrib2f(Index,X,Y) ->
- wxe_util:cast(5499, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat>>).
+ cast(5499, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat>>).
%% @spec (Index,{X,Y}) -> ok
%% @equiv vertexAttrib2f(Index,X,Y)
+-spec vertexAttrib2fv(integer(),{float(),float()}) -> ok.
vertexAttrib2fv(Index,{X,Y}) -> vertexAttrib2f(Index,X,Y).
%% @spec (Index::integer(),X::integer(),Y::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib2s(integer(),integer(),integer()) -> ok.
vertexAttrib2s(Index,X,Y) ->
- wxe_util:cast(5500, <<Index:?GLuint,X:?GLshort,Y:?GLshort>>).
+ cast(5500, <<Index:?GLuint,X:?GLshort,Y:?GLshort>>).
%% @spec (Index,{X,Y}) -> ok
%% @equiv vertexAttrib2s(Index,X,Y)
+-spec vertexAttrib2sv(integer(),{integer(),integer()}) -> ok.
vertexAttrib2sv(Index,{X,Y}) -> vertexAttrib2s(Index,X,Y).
%% @spec (Index::integer(),X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib3d(integer(),float(),float(),float()) -> ok.
vertexAttrib3d(Index,X,Y,Z) ->
- wxe_util:cast(5501, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5501, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @spec (Index,{X,Y,Z}) -> ok
%% @equiv vertexAttrib3d(Index,X,Y,Z)
+-spec vertexAttrib3dv(integer(),{float(),float(),float()}) -> ok.
vertexAttrib3dv(Index,{X,Y,Z}) -> vertexAttrib3d(Index,X,Y,Z).
%% @spec (Index::integer(),X::float(),Y::float(),Z::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib3f(integer(),float(),float(),float()) -> ok.
vertexAttrib3f(Index,X,Y,Z) ->
- wxe_util:cast(5502, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5502, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @spec (Index,{X,Y,Z}) -> ok
%% @equiv vertexAttrib3f(Index,X,Y,Z)
+-spec vertexAttrib3fv(integer(),{float(),float(),float()}) -> ok.
vertexAttrib3fv(Index,{X,Y,Z}) -> vertexAttrib3f(Index,X,Y,Z).
%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib3s(integer(),integer(),integer(),integer()) -> ok.
vertexAttrib3s(Index,X,Y,Z) ->
- wxe_util:cast(5503, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort>>).
+ cast(5503, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort>>).
%% @spec (Index,{X,Y,Z}) -> ok
%% @equiv vertexAttrib3s(Index,X,Y,Z)
+-spec vertexAttrib3sv(integer(),{integer(),integer(),integer()}) -> ok.
vertexAttrib3sv(Index,{X,Y,Z}) -> vertexAttrib3s(Index,X,Y,Z).
-%% @spec (Index::integer(),V::{integer()}) -> ok
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4Nbv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4Nbv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5504, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
+ cast(5504, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
-%% @spec (Index::integer(),V::{integer()}) -> ok
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4Niv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4Niv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5505, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ cast(5505, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
-%% @spec (Index::integer(),V::{integer()}) -> ok
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4Nsv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4Nsv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5506, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
+ cast(5506, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4Nub(integer(),integer(),integer(),integer(),integer()) -> ok.
vertexAttrib4Nub(Index,X,Y,Z,W) ->
- wxe_util:cast(5507, <<Index:?GLuint,X:?GLubyte,Y:?GLubyte,Z:?GLubyte,W:?GLubyte>>).
+ cast(5507, <<Index:?GLuint,X:?GLubyte,Y:?GLubyte,Z:?GLubyte,W:?GLubyte>>).
%% @spec (Index,{X,Y,Z,W}) -> ok
%% @equiv vertexAttrib4Nub(Index,X,Y,Z,W)
+-spec vertexAttrib4Nubv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4Nubv(Index,{X,Y,Z,W}) -> vertexAttrib4Nub(Index,X,Y,Z,W).
-%% @spec (Index::integer(),V::{integer()}) -> ok
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4Nuiv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4Nuiv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5508, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
+ cast(5508, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
-%% @spec (Index::integer(),V::{integer()}) -> ok
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4Nusv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4Nusv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5509, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
+ cast(5509, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
-%% @spec (Index::integer(),V::{integer()}) -> ok
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4bv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4bv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5510, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
+ cast(5510, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
%% @spec (Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4d(integer(),float(),float(),float(),float()) -> ok.
vertexAttrib4d(Index,X,Y,Z,W) ->
- wxe_util:cast(5511, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5511, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @spec (Index,{X,Y,Z,W}) -> ok
%% @equiv vertexAttrib4d(Index,X,Y,Z,W)
+-spec vertexAttrib4dv(integer(),{float(),float(),float(),float()}) -> ok.
vertexAttrib4dv(Index,{X,Y,Z,W}) -> vertexAttrib4d(Index,X,Y,Z,W).
%% @spec (Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4f(integer(),float(),float(),float(),float()) -> ok.
vertexAttrib4f(Index,X,Y,Z,W) ->
- wxe_util:cast(5512, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5512, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
%% @spec (Index,{X,Y,Z,W}) -> ok
%% @equiv vertexAttrib4f(Index,X,Y,Z,W)
+-spec vertexAttrib4fv(integer(),{float(),float(),float(),float()}) -> ok.
vertexAttrib4fv(Index,{X,Y,Z,W}) -> vertexAttrib4f(Index,X,Y,Z,W).
-%% @spec (Index::integer(),V::{integer()}) -> ok
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4iv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4iv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5513, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ cast(5513, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4s(integer(),integer(),integer(),integer(),integer()) -> ok.
vertexAttrib4s(Index,X,Y,Z,W) ->
- wxe_util:cast(5514, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
+ cast(5514, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
%% @spec (Index,{X,Y,Z,W}) -> ok
%% @equiv vertexAttrib4s(Index,X,Y,Z,W)
+-spec vertexAttrib4sv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4sv(Index,{X,Y,Z,W}) -> vertexAttrib4s(Index,X,Y,Z,W).
-%% @spec (Index::integer(),V::{integer()}) -> ok
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4ubv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4ubv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5515, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
+ cast(5515, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
-%% @spec (Index::integer(),V::{integer()}) -> ok
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4uiv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4uiv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5516, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
+ cast(5516, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
-%% @spec (Index::integer(),V::{integer()}) -> ok
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
+-spec vertexAttrib4usv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
vertexAttrib4usv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5517, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
+ cast(5517, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
-%% @spec (Index::integer(),Size::integer(),Type::enum(),Normalized::0|1,Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Index::integer(),Size::integer(),Type::enum(),Normalized::0|1,Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml">external</a> documentation.
+-spec vertexAttribPointer(integer(),integer(),enum(),0|1,integer(),offset()|mem()) -> ok.
vertexAttribPointer(Index,Size,Type,Normalized,Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5518, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5518, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei,Pointer:?GLuint>>);
vertexAttribPointer(Index,Size,Type,Normalized,Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5519, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5519, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei>>).
-%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix2x.xml">external</a> documentation.
+-spec uniformMatrix2x3fv(integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok.
uniformMatrix2x3fv(Location,Transpose,Value) ->
- wxe_util:cast(5520, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ cast(5520, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix3x.xml">external</a> documentation.
+-spec uniformMatrix3x2fv(integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok.
uniformMatrix3x2fv(Location,Transpose,Value) ->
- wxe_util:cast(5521, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ cast(5521, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix2x.xml">external</a> documentation.
+-spec uniformMatrix2x4fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
uniformMatrix2x4fv(Location,Transpose,Value) ->
- wxe_util:cast(5522, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ cast(5522, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix4x.xml">external</a> documentation.
+-spec uniformMatrix4x2fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
uniformMatrix4x2fv(Location,Transpose,Value) ->
- wxe_util:cast(5523, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ cast(5523, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix3x.xml">external</a> documentation.
+-spec uniformMatrix3x4fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
uniformMatrix3x4fv(Location,Transpose,Value) ->
- wxe_util:cast(5524, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ cast(5524, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix4x.xml">external</a> documentation.
+-spec uniformMatrix4x3fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
uniformMatrix4x3fv(Location,Transpose,Value) ->
- wxe_util:cast(5525, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ cast(5525, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
%% @spec (Index::integer(),R::0|1,G::0|1,B::0|1,A::0|1) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorMaski.xml">external</a> documentation.
+-spec colorMaski(integer(),0|1,0|1,0|1,0|1) -> ok.
colorMaski(Index,R,G,B,A) ->
- wxe_util:cast(5526, <<Index:?GLuint,R:?GLboolean,G:?GLboolean,B:?GLboolean,A:?GLboolean>>).
+ cast(5526, <<Index:?GLuint,R:?GLboolean,G:?GLboolean,B:?GLboolean,A:?GLboolean>>).
%% @spec (Target::enum(),Index::integer()) -> [0|1]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBooleani_v.xml">external</a> documentation.
+-spec getBooleani_v(enum(),integer()) -> [0|1].
getBooleani_v(Target,Index) ->
- wxe_util:call(5527, <<Target:?GLenum,Index:?GLuint>>).
+ call(5527, <<Target:?GLenum,Index:?GLuint>>).
%% @spec (Target::enum(),Index::integer()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetIntegeri_v.xml">external</a> documentation.
+-spec getIntegeri_v(enum(),integer()) -> [integer()].
getIntegeri_v(Target,Index) ->
- wxe_util:call(5528, <<Target:?GLenum,Index:?GLuint>>).
+ call(5528, <<Target:?GLenum,Index:?GLuint>>).
%% @spec (Target::enum(),Index::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml">external</a> documentation.
+-spec enablei(enum(),integer()) -> ok.
enablei(Target,Index) ->
- wxe_util:cast(5529, <<Target:?GLenum,Index:?GLuint>>).
+ cast(5529, <<Target:?GLenum,Index:?GLuint>>).
%% @spec (Target::enum(),Index::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDisable.xml">external</a> documentation.
+-spec disablei(enum(),integer()) -> ok.
disablei(Target,Index) ->
- wxe_util:cast(5530, <<Target:?GLenum,Index:?GLuint>>).
+ cast(5530, <<Target:?GLenum,Index:?GLuint>>).
%% @spec (Target::enum(),Index::integer()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsEnabledi.xml">external</a> documentation.
+-spec isEnabledi(enum(),integer()) -> 0|1.
isEnabledi(Target,Index) ->
- wxe_util:call(5531, <<Target:?GLenum,Index:?GLuint>>).
+ call(5531, <<Target:?GLenum,Index:?GLuint>>).
%% @spec (PrimitiveMode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginTransformFeedback.xml">external</a> documentation.
+-spec beginTransformFeedback(enum()) -> ok.
beginTransformFeedback(PrimitiveMode) ->
- wxe_util:cast(5532, <<PrimitiveMode:?GLenum>>).
+ cast(5532, <<PrimitiveMode:?GLenum>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEndTransformFeedback.xml">external</a> documentation.
+-spec endTransformFeedback() -> ok.
endTransformFeedback() ->
- wxe_util:cast(5533, <<>>).
+ cast(5533, <<>>).
%% @spec (Target::enum(),Index::integer(),Buffer::integer(),Offset::integer(),Size::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBufferRange.xml">external</a> documentation.
+-spec bindBufferRange(enum(),integer(),integer(),integer(),integer()) -> ok.
bindBufferRange(Target,Index,Buffer,Offset,Size) ->
- wxe_util:cast(5534, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
+ cast(5534, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
%% @spec (Target::enum(),Index::integer(),Buffer::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBufferBase.xml">external</a> documentation.
+-spec bindBufferBase(enum(),integer(),integer()) -> ok.
bindBufferBase(Target,Index,Buffer) ->
- wxe_util:cast(5535, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint>>).
+ cast(5535, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint>>).
%% @spec (Program::integer(),Varyings::[string()],BufferMode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTransformFeedbackVaryings.xml">external</a> documentation.
+-spec transformFeedbackVaryings(integer(),[string()],enum()) -> ok.
transformFeedbackVaryings(Program,Varyings,BufferMode) ->
VaryingsTemp = list_to_binary([[Str|[0]] || Str <- Varyings ]),
- wxe_util:cast(5536, <<Program:?GLuint,(length(Varyings)):?GLuint,(size(VaryingsTemp)):?GLuint,(VaryingsTemp)/binary,0:((8-((size(VaryingsTemp)+0) rem 8)) rem 8),BufferMode:?GLenum>>).
+ cast(5536, <<Program:?GLuint,(length(Varyings)):?GLuint,(size(VaryingsTemp)):?GLuint,(VaryingsTemp)/binary,0:((8-((size(VaryingsTemp)+0) rem 8)) rem 8),BufferMode:?GLenum>>).
%% @spec (Program::integer(),Index::integer(),BufSize::integer()) -> {Size::integer(),Type::enum(),Name::string()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTransformFeedbackVarying.xml">external</a> documentation.
+-spec getTransformFeedbackVarying(integer(),integer(),integer()) -> {integer(),enum(),string()}.
getTransformFeedbackVarying(Program,Index,BufSize) ->
- wxe_util:call(5537, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
+ call(5537, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
%% @spec (Target::enum(),Clamp::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClampColor.xml">external</a> documentation.
+-spec clampColor(enum(),enum()) -> ok.
clampColor(Target,Clamp) ->
- wxe_util:cast(5538, <<Target:?GLenum,Clamp:?GLenum>>).
+ cast(5538, <<Target:?GLenum,Clamp:?GLenum>>).
%% @spec (Id::integer(),Mode::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginConditionalRender.xml">external</a> documentation.
+-spec beginConditionalRender(integer(),enum()) -> ok.
beginConditionalRender(Id,Mode) ->
- wxe_util:cast(5539, <<Id:?GLuint,Mode:?GLenum>>).
+ cast(5539, <<Id:?GLuint,Mode:?GLenum>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEndConditionalRender.xml">external</a> documentation.
+-spec endConditionalRender() -> ok.
endConditionalRender() ->
- wxe_util:cast(5540, <<>>).
+ cast(5540, <<>>).
-%% @spec (Index::integer(),Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok
+%% @spec (Index::integer(),Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribIPointer.xml">external</a> documentation.
+-spec vertexAttribIPointer(integer(),integer(),enum(),integer(),offset()|mem()) -> ok.
vertexAttribIPointer(Index,Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- wxe_util:cast(5541, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5541, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
vertexAttribIPointer(Index,Size,Type,Stride,Pointer) ->
- wxe_util:send_bin(Pointer),
- wxe_util:cast(5542, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+ send_bin(Pointer),
+ cast(5542, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
-%% @spec (Index::integer(),Pname::enum()) -> {integer()}
+%% @spec (Index::integer(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttribI.xml">external</a> documentation.
+-spec getVertexAttribIiv(integer(),enum()) -> {integer(),integer(),integer(),integer()}.
getVertexAttribIiv(Index,Pname) ->
- wxe_util:call(5543, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5543, <<Index:?GLuint,Pname:?GLenum>>).
-%% @spec (Index::integer(),Pname::enum()) -> {integer()}
+%% @spec (Index::integer(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttribI.xml">external</a> documentation.
+-spec getVertexAttribIuiv(integer(),enum()) -> {integer(),integer(),integer(),integer()}.
getVertexAttribIuiv(Index,Pname) ->
- wxe_util:call(5544, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5544, <<Index:?GLuint,Pname:?GLenum>>).
+
+%% @spec (Index::integer(),X::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI1i(integer(),integer()) -> ok.
+vertexAttribI1i(Index,X) ->
+ cast(5545, <<Index:?GLuint,X:?GLint>>).
+
+%% @spec (Index::integer(),X::integer(),Y::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI2i(integer(),integer(),integer()) -> ok.
+vertexAttribI2i(Index,X,Y) ->
+ cast(5546, <<Index:?GLuint,X:?GLint,Y:?GLint>>).
+
+%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI3i(integer(),integer(),integer(),integer()) -> ok.
+vertexAttribI3i(Index,X,Y,Z) ->
+ cast(5547, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint>>).
+
+%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI4i(integer(),integer(),integer(),integer(),integer()) -> ok.
+vertexAttribI4i(Index,X,Y,Z,W) ->
+ cast(5548, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
+
+%% @spec (Index::integer(),X::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI1ui(integer(),integer()) -> ok.
+vertexAttribI1ui(Index,X) ->
+ cast(5549, <<Index:?GLuint,X:?GLuint>>).
+
+%% @spec (Index::integer(),X::integer(),Y::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI2ui(integer(),integer(),integer()) -> ok.
+vertexAttribI2ui(Index,X,Y) ->
+ cast(5550, <<Index:?GLuint,X:?GLuint,Y:?GLuint>>).
+
+%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI3ui(integer(),integer(),integer(),integer()) -> ok.
+vertexAttribI3ui(Index,X,Y,Z) ->
+ cast(5551, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint>>).
+
+%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI4ui(integer(),integer(),integer(),integer(),integer()) -> ok.
+vertexAttribI4ui(Index,X,Y,Z,W) ->
+ cast(5552, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint,W:?GLuint>>).
+
+%% @spec (Index,{X}) -> ok
+%% @equiv vertexAttribI1i(Index,X)
+-spec vertexAttribI1iv(integer(),{integer()}) -> ok.
+vertexAttribI1iv(Index,{X}) -> vertexAttribI1i(Index,X).
+
+%% @spec (Index,{X,Y}) -> ok
+%% @equiv vertexAttribI2i(Index,X,Y)
+-spec vertexAttribI2iv(integer(),{integer(),integer()}) -> ok.
+vertexAttribI2iv(Index,{X,Y}) -> vertexAttribI2i(Index,X,Y).
+
+%% @spec (Index,{X,Y,Z}) -> ok
+%% @equiv vertexAttribI3i(Index,X,Y,Z)
+-spec vertexAttribI3iv(integer(),{integer(),integer(),integer()}) -> ok.
+vertexAttribI3iv(Index,{X,Y,Z}) -> vertexAttribI3i(Index,X,Y,Z).
+
+%% @spec (Index,{X,Y,Z,W}) -> ok
+%% @equiv vertexAttribI4i(Index,X,Y,Z,W)
+-spec vertexAttribI4iv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
+vertexAttribI4iv(Index,{X,Y,Z,W}) -> vertexAttribI4i(Index,X,Y,Z,W).
+
+%% @spec (Index,{X}) -> ok
+%% @equiv vertexAttribI1ui(Index,X)
+-spec vertexAttribI1uiv(integer(),{integer()}) -> ok.
+vertexAttribI1uiv(Index,{X}) -> vertexAttribI1ui(Index,X).
+
+%% @spec (Index,{X,Y}) -> ok
+%% @equiv vertexAttribI2ui(Index,X,Y)
+-spec vertexAttribI2uiv(integer(),{integer(),integer()}) -> ok.
+vertexAttribI2uiv(Index,{X,Y}) -> vertexAttribI2ui(Index,X,Y).
+
+%% @spec (Index,{X,Y,Z}) -> ok
+%% @equiv vertexAttribI3ui(Index,X,Y,Z)
+-spec vertexAttribI3uiv(integer(),{integer(),integer(),integer()}) -> ok.
+vertexAttribI3uiv(Index,{X,Y,Z}) -> vertexAttribI3ui(Index,X,Y,Z).
+
+%% @spec (Index,{X,Y,Z,W}) -> ok
+%% @equiv vertexAttribI4ui(Index,X,Y,Z,W)
+-spec vertexAttribI4uiv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
+vertexAttribI4uiv(Index,{X,Y,Z,W}) -> vertexAttribI4ui(Index,X,Y,Z,W).
+
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI4bv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
+vertexAttribI4bv(Index,{V1,V2,V3,V4}) ->
+ cast(5553, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
+
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI4sv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
+vertexAttribI4sv(Index,{V1,V2,V3,V4}) ->
+ cast(5554, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
+
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI4ubv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
+vertexAttribI4ubv(Index,{V1,V2,V3,V4}) ->
+ cast(5555, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
+
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
+-spec vertexAttribI4usv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
+vertexAttribI4usv(Index,{V1,V2,V3,V4}) ->
+ cast(5556, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
-%% @spec (Program::integer(),Location::integer()) -> {integer()}
+%% @spec (Program::integer(),Location::integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml">external</a> documentation.
+-spec getUniformuiv(integer(),integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}.
getUniformuiv(Program,Location) ->
- wxe_util:call(5545, <<Program:?GLuint,Location:?GLint>>).
+ call(5557, <<Program:?GLuint,Location:?GLint>>).
%% @spec (Program::integer(),Color::integer(),Name::string()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFragDataLocation.xml">external</a> documentation.
+-spec bindFragDataLocation(integer(),integer(),string()) -> ok.
bindFragDataLocation(Program,Color,Name) ->
- wxe_util:cast(5546, <<Program:?GLuint,Color:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ cast(5558, <<Program:?GLuint,Color:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
%% @spec (Program::integer(),Name::string()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFragDataLocation.xml">external</a> documentation.
+-spec getFragDataLocation(integer(),string()) -> integer().
getFragDataLocation(Program,Name) ->
- wxe_util:call(5547, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ call(5559, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
%% @spec (Location::integer(),V0::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform1ui(integer(),integer()) -> ok.
uniform1ui(Location,V0) ->
- wxe_util:cast(5548, <<Location:?GLint,V0:?GLuint>>).
+ cast(5560, <<Location:?GLint,V0:?GLuint>>).
%% @spec (Location::integer(),V0::integer(),V1::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform2ui(integer(),integer(),integer()) -> ok.
uniform2ui(Location,V0,V1) ->
- wxe_util:cast(5549, <<Location:?GLint,V0:?GLuint,V1:?GLuint>>).
+ cast(5561, <<Location:?GLint,V0:?GLuint,V1:?GLuint>>).
%% @spec (Location::integer(),V0::integer(),V1::integer(),V2::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform3ui(integer(),integer(),integer(),integer()) -> ok.
uniform3ui(Location,V0,V1,V2) ->
- wxe_util:cast(5550, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
+ cast(5562, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
%% @spec (Location::integer(),V0::integer(),V1::integer(),V2::integer(),V3::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform4ui(integer(),integer(),integer(),integer(),integer()) -> ok.
uniform4ui(Location,V0,V1,V2,V3) ->
- wxe_util:cast(5551, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
+ cast(5563, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
%% @spec (Location::integer(),Value::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform1uiv(integer(),[integer()]) -> ok.
uniform1uiv(Location,Value) ->
- wxe_util:cast(5552, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5564, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>).
-%% @spec (Location::integer(),Value::[{integer()}]) -> ok
+%% @spec (Location::integer(),Value::[{integer(),integer()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform2uiv(integer(),[{integer(),integer()}]) -> ok.
uniform2uiv(Location,Value) ->
- wxe_util:cast(5553, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5565, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<V1:?GLuint,V2:?GLuint>> || {V1,V2} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Value::[{integer()}]) -> ok
+%% @spec (Location::integer(),Value::[{integer(),integer(),integer()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform3uiv(integer(),[{integer(),integer(),integer()}]) -> ok.
uniform3uiv(Location,Value) ->
- wxe_util:cast(5554, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5566, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint>> || {V1,V2,V3} <- Value>>)/binary>>).
-%% @spec (Location::integer(),Value::[{integer()}]) -> ok
+%% @spec (Location::integer(),Value::[{integer(),integer(),integer(),integer()}]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform4uiv(integer(),[{integer(),integer(),integer(),integer()}]) -> ok.
uniform4uiv(Location,Value) ->
- wxe_util:cast(5555, <<Location:?GLint,(length(Value)):?GLuint,
+ cast(5567, <<Location:?GLint,(length(Value)):?GLuint,
(<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameterI.xml">external</a> documentation.
+-spec texParameterIiv(enum(),enum(),{integer()}) -> ok.
texParameterIiv(Target,Pname,Params) ->
- wxe_util:cast(5556, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5568, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameterI.xml">external</a> documentation.
+-spec texParameterIuiv(enum(),enum(),{integer()}) -> ok.
texParameterIuiv(Target,Pname,Params) ->
- wxe_util:cast(5557, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5569, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLuint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
-%% @spec (Target::enum(),Pname::enum()) -> {integer()}
+%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameterI.xml">external</a> documentation.
+-spec getTexParameterIiv(enum(),enum()) -> {integer(),integer(),integer(),integer()}.
getTexParameterIiv(Target,Pname) ->
- wxe_util:call(5558, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5570, <<Target:?GLenum,Pname:?GLenum>>).
-%% @spec (Target::enum(),Pname::enum()) -> {integer()}
+%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameterI.xml">external</a> documentation.
+-spec getTexParameterIuiv(enum(),enum()) -> {integer(),integer(),integer(),integer()}.
getTexParameterIuiv(Target,Pname) ->
- wxe_util:call(5559, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5571, <<Target:?GLenum,Pname:?GLenum>>).
%% @spec (Buffer::enum(),Drawbuffer::integer(),Value::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBuffer.xml">external</a> documentation.
+-spec clearBufferiv(enum(),integer(),{integer()}) -> ok.
clearBufferiv(Buffer,Drawbuffer,Value) ->
- wxe_util:cast(5560, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
+ cast(5572, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @spec (Buffer::enum(),Drawbuffer::integer(),Value::{integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBuffer.xml">external</a> documentation.
+-spec clearBufferuiv(enum(),integer(),{integer()}) -> ok.
clearBufferuiv(Buffer,Drawbuffer,Value) ->
- wxe_util:cast(5561, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
+ cast(5573, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLuint>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @spec (Buffer::enum(),Drawbuffer::integer(),Value::{float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBuffer.xml">external</a> documentation.
+-spec clearBufferfv(enum(),integer(),{float()}) -> ok.
clearBufferfv(Buffer,Drawbuffer,Value) ->
- wxe_util:cast(5562, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
+ cast(5574, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @spec (Buffer::enum(),Drawbuffer::integer(),Depth::float(),Stencil::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBufferfi.xml">external</a> documentation.
+-spec clearBufferfi(enum(),integer(),float(),integer()) -> ok.
clearBufferfi(Buffer,Drawbuffer,Depth,Stencil) ->
- wxe_util:cast(5563, <<Buffer:?GLenum,Drawbuffer:?GLint,Depth:?GLfloat,Stencil:?GLint>>).
+ cast(5575, <<Buffer:?GLenum,Drawbuffer:?GLint,Depth:?GLfloat,Stencil:?GLint>>).
%% @spec (Name::enum(),Index::integer()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetString.xml">external</a> documentation.
+-spec getStringi(enum(),integer()) -> string().
getStringi(Name,Index) ->
- wxe_util:call(5564, <<Name:?GLenum,Index:?GLuint>>).
-
-%% @spec (Index::integer(),X::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI1i(Index,X) ->
- wxe_util:cast(5565, <<Index:?GLuint,X:?GLint>>).
-
-%% @spec (Index::integer(),X::integer(),Y::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI2i(Index,X,Y) ->
- wxe_util:cast(5566, <<Index:?GLuint,X:?GLint,Y:?GLint>>).
-
-%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI3i(Index,X,Y,Z) ->
- wxe_util:cast(5567, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint>>).
-
-%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI4i(Index,X,Y,Z,W) ->
- wxe_util:cast(5568, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
-
-%% @spec (Index::integer(),X::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI1ui(Index,X) ->
- wxe_util:cast(5569, <<Index:?GLuint,X:?GLuint>>).
-
-%% @spec (Index::integer(),X::integer(),Y::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI2ui(Index,X,Y) ->
- wxe_util:cast(5570, <<Index:?GLuint,X:?GLuint,Y:?GLuint>>).
-
-%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI3ui(Index,X,Y,Z) ->
- wxe_util:cast(5571, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint>>).
-
-%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI4ui(Index,X,Y,Z,W) ->
- wxe_util:cast(5572, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint,W:?GLuint>>).
-
-%% @spec (Index,{X}) -> ok
-%% @equiv vertexAttribI1i(Index,X)
-vertexAttribI1iv(Index,{X}) -> vertexAttribI1i(Index,X).
-
-%% @spec (Index,{X,Y}) -> ok
-%% @equiv vertexAttribI2i(Index,X,Y)
-vertexAttribI2iv(Index,{X,Y}) -> vertexAttribI2i(Index,X,Y).
-
-%% @spec (Index,{X,Y,Z}) -> ok
-%% @equiv vertexAttribI3i(Index,X,Y,Z)
-vertexAttribI3iv(Index,{X,Y,Z}) -> vertexAttribI3i(Index,X,Y,Z).
-
-%% @spec (Index,{X,Y,Z,W}) -> ok
-%% @equiv vertexAttribI4i(Index,X,Y,Z,W)
-vertexAttribI4iv(Index,{X,Y,Z,W}) -> vertexAttribI4i(Index,X,Y,Z,W).
-
-%% @spec (Index,{X}) -> ok
-%% @equiv vertexAttribI1ui(Index,X)
-vertexAttribI1uiv(Index,{X}) -> vertexAttribI1ui(Index,X).
-
-%% @spec (Index,{X,Y}) -> ok
-%% @equiv vertexAttribI2ui(Index,X,Y)
-vertexAttribI2uiv(Index,{X,Y}) -> vertexAttribI2ui(Index,X,Y).
-
-%% @spec (Index,{X,Y,Z}) -> ok
-%% @equiv vertexAttribI3ui(Index,X,Y,Z)
-vertexAttribI3uiv(Index,{X,Y,Z}) -> vertexAttribI3ui(Index,X,Y,Z).
-
-%% @spec (Index,{X,Y,Z,W}) -> ok
-%% @equiv vertexAttribI4ui(Index,X,Y,Z,W)
-vertexAttribI4uiv(Index,{X,Y,Z,W}) -> vertexAttribI4ui(Index,X,Y,Z,W).
-
-%% @spec (Index::integer(),V::{integer()}) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI4bv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5573, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
-
-%% @spec (Index::integer(),V::{integer()}) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI4sv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5574, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
-
-%% @spec (Index::integer(),V::{integer()}) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI4ubv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5575, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
-
-%% @spec (Index::integer(),V::{integer()}) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation.
-vertexAttribI4usv(Index,{V1,V2,V3,V4}) ->
- wxe_util:cast(5576, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
+ call(5576, <<Name:?GLenum,Index:?GLuint>>).
%% @spec (Mode::enum(),First::integer(),Count::integer(),Primcount::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArraysInstance.xml">external</a> documentation.
+-spec drawArraysInstanced(enum(),integer(),integer(),integer()) -> ok.
drawArraysInstanced(Mode,First,Count,Primcount) ->
- wxe_util:cast(5577, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei>>).
+ cast(5577, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei>>).
-%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|binary(),Primcount::integer()) -> ok
+%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|mem(),Primcount::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstance.xml">external</a> documentation.
+-spec drawElementsInstanced(enum(),integer(),enum(),offset()|mem(),integer()) -> ok.
drawElementsInstanced(Mode,Count,Type,Indices,Primcount) when is_integer(Indices) ->
- wxe_util:cast(5578, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei>>);
+ cast(5578, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei>>);
drawElementsInstanced(Mode,Count,Type,Indices,Primcount) ->
- wxe_util:send_bin(Indices),
- wxe_util:cast(5579, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei>>).
+ send_bin(Indices),
+ cast(5579, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei>>).
%% @spec (Target::enum(),Internalformat::enum(),Buffer::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexBuffer.xml">external</a> documentation.
+-spec texBuffer(enum(),enum(),integer()) -> ok.
texBuffer(Target,Internalformat,Buffer) ->
- wxe_util:cast(5580, <<Target:?GLenum,Internalformat:?GLenum,Buffer:?GLuint>>).
+ cast(5580, <<Target:?GLenum,Internalformat:?GLenum,Buffer:?GLuint>>).
%% @spec (Index::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPrimitiveRestartIndex.xml">external</a> documentation.
+-spec primitiveRestartIndex(integer()) -> ok.
primitiveRestartIndex(Index) ->
- wxe_util:cast(5581, <<Index:?GLuint>>).
+ cast(5581, <<Index:?GLuint>>).
+
+%% @spec (Target::enum(),Index::integer()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetInteger64i_v.xml">external</a> documentation.
+-spec getInteger64i_v(enum(),integer()) -> [integer()].
+getInteger64i_v(Target,Index) ->
+ call(5582, <<Target:?GLenum,Index:?GLuint>>).
+
+%% @spec (Target::enum(),Pname::enum()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameteri64v.xml">external</a> documentation.
+-spec getBufferParameteri64v(enum(),enum()) -> [integer()].
+getBufferParameteri64v(Target,Pname) ->
+ call(5583, <<Target:?GLenum,Pname:?GLenum>>).
+
+%% @spec (Target::enum(),Attachment::enum(),Texture::integer(),Level::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTexture.xml">external</a> documentation.
+-spec framebufferTexture(enum(),enum(),integer(),integer()) -> ok.
+framebufferTexture(Target,Attachment,Texture,Level) ->
+ cast(5584, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (Index::integer(),Divisor::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribDivisor.xml">external</a> documentation.
+-spec vertexAttribDivisor(integer(),integer()) -> ok.
+vertexAttribDivisor(Index,Divisor) ->
+ cast(5585, <<Index:?GLuint,Divisor:?GLuint>>).
+
+%% @spec (Value::clamp()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMinSampleShading.xml">external</a> documentation.
+-spec minSampleShading(clamp()) -> ok.
+minSampleShading(Value) ->
+ cast(5586, <<Value:?GLclampf>>).
+
+%% @spec (Buf::integer(),Mode::enum()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquation.xml">external</a> documentation.
+-spec blendEquationi(integer(),enum()) -> ok.
+blendEquationi(Buf,Mode) ->
+ cast(5587, <<Buf:?GLuint,Mode:?GLenum>>).
+
+%% @spec (Buf::integer(),ModeRGB::enum(),ModeAlpha::enum()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquationSeparate.xml">external</a> documentation.
+-spec blendEquationSeparatei(integer(),enum(),enum()) -> ok.
+blendEquationSeparatei(Buf,ModeRGB,ModeAlpha) ->
+ cast(5588, <<Buf:?GLuint,ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
+
+%% @spec (Buf::integer(),Src::enum(),Dst::enum()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunci.xml">external</a> documentation.
+-spec blendFunci(integer(),enum(),enum()) -> ok.
+blendFunci(Buf,Src,Dst) ->
+ cast(5589, <<Buf:?GLuint,Src:?GLenum,Dst:?GLenum>>).
+
+%% @spec (Buf::integer(),SrcRGB::enum(),DstRGB::enum(),SrcAlpha::enum(),DstAlpha::enum()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendFuncSeparate.xml">external</a> documentation.
+-spec blendFuncSeparatei(integer(),enum(),enum(),enum(),enum()) -> ok.
+blendFuncSeparatei(Buf,SrcRGB,DstRGB,SrcAlpha,DstAlpha) ->
+ cast(5590, <<Buf:?GLuint,SrcRGB:?GLenum,DstRGB:?GLenum,SrcAlpha:?GLenum,DstAlpha:?GLenum>>).
+
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrixARB.xml">external</a> documentation.
+-spec loadTransposeMatrixfARB({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
loadTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5582, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
+ cast(5591, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
loadTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5582, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
+ cast(5591, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrixARB.xml">external</a> documentation.
+-spec loadTransposeMatrixdARB({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
loadTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5583, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
+ cast(5592, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
loadTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5583, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
+ cast(5592, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrixARB.xml">external</a> documentation.
+-spec multTransposeMatrixfARB({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
multTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5584, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
+ cast(5593, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>);
multTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5584, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
+ cast(5593, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>).
-%% @spec (M::{float()}) -> ok
+%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrixARB.xml">external</a> documentation.
+-spec multTransposeMatrixdARB({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok.
multTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- wxe_util:cast(5585, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
+ cast(5594, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>);
multTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) ->
- wxe_util:cast(5585, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
+ cast(5594, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>).
%% @spec (Weights::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
+-spec weightbvARB([integer()]) -> ok.
weightbvARB(Weights) ->
- wxe_util:cast(5586, <<(length(Weights)):?GLuint,
+ cast(5595, <<(length(Weights)):?GLuint,
(<< <<C:?GLbyte>> || C <- Weights>>)/binary,0:((8-((length(Weights)+ 4) rem 8)) rem 8)>>).
%% @spec (Weights::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
+-spec weightsvARB([integer()]) -> ok.
weightsvARB(Weights) ->
- wxe_util:cast(5587, <<(length(Weights)):?GLuint,
+ cast(5596, <<(length(Weights)):?GLuint,
(<< <<C:?GLshort>> || C <- Weights>>)/binary,0:((8-((length(Weights)*2+ 4) rem 8)) rem 8)>>).
%% @spec (Weights::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
+-spec weightivARB([integer()]) -> ok.
weightivARB(Weights) ->
- wxe_util:cast(5588, <<(length(Weights)):?GLuint,
+ cast(5597, <<(length(Weights)):?GLuint,
(<< <<C:?GLint>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>).
%% @spec (Weights::[float()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
+-spec weightfvARB([float()]) -> ok.
weightfvARB(Weights) ->
- wxe_util:cast(5589, <<(length(Weights)):?GLuint,
+ cast(5598, <<(length(Weights)):?GLuint,
(<< <<C:?GLfloat>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>).
%% @spec (Weights::[float()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
+-spec weightdvARB([float()]) -> ok.
weightdvARB(Weights) ->
- wxe_util:cast(5590, <<(length(Weights)):?GLuint,0:32,
+ cast(5599, <<(length(Weights)):?GLuint,0:32,
(<< <<C:?GLdouble>> || C <- Weights>>)/binary>>).
%% @spec (Weights::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
+-spec weightubvARB([integer()]) -> ok.
weightubvARB(Weights) ->
- wxe_util:cast(5591, <<(length(Weights)):?GLuint,
+ cast(5600, <<(length(Weights)):?GLuint,
(<< <<C:?GLubyte>> || C <- Weights>>)/binary,0:((8-((length(Weights)+ 4) rem 8)) rem 8)>>).
%% @spec (Weights::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
+-spec weightusvARB([integer()]) -> ok.
weightusvARB(Weights) ->
- wxe_util:cast(5592, <<(length(Weights)):?GLuint,
+ cast(5601, <<(length(Weights)):?GLuint,
(<< <<C:?GLushort>> || C <- Weights>>)/binary,0:((8-((length(Weights)*2+ 4) rem 8)) rem 8)>>).
%% @spec (Weights::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
+-spec weightuivARB([integer()]) -> ok.
weightuivARB(Weights) ->
- wxe_util:cast(5593, <<(length(Weights)):?GLuint,
+ cast(5602, <<(length(Weights)):?GLuint,
(<< <<C:?GLuint>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>).
%% @spec (Count::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexBlenARB.xml">external</a> documentation.
+-spec vertexBlendARB(integer()) -> ok.
vertexBlendARB(Count) ->
- wxe_util:cast(5594, <<Count:?GLint>>).
+ cast(5603, <<Count:?GLint>>).
%% @spec (Index::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCurrentPaletteMatrixARB.xml">external</a> documentation.
+-spec currentPaletteMatrixARB(integer()) -> ok.
currentPaletteMatrixARB(Index) ->
- wxe_util:cast(5595, <<Index:?GLint>>).
+ cast(5604, <<Index:?GLint>>).
%% @spec (Indices::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation.
+-spec matrixIndexubvARB([integer()]) -> ok.
matrixIndexubvARB(Indices) ->
- wxe_util:cast(5596, <<(length(Indices)):?GLuint,
+ cast(5605, <<(length(Indices)):?GLuint,
(<< <<C:?GLubyte>> || C <- Indices>>)/binary,0:((8-((length(Indices)+ 4) rem 8)) rem 8)>>).
%% @spec (Indices::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation.
+-spec matrixIndexusvARB([integer()]) -> ok.
matrixIndexusvARB(Indices) ->
- wxe_util:cast(5597, <<(length(Indices)):?GLuint,
+ cast(5606, <<(length(Indices)):?GLuint,
(<< <<C:?GLushort>> || C <- Indices>>)/binary,0:((8-((length(Indices)*2+ 4) rem 8)) rem 8)>>).
%% @spec (Indices::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation.
+-spec matrixIndexuivARB([integer()]) -> ok.
matrixIndexuivARB(Indices) ->
- wxe_util:cast(5598, <<(length(Indices)):?GLuint,
+ cast(5607, <<(length(Indices)):?GLuint,
(<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((1+length(Indices)) rem 2)*32)>>).
%% @spec (Target::enum(),Format::enum(),String::string()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramStringARB.xml">external</a> documentation.
+-spec programStringARB(enum(),enum(),string()) -> ok.
programStringARB(Target,Format,String) ->
- wxe_util:cast(5599, <<Target:?GLenum,Format:?GLenum,(list_to_binary([String|[0]]))/binary,0:((8-((length(String)+ 1) rem 8)) rem 8)>>).
+ cast(5608, <<Target:?GLenum,Format:?GLenum,(list_to_binary([String|[0]]))/binary,0:((8-((length(String)+ 1) rem 8)) rem 8)>>).
%% @spec (Target::enum(),Program::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindProgramARB.xml">external</a> documentation.
+-spec bindProgramARB(enum(),integer()) -> ok.
bindProgramARB(Target,Program) ->
- wxe_util:cast(5600, <<Target:?GLenum,Program:?GLuint>>).
+ cast(5609, <<Target:?GLenum,Program:?GLuint>>).
%% @spec (Programs::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgramsARB.xml">external</a> documentation.
+-spec deleteProgramsARB([integer()]) -> ok.
deleteProgramsARB(Programs) ->
- wxe_util:cast(5601, <<(length(Programs)):?GLuint,
+ cast(5610, <<(length(Programs)):?GLuint,
(<< <<C:?GLuint>> || C <- Programs>>)/binary,0:(((1+length(Programs)) rem 2)*32)>>).
%% @spec (N::integer()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenProgramsARB.xml">external</a> documentation.
+-spec genProgramsARB(integer()) -> [integer()].
genProgramsARB(N) ->
- wxe_util:call(5602, <<N:?GLsizei>>).
+ call(5611, <<N:?GLsizei>>).
%% @spec (Target::enum(),Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
+-spec programEnvParameter4dARB(enum(),integer(),float(),float(),float(),float()) -> ok.
programEnvParameter4dARB(Target,Index,X,Y,Z,W) ->
- wxe_util:cast(5603, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5612, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
-%% @spec (Target::enum(),Index::integer(),Params::{float()}) -> ok
+%% @spec (Target::enum(),Index::integer(),Params::{float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
+-spec programEnvParameter4dvARB(enum(),integer(),{float(),float(),float(),float()}) -> ok.
programEnvParameter4dvARB(Target,Index,{P1,P2,P3,P4}) ->
- wxe_util:cast(5604, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
+ cast(5613, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
%% @spec (Target::enum(),Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
+-spec programEnvParameter4fARB(enum(),integer(),float(),float(),float(),float()) -> ok.
programEnvParameter4fARB(Target,Index,X,Y,Z,W) ->
- wxe_util:cast(5605, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5614, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
-%% @spec (Target::enum(),Index::integer(),Params::{float()}) -> ok
+%% @spec (Target::enum(),Index::integer(),Params::{float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
+-spec programEnvParameter4fvARB(enum(),integer(),{float(),float(),float(),float()}) -> ok.
programEnvParameter4fvARB(Target,Index,{P1,P2,P3,P4}) ->
- wxe_util:cast(5606, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
+ cast(5615, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
%% @spec (Target::enum(),Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
+-spec programLocalParameter4dARB(enum(),integer(),float(),float(),float(),float()) -> ok.
programLocalParameter4dARB(Target,Index,X,Y,Z,W) ->
- wxe_util:cast(5607, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5616, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
-%% @spec (Target::enum(),Index::integer(),Params::{float()}) -> ok
+%% @spec (Target::enum(),Index::integer(),Params::{float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
+-spec programLocalParameter4dvARB(enum(),integer(),{float(),float(),float(),float()}) -> ok.
programLocalParameter4dvARB(Target,Index,{P1,P2,P3,P4}) ->
- wxe_util:cast(5608, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
+ cast(5617, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
%% @spec (Target::enum(),Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
+-spec programLocalParameter4fARB(enum(),integer(),float(),float(),float(),float()) -> ok.
programLocalParameter4fARB(Target,Index,X,Y,Z,W) ->
- wxe_util:cast(5609, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5618, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
-%% @spec (Target::enum(),Index::integer(),Params::{float()}) -> ok
+%% @spec (Target::enum(),Index::integer(),Params::{float(),float(),float(),float()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
+-spec programLocalParameter4fvARB(enum(),integer(),{float(),float(),float(),float()}) -> ok.
programLocalParameter4fvARB(Target,Index,{P1,P2,P3,P4}) ->
- wxe_util:cast(5610, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
+ cast(5619, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
-%% @spec (Target::enum(),Index::integer()) -> {float()}
+%% @spec (Target::enum(),Index::integer()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramEnvParameterARB.xml">external</a> documentation.
+-spec getProgramEnvParameterdvARB(enum(),integer()) -> {float(),float(),float(),float()}.
getProgramEnvParameterdvARB(Target,Index) ->
- wxe_util:call(5611, <<Target:?GLenum,Index:?GLuint>>).
+ call(5620, <<Target:?GLenum,Index:?GLuint>>).
-%% @spec (Target::enum(),Index::integer()) -> {float()}
+%% @spec (Target::enum(),Index::integer()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramEnvParameterARB.xml">external</a> documentation.
+-spec getProgramEnvParameterfvARB(enum(),integer()) -> {float(),float(),float(),float()}.
getProgramEnvParameterfvARB(Target,Index) ->
- wxe_util:call(5612, <<Target:?GLenum,Index:?GLuint>>).
+ call(5621, <<Target:?GLenum,Index:?GLuint>>).
-%% @spec (Target::enum(),Index::integer()) -> {float()}
+%% @spec (Target::enum(),Index::integer()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramLocalParameterARB.xml">external</a> documentation.
+-spec getProgramLocalParameterdvARB(enum(),integer()) -> {float(),float(),float(),float()}.
getProgramLocalParameterdvARB(Target,Index) ->
- wxe_util:call(5613, <<Target:?GLenum,Index:?GLuint>>).
+ call(5622, <<Target:?GLenum,Index:?GLuint>>).
-%% @spec (Target::enum(),Index::integer()) -> {float()}
+%% @spec (Target::enum(),Index::integer()) -> {float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramLocalParameterARB.xml">external</a> documentation.
+-spec getProgramLocalParameterfvARB(enum(),integer()) -> {float(),float(),float(),float()}.
getProgramLocalParameterfvARB(Target,Index) ->
- wxe_util:call(5614, <<Target:?GLenum,Index:?GLuint>>).
+ call(5623, <<Target:?GLenum,Index:?GLuint>>).
-%% @spec (Target::enum(),Pname::enum(),String::wx:wx_mem()) -> ok
+%% @spec (Target::enum(),Pname::enum(),String::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramStringARB.xml">external</a> documentation.
+-spec getProgramStringARB(enum(),enum(),mem()) -> ok.
getProgramStringARB(Target,Pname,String) ->
- wxe_util:send_bin(String#wx_mem.bin),
- wxe_util:call(5615, <<Target:?GLenum,Pname:?GLenum>>).
+ send_bin(String),
+ call(5624, <<Target:?GLenum,Pname:?GLenum>>).
+
+%% @spec (Target::enum(),Pname::enum()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameterARB.xml">external</a> documentation.
+-spec getBufferParameterivARB(enum(),enum()) -> [integer()].
+getBufferParameterivARB(Target,Pname) ->
+ call(5625, <<Target:?GLenum,Pname:?GLenum>>).
%% @spec (Obj::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteObjectARB.xml">external</a> documentation.
+-spec deleteObjectARB(integer()) -> ok.
deleteObjectARB(Obj) ->
- wxe_util:cast(5616, <<Obj:?GLhandleARB>>).
+ cast(5626, <<Obj:?GLhandleARB>>).
%% @spec (Pname::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetHandleARB.xml">external</a> documentation.
+-spec getHandleARB(enum()) -> integer().
getHandleARB(Pname) ->
- wxe_util:call(5617, <<Pname:?GLenum>>).
+ call(5627, <<Pname:?GLenum>>).
%% @spec (ContainerObj::integer(),AttachedObj::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDetachObjectARB.xml">external</a> documentation.
+-spec detachObjectARB(integer(),integer()) -> ok.
detachObjectARB(ContainerObj,AttachedObj) ->
- wxe_util:cast(5618, <<ContainerObj:?GLhandleARB,AttachedObj:?GLhandleARB>>).
+ cast(5628, <<ContainerObj:?GLhandleARB,AttachedObj:?GLhandleARB>>).
%% @spec (ShaderType::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShaderObjectARB.xml">external</a> documentation.
+-spec createShaderObjectARB(enum()) -> integer().
createShaderObjectARB(ShaderType) ->
- wxe_util:call(5619, <<ShaderType:?GLenum>>).
+ call(5629, <<ShaderType:?GLenum>>).
%% @spec (ShaderObj::integer(),String::[string()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderSourceARB.xml">external</a> documentation.
+-spec shaderSourceARB(integer(),[string()]) -> ok.
shaderSourceARB(ShaderObj,String) ->
StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
- wxe_util:cast(5620, <<ShaderObj:?GLhandleARB,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+4) rem 8)) rem 8)>>).
+ cast(5630, <<ShaderObj:?GLhandleARB,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+4) rem 8)) rem 8)>>).
%% @spec (ShaderObj::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShaderARB.xml">external</a> documentation.
+-spec compileShaderARB(integer()) -> ok.
compileShaderARB(ShaderObj) ->
- wxe_util:cast(5621, <<ShaderObj:?GLhandleARB>>).
+ cast(5631, <<ShaderObj:?GLhandleARB>>).
%% @spec () -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateProgramObjectARB.xml">external</a> documentation.
+-spec createProgramObjectARB() -> integer().
createProgramObjectARB() ->
- wxe_util:call(5622, <<>>).
+ call(5632, <<>>).
%% @spec (ContainerObj::integer(),Obj::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAttachObjectARB.xml">external</a> documentation.
+-spec attachObjectARB(integer(),integer()) -> ok.
attachObjectARB(ContainerObj,Obj) ->
- wxe_util:cast(5623, <<ContainerObj:?GLhandleARB,Obj:?GLhandleARB>>).
+ cast(5633, <<ContainerObj:?GLhandleARB,Obj:?GLhandleARB>>).
%% @spec (ProgramObj::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgramARB.xml">external</a> documentation.
+-spec linkProgramARB(integer()) -> ok.
linkProgramARB(ProgramObj) ->
- wxe_util:cast(5624, <<ProgramObj:?GLhandleARB>>).
+ cast(5634, <<ProgramObj:?GLhandleARB>>).
%% @spec (ProgramObj::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgramObjectARB.xml">external</a> documentation.
+-spec useProgramObjectARB(integer()) -> ok.
useProgramObjectARB(ProgramObj) ->
- wxe_util:cast(5625, <<ProgramObj:?GLhandleARB>>).
+ cast(5635, <<ProgramObj:?GLhandleARB>>).
%% @spec (ProgramObj::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgramARB.xml">external</a> documentation.
+-spec validateProgramARB(integer()) -> ok.
validateProgramARB(ProgramObj) ->
- wxe_util:cast(5626, <<ProgramObj:?GLhandleARB>>).
+ cast(5636, <<ProgramObj:?GLhandleARB>>).
%% @spec (Obj::integer(),Pname::enum()) -> float()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetObjectParameterARB.xml">external</a> documentation.
+-spec getObjectParameterfvARB(integer(),enum()) -> float().
getObjectParameterfvARB(Obj,Pname) ->
- wxe_util:call(5627, <<Obj:?GLhandleARB,Pname:?GLenum>>).
+ call(5637, <<Obj:?GLhandleARB,Pname:?GLenum>>).
%% @spec (Obj::integer(),Pname::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetObjectParameterARB.xml">external</a> documentation.
+-spec getObjectParameterivARB(integer(),enum()) -> integer().
getObjectParameterivARB(Obj,Pname) ->
- wxe_util:call(5628, <<Obj:?GLhandleARB,Pname:?GLenum>>).
+ call(5638, <<Obj:?GLhandleARB,Pname:?GLenum>>).
%% @spec (Obj::integer(),MaxLength::integer()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetInfoLogARB.xml">external</a> documentation.
+-spec getInfoLogARB(integer(),integer()) -> string().
getInfoLogARB(Obj,MaxLength) ->
- wxe_util:call(5629, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
+ call(5639, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
%% @spec (ContainerObj::integer(),MaxCount::integer()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttachedObjectsARB.xml">external</a> documentation.
+-spec getAttachedObjectsARB(integer(),integer()) -> [integer()].
getAttachedObjectsARB(ContainerObj,MaxCount) ->
- wxe_util:call(5630, <<ContainerObj:?GLhandleARB,MaxCount:?GLsizei>>).
+ call(5640, <<ContainerObj:?GLhandleARB,MaxCount:?GLsizei>>).
%% @spec (ProgramObj::integer(),Name::string()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocationARB.xml">external</a> documentation.
+-spec getUniformLocationARB(integer(),string()) -> integer().
getUniformLocationARB(ProgramObj,Name) ->
- wxe_util:call(5631, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ call(5641, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
%% @spec (ProgramObj::integer(),Index::integer(),MaxLength::integer()) -> {Size::integer(),Type::enum(),Name::string()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformARB.xml">external</a> documentation.
+-spec getActiveUniformARB(integer(),integer(),integer()) -> {integer(),enum(),string()}.
getActiveUniformARB(ProgramObj,Index,MaxLength) ->
- wxe_util:call(5632, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
+ call(5642, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
-%% @spec (ProgramObj::integer(),Location::integer()) -> {float()}
+%% @spec (ProgramObj::integer(),Location::integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformARB.xml">external</a> documentation.
+-spec getUniformfvARB(integer(),integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}.
getUniformfvARB(ProgramObj,Location) ->
- wxe_util:call(5633, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
+ call(5643, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
-%% @spec (ProgramObj::integer(),Location::integer()) -> {integer()}
+%% @spec (ProgramObj::integer(),Location::integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformARB.xml">external</a> documentation.
+-spec getUniformivARB(integer(),integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}.
getUniformivARB(ProgramObj,Location) ->
- wxe_util:call(5634, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
+ call(5644, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
%% @spec (Obj::integer(),MaxLength::integer()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderSourceARB.xml">external</a> documentation.
+-spec getShaderSourceARB(integer(),integer()) -> string().
getShaderSourceARB(Obj,MaxLength) ->
- wxe_util:call(5635, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
+ call(5645, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
%% @spec (ProgramObj::integer(),Index::integer(),Name::string()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocationARB.xml">external</a> documentation.
+-spec bindAttribLocationARB(integer(),integer(),string()) -> ok.
bindAttribLocationARB(ProgramObj,Index,Name) ->
- wxe_util:cast(5636, <<ProgramObj:?GLhandleARB,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ cast(5646, <<ProgramObj:?GLhandleARB,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
%% @spec (ProgramObj::integer(),Index::integer(),MaxLength::integer()) -> {Size::integer(),Type::enum(),Name::string()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveAttribARB.xml">external</a> documentation.
+-spec getActiveAttribARB(integer(),integer(),integer()) -> {integer(),enum(),string()}.
getActiveAttribARB(ProgramObj,Index,MaxLength) ->
- wxe_util:call(5637, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
+ call(5647, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
%% @spec (ProgramObj::integer(),Name::string()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocationARB.xml">external</a> documentation.
+-spec getAttribLocationARB(integer(),string()) -> integer().
getAttribLocationARB(ProgramObj,Name) ->
- wxe_util:call(5638, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ call(5648, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
%% @spec (Renderbuffer::integer()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsRenderbuffer.xml">external</a> documentation.
+-spec isRenderbuffer(integer()) -> 0|1.
isRenderbuffer(Renderbuffer) ->
- wxe_util:call(5639, <<Renderbuffer:?GLuint>>).
+ call(5649, <<Renderbuffer:?GLuint>>).
%% @spec (Target::enum(),Renderbuffer::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindRenderbuffer.xml">external</a> documentation.
+-spec bindRenderbuffer(enum(),integer()) -> ok.
bindRenderbuffer(Target,Renderbuffer) ->
- wxe_util:cast(5640, <<Target:?GLenum,Renderbuffer:?GLuint>>).
+ cast(5650, <<Target:?GLenum,Renderbuffer:?GLuint>>).
%% @spec (Renderbuffers::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteRenderbuffers.xml">external</a> documentation.
+-spec deleteRenderbuffers([integer()]) -> ok.
deleteRenderbuffers(Renderbuffers) ->
- wxe_util:cast(5641, <<(length(Renderbuffers)):?GLuint,
+ cast(5651, <<(length(Renderbuffers)):?GLuint,
(<< <<C:?GLuint>> || C <- Renderbuffers>>)/binary,0:(((1+length(Renderbuffers)) rem 2)*32)>>).
%% @spec (N::integer()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenRenderbuffers.xml">external</a> documentation.
+-spec genRenderbuffers(integer()) -> [integer()].
genRenderbuffers(N) ->
- wxe_util:call(5642, <<N:?GLsizei>>).
+ call(5652, <<N:?GLsizei>>).
%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Height::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRenderbufferStorage.xml">external</a> documentation.
+-spec renderbufferStorage(enum(),enum(),integer(),integer()) -> ok.
renderbufferStorage(Target,Internalformat,Width,Height) ->
- wxe_util:cast(5643, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5653, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
%% @spec (Target::enum(),Pname::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetRenderbufferParameter.xml">external</a> documentation.
+-spec getRenderbufferParameteriv(enum(),enum()) -> integer().
getRenderbufferParameteriv(Target,Pname) ->
- wxe_util:call(5644, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5654, <<Target:?GLenum,Pname:?GLenum>>).
%% @spec (Framebuffer::integer()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsFramebuffer.xml">external</a> documentation.
+-spec isFramebuffer(integer()) -> 0|1.
isFramebuffer(Framebuffer) ->
- wxe_util:call(5645, <<Framebuffer:?GLuint>>).
+ call(5655, <<Framebuffer:?GLuint>>).
%% @spec (Target::enum(),Framebuffer::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFramebuffer.xml">external</a> documentation.
+-spec bindFramebuffer(enum(),integer()) -> ok.
bindFramebuffer(Target,Framebuffer) ->
- wxe_util:cast(5646, <<Target:?GLenum,Framebuffer:?GLuint>>).
+ cast(5656, <<Target:?GLenum,Framebuffer:?GLuint>>).
%% @spec (Framebuffers::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteFramebuffers.xml">external</a> documentation.
+-spec deleteFramebuffers([integer()]) -> ok.
deleteFramebuffers(Framebuffers) ->
- wxe_util:cast(5647, <<(length(Framebuffers)):?GLuint,
+ cast(5657, <<(length(Framebuffers)):?GLuint,
(<< <<C:?GLuint>> || C <- Framebuffers>>)/binary,0:(((1+length(Framebuffers)) rem 2)*32)>>).
%% @spec (N::integer()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenFramebuffers.xml">external</a> documentation.
+-spec genFramebuffers(integer()) -> [integer()].
genFramebuffers(N) ->
- wxe_util:call(5648, <<N:?GLsizei>>).
+ call(5658, <<N:?GLsizei>>).
%% @spec (Target::enum()) -> enum()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCheckFramebufferStatus.xml">external</a> documentation.
+-spec checkFramebufferStatus(enum()) -> enum().
checkFramebufferStatus(Target) ->
- wxe_util:call(5649, <<Target:?GLenum>>).
+ call(5659, <<Target:?GLenum>>).
%% @spec (Target::enum(),Attachment::enum(),Textarget::enum(),Texture::integer(),Level::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTexture1D.xml">external</a> documentation.
+-spec framebufferTexture1D(enum(),enum(),enum(),integer(),integer()) -> ok.
framebufferTexture1D(Target,Attachment,Textarget,Texture,Level) ->
- wxe_util:cast(5650, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
+ cast(5660, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
%% @spec (Target::enum(),Attachment::enum(),Textarget::enum(),Texture::integer(),Level::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTexture2D.xml">external</a> documentation.
+-spec framebufferTexture2D(enum(),enum(),enum(),integer(),integer()) -> ok.
framebufferTexture2D(Target,Attachment,Textarget,Texture,Level) ->
- wxe_util:cast(5651, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
+ cast(5661, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
%% @spec (Target::enum(),Attachment::enum(),Textarget::enum(),Texture::integer(),Level::integer(),Zoffset::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTexture3D.xml">external</a> documentation.
+-spec framebufferTexture3D(enum(),enum(),enum(),integer(),integer(),integer()) -> ok.
framebufferTexture3D(Target,Attachment,Textarget,Texture,Level,Zoffset) ->
- wxe_util:cast(5652, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint,Zoffset:?GLint>>).
+ cast(5662, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint,Zoffset:?GLint>>).
%% @spec (Target::enum(),Attachment::enum(),Renderbuffertarget::enum(),Renderbuffer::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferRenderbuffer.xml">external</a> documentation.
+-spec framebufferRenderbuffer(enum(),enum(),enum(),integer()) -> ok.
framebufferRenderbuffer(Target,Attachment,Renderbuffertarget,Renderbuffer) ->
- wxe_util:cast(5653, <<Target:?GLenum,Attachment:?GLenum,Renderbuffertarget:?GLenum,Renderbuffer:?GLuint>>).
+ cast(5663, <<Target:?GLenum,Attachment:?GLenum,Renderbuffertarget:?GLenum,Renderbuffer:?GLuint>>).
%% @spec (Target::enum(),Attachment::enum(),Pname::enum()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFramebufferAttachmentParameter.xml">external</a> documentation.
+-spec getFramebufferAttachmentParameteriv(enum(),enum(),enum()) -> integer().
getFramebufferAttachmentParameteriv(Target,Attachment,Pname) ->
- wxe_util:call(5654, <<Target:?GLenum,Attachment:?GLenum,Pname:?GLenum>>).
+ call(5664, <<Target:?GLenum,Attachment:?GLenum,Pname:?GLenum>>).
%% @spec (Target::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenerateMipmap.xml">external</a> documentation.
+-spec generateMipmap(enum()) -> ok.
generateMipmap(Target) ->
- wxe_util:cast(5655, <<Target:?GLenum>>).
+ cast(5665, <<Target:?GLenum>>).
%% @spec (SrcX0::integer(),SrcY0::integer(),SrcX1::integer(),SrcY1::integer(),DstX0::integer(),DstY0::integer(),DstX1::integer(),DstY1::integer(),Mask::integer(),Filter::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlitFramebuffer.xml">external</a> documentation.
+-spec blitFramebuffer(integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),enum()) -> ok.
blitFramebuffer(SrcX0,SrcY0,SrcX1,SrcY1,DstX0,DstY0,DstX1,DstY1,Mask,Filter) ->
- wxe_util:cast(5656, <<SrcX0:?GLint,SrcY0:?GLint,SrcX1:?GLint,SrcY1:?GLint,DstX0:?GLint,DstY0:?GLint,DstX1:?GLint,DstY1:?GLint,Mask:?GLbitfield,Filter:?GLenum>>).
+ cast(5666, <<SrcX0:?GLint,SrcY0:?GLint,SrcX1:?GLint,SrcY1:?GLint,DstX0:?GLint,DstY0:?GLint,DstX1:?GLint,DstY1:?GLint,Mask:?GLbitfield,Filter:?GLenum>>).
%% @spec (Target::enum(),Samples::integer(),Internalformat::enum(),Width::integer(),Height::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRenderbufferStorageMultisample.xml">external</a> documentation.
+-spec renderbufferStorageMultisample(enum(),integer(),enum(),integer(),integer()) -> ok.
renderbufferStorageMultisample(Target,Samples,Internalformat,Width,Height) ->
- wxe_util:cast(5657, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5667, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
%% @spec (Target::enum(),Attachment::enum(),Texture::integer(),Level::integer(),Layer::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTextureLayer.xml">external</a> documentation.
+-spec framebufferTextureLayer(enum(),enum(),integer(),integer(),integer()) -> ok.
framebufferTextureLayer(Target,Attachment,Texture,Level,Layer) ->
- wxe_util:cast(5658, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Layer:?GLint>>).
-
-%% @spec (Program::integer(),Pname::enum(),Value::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramParameterARB.xml">external</a> documentation.
-programParameteriARB(Program,Pname,Value) ->
- wxe_util:cast(5659, <<Program:?GLuint,Pname:?GLenum,Value:?GLint>>).
-
-%% @spec (Target::enum(),Attachment::enum(),Texture::integer(),Level::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTextureARB.xml">external</a> documentation.
-framebufferTextureARB(Target,Attachment,Texture,Level) ->
- wxe_util:cast(5660, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint>>).
+ cast(5668, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Layer:?GLint>>).
%% @spec (Target::enum(),Attachment::enum(),Texture::integer(),Level::integer(),Face::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTextureFaceARB.xml">external</a> documentation.
+-spec framebufferTextureFaceARB(enum(),enum(),integer(),integer(),enum()) -> ok.
framebufferTextureFaceARB(Target,Attachment,Texture,Level,Face) ->
- wxe_util:cast(5661, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Face:?GLenum>>).
-
-%% @spec (Index::integer(),Divisor::integer()) -> ok
-%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribDivisorARB.xml">external</a> documentation.
-vertexAttribDivisorARB(Index,Divisor) ->
- wxe_util:cast(5662, <<Index:?GLuint,Divisor:?GLuint>>).
+ cast(5669, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Face:?GLenum>>).
%% @spec (Target::enum(),Offset::integer(),Length::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFlushMappedBufferRange.xml">external</a> documentation.
+-spec flushMappedBufferRange(enum(),integer(),integer()) -> ok.
flushMappedBufferRange(Target,Offset,Length) ->
- wxe_util:cast(5663, <<Target:?GLenum,0:32,Offset:?GLintptr,Length:?GLsizeiptr>>).
+ cast(5670, <<Target:?GLenum,0:32,Offset:?GLintptr,Length:?GLsizeiptr>>).
%% @spec (Array::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindVertexArray.xml">external</a> documentation.
+-spec bindVertexArray(integer()) -> ok.
bindVertexArray(Array) ->
- wxe_util:cast(5664, <<Array:?GLuint>>).
+ cast(5671, <<Array:?GLuint>>).
%% @spec (Arrays::[integer()]) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteVertexArrays.xml">external</a> documentation.
+-spec deleteVertexArrays([integer()]) -> ok.
deleteVertexArrays(Arrays) ->
- wxe_util:cast(5665, <<(length(Arrays)):?GLuint,
+ cast(5672, <<(length(Arrays)):?GLuint,
(<< <<C:?GLuint>> || C <- Arrays>>)/binary,0:(((1+length(Arrays)) rem 2)*32)>>).
%% @spec (N::integer()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenVertexArrays.xml">external</a> documentation.
+-spec genVertexArrays(integer()) -> [integer()].
genVertexArrays(N) ->
- wxe_util:call(5666, <<N:?GLsizei>>).
+ call(5673, <<N:?GLsizei>>).
%% @spec (Array::integer()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsVertexArray.xml">external</a> documentation.
+-spec isVertexArray(integer()) -> 0|1.
isVertexArray(Array) ->
- wxe_util:call(5667, <<Array:?GLuint>>).
+ call(5674, <<Array:?GLuint>>).
%% @spec (Program::integer(),UniformNames::[string()]) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformIndices.xml">external</a> documentation.
+-spec getUniformIndices(integer(),[string()]) -> [integer()].
getUniformIndices(Program,UniformNames) ->
UniformNamesTemp = list_to_binary([[Str|[0]] || Str <- UniformNames ]),
- wxe_util:call(5668, <<Program:?GLuint,(length(UniformNames)):?GLuint,(size(UniformNamesTemp)):?GLuint,(UniformNamesTemp)/binary,0:((8-((size(UniformNamesTemp)+0) rem 8)) rem 8)>>).
+ call(5675, <<Program:?GLuint,(length(UniformNames)):?GLuint,(size(UniformNamesTemp)):?GLuint,(UniformNamesTemp)/binary,0:((8-((size(UniformNamesTemp)+0) rem 8)) rem 8)>>).
%% @spec (Program::integer(),UniformIndices::[integer()],Pname::enum()) -> [integer()]
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniforms.xml">external</a> documentation.
+-spec getActiveUniformsiv(integer(),[integer()],enum()) -> [integer()].
getActiveUniformsiv(Program,UniformIndices,Pname) ->
- wxe_util:call(5669, <<Program:?GLuint,(length(UniformIndices)):?GLuint,
+ call(5676, <<Program:?GLuint,(length(UniformIndices)):?GLuint,
(<< <<C:?GLuint>> || C <- UniformIndices>>)/binary,0:(((length(UniformIndices)) rem 2)*32),Pname:?GLenum>>).
%% @spec (Program::integer(),UniformIndex::integer(),BufSize::integer()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformName.xml">external</a> documentation.
+-spec getActiveUniformName(integer(),integer(),integer()) -> string().
getActiveUniformName(Program,UniformIndex,BufSize) ->
- wxe_util:call(5670, <<Program:?GLuint,UniformIndex:?GLuint,BufSize:?GLsizei>>).
+ call(5677, <<Program:?GLuint,UniformIndex:?GLuint,BufSize:?GLsizei>>).
%% @spec (Program::integer(),UniformBlockName::string()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformBlockIndex.xml">external</a> documentation.
+-spec getUniformBlockIndex(integer(),string()) -> integer().
getUniformBlockIndex(Program,UniformBlockName) ->
- wxe_util:call(5671, <<Program:?GLuint,(list_to_binary([UniformBlockName|[0]]))/binary,0:((8-((length(UniformBlockName)+ 5) rem 8)) rem 8)>>).
+ call(5678, <<Program:?GLuint,(list_to_binary([UniformBlockName|[0]]))/binary,0:((8-((length(UniformBlockName)+ 5) rem 8)) rem 8)>>).
-%% @spec (Program::integer(),UniformBlockIndex::integer(),Pname::enum(),Params::wx:wx_mem()) -> ok
+%% @spec (Program::integer(),UniformBlockIndex::integer(),Pname::enum(),Params::mem()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformBlock.xml">external</a> documentation.
+-spec getActiveUniformBlockiv(integer(),integer(),enum(),mem()) -> ok.
getActiveUniformBlockiv(Program,UniformBlockIndex,Pname,Params) ->
- wxe_util:send_bin(Params#wx_mem.bin),
- wxe_util:call(5672, <<Program:?GLuint,UniformBlockIndex:?GLuint,Pname:?GLenum>>).
+ send_bin(Params),
+ call(5679, <<Program:?GLuint,UniformBlockIndex:?GLuint,Pname:?GLenum>>).
%% @spec (Program::integer(),UniformBlockIndex::integer(),BufSize::integer()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformBlockName.xml">external</a> documentation.
+-spec getActiveUniformBlockName(integer(),integer(),integer()) -> string().
getActiveUniformBlockName(Program,UniformBlockIndex,BufSize) ->
- wxe_util:call(5673, <<Program:?GLuint,UniformBlockIndex:?GLuint,BufSize:?GLsizei>>).
+ call(5680, <<Program:?GLuint,UniformBlockIndex:?GLuint,BufSize:?GLsizei>>).
%% @spec (Program::integer(),UniformBlockIndex::integer(),UniformBlockBinding::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformBlockBinding.xml">external</a> documentation.
+-spec uniformBlockBinding(integer(),integer(),integer()) -> ok.
uniformBlockBinding(Program,UniformBlockIndex,UniformBlockBinding) ->
- wxe_util:cast(5674, <<Program:?GLuint,UniformBlockIndex:?GLuint,UniformBlockBinding:?GLuint>>).
+ cast(5681, <<Program:?GLuint,UniformBlockIndex:?GLuint,UniformBlockBinding:?GLuint>>).
%% @spec (ReadTarget::enum(),WriteTarget::enum(),ReadOffset::integer(),WriteOffset::integer(),Size::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyBufferSubData.xml">external</a> documentation.
+-spec copyBufferSubData(enum(),enum(),integer(),integer(),integer()) -> ok.
copyBufferSubData(ReadTarget,WriteTarget,ReadOffset,WriteOffset,Size) ->
- wxe_util:cast(5675, <<ReadTarget:?GLenum,WriteTarget:?GLenum,ReadOffset:?GLintptr,WriteOffset:?GLintptr,Size:?GLsizeiptr>>).
+ cast(5682, <<ReadTarget:?GLenum,WriteTarget:?GLenum,ReadOffset:?GLintptr,WriteOffset:?GLintptr,Size:?GLsizeiptr>>).
+
+%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|mem(),Basevertex::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsBaseVertex.xml">external</a> documentation.
+-spec drawElementsBaseVertex(enum(),integer(),enum(),offset()|mem(),integer()) -> ok.
+drawElementsBaseVertex(Mode,Count,Type,Indices,Basevertex) when is_integer(Indices) ->
+ cast(5683, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Basevertex:?GLint>>);
+drawElementsBaseVertex(Mode,Count,Type,Indices,Basevertex) ->
+ send_bin(Indices),
+ cast(5684, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Basevertex:?GLint>>).
+
+%% @spec (Mode::enum(),Start::integer(),End::integer(),Count::integer(),Type::enum(),Indices::offset()|mem(),Basevertex::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawRangeElementsBaseVertex.xml">external</a> documentation.
+-spec drawRangeElementsBaseVertex(enum(),integer(),integer(),integer(),enum(),offset()|mem(),integer()) -> ok.
+drawRangeElementsBaseVertex(Mode,Start,End,Count,Type,Indices,Basevertex) when is_integer(Indices) ->
+ cast(5685, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Basevertex:?GLint>>);
+drawRangeElementsBaseVertex(Mode,Start,End,Count,Type,Indices,Basevertex) ->
+ send_bin(Indices),
+ cast(5686, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Basevertex:?GLint>>).
+
+%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|mem(),Primcount::integer(),Basevertex::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstancedBaseVertex.xml">external</a> documentation.
+-spec drawElementsInstancedBaseVertex(enum(),integer(),enum(),offset()|mem(),integer(),integer()) -> ok.
+drawElementsInstancedBaseVertex(Mode,Count,Type,Indices,Primcount,Basevertex) when is_integer(Indices) ->
+ cast(5687, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Basevertex:?GLint>>);
+drawElementsInstancedBaseVertex(Mode,Count,Type,Indices,Primcount,Basevertex) ->
+ send_bin(Indices),
+ cast(5688, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Basevertex:?GLint>>).
+
+%% @spec (Mode::enum()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProvokingVertex.xml">external</a> documentation.
+-spec provokingVertex(enum()) -> ok.
+provokingVertex(Mode) ->
+ cast(5689, <<Mode:?GLenum>>).
+
+%% @spec (Condition::enum(),Flags::integer()) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFenceSync.xml">external</a> documentation.
+-spec fenceSync(enum(),integer()) -> integer().
+fenceSync(Condition,Flags) ->
+ call(5690, <<Condition:?GLenum,Flags:?GLbitfield>>).
+
+%% @spec (Sync::integer()) -> 0|1
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsSync.xml">external</a> documentation.
+-spec isSync(integer()) -> 0|1.
+isSync(Sync) ->
+ call(5691, <<Sync:?GLsync>>).
+
+%% @spec (Sync::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteSync.xml">external</a> documentation.
+-spec deleteSync(integer()) -> ok.
+deleteSync(Sync) ->
+ cast(5692, <<Sync:?GLsync>>).
+
+%% @spec (Sync::integer(),Flags::integer(),Timeout::integer()) -> enum()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClientWaitSync.xml">external</a> documentation.
+-spec clientWaitSync(integer(),integer(),integer()) -> enum().
+clientWaitSync(Sync,Flags,Timeout) ->
+ call(5693, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>).
+
+%% @spec (Sync::integer(),Flags::integer(),Timeout::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWaitSync.xml">external</a> documentation.
+-spec waitSync(integer(),integer(),integer()) -> ok.
+waitSync(Sync,Flags,Timeout) ->
+ cast(5694, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>).
+
+%% @spec (Pname::enum()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetInteger64v.xml">external</a> documentation.
+-spec getInteger64v(enum()) -> [integer()].
+getInteger64v(Pname) ->
+ call(5695, <<Pname:?GLenum>>).
+
+%% @spec (Sync::integer(),Pname::enum(),BufSize::integer()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSync.xml">external</a> documentation.
+-spec getSynciv(integer(),enum(),integer()) -> [integer()].
+getSynciv(Sync,Pname,BufSize) ->
+ call(5696, <<Sync:?GLsync,Pname:?GLenum,BufSize:?GLsizei>>).
+
+%% @spec (Target::enum(),Samples::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Fixedsamplelocations::0|1) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2DMultisample.xml">external</a> documentation.
+-spec texImage2DMultisample(enum(),integer(),integer(),integer(),integer(),0|1) -> ok.
+texImage2DMultisample(Target,Samples,Internalformat,Width,Height,Fixedsamplelocations) ->
+ cast(5697, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Fixedsamplelocations:?GLboolean>>).
+
+%% @spec (Target::enum(),Samples::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Depth::integer(),Fixedsamplelocations::0|1) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3DMultisample.xml">external</a> documentation.
+-spec texImage3DMultisample(enum(),integer(),integer(),integer(),integer(),integer(),0|1) -> ok.
+texImage3DMultisample(Target,Samples,Internalformat,Width,Height,Depth,Fixedsamplelocations) ->
+ cast(5698, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Fixedsamplelocations:?GLboolean>>).
+
+%% @spec (Pname::enum(),Index::integer()) -> {float(),float()}
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMultisample.xml">external</a> documentation.
+-spec getMultisamplefv(enum(),integer()) -> {float(),float()}.
+getMultisamplefv(Pname,Index) ->
+ call(5699, <<Pname:?GLenum,Index:?GLuint>>).
+
+%% @spec (Index::integer(),Mask::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSampleMaski.xml">external</a> documentation.
+-spec sampleMaski(integer(),integer()) -> ok.
+sampleMaski(Index,Mask) ->
+ cast(5700, <<Index:?GLuint,Mask:?GLbitfield>>).
+
+%% @spec (Type::enum(),Name::string(),String::string()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNamedStringARB.xml">external</a> documentation.
+-spec namedStringARB(enum(),string(),string()) -> ok.
+namedStringARB(Type,Name,String) ->
+ cast(5701, <<Type:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8),(list_to_binary([String|[0]]))/binary,0:((8-((length(String)+ 1) rem 8)) rem 8)>>).
+
+%% @spec (Name::string()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteNamedStringARB.xml">external</a> documentation.
+-spec deleteNamedStringARB(string()) -> ok.
+deleteNamedStringARB(Name) ->
+ cast(5702, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+
+%% @spec (Shader::integer(),Path::[string()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShaderIncludeARB.xml">external</a> documentation.
+-spec compileShaderIncludeARB(integer(),[string()]) -> ok.
+compileShaderIncludeARB(Shader,Path) ->
+ PathTemp = list_to_binary([[Str|[0]] || Str <- Path ]),
+ cast(5703, <<Shader:?GLuint,(length(Path)):?GLuint,(size(PathTemp)):?GLuint,(PathTemp)/binary,0:((8-((size(PathTemp)+0) rem 8)) rem 8)>>).
+
+%% @spec (Name::string()) -> 0|1
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsNamedStringARB.xml">external</a> documentation.
+-spec isNamedStringARB(string()) -> 0|1.
+isNamedStringARB(Name) ->
+ call(5704, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+
+%% @spec (Name::string(),BufSize::integer()) -> string()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetNamedStringARB.xml">external</a> documentation.
+-spec getNamedStringARB(string(),integer()) -> string().
+getNamedStringARB(Name,BufSize) ->
+ call(5705, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8),BufSize:?GLsizei>>).
+
+%% @spec (Name::string(),Pname::enum()) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetNamedStringARB.xml">external</a> documentation.
+-spec getNamedStringivARB(string(),enum()) -> integer().
+getNamedStringivARB(Name,Pname) ->
+ call(5706, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8),Pname:?GLenum>>).
+
+%% @spec (Program::integer(),ColorNumber::integer(),Index::integer(),Name::string()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFragDataLocationIndexe.xml">external</a> documentation.
+-spec bindFragDataLocationIndexed(integer(),integer(),integer(),string()) -> ok.
+bindFragDataLocationIndexed(Program,ColorNumber,Index,Name) ->
+ cast(5707, <<Program:?GLuint,ColorNumber:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+
+%% @spec (Program::integer(),Name::string()) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFragDataIndex.xml">external</a> documentation.
+-spec getFragDataIndex(integer(),string()) -> integer().
+getFragDataIndex(Program,Name) ->
+ call(5708, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+
+%% @spec (Count::integer()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenSamplers.xml">external</a> documentation.
+-spec genSamplers(integer()) -> [integer()].
+genSamplers(Count) ->
+ call(5709, <<Count:?GLsizei>>).
+
+%% @spec (Samplers::[integer()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteSamplers.xml">external</a> documentation.
+-spec deleteSamplers([integer()]) -> ok.
+deleteSamplers(Samplers) ->
+ cast(5710, <<(length(Samplers)):?GLuint,
+ (<< <<C:?GLuint>> || C <- Samplers>>)/binary,0:(((1+length(Samplers)) rem 2)*32)>>).
+
+%% @spec (Sampler::integer()) -> 0|1
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsSampler.xml">external</a> documentation.
+-spec isSampler(integer()) -> 0|1.
+isSampler(Sampler) ->
+ call(5711, <<Sampler:?GLuint>>).
+
+%% @spec (Unit::integer(),Sampler::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindSampler.xml">external</a> documentation.
+-spec bindSampler(integer(),integer()) -> ok.
+bindSampler(Unit,Sampler) ->
+ cast(5712, <<Unit:?GLuint,Sampler:?GLuint>>).
+
+%% @spec (Sampler::integer(),Pname::enum(),Param::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameter.xml">external</a> documentation.
+-spec samplerParameteri(integer(),enum(),integer()) -> ok.
+samplerParameteri(Sampler,Pname,Param) ->
+ cast(5713, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLint>>).
+
+%% @spec (Sampler::integer(),Pname::enum(),Param::[integer()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameter.xml">external</a> documentation.
+-spec samplerParameteriv(integer(),enum(),[integer()]) -> ok.
+samplerParameteriv(Sampler,Pname,Param) ->
+ cast(5714, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint,
+ (<< <<C:?GLint>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>).
+
+%% @spec (Sampler::integer(),Pname::enum(),Param::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameter.xml">external</a> documentation.
+-spec samplerParameterf(integer(),enum(),float()) -> ok.
+samplerParameterf(Sampler,Pname,Param) ->
+ cast(5715, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLfloat>>).
+
+%% @spec (Sampler::integer(),Pname::enum(),Param::[float()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameter.xml">external</a> documentation.
+-spec samplerParameterfv(integer(),enum(),[float()]) -> ok.
+samplerParameterfv(Sampler,Pname,Param) ->
+ cast(5716, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint,
+ (<< <<C:?GLfloat>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>).
+
+%% @spec (Sampler::integer(),Pname::enum(),Param::[integer()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameterI.xml">external</a> documentation.
+-spec samplerParameterIiv(integer(),enum(),[integer()]) -> ok.
+samplerParameterIiv(Sampler,Pname,Param) ->
+ cast(5717, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint,
+ (<< <<C:?GLint>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>).
+
+%% @spec (Sampler::integer(),Pname::enum(),Param::[integer()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameterI.xml">external</a> documentation.
+-spec samplerParameterIuiv(integer(),enum(),[integer()]) -> ok.
+samplerParameterIuiv(Sampler,Pname,Param) ->
+ cast(5718, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint,
+ (<< <<C:?GLuint>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>).
+
+%% @spec (Sampler::integer(),Pname::enum()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameter.xml">external</a> documentation.
+-spec getSamplerParameteriv(integer(),enum()) -> [integer()].
+getSamplerParameteriv(Sampler,Pname) ->
+ call(5719, <<Sampler:?GLuint,Pname:?GLenum>>).
+
+%% @spec (Sampler::integer(),Pname::enum()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameterI.xml">external</a> documentation.
+-spec getSamplerParameterIiv(integer(),enum()) -> [integer()].
+getSamplerParameterIiv(Sampler,Pname) ->
+ call(5720, <<Sampler:?GLuint,Pname:?GLenum>>).
+
+%% @spec (Sampler::integer(),Pname::enum()) -> [float()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameter.xml">external</a> documentation.
+-spec getSamplerParameterfv(integer(),enum()) -> [float()].
+getSamplerParameterfv(Sampler,Pname) ->
+ call(5721, <<Sampler:?GLuint,Pname:?GLenum>>).
+
+%% @spec (Sampler::integer(),Pname::enum()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameterI.xml">external</a> documentation.
+-spec getSamplerParameterIuiv(integer(),enum()) -> [integer()].
+getSamplerParameterIuiv(Sampler,Pname) ->
+ call(5722, <<Sampler:?GLuint,Pname:?GLenum>>).
+
+%% @spec (Id::integer(),Target::enum()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glQueryCounter.xml">external</a> documentation.
+-spec queryCounter(integer(),enum()) -> ok.
+queryCounter(Id,Target) ->
+ cast(5723, <<Id:?GLuint,Target:?GLenum>>).
+
+%% @spec (Id::integer(),Pname::enum()) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObjecti64v.xml">external</a> documentation.
+-spec getQueryObjecti64v(integer(),enum()) -> integer().
+getQueryObjecti64v(Id,Pname) ->
+ call(5724, <<Id:?GLuint,Pname:?GLenum>>).
+
+%% @spec (Id::integer(),Pname::enum()) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObjectui64v.xml">external</a> documentation.
+-spec getQueryObjectui64v(integer(),enum()) -> integer().
+getQueryObjectui64v(Id,Pname) ->
+ call(5725, <<Id:?GLuint,Pname:?GLenum>>).
+
+%% @spec (Mode::enum(),Indirect::offset()|mem()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArraysIndirect.xml">external</a> documentation.
+-spec drawArraysIndirect(enum(),offset()|mem()) -> ok.
+drawArraysIndirect(Mode,Indirect) when is_integer(Indirect) ->
+ cast(5726, <<Mode:?GLenum,Indirect:?GLuint>>);
+drawArraysIndirect(Mode,Indirect) ->
+ send_bin(Indirect),
+ cast(5727, <<Mode:?GLenum>>).
+
+%% @spec (Mode::enum(),Type::enum(),Indirect::offset()|mem()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsIndirect.xml">external</a> documentation.
+-spec drawElementsIndirect(enum(),enum(),offset()|mem()) -> ok.
+drawElementsIndirect(Mode,Type,Indirect) when is_integer(Indirect) ->
+ cast(5728, <<Mode:?GLenum,Type:?GLenum,Indirect:?GLuint>>);
+drawElementsIndirect(Mode,Type,Indirect) ->
+ send_bin(Indirect),
+ cast(5729, <<Mode:?GLenum,Type:?GLenum>>).
+
+%% @spec (Location::integer(),X::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform1d(integer(),float()) -> ok.
+uniform1d(Location,X) ->
+ cast(5730, <<Location:?GLint,0:32,X:?GLdouble>>).
+
+%% @spec (Location::integer(),X::float(),Y::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform2d(integer(),float(),float()) -> ok.
+uniform2d(Location,X,Y) ->
+ cast(5731, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble>>).
+
+%% @spec (Location::integer(),X::float(),Y::float(),Z::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform3d(integer(),float(),float(),float()) -> ok.
+uniform3d(Location,X,Y,Z) ->
+ cast(5732, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+
+%% @spec (Location::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform4d(integer(),float(),float(),float(),float()) -> ok.
+uniform4d(Location,X,Y,Z,W) ->
+ cast(5733, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+
+%% @spec (Location::integer(),Value::[float()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform1dv(integer(),[float()]) -> ok.
+uniform1dv(Location,Value) ->
+ cast(5734, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ (<< <<C:?GLdouble>> || C <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Value::[{float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform2dv(integer(),[{float(),float()}]) -> ok.
+uniform2dv(Location,Value) ->
+ cast(5735, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble>> || {V1,V2} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Value::[{float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform3dv(integer(),[{float(),float(),float()}]) -> ok.
+uniform3dv(Location,Value) ->
+ cast(5736, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>> || {V1,V2,V3} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Value::[{float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
+-spec uniform4dv(integer(),[{float(),float(),float(),float()}]) -> ok.
+uniform4dv(Location,Value) ->
+ cast(5737, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation.
+-spec uniformMatrix2dv(integer(),0|1,[{float(),float(),float(),float()}]) -> ok.
+uniformMatrix2dv(Location,Transpose,Value) ->
+ cast(5738, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation.
+-spec uniformMatrix3dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+uniformMatrix3dv(Location,Transpose,Value) ->
+ cast(5739, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation.
+-spec uniformMatrix4dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+uniformMatrix4dv(Location,Transpose,Value) ->
+ cast(5740, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble,V13:?GLdouble,V14:?GLdouble,V15:?GLdouble,V16:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix2x.xml">external</a> documentation.
+-spec uniformMatrix2x3dv(integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok.
+uniformMatrix2x3dv(Location,Transpose,Value) ->
+ cast(5741, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix2x.xml">external</a> documentation.
+-spec uniformMatrix2x4dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+uniformMatrix2x4dv(Location,Transpose,Value) ->
+ cast(5742, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix3x.xml">external</a> documentation.
+-spec uniformMatrix3x2dv(integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok.
+uniformMatrix3x2dv(Location,Transpose,Value) ->
+ cast(5743, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix3x.xml">external</a> documentation.
+-spec uniformMatrix3x4dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+uniformMatrix3x4dv(Location,Transpose,Value) ->
+ cast(5744, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix4x.xml">external</a> documentation.
+-spec uniformMatrix4x2dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+uniformMatrix4x2dv(Location,Transpose,Value) ->
+ cast(5745, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
+
+%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix4x.xml">external</a> documentation.
+-spec uniformMatrix4x3dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+uniformMatrix4x3dv(Location,Transpose,Value) ->
+ cast(5746, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml">external</a> documentation.
+-spec getUniformdv(integer(),integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}.
+getUniformdv(Program,Location) ->
+ call(5747, <<Program:?GLuint,Location:?GLint>>).
+
+%% @spec (Program::integer(),Shadertype::enum(),Name::string()) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSubroutineUniformLocation.xml">external</a> documentation.
+-spec getSubroutineUniformLocation(integer(),enum(),string()) -> integer().
+getSubroutineUniformLocation(Program,Shadertype,Name) ->
+ call(5748, <<Program:?GLuint,Shadertype:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+
+%% @spec (Program::integer(),Shadertype::enum(),Name::string()) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSubroutineIndex.xml">external</a> documentation.
+-spec getSubroutineIndex(integer(),enum(),string()) -> integer().
+getSubroutineIndex(Program,Shadertype,Name) ->
+ call(5749, <<Program:?GLuint,Shadertype:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+
+%% @spec (Program::integer(),Shadertype::enum(),Index::integer(),Bufsize::integer()) -> string()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveSubroutineUniformName.xml">external</a> documentation.
+-spec getActiveSubroutineUniformName(integer(),enum(),integer(),integer()) -> string().
+getActiveSubroutineUniformName(Program,Shadertype,Index,Bufsize) ->
+ call(5750, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>).
+
+%% @spec (Program::integer(),Shadertype::enum(),Index::integer(),Bufsize::integer()) -> string()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveSubroutineName.xml">external</a> documentation.
+-spec getActiveSubroutineName(integer(),enum(),integer(),integer()) -> string().
+getActiveSubroutineName(Program,Shadertype,Index,Bufsize) ->
+ call(5751, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>).
+
+%% @spec (Shadertype::enum(),Indices::[integer()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformSubroutines.xml">external</a> documentation.
+-spec uniformSubroutinesuiv(enum(),[integer()]) -> ok.
+uniformSubroutinesuiv(Shadertype,Indices) ->
+ cast(5752, <<Shadertype:?GLenum,(length(Indices)):?GLuint,
+ (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((length(Indices)) rem 2)*32)>>).
+
+%% @spec (Shadertype::enum(),Location::integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformSubroutine.xml">external</a> documentation.
+-spec getUniformSubroutineuiv(enum(),integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}.
+getUniformSubroutineuiv(Shadertype,Location) ->
+ call(5753, <<Shadertype:?GLenum,Location:?GLint>>).
+
+%% @spec (Program::integer(),Shadertype::enum(),Pname::enum()) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramStage.xml">external</a> documentation.
+-spec getProgramStageiv(integer(),enum(),enum()) -> integer().
+getProgramStageiv(Program,Shadertype,Pname) ->
+ call(5754, <<Program:?GLuint,Shadertype:?GLenum,Pname:?GLenum>>).
+
+%% @spec (Pname::enum(),Value::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPatchParameter.xml">external</a> documentation.
+-spec patchParameteri(enum(),integer()) -> ok.
+patchParameteri(Pname,Value) ->
+ cast(5755, <<Pname:?GLenum,Value:?GLint>>).
+
+%% @spec (Pname::enum(),Values::[float()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPatchParameter.xml">external</a> documentation.
+-spec patchParameterfv(enum(),[float()]) -> ok.
+patchParameterfv(Pname,Values) ->
+ cast(5756, <<Pname:?GLenum,(length(Values)):?GLuint,
+ (<< <<C:?GLfloat>> || C <- Values>>)/binary,0:(((length(Values)) rem 2)*32)>>).
+
+%% @spec (Target::enum(),Id::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindTransformFeedback.xml">external</a> documentation.
+-spec bindTransformFeedback(enum(),integer()) -> ok.
+bindTransformFeedback(Target,Id) ->
+ cast(5757, <<Target:?GLenum,Id:?GLuint>>).
+
+%% @spec (Ids::[integer()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTransformFeedbacks.xml">external</a> documentation.
+-spec deleteTransformFeedbacks([integer()]) -> ok.
+deleteTransformFeedbacks(Ids) ->
+ cast(5758, <<(length(Ids)):?GLuint,
+ (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+length(Ids)) rem 2)*32)>>).
+
+%% @spec (N::integer()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenTransformFeedbacks.xml">external</a> documentation.
+-spec genTransformFeedbacks(integer()) -> [integer()].
+genTransformFeedbacks(N) ->
+ call(5759, <<N:?GLsizei>>).
+
+%% @spec (Id::integer()) -> 0|1
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsTransformFeedback.xml">external</a> documentation.
+-spec isTransformFeedback(integer()) -> 0|1.
+isTransformFeedback(Id) ->
+ call(5760, <<Id:?GLuint>>).
+
+%% @spec () -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPauseTransformFeedback.xml">external</a> documentation.
+-spec pauseTransformFeedback() -> ok.
+pauseTransformFeedback() ->
+ cast(5761, <<>>).
+
+%% @spec () -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glResumeTransformFeedback.xml">external</a> documentation.
+-spec resumeTransformFeedback() -> ok.
+resumeTransformFeedback() ->
+ cast(5762, <<>>).
+
+%% @spec (Mode::enum(),Id::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedback.xml">external</a> documentation.
+-spec drawTransformFeedback(enum(),integer()) -> ok.
+drawTransformFeedback(Mode,Id) ->
+ cast(5763, <<Mode:?GLenum,Id:?GLuint>>).
+
+%% @spec (Mode::enum(),Id::integer(),Stream::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedbackStream.xml">external</a> documentation.
+-spec drawTransformFeedbackStream(enum(),integer(),integer()) -> ok.
+drawTransformFeedbackStream(Mode,Id,Stream) ->
+ cast(5764, <<Mode:?GLenum,Id:?GLuint,Stream:?GLuint>>).
+
+%% @spec (Target::enum(),Index::integer(),Id::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginQueryIndexe.xml">external</a> documentation.
+-spec beginQueryIndexed(enum(),integer(),integer()) -> ok.
+beginQueryIndexed(Target,Index,Id) ->
+ cast(5765, <<Target:?GLenum,Index:?GLuint,Id:?GLuint>>).
+
+%% @spec (Target::enum(),Index::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEndQueryIndexe.xml">external</a> documentation.
+-spec endQueryIndexed(enum(),integer()) -> ok.
+endQueryIndexed(Target,Index) ->
+ cast(5766, <<Target:?GLenum,Index:?GLuint>>).
+
+%% @spec (Target::enum(),Index::integer(),Pname::enum()) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryIndexed.xml">external</a> documentation.
+-spec getQueryIndexediv(enum(),integer(),enum()) -> integer().
+getQueryIndexediv(Target,Index,Pname) ->
+ call(5767, <<Target:?GLenum,Index:?GLuint,Pname:?GLenum>>).
+
+%% @spec () -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glReleaseShaderCompiler.xml">external</a> documentation.
+-spec releaseShaderCompiler() -> ok.
+releaseShaderCompiler() ->
+ cast(5768, <<>>).
+
+%% @spec (Shaders::[integer()],Binaryformat::enum(),Binary::binary()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderBinary.xml">external</a> documentation.
+-spec shaderBinary([integer()],enum(),binary()) -> ok.
+shaderBinary(Shaders,Binaryformat,Binary) ->
+ send_bin(Binary),
+ cast(5769, <<(length(Shaders)):?GLuint,
+ (<< <<C:?GLuint>> || C <- Shaders>>)/binary,0:(((1+length(Shaders)) rem 2)*32),Binaryformat:?GLenum>>).
+
+%% @spec (Shadertype::enum(),Precisiontype::enum()) -> {Range::{integer(),integer()},Precision::integer()}
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderPrecisionFormat.xml">external</a> documentation.
+-spec getShaderPrecisionFormat(enum(),enum()) -> {{integer(),integer()},integer()}.
+getShaderPrecisionFormat(Shadertype,Precisiontype) ->
+ call(5770, <<Shadertype:?GLenum,Precisiontype:?GLenum>>).
+
+%% @spec (N::clamp(),F::clamp()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRange.xml">external</a> documentation.
+-spec depthRangef(clamp(),clamp()) -> ok.
+depthRangef(N,F) ->
+ cast(5771, <<N:?GLclampf,F:?GLclampf>>).
+
+%% @spec (D::clamp()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearDepthf.xml">external</a> documentation.
+-spec clearDepthf(clamp()) -> ok.
+clearDepthf(D) ->
+ cast(5772, <<D:?GLclampf>>).
+
+%% @spec (Program::integer(),BufSize::integer()) -> {BinaryFormat::enum(),Binary::binary()}
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramBinary.xml">external</a> documentation.
+-spec getProgramBinary(integer(),integer()) -> {enum(),binary()}.
+getProgramBinary(Program,BufSize) ->
+ call(5773, <<Program:?GLuint,BufSize:?GLsizei>>).
+
+%% @spec (Program::integer(),BinaryFormat::enum(),Binary::binary()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramBinary.xml">external</a> documentation.
+-spec programBinary(integer(),enum(),binary()) -> ok.
+programBinary(Program,BinaryFormat,Binary) ->
+ send_bin(Binary),
+ cast(5774, <<Program:?GLuint,BinaryFormat:?GLenum>>).
+
+%% @spec (Program::integer(),Pname::enum(),Value::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramParameter.xml">external</a> documentation.
+-spec programParameteri(integer(),enum(),integer()) -> ok.
+programParameteri(Program,Pname,Value) ->
+ cast(5775, <<Program:?GLuint,Pname:?GLenum,Value:?GLint>>).
+
+%% @spec (Pipeline::integer(),Stages::integer(),Program::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgramStages.xml">external</a> documentation.
+-spec useProgramStages(integer(),integer(),integer()) -> ok.
+useProgramStages(Pipeline,Stages,Program) ->
+ cast(5776, <<Pipeline:?GLuint,Stages:?GLbitfield,Program:?GLuint>>).
+
+%% @spec (Pipeline::integer(),Program::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glActiveShaderProgram.xml">external</a> documentation.
+-spec activeShaderProgram(integer(),integer()) -> ok.
+activeShaderProgram(Pipeline,Program) ->
+ cast(5777, <<Pipeline:?GLuint,Program:?GLuint>>).
+
+%% @spec (Type::enum(),Strings::[string()]) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShaderProgramv.xml">external</a> documentation.
+-spec createShaderProgramv(enum(),[string()]) -> integer().
+createShaderProgramv(Type,Strings) ->
+ StringsTemp = list_to_binary([[Str|[0]] || Str <- Strings ]),
+ call(5778, <<Type:?GLenum,(length(Strings)):?GLuint,(size(StringsTemp)):?GLuint,(StringsTemp)/binary,0:((8-((size(StringsTemp)+0) rem 8)) rem 8)>>).
+
+%% @spec (Pipeline::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindProgramPipeline.xml">external</a> documentation.
+-spec bindProgramPipeline(integer()) -> ok.
+bindProgramPipeline(Pipeline) ->
+ cast(5779, <<Pipeline:?GLuint>>).
+
+%% @spec (Pipelines::[integer()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgramPipelines.xml">external</a> documentation.
+-spec deleteProgramPipelines([integer()]) -> ok.
+deleteProgramPipelines(Pipelines) ->
+ cast(5780, <<(length(Pipelines)):?GLuint,
+ (<< <<C:?GLuint>> || C <- Pipelines>>)/binary,0:(((1+length(Pipelines)) rem 2)*32)>>).
+
+%% @spec (N::integer()) -> [integer()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenProgramPipelines.xml">external</a> documentation.
+-spec genProgramPipelines(integer()) -> [integer()].
+genProgramPipelines(N) ->
+ call(5781, <<N:?GLsizei>>).
+
+%% @spec (Pipeline::integer()) -> 0|1
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsProgramPipeline.xml">external</a> documentation.
+-spec isProgramPipeline(integer()) -> 0|1.
+isProgramPipeline(Pipeline) ->
+ call(5782, <<Pipeline:?GLuint>>).
+
+%% @spec (Pipeline::integer(),Pname::enum()) -> integer()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramPipeline.xml">external</a> documentation.
+-spec getProgramPipelineiv(integer(),enum()) -> integer().
+getProgramPipelineiv(Pipeline,Pname) ->
+ call(5783, <<Pipeline:?GLuint,Pname:?GLenum>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform1i(integer(),integer(),integer()) -> ok.
+programUniform1i(Program,Location,V0) ->
+ cast(5784, <<Program:?GLuint,Location:?GLint,V0:?GLint>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[integer()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform1iv(integer(),integer(),[integer()]) -> ok.
+programUniform1iv(Program,Location,Value) ->
+ cast(5785, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<C:?GLint>> || C <- Value>>)/binary,0:(((1+length(Value)) rem 2)*32)>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform1f(integer(),integer(),float()) -> ok.
+programUniform1f(Program,Location,V0) ->
+ cast(5786, <<Program:?GLuint,Location:?GLint,V0:?GLfloat>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[float()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform1fv(integer(),integer(),[float()]) -> ok.
+programUniform1fv(Program,Location,Value) ->
+ cast(5787, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((1+length(Value)) rem 2)*32)>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform1d(integer(),integer(),float()) -> ok.
+programUniform1d(Program,Location,V0) ->
+ cast(5788, <<Program:?GLuint,Location:?GLint,V0:?GLdouble>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[float()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform1dv(integer(),integer(),[float()]) -> ok.
+programUniform1dv(Program,Location,Value) ->
+ cast(5789, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ (<< <<C:?GLdouble>> || C <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform1ui(integer(),integer(),integer()) -> ok.
+programUniform1ui(Program,Location,V0) ->
+ cast(5790, <<Program:?GLuint,Location:?GLint,V0:?GLuint>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[integer()]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform1uiv(integer(),integer(),[integer()]) -> ok.
+programUniform1uiv(Program,Location,Value) ->
+ cast(5791, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((1+length(Value)) rem 2)*32)>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform2i(integer(),integer(),integer(),integer()) -> ok.
+programUniform2i(Program,Location,V0,V1) ->
+ cast(5792, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform2iv(integer(),integer(),[{integer(),integer()}]) -> ok.
+programUniform2iv(Program,Location,Value) ->
+ cast(5793, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<V1:?GLint,V2:?GLint>> || {V1,V2} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform2f(integer(),integer(),float(),float()) -> ok.
+programUniform2f(Program,Location,V0,V1) ->
+ cast(5794, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform2fv(integer(),integer(),[{float(),float()}]) -> ok.
+programUniform2fv(Program,Location,Value) ->
+ cast(5795, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat>> || {V1,V2} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform2d(integer(),integer(),float(),float()) -> ok.
+programUniform2d(Program,Location,V0,V1) ->
+ cast(5796, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform2dv(integer(),integer(),[{float(),float()}]) -> ok.
+programUniform2dv(Program,Location,Value) ->
+ cast(5797, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble>> || {V1,V2} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform2ui(integer(),integer(),integer(),integer()) -> ok.
+programUniform2ui(Program,Location,V0,V1) ->
+ cast(5798, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform2uiv(integer(),integer(),[{integer(),integer()}]) -> ok.
+programUniform2uiv(Program,Location,Value) ->
+ cast(5799, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<V1:?GLuint,V2:?GLuint>> || {V1,V2} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer(),V2::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform3i(integer(),integer(),integer(),integer(),integer()) -> ok.
+programUniform3i(Program,Location,V0,V1,V2) ->
+ cast(5800, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer(),integer()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform3iv(integer(),integer(),[{integer(),integer(),integer()}]) -> ok.
+programUniform3iv(Program,Location,Value) ->
+ cast(5801, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<V1:?GLint,V2:?GLint,V3:?GLint>> || {V1,V2,V3} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float(),V2::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform3f(integer(),integer(),float(),float(),float()) -> ok.
+programUniform3f(Program,Location,V0,V1,V2) ->
+ cast(5802, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform3fv(integer(),integer(),[{float(),float(),float()}]) -> ok.
+programUniform3fv(Program,Location,Value) ->
+ cast(5803, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>> || {V1,V2,V3} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float(),V2::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform3d(integer(),integer(),float(),float(),float()) -> ok.
+programUniform3d(Program,Location,V0,V1,V2) ->
+ cast(5804, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform3dv(integer(),integer(),[{float(),float(),float()}]) -> ok.
+programUniform3dv(Program,Location,Value) ->
+ cast(5805, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>> || {V1,V2,V3} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer(),V2::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform3ui(integer(),integer(),integer(),integer(),integer()) -> ok.
+programUniform3ui(Program,Location,V0,V1,V2) ->
+ cast(5806, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer(),integer()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform3uiv(integer(),integer(),[{integer(),integer(),integer()}]) -> ok.
+programUniform3uiv(Program,Location,Value) ->
+ cast(5807, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint>> || {V1,V2,V3} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer(),V2::integer(),V3::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform4i(integer(),integer(),integer(),integer(),integer(),integer()) -> ok.
+programUniform4i(Program,Location,V0,V1,V2,V3) ->
+ cast(5808, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer(),integer(),integer()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform4iv(integer(),integer(),[{integer(),integer(),integer(),integer()}]) -> ok.
+programUniform4iv(Program,Location,Value) ->
+ cast(5809, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float(),V2::float(),V3::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform4f(integer(),integer(),float(),float(),float(),float()) -> ok.
+programUniform4f(Program,Location,V0,V1,V2,V3) ->
+ cast(5810, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform4fv(integer(),integer(),[{float(),float(),float(),float()}]) -> ok.
+programUniform4fv(Program,Location,Value) ->
+ cast(5811, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float(),V2::float(),V3::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform4d(integer(),integer(),float(),float(),float(),float()) -> ok.
+programUniform4d(Program,Location,V0,V1,V2,V3) ->
+ cast(5812, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform4dv(integer(),integer(),[{float(),float(),float(),float()}]) -> ok.
+programUniform4dv(Program,Location,Value) ->
+ cast(5813, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer(),V2::integer(),V3::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform4ui(integer(),integer(),integer(),integer(),integer(),integer()) -> ok.
+programUniform4ui(Program,Location,V0,V1,V2,V3) ->
+ cast(5814, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
+
+%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer(),integer(),integer()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
+-spec programUniform4uiv(integer(),integer(),[{integer(),integer(),integer(),integer()}]) -> ok.
+programUniform4uiv(Program,Location,Value) ->
+ cast(5815, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ (<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation.
+-spec programUniformMatrix2fv(integer(),integer(),0|1,[{float(),float(),float(),float()}]) -> ok.
+programUniformMatrix2fv(Program,Location,Transpose,Value) ->
+ cast(5816, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation.
+-spec programUniformMatrix3fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix3fv(Program,Location,Transpose,Value) ->
+ cast(5817, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation.
+-spec programUniformMatrix4fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix4fv(Program,Location,Transpose,Value) ->
+ cast(5818, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat,V13:?GLfloat,V14:?GLfloat,V15:?GLfloat,V16:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation.
+-spec programUniformMatrix2dv(integer(),integer(),0|1,[{float(),float(),float(),float()}]) -> ok.
+programUniformMatrix2dv(Program,Location,Transpose,Value) ->
+ cast(5819, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation.
+-spec programUniformMatrix3dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix3dv(Program,Location,Transpose,Value) ->
+ cast(5820, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation.
+-spec programUniformMatrix4dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix4dv(Program,Location,Transpose,Value) ->
+ cast(5821, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble,V13:?GLdouble,V14:?GLdouble,V15:?GLdouble,V16:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix2x.xml">external</a> documentation.
+-spec programUniformMatrix2x3fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix2x3fv(Program,Location,Transpose,Value) ->
+ cast(5822, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix3x.xml">external</a> documentation.
+-spec programUniformMatrix3x2fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix3x2fv(Program,Location,Transpose,Value) ->
+ cast(5823, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix2x.xml">external</a> documentation.
+-spec programUniformMatrix2x4fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix2x4fv(Program,Location,Transpose,Value) ->
+ cast(5824, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix4x.xml">external</a> documentation.
+-spec programUniformMatrix4x2fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix4x2fv(Program,Location,Transpose,Value) ->
+ cast(5825, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix3x.xml">external</a> documentation.
+-spec programUniformMatrix3x4fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix3x4fv(Program,Location,Transpose,Value) ->
+ cast(5826, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix4x.xml">external</a> documentation.
+-spec programUniformMatrix4x3fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix4x3fv(Program,Location,Transpose,Value) ->
+ cast(5827, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix2x.xml">external</a> documentation.
+-spec programUniformMatrix2x3dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix2x3dv(Program,Location,Transpose,Value) ->
+ cast(5828, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix3x.xml">external</a> documentation.
+-spec programUniformMatrix3x2dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix3x2dv(Program,Location,Transpose,Value) ->
+ cast(5829, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix2x.xml">external</a> documentation.
+-spec programUniformMatrix2x4dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix2x4dv(Program,Location,Transpose,Value) ->
+ cast(5830, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix4x.xml">external</a> documentation.
+-spec programUniformMatrix4x2dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix4x2dv(Program,Location,Transpose,Value) ->
+ cast(5831, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix3x.xml">external</a> documentation.
+-spec programUniformMatrix3x4dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix3x4dv(Program,Location,Transpose,Value) ->
+ cast(5832, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
+
+%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix4x.xml">external</a> documentation.
+-spec programUniformMatrix4x3dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok.
+programUniformMatrix4x3dv(Program,Location,Transpose,Value) ->
+ cast(5833, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>).
+
+%% @spec (Pipeline::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgramPipeline.xml">external</a> documentation.
+-spec validateProgramPipeline(integer()) -> ok.
+validateProgramPipeline(Pipeline) ->
+ cast(5834, <<Pipeline:?GLuint>>).
+
+%% @spec (Pipeline::integer(),BufSize::integer()) -> string()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramPipelineInfoLog.xml">external</a> documentation.
+-spec getProgramPipelineInfoLog(integer(),integer()) -> string().
+getProgramPipelineInfoLog(Pipeline,BufSize) ->
+ call(5835, <<Pipeline:?GLuint,BufSize:?GLsizei>>).
+
+%% @spec (Index::integer(),X::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
+-spec vertexAttribL1d(integer(),float()) -> ok.
+vertexAttribL1d(Index,X) ->
+ cast(5836, <<Index:?GLuint,0:32,X:?GLdouble>>).
+
+%% @spec (Index::integer(),X::float(),Y::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
+-spec vertexAttribL2d(integer(),float(),float()) -> ok.
+vertexAttribL2d(Index,X,Y) ->
+ cast(5837, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
+
+%% @spec (Index::integer(),X::float(),Y::float(),Z::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
+-spec vertexAttribL3d(integer(),float(),float(),float()) -> ok.
+vertexAttribL3d(Index,X,Y,Z) ->
+ cast(5838, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+
+%% @spec (Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
+-spec vertexAttribL4d(integer(),float(),float(),float(),float()) -> ok.
+vertexAttribL4d(Index,X,Y,Z,W) ->
+ cast(5839, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+
+%% @spec (Index,{X}) -> ok
+%% @equiv vertexAttribL1d(Index,X)
+-spec vertexAttribL1dv(integer(),{float()}) -> ok.
+vertexAttribL1dv(Index,{X}) -> vertexAttribL1d(Index,X).
+
+%% @spec (Index,{X,Y}) -> ok
+%% @equiv vertexAttribL2d(Index,X,Y)
+-spec vertexAttribL2dv(integer(),{float(),float()}) -> ok.
+vertexAttribL2dv(Index,{X,Y}) -> vertexAttribL2d(Index,X,Y).
+
+%% @spec (Index,{X,Y,Z}) -> ok
+%% @equiv vertexAttribL3d(Index,X,Y,Z)
+-spec vertexAttribL3dv(integer(),{float(),float(),float()}) -> ok.
+vertexAttribL3dv(Index,{X,Y,Z}) -> vertexAttribL3d(Index,X,Y,Z).
+
+%% @spec (Index,{X,Y,Z,W}) -> ok
+%% @equiv vertexAttribL4d(Index,X,Y,Z,W)
+-spec vertexAttribL4dv(integer(),{float(),float(),float(),float()}) -> ok.
+vertexAttribL4dv(Index,{X,Y,Z,W}) -> vertexAttribL4d(Index,X,Y,Z,W).
+
+%% @spec (Index::integer(),Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribLPointer.xml">external</a> documentation.
+-spec vertexAttribLPointer(integer(),integer(),enum(),integer(),offset()|mem()) -> ok.
+vertexAttribLPointer(Index,Size,Type,Stride,Pointer) when is_integer(Pointer) ->
+ cast(5840, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+vertexAttribLPointer(Index,Size,Type,Stride,Pointer) ->
+ send_bin(Pointer),
+ cast(5841, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+
+%% @spec (Index::integer(),Pname::enum()) -> {float(),float(),float(),float()}
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttribL.xml">external</a> documentation.
+-spec getVertexAttribLdv(integer(),enum()) -> {float(),float(),float(),float()}.
+getVertexAttribLdv(Index,Pname) ->
+ call(5842, <<Index:?GLuint,Pname:?GLenum>>).
+
+%% @spec (First::integer(),V::[{float(),float(),float(),float()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewportArrayv.xml">external</a> documentation.
+-spec viewportArrayv(integer(),[{float(),float(),float(),float()}]) -> ok.
+viewportArrayv(First,V) ->
+ cast(5843, <<First:?GLuint,(length(V)):?GLuint,
+ (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- V>>)/binary>>).
+
+%% @spec (Index::integer(),X::float(),Y::float(),W::float(),H::float()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewportIndexed.xml">external</a> documentation.
+-spec viewportIndexedf(integer(),float(),float(),float(),float()) -> ok.
+viewportIndexedf(Index,X,Y,W,H) ->
+ cast(5844, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,W:?GLfloat,H:?GLfloat>>).
+
+%% @spec (Index::integer(),V::{float(),float(),float(),float()}) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewportIndexed.xml">external</a> documentation.
+-spec viewportIndexedfv(integer(),{float(),float(),float(),float()}) -> ok.
+viewportIndexedfv(Index,{V1,V2,V3,V4}) ->
+ cast(5845, <<Index:?GLuint,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>>).
+
+%% @spec (First::integer(),V::[{integer(),integer(),integer(),integer()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorArrayv.xml">external</a> documentation.
+-spec scissorArrayv(integer(),[{integer(),integer(),integer(),integer()}]) -> ok.
+scissorArrayv(First,V) ->
+ cast(5846, <<First:?GLuint,(length(V)):?GLuint,
+ (<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- V>>)/binary>>).
+
+%% @spec (Index::integer(),Left::integer(),Bottom::integer(),Width::integer(),Height::integer()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorIndexe.xml">external</a> documentation.
+-spec scissorIndexed(integer(),integer(),integer(),integer(),integer()) -> ok.
+scissorIndexed(Index,Left,Bottom,Width,Height) ->
+ cast(5847, <<Index:?GLuint,Left:?GLint,Bottom:?GLint,Width:?GLsizei,Height:?GLsizei>>).
+
+%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorIndexe.xml">external</a> documentation.
+-spec scissorIndexedv(integer(),{integer(),integer(),integer(),integer()}) -> ok.
+scissorIndexedv(Index,{V1,V2,V3,V4}) ->
+ cast(5848, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+
+%% @spec (First::integer(),V::[{clamp(),clamp()}]) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRangeArrayv.xml">external</a> documentation.
+-spec depthRangeArrayv(integer(),[{clamp(),clamp()}]) -> ok.
+depthRangeArrayv(First,V) ->
+ cast(5849, <<First:?GLuint,0:32,(length(V)):?GLuint,0:32,
+ (<< <<V1:?GLclampd,V2:?GLclampd>> || {V1,V2} <- V>>)/binary>>).
+
+%% @spec (Index::integer(),N::clamp(),F::clamp()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRangeIndexe.xml">external</a> documentation.
+-spec depthRangeIndexed(integer(),clamp(),clamp()) -> ok.
+depthRangeIndexed(Index,N,F) ->
+ cast(5850, <<Index:?GLuint,0:32,N:?GLclampd,F:?GLclampd>>).
+
+%% @spec (Target::enum(),Index::integer()) -> [float()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFloati_v.xml">external</a> documentation.
+-spec getFloati_v(enum(),integer()) -> [float()].
+getFloati_v(Target,Index) ->
+ call(5851, <<Target:?GLenum,Index:?GLuint>>).
+
+%% @spec (Target::enum(),Index::integer()) -> [float()]
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetDoublei_v.xml">external</a> documentation.
+-spec getDoublei_v(enum(),integer()) -> [float()].
+getDoublei_v(Target,Index) ->
+ call(5852, <<Target:?GLenum,Index:?GLuint>>).
+
+%% @spec (Source::enum(),Type::enum(),Severity::enum(),Ids::[integer()],Enabled::0|1) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDebugMessageControlARB.xml">external</a> documentation.
+-spec debugMessageControlARB(enum(),enum(),enum(),[integer()],0|1) -> ok.
+debugMessageControlARB(Source,Type,Severity,Ids,Enabled) ->
+ cast(5853, <<Source:?GLenum,Type:?GLenum,Severity:?GLenum,(length(Ids)):?GLuint,
+ (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((length(Ids)) rem 2)*32),Enabled:?GLboolean>>).
+
+%% @spec (Source::enum(),Type::enum(),Id::integer(),Severity::enum(),Buf::string()) -> ok
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDebugMessageInsertARB.xml">external</a> documentation.
+-spec debugMessageInsertARB(enum(),enum(),integer(),enum(),string()) -> ok.
+debugMessageInsertARB(Source,Type,Id,Severity,Buf) ->
+ cast(5854, <<Source:?GLenum,Type:?GLenum,Id:?GLuint,Severity:?GLenum,(list_to_binary([Buf|[0]]))/binary,0:((8-((length(Buf)+ 1) rem 8)) rem 8)>>).
+
+%% @spec (Count::integer(),Bufsize::integer()) -> {integer(),Sources::[enum()],Types::[enum()],Ids::[integer()],Severities::[enum()],MessageLog::[string()]}
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetDebugMessageLogARB.xml">external</a> documentation.
+-spec getDebugMessageLogARB(integer(),integer()) -> {integer(),[enum()],[enum()],[integer()],[enum()],[string()]}.
+getDebugMessageLogARB(Count,Bufsize) ->
+ call(5855, <<Count:?GLuint,Bufsize:?GLsizei>>).
+
+%% @spec () -> enum()
+%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetGraphicsResetStatusARB.xml">external</a> documentation.
+-spec getGraphicsResetStatusARB() -> enum().
+getGraphicsResetStatusARB() ->
+ call(5856, <<>>).
%% @spec () -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glResizeBuffersMESA.xml">external</a> documentation.
+-spec resizeBuffersMESA() -> ok.
resizeBuffersMESA() ->
- wxe_util:cast(5676, <<>>).
+ cast(5857, <<>>).
%% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos4dMESA.xml">external</a> documentation.
+-spec windowPos4dMESA(float(),float(),float(),float()) -> ok.
windowPos4dMESA(X,Y,Z,W) ->
- wxe_util:cast(5677, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5858, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv windowPos4dMESA(X,Y,Z,W)
+-spec windowPos4dvMESA({float(),float(),float(),float()}) -> ok.
windowPos4dvMESA({X,Y,Z,W}) -> windowPos4dMESA(X,Y,Z,W).
%% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos4fMESA.xml">external</a> documentation.
+-spec windowPos4fMESA(float(),float(),float(),float()) -> ok.
windowPos4fMESA(X,Y,Z,W) ->
- wxe_util:cast(5678, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5859, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv windowPos4fMESA(X,Y,Z,W)
+-spec windowPos4fvMESA({float(),float(),float(),float()}) -> ok.
windowPos4fvMESA({X,Y,Z,W}) -> windowPos4fMESA(X,Y,Z,W).
%% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos4iMESA.xml">external</a> documentation.
+-spec windowPos4iMESA(integer(),integer(),integer(),integer()) -> ok.
windowPos4iMESA(X,Y,Z,W) ->
- wxe_util:cast(5679, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
+ cast(5860, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv windowPos4iMESA(X,Y,Z,W)
+-spec windowPos4ivMESA({integer(),integer(),integer(),integer()}) -> ok.
windowPos4ivMESA({X,Y,Z,W}) -> windowPos4iMESA(X,Y,Z,W).
%% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos4sMESA.xml">external</a> documentation.
+-spec windowPos4sMESA(integer(),integer(),integer(),integer()) -> ok.
windowPos4sMESA(X,Y,Z,W) ->
- wxe_util:cast(5680, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
+ cast(5861, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
%% @spec ({X,Y,Z,W}) -> ok
%% @equiv windowPos4sMESA(X,Y,Z,W)
+-spec windowPos4svMESA({integer(),integer(),integer(),integer()}) -> ok.
windowPos4svMESA({X,Y,Z,W}) -> windowPos4sMESA(X,Y,Z,W).
%% @spec (Zmin::clamp(),Zmax::clamp()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthBoundsEXT.xml">external</a> documentation.
+-spec depthBoundsEXT(clamp(),clamp()) -> ok.
depthBoundsEXT(Zmin,Zmax) ->
- wxe_util:cast(5681, <<Zmin:?GLclampd,Zmax:?GLclampd>>).
+ cast(5862, <<Zmin:?GLclampd,Zmax:?GLclampd>>).
%% @spec (StencilTagBits::integer(),StencilClearTag::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilClearTagEXT.xml">external</a> documentation.
+-spec stencilClearTagEXT(integer(),integer()) -> ok.
stencilClearTagEXT(StencilTagBits,StencilClearTag) ->
- wxe_util:cast(5682, <<StencilTagBits:?GLsizei,StencilClearTag:?GLuint>>).
+ cast(5863, <<StencilTagBits:?GLsizei,StencilClearTag:?GLuint>>).
diff --git a/lib/wx/src/gen/gl_debug.hrl b/lib/wx/src/gen/gl_debug.hrl
deleted file mode 100644
index 0b8086f24e..0000000000
--- a/lib/wx/src/gen/gl_debug.hrl
+++ /dev/null
@@ -1,697 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%% This file is generated DO NOT EDIT
-
-gldebug_table() ->
-[
- {5037, {gl, accum, 0}},
- {5038, {gl, alphaFunc, 0}},
- {5039, {gl, areTexturesResident, 0}},
- {5040, {gl, arrayElement, 0}},
- {5041, {gl, 'begin', 0}},
- {5042, {gl, bindTexture, 0}},
- {5043, {gl, bitmap, 0}},
- {5044, {gl, bitmap, 0}},
- {5045, {gl, blendFunc, 0}},
- {5046, {gl, callList, 0}},
- {5047, {gl, callLists, 0}},
- {5048, {gl, clear, 0}},
- {5049, {gl, clearAccum, 0}},
- {5050, {gl, clearColor, 0}},
- {5051, {gl, clearDepth, 0}},
- {5052, {gl, clearIndex, 0}},
- {5053, {gl, clearStencil, 0}},
- {5054, {gl, clipPlane, 0}},
- {5055, {gl, color3b, 0}},
- {5056, {gl, color3d, 0}},
- {5057, {gl, color3f, 0}},
- {5058, {gl, color3i, 0}},
- {5059, {gl, color3s, 0}},
- {5060, {gl, color3ub, 0}},
- {5061, {gl, color3ui, 0}},
- {5062, {gl, color3us, 0}},
- {5063, {gl, color4b, 0}},
- {5064, {gl, color4d, 0}},
- {5065, {gl, color4f, 0}},
- {5066, {gl, color4i, 0}},
- {5067, {gl, color4s, 0}},
- {5068, {gl, color4ub, 0}},
- {5069, {gl, color4ui, 0}},
- {5070, {gl, color4us, 0}},
- {5071, {gl, colorMask, 0}},
- {5072, {gl, colorMaterial, 0}},
- {5073, {gl, colorPointer, 0}},
- {5074, {gl, colorPointer, 0}},
- {5075, {gl, copyPixels, 0}},
- {5076, {gl, copyTexImage1D, 0}},
- {5077, {gl, copyTexImage2D, 0}},
- {5078, {gl, copyTexSubImage1D, 0}},
- {5079, {gl, copyTexSubImage2D, 0}},
- {5080, {gl, cullFace, 0}},
- {5081, {gl, deleteLists, 0}},
- {5082, {gl, deleteTextures, 0}},
- {5083, {gl, depthFunc, 0}},
- {5084, {gl, depthMask, 0}},
- {5085, {gl, depthRange, 0}},
- {5086, {gl, disable, 0}},
- {5087, {gl, disableClientState, 0}},
- {5088, {gl, drawArrays, 0}},
- {5089, {gl, drawBuffer, 0}},
- {5090, {gl, drawElements, 0}},
- {5091, {gl, drawElements, 0}},
- {5092, {gl, drawPixels, 0}},
- {5093, {gl, drawPixels, 0}},
- {5094, {gl, edgeFlag, 0}},
- {5095, {gl, edgeFlagPointer, 0}},
- {5096, {gl, edgeFlagPointer, 0}},
- {5097, {gl, enable, 0}},
- {5098, {gl, enableClientState, 0}},
- {5099, {gl, 'end', 0}},
- {5100, {gl, endList, 0}},
- {5101, {gl, evalCoord1d, 0}},
- {5102, {gl, evalCoord1f, 0}},
- {5103, {gl, evalCoord2d, 0}},
- {5104, {gl, evalCoord2f, 0}},
- {5105, {gl, evalMesh1, 0}},
- {5106, {gl, evalMesh2, 0}},
- {5107, {gl, evalPoint1, 0}},
- {5108, {gl, evalPoint2, 0}},
- {5109, {gl, feedbackBuffer, 0}},
- {5110, {gl, finish, 0}},
- {5111, {gl, flush, 0}},
- {5112, {gl, fogf, 0}},
- {5113, {gl, fogfv, 0}},
- {5114, {gl, fogi, 0}},
- {5115, {gl, fogiv, 0}},
- {5116, {gl, frontFace, 0}},
- {5117, {gl, frustum, 0}},
- {5118, {gl, genLists, 0}},
- {5119, {gl, genTextures, 0}},
- {5120, {gl, getBooleanv, 0}},
- {5121, {gl, getClipPlane, 0}},
- {5122, {gl, getDoublev, 0}},
- {5123, {gl, getError, 0}},
- {5124, {gl, getFloatv, 0}},
- {5125, {gl, getIntegerv, 0}},
- {5126, {gl, getLightfv, 0}},
- {5127, {gl, getLightiv, 0}},
- {5128, {gl, getMapdv, 0}},
- {5129, {gl, getMapfv, 0}},
- {5130, {gl, getMapiv, 0}},
- {5131, {gl, getMaterialfv, 0}},
- {5132, {gl, getMaterialiv, 0}},
- {5133, {gl, getPixelMapfv, 0}},
- {5134, {gl, getPixelMapuiv, 0}},
- {5135, {gl, getPixelMapusv, 0}},
- {5136, {gl, getPolygonStipple, 0}},
- {5137, {gl, getString, 0}},
- {5138, {gl, getTexEnvfv, 0}},
- {5139, {gl, getTexEnviv, 0}},
- {5140, {gl, getTexGendv, 0}},
- {5141, {gl, getTexGenfv, 0}},
- {5142, {gl, getTexGeniv, 0}},
- {5143, {gl, getTexImage, 0}},
- {5144, {gl, getTexLevelParameterfv, 0}},
- {5145, {gl, getTexLevelParameteriv, 0}},
- {5146, {gl, getTexParameterfv, 0}},
- {5147, {gl, getTexParameteriv, 0}},
- {5148, {gl, hint, 0}},
- {5149, {gl, indexMask, 0}},
- {5150, {gl, indexPointer, 0}},
- {5151, {gl, indexPointer, 0}},
- {5152, {gl, indexd, 0}},
- {5153, {gl, indexf, 0}},
- {5154, {gl, indexi, 0}},
- {5155, {gl, indexs, 0}},
- {5156, {gl, indexub, 0}},
- {5157, {gl, initNames, 0}},
- {5158, {gl, interleavedArrays, 0}},
- {5159, {gl, interleavedArrays, 0}},
- {5160, {gl, isEnabled, 0}},
- {5161, {gl, isList, 0}},
- {5162, {gl, isTexture, 0}},
- {5163, {gl, lightModelf, 0}},
- {5164, {gl, lightModelfv, 0}},
- {5165, {gl, lightModeli, 0}},
- {5166, {gl, lightModeliv, 0}},
- {5167, {gl, lightf, 0}},
- {5168, {gl, lightfv, 0}},
- {5169, {gl, lighti, 0}},
- {5170, {gl, lightiv, 0}},
- {5171, {gl, lineStipple, 0}},
- {5172, {gl, lineWidth, 0}},
- {5173, {gl, listBase, 0}},
- {5174, {gl, loadIdentity, 0}},
- {5175, {gl, loadMatrixd, 0}},
- {5176, {gl, loadMatrixf, 0}},
- {5177, {gl, loadName, 0}},
- {5178, {gl, logicOp, 0}},
- {5179, {gl, map1d, 0}},
- {5180, {gl, map1f, 0}},
- {5181, {gl, map2d, 0}},
- {5182, {gl, map2f, 0}},
- {5183, {gl, mapGrid1d, 0}},
- {5184, {gl, mapGrid1f, 0}},
- {5185, {gl, mapGrid2d, 0}},
- {5186, {gl, mapGrid2f, 0}},
- {5187, {gl, materialf, 0}},
- {5188, {gl, materialfv, 0}},
- {5189, {gl, materiali, 0}},
- {5190, {gl, materialiv, 0}},
- {5191, {gl, matrixMode, 0}},
- {5192, {gl, multMatrixd, 0}},
- {5193, {gl, multMatrixf, 0}},
- {5194, {gl, newList, 0}},
- {5195, {gl, normal3b, 0}},
- {5196, {gl, normal3d, 0}},
- {5197, {gl, normal3f, 0}},
- {5198, {gl, normal3i, 0}},
- {5199, {gl, normal3s, 0}},
- {5200, {gl, normalPointer, 0}},
- {5201, {gl, normalPointer, 0}},
- {5202, {gl, ortho, 0}},
- {5203, {gl, passThrough, 0}},
- {5204, {gl, pixelMapfv, 0}},
- {5205, {gl, pixelMapuiv, 0}},
- {5206, {gl, pixelMapusv, 0}},
- {5207, {gl, pixelStoref, 0}},
- {5208, {gl, pixelStorei, 0}},
- {5209, {gl, pixelTransferf, 0}},
- {5210, {gl, pixelTransferi, 0}},
- {5211, {gl, pixelZoom, 0}},
- {5212, {gl, pointSize, 0}},
- {5213, {gl, polygonMode, 0}},
- {5214, {gl, polygonOffset, 0}},
- {5215, {gl, polygonStipple, 0}},
- {5216, {gl, popAttrib, 0}},
- {5217, {gl, popClientAttrib, 0}},
- {5218, {gl, popMatrix, 0}},
- {5219, {gl, popName, 0}},
- {5220, {gl, prioritizeTextures, 0}},
- {5221, {gl, pushAttrib, 0}},
- {5222, {gl, pushClientAttrib, 0}},
- {5223, {gl, pushMatrix, 0}},
- {5224, {gl, pushName, 0}},
- {5225, {gl, rasterPos2d, 0}},
- {5226, {gl, rasterPos2f, 0}},
- {5227, {gl, rasterPos2i, 0}},
- {5228, {gl, rasterPos2s, 0}},
- {5229, {gl, rasterPos3d, 0}},
- {5230, {gl, rasterPos3f, 0}},
- {5231, {gl, rasterPos3i, 0}},
- {5232, {gl, rasterPos3s, 0}},
- {5233, {gl, rasterPos4d, 0}},
- {5234, {gl, rasterPos4f, 0}},
- {5235, {gl, rasterPos4i, 0}},
- {5236, {gl, rasterPos4s, 0}},
- {5237, {gl, readBuffer, 0}},
- {5238, {gl, readPixels, 0}},
- {5239, {gl, rectd, 0}},
- {5240, {gl, rectdv, 0}},
- {5241, {gl, rectf, 0}},
- {5242, {gl, rectfv, 0}},
- {5243, {gl, recti, 0}},
- {5244, {gl, rectiv, 0}},
- {5245, {gl, rects, 0}},
- {5246, {gl, rectsv, 0}},
- {5247, {gl, renderMode, 0}},
- {5248, {gl, rotated, 0}},
- {5249, {gl, rotatef, 0}},
- {5250, {gl, scaled, 0}},
- {5251, {gl, scalef, 0}},
- {5252, {gl, scissor, 0}},
- {5253, {gl, selectBuffer, 0}},
- {5254, {gl, shadeModel, 0}},
- {5255, {gl, stencilFunc, 0}},
- {5256, {gl, stencilMask, 0}},
- {5257, {gl, stencilOp, 0}},
- {5258, {gl, texCoord1d, 0}},
- {5259, {gl, texCoord1f, 0}},
- {5260, {gl, texCoord1i, 0}},
- {5261, {gl, texCoord1s, 0}},
- {5262, {gl, texCoord2d, 0}},
- {5263, {gl, texCoord2f, 0}},
- {5264, {gl, texCoord2i, 0}},
- {5265, {gl, texCoord2s, 0}},
- {5266, {gl, texCoord3d, 0}},
- {5267, {gl, texCoord3f, 0}},
- {5268, {gl, texCoord3i, 0}},
- {5269, {gl, texCoord3s, 0}},
- {5270, {gl, texCoord4d, 0}},
- {5271, {gl, texCoord4f, 0}},
- {5272, {gl, texCoord4i, 0}},
- {5273, {gl, texCoord4s, 0}},
- {5274, {gl, texCoordPointer, 0}},
- {5275, {gl, texCoordPointer, 0}},
- {5276, {gl, texEnvf, 0}},
- {5277, {gl, texEnvfv, 0}},
- {5278, {gl, texEnvi, 0}},
- {5279, {gl, texEnviv, 0}},
- {5280, {gl, texGend, 0}},
- {5281, {gl, texGendv, 0}},
- {5282, {gl, texGenf, 0}},
- {5283, {gl, texGenfv, 0}},
- {5284, {gl, texGeni, 0}},
- {5285, {gl, texGeniv, 0}},
- {5286, {gl, texImage1D, 0}},
- {5287, {gl, texImage1D, 0}},
- {5288, {gl, texImage2D, 0}},
- {5289, {gl, texImage2D, 0}},
- {5290, {gl, texParameterf, 0}},
- {5291, {gl, texParameterfv, 0}},
- {5292, {gl, texParameteri, 0}},
- {5293, {gl, texParameteriv, 0}},
- {5294, {gl, texSubImage1D, 0}},
- {5295, {gl, texSubImage1D, 0}},
- {5296, {gl, texSubImage2D, 0}},
- {5297, {gl, texSubImage2D, 0}},
- {5298, {gl, translated, 0}},
- {5299, {gl, translatef, 0}},
- {5300, {gl, vertex2d, 0}},
- {5301, {gl, vertex2f, 0}},
- {5302, {gl, vertex2i, 0}},
- {5303, {gl, vertex2s, 0}},
- {5304, {gl, vertex3d, 0}},
- {5305, {gl, vertex3f, 0}},
- {5306, {gl, vertex3i, 0}},
- {5307, {gl, vertex3s, 0}},
- {5308, {gl, vertex4d, 0}},
- {5309, {gl, vertex4f, 0}},
- {5310, {gl, vertex4i, 0}},
- {5311, {gl, vertex4s, 0}},
- {5312, {gl, vertexPointer, 0}},
- {5313, {gl, vertexPointer, 0}},
- {5314, {gl, viewport, 0}},
- {5315, {gl, blendColor, 0}},
- {5316, {gl, blendEquation, 0}},
- {5317, {gl, drawRangeElements, 0}},
- {5318, {gl, drawRangeElements, 0}},
- {5319, {gl, texImage3D, 0}},
- {5320, {gl, texImage3D, 0}},
- {5321, {gl, texSubImage3D, 0}},
- {5322, {gl, texSubImage3D, 0}},
- {5323, {gl, copyTexSubImage3D, 0}},
- {5324, {gl, colorTable, 0}},
- {5325, {gl, colorTable, 0}},
- {5326, {gl, colorTableParameterfv, 0}},
- {5327, {gl, colorTableParameteriv, 0}},
- {5328, {gl, copyColorTable, 0}},
- {5329, {gl, getColorTable, 0}},
- {5330, {gl, getColorTableParameterfv, 0}},
- {5331, {gl, getColorTableParameteriv, 0}},
- {5332, {gl, colorSubTable, 0}},
- {5333, {gl, colorSubTable, 0}},
- {5334, {gl, copyColorSubTable, 0}},
- {5335, {gl, convolutionFilter1D, 0}},
- {5336, {gl, convolutionFilter1D, 0}},
- {5337, {gl, convolutionFilter2D, 0}},
- {5338, {gl, convolutionFilter2D, 0}},
- {5339, {gl, convolutionParameterf, 0}},
- {5340, {gl, convolutionParameteri, 0}},
- {5341, {gl, copyConvolutionFilter1D, 0}},
- {5342, {gl, copyConvolutionFilter2D, 0}},
- {5343, {gl, getConvolutionFilter, 0}},
- {5344, {gl, getConvolutionParameterfv, 0}},
- {5345, {gl, getConvolutionParameteriv, 0}},
- {5346, {gl, separableFilter2D, 0}},
- {5347, {gl, separableFilter2D, 0}},
- {5348, {gl, getHistogram, 0}},
- {5349, {gl, getHistogramParameterfv, 0}},
- {5350, {gl, getHistogramParameteriv, 0}},
- {5351, {gl, getMinmax, 0}},
- {5352, {gl, getMinmaxParameterfv, 0}},
- {5353, {gl, getMinmaxParameteriv, 0}},
- {5354, {gl, histogram, 0}},
- {5355, {gl, minmax, 0}},
- {5356, {gl, resetHistogram, 0}},
- {5357, {gl, resetMinmax, 0}},
- {5358, {gl, activeTexture, 0}},
- {5359, {gl, sampleCoverage, 0}},
- {5360, {gl, compressedTexImage3D, 0}},
- {5361, {gl, compressedTexImage3D, 0}},
- {5362, {gl, compressedTexImage2D, 0}},
- {5363, {gl, compressedTexImage2D, 0}},
- {5364, {gl, compressedTexImage1D, 0}},
- {5365, {gl, compressedTexImage1D, 0}},
- {5366, {gl, compressedTexSubImage3D, 0}},
- {5367, {gl, compressedTexSubImage3D, 0}},
- {5368, {gl, compressedTexSubImage2D, 0}},
- {5369, {gl, compressedTexSubImage2D, 0}},
- {5370, {gl, compressedTexSubImage1D, 0}},
- {5371, {gl, compressedTexSubImage1D, 0}},
- {5372, {gl, getCompressedTexImage, 0}},
- {5373, {gl, clientActiveTexture, 0}},
- {5374, {gl, multiTexCoord1d, 0}},
- {5375, {gl, multiTexCoord1f, 0}},
- {5376, {gl, multiTexCoord1i, 0}},
- {5377, {gl, multiTexCoord1s, 0}},
- {5378, {gl, multiTexCoord2d, 0}},
- {5379, {gl, multiTexCoord2f, 0}},
- {5380, {gl, multiTexCoord2i, 0}},
- {5381, {gl, multiTexCoord2s, 0}},
- {5382, {gl, multiTexCoord3d, 0}},
- {5383, {gl, multiTexCoord3f, 0}},
- {5384, {gl, multiTexCoord3i, 0}},
- {5385, {gl, multiTexCoord3s, 0}},
- {5386, {gl, multiTexCoord4d, 0}},
- {5387, {gl, multiTexCoord4f, 0}},
- {5388, {gl, multiTexCoord4i, 0}},
- {5389, {gl, multiTexCoord4s, 0}},
- {5390, {gl, loadTransposeMatrixf, 0}},
- {5391, {gl, loadTransposeMatrixd, 0}},
- {5392, {gl, multTransposeMatrixf, 0}},
- {5393, {gl, multTransposeMatrixd, 0}},
- {5394, {gl, blendFuncSeparate, 0}},
- {5395, {gl, multiDrawArrays, 0}},
- {5396, {gl, pointParameterf, 0}},
- {5397, {gl, pointParameterfv, 0}},
- {5398, {gl, pointParameteri, 0}},
- {5399, {gl, pointParameteriv, 0}},
- {5400, {gl, fogCoordf, 0}},
- {5401, {gl, fogCoordd, 0}},
- {5402, {gl, fogCoordPointer, 0}},
- {5403, {gl, fogCoordPointer, 0}},
- {5404, {gl, secondaryColor3b, 0}},
- {5405, {gl, secondaryColor3d, 0}},
- {5406, {gl, secondaryColor3f, 0}},
- {5407, {gl, secondaryColor3i, 0}},
- {5408, {gl, secondaryColor3s, 0}},
- {5409, {gl, secondaryColor3ub, 0}},
- {5410, {gl, secondaryColor3ui, 0}},
- {5411, {gl, secondaryColor3us, 0}},
- {5412, {gl, secondaryColorPointer, 0}},
- {5413, {gl, secondaryColorPointer, 0}},
- {5414, {gl, windowPos2d, 0}},
- {5415, {gl, windowPos2f, 0}},
- {5416, {gl, windowPos2i, 0}},
- {5417, {gl, windowPos2s, 0}},
- {5418, {gl, windowPos3d, 0}},
- {5419, {gl, windowPos3f, 0}},
- {5420, {gl, windowPos3i, 0}},
- {5421, {gl, windowPos3s, 0}},
- {5422, {gl, genQueries, 0}},
- {5423, {gl, deleteQueries, 0}},
- {5424, {gl, isQuery, 0}},
- {5425, {gl, beginQuery, 0}},
- {5426, {gl, endQuery, 0}},
- {5427, {gl, getQueryiv, 0}},
- {5428, {gl, getQueryObjectiv, 0}},
- {5429, {gl, getQueryObjectuiv, 0}},
- {5430, {gl, bindBuffer, 0}},
- {5431, {gl, deleteBuffers, 0}},
- {5432, {gl, genBuffers, 0}},
- {5433, {gl, isBuffer, 0}},
- {5434, {gl, bufferData, 0}},
- {5435, {gl, bufferData, 0}},
- {5436, {gl, bufferSubData, 0}},
- {5437, {gl, bufferSubData, 0}},
- {5438, {gl, getBufferSubData, 0}},
- {5439, {gl, getBufferParameteriv, 0}},
- {5440, {gl, blendEquationSeparate, 0}},
- {5441, {gl, drawBuffers, 0}},
- {5442, {gl, stencilOpSeparate, 0}},
- {5443, {gl, stencilFuncSeparate, 0}},
- {5444, {gl, stencilMaskSeparate, 0}},
- {5445, {gl, attachShader, 0}},
- {5446, {gl, bindAttribLocation, 0}},
- {5447, {gl, compileShader, 0}},
- {5448, {gl, createProgram, 0}},
- {5449, {gl, createShader, 0}},
- {5450, {gl, deleteProgram, 0}},
- {5451, {gl, deleteShader, 0}},
- {5452, {gl, detachShader, 0}},
- {5453, {gl, disableVertexAttribArray, 0}},
- {5454, {gl, enableVertexAttribArray, 0}},
- {5455, {gl, getActiveAttrib, 0}},
- {5456, {gl, getActiveUniform, 0}},
- {5457, {gl, getAttachedShaders, 0}},
- {5458, {gl, getAttribLocation, 0}},
- {5459, {gl, getProgramiv, 0}},
- {5460, {gl, getProgramInfoLog, 0}},
- {5461, {gl, getShaderiv, 0}},
- {5462, {gl, getShaderInfoLog, 0}},
- {5463, {gl, getShaderSource, 0}},
- {5464, {gl, getUniformLocation, 0}},
- {5465, {gl, getUniformfv, 0}},
- {5466, {gl, getUniformiv, 0}},
- {5467, {gl, getVertexAttribdv, 0}},
- {5468, {gl, getVertexAttribfv, 0}},
- {5469, {gl, getVertexAttribiv, 0}},
- {5470, {gl, isProgram, 0}},
- {5471, {gl, isShader, 0}},
- {5472, {gl, linkProgram, 0}},
- {5473, {gl, shaderSource, 0}},
- {5474, {gl, useProgram, 0}},
- {5475, {gl, uniform1f, 0}},
- {5476, {gl, uniform2f, 0}},
- {5477, {gl, uniform3f, 0}},
- {5478, {gl, uniform4f, 0}},
- {5479, {gl, uniform1i, 0}},
- {5480, {gl, uniform2i, 0}},
- {5481, {gl, uniform3i, 0}},
- {5482, {gl, uniform4i, 0}},
- {5483, {gl, uniform1fv, 0}},
- {5484, {gl, uniform2fv, 0}},
- {5485, {gl, uniform3fv, 0}},
- {5486, {gl, uniform4fv, 0}},
- {5487, {gl, uniform1iv, 0}},
- {5488, {gl, uniform2iv, 0}},
- {5489, {gl, uniform3iv, 0}},
- {5490, {gl, uniform4iv, 0}},
- {5491, {gl, uniformMatrix2fv, 0}},
- {5492, {gl, uniformMatrix3fv, 0}},
- {5493, {gl, uniformMatrix4fv, 0}},
- {5494, {gl, validateProgram, 0}},
- {5495, {gl, vertexAttrib1d, 0}},
- {5496, {gl, vertexAttrib1f, 0}},
- {5497, {gl, vertexAttrib1s, 0}},
- {5498, {gl, vertexAttrib2d, 0}},
- {5499, {gl, vertexAttrib2f, 0}},
- {5500, {gl, vertexAttrib2s, 0}},
- {5501, {gl, vertexAttrib3d, 0}},
- {5502, {gl, vertexAttrib3f, 0}},
- {5503, {gl, vertexAttrib3s, 0}},
- {5504, {gl, vertexAttrib4Nbv, 0}},
- {5505, {gl, vertexAttrib4Niv, 0}},
- {5506, {gl, vertexAttrib4Nsv, 0}},
- {5507, {gl, vertexAttrib4Nub, 0}},
- {5508, {gl, vertexAttrib4Nuiv, 0}},
- {5509, {gl, vertexAttrib4Nusv, 0}},
- {5510, {gl, vertexAttrib4bv, 0}},
- {5511, {gl, vertexAttrib4d, 0}},
- {5512, {gl, vertexAttrib4f, 0}},
- {5513, {gl, vertexAttrib4iv, 0}},
- {5514, {gl, vertexAttrib4s, 0}},
- {5515, {gl, vertexAttrib4ubv, 0}},
- {5516, {gl, vertexAttrib4uiv, 0}},
- {5517, {gl, vertexAttrib4usv, 0}},
- {5518, {gl, vertexAttribPointer, 0}},
- {5519, {gl, vertexAttribPointer, 0}},
- {5520, {gl, uniformMatrix2x3fv, 0}},
- {5521, {gl, uniformMatrix3x2fv, 0}},
- {5522, {gl, uniformMatrix2x4fv, 0}},
- {5523, {gl, uniformMatrix4x2fv, 0}},
- {5524, {gl, uniformMatrix3x4fv, 0}},
- {5525, {gl, uniformMatrix4x3fv, 0}},
- {5526, {gl, colorMaski, 0}},
- {5527, {gl, getBooleani_v, 0}},
- {5528, {gl, getIntegeri_v, 0}},
- {5529, {gl, enablei, 0}},
- {5530, {gl, disablei, 0}},
- {5531, {gl, isEnabledi, 0}},
- {5532, {gl, beginTransformFeedback, 0}},
- {5533, {gl, endTransformFeedback, 0}},
- {5534, {gl, bindBufferRange, 0}},
- {5535, {gl, bindBufferBase, 0}},
- {5536, {gl, transformFeedbackVaryings, 0}},
- {5537, {gl, getTransformFeedbackVarying, 0}},
- {5538, {gl, clampColor, 0}},
- {5539, {gl, beginConditionalRender, 0}},
- {5540, {gl, endConditionalRender, 0}},
- {5541, {gl, vertexAttribIPointer, 0}},
- {5542, {gl, vertexAttribIPointer, 0}},
- {5543, {gl, getVertexAttribIiv, 0}},
- {5544, {gl, getVertexAttribIuiv, 0}},
- {5545, {gl, getUniformuiv, 0}},
- {5546, {gl, bindFragDataLocation, 0}},
- {5547, {gl, getFragDataLocation, 0}},
- {5548, {gl, uniform1ui, 0}},
- {5549, {gl, uniform2ui, 0}},
- {5550, {gl, uniform3ui, 0}},
- {5551, {gl, uniform4ui, 0}},
- {5552, {gl, uniform1uiv, 0}},
- {5553, {gl, uniform2uiv, 0}},
- {5554, {gl, uniform3uiv, 0}},
- {5555, {gl, uniform4uiv, 0}},
- {5556, {gl, texParameterIiv, 0}},
- {5557, {gl, texParameterIuiv, 0}},
- {5558, {gl, getTexParameterIiv, 0}},
- {5559, {gl, getTexParameterIuiv, 0}},
- {5560, {gl, clearBufferiv, 0}},
- {5561, {gl, clearBufferuiv, 0}},
- {5562, {gl, clearBufferfv, 0}},
- {5563, {gl, clearBufferfi, 0}},
- {5564, {gl, getStringi, 0}},
- {5565, {gl, vertexAttribI1i, 0}},
- {5566, {gl, vertexAttribI2i, 0}},
- {5567, {gl, vertexAttribI3i, 0}},
- {5568, {gl, vertexAttribI4i, 0}},
- {5569, {gl, vertexAttribI1ui, 0}},
- {5570, {gl, vertexAttribI2ui, 0}},
- {5571, {gl, vertexAttribI3ui, 0}},
- {5572, {gl, vertexAttribI4ui, 0}},
- {5573, {gl, vertexAttribI4bv, 0}},
- {5574, {gl, vertexAttribI4sv, 0}},
- {5575, {gl, vertexAttribI4ubv, 0}},
- {5576, {gl, vertexAttribI4usv, 0}},
- {5577, {gl, drawArraysInstanced, 0}},
- {5578, {gl, drawElementsInstanced, 0}},
- {5579, {gl, drawElementsInstanced, 0}},
- {5580, {gl, texBuffer, 0}},
- {5581, {gl, primitiveRestartIndex, 0}},
- {5582, {gl, loadTransposeMatrixfARB, 0}},
- {5583, {gl, loadTransposeMatrixdARB, 0}},
- {5584, {gl, multTransposeMatrixfARB, 0}},
- {5585, {gl, multTransposeMatrixdARB, 0}},
- {5586, {gl, weightbvARB, 0}},
- {5587, {gl, weightsvARB, 0}},
- {5588, {gl, weightivARB, 0}},
- {5589, {gl, weightfvARB, 0}},
- {5590, {gl, weightdvARB, 0}},
- {5591, {gl, weightubvARB, 0}},
- {5592, {gl, weightusvARB, 0}},
- {5593, {gl, weightuivARB, 0}},
- {5594, {gl, vertexBlendARB, 0}},
- {5595, {gl, currentPaletteMatrixARB, 0}},
- {5596, {gl, matrixIndexubvARB, 0}},
- {5597, {gl, matrixIndexusvARB, 0}},
- {5598, {gl, matrixIndexuivARB, 0}},
- {5599, {gl, programStringARB, 0}},
- {5600, {gl, bindProgramARB, 0}},
- {5601, {gl, deleteProgramsARB, 0}},
- {5602, {gl, genProgramsARB, 0}},
- {5603, {gl, programEnvParameter4dARB, 0}},
- {5604, {gl, programEnvParameter4dvARB, 0}},
- {5605, {gl, programEnvParameter4fARB, 0}},
- {5606, {gl, programEnvParameter4fvARB, 0}},
- {5607, {gl, programLocalParameter4dARB, 0}},
- {5608, {gl, programLocalParameter4dvARB, 0}},
- {5609, {gl, programLocalParameter4fARB, 0}},
- {5610, {gl, programLocalParameter4fvARB, 0}},
- {5611, {gl, getProgramEnvParameterdvARB, 0}},
- {5612, {gl, getProgramEnvParameterfvARB, 0}},
- {5613, {gl, getProgramLocalParameterdvARB, 0}},
- {5614, {gl, getProgramLocalParameterfvARB, 0}},
- {5615, {gl, getProgramStringARB, 0}},
- {5616, {gl, deleteObjectARB, 0}},
- {5617, {gl, getHandleARB, 0}},
- {5618, {gl, detachObjectARB, 0}},
- {5619, {gl, createShaderObjectARB, 0}},
- {5620, {gl, shaderSourceARB, 0}},
- {5621, {gl, compileShaderARB, 0}},
- {5622, {gl, createProgramObjectARB, 0}},
- {5623, {gl, attachObjectARB, 0}},
- {5624, {gl, linkProgramARB, 0}},
- {5625, {gl, useProgramObjectARB, 0}},
- {5626, {gl, validateProgramARB, 0}},
- {5627, {gl, getObjectParameterfvARB, 0}},
- {5628, {gl, getObjectParameterivARB, 0}},
- {5629, {gl, getInfoLogARB, 0}},
- {5630, {gl, getAttachedObjectsARB, 0}},
- {5631, {gl, getUniformLocationARB, 0}},
- {5632, {gl, getActiveUniformARB, 0}},
- {5633, {gl, getUniformfvARB, 0}},
- {5634, {gl, getUniformivARB, 0}},
- {5635, {gl, getShaderSourceARB, 0}},
- {5636, {gl, bindAttribLocationARB, 0}},
- {5637, {gl, getActiveAttribARB, 0}},
- {5638, {gl, getAttribLocationARB, 0}},
- {5639, {gl, isRenderbuffer, 0}},
- {5640, {gl, bindRenderbuffer, 0}},
- {5641, {gl, deleteRenderbuffers, 0}},
- {5642, {gl, genRenderbuffers, 0}},
- {5643, {gl, renderbufferStorage, 0}},
- {5644, {gl, getRenderbufferParameteriv, 0}},
- {5645, {gl, isFramebuffer, 0}},
- {5646, {gl, bindFramebuffer, 0}},
- {5647, {gl, deleteFramebuffers, 0}},
- {5648, {gl, genFramebuffers, 0}},
- {5649, {gl, checkFramebufferStatus, 0}},
- {5650, {gl, framebufferTexture1D, 0}},
- {5651, {gl, framebufferTexture2D, 0}},
- {5652, {gl, framebufferTexture3D, 0}},
- {5653, {gl, framebufferRenderbuffer, 0}},
- {5654, {gl, getFramebufferAttachmentParameteriv, 0}},
- {5655, {gl, generateMipmap, 0}},
- {5656, {gl, blitFramebuffer, 0}},
- {5657, {gl, renderbufferStorageMultisample, 0}},
- {5658, {gl, framebufferTextureLayer, 0}},
- {5659, {gl, programParameteriARB, 0}},
- {5660, {gl, framebufferTextureARB, 0}},
- {5661, {gl, framebufferTextureFaceARB, 0}},
- {5662, {gl, vertexAttribDivisorARB, 0}},
- {5663, {gl, flushMappedBufferRange, 0}},
- {5664, {gl, bindVertexArray, 0}},
- {5665, {gl, deleteVertexArrays, 0}},
- {5666, {gl, genVertexArrays, 0}},
- {5667, {gl, isVertexArray, 0}},
- {5668, {gl, getUniformIndices, 0}},
- {5669, {gl, getActiveUniformsiv, 0}},
- {5670, {gl, getActiveUniformName, 0}},
- {5671, {gl, getUniformBlockIndex, 0}},
- {5672, {gl, getActiveUniformBlockiv, 0}},
- {5673, {gl, getActiveUniformBlockName, 0}},
- {5674, {gl, uniformBlockBinding, 0}},
- {5675, {gl, copyBufferSubData, 0}},
- {5676, {gl, resizeBuffersMESA, 0}},
- {5677, {gl, windowPos4dMESA, 0}},
- {5678, {gl, windowPos4fMESA, 0}},
- {5679, {gl, windowPos4iMESA, 0}},
- {5680, {gl, windowPos4sMESA, 0}},
- {5681, {gl, depthBoundsEXT, 0}},
- {5682, {gl, stencilClearTagEXT, 0}},
- {5010, {glu, build1DMipmapLevels, 0}},
- {5011, {glu, build1DMipmaps, 0}},
- {5012, {glu, build2DMipmapLevels, 0}},
- {5013, {glu, build2DMipmaps, 0}},
- {5014, {glu, build3DMipmapLevels, 0}},
- {5015, {glu, build3DMipmaps, 0}},
- {5016, {glu, checkExtension, 0}},
- {5017, {glu, cylinder, 0}},
- {5018, {glu, deleteQuadric, 0}},
- {5019, {glu, disk, 0}},
- {5020, {glu, errorString, 0}},
- {5021, {glu, getString, 0}},
- {5022, {glu, lookAt, 0}},
- {5023, {glu, newQuadric, 0}},
- {5024, {glu, ortho2D, 0}},
- {5025, {glu, partialDisk, 0}},
- {5026, {glu, perspective, 0}},
- {5027, {glu, pickMatrix, 0}},
- {5028, {glu, project, 0}},
- {5029, {glu, quadricDrawStyle, 0}},
- {5030, {glu, quadricNormals, 0}},
- {5031, {glu, quadricOrientation, 0}},
- {5032, {glu, quadricTexture, 0}},
- {5033, {glu, scaleImage, 0}},
- {5034, {glu, sphere, 0}},
- {5035, {glu, unProject, 0}},
- {5036, {glu, unProject4, 0}},
- {-1, {mod, func, -1}}
-].
-
diff --git a/lib/wx/src/gen/glu.erl b/lib/wx/src/gen/glu.erl
index d410c4663d..c16f0cf125 100644
--- a/lib/wx/src/gen/glu.erl
+++ b/lib/wx/src/gen/glu.erl
@@ -25,14 +25,13 @@
%%
%% Booleans are represented by integers 0 and 1.
-%% @type wx_mem(). see wx.erl on memory allocation functions
+%% @type mem(). memory block
%% @type enum(). An integer defined in gl.hrl
%% @type offset(). An integer which is an offset in an array
%% @type clamp(). A float clamped between 0.0 - 1.0
-module(glu).
-compile(inline).
--include("wxe.hrl").
-define(GLenum,32/native-unsigned).
-define(GLboolean,8/native-unsigned).
-define(GLbitfield,32/native-unsigned).
@@ -51,6 +50,11 @@
-define(GLintptr,64/native-unsigned).
-define(GLUquadric,64/native-unsigned).
-define(GLhandleARB,64/native-unsigned).
+-define(GLsync,64/native-unsigned).
+-define(GLuint64,64/native-unsigned).
+-define(GLint64,64/native-signed).
+-type enum() :: non_neg_integer().
+-type mem() :: binary() | tuple().
-export([tesselate/2,build1DMipmapLevels/9,build1DMipmaps/6,build2DMipmapLevels/10,
build2DMipmaps/7,build3DMipmapLevels/11,build3DMipmaps/8,checkExtension/2,
@@ -59,7 +63,7 @@
quadricDrawStyle/2,quadricNormals/2,quadricOrientation/2,quadricTexture/2,
scaleImage/9,sphere/4,unProject/6,unProject4/9]).
-
+-import(gl, [call/2,cast/2,send_bin/1]).
%% API
%% @spec (Vec3, [Vec3]) -> {Triangles, VertexPos}
@@ -73,159 +77,184 @@
%% vertex positions, it starts with the vertices in Vs and
%% may contain newly created vertices in the end.
tesselate({Nx,Ny,Nz}, Vs) ->
- wxe_util:call(5000, <<(length(Vs)):32/native,0:32,
+ call(5000, <<(length(Vs)):32/native,0:32,
Nx:?GLdouble,Ny:?GLdouble,Nz:?GLdouble,
(<< <<Vx:?GLdouble,Vy:?GLdouble,Vz:?GLdouble >>
|| {Vx,Vy,Vz} <- Vs>>)/binary >>).
%% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Format::enum(),Type::enum(),Level::integer(),Base::integer(),Max::integer(),Data::binary()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild1DMipmapLevels.xml">external</a> documentation.
+-spec build1DMipmapLevels(enum(),integer(),integer(),enum(),enum(),integer(),integer(),integer(),binary()) -> integer().
build1DMipmapLevels(Target,InternalFormat,Width,Format,Type,Level,Base,Max,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:call(5010, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>).
+ send_bin(Data),
+ call(5010, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>).
%% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Format::enum(),Type::enum(),Data::binary()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild1DMipmaps.xml">external</a> documentation.
+-spec build1DMipmaps(enum(),integer(),integer(),enum(),enum(),binary()) -> integer().
build1DMipmaps(Target,InternalFormat,Width,Format,Type,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:call(5011, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Data),
+ call(5011, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>).
%% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Level::integer(),Base::integer(),Max::integer(),Data::binary()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild2DMipmapLevels.xml">external</a> documentation.
+-spec build2DMipmapLevels(enum(),integer(),integer(),integer(),enum(),enum(),integer(),integer(),integer(),binary()) -> integer().
build2DMipmapLevels(Target,InternalFormat,Width,Height,Format,Type,Level,Base,Max,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:call(5012, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>).
+ send_bin(Data),
+ call(5012, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>).
%% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Data::binary()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild2DMipmaps.xml">external</a> documentation.
+-spec build2DMipmaps(enum(),integer(),integer(),integer(),enum(),enum(),binary()) -> integer().
build2DMipmaps(Target,InternalFormat,Width,Height,Format,Type,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:call(5013, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Data),
+ call(5013, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>).
%% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),Type::enum(),Level::integer(),Base::integer(),Max::integer(),Data::binary()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild3DMipmapLevels.xml">external</a> documentation.
+-spec build3DMipmapLevels(enum(),integer(),integer(),integer(),integer(),enum(),enum(),integer(),integer(),integer(),binary()) -> integer().
build3DMipmapLevels(Target,InternalFormat,Width,Height,Depth,Format,Type,Level,Base,Max,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:call(5014, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>).
+ send_bin(Data),
+ call(5014, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>).
%% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),Type::enum(),Data::binary()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild3DMipmaps.xml">external</a> documentation.
+-spec build3DMipmaps(enum(),integer(),integer(),integer(),integer(),enum(),enum(),binary()) -> integer().
build3DMipmaps(Target,InternalFormat,Width,Height,Depth,Format,Type,Data) ->
- wxe_util:send_bin(Data),
- wxe_util:call(5015, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum>>).
+ send_bin(Data),
+ call(5015, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum>>).
-%% @spec (ExtName::[integer()],ExtString::[integer()]) -> 0|1
+%% @spec (ExtName::string(),ExtString::string()) -> 0|1
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluCheckExtension.xml">external</a> documentation.
+-spec checkExtension(string(),string()) -> 0|1.
checkExtension(ExtName,ExtString) ->
- wxe_util:call(5016, <<(length(ExtName)):?GLuint,
- (<< <<C:?GLubyte>> || C <- ExtName>>)/binary,0:((8-((length(ExtName)+ 4) rem 8)) rem 8),(length(ExtString)):?GLuint,
- (<< <<C:?GLubyte>> || C <- ExtString>>)/binary,0:((8-((length(ExtString)+ 4) rem 8)) rem 8)>>).
+ call(5016, <<(list_to_binary([ExtName|[0]]))/binary,0:((8-((length(ExtName)+ 1) rem 8)) rem 8),(list_to_binary([ExtString|[0]]))/binary,0:((8-((length(ExtString)+ 1) rem 8)) rem 8)>>).
%% @spec (Quad::integer(),Base::float(),Top::float(),Height::float(),Slices::integer(),Stacks::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluCylinder.xml">external</a> documentation.
+-spec cylinder(integer(),float(),float(),float(),integer(),integer()) -> ok.
cylinder(Quad,Base,Top,Height,Slices,Stacks) ->
- wxe_util:cast(5017, <<Quad:?GLUquadric,Base:?GLdouble,Top:?GLdouble,Height:?GLdouble,Slices:?GLint,Stacks:?GLint>>).
+ cast(5017, <<Quad:?GLUquadric,Base:?GLdouble,Top:?GLdouble,Height:?GLdouble,Slices:?GLint,Stacks:?GLint>>).
%% @spec (Quad::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluDeleteQuadric.xml">external</a> documentation.
+-spec deleteQuadric(integer()) -> ok.
deleteQuadric(Quad) ->
- wxe_util:cast(5018, <<Quad:?GLUquadric>>).
+ cast(5018, <<Quad:?GLUquadric>>).
%% @spec (Quad::integer(),Inner::float(),Outer::float(),Slices::integer(),Loops::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluDisk.xml">external</a> documentation.
+-spec disk(integer(),float(),float(),integer(),integer()) -> ok.
disk(Quad,Inner,Outer,Slices,Loops) ->
- wxe_util:cast(5019, <<Quad:?GLUquadric,Inner:?GLdouble,Outer:?GLdouble,Slices:?GLint,Loops:?GLint>>).
+ cast(5019, <<Quad:?GLUquadric,Inner:?GLdouble,Outer:?GLdouble,Slices:?GLint,Loops:?GLint>>).
%% @spec (Error::enum()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluErrorString.xml">external</a> documentation.
+-spec errorString(enum()) -> string().
errorString(Error) ->
- wxe_util:call(5020, <<Error:?GLenum>>).
+ call(5020, <<Error:?GLenum>>).
%% @spec (Name::enum()) -> string()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluGetString.xml">external</a> documentation.
+-spec getString(enum()) -> string().
getString(Name) ->
- wxe_util:call(5021, <<Name:?GLenum>>).
+ call(5021, <<Name:?GLenum>>).
%% @spec (EyeX::float(),EyeY::float(),EyeZ::float(),CenterX::float(),CenterY::float(),CenterZ::float(),UpX::float(),UpY::float(),UpZ::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluLookAt.xml">external</a> documentation.
+-spec lookAt(float(),float(),float(),float(),float(),float(),float(),float(),float()) -> ok.
lookAt(EyeX,EyeY,EyeZ,CenterX,CenterY,CenterZ,UpX,UpY,UpZ) ->
- wxe_util:cast(5022, <<EyeX:?GLdouble,EyeY:?GLdouble,EyeZ:?GLdouble,CenterX:?GLdouble,CenterY:?GLdouble,CenterZ:?GLdouble,UpX:?GLdouble,UpY:?GLdouble,UpZ:?GLdouble>>).
+ cast(5022, <<EyeX:?GLdouble,EyeY:?GLdouble,EyeZ:?GLdouble,CenterX:?GLdouble,CenterY:?GLdouble,CenterZ:?GLdouble,UpX:?GLdouble,UpY:?GLdouble,UpZ:?GLdouble>>).
%% @spec () -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluNewQuadric.xml">external</a> documentation.
+-spec newQuadric() -> integer().
newQuadric() ->
- wxe_util:call(5023, <<>>).
+ call(5023, <<>>).
%% @spec (Left::float(),Right::float(),Bottom::float(),Top::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluOrtho2D.xml">external</a> documentation.
+-spec ortho2D(float(),float(),float(),float()) -> ok.
ortho2D(Left,Right,Bottom,Top) ->
- wxe_util:cast(5024, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble>>).
+ cast(5024, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble>>).
%% @spec (Quad::integer(),Inner::float(),Outer::float(),Slices::integer(),Loops::integer(),Start::float(),Sweep::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluPartialDisk.xml">external</a> documentation.
+-spec partialDisk(integer(),float(),float(),integer(),integer(),float(),float()) -> ok.
partialDisk(Quad,Inner,Outer,Slices,Loops,Start,Sweep) ->
- wxe_util:cast(5025, <<Quad:?GLUquadric,Inner:?GLdouble,Outer:?GLdouble,Slices:?GLint,Loops:?GLint,Start:?GLdouble,Sweep:?GLdouble>>).
+ cast(5025, <<Quad:?GLUquadric,Inner:?GLdouble,Outer:?GLdouble,Slices:?GLint,Loops:?GLint,Start:?GLdouble,Sweep:?GLdouble>>).
%% @spec (Fovy::float(),Aspect::float(),ZNear::float(),ZFar::float()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml">external</a> documentation.
+-spec perspective(float(),float(),float(),float()) -> ok.
perspective(Fovy,Aspect,ZNear,ZFar) ->
- wxe_util:cast(5026, <<Fovy:?GLdouble,Aspect:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>).
+ cast(5026, <<Fovy:?GLdouble,Aspect:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>).
-%% @spec (X::float(),Y::float(),DelX::float(),DelY::float(),Viewport::{integer()}) -> ok
+%% @spec (X::float(),Y::float(),DelX::float(),DelY::float(),Viewport::{integer(),integer(),integer(),integer()}) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluPickMatrix.xml">external</a> documentation.
+-spec pickMatrix(float(),float(),float(),float(),{integer(),integer(),integer(),integer()}) -> ok.
pickMatrix(X,Y,DelX,DelY,{V1,V2,V3,V4}) ->
- wxe_util:cast(5027, <<X:?GLdouble,Y:?GLdouble,DelX:?GLdouble,DelY:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ cast(5027, <<X:?GLdouble,Y:?GLdouble,DelX:?GLdouble,DelY:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
-%% @spec (ObjX::float(),ObjY::float(),ObjZ::float(),Model::{float()},Proj::{float()},View::{integer()}) -> {integer(),WinX::float(),WinY::float(),WinZ::float()}
+%% @spec (ObjX::float(),ObjY::float(),ObjZ::float(),Model::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},Proj::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},View::{integer(),integer(),integer(),integer()}) -> {integer(),WinX::float(),WinY::float(),WinZ::float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluProject.xml">external</a> documentation.
+-spec project(float(),float(),float(),{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{integer(),integer(),integer(),integer()}) -> {integer(),float(),float(),float()}.
project(ObjX,ObjY,ObjZ,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16},{V1,V2,V3,V4}) ->
- wxe_util:call(5028, <<ObjX:?GLdouble,ObjY:?GLdouble,ObjZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>);
+ call(5028, <<ObjX:?GLdouble,ObjY:?GLdouble,ObjZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>);
project(ObjX,ObjY,ObjZ,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12},{V1,V2,V3,V4}) ->
- wxe_util:call(5028, <<ObjX:?GLdouble,ObjY:?GLdouble,ObjZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ call(5028, <<ObjX:?GLdouble,ObjY:?GLdouble,ObjZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
%% @spec (Quad::integer(),Draw::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluQuadricDrawStyle.xml">external</a> documentation.
+-spec quadricDrawStyle(integer(),enum()) -> ok.
quadricDrawStyle(Quad,Draw) ->
- wxe_util:cast(5029, <<Quad:?GLUquadric,Draw:?GLenum>>).
+ cast(5029, <<Quad:?GLUquadric,Draw:?GLenum>>).
%% @spec (Quad::integer(),Normal::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluQuadricNormals.xml">external</a> documentation.
+-spec quadricNormals(integer(),enum()) -> ok.
quadricNormals(Quad,Normal) ->
- wxe_util:cast(5030, <<Quad:?GLUquadric,Normal:?GLenum>>).
+ cast(5030, <<Quad:?GLUquadric,Normal:?GLenum>>).
%% @spec (Quad::integer(),Orientation::enum()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluQuadricOrientation.xml">external</a> documentation.
+-spec quadricOrientation(integer(),enum()) -> ok.
quadricOrientation(Quad,Orientation) ->
- wxe_util:cast(5031, <<Quad:?GLUquadric,Orientation:?GLenum>>).
+ cast(5031, <<Quad:?GLUquadric,Orientation:?GLenum>>).
%% @spec (Quad::integer(),Texture::0|1) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluQuadricTexture.xml">external</a> documentation.
+-spec quadricTexture(integer(),0|1) -> ok.
quadricTexture(Quad,Texture) ->
- wxe_util:cast(5032, <<Quad:?GLUquadric,Texture:?GLboolean>>).
+ cast(5032, <<Quad:?GLUquadric,Texture:?GLboolean>>).
-%% @spec (Format::enum(),WIn::integer(),HIn::integer(),TypeIn::enum(),DataIn::binary(),WOut::integer(),HOut::integer(),TypeOut::enum(),DataOut::wx:wx_mem()) -> integer()
+%% @spec (Format::enum(),WIn::integer(),HIn::integer(),TypeIn::enum(),DataIn::binary(),WOut::integer(),HOut::integer(),TypeOut::enum(),DataOut::mem()) -> integer()
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluScaleImage.xml">external</a> documentation.
+-spec scaleImage(enum(),integer(),integer(),enum(),binary(),integer(),integer(),enum(),mem()) -> integer().
scaleImage(Format,WIn,HIn,TypeIn,DataIn,WOut,HOut,TypeOut,DataOut) ->
- wxe_util:send_bin(DataIn),
- wxe_util:send_bin(DataOut#wx_mem.bin),
- wxe_util:call(5033, <<Format:?GLenum,WIn:?GLsizei,HIn:?GLsizei,TypeIn:?GLenum,WOut:?GLsizei,HOut:?GLsizei,TypeOut:?GLenum>>).
+ send_bin(DataIn),
+ send_bin(DataOut),
+ call(5033, <<Format:?GLenum,WIn:?GLsizei,HIn:?GLsizei,TypeIn:?GLenum,WOut:?GLsizei,HOut:?GLsizei,TypeOut:?GLenum>>).
%% @spec (Quad::integer(),Radius::float(),Slices::integer(),Stacks::integer()) -> ok
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluSphere.xml">external</a> documentation.
+-spec sphere(integer(),float(),integer(),integer()) -> ok.
sphere(Quad,Radius,Slices,Stacks) ->
- wxe_util:cast(5034, <<Quad:?GLUquadric,Radius:?GLdouble,Slices:?GLint,Stacks:?GLint>>).
+ cast(5034, <<Quad:?GLUquadric,Radius:?GLdouble,Slices:?GLint,Stacks:?GLint>>).
-%% @spec (WinX::float(),WinY::float(),WinZ::float(),Model::{float()},Proj::{float()},View::{integer()}) -> {integer(),ObjX::float(),ObjY::float(),ObjZ::float()}
+%% @spec (WinX::float(),WinY::float(),WinZ::float(),Model::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},Proj::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},View::{integer(),integer(),integer(),integer()}) -> {integer(),ObjX::float(),ObjY::float(),ObjZ::float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluUnProject.xml">external</a> documentation.
+-spec unProject(float(),float(),float(),{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{integer(),integer(),integer(),integer()}) -> {integer(),float(),float(),float()}.
unProject(WinX,WinY,WinZ,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16},{V1,V2,V3,V4}) ->
- wxe_util:call(5035, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>);
+ call(5035, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>);
unProject(WinX,WinY,WinZ,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12},{V1,V2,V3,V4}) ->
- wxe_util:call(5035, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ call(5035, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
-%% @spec (WinX::float(),WinY::float(),WinZ::float(),ClipW::float(),Model::{float()},Proj::{float()},View::{integer()},NearVal::float(),FarVal::float()) -> {integer(),ObjX::float(),ObjY::float(),ObjZ::float(),ObjW::float()}
+%% @spec (WinX::float(),WinY::float(),WinZ::float(),ClipW::float(),Model::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},Proj::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},View::{integer(),integer(),integer(),integer()},NearVal::float(),FarVal::float()) -> {integer(),ObjX::float(),ObjY::float(),ObjZ::float(),ObjW::float()}
%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluUnProject.xml">external</a> documentation.
+-spec unProject4(float(),float(),float(),float(),{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{integer(),integer(),integer(),integer()},float(),float()) -> {integer(),float(),float(),float(),float()}.
unProject4(WinX,WinY,WinZ,ClipW,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16},{V1,V2,V3,V4},NearVal,FarVal) ->
- wxe_util:call(5036, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,ClipW:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint,NearVal:?GLdouble,FarVal:?GLdouble>>);
+ call(5036, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,ClipW:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint,NearVal:?GLdouble,FarVal:?GLdouble>>);
unProject4(WinX,WinY,WinZ,ClipW,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12},{V1,V2,V3,V4},NearVal,FarVal) ->
- wxe_util:call(5036, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,ClipW:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint,NearVal:?GLdouble,FarVal:?GLdouble>>).
+ call(5036, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,ClipW:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint,NearVal:?GLdouble,FarVal:?GLdouble>>).
diff --git a/lib/wx/src/gen/wxGLCanvas.erl b/lib/wx/src/gen/wxGLCanvas.erl
index 3e0d1bd9ae..032d42535d 100644
--- a/lib/wx/src/gen/wxGLCanvas.erl
+++ b/lib/wx/src/gen/wxGLCanvas.erl
@@ -144,8 +144,10 @@ getContext(#wx_ref{type=ThisT,ref=ThisRef}) ->
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxglcanvas.html#wxglcanvassetcurrent">external documentation</a>.
setCurrent(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxGLCanvas),
- wxe_util:cast(?wxGLCanvas_SetCurrent,
- <<ThisRef:32/?UI>>).
+ _Result = wxe_util:cast(?wxGLCanvas_SetCurrent,
+ <<ThisRef:32/?UI>>),
+ {ok, _} = wxe_master:init_opengl(),
+ _Result.
%% @spec (This::wxGLCanvas()) -> ok
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxglcanvas.html#wxglcanvasswapbuffers">external documentation</a>.
diff --git a/lib/wx/src/gen/wxSystemSettings.erl b/lib/wx/src/gen/wxSystemSettings.erl
new file mode 100644
index 0000000000..3f7e0a1ad6
--- /dev/null
+++ b/lib/wx/src/gen/wxSystemSettings.erl
@@ -0,0 +1,79 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%% This file is generated DO NOT EDIT
+
+%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemsettings.html">wxSystemSettings</a>.
+%% @type wxSystemSettings(). An object reference, The representation is internal
+%% and can be changed without notice. It can't be used for comparsion
+%% stored on disc or distributed for use on other nodes.
+
+-module(wxSystemSettings).
+-include("wxe.hrl").
+-export([getColour/1,getFont/1,getMetric/1,getMetric/2,getScreenType/0]).
+
+%% inherited exports
+-export([parent_class/1]).
+
+%% @hidden
+parent_class(_Class) -> erlang:error({badtype, ?MODULE}).
+
+%% @spec (Index::WxSystemColour) -> wx:colour()
+%% WxSystemColour = integer()
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemsettings.html#wxsystemsettingsgetcolour">external documentation</a>.
+%%<br /> WxSystemColour is one of ?wxSYS_COLOUR_SCROLLBAR | ?wxSYS_COLOUR_BACKGROUND | ?wxSYS_COLOUR_DESKTOP | ?wxSYS_COLOUR_ACTIVECAPTION | ?wxSYS_COLOUR_INACTIVECAPTION | ?wxSYS_COLOUR_MENU | ?wxSYS_COLOUR_WINDOW | ?wxSYS_COLOUR_WINDOWFRAME | ?wxSYS_COLOUR_MENUTEXT | ?wxSYS_COLOUR_WINDOWTEXT | ?wxSYS_COLOUR_CAPTIONTEXT | ?wxSYS_COLOUR_ACTIVEBORDER | ?wxSYS_COLOUR_INACTIVEBORDER | ?wxSYS_COLOUR_APPWORKSPACE | ?wxSYS_COLOUR_HIGHLIGHT | ?wxSYS_COLOUR_HIGHLIGHTTEXT | ?wxSYS_COLOUR_BTNFACE | ?wxSYS_COLOUR_3DFACE | ?wxSYS_COLOUR_BTNSHADOW | ?wxSYS_COLOUR_3DSHADOW | ?wxSYS_COLOUR_GRAYTEXT | ?wxSYS_COLOUR_BTNTEXT | ?wxSYS_COLOUR_INACTIVECAPTIONTEXT | ?wxSYS_COLOUR_BTNHIGHLIGHT | ?wxSYS_COLOUR_BTNHILIGHT | ?wxSYS_COLOUR_3DHIGHLIGHT | ?wxSYS_COLOUR_3DHILIGHT | ?wxSYS_COLOUR_3DDKSHADOW | ?wxSYS_COLOUR_3DLIGHT | ?wxSYS_COLOUR_INFOTEXT | ?wxSYS_COLOUR_INFOBK | ?wxSYS_COLOUR_LISTBOX | ?wxSYS_COLOUR_HOTLIGHT | ?wxSYS_COLOUR_GRADIENTACTIVECAPTION | ?wxSYS_COLOUR_GRADIENTINACTIVECAPTION | ?wxSYS_COLOUR_MENUHILIGHT | ?wxSYS_COLOUR_MENUBAR | ?wxSYS_COLOUR_LISTBOXTEXT | ?wxSYS_COLOUR_MAX
+getColour(Index)
+ when is_integer(Index) ->
+ wxe_util:call(?wxSystemSettings_GetColour,
+ <<Index:32/?UI>>).
+
+%% @spec (Index::WxSystemFont) -> wxFont:wxFont()
+%% WxSystemFont = integer()
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemsettings.html#wxsystemsettingsgetfont">external documentation</a>.
+%%<br /> WxSystemFont is one of ?wxSYS_OEM_FIXED_FONT | ?wxSYS_ANSI_FIXED_FONT | ?wxSYS_ANSI_VAR_FONT | ?wxSYS_SYSTEM_FONT | ?wxSYS_DEVICE_DEFAULT_FONT | ?wxSYS_DEFAULT_PALETTE | ?wxSYS_SYSTEM_FIXED_FONT | ?wxSYS_DEFAULT_GUI_FONT | ?wxSYS_ICONTITLE_FONT
+getFont(Index)
+ when is_integer(Index) ->
+ wxe_util:call(?wxSystemSettings_GetFont,
+ <<Index:32/?UI>>).
+
+%% @spec (Index::WxSystemMetric) -> integer()
+%% @equiv getMetric(Index, [])
+getMetric(Index)
+ when is_integer(Index) ->
+ getMetric(Index, []).
+
+%% @spec (Index::WxSystemMetric, [Option]) -> integer()
+%% Option = {win, wxWindow:wxWindow()}
+%% WxSystemMetric = integer()
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemsettings.html#wxsystemsettingsgetmetric">external documentation</a>.
+%%<br /> WxSystemMetric is one of ?wxSYS_MOUSE_BUTTONS | ?wxSYS_BORDER_X | ?wxSYS_BORDER_Y | ?wxSYS_CURSOR_X | ?wxSYS_CURSOR_Y | ?wxSYS_DCLICK_X | ?wxSYS_DCLICK_Y | ?wxSYS_DRAG_X | ?wxSYS_DRAG_Y | ?wxSYS_EDGE_X | ?wxSYS_EDGE_Y | ?wxSYS_HSCROLL_ARROW_X | ?wxSYS_HSCROLL_ARROW_Y | ?wxSYS_HTHUMB_X | ?wxSYS_ICON_X | ?wxSYS_ICON_Y | ?wxSYS_ICONSPACING_X | ?wxSYS_ICONSPACING_Y | ?wxSYS_WINDOWMIN_X | ?wxSYS_WINDOWMIN_Y | ?wxSYS_SCREEN_X | ?wxSYS_SCREEN_Y | ?wxSYS_FRAMESIZE_X | ?wxSYS_FRAMESIZE_Y | ?wxSYS_SMALLICON_X | ?wxSYS_SMALLICON_Y | ?wxSYS_HSCROLL_Y | ?wxSYS_VSCROLL_X | ?wxSYS_VSCROLL_ARROW_X | ?wxSYS_VSCROLL_ARROW_Y | ?wxSYS_VTHUMB_Y | ?wxSYS_CAPTION_Y | ?wxSYS_MENU_Y | ?wxSYS_NETWORK_PRESENT | ?wxSYS_PENWINDOWS_PRESENT | ?wxSYS_SHOW_SOUNDS | ?wxSYS_SWAP_BUTTONS
+getMetric(Index, Options)
+ when is_integer(Index),is_list(Options) ->
+ MOpts = fun({win, #wx_ref{type=WinT,ref=WinRef}}, Acc) -> ?CLASS(WinT,wxWindow),[<<1:32/?UI,WinRef:32/?UI>>|Acc];
+ (BadOpt, _) -> erlang:error({badoption, BadOpt}) end,
+ BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)),
+ wxe_util:call(?wxSystemSettings_GetMetric,
+ <<Index:32/?UI, 0:32,BinOpt/binary>>).
+
+%% @spec () -> WxSystemScreenType
+%% WxSystemScreenType = integer()
+%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemsettings.html#wxsystemsettingsgetscreentype">external documentation</a>.
+%%<br /> WxSystemScreenType is one of ?wxSYS_SCREEN_NONE | ?wxSYS_SCREEN_TINY | ?wxSYS_SCREEN_PDA | ?wxSYS_SCREEN_SMALL | ?wxSYS_SCREEN_DESKTOP
+getScreenType() ->
+ wxe_util:call(?wxSystemSettings_GetScreenType,
+ <<>>).
+
diff --git a/lib/wx/src/wx.erl b/lib/wx/src/wx.erl
index 14abd0d817..9d76f3bc42 100644
--- a/lib/wx/src/wx.erl
+++ b/lib/wx/src/wx.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -96,7 +96,8 @@ new() ->
%% @doc Starts a wx server.
%% Option may be {debug, Level}, see debug/1.
new(Options) when is_list(Options) ->
- #wx_env{} = wxe_server:start(),
+ #wx_env{port=Port} = wxe_server:start(),
+ put(opengl_port, Port),
Debug = proplists:get_value(debug, Options, 0),
debug(Debug),
null().
@@ -121,8 +122,9 @@ get_env() ->
%% @spec (wx_env()) -> ok
%% @doc Sets the process wx environment, allows this process to use
%% another process wx environment.
-set_env(#wx_env{sv=Pid} = Env) ->
- put(?WXE_IDENTIFIER, Env),
+set_env(#wx_env{sv=Pid, port=Port} = Env) ->
+ put(?WXE_IDENTIFIER, Env),
+ put(opengl_port, Port),
%% wxe_util:cast(?REGISTER_PID, <<>>),
wxe_server:register_me(Pid),
ok.
diff --git a/lib/wx/src/wxe.hrl b/lib/wx/src/wxe.hrl
index bb70a03bfe..bd34b13385 100644
--- a/lib/wx/src/wxe.hrl
+++ b/lib/wx/src/wxe.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -50,6 +50,8 @@
-define(WXE_CB_START, 8). %% Used for event-callback start
-define(WXE_DEBUG_DRIVER, 9). %% Set debug
%%-define(WXE_DEBUG_PING, 10). %% debug ping (when using debugger it's needed)
--define(WXE_BIN_INCR, 5001). %% Binary refc incr
--define(WXE_BIN_DECR, 5002). %% Binary refc decr
+-define(WXE_BIN_INCR, 11). %% Binary refc incr
+-define(WXE_BIN_DECR, 12). %% Binary refc decr
+-define(WXE_INIT_OPENGL, 13). %% Binary refc decr
+
-include("gen/wxe_funcs.hrl").
diff --git a/lib/wx/src/wxe_master.erl b/lib/wx/src/wxe_master.erl
index 5ab76a77cf..9efe59054c 100644
--- a/lib/wx/src/wxe_master.erl
+++ b/lib/wx/src/wxe_master.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,7 +28,7 @@
-behaviour(gen_server).
%% API
--export([start/0, init_port/0]).
+-export([start/0, init_port/0, init_opengl/0]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -38,8 +38,8 @@
users, %% List of wx servers, needed ??
driver}). %% Driver name so wx_server can create it's own port
+-include("wxe.hrl").
-include("gen/wxe_debug.hrl").
--include("gen/gl_debug.hrl").
-define(DRIVER, "wxe_driver").
@@ -74,6 +74,14 @@ init_port() ->
receive wx_port_initiated -> ok end,
{Port, CBport}.
+
+%%--------------------------------------------------------------------
+%% Initlizes the opengl library
+%%--------------------------------------------------------------------
+init_opengl() ->
+ GLLib = wxe_util:wxgl_dl(),
+ wxe_util:call(?WXE_INIT_OPENGL, <<(list_to_binary(GLLib))/binary, 0:8>>).
+
%%====================================================================
%% gen_server callbacks
%%====================================================================
@@ -87,7 +95,7 @@ init_port() ->
%%--------------------------------------------------------------------
init([]) ->
DriverName = ?DRIVER,
- PrivDir = priv_dir(),
+ PrivDir = wxe_util:priv_dir(?DRIVER),
erlang:group_leader(whereis(init), self()),
case catch erlang:system_info(smp_support) of
true -> ok;
@@ -120,20 +128,19 @@ init([]) ->
process_flag(trap_exit, true),
DriverWithArgs = DriverName ++ " " ++ code:priv_dir(wx) ++ [0],
- case catch open_port({spawn, DriverWithArgs},[binary]) of
- {'EXIT', Err} ->
- erlang:error({open_port,Err});
- Port ->
- wx_debug_info = ets:new(wx_debug_info, [named_table]),
- wx_non_consts = ets:new(wx_non_consts, [named_table]),
- true = ets:insert(wx_debug_info, wxdebug_table()),
- true = ets:insert(wx_debug_info, gldebug_table()),
- spawn_link(fun() -> debug_ping(Port) end),
- receive
- {wx_consts, List} ->
- true = ets:insert(wx_non_consts, List)
- end,
- {ok, #state{cb_port=Port, driver=DriverName, users=gb_sets:empty()}}
+ try
+ Port = open_port({spawn, DriverWithArgs},[binary]),
+ wx_debug_info = ets:new(wx_debug_info, [named_table]),
+ wx_non_consts = ets:new(wx_non_consts, [named_table]),
+ true = ets:insert(wx_debug_info, wxdebug_table()),
+ spawn_link(fun() -> debug_ping(Port) end),
+ receive
+ {wx_consts, List} ->
+ true = ets:insert(wx_non_consts, List)
+ end,
+ {ok, #state{cb_port=Port, driver=DriverName, users=gb_sets:empty()}}
+ catch _:Err ->
+ error({Err, "Could not initiate graphics"})
end.
%%--------------------------------------------------------------------
@@ -205,108 +212,9 @@ code_change(_OldVsn, State, _Extra) ->
%%%%%%%%%%%% INTERNAL %%%%%%%%%%%%%%%%%%%%%%%%
-%% If you want anything done, do it yourself.
-
-priv_dir() ->
- Type = erlang:system_info(system_architecture),
- {file, Path} = code:is_loaded(?MODULE),
- Priv = case filelib:is_regular(Path) of
- true ->
- Beam = filename:join(["ebin/",atom_to_list(?MODULE) ++ ".beam"]),
- filename:join(strip(Path, Beam), "priv");
- false ->
- code:priv_dir(wx)
- end,
- try
- {ok, Dirs0} = file:list_dir(Priv),
- Dirs1 = split_dirs(Dirs0),
- Dirs = lists:reverse(lists:sort(Dirs1)),
-
- Best = best_dir(hd(split_dirs([Type])),Dirs, Priv),
- filename:join(Priv, Best)
- catch _:_ ->
- error_logger:format("WX ERROR: Could not find suitable \'~s\' for ~s in: ~s~n",
- [?DRIVER, Type, Priv]),
- erlang:error({load_driver, "No driver found"})
- end.
-
-best_dir(Dir, Dirs0, Priv) ->
- Dirs = [{D,D} || D <- Dirs0],
- best_dir(Dir, Dirs, [], Priv).
-
-best_dir(Pre, [{[],_}|R], Acc, Priv) -> %% Empty skip'em
- best_dir(Pre, R, Acc, Priv);
-best_dir(Pre, [{Pre,Dir}|R], Acc, Priv) ->
- Real = dir_app(lists:reverse(Dir)),
- case file:list_dir(filename:join(Priv,Real)) of
- {ok, Fs} ->
- case lists:any(fun(File) -> filename:rootname(File) =:= ?DRIVER end, Fs) of
- true -> Real; %% Found dir and it contains a driver
- false -> best_dir(Pre, R, Acc, Priv)
- end;
- _ ->
- best_dir(Pre, R, Acc, Priv)
- end;
-best_dir(Pre, [{[_|F],Dir}|R], Acc, Priv) ->
- best_dir(Pre, R, [{F,Dir}|Acc], Priv);
-best_dir(_Pre, [], [],_) -> throw(no_dir); %% Nothing found
-best_dir([_|Pre], [], Acc, Priv) ->
- best_dir(Pre, lists:reverse(Acc), [], Priv);
-best_dir([], _, _,_) -> throw(no_dir). %% Nothing found
-
-split_dirs(Dirs0) ->
- ToInt = fun(Str) ->
- try
- list_to_integer(Str)
- catch _:_ -> Str
- end
- end,
- Split = fun(Dir) ->
- Toks = tokens(Dir,".-"),
- lists:reverse([ToInt(Str) || Str <- Toks])
- end,
- lists:map(Split,Dirs0).
-
-dir_app([]) -> [];
-dir_app([Dir]) -> Dir;
-dir_app(Dir) ->
- dir_app2(Dir).
-dir_app2([Int]) when is_integer(Int) ->
- integer_to_list(Int);
-dir_app2([Str]) when is_list(Str) ->
- Str;
-dir_app2([Head|Rest]) when is_integer(Head) ->
- integer_to_list(Head) ++ dir_app2(Rest);
-dir_app2([Head|Rest]) when is_list(Head) ->
- Head ++ dir_app2(Rest).
-
-strip(Src, Src) ->
- [];
-strip([H|R], Src) ->
- [H| strip(R, Src)].
-
-
debug_ping(Port) ->
timer:sleep(1*333),
_R = (catch erlang:port_call(Port, 0, [])),
%% io:format("Erlang ping ~p ~n", [_R]),
debug_ping(Port).
-tokens(S,Seps) ->
- tokens1(S, Seps, []).
-
-tokens1([C|S], Seps, Toks) ->
- case lists:member(C, Seps) of
- true -> tokens1(S, Seps, [[C]|Toks]);
- false -> tokens2(S, Seps, Toks, [C])
- end;
-tokens1([], _Seps, Toks) ->
- lists:reverse(Toks).
-
-tokens2([C|S], Seps, Toks, Cs) ->
- case lists:member(C, Seps) of
- true -> tokens1(S, Seps, [[C], lists:reverse(Cs) |Toks]);
- false -> tokens2(S, Seps, Toks, [C|Cs])
- end;
-tokens2([], _Seps, Toks, Cs) ->
- lists:reverse([lists:reverse(Cs)|Toks]).
diff --git a/lib/wx/src/wxe_util.erl b/lib/wx/src/wxe_util.erl
index a2fb4641c9..02bca62486 100644
--- a/lib/wx/src/wxe_util.erl
+++ b/lib/wx/src/wxe_util.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -32,8 +32,9 @@
get_const/1,colour_bin/1,datetime_bin/1,
to_bool/1,from_bool/1]).
--include("wxe.hrl").
+-export([wxgl_dl/0, priv_dir/1]).
+-include("wxe.hrl").
to_bool(0) -> false;
to_bool(_) -> true.
@@ -199,3 +200,47 @@ check_previous() ->
erlang:error({Error, MF})
after 0 -> ok
end.
+
+%% Get gl dynamic library
+
+wxgl_dl() ->
+ DynLib0 = "erl_gl",
+ PrivDir = priv_dir(DynLib0),
+ DynLib = case os:type() of
+ {win32,_} ->
+ DynLib0 ++ ".dll";
+ _ ->
+ DynLib0 ++ ".so"
+ end,
+ filename:join(PrivDir, DynLib).
+
+priv_dir(Driver0) ->
+ {file, Path} = code:is_loaded(?MODULE),
+ Priv = case filelib:is_regular(Path) of
+ true ->
+ Beam = filename:join(["ebin/",atom_to_list(?MODULE) ++ ".beam"]),
+ filename:join(strip(Path, Beam), "priv");
+ false ->
+ code:priv_dir(wx)
+ end,
+ Driver = case os:type() of
+ {win32,_} ->
+ Driver0 ++ ".dll";
+ _ ->
+ Driver0 ++ ".so"
+ end,
+
+ case file:read_file_info(filename:join(Priv, Driver)) of
+ {ok, _} ->
+ Priv;
+ {error, _} ->
+ error_logger:format("ERROR: Could not find \'~s\' in: ~s~n",
+ [Driver, Priv]),
+ erlang:error({load_driver, "No driver found"})
+ end.
+
+strip(Src, Src) ->
+ [];
+strip([H|R], Src) ->
+ [H| strip(R, Src)].
+
diff --git a/lib/wx/test/Makefile b/lib/wx/test/Makefile
index dfec4bb695..90272372b2 100644
--- a/lib/wx/test/Makefile
+++ b/lib/wx/test/Makefile
@@ -62,7 +62,7 @@ release_spec:
release_tests_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) wx.spec wx_test_lib.hrl $(ErlSrc) $(ErlTargets) $(RELSYSDIR)
+ $(INSTALL_DATA) wx.spec wx.cover wx_test_lib.hrl $(ErlSrc) $(ErlTargets) $(RELSYSDIR)
$(INSTALL_SCRIPT) wxt $(RELSYSDIR)
release_docs_spec:
diff --git a/lib/wx/test/wx.cover b/lib/wx/test/wx.cover
new file mode 100644
index 0000000000..47e162ba7d
--- /dev/null
+++ b/lib/wx/test/wx.cover
@@ -0,0 +1,2 @@
+{incl_app,wx,details}.
+
diff --git a/lib/wx/test/wx.spec b/lib/wx/test/wx.spec
index a9201e5737..21e4a8c064 100644
--- a/lib/wx/test/wx.spec
+++ b/lib/wx/test/wx.spec
@@ -1,2 +1 @@
-{topcase, {dir, "../wx_test"}}.
-
+{suites,"../wx_test",all}.
diff --git a/lib/wx/test/wx_app_SUITE.erl b/lib/wx/test/wx_app_SUITE.erl
index 8fff324913..9c1e5868f4 100644
--- a/lib/wx/test/wx_app_SUITE.erl
+++ b/lib/wx/test/wx_app_SUITE.erl
@@ -45,22 +45,28 @@ init_per_testcase(Case, Config0) ->
end_per_testcase(Func,Config) ->
wx_test_lib:end_per_testcase(Func, Config).
-fin_per_testcase(Case, Config) ->
- wx_test_lib:end_per_testcase(Case, Config).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-all() ->
- all(suite).
-
-all(suite) ->
- [
- fields,
- modules,
- exportall,
- app_depend,
- undef_funcs
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [fields, modules, exportall, app_depend, undef_funcs].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/wx/test/wx_basic_SUITE.erl b/lib/wx/test/wx_basic_SUITE.erl
index 599aa371ba..bdf54a1b35 100644
--- a/lib/wx/test/wx_basic_SUITE.erl
+++ b/lib/wx/test/wx_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -23,8 +23,9 @@
%%% Created : 3 Nov 2008 by Dan Gudmundsson <[email protected]>
%%%-------------------------------------------------------------------
-module(wx_basic_SUITE).
--export([all/0, init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
-compile(export_all).
@@ -41,20 +42,23 @@ init_per_testcase(Func,Config) ->
wx_test_lib:init_per_testcase(Func,Config).
end_per_testcase(Func,Config) ->
wx_test_lib:end_per_testcase(Func,Config).
-fin_per_testcase(Func,Config) -> %% For test_server
- wx_test_lib:end_per_testcase(Func,Config).
%% SUITE specification
-all() ->
- all(suite).
-all(suite) ->
- [
- create_window,
- several_apps,
- wx_api,
- wx_misc,
- data_types
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [create_window, several_apps, wx_api, wx_misc,
+ data_types].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% The test cases
diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl
index 6f43247d74..9c9dcd3576 100644
--- a/lib/wx/test/wx_class_SUITE.erl
+++ b/lib/wx/test/wx_class_SUITE.erl
@@ -24,8 +24,9 @@
%%%-------------------------------------------------------------------
-module(wx_class_SUITE).
--export([all/0, init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
-compile(export_all).
@@ -42,24 +43,23 @@ init_per_testcase(Func,Config) ->
wx_test_lib:init_per_testcase(Func,Config).
end_per_testcase(Func,Config) ->
wx_test_lib:end_per_testcase(Func,Config).
-fin_per_testcase(Func,Config) -> %% For test_server
- wx_test_lib:end_per_testcase(Func,Config).
%% SUITE specification
-all() ->
- all(suite).
-all(suite) ->
- [
- calendarCtrl,
- treeCtrl,
- notebook,
- staticBoxSizer,
- clipboard,
- helpFrame,
- htmlWindow,
- listCtrlSort,
- radioBox
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [calendarCtrl, treeCtrl, notebook, staticBoxSizer,
+ clipboard, helpFrame, htmlWindow, listCtrlSort,
+ radioBox, systemSettings].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
%% The test cases
@@ -392,3 +392,17 @@ radioBox(Config) ->
wxWindow:show(Frame),
wx_test_lib:wx_destroy(Frame,Config).
+
+
+systemSettings(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo);
+systemSettings(Config) ->
+ Wx = wx:new(),
+ Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"),
+
+ ?m({_,_,_,_}, wxSystemSettings:getColour(?wxSYS_COLOUR_DESKTOP)),
+ ?mt(wxFont, wxSystemSettings:getFont(?wxSYS_SYSTEM_FONT)),
+ ?m(true, is_integer(wxSystemSettings:getMetric(?wxSYS_MOUSE_BUTTONS))),
+ ?m(true, is_integer(wxSystemSettings:getScreenType())),
+
+ wxWindow:show(Frame),
+ wx_test_lib:wx_destroy(Frame,Config).
diff --git a/lib/wx/test/wx_event_SUITE.erl b/lib/wx/test/wx_event_SUITE.erl
index dea10d892e..3258f55e50 100644
--- a/lib/wx/test/wx_event_SUITE.erl
+++ b/lib/wx/test/wx_event_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,8 +22,9 @@
%%% Created : 3 Nov 2008 by Dan Gudmundsson <[email protected]>
%%%-------------------------------------------------------------------
-module(wx_event_SUITE).
--export([all/0, init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
-compile(export_all).
@@ -40,22 +41,23 @@ init_per_testcase(Func,Config) ->
wx_test_lib:init_per_testcase(Func,Config).
end_per_testcase(Func,Config) ->
wx_test_lib:end_per_testcase(Func,Config).
-fin_per_testcase(Func,Config) -> %% For test_server
- wx_test_lib:end_per_testcase(Func,Config).
%% SUITE specification
-all() ->
- all(suite).
-all(suite) ->
- [
- connect,
- disconnect,
- connect_msg_20,
- connect_cb_20,
- mouse_on_grid,
- spin_event,
- connect_in_callback
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [connect, disconnect, connect_msg_20, connect_cb_20,
+ mouse_on_grid, spin_event, connect_in_callback].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% The test cases
diff --git a/lib/wx/test/wx_opengl_SUITE.erl b/lib/wx/test/wx_opengl_SUITE.erl
index ce4651bcb1..93efa4c68f 100644
--- a/lib/wx/test/wx_opengl_SUITE.erl
+++ b/lib/wx/test/wx_opengl_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,8 +22,9 @@
%%% Created : 3 Nov 2008 by Dan Gudmundsson <[email protected]>
%%%-------------------------------------------------------------------
-module(wx_opengl_SUITE).
--export([all/0, init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
-compile(export_all).
@@ -48,18 +49,23 @@ init_per_testcase(Func,Config) ->
wx_test_lib:init_per_testcase(Func,Config).
end_per_testcase(Func,Config) ->
wx_test_lib:end_per_testcase(Func,Config).
-fin_per_testcase(Func,Config) -> %% For test_server
- wx_test_lib:end_per_testcase(Func,Config).
%% SUITE specification
-all() ->
- all(suite).
-all(suite) ->
- [
- canvas,
- glu_tesselation
- ].
-
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [canvas, glu_tesselation].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
%% The test cases
-define(VS, {{ 0.5, 0.5, -0.5}, %1
@@ -91,7 +97,7 @@ canvas(Config) ->
?m(true, wxWindow:show(Frame)),
?m(false, wx:is_null(wxGLCanvas:getContext(Canvas))),
- ?m({'EXIT', {{no_gl_context,_},_}}, gl:getString(?GL_VENDOR)),
+ ?m({'EXIT', {{error, no_gl_context,_},_}}, gl:getString(?GL_VENDOR)),
?m(ok, wxGLCanvas:setCurrent(Canvas)),
io:format("Vendor: ~s~n", [gl:getString(?GL_VENDOR)]),
@@ -113,7 +119,7 @@ canvas(Config) ->
Data = {?FACES,?VS},
drawBox(0, Data),
?m(ok, wxGLCanvas:swapBuffers(Canvas)),
-
+ ?m([], flush()),
Env = wx:get_env(),
Tester = self(),
spawn_link(fun() ->
@@ -125,10 +131,23 @@ canvas(Config) ->
%% This may fail when window is deleted
catch draw_loop(2,Data,Canvas)
end),
-
?m_receive(works),
+ ?m([], flush()),
+ io:format("Undef func ~p ~n", [catch gl:uniform1d(2, 0.75)]),
+ timer:sleep(500),
+ ?m([], flush()),
wx_test_lib:wx_destroy(Frame, Config).
-
+
+flush() ->
+ flush([]).
+
+flush(Collected) ->
+ receive Msg ->
+ flush([Msg|Collected])
+ after 1 ->
+ lists:reverse(Collected)
+ end.
+
draw_loop(Deg,Data,Canvas) ->
timer:sleep(15),
drawBox(Deg,Data),
@@ -136,6 +155,7 @@ draw_loop(Deg,Data,Canvas) ->
draw_loop(Deg+1, Data,Canvas).
+
drawBox(Deg,{Fs,Vs}) ->
gl:matrixMode(?GL_MODELVIEW),
gl:loadIdentity(),
diff --git a/lib/wx/test/wx_test_lib.erl b/lib/wx/test/wx_test_lib.erl
index 9368aa4bdc..8509d6be6f 100644
--- a/lib/wx/test/wx_test_lib.erl
+++ b/lib/wx/test/wx_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -35,7 +35,7 @@ init_per_suite(Config) ->
exit("Can not test on MacOSX");
{unix, _} ->
io:format("DISPLAY ~s~n", [os:getenv("DISPLAY")]),
- case proplists:get_value(xserver, Config, none) of
+ case ct:get_config(xserver, none) of
none -> ignore;
Server ->
os:putenv("DISPLAY", Server)
@@ -200,7 +200,7 @@ eval_test_case(Mod, Fun, Config) ->
test_case_evaluator(Mod, Fun, [Config]) ->
NewConfig = Mod:init_per_testcase(Fun, Config),
R = apply(Mod, Fun, [NewConfig]),
- Mod:fin_per_testcase(Fun, NewConfig),
+ Mod:end_per_testcase(Fun, NewConfig),
exit({test_case_ok, R}).
wait_for_evaluator(Pid, Mod, Fun, Config) ->
@@ -216,12 +216,12 @@ wait_for_evaluator(Pid, Mod, Fun, Config) ->
{'EXIT', Pid, {skipped, Reason}} ->
log("<WARNING> Test case ~w skipped, because ~p~n",
[{Mod, Fun}, Reason]),
- Mod:fin_per_testcase(Fun, Config),
+ Mod:end_per_testcase(Fun, Config),
{skip, {Mod, Fun}, Reason};
{'EXIT', Pid, Reason} ->
log("<ERROR> Eval process ~w exited, because ~p~n",
[{Mod, Fun}, Reason]),
- Mod:fin_per_testcase(Fun, Config),
+ Mod:end_per_testcase(Fun, Config),
{crash, {Mod, Fun}, Reason}
end.
diff --git a/lib/wx/test/wx_xtra_SUITE.erl b/lib/wx/test/wx_xtra_SUITE.erl
index d5888bbf94..0d876c4e52 100644
--- a/lib/wx/test/wx_xtra_SUITE.erl
+++ b/lib/wx/test/wx_xtra_SUITE.erl
@@ -23,8 +23,9 @@
%%% Created : 3 Nov 2008 by Dan Gudmundsson <[email protected]>
%%%-------------------------------------------------------------------
-module(wx_xtra_SUITE).
--export([all/0, init_per_suite/1, end_per_suite/1,
- init_per_testcase/2, fin_per_testcase/2, end_per_testcase/2]).
+-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2]).
-compile(export_all).
@@ -41,19 +42,23 @@ init_per_testcase(Func,Config) ->
wx_test_lib:init_per_testcase(Func,Config).
end_per_testcase(Func,Config) ->
wx_test_lib:end_per_testcase(Func,Config).
-fin_per_testcase(Func,Config) -> %% For test_server
- wx_test_lib:end_per_testcase(Func,Config).
%% SUITE specification
-all() ->
- all(suite).
-all(suite) ->
- [
- destroy_app,
- multiple_add_in_sizer,
- app_dies,
- menu_item_debug
- ].
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [destroy_app, multiple_add_in_sizer, app_dies,
+ menu_item_debug].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
%% The test cases
diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk
index c0cc302317..dea0678063 100644
--- a/lib/wx/vsn.mk
+++ b/lib/wx/vsn.mk
@@ -1 +1 @@
-WX_VSN = 0.98.7
+WX_VSN = 0.98.8
diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml
index d67a622481..aa66cbec77 100644
--- a/lib/xmerl/doc/src/notes.xml
+++ b/lib/xmerl/doc/src/notes.xml
@@ -31,6 +31,40 @@
<p>This document describes the changes made to the Xmerl application.</p>
+<section><title>Xmerl 1.2.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> An empty element declared as simpleContent was not
+ properly validated. </p>
+ <p>
+ Own Id: OTP-8599</p>
+ </item>
+ <item>
+ <p> Fix format_man_pages so it handles all man sections
+ and remove warnings/errors in various man pages. </p>
+ <p>
+ Own Id: OTP-8600</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Fix entity checking so there are no fatal errors for
+ undefined entities when option skip_external_dtd is used.
+ </p>
+ <p>
+ Own Id: OTP-8947</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Xmerl 1.2.6</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/xmerl/src/xmerl_lib.erl b/lib/xmerl/src/xmerl_lib.erl
index 7b76a76a33..1b3a7e57f0 100644
--- a/lib/xmerl/src/xmerl_lib.erl
+++ b/lib/xmerl/src/xmerl_lib.erl
@@ -148,9 +148,10 @@ expand_element(Element) ->
expand_element(Element, Pos, Parents) ->
expand_element(Element, Pos, Parents, false).
-expand_element(E = #xmlElement{}, Pos, Parents, Norm) ->
- Content = expand_content(E#xmlElement.content, 1, Parents, Norm),
- Attrs = expand_attributes(E#xmlElement.attributes, 1, []),
+expand_element(E = #xmlElement{name = N}, Pos, Parents, Norm) ->
+ NewParents = [{N,Pos}|Parents],
+ Content = expand_content(E#xmlElement.content, 1, NewParents, Norm),
+ Attrs = expand_attributes(E#xmlElement.attributes, 1, NewParents),
E#xmlElement{pos = Pos,
parents = Parents,
attributes = Attrs,
diff --git a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
index 9d184152d1..3b9eaa309c 100644
--- a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
+++ b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
@@ -1,7 +1,7 @@
%%-*-erlang-*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -934,6 +934,13 @@ parse_att_value(?STRING_REST("&", Rest), State, Stop, Acc) ->
parse_att_value(Rest1, State2, Stop, ParsedValue ++ Acc);
{external_general, Name, _} ->
?fatal_error(State1, "External parsed entity reference in attribute value: " ++ Name);
+ {not_found, Name} ->
+ case State#xmerl_sax_parser_state.skip_external_dtd of
+ false ->
+ ?fatal_error(State1, "Entity not declared: " ++ Name); %%VC: Entity Declared
+ true ->
+ parse_att_value(Rest1, State1, Stop, ";" ++ lists:reverse(Name) ++ "&" ++ Acc)
+ end;
{unparsed, Name, _} ->
?fatal_error(State1, "Unparsed entity reference in attribute value: " ++ Name)
end;
@@ -1098,6 +1105,13 @@ parse_content(?STRING_REST("&", Rest), State, Acc, _IgnorableWS) ->
{external_general, _, {PubId, SysId}} ->
State2 = parse_external_entity(State1, PubId, SysId),
parse_content(Rest1, State2, Acc, false);
+ {not_found, Name} ->
+ case State#xmerl_sax_parser_state.skip_external_dtd of
+ false ->
+ ?fatal_error(State1, "Entity not declared: " ++ Name); %%VC: Entity Declared
+ true ->
+ parse_content(Rest1, State1, ";" ++ lists:reverse(Name) ++ "&" ++ Acc, false)
+ end;
{unparsed, Name, _} ->
?fatal_error(State1, "Unparsed entity reference in content: " ++ Name)
end;
@@ -1357,7 +1371,7 @@ look_up_reference(Name, HaveToExist, State) ->
yes ->
?fatal_error(State, "Entity not declared: " ++ Name); %%WFC: Entity Declared
no ->
- ?fatal_error(State, "Entity not declared: " ++ Name) %%VC: Entity Declared
+ {not_found, Name} %%VC: Entity Declared
end;
false ->
{not_found, Name}
@@ -1869,7 +1883,14 @@ parse_doctype_decl(?STRING_REST("%", Rest), State) ->
parse_doctype_decl(?APPEND_STRING(IValue, Rest1), State1);
{external_parameter, _, {PubId, SysId}} ->
State2 = parse_external_entity(State1#xmerl_sax_parser_state{file_type = entity}, PubId, SysId),
- parse_doctype_decl(Rest1, State2)
+ parse_doctype_decl(Rest1, State2);
+ {not_found, Name} ->
+ case State#xmerl_sax_parser_state.skip_external_dtd of
+ false ->
+ ?fatal_error(State1, "Entity not declared: " ++ Name); %%WFC: Entity Declared
+ true ->
+ parse_doctype_decl(Rest1, State1)
+ end
end;
parse_doctype_decl(?STRING_REST("<!", Rest1), State) ->
parse_doctype_decl_1(Rest1, State);
@@ -2443,7 +2464,7 @@ parse_ndata(Bytes, State) ->
%% Acc = string()
%% Result : {Value, Rest, State}
%% Value = string()
-%% Description: Parse an attribute value
+%% Description: Parse an entity value
%%----------------------------------------------------------------------
parse_entity_value(?STRING_EMPTY, State, undefined, Acc) ->
{Acc, [], State}; %% stop clause when parsing references
@@ -2473,7 +2494,7 @@ parse_entity_value(?STRING_REST("&", Rest), State, Stop, Acc) ->
{external_general, Name, _} ->
parse_entity_value(Rest1, State1, Stop, ";" ++ lists:reverse(Name) ++ "&" ++ Acc);
{not_found, Name} ->
- parse_entity_value(Rest1, State1, Stop, ";" ++ lists:reverse(Name) ++ "&" ++ Acc);
+ parse_entity_value(Rest1, State1, Stop, ";" ++ lists:reverse(Name) ++ "&" ++ Acc);
{unparsed, Name, _} ->
?fatal_error(State1, "Unparsed entity reference in entity value: " ++ Name)
end;
@@ -2490,7 +2511,15 @@ parse_entity_value(?STRING_REST("%", Rest), #xmerl_sax_parser_state{file_type=Ty
IValue = ?TO_INPUT_FORMAT(" " ++ RefValue ++ " "),
parse_entity_value(?APPEND_STRING(IValue, Rest1), State1, Stop, Acc);
{external_parameter, _, {_PubId, _SysId}} ->
- ?fatal_error(State1, "Parameter references in entity value not supported yet.")
+ ?fatal_error(State1, "Parameter references in entity value not supported yet.");
+ {not_found, Name} ->
+ case State#xmerl_sax_parser_state.skip_external_dtd of
+ false ->
+ ?fatal_error(State1, "Entity not declared: " ++ Name); %%VC: Entity Declared
+ true ->
+ parse_entity_value(Rest1, State1, Stop, ";" ++ lists:reverse(Name) ++ "&" ++ Acc)
+ end
+
end
end;
parse_entity_value(?STRING_UNBOUND_REST(Stop, Rest), State, Stop, Acc) ->
diff --git a/lib/xmerl/src/xmerl_scan.erl b/lib/xmerl/src/xmerl_scan.erl
index e2e6f95c4a..e07d495fc7 100644
--- a/lib/xmerl/src/xmerl_scan.erl
+++ b/lib/xmerl/src/xmerl_scan.erl
@@ -34,7 +34,9 @@
%% See also <a href="xmerl_examples.html">tutorial</a> on customization
%% functions.
%% </p>
+%% <p>
%% Possible options are:
+%% </p>
%% <dl>
%% <dt><code>{acc_fun, Fun}</code></dt>
%% <dd>Call back function to accumulate contents of entity.</dd>
diff --git a/lib/xmerl/src/xmerl_xpath.erl b/lib/xmerl/src/xmerl_xpath.erl
index 182a186d2c..e654a8ef1d 100644
--- a/lib/xmerl/src/xmerl_xpath.erl
+++ b/lib/xmerl/src/xmerl_xpath.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -57,7 +57,9 @@
%% @type option_list(). <p>Options allows to customize the behaviour of the
%% XPath scanner.
%% </p>
+%% <p>
%% Possible options are:
+%% </p>
%% <dl>
%% <dt><code>{namespace, #xmlNamespace}</code></dt>
%% <dd>Set namespace nodes, from XmlNamspace, in xmlContext</dd>
diff --git a/lib/xmerl/src/xmerl_xsd.erl b/lib/xmerl/src/xmerl_xsd.erl
index 1aedc9e270..c0923520c2 100644
--- a/lib/xmerl/src/xmerl_xsd.erl
+++ b/lib/xmerl/src/xmerl_xsd.erl
@@ -29,7 +29,9 @@
%% @type option_list(). <p>Options allow to customize the behaviour of the
%% validation.
%% </p>
+%% <p>
%% Possible options are :
+%% </p>
%% <dl>
%% <dt><code>{tab2file,boolean()}</code></dt>
%% <dd>Enables saving of abstract structure on file for debugging
@@ -46,6 +48,7 @@
%% <dd>It is possible by this option to provide a state with process
%% information from an earlier validation.</dd>
%% </dl>
+%% @end
%%%-------------------------------------------------------------------
-module(xmerl_xsd).
diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk
index d85a57f447..a4d7efaee3 100644
--- a/lib/xmerl/vsn.mk
+++ b/lib/xmerl/vsn.mk
@@ -1 +1 @@
-XMERL_VSN = 1.2.6
+XMERL_VSN = 1.2.7
diff --git a/make/emd2exml.in b/make/emd2exml.in
index 17cb0a0b57..16c38379d9 100644
--- a/make/emd2exml.in
+++ b/make/emd2exml.in
@@ -44,6 +44,7 @@
-define(DELAYED_TOC_IX, 1).
-define(DELAYED_START_IX, 2).
+-compile({no_auto_import,[error/2]}).
-mode(compile).
-export([main/1]).
@@ -380,6 +381,8 @@ put_text(S, [$>|Cs], CTag, EmTag, Acc) when CTag /= no ->
put_text(S, Cs, CTag, EmTag, ["&gt;"|Acc]);
put_text(S, [$&|Cs], CTag, EmTag, Acc) when CTag /= no ->
put_text(S, Cs, CTag, EmTag, ["&amp;"|Acc]);
+put_text(S, [$&, $ |Cs], CTag, EmTag, Acc) -> %Workaround for INSTALL-WIN32.md
+ put_text(S, Cs, CTag, EmTag, ["&amp; "|Acc]);
put_text(S, [$'|Cs], CTag, EmTag, Acc)when CTag /= no ->
put_text(S, Cs, CTag, EmTag, ["&apos;"|Acc]);
put_text(S, [$<|Cs], no, EmTag, Acc) ->
diff --git a/make/otp.mk.in b/make/otp.mk.in
index 6ae7c5b456..bf287be416 100644
--- a/make/otp.mk.in
+++ b/make/otp.mk.in
@@ -209,6 +209,8 @@ MAN9DIR = $(DOCDIR)/man9
TEXDIR = .
+SPECDIR = $(DOCDIR)/specs
+
# HTML & GIF files that always are generated and must be delivered
SGML_COLL_FILES = $(SGML_APPLICATION_FILES) $(SGML_PART_FILES)
XML_COLL_FILES = $(XML_APPLICATION_FILES) $(XML_PART_FILES)
@@ -237,41 +239,52 @@ FOP = @FOP@
DOCGEN=$(ERL_TOP)/lib/erl_docgen
+SPECS_ESRC = ../../src
+# Extract specifications and types from Erlang source files (-spec, -type)
+$(SPECDIR)/specs_%.xml: $(SPECS_ESRC)/%.erl
+ escript $(DOCGEN)/priv/bin/specs_gen.escript $(SPECS_FLAGS) -o$(dir $@) $<
-$(MAN1DIR)/%.1:: %.xml
+$(MAN1DIR)/%.1: %.xml
date=`date +"%B %e %Y"`; \
xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-$(MAN2DIR)/%.2:: %.xml
+$(MAN2DIR)/%.2: %.xml
date=`date +"%B %e %Y"`; \
xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-$(MAN3DIR)/%.3:: %.xml
+ifneq ($(wildcard $(SPECDIR)),)
+$(MAN3DIR)/%.3: %.xml $(SPECDIR)/specs_%.xml
+ date=`date +"%B %e %Y"`; \
+ specs_file=`pwd`/$(SPECDIR)/specs_$*.xml; \
+ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --stringparam specs_file "$$specs_file" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+else
+$(MAN3DIR)/%.3: %.xml
date=`date +"%B %e %Y"`; \
xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
+endif
# left for compatability
-$(MAN4DIR)/%.4:: %.xml
+$(MAN4DIR)/%.4: %.xml
date=`date +"%B %e %Y"`; \
xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-$(MAN4DIR)/%.5:: %.xml
+$(MAN4DIR)/%.5: %.xml
date=`date +"%B %e %Y"`; \
xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
# left for compatability
-$(MAN6DIR)/%.6:: %_app.xml
+$(MAN6DIR)/%.6: %_app.xml
date=`date +"%B %e %Y"`; \
xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-$(MAN6DIR)/%.7:: %_app.xml
+$(MAN6DIR)/%.7: %_app.xml
date=`date +"%B %e %Y"`; \
xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
-$(MAN9DIR)/%.9:: %.xml
+$(MAN9DIR)/%.9: %.xml
date=`date +"%B %e %Y"`; \
xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $<
diff --git a/make/otp_release_targets.mk b/make/otp_release_targets.mk
index 7d433e738c..8058e634d4 100644
--- a/make/otp_release_targets.mk
+++ b/make/otp_release_targets.mk
@@ -21,13 +21,30 @@
# Targets for the new documentation support
# ----------------------------------------------------
+ifneq ($(TOP_SPECS_FILE),)
+TOP_SPECS_PARAM = --stringparam specs_file "`pwd`/$(TOP_SPECS_FILE)"
+endif
+
+MOD2APP = $(ERL_TOP)/make/$(TARGET)/mod2app.xml
+ifneq ($(wildcard $(MOD2APP)),)
+MOD2APP_PARAM = --stringparam mod2app_file "$(MOD2APP)"
+endif
+
ifeq ($(TOPDOC),)
-$(HTMLDIR)/index.html: $(XML_FILES)
+$(HTMLDIR)/index.html: $(XML_FILES) $(SPECS_FILES)
date=`date +"%B %e %Y"`; \
- $(XSLTPROC) --noout --stringparam outdir $(HTMLDIR) --stringparam docgen "$(DOCGEN)" --stringparam topdocdir "$(TOPDOCDIR)" \
- --stringparam pdfdir "$(PDFDIR)" \
- --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude \
- -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_html.xsl book.xml
+ $(XSLTPROC) --noout \
+ --stringparam outdir $(HTMLDIR) \
+ --stringparam docgen "$(DOCGEN)" \
+ --stringparam topdocdir "$(TOPDOCDIR)" \
+ --stringparam pdfdir "$(PDFDIR)" \
+ --xinclude $(TOP_SPECS_PARAM) $(MOD2APP_PARAM) \
+ --stringparam gendate "$$date" \
+ --stringparam appname "$(APPLICATION)" \
+ --stringparam appver "$(VSN)" \
+ -path $(DOCGEN)/priv/docbuilder_dtd \
+ -path $(DOCGEN)/priv/dtd_html_entities \
+ $(DOCGEN)/priv/xsl/db_html.xsl book.xml
endif
$(HTMLDIR)/users_guide.html: $(XML_FILES)
@@ -37,14 +54,17 @@ $(HTMLDIR)/users_guide.html: $(XML_FILES)
--stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude \
-path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_html.xsl book.xml
-
-%.fo: $(XML_FILES)
+%.fo: $(XML_FILES) $(SPECS_FILES)
date=`date +"%B %e %Y"`; \
- $(XSLTPROC) --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" \
- --stringparam appver "$(VSN)" --xinclude \
- -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_pdf.xsl book.xml > $@
-
-
+ $(XSLTPROC) \
+ --stringparam docgen "$(DOCGEN)" \
+ --stringparam gendate "$$date" \
+ --stringparam appname "$(APPLICATION)" \
+ --stringparam appver "$(VSN)" \
+ --xinclude $(TOP_SPECS_PARAM) \
+ -path $(DOCGEN)/priv/docbuilder_dtd \
+ -path $(DOCGEN)/priv/dtd_html_entities \
+ $(DOCGEN)/priv/xsl/db_pdf.xsl book.xml > $@
# ------------------------------------------------------------------------
# The following targets just exist in the documentation directory
diff --git a/system/doc/efficiency_guide/advanced.xml b/system/doc/efficiency_guide/advanced.xml
index 2383e3cf3d..8126b93a2d 100644
--- a/system/doc/efficiency_guide/advanced.xml
+++ b/system/doc/efficiency_guide/advanced.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2010</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -200,7 +200,7 @@ On 64-bit architectures: 4 words for a reference from the current local node, an
<seealso marker="#ports">the maximum number of Erlang ports</seealso>
available, and operating system specific settings and limits.</item>
<tag><em>Number of arguments to a function or fun</em></tag>
- <item>256</item>
+ <item>255</item>
</taglist>
</section>
</chapter>
diff --git a/system/doc/top/Makefile b/system/doc/top/Makefile
index 148fefaf13..aac90fcaa4 100644
--- a/system/doc/top/Makefile
+++ b/system/doc/top/Makefile
@@ -246,7 +246,7 @@ release_docs_spec: docs
$(INSTALL_DATA) $(INDEX_FILES) $(MAN_INDEX) $(TOP_HTML_FILES) $(RELSYSDIR)
$(INSTALL_DIR) $(RELSYSDIR)/docbuild
$(INSTALL_DATA) $(INDEX_SCRIPT) $(MAN_INDEX_SCRIPT) $(JAVASCRIPT_BUILD_SCRIPT) \
- $(INDEX_SCRIPT_SRC) $(MAN_INDEX_SCRIPT_SRC) $(JAVASCRIPT_BUILD_SCRIPT_SRC) \
+ $(INDEX_SRC) $(MAN_INDEX_SRC) $(JAVASCRIPT_BUILD_SCRIPT_SRC) \
$(TEMPLATES) $(RELSYSDIR)/docbuild
diff --git a/system/doc/top/src/erl_html_tools.erl b/system/doc/top/src/erl_html_tools.erl
index fef56331fc..599268804e 100644
--- a/system/doc/top/src/erl_html_tools.erl
+++ b/system/doc/top/src/erl_html_tools.erl
@@ -40,7 +40,8 @@ group_order() ->
{test, "Test"},
{doc, "Documentation"},
{orb, "Object Request Broker & IDL"},
- {misc, "Miscellaneous"}
+ {misc, "Miscellaneous"},
+ {eric, "Ericsson Internal"}
].
top_index() ->