aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml11
-rw-r--r--HOWTO/INSTALL.md4
-rw-r--r--bootstrap/bin/start.bootbin5455 -> 5435 bytes
-rw-r--r--bootstrap/bin/start_clean.bootbin5455 -> 5435 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bool.beambin15720 -> 0 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bsm.beambin12632 -> 12600 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_dead.beambin13296 -> 13848 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_dict.beambin5292 -> 5284 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_disasm.beambin26192 -> 26192 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_except.beambin3564 -> 3564 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_jump.beambin10052 -> 9196 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_type.beambin17748 -> 17756 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_utils.beambin13788 -> 13656 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_validator.beambin30852 -> 30792 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl.beambin32080 -> 32080 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compile.beambin39512 -> 39824 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.app1
-rw-r--r--bootstrap/lib/compiler/ebin/core_lint.beambin13572 -> 13572 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_scan.beambin6636 -> 6636 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/erl_bifs.beambin2152 -> 2160 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_fold.beambin52544 -> 51860 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_inline.beambin4236 -> 4236 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_codegen.beambin56480 -> 56824 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_core.beambin57572 -> 58156 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel.beambin46636 -> 54900 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel_pp.beambin12704 -> 12812 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_life.beambin17788 -> 17792 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_controller.beambin31936 -> 31936 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_master.beambin6636 -> 6664 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code.beambin12152 -> 13300 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code_server.beambin24588 -> 24644 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log.beambin35836 -> 35776 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/dist_ac.beambin26340 -> 26336 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/dist_util.beambin11212 -> 11212 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erts_debug.beambin5544 -> 5544 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file.beambin14572 -> 14564 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file_io_server.beambin15544 -> 15472 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/gen_sctp.beambin3392 -> 3388 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global.beambin32256 -> 32224 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global_group.beambin17548 -> 17548 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/group.beambin14032 -> 14008 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/heart.beambin5544 -> 5544 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/hipe_unified_loader.beambin12624 -> 12608 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet.beambin24160 -> 24160 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_tcp.beambin3092 -> 3076 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_udp.beambin1796 -> 1768 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_config.beambin7728 -> 7728 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_db.beambin27020 -> 26988 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_gethost_native.beambin10436 -> 10436 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_res.beambin14856 -> 14808 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_sctp.beambin2300 -> 2300 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_tcp.beambin2776 -> 2768 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_tcp_dist.beambin7616 -> 7612 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_udp.beambin1940 -> 1936 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.appup6
-rw-r--r--bootstrap/lib/kernel/ebin/net_kernel.beambin24848 -> 24824 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/pg2.beambin7912 -> 7912 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/ram_file.beambin6984 -> 6720 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/rpc.beambin8140 -> 8140 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user.beambin11576 -> 11576 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user_drv.beambin11420 -> 11368 bytes
-rw-r--r--bootstrap/lib/kernel/include/dist_util.hrl2
-rw-r--r--bootstrap/lib/stdlib/ebin/array.beambin12000 -> 11992 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/c.beambin14600 -> 14816 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/calendar.beambin5136 -> 5136 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets.beambin53684 -> 51536 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_utils.beambin28796 -> 28444 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v8.beambin27496 -> 0 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v9.beambin49820 -> 49188 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph.beambin8312 -> 8312 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/edlin.beambin10184 -> 10184 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/epp.beambin29280 -> 29280 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_anno.beambin4016 -> 3648 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_eval.beambin30632 -> 30632 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_expand_records.beambin22708 -> 22708 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_internal.beambin7764 -> 7764 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin91320 -> 91332 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_scan.beambin28844 -> 28612 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/error_logger_file_h.beambin4684 -> 4460 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/error_logger_tty_h.beambin4968 -> 4744 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/escript.beambin17584 -> 17596 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ets.beambin22588 -> 22588 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/file_sorter.beambin30400 -> 30376 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filename.beambin14856 -> 14596 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gb_trees.beambin5128 -> 5124 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen.beambin5412 -> 5408 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_event.beambin13416 -> 13396 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_server.beambin12448 -> 12448 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_statem.beambin14076 -> 17344 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_fread.beambin7280 -> 7252 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_pretty.beambin15152 -> 15080 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/log_mf_h.beambin2636 -> 2636 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/math.beambin1260 -> 1296 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ms_transform.beambin20464 -> 20492 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/proc_lib.beambin10624 -> 10872 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/proplists.beambin4968 -> 4732 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc.beambin70112 -> 70032 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc_pt.beambin76868 -> 76976 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/queue.beambin6212 -> 6212 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/rand.beambin13560 -> 15528 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sets.beambin7064 -> 6744 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell.beambin30300 -> 30300 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell_default.beambin3932 -> 4028 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sofs.beambin40624 -> 40620 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.app1
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.appup6
-rw-r--r--bootstrap/lib/stdlib/ebin/supervisor.beambin23696 -> 23792 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sys.beambin8564 -> 8564 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/timer.beambin5472 -> 5468 bytes
-rw-r--r--bootstrap/lib/stdlib/include/assert.hrl184
-rw-r--r--erts/configure.in18
-rw-r--r--erts/doc/src/erl.xml14
-rw-r--r--erts/doc/src/erl_driver.xml4
-rw-r--r--erts/doc/src/erlang.xml24
-rw-r--r--erts/doc/src/notes.xml44
-rw-r--r--erts/emulator/Makefile.in7
-rw-r--r--erts/emulator/beam/atom.c4
-rw-r--r--erts/emulator/beam/atom.h4
-rw-r--r--erts/emulator/beam/beam_bif_load.c9
-rw-r--r--erts/emulator/beam/beam_bp.c2
-rw-r--r--erts/emulator/beam/beam_bp.h2
-rw-r--r--erts/emulator/beam/beam_debug.c8
-rw-r--r--erts/emulator/beam/beam_emu.c6
-rw-r--r--erts/emulator/beam/beam_load.c2
-rw-r--r--erts/emulator/beam/beam_load.h3
-rw-r--r--erts/emulator/beam/bif.tab1
-rw-r--r--erts/emulator/beam/break.c142
-rw-r--r--erts/emulator/beam/dist.c15
-rw-r--r--erts/emulator/beam/erl_afit_alloc.c4
-rw-r--r--erts/emulator/beam/erl_alloc.c12
-rw-r--r--erts/emulator/beam/erl_alloc.h6
-rw-r--r--erts/emulator/beam/erl_alloc_util.c43
-rw-r--r--erts/emulator/beam/erl_alloc_util.h10
-rw-r--r--erts/emulator/beam/erl_ao_firstfit_alloc.c4
-rw-r--r--erts/emulator/beam/erl_bestfit_alloc.c4
-rw-r--r--erts/emulator/beam/erl_bif_ddll.c2
-rw-r--r--erts/emulator/beam/erl_bif_info.c2
-rw-r--r--erts/emulator/beam/erl_db.c6
-rw-r--r--erts/emulator/beam/erl_db.h2
-rw-r--r--erts/emulator/beam/erl_db_hash.c4
-rw-r--r--erts/emulator/beam/erl_db_tree.c4
-rw-r--r--erts/emulator/beam/erl_db_util.h2
-rw-r--r--erts/emulator/beam/erl_debug.c10
-rw-r--r--erts/emulator/beam/erl_drv_nif.h4
-rw-r--r--erts/emulator/beam/erl_fun.c28
-rw-r--r--erts/emulator/beam/erl_fun.h7
-rw-r--r--erts/emulator/beam/erl_gc.c17
-rw-r--r--erts/emulator/beam/erl_goodfit_alloc.c4
-rw-r--r--erts/emulator/beam/erl_hl_timer.c4
-rw-r--r--erts/emulator/beam/erl_hl_timer.h2
-rw-r--r--erts/emulator/beam/erl_init.c16
-rw-r--r--erts/emulator/beam/erl_instrument.c74
-rw-r--r--erts/emulator/beam/erl_instrument.h4
-rw-r--r--erts/emulator/beam/erl_lock_count.c4
-rw-r--r--erts/emulator/beam/erl_math.c5
-rw-r--r--erts/emulator/beam/erl_msacc.h8
-rw-r--r--erts/emulator/beam/erl_nif.c173
-rw-r--r--erts/emulator/beam/erl_nif.h15
-rw-r--r--erts/emulator/beam/erl_node_tables.c8
-rw-r--r--erts/emulator/beam/erl_node_tables.h6
-rw-r--r--erts/emulator/beam/erl_port.h4
-rw-r--r--erts/emulator/beam/erl_process.c72
-rw-r--r--erts/emulator/beam/erl_process.h20
-rw-r--r--erts/emulator/beam/erl_process_dict.c6
-rw-r--r--erts/emulator/beam/erl_process_dict.h6
-rw-r--r--erts/emulator/beam/erl_process_dump.c48
-rw-r--r--erts/emulator/beam/export.c2
-rw-r--r--erts/emulator/beam/export.h2
-rw-r--r--erts/emulator/beam/external.c2
-rw-r--r--erts/emulator/beam/global.h53
-rw-r--r--erts/emulator/beam/hash.c2
-rw-r--r--erts/emulator/beam/hash.h4
-rw-r--r--erts/emulator/beam/index.c2
-rw-r--r--erts/emulator/beam/index.h2
-rw-r--r--erts/emulator/beam/io.c4
-rw-r--r--erts/emulator/beam/module.c2
-rw-r--r--erts/emulator/beam/module.h2
-rw-r--r--erts/emulator/beam/register.c2
-rw-r--r--erts/emulator/beam/register.h2
-rw-r--r--erts/emulator/beam/sys.h21
-rw-r--r--erts/emulator/beam/utils.c37
-rw-r--r--erts/emulator/hipe/hipe_mode_switch.c7
-rw-r--r--erts/emulator/hipe/hipe_mode_switch.h2
-rw-r--r--erts/emulator/hipe/hipe_x86_signal.c2
-rw-r--r--erts/emulator/sys/common/erl_mmap.c14
-rw-r--r--erts/emulator/sys/common/erl_mmap.h5
-rw-r--r--erts/emulator/sys/common/erl_mseg.c20
-rw-r--r--erts/emulator/sys/common/erl_mseg.h4
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys.h4
-rw-r--r--erts/emulator/sys/unix/sys.c8
-rw-r--r--erts/emulator/sys/win32/erl_win_sys.h2
-rw-r--r--erts/emulator/sys/win32/sys.c9
-rw-r--r--erts/emulator/test/bif_SUITE.erl29
-rw-r--r--erts/emulator/test/code_SUITE.erl168
-rw-r--r--erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl186
-rw-r--r--erts/emulator/test/nif_SUITE.erl82
-rw-r--r--erts/emulator/test/nif_SUITE_data/Makefile.src8
-rw-r--r--erts/emulator/test/nif_SUITE_data/hipe_compiled.erl6
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c15
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_api_2_0/README5
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_drv_nif.h48
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_nif.h206
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_nif_api_funcs.h257
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_api_2_4/README6
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_drv_nif.h48
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_nif.h237
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_nif_api_funcs.h503
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.1.2_0.c4
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.1.2_4.c4
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.2.2_0.c4
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.2.2_4.c4
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.3.2_0.c4
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.3.2_4.c4
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.c15
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.erl29
-rw-r--r--erts/emulator/test/port_SUITE.erl25
-rw-r--r--erts/etc/unix/etp-commands.in123
-rw-r--r--erts/etc/unix/run_erl.c4
-rw-r--r--erts/include/internal/erl_printf.h7
-rw-r--r--erts/include/internal/erl_printf_format.h3
-rw-r--r--erts/lib_src/common/erl_printf.c37
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin55752 -> 55804 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin105884 -> 105984 bytes
-rw-r--r--erts/preloaded/ebin/erts_internal.beambin10872 -> 10896 bytes
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl23
-rw-r--r--erts/preloaded/src/erlang.erl16
-rw-r--r--erts/preloaded/src/erts_internal.erl3
-rw-r--r--erts/vsn.mk2
-rw-r--r--lib/common_test/src/Makefile1
-rw-r--r--lib/common_test/src/ct_default_gl.erl83
-rw-r--r--lib/common_test/src/ct_framework.erl14
-rw-r--r--lib/common_test/src/ct_logs.erl13
-rw-r--r--lib/common_test/src/ct_run.erl15
-rw-r--r--lib/common_test/src/ct_util.erl18
-rw-r--r--lib/common_test/src/ct_util.hrl1
-rw-r--r--lib/compiler/src/Makefile1
-rw-r--r--lib/compiler/src/beam_bool.erl765
-rw-r--r--lib/compiler/src/beam_dead.erl32
-rw-r--r--lib/compiler/src/beam_jump.erl32
-rw-r--r--lib/compiler/src/beam_type.erl1
-rw-r--r--lib/compiler/src/beam_utils.erl16
-rw-r--r--lib/compiler/src/beam_validator.erl1
-rw-r--r--lib/compiler/src/cerl.erl10
-rw-r--r--lib/compiler/src/cerl_clauses.erl9
-rw-r--r--lib/compiler/src/cerl_inline.erl11
-rw-r--r--lib/compiler/src/cerl_trees.erl9
-rw-r--r--lib/compiler/src/compile.erl16
-rw-r--r--lib/compiler/src/compiler.app.src1
-rw-r--r--lib/compiler/src/core_parse.yrl15
-rw-r--r--lib/compiler/src/erl_bifs.erl1
-rw-r--r--lib/compiler/src/rec_env.erl9
-rw-r--r--lib/compiler/src/sys_core_fold.erl147
-rw-r--r--lib/compiler/src/v3_codegen.erl20
-rw-r--r--lib/compiler/src/v3_core.erl32
-rw-r--r--lib/compiler/src/v3_kernel.erl474
-rw-r--r--lib/compiler/src/v3_kernel.hrl2
-rw-r--r--lib/compiler/src/v3_kernel_pp.erl9
-rw-r--r--lib/compiler/src/v3_life.erl4
-rw-r--r--lib/compiler/test/Makefile17
-rw-r--r--lib/compiler/test/beam_bool_SUITE.erl197
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl33
-rw-r--r--lib/compiler/test/compile_SUITE.erl134
-rw-r--r--lib/compiler/test/core_SUITE.erl20
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core147
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core98
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core98
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core82
-rw-r--r--lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core98
-rw-r--r--lib/compiler/test/core_fold_SUITE.erl20
-rw-r--r--lib/compiler/test/float_SUITE.erl7
-rw-r--r--lib/compiler/test/guard_SUITE.erl303
-rw-r--r--lib/compiler/test/lfe-core.patch97
-rw-r--r--lib/compiler/test/lfe-source.patch117
-rw-r--r--lib/compiler/test/lfe.readme31
-rw-r--r--lib/compiler/test/lfe_andor_SUITE.core2014
-rw-r--r--lib/compiler/test/lfe_guard_SUITE.core3438
-rw-r--r--lib/compiler/test/misc_SUITE.erl8
-rw-r--r--lib/compiler/test/record_SUITE_data/record_access_in_guards.erl63
-rw-r--r--lib/compiler/test/warnings_SUITE.erl136
-rw-r--r--lib/cosProperty/doc/src/notes.xml16
-rw-r--r--lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl2
-rw-r--r--lib/cosProperty/vsn.mk2
-rw-r--r--lib/crypto/c_src/crypto.c150
-rw-r--r--lib/crypto/src/crypto.erl625
-rw-r--r--lib/crypto/test/Makefile3
-rw-r--r--lib/crypto/test/blowfish_SUITE.erl25
-rw-r--r--lib/crypto/test/old_crypto_SUITE.erl2350
-rw-r--r--lib/dialyzer/RELEASE_NOTES2
-rw-r--r--lib/dialyzer/doc/manual.txt2
-rw-r--r--lib/dialyzer/doc/src/dialyzer.xml2
-rw-r--r--lib/dialyzer/doc/src/notes.xml4
-rw-r--r--lib/dialyzer/src/dialyzer.erl21
-rw-r--r--lib/dialyzer/src/dialyzer.hrl6
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_behaviours.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_callgraph.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_cl.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_cl_parse.erl9
-rw-r--r--lib/dialyzer/src/dialyzer_codeserver.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl42
-rw-r--r--lib/dialyzer/src/dialyzer_coordinator.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_dataflow.erl64
-rw-r--r--lib/dialyzer/src/dialyzer_dep.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_explanation.erl10
-rw-r--r--lib/dialyzer/src/dialyzer_gui_wx.erl9
-rw-r--r--lib/dialyzer/src/dialyzer_gui_wx.hrl12
-rw-r--r--lib/dialyzer/src/dialyzer_options.erl17
-rw-r--r--lib/dialyzer/src/dialyzer_plt.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_race_data_server.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_races.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_succ_typings.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_timing.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_typesig.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl7
-rw-r--r--lib/dialyzer/src/dialyzer_worker.erl7
-rw-r--r--lib/dialyzer/test/map_SUITE_data/results/map_in_guard24
-rw-r--r--lib/dialyzer/test/map_SUITE_data/results/opaque_key8
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/array4
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/dict18
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/ets6
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/my_queue2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/opaque2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/para4
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/queue6
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/rec4
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/simple46
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/timer4
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/union8
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/results/wings8
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_ig_moves.erl8
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_vectors.erl7
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/cerl.erl7
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/core_parse.hrl7
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer.hrl7
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_dataflow.erl7
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_races.erl7
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/recrec/erl_types.erl8
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl2
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/is_rec.erl6
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl8
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl26
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/timer/timer_use.erl4
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl4
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/guards2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/ms.erl8
-rw-r--r--lib/edoc/COPYING504
-rw-r--r--lib/edoc/doc/overview.edoc4
-rw-r--r--lib/edoc/include/edoc_doclet.hrl29
-rw-r--r--lib/edoc/src/edoc.erl33
-rw-r--r--lib/edoc/src/edoc.hrl29
-rw-r--r--lib/edoc/src/edoc_data.erl29
-rw-r--r--lib/edoc/src/edoc_doclet.erl29
-rw-r--r--lib/edoc/src/edoc_extract.erl29
-rw-r--r--lib/edoc/src/edoc_layout.erl29
-rw-r--r--lib/edoc/src/edoc_lib.erl29
-rw-r--r--lib/edoc/src/edoc_macros.erl29
-rw-r--r--lib/edoc/src/edoc_parser.yrl106
-rw-r--r--lib/edoc/src/edoc_refs.erl29
-rw-r--r--lib/edoc/src/edoc_report.erl29
-rw-r--r--lib/edoc/src/edoc_run.erl29
-rw-r--r--lib/edoc/src/edoc_tags.erl29
-rw-r--r--lib/edoc/src/edoc_types.erl29
-rw-r--r--lib/edoc/src/edoc_types.hrl29
-rw-r--r--lib/edoc/src/edoc_wiki.erl29
-rw-r--r--lib/edoc/src/otpsgml_layout.erl29
-rw-r--r--lib/eldap/doc/src/eldap.xml22
-rw-r--r--lib/erl_docgen/src/docgen_edoc_xml_cb.erl11
-rw-r--r--lib/eunit/COPYING504
-rw-r--r--lib/eunit/include/eunit.hrl33
-rw-r--r--lib/eunit/src/eunit.erl29
-rw-r--r--lib/eunit/src/eunit_autoexport.erl29
-rw-r--r--lib/eunit/src/eunit_data.erl29
-rw-r--r--lib/eunit/src/eunit_internal.hrl21
-rw-r--r--lib/eunit/src/eunit_lib.erl29
-rw-r--r--lib/eunit/src/eunit_listener.erl29
-rw-r--r--lib/eunit/src/eunit_proc.erl29
-rw-r--r--lib/eunit/src/eunit_serial.erl29
-rw-r--r--lib/eunit/src/eunit_server.erl29
-rw-r--r--lib/eunit/src/eunit_striptests.erl29
-rw-r--r--lib/eunit/src/eunit_surefire.erl29
-rw-r--r--lib/eunit/src/eunit_test.erl29
-rw-r--r--lib/eunit/src/eunit_tests.erl29
-rw-r--r--lib/eunit/src/eunit_tty.erl29
-rw-r--r--lib/hipe/amd64/hipe_amd64_assemble.erl9
-rw-r--r--lib/hipe/amd64/hipe_amd64_defuse.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_encode.erl51
-rw-r--r--lib/hipe/amd64/hipe_amd64_frame.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_liveness.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_main.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_pp.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_finalise.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_ls.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_naive.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_postconditions.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl7
-rw-r--r--lib/hipe/amd64/hipe_amd64_registers.erl7
-rw-r--r--lib/hipe/amd64/hipe_amd64_spill_restore.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_sse2.erl6
-rw-r--r--lib/hipe/amd64/hipe_amd64_subst.erl8
-rw-r--r--lib/hipe/amd64/hipe_amd64_x87.erl8
-rw-r--r--lib/hipe/amd64/hipe_rtl_to_amd64.erl8
-rw-r--r--lib/hipe/arm/hipe_arm.erl7
-rw-r--r--lib/hipe/arm/hipe_arm.hrl7
-rw-r--r--lib/hipe/arm/hipe_arm_assemble.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_cfg.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_defuse.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_encode.erl6
-rw-r--r--lib/hipe/arm/hipe_arm_finalise.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_frame.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_liveness_gpr.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_main.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_pp.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_ra.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_ra_finalise.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_ra_ls.erl6
-rw-r--r--lib/hipe/arm/hipe_arm_ra_naive.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_ra_postconditions.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_registers.erl7
-rw-r--r--lib/hipe/arm/hipe_arm_subst.erl7
-rw-r--r--lib/hipe/arm/hipe_rtl_to_arm.erl116
-rw-r--r--lib/hipe/cerl/cerl_cconv.erl9
-rw-r--r--lib/hipe/cerl/cerl_closurean.erl17
-rw-r--r--lib/hipe/cerl/cerl_hipe_primops.hrl17
-rw-r--r--lib/hipe/cerl/cerl_hipeify.erl9
-rw-r--r--lib/hipe/cerl/cerl_lib.erl10
-rw-r--r--lib/hipe/cerl/cerl_messagean.erl16
-rw-r--r--lib/hipe/cerl/cerl_pmatch.erl9
-rw-r--r--lib/hipe/cerl/cerl_prettypr.erl16
-rw-r--r--lib/hipe/cerl/cerl_to_icode.erl8
-rw-r--r--lib/hipe/cerl/cerl_typean.erl14
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl20
-rw-r--r--lib/hipe/cerl/erl_types.erl24
-rw-r--r--lib/hipe/flow/cfg.hrl8
-rw-r--r--lib/hipe/flow/cfg.inc6
-rw-r--r--lib/hipe/flow/ebb.inc6
-rw-r--r--lib/hipe/flow/hipe_bb.erl6
-rw-r--r--lib/hipe/flow/hipe_bb.hrl6
-rw-r--r--lib/hipe/flow/hipe_dominators.erl6
-rw-r--r--lib/hipe/flow/hipe_gen_cfg.erl9
-rw-r--r--lib/hipe/flow/liveness.inc6
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl34
-rw-r--r--lib/hipe/icode/hipe_icode.erl26
-rw-r--r--lib/hipe/icode/hipe_icode.hrl7
-rw-r--r--lib/hipe/icode/hipe_icode_bincomp.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_call_elim.erl10
-rw-r--r--lib/hipe/icode/hipe_icode_callgraph.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_cfg.erl8
-rw-r--r--lib/hipe/icode/hipe_icode_coordinator.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_ebb.erl9
-rw-r--r--lib/hipe/icode/hipe_icode_exceptions.erl9
-rw-r--r--lib/hipe/icode/hipe_icode_fp.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_heap_test.erl9
-rw-r--r--lib/hipe/icode/hipe_icode_inline_bifs.erl8
-rw-r--r--lib/hipe/icode/hipe_icode_instruction_counter.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_liveness.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_mulret.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_pp.erl10
-rw-r--r--lib/hipe/icode/hipe_icode_primops.erl14
-rw-r--r--lib/hipe/icode/hipe_icode_primops.hrl8
-rw-r--r--lib/hipe/icode/hipe_icode_range.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_split_arith.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_ssa.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_ssa_const_prop.erl49
-rw-r--r--lib/hipe/icode/hipe_icode_ssa_copy_prop.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_type.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_type.hrl7
-rw-r--r--lib/hipe/llvm/hipe_llvm_main.erl14
-rw-r--r--lib/hipe/llvm/hipe_rtl_to_llvm.erl177
-rw-r--r--lib/hipe/main/hipe.erl95
-rw-r--r--lib/hipe/main/hipe.hrl.src16
-rw-r--r--lib/hipe/main/hipe_main.erl6
-rw-r--r--lib/hipe/misc/hipe_consttab.erl6
-rw-r--r--lib/hipe/misc/hipe_consttab.hrl6
-rw-r--r--lib/hipe/misc/hipe_data_pp.erl7
-rw-r--r--lib/hipe/misc/hipe_gensym.erl8
-rw-r--r--lib/hipe/misc/hipe_pack_constants.erl8
-rw-r--r--lib/hipe/misc/hipe_sdi.erl6
-rw-r--r--lib/hipe/misc/hipe_sdi.hrl8
-rw-r--r--lib/hipe/misc/hipe_segment_trees.erl7
-rw-r--r--lib/hipe/opt/hipe_schedule.erl7
-rw-r--r--lib/hipe/opt/hipe_schedule_prio.erl6
-rw-r--r--lib/hipe/opt/hipe_spillmin.erl8
-rw-r--r--lib/hipe/opt/hipe_spillmin_color.erl6
-rw-r--r--lib/hipe/opt/hipe_spillmin_scan.erl6
-rw-r--r--lib/hipe/opt/hipe_target_machine.erl7
-rw-r--r--lib/hipe/opt/hipe_ultra_mod2.erl7
-rw-r--r--lib/hipe/opt/hipe_ultra_prio.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc.erl8
-rw-r--r--lib/hipe/ppc/hipe_ppc.hrl8
-rw-r--r--lib/hipe/ppc/hipe_ppc_assemble.erl8
-rw-r--r--lib/hipe/ppc/hipe_ppc_cfg.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_defuse.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_encode.erl6
-rw-r--r--lib/hipe/ppc/hipe_ppc_finalise.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_frame.erl12
-rw-r--r--lib/hipe/ppc/hipe_ppc_liveness_all.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_liveness_fpr.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_liveness_gpr.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_main.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_pp.erl13
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_finalise.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_ls.erl6
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_naive.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_postconditions.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_registers.erl7
-rw-r--r--lib/hipe/ppc/hipe_ppc_subst.erl7
-rw-r--r--lib/hipe/ppc/hipe_rtl_to_ppc.erl95
-rw-r--r--lib/hipe/regalloc/hipe_adj_list.erl6
-rw-r--r--lib/hipe/regalloc/hipe_amd64_specific.erl9
-rw-r--r--lib/hipe/regalloc/hipe_amd64_specific_sse2.erl7
-rw-r--r--lib/hipe/regalloc/hipe_amd64_specific_x87.erl9
-rw-r--r--lib/hipe/regalloc/hipe_arm_specific.erl7
-rw-r--r--lib/hipe/regalloc/hipe_coalescing_regalloc.erl6
-rw-r--r--lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl6
-rw-r--r--lib/hipe/regalloc/hipe_ig.erl6
-rw-r--r--lib/hipe/regalloc/hipe_ig_moves.erl6
-rw-r--r--lib/hipe/regalloc/hipe_ls_regalloc.erl6
-rw-r--r--lib/hipe/regalloc/hipe_moves.erl7
-rw-r--r--lib/hipe/regalloc/hipe_node_sets.erl7
-rw-r--r--lib/hipe/regalloc/hipe_optimistic_regalloc.erl6
-rw-r--r--lib/hipe/regalloc/hipe_ppc_specific.erl7
-rw-r--r--lib/hipe/regalloc/hipe_ppc_specific_fp.erl7
-rw-r--r--lib/hipe/regalloc/hipe_reg_worklists.erl6
-rw-r--r--lib/hipe/regalloc/hipe_regalloc_loop.erl6
-rw-r--r--lib/hipe/regalloc/hipe_regalloc_prepass.erl6
-rw-r--r--lib/hipe/regalloc/hipe_sparc_specific.erl7
-rw-r--r--lib/hipe/regalloc/hipe_sparc_specific_fp.erl7
-rw-r--r--lib/hipe/regalloc/hipe_spillcost.erl7
-rw-r--r--lib/hipe/regalloc/hipe_spillcost.hrl8
-rw-r--r--lib/hipe/regalloc/hipe_temp_map.erl7
-rw-r--r--lib/hipe/regalloc/hipe_x86_specific.erl7
-rw-r--r--lib/hipe/regalloc/hipe_x86_specific_x87.erl7
-rw-r--r--lib/hipe/rtl/hipe_icode2rtl.erl9
-rw-r--r--lib/hipe/rtl/hipe_rtl.erl102
-rw-r--r--lib/hipe/rtl/hipe_rtl.hrl7
-rw-r--r--lib/hipe/rtl/hipe_rtl_arch.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith.inc6
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith_32.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith_64.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary.erl10
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_construct.erl19
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_match.erl48
-rw-r--r--lib/hipe/rtl/hipe_rtl_cfg.erl14
-rw-r--r--lib/hipe/rtl/hipe_rtl_cleanup_const.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_exceptions.erl8
-rw-r--r--lib/hipe/rtl/hipe_rtl_lcm.erl7
-rw-r--r--lib/hipe/rtl/hipe_rtl_liveness.erl8
-rw-r--r--lib/hipe/rtl/hipe_rtl_mk_switch.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_primops.erl9
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa.erl8
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl7
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl88
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssapre.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_symbolic.erl6
-rw-r--r--lib/hipe/rtl/hipe_rtl_varmap.erl7
-rw-r--r--lib/hipe/rtl/hipe_tagscheme.erl132
-rw-r--r--lib/hipe/sparc/hipe_rtl_to_sparc.erl146
-rw-r--r--lib/hipe/sparc/hipe_sparc.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc.hrl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_assemble.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_cfg.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_defuse.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_encode.erl6
-rw-r--r--lib/hipe/sparc/hipe_sparc_finalise.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_frame.erl12
-rw-r--r--lib/hipe/sparc/hipe_sparc_liveness_all.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_liveness_fpr.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_liveness_gpr.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_main.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_pp.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_finalise.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_ls.erl6
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_naive.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_postconditions.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_registers.erl7
-rw-r--r--lib/hipe/sparc/hipe_sparc_subst.erl7
-rw-r--r--lib/hipe/ssa/hipe_ssa.inc28
-rw-r--r--lib/hipe/ssa/hipe_ssa_const_prop.inc6
-rw-r--r--lib/hipe/ssa/hipe_ssa_copy_prop.inc6
-rw-r--r--lib/hipe/ssa/hipe_ssa_liveness.inc6
-rw-r--r--lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl48
-rw-r--r--lib/hipe/test/maps_SUITE_data/maps_redundant_branch_is_key.erl14
-rw-r--r--lib/hipe/tools/hipe_jit.erl6
-rw-r--r--lib/hipe/tools/hipe_profile.erl7
-rw-r--r--lib/hipe/tools/hipe_timer.erl7
-rw-r--r--lib/hipe/util/hipe_digraph.erl6
-rw-r--r--lib/hipe/util/hipe_dot.erl6
-rw-r--r--lib/hipe/util/hipe_timing.erl6
-rw-r--r--lib/hipe/util/hipe_vectors.erl6
-rw-r--r--lib/hipe/x86/NOTES.OPTIM2
-rw-r--r--lib/hipe/x86/NOTES.RA2
-rw-r--r--lib/hipe/x86/hipe_rtl_to_x86.erl91
-rw-r--r--lib/hipe/x86/hipe_x86.erl19
-rw-r--r--lib/hipe/x86/hipe_x86.hrl7
-rw-r--r--lib/hipe/x86/hipe_x86_assemble.erl60
-rw-r--r--lib/hipe/x86/hipe_x86_cfg.erl7
-rw-r--r--lib/hipe/x86/hipe_x86_defuse.erl9
-rw-r--r--lib/hipe/x86/hipe_x86_encode.erl30
-rw-r--r--lib/hipe/x86/hipe_x86_encode.txt2
-rw-r--r--lib/hipe/x86/hipe_x86_frame.erl14
-rw-r--r--lib/hipe/x86/hipe_x86_liveness.erl6
-rw-r--r--lib/hipe/x86/hipe_x86_main.erl7
-rw-r--r--lib/hipe/x86/hipe_x86_postpass.erl45
-rw-r--r--lib/hipe/x86/hipe_x86_pp.erl12
-rw-r--r--lib/hipe/x86/hipe_x86_ra.erl7
-rw-r--r--lib/hipe/x86/hipe_x86_ra_finalise.erl11
-rw-r--r--lib/hipe/x86/hipe_x86_ra_ls.erl6
-rw-r--r--lib/hipe/x86/hipe_x86_ra_naive.erl13
-rw-r--r--lib/hipe/x86/hipe_x86_ra_postconditions.erl17
-rw-r--r--lib/hipe/x86/hipe_x86_registers.erl8
-rw-r--r--lib/hipe/x86/hipe_x86_spill_restore.erl6
-rw-r--r--lib/hipe/x86/hipe_x86_subst.erl7
-rw-r--r--lib/hipe/x86/hipe_x86_x87.erl6
-rw-r--r--lib/inets/doc/src/http_uri.xml2
-rw-r--r--lib/inets/src/http_client/httpc_request.erl6
-rw-r--r--lib/kernel/doc/src/code.xml42
-rw-r--r--lib/kernel/doc/src/file.xml8
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml6
-rw-r--r--lib/kernel/doc/src/gen_udp.xml6
-rw-r--r--lib/kernel/doc/src/inet.xml5
-rw-r--r--lib/kernel/doc/src/rpc.xml16
-rw-r--r--lib/kernel/include/dist_util.hrl2
-rw-r--r--lib/kernel/src/code.erl160
-rw-r--r--lib/kernel/src/gen_sctp.erl2
-rw-r--r--lib/kernel/src/gen_tcp.erl2
-rw-r--r--lib/kernel/src/gen_udp.erl2
-rw-r--r--lib/kernel/src/global.erl16
-rw-r--r--lib/kernel/src/hipe_ext_format.hrl12
-rw-r--r--lib/kernel/src/hipe_unified_loader.erl11
-rw-r--r--lib/kernel/src/kernel.appup.src6
-rw-r--r--lib/kernel/src/net_kernel.erl4
-rw-r--r--lib/kernel/test/code_SUITE.erl180
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap3.xmlsrc2
-rw-r--r--lib/mnesia/src/Makefile1
-rw-r--r--lib/mnesia/src/mnesia.app.src5
-rw-r--r--lib/mnesia/src/mnesia.erl309
-rw-r--r--lib/mnesia/src/mnesia_app.erl41
-rw-r--r--lib/mnesia/src/mnesia_lib.erl16
-rw-r--r--lib/mnesia/src/mnesia_sup.erl33
-rw-r--r--lib/mnesia/test/ext_test.erl4
-rw-r--r--lib/mnesia/test/mnesia_test_lib.erl1
-rwxr-xr-xlib/observer/priv/bin/cdv2
-rw-r--r--lib/observer/priv/bin/cdv.bat2
-rw-r--r--lib/observer/priv/crashdump_viewer.tool2
-rw-r--r--lib/observer/priv/crashdump_viewer/collapsd.gifbin141 -> 0 bytes
-rw-r--r--lib/observer/priv/crashdump_viewer/exploded.gifbin143 -> 0 bytes
-rw-r--r--lib/observer/src/Makefile10
-rw-r--r--lib/odbc/configure.in24
-rw-r--r--lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl7
-rw-r--r--lib/orber/doc/src/notes.xml14
-rw-r--r--lib/orber/src/corba.erl2
-rw-r--r--lib/orber/src/orber_ifr_contained.erl2
-rw-r--r--lib/orber/vsn.mk2
-rw-r--r--lib/public_key/doc/src/public_key.xml30
-rw-r--r--lib/public_key/src/public_key.erl39
-rw-r--r--lib/public_key/test/public_key_SUITE.erl82
-rw-r--r--lib/reltool/doc/src/reltool_examples.xml2
-rw-r--r--lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat5
-rw-r--r--lib/sasl/src/sasl.appup.src6
-rw-r--r--lib/sasl/src/systools_make.erl4
-rw-r--r--lib/sasl/test/systools_SUITE.erl35
-rw-r--r--lib/sasl/test/test_lib.hrl4
-rw-r--r--lib/ssh/doc/src/introduction.xml2
-rw-r--r--lib/ssh/doc/src/ssh.xml14
-rw-r--r--lib/ssh/doc/src/ssh_protocol.xml2
-rw-r--r--lib/ssh/src/Makefile2
-rw-r--r--lib/ssh/src/ssh.erl9
-rw-r--r--lib/ssh/src/ssh_channel.erl2
-rw-r--r--lib/ssh/src/ssh_connection.erl3
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl25
-rw-r--r--lib/ssh/src/ssh_dbg.erl10
-rw-r--r--lib/ssh/src/ssh_dbg.hrl27
-rw-r--r--lib/ssh/src/ssh_transport.erl16
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl33
-rw-r--r--lib/ssh/test/ssh_connection_SUITE.erl140
-rw-r--r--lib/ssh/test/ssh_options_SUITE.erl126
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE.erl40
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE.erl20
-rw-r--r--lib/ssh/test/ssh_test_lib.erl62
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE.erl116
-rw-r--r--lib/ssl/doc/src/ssl.xml31
-rw-r--r--lib/ssl/doc/src/ssl_distribution.xml2
-rw-r--r--lib/ssl/src/ssl.erl56
-rw-r--r--lib/ssl/src/ssl_connection.erl20
-rw-r--r--lib/ssl/src/ssl_handshake.erl45
-rw-r--r--lib/ssl/src/ssl_internal.hrl2
-rw-r--r--lib/ssl/src/tls_handshake.erl6
-rw-r--r--lib/ssl/src/tls_v1.erl33
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE.erl245
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl47
-rw-r--r--lib/ssl/test/ssl_certificate_verify_SUITE.erl3
-rw-r--r--lib/ssl/test/ssl_packet_SUITE.erl6
-rw-r--r--lib/ssl/test/ssl_test_lib.erl63
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl2
-rw-r--r--lib/stdlib/doc/src/assert_hrl.xml33
-rw-r--r--lib/stdlib/doc/src/c.xml18
-rw-r--r--lib/stdlib/doc/src/dets.xml61
-rw-r--r--lib/stdlib/doc/src/gen_statem.xml79
-rw-r--r--lib/stdlib/doc/src/maps.xml2
-rw-r--r--lib/stdlib/doc/src/math.xml1
-rw-r--r--lib/stdlib/doc/src/orddict.xml2
-rw-r--r--lib/stdlib/doc/src/ordsets.xml3
-rw-r--r--lib/stdlib/doc/src/proc_lib.xml6
-rw-r--r--lib/stdlib/doc/src/rand.xml35
-rw-r--r--lib/stdlib/doc/src/supervisor.xml6
-rw-r--r--lib/stdlib/include/assert.hrl184
-rw-r--r--lib/stdlib/src/Makefile2
-rw-r--r--lib/stdlib/src/array.erl14
-rw-r--r--lib/stdlib/src/c.erl14
-rw-r--r--lib/stdlib/src/dets.erl480
-rw-r--r--lib/stdlib/src/dets.hrl162
-rw-r--r--lib/stdlib/src/dets_utils.erl26
-rw-r--r--lib/stdlib/src/dets_v8.erl1594
-rw-r--r--lib/stdlib/src/dets_v9.erl112
-rw-r--r--lib/stdlib/src/erl_parse.yrl47
-rw-r--r--lib/stdlib/src/error_logger_file_h.erl57
-rw-r--r--lib/stdlib/src/error_logger_tty_h.erl58
-rw-r--r--lib/stdlib/src/gb_sets.erl7
-rw-r--r--lib/stdlib/src/gb_trees.erl7
-rw-r--r--lib/stdlib/src/gen_statem.erl668
-rw-r--r--lib/stdlib/src/math.erl8
-rw-r--r--lib/stdlib/src/proc_lib.erl19
-rw-r--r--lib/stdlib/src/proplists.erl15
-rw-r--r--lib/stdlib/src/rand.erl140
-rw-r--r--lib/stdlib/src/sets.erl66
-rw-r--r--lib/stdlib/src/shell_default.erl4
-rw-r--r--lib/stdlib/src/stdlib.app.src1
-rw-r--r--lib/stdlib/src/stdlib.appup.src6
-rw-r--r--lib/stdlib/test/base64_SUITE.erl41
-rw-r--r--lib/stdlib/test/dets_SUITE.erl802
-rw-r--r--lib/stdlib/test/dets_SUITE_data/dets_test_v8b.detsbin37396 -> 0 bytes
-rw-r--r--lib/stdlib/test/dets_SUITE_data/dets_test_v8b_little_endian.detsbin37396 -> 0 bytes
-rw-r--r--lib/stdlib/test/dets_SUITE_data/version_8.dets (renamed from lib/stdlib/test/dets_SUITE_data/version_r2d.dets)bin33885 -> 35143 bytes
-rw-r--r--lib/stdlib/test/dets_SUITE_data/version_r3b02.detsbin34484 -> 0 bytes
-rw-r--r--lib/stdlib/test/error_logger_h_SUITE.erl4
-rw-r--r--lib/stdlib/test/ets_SUITE.erl282
-rw-r--r--lib/stdlib/test/gen_statem_SUITE.erl36
-rw-r--r--lib/stdlib/test/proc_lib_SUITE.erl31
-rw-r--r--lib/stdlib/test/rand_SUITE.erl208
-rw-r--r--lib/stdlib/test/tar_SUITE.erl26
-rw-r--r--lib/syntax_tools/AUTHORS2
-rw-r--r--lib/syntax_tools/COPYING504
-rw-r--r--lib/syntax_tools/src/epp_dodger.erl29
-rw-r--r--lib/syntax_tools/src/erl_comment_scan.erl29
-rw-r--r--lib/syntax_tools/src/erl_prettypr.erl29
-rw-r--r--lib/syntax_tools/src/erl_recomment.erl29
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl33
-rw-r--r--lib/syntax_tools/src/erl_syntax_lib.erl33
-rw-r--r--lib/syntax_tools/src/erl_tidy.erl33
-rw-r--r--lib/syntax_tools/src/igor.erl33
-rw-r--r--lib/syntax_tools/src/merl.erl10
-rw-r--r--lib/syntax_tools/src/merl_tests.erl10
-rw-r--r--lib/syntax_tools/src/merl_transform.erl10
-rw-r--r--lib/syntax_tools/src/prettypr.erl29
-rw-r--r--lib/syntax_tools/syntax_tools.pub13
-rw-r--r--lib/syntax_tools/test/syntax_tools_SUITE.erl6
-rw-r--r--lib/tools/emacs/Makefile1
-rw-r--r--lib/tools/emacs/erlang-edoc.el2
-rw-r--r--lib/tools/emacs/erlang-start.el14
-rw-r--r--lib/tools/emacs/erlang.el30
-rw-r--r--lib/tools/emacs/erldoc.el508
-rw-r--r--lib/tools/src/fprof.erl6
-rw-r--r--lib/typer/src/typer.erl7
-rw-r--r--lib/wx/api_gen/gl_gen.erl33
-rw-r--r--lib/wx/api_gen/gl_gen_c.erl31
-rw-r--r--lib/wx/api_gen/gl_gen_erl.erl41
-rw-r--r--lib/wx/api_gen/glapi.conf6
-rw-r--r--lib/wx/api_gen/wx_gen_cpp.erl3
-rw-r--r--lib/wx/c_src/gen/gl_funcs.cpp1052
-rw-r--r--lib/wx/c_src/gen/wxe_events.cpp2
-rw-r--r--lib/wx/src/gen/gl.erl1209
-rw-r--r--lib/wx/src/gen/glu.erl4
-rw-r--r--lib/xmerl/notes.html28
-rw-r--r--lib/xmerl/xmerl.pub19
-rw-r--r--otp_versions.table1
-rw-r--r--system/COPYRIGHT128
-rw-r--r--system/doc/design_principles/applications.xml160
-rw-r--r--system/doc/design_principles/statem.xml29
-rw-r--r--system/doc/design_principles/sup_princ.xml4
788 files changed, 18273 insertions, 15012 deletions
diff --git a/.gitignore b/.gitignore
index 71350ca1b9..fdbf0d2d5f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,7 @@ i386-pc-solaris[0-9]*.[0-9]*
i386-unknown-freebsd[0-9]*.[0-9]*
tile-tilera-linux-gnu
powerpc-unknown-linux-gnu
+aarch64-unknown-linux-gnu
i386-elf-ose
powerpc-unknown-ose
diff --git a/.travis.yml b/.travis.yml
index 48d8031bd0..01586b8ccb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -32,9 +32,16 @@ script:
- ./otp_build all -a
after_success:
+ - $ERL_TOP/bin/dialyzer --build_plt --apps asn1 compiler crypto dialyzer edoc erts et hipe inets kernel mnesia observer public_key runtime_tools snmp ssh ssl stdlib syntax_tools wx xmerl --statistics
+ - $ERL_TOP/bin/dialyzer -n -Wunknown -Wunmatched_returns --apps compiler erts kernel stdlib --statistics
+ - $ERL_TOP/bin/dialyzer -n -Wunknown -Wunmatched_returns --apps asn1 crypto dialyzer --statistics
+ - $ERL_TOP/bin/dialyzer -n -Wunknown -Wunmatched_returns --apps hipe parsetools public_key --statistics
+ - $ERL_TOP/bin/dialyzer -n -Wunknown -Wunmatched_returns --apps runtime_tools sasl tools --statistics
+ - $ERL_TOP/bin/dialyzer -n --apps common_test debugger edoc --statistics
+ - $ERL_TOP/bin/dialyzer -n --apps inets mnesia observer --statistics
+ - $ERL_TOP/bin/dialyzer -n --apps ssh ssl syntax_tools --statistics
+ - $ERL_TOP/bin/dialyzer -n --apps tools wx xmerl --statistics
- ./otp_build tests && make release_docs
after_script:
- cd $ERL_TOP/release/tests/test_server && $ERL_TOP/bin/erl -s ts install -s ts smoke_test batch -s init stop
-
-
diff --git a/HOWTO/INSTALL.md b/HOWTO/INSTALL.md
index 8632f46264..8587774c12 100644
--- a/HOWTO/INSTALL.md
+++ b/HOWTO/INSTALL.md
@@ -564,6 +564,10 @@ as before, but the build process will take a much longer time.
> automatically when `make` is invoked from `$ERL_TOP` with either the
> `clean` target, or the default target. It is also automatically invoked
> if `./otp_build remove_prebuilt_files` is invoked.
+>
+> If you need to verify the bootstrap beam files match the provided
+> source files, use `./otp_build update_primary` to create a new commit that
+> contains differences, if any exist.
#### How to Build a Debug Enabled Erlang RunTime System ####
diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot
index 4c0f9181b0..68dc2a5f61 100644
--- a/bootstrap/bin/start.boot
+++ b/bootstrap/bin/start.boot
Binary files differ
diff --git a/bootstrap/bin/start_clean.boot b/bootstrap/bin/start_clean.boot
index 4c0f9181b0..68dc2a5f61 100644
--- a/bootstrap/bin/start_clean.boot
+++ b/bootstrap/bin/start_clean.boot
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_bool.beam b/bootstrap/lib/compiler/ebin/beam_bool.beam
deleted file mode 100644
index 37f368190e..0000000000
--- a/bootstrap/lib/compiler/ebin/beam_bool.beam
+++ /dev/null
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_bsm.beam b/bootstrap/lib/compiler/ebin/beam_bsm.beam
index 1a7009c849..f52d74d1dc 100644
--- a/bootstrap/lib/compiler/ebin/beam_bsm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_bsm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_dead.beam b/bootstrap/lib/compiler/ebin/beam_dead.beam
index 8f5de4c19f..febe5c1e5f 100644
--- a/bootstrap/lib/compiler/ebin/beam_dead.beam
+++ b/bootstrap/lib/compiler/ebin/beam_dead.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_dict.beam b/bootstrap/lib/compiler/ebin/beam_dict.beam
index 665512eae1..0f85080a31 100644
--- a/bootstrap/lib/compiler/ebin/beam_dict.beam
+++ b/bootstrap/lib/compiler/ebin/beam_dict.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_disasm.beam b/bootstrap/lib/compiler/ebin/beam_disasm.beam
index 3512deb0d3..f99e90ea72 100644
--- a/bootstrap/lib/compiler/ebin/beam_disasm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_disasm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_except.beam b/bootstrap/lib/compiler/ebin/beam_except.beam
index 03fc2edd02..361d41017c 100644
--- a/bootstrap/lib/compiler/ebin/beam_except.beam
+++ b/bootstrap/lib/compiler/ebin/beam_except.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_jump.beam b/bootstrap/lib/compiler/ebin/beam_jump.beam
index 16db9eb358..fa1d85ad04 100644
--- a/bootstrap/lib/compiler/ebin/beam_jump.beam
+++ b/bootstrap/lib/compiler/ebin/beam_jump.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_type.beam b/bootstrap/lib/compiler/ebin/beam_type.beam
index 19c85f36d2..5435bcf26b 100644
--- a/bootstrap/lib/compiler/ebin/beam_type.beam
+++ b/bootstrap/lib/compiler/ebin/beam_type.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_utils.beam b/bootstrap/lib/compiler/ebin/beam_utils.beam
index 52c25a2ec6..e45b4ef895 100644
--- a/bootstrap/lib/compiler/ebin/beam_utils.beam
+++ b/bootstrap/lib/compiler/ebin/beam_utils.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_validator.beam b/bootstrap/lib/compiler/ebin/beam_validator.beam
index f1a93dc4df..1b1e42b6b1 100644
--- a/bootstrap/lib/compiler/ebin/beam_validator.beam
+++ b/bootstrap/lib/compiler/ebin/beam_validator.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl.beam b/bootstrap/lib/compiler/ebin/cerl.beam
index e432edd537..24c039780a 100644
--- a/bootstrap/lib/compiler/ebin/cerl.beam
+++ b/bootstrap/lib/compiler/ebin/cerl.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/compile.beam b/bootstrap/lib/compiler/ebin/compile.beam
index 86d7a86aa2..721b86c92c 100644
--- a/bootstrap/lib/compiler/ebin/compile.beam
+++ b/bootstrap/lib/compiler/ebin/compile.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/compiler.app b/bootstrap/lib/compiler/ebin/compiler.app
index 5842aff4f1..237993f080 100644
--- a/bootstrap/lib/compiler/ebin/compiler.app
+++ b/bootstrap/lib/compiler/ebin/compiler.app
@@ -24,7 +24,6 @@
beam_a,
beam_asm,
beam_block,
- beam_bool,
beam_bs,
beam_bsm,
beam_clean,
diff --git a/bootstrap/lib/compiler/ebin/core_lint.beam b/bootstrap/lib/compiler/ebin/core_lint.beam
index fa345d2da4..4c037ee7b0 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_scan.beam b/bootstrap/lib/compiler/ebin/core_scan.beam
index 3017a4e026..e56ef9afd8 100644
--- a/bootstrap/lib/compiler/ebin/core_scan.beam
+++ b/bootstrap/lib/compiler/ebin/core_scan.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/erl_bifs.beam b/bootstrap/lib/compiler/ebin/erl_bifs.beam
index 3ff1f7c5a0..f96a9698c4 100644
--- a/bootstrap/lib/compiler/ebin/erl_bifs.beam
+++ b/bootstrap/lib/compiler/ebin/erl_bifs.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_core_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam
index 48171c8fd2..180875b297 100644
--- a/bootstrap/lib/compiler/ebin/sys_core_fold.beam
+++ b/bootstrap/lib/compiler/ebin/sys_core_fold.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_core_inline.beam b/bootstrap/lib/compiler/ebin/sys_core_inline.beam
index 2f44e76e87..821eb13469 100644
--- a/bootstrap/lib/compiler/ebin/sys_core_inline.beam
+++ b/bootstrap/lib/compiler/ebin/sys_core_inline.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_codegen.beam b/bootstrap/lib/compiler/ebin/v3_codegen.beam
index 8a6b8d912c..65f093a575 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 61963adb8f..9f5c4a45bf 100644
--- a/bootstrap/lib/compiler/ebin/v3_core.beam
+++ b/bootstrap/lib/compiler/ebin/v3_core.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_kernel.beam b/bootstrap/lib/compiler/ebin/v3_kernel.beam
index d3fe183fee..509ef4ffa0 100644
--- a/bootstrap/lib/compiler/ebin/v3_kernel.beam
+++ b/bootstrap/lib/compiler/ebin/v3_kernel.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam b/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam
index 2ded237ea4..7995c58cac 100644
--- a/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam
+++ b/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_life.beam b/bootstrap/lib/compiler/ebin/v3_life.beam
index 8ffe24ca24..fb35981da8 100644
--- a/bootstrap/lib/compiler/ebin/v3_life.beam
+++ b/bootstrap/lib/compiler/ebin/v3_life.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/application_controller.beam b/bootstrap/lib/kernel/ebin/application_controller.beam
index be2334575d..ebe2044b6f 100644
--- a/bootstrap/lib/kernel/ebin/application_controller.beam
+++ b/bootstrap/lib/kernel/ebin/application_controller.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/application_master.beam b/bootstrap/lib/kernel/ebin/application_master.beam
index da770c5a84..9ca23b0322 100644
--- a/bootstrap/lib/kernel/ebin/application_master.beam
+++ b/bootstrap/lib/kernel/ebin/application_master.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/code.beam b/bootstrap/lib/kernel/ebin/code.beam
index cfcce2dc20..bb9ca635c4 100644
--- a/bootstrap/lib/kernel/ebin/code.beam
+++ b/bootstrap/lib/kernel/ebin/code.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/code_server.beam b/bootstrap/lib/kernel/ebin/code_server.beam
index e369cc2f36..c697a6574e 100644
--- a/bootstrap/lib/kernel/ebin/code_server.beam
+++ b/bootstrap/lib/kernel/ebin/code_server.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/disk_log.beam b/bootstrap/lib/kernel/ebin/disk_log.beam
index 7a4e3cf574..c88421ac14 100644
--- a/bootstrap/lib/kernel/ebin/disk_log.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/dist_ac.beam b/bootstrap/lib/kernel/ebin/dist_ac.beam
index ee709b6b18..fed7ee342f 100644
--- a/bootstrap/lib/kernel/ebin/dist_ac.beam
+++ b/bootstrap/lib/kernel/ebin/dist_ac.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/dist_util.beam b/bootstrap/lib/kernel/ebin/dist_util.beam
index 8e92868b01..5b3280c66d 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/erts_debug.beam b/bootstrap/lib/kernel/ebin/erts_debug.beam
index 0bbfe109c8..8a4241c25f 100644
--- a/bootstrap/lib/kernel/ebin/erts_debug.beam
+++ b/bootstrap/lib/kernel/ebin/erts_debug.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/file.beam b/bootstrap/lib/kernel/ebin/file.beam
index ac966359b7..ac65edf298 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 2e7155b8f6..57587353aa 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/gen_sctp.beam b/bootstrap/lib/kernel/ebin/gen_sctp.beam
index fca569c779..c98d25a3d0 100644
--- a/bootstrap/lib/kernel/ebin/gen_sctp.beam
+++ b/bootstrap/lib/kernel/ebin/gen_sctp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/global.beam b/bootstrap/lib/kernel/ebin/global.beam
index 8dea0c3d14..09ac326ecb 100644
--- a/bootstrap/lib/kernel/ebin/global.beam
+++ b/bootstrap/lib/kernel/ebin/global.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/global_group.beam b/bootstrap/lib/kernel/ebin/global_group.beam
index 8bd51c2424..778972ea34 100644
--- a/bootstrap/lib/kernel/ebin/global_group.beam
+++ b/bootstrap/lib/kernel/ebin/global_group.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/group.beam b/bootstrap/lib/kernel/ebin/group.beam
index c2c66f77ec..b424be4aa2 100644
--- a/bootstrap/lib/kernel/ebin/group.beam
+++ b/bootstrap/lib/kernel/ebin/group.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/heart.beam b/bootstrap/lib/kernel/ebin/heart.beam
index 2ab7ef9d9f..a76b19c23b 100644
--- a/bootstrap/lib/kernel/ebin/heart.beam
+++ b/bootstrap/lib/kernel/ebin/heart.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
index 73e95b03c7..ac0f44b7c8 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 3c18376789..c4554c1f35 100644
--- a/bootstrap/lib/kernel/ebin/inet.beam
+++ b/bootstrap/lib/kernel/ebin/inet.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet6_tcp.beam b/bootstrap/lib/kernel/ebin/inet6_tcp.beam
index 80e8e389a2..dbcc995df7 100644
--- a/bootstrap/lib/kernel/ebin/inet6_tcp.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_tcp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet6_udp.beam b/bootstrap/lib/kernel/ebin/inet6_udp.beam
index 39b9f0343b..c15d0da74a 100644
--- a/bootstrap/lib/kernel/ebin/inet6_udp.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_udp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_config.beam b/bootstrap/lib/kernel/ebin/inet_config.beam
index f49fa7a376..32fb3b0092 100644
--- a/bootstrap/lib/kernel/ebin/inet_config.beam
+++ b/bootstrap/lib/kernel/ebin/inet_config.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_db.beam b/bootstrap/lib/kernel/ebin/inet_db.beam
index c778948935..fc0c7b6bdc 100644
--- a/bootstrap/lib/kernel/ebin/inet_db.beam
+++ b/bootstrap/lib/kernel/ebin/inet_db.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_gethost_native.beam b/bootstrap/lib/kernel/ebin/inet_gethost_native.beam
index f090de9fba..71f42e52c5 100644
--- a/bootstrap/lib/kernel/ebin/inet_gethost_native.beam
+++ b/bootstrap/lib/kernel/ebin/inet_gethost_native.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_res.beam b/bootstrap/lib/kernel/ebin/inet_res.beam
index 71e06cf677..6214372945 100644
--- a/bootstrap/lib/kernel/ebin/inet_res.beam
+++ b/bootstrap/lib/kernel/ebin/inet_res.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_sctp.beam b/bootstrap/lib/kernel/ebin/inet_sctp.beam
index e2f574b514..153f7b389e 100644
--- a/bootstrap/lib/kernel/ebin/inet_sctp.beam
+++ b/bootstrap/lib/kernel/ebin/inet_sctp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_tcp.beam b/bootstrap/lib/kernel/ebin/inet_tcp.beam
index d0c9f09f6f..b8fc4cfd74 100644
--- a/bootstrap/lib/kernel/ebin/inet_tcp.beam
+++ b/bootstrap/lib/kernel/ebin/inet_tcp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam b/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam
index 623efc6e2d..41dd317f5d 100644
--- a/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam
+++ b/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_udp.beam b/bootstrap/lib/kernel/ebin/inet_udp.beam
index 11eb4f840f..aa2e0d4326 100644
--- a/bootstrap/lib/kernel/ebin/inet_udp.beam
+++ b/bootstrap/lib/kernel/ebin/inet_udp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/kernel.appup b/bootstrap/lib/kernel/ebin/kernel.appup
index 28f35f54d2..e4c1733c39 100644
--- a/bootstrap/lib/kernel/ebin/kernel.appup
+++ b/bootstrap/lib/kernel/ebin/kernel.appup
@@ -18,9 +18,7 @@
%% %CopyrightEnd%
{"5.1",
%% Up from - max one major revision back
- [{<<"5\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.*
+ [{<<"5\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-19.*
%% Down to - max one major revision back
- [{<<"5\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.*
+ [{<<"5\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-19.*
}.
diff --git a/bootstrap/lib/kernel/ebin/net_kernel.beam b/bootstrap/lib/kernel/ebin/net_kernel.beam
index b5098142eb..f4b36af447 100644
--- a/bootstrap/lib/kernel/ebin/net_kernel.beam
+++ b/bootstrap/lib/kernel/ebin/net_kernel.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/pg2.beam b/bootstrap/lib/kernel/ebin/pg2.beam
index a2d7b33378..d1fd670bb2 100644
--- a/bootstrap/lib/kernel/ebin/pg2.beam
+++ b/bootstrap/lib/kernel/ebin/pg2.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/ram_file.beam b/bootstrap/lib/kernel/ebin/ram_file.beam
index 6ac74978da..92ad2aecca 100644
--- a/bootstrap/lib/kernel/ebin/ram_file.beam
+++ b/bootstrap/lib/kernel/ebin/ram_file.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/rpc.beam b/bootstrap/lib/kernel/ebin/rpc.beam
index b9040c5427..313d83ecaa 100644
--- a/bootstrap/lib/kernel/ebin/rpc.beam
+++ b/bootstrap/lib/kernel/ebin/rpc.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/user.beam b/bootstrap/lib/kernel/ebin/user.beam
index d1f99cf6f2..d2527fe98c 100644
--- a/bootstrap/lib/kernel/ebin/user.beam
+++ b/bootstrap/lib/kernel/ebin/user.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/user_drv.beam b/bootstrap/lib/kernel/ebin/user_drv.beam
index bd9b1a3bce..86c3d7788e 100644
--- a/bootstrap/lib/kernel/ebin/user_drv.beam
+++ b/bootstrap/lib/kernel/ebin/user_drv.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/include/dist_util.hrl b/bootstrap/lib/kernel/include/dist_util.hrl
index 320e916c04..e3d2fe0eb6 100644
--- a/bootstrap/lib/kernel/include/dist_util.hrl
+++ b/bootstrap/lib/kernel/include/dist_util.hrl
@@ -29,7 +29,7 @@
-endif.
-ifdef(dist_trace).
--define(trace(Fmt,Args), io:format("~p ~p:~s",[erlang:now(),node(),lists:flatten(io_lib:format(Fmt, Args))])).
+-define(trace(Fmt,Args), io:format("~p ~p:~s",[erlang:timestamp(),node(),lists:flatten(io_lib:format(Fmt, Args))])).
% Use the one below for config-file (early boot) connection tracing
%-define(trace(Fmt,Args), erlang:display([erlang:now(),node(),lists:flatten(io_lib:format(Fmt, Args))])).
-define(trace_factor,8).
diff --git a/bootstrap/lib/stdlib/ebin/array.beam b/bootstrap/lib/stdlib/ebin/array.beam
index a965fe10d2..d3fa6db97b 100644
--- a/bootstrap/lib/stdlib/ebin/array.beam
+++ b/bootstrap/lib/stdlib/ebin/array.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/c.beam b/bootstrap/lib/stdlib/ebin/c.beam
index ce98ae5e14..865a9ac58c 100644
--- a/bootstrap/lib/stdlib/ebin/c.beam
+++ b/bootstrap/lib/stdlib/ebin/c.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/calendar.beam b/bootstrap/lib/stdlib/ebin/calendar.beam
index e71eebae3f..acd7620777 100644
--- a/bootstrap/lib/stdlib/ebin/calendar.beam
+++ b/bootstrap/lib/stdlib/ebin/calendar.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets.beam b/bootstrap/lib/stdlib/ebin/dets.beam
index a563317049..59f6e7670d 100644
--- a/bootstrap/lib/stdlib/ebin/dets.beam
+++ b/bootstrap/lib/stdlib/ebin/dets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_utils.beam b/bootstrap/lib/stdlib/ebin/dets_utils.beam
index b9a2ab35e3..d642fd6d8f 100644
--- a/bootstrap/lib/stdlib/ebin/dets_utils.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_utils.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_v8.beam b/bootstrap/lib/stdlib/ebin/dets_v8.beam
deleted file mode 100644
index b54b97234c..0000000000
--- a/bootstrap/lib/stdlib/ebin/dets_v8.beam
+++ /dev/null
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_v9.beam b/bootstrap/lib/stdlib/ebin/dets_v9.beam
index c8f604a5b0..3478b9c6d6 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 76713562bc..42ffaf8394 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/edlin.beam b/bootstrap/lib/stdlib/ebin/edlin.beam
index 8b1719eb0a..0df86f15b4 100644
--- a/bootstrap/lib/stdlib/ebin/edlin.beam
+++ b/bootstrap/lib/stdlib/ebin/edlin.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam
index 93245a4c3d..d01cef0a9a 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_anno.beam b/bootstrap/lib/stdlib/ebin/erl_anno.beam
index 72a255c88f..bb1bdeaf94 100644
--- a/bootstrap/lib/stdlib/ebin/erl_anno.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_anno.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_eval.beam b/bootstrap/lib/stdlib/ebin/erl_eval.beam
index 10f44892b8..e633572309 100644
--- a/bootstrap/lib/stdlib/ebin/erl_eval.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_eval.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
index 2933bd3970..5e5bff219c 100644
--- a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_internal.beam b/bootstrap/lib/stdlib/ebin/erl_internal.beam
index 544e523163..dc52205d63 100644
--- a/bootstrap/lib/stdlib/ebin/erl_internal.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_internal.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam
index c5c856eacd..665045daa8 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_scan.beam b/bootstrap/lib/stdlib/ebin/erl_scan.beam
index 2426bcf21b..0e32572156 100644
--- a/bootstrap/lib/stdlib/ebin/erl_scan.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_scan.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam b/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam
index b845a64248..181e44b3be 100644
--- a/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam
+++ b/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam b/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam
index af784cf79d..a2a92d2960 100644
--- a/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam
+++ b/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/escript.beam b/bootstrap/lib/stdlib/ebin/escript.beam
index afcbebab70..096c28e969 100644
--- a/bootstrap/lib/stdlib/ebin/escript.beam
+++ b/bootstrap/lib/stdlib/ebin/escript.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ets.beam b/bootstrap/lib/stdlib/ebin/ets.beam
index 27704a3fb9..291b988002 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/file_sorter.beam b/bootstrap/lib/stdlib/ebin/file_sorter.beam
index 4a484f1bcf..5e6d9fd2ac 100644
--- a/bootstrap/lib/stdlib/ebin/file_sorter.beam
+++ b/bootstrap/lib/stdlib/ebin/file_sorter.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/filename.beam b/bootstrap/lib/stdlib/ebin/filename.beam
index deca03bef1..65fa3a97ad 100644
--- a/bootstrap/lib/stdlib/ebin/filename.beam
+++ b/bootstrap/lib/stdlib/ebin/filename.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gb_trees.beam b/bootstrap/lib/stdlib/ebin/gb_trees.beam
index d8579c63cd..334e3649ae 100644
--- a/bootstrap/lib/stdlib/ebin/gb_trees.beam
+++ b/bootstrap/lib/stdlib/ebin/gb_trees.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen.beam b/bootstrap/lib/stdlib/ebin/gen.beam
index 08735311fb..82b820af23 100644
--- a/bootstrap/lib/stdlib/ebin/gen.beam
+++ b/bootstrap/lib/stdlib/ebin/gen.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_event.beam b/bootstrap/lib/stdlib/ebin/gen_event.beam
index 1553aeb6d0..023366da29 100644
--- a/bootstrap/lib/stdlib/ebin/gen_event.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_event.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_server.beam b/bootstrap/lib/stdlib/ebin/gen_server.beam
index e9f839df0c..ed71dcfeb7 100644
--- a/bootstrap/lib/stdlib/ebin/gen_server.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_server.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_statem.beam b/bootstrap/lib/stdlib/ebin/gen_statem.beam
index 748bd1b987..c795111f93 100644
--- a/bootstrap/lib/stdlib/ebin/gen_statem.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_statem.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib_fread.beam b/bootstrap/lib/stdlib/ebin/io_lib_fread.beam
index 62a4beeb2d..d0e9f703a5 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib_fread.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib_fread.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam b/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
index 32f83d1e4a..04f0b9aa78 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/log_mf_h.beam b/bootstrap/lib/stdlib/ebin/log_mf_h.beam
index d0e18955c7..6de9494e84 100644
--- a/bootstrap/lib/stdlib/ebin/log_mf_h.beam
+++ b/bootstrap/lib/stdlib/ebin/log_mf_h.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/math.beam b/bootstrap/lib/stdlib/ebin/math.beam
index 4726add7d1..a155482a64 100644
--- a/bootstrap/lib/stdlib/ebin/math.beam
+++ b/bootstrap/lib/stdlib/ebin/math.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ms_transform.beam b/bootstrap/lib/stdlib/ebin/ms_transform.beam
index a1e1c6ebb6..dd7a1f54ba 100644
--- a/bootstrap/lib/stdlib/ebin/ms_transform.beam
+++ b/bootstrap/lib/stdlib/ebin/ms_transform.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/proc_lib.beam b/bootstrap/lib/stdlib/ebin/proc_lib.beam
index 9e04a826fd..dc2ccd4937 100644
--- a/bootstrap/lib/stdlib/ebin/proc_lib.beam
+++ b/bootstrap/lib/stdlib/ebin/proc_lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/proplists.beam b/bootstrap/lib/stdlib/ebin/proplists.beam
index 464c0e0e57..b54b757d39 100644
--- a/bootstrap/lib/stdlib/ebin/proplists.beam
+++ b/bootstrap/lib/stdlib/ebin/proplists.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/qlc.beam b/bootstrap/lib/stdlib/ebin/qlc.beam
index eb50a910bf..0a69525558 100644
--- a/bootstrap/lib/stdlib/ebin/qlc.beam
+++ b/bootstrap/lib/stdlib/ebin/qlc.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/qlc_pt.beam b/bootstrap/lib/stdlib/ebin/qlc_pt.beam
index 49acba2704..25948e7878 100644
--- a/bootstrap/lib/stdlib/ebin/qlc_pt.beam
+++ b/bootstrap/lib/stdlib/ebin/qlc_pt.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/queue.beam b/bootstrap/lib/stdlib/ebin/queue.beam
index 85b1e81d16..4bb2570dee 100644
--- a/bootstrap/lib/stdlib/ebin/queue.beam
+++ b/bootstrap/lib/stdlib/ebin/queue.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/rand.beam b/bootstrap/lib/stdlib/ebin/rand.beam
index 31b7683780..9ec7185f9e 100644
--- a/bootstrap/lib/stdlib/ebin/rand.beam
+++ b/bootstrap/lib/stdlib/ebin/rand.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sets.beam b/bootstrap/lib/stdlib/ebin/sets.beam
index 29a5e2d83c..ef6e70298d 100644
--- a/bootstrap/lib/stdlib/ebin/sets.beam
+++ b/bootstrap/lib/stdlib/ebin/sets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/shell.beam b/bootstrap/lib/stdlib/ebin/shell.beam
index fd556a15ef..00164c704e 100644
--- a/bootstrap/lib/stdlib/ebin/shell.beam
+++ b/bootstrap/lib/stdlib/ebin/shell.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/shell_default.beam b/bootstrap/lib/stdlib/ebin/shell_default.beam
index f295c9f116..a53a8fa5d2 100644
--- a/bootstrap/lib/stdlib/ebin/shell_default.beam
+++ b/bootstrap/lib/stdlib/ebin/shell_default.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sofs.beam b/bootstrap/lib/stdlib/ebin/sofs.beam
index 7b8ab95876..88fa6f85a9 100644
--- a/bootstrap/lib/stdlib/ebin/sofs.beam
+++ b/bootstrap/lib/stdlib/ebin/sofs.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/stdlib.app b/bootstrap/lib/stdlib/ebin/stdlib.app
index 0ac85cef0c..916b7a0483 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.app
+++ b/bootstrap/lib/stdlib/ebin/stdlib.app
@@ -31,7 +31,6 @@
dets_server,
dets_sup,
dets_utils,
- dets_v8,
dets_v9,
dict,
digraph,
diff --git a/bootstrap/lib/stdlib/ebin/stdlib.appup b/bootstrap/lib/stdlib/ebin/stdlib.appup
index db27ef6efd..87ee9b4c2c 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.appup
+++ b/bootstrap/lib/stdlib/ebin/stdlib.appup
@@ -18,9 +18,7 @@
%% %CopyrightEnd%
{"3.1",
%% Up from - max one major revision back
- [{<<"3\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.*
+ [{<<"3\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-19.*
%% Down to - max one major revision back
- [{<<"3\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.*
+ [{<<"3\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-19.*
}.
diff --git a/bootstrap/lib/stdlib/ebin/supervisor.beam b/bootstrap/lib/stdlib/ebin/supervisor.beam
index a05ae66941..24495b464e 100644
--- a/bootstrap/lib/stdlib/ebin/supervisor.beam
+++ b/bootstrap/lib/stdlib/ebin/supervisor.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sys.beam b/bootstrap/lib/stdlib/ebin/sys.beam
index d0162bdd07..582867f28a 100644
--- a/bootstrap/lib/stdlib/ebin/sys.beam
+++ b/bootstrap/lib/stdlib/ebin/sys.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/timer.beam b/bootstrap/lib/stdlib/ebin/timer.beam
index e23790c427..b5d68fd677 100644
--- a/bootstrap/lib/stdlib/ebin/timer.beam
+++ b/bootstrap/lib/stdlib/ebin/timer.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/include/assert.hrl b/bootstrap/lib/stdlib/include/assert.hrl
index 9e5d4eb598..2fbaeba0b2 100644
--- a/bootstrap/lib/stdlib/include/assert.hrl
+++ b/bootstrap/lib/stdlib/include/assert.hrl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright (C) 2004-2016 Richard Carlsson, Mickaël Rémond
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +10,7 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
+%% Copyright (C) 2004-2016 Richard Carlsson, Mickaël Rémond
-ifndef(ASSERT_HRL).
-define(ASSERT_HRL, true).
@@ -56,7 +50,8 @@
%% It is not possible to nest assert macros.
-ifdef(NOASSERT).
--define(assert(BoolExpr),ok).
+-define(assert(BoolExpr), ok).
+-define(assert(BoolExpr, Comment), ok).
-else.
%% The assert macro is written the way it is so as not to cause warnings
%% for clauses that cannot match, even if the expression is a constant or
@@ -79,11 +74,31 @@
end
end)())
end).
+-define(assert(BoolExpr, Comment),
+ begin
+ ((fun () ->
+ __T = is_process_alive(self()), % cheap source of truth
+ case (BoolExpr) of
+ __T -> ok;
+ __V -> erlang:error({assert,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??BoolExpr)},
+ {expected, true},
+ case not __T of
+ __V -> {value, false};
+ _ -> {not_boolean, __V}
+ end]})
+ end
+ end)())
+ end).
-endif.
%% This is the inverse case of assert, for convenience.
-ifdef(NOASSERT).
-define(assertNot(BoolExpr),ok).
+-define(assertNot(BoolExpr, Comment), ok).
-else.
-define(assertNot(BoolExpr),
begin
@@ -103,12 +118,32 @@
end
end)())
end).
+-define(assertNot(BoolExpr, Comment),
+ begin
+ ((fun () ->
+ __F = not is_process_alive(self()),
+ case (BoolExpr) of
+ __F -> ok;
+ __V -> erlang:error({assert,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??BoolExpr)},
+ {expected, false},
+ case not __F of
+ __V -> {value, true};
+ _ -> {not_boolean, __V}
+ end]})
+ end
+ end)())
+ end).
-endif.
%% This is mostly a convenience which gives more detailed reports.
%% Note: Guard is a guarded pattern, and can not be used for value.
-ifdef(NOASSERT).
-define(assertMatch(Guard, Expr), ok).
+-define(assertMatch(Guard, Expr, Comment), ok).
-else.
-define(assertMatch(Guard, Expr),
begin
@@ -124,11 +159,27 @@
end
end)())
end).
+-define(assertMatch(Guard, Expr, Comment),
+ begin
+ ((fun () ->
+ case (Expr) of
+ Guard -> ok;
+ __V -> erlang:error({assertMatch,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern, (??Guard)},
+ {value, __V}]})
+ end
+ end)())
+ end).
-endif.
%% This is the inverse case of assertMatch, for convenience.
-ifdef(NOASSERT).
-define(assertNotMatch(Guard, Expr), ok).
+-define(assertNotMatch(Guard, Expr, Comment), ok).
-else.
-define(assertNotMatch(Guard, Expr),
begin
@@ -145,12 +196,29 @@
end
end)())
end).
+-define(assertNotMatch(Guard, Expr, Comment),
+ begin
+ ((fun () ->
+ __V = (Expr),
+ case __V of
+ Guard -> erlang:error({assertNotMatch,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern, (??Guard)},
+ {value, __V}]});
+ _ -> ok
+ end
+ end)())
+ end).
-endif.
%% This is a convenience macro which gives more detailed reports when
%% the expected LHS value is not a pattern, but a computed value
-ifdef(NOASSERT).
-define(assertEqual(Expect, Expr), ok).
+-define(assertEqual(Expect, Expr, Comment), ok).
-else.
-define(assertEqual(Expect, Expr),
begin
@@ -167,11 +235,28 @@
end
end)())
end).
+-define(assertEqual(Expect, Expr, Comment),
+ begin
+ ((fun () ->
+ __X = (Expect),
+ case (Expr) of
+ __X -> ok;
+ __V -> erlang:error({assertEqual,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {expected, __X},
+ {value, __V}]})
+ end
+ end)())
+ end).
-endif.
%% This is the inverse case of assertEqual, for convenience.
-ifdef(NOASSERT).
-define(assertNotEqual(Unexpected, Expr), ok).
+-define(assertNotEqual(Unexpected, Expr, Comment), ok).
-else.
-define(assertNotEqual(Unexpected, Expr),
begin
@@ -187,12 +272,28 @@
end
end)())
end).
+-define(assertNotEqual(Unexpected, Expr, Comment),
+ begin
+ ((fun () ->
+ __X = (Unexpected),
+ case (Expr) of
+ __X -> erlang:error({assertNotEqual,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {value, __X}]});
+ _ -> ok
+ end
+ end)())
+ end).
-endif.
%% Note: Class and Term are patterns, and can not be used for value.
%% Term can be a guarded pattern, but Class cannot.
-ifdef(NOASSERT).
-define(assertException(Class, Term, Expr), ok).
+-define(assertException(Class, Term, Expr, Comment), ok).
-else.
-define(assertException(Class, Term, Expr),
begin
@@ -222,17 +323,54 @@
end
end)())
end).
+-define(assertException(Class, Term, Expr, Comment),
+ begin
+ ((fun () ->
+ try (Expr) of
+ __V -> erlang:error({assertException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "++(??Term)
+ ++" , [...] }"},
+ {unexpected_success, __V}]})
+ catch
+ Class:Term -> ok;
+ __C:__T ->
+ erlang:error({assertException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "++(??Term)
+ ++" , [...] }"},
+ {unexpected_exception,
+ {__C, __T,
+ erlang:get_stacktrace()}}]})
+ end
+ end)())
+ end).
-endif.
-define(assertError(Term, Expr), ?assertException(error, Term, Expr)).
+-define(assertError(Term, Expr, Comment),
+ ?assertException(error, Term, Expr, Comment)).
-define(assertExit(Term, Expr), ?assertException(exit, Term, Expr)).
+-define(assertExit(Term, Expr, Comment),
+ ?assertException(exit, Term, Expr, Comment)).
-define(assertThrow(Term, Expr), ?assertException(throw, Term, Expr)).
+-define(assertThrow(Term, Expr, Comment),
+ ?assertException(throw, Term, Expr, Comment)).
%% This is the inverse case of assertException, for convenience.
%% Note: Class and Term are patterns, and can not be used for value.
%% Both Class and Term can be guarded patterns.
-ifdef(NOASSERT).
-define(assertNotException(Class, Term, Expr), ok).
+-define(assertNotException(Class, Term, Expr, Comment), ok).
-else.
-define(assertNotException(Class, Term, Expr),
begin
@@ -263,6 +401,36 @@
end
end)())
end).
+-define(assertNotException(Class, Term, Expr, Comment),
+ begin
+ ((fun () ->
+ try (Expr) of
+ _ -> ok
+ catch
+ __C:__T ->
+ case __C of
+ Class ->
+ case __T of
+ Term ->
+ erlang:error({assertNotException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "
+ ++(??Term)++" , [...] }"},
+ {unexpected_exception,
+ {__C, __T,
+ erlang:get_stacktrace()
+ }}]});
+ _ -> ok
+ end;
+ _ -> ok
+ end
+ end
+ end)())
+ end).
-endif.
-endif. % ASSERT_HRL
diff --git a/erts/configure.in b/erts/configure.in
index 4bff2ebf3d..98f3e6bcc5 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -533,6 +533,7 @@ if test "x$GCC" = xyes; then
# Treat certain GCC warnings as errors
LM_TRY_ENABLE_CFLAG([-Werror=return-type], [WERRORFLAGS])
LM_TRY_ENABLE_CFLAG([-Werror=implicit], [WERRORFLAGS])
+ LM_TRY_ENABLE_CFLAG([-Werror=undef], [WERRORFLAGS])
# until the emulator can handle this, I suggest we turn it off!
#WFLAGS="-Wall -Wshadow -Wcast-qual -Wmissing-declarations"
@@ -2783,6 +2784,23 @@ if test "$cross_compiling" != "yes" && test X${enable_hipe} != Xno; then
fi
fi
+dnl Check to disable -fPIE and friends for HiPE on amd64
+if test X${enable_hipe} = Xyes && test X$ARCH = Xamd64; then
+ AC_TRY_COMPILE(, [#if defined(__pie__) || defined(__PIE__)
+ #error -fPIE is enabled by default
+ #endif],
+ [AC_MSG_NOTICE([No -fPIE enabled by default])],
+ [AC_MSG_WARN([Security feature -fPIE will be disabled for HiPE])
+ STATIC_CFLAGS="-fno-PIE $STATIC_CFLAGS"
+ saved_LDFLAGS=$LDFLAGS
+ LDFLAGS="-no-pie $LDFLAGS"
+ AC_TRY_LINK(,, [],
+ [AC_MSG_WARN([Linked does not accept option -no-pie])
+ LDFLAGS=$saved_LDFLAGS])])
+
+fi
+
+
if test X${enable_fp_exceptions} = Xauto ; then
case $host_os in
*linux*)
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index eb1d24cf12..f2a55f6298 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -250,6 +250,11 @@
environment variable <c><![CDATA[DISPLAY]]></c> set to
<c><![CDATA[gin:0]]></c>.</p>
</item>
+ <tag><c><![CDATA[-epmd_module Module]]></c> (init flag)</tag>
+ <item>
+ <p>Configures the module responsible to communicate to
+ <seealso marker="epmd">epmd</seealso>. Defaults to <c>erl_epmd</c>.</p>
+ </item>
<tag><c><![CDATA[-eval Expr]]></c> (init flag)</tag>
<item>
<p>Makes <c><![CDATA[init]]></c> evaluate the expression
@@ -1535,6 +1540,15 @@
</item>
</taglist>
</item>
+ <tag><c><![CDATA[ERL_CRASH_DUMP_BYTES]]></c></tag>
+ <item>
+ <p>This variable sets the maximum size of a crash dump file in bytes.
+ The crash dump will be truncated if this limit is exceeded. If the
+ variable is not set, no size limit is enforced by default. If the
+ variable is set to <c>0</c>, the runtime system does not even attempt
+ to write a crash dump file.</p>
+ <p>Introduced in ERTS 8.1.2 (Erlang/OTP 19.2).</p>
+ </item>
<tag><marker id="ERL_AFLAGS"/><c><![CDATA[ERL_AFLAGS]]></c></tag>
<item>
<p>The content of this variable is added to the beginning of the
diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml
index 5191742bc9..d8bf45c523 100644
--- a/erts/doc/src/erl_driver.xml
+++ b/erts/doc/src/erl_driver.xml
@@ -2039,7 +2039,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code>
<fsummary>Set and get limits for busy port message queue.</fsummary>
<desc>
<marker id="erl_drv_busy_msgq_limits"></marker>
- <p>Sets and gets limits that will be used for controling the
+ <p>Sets and gets limits that will be used for controlling the
busy state of the port message queue.</p>
<p>The port message queue is set into a busy
state when the amount of command data queued on the
@@ -2112,7 +2112,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code>
It is used to identify the condition variable in planned
future debug functionality.</p>
<p>Returns <c>NULL</c> on failure. The driver
- creating the condition variable is responsibile for
+ creating the condition variable is responsible for
destroying it before the driver is unloaded.</p>
<p>This function is thread-safe.</p>
</desc>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 3d1775e973..3dad09365e 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -2618,6 +2618,10 @@ os_prompt%</pre>
code of a module that has been upgraded; this is not
allowed.
</item>
+ <tag><c>notsup</c></tag>
+ <item>Lack of support. Such as loading NIF library for a
+ HiPE compiled module.
+ </item>
</taglist>
</desc>
</func>
@@ -9564,6 +9568,10 @@ timestamp() ->
<type name="trace_info_item_result"/>
<type name="trace_info_flag"/>
<type name="trace_match_spec"/>
+ <type name="match_variable"/>
+ <type_desc name="match_variable">
+ Approximation of '$1' | '$2' | '$3' | ...
+ </type_desc>
<desc>
<p>Returns trace information about a port, process, function, or
event.</p>
@@ -9695,6 +9703,10 @@ timestamp() ->
</fsummary>
<type name="trace_pattern_mfa"/>
<type name="trace_match_spec"/>
+ <type_desc name="match_variable">
+ Approximation of '$1' | '$2' | '$3' | ...
+ </type_desc>
+ <type name="match_variable"/>
<desc>
<p>The same as
<seealso marker="#trace_pattern/3">
@@ -9707,6 +9719,10 @@ timestamp() ->
<name name="trace_pattern" arity="3" clause_i="1"/>
<fsummary>Set trace pattern for message sending.</fsummary>
<type name="trace_match_spec"/>
+ <type name="match_variable"/>
+ <type_desc name="match_variable">
+ Approximation of '$1' | '$2' | '$3' | ...
+ </type_desc>
<desc>
<p>Sets trace pattern for <em>message sending</em>.
Must be combined with
@@ -9774,6 +9790,10 @@ timestamp() ->
<name name="trace_pattern" arity="3" clause_i="2"/>
<fsummary>Set trace pattern for tracing of message receiving.</fsummary>
<type name="trace_match_spec"/>
+ <type name="match_variable"/>
+ <type_desc name="match_variable">
+ Approximation of '$1' | '$2' | '$3' | ...
+ </type_desc>
<desc>
<p>Sets trace pattern for <em>message receiving</em>.
Must be combined with
@@ -9844,6 +9864,10 @@ timestamp() ->
<type name="trace_pattern_mfa"/>
<type name="trace_match_spec"/>
<type name="trace_pattern_flag"/>
+ <type name="match_variable"/>
+ <type_desc name="match_variable">
+ Approximation of '$1' | '$2' | '$3' | ...
+ </type_desc>
<desc>
<p>Enables or disables <em>call tracing</em> for one or more functions.
Must be combined with
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 412675fd2b..dd260f2d1f 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -32,6 +32,50 @@
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 8.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The emulator got a dynamic library dependency towards
+ libsctp, which on Linux was not intended since the
+ emulator there loads and resolves the needed sctp
+ functions in runtime. This has been fixed and a configure
+ switch --enable-sctp=lib has been added for those who
+ want such a library dependency.</p>
+ <p>
+ Own Id: OTP-13956 Aux Id: ERL-262, ERL-133 </p>
+ </item>
+ <item>
+ <p>
+ Fix SIGUSR1 crashdump generation</p>
+ <p>
+ Do not generate a core when a crashdump is asked for.</p>
+ <p>
+ Own Id: OTP-13997</p>
+ </item>
+ <item>
+ <p>The new functions in <c>code</c> that allows loading
+ of many modules at once had a performance problem. While
+ executing a helper function in the <c>erl_prim_loader</c>
+ process, garbage messages were produced. The garbages
+ messages were ignored and ultimately discarded, but there
+ would be a negative impact on performance and memory
+ usage. The number of garbage message depended on both the
+ number of modules to be loaded and the length of the code
+ path.</p>
+ <p>The functions affected of this problem were:
+ <c>atomic_load/1</c>, <c>ensure_modules_loaded/1</c>, and
+ <c>prepare_loading/1</c>.</p>
+ <p>
+ Own Id: OTP-14009</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 8.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index fa4de5805e..ce50022683 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -49,6 +49,7 @@ CREATE_DIRS=
LDFLAGS=@LDFLAGS@
ARFLAGS=rc
OMIT_OMIT_FP=no
+TYPE_LIBS=
DIRTY_SCHEDULER_SUPPORT=@DIRTY_SCHEDULER_SUPPORT@
@@ -89,7 +90,7 @@ PURIFY =
TYPEMARKER = .gcov
TYPE_FLAGS = $(DEBUG_CFLAGS) -DERTS_GCOV -DNO_JUMP_TABLE -fprofile-arcs -ftest-coverage -O0 -DERTS_CAN_INLINE=0 -DERTS_INLINE=
ifneq ($(findstring solaris,$(TARGET)),solaris)
-LIBS += -lgcov
+TYPE_LIBS = -lgcov
endif
ENABLE_ALLOC_TYPE_VARS += debug
else
@@ -145,6 +146,8 @@ endif
endif
endif
+LIBS += $(TYPE_LIBS)
+
comma:=,
space:=
space+=
@@ -932,7 +935,7 @@ $(OBJDIR)/%.o: hipe/%.c
$(V_CC) $(subst O2,O3, $(CFLAGS)) $(INCLUDES) -c $< -o $@
$(BINDIR)/hipe_mkliterals$(TF_MARKER): $(OBJDIR)/hipe_mkliterals.o
- $(ld_verbose)$(CC) $(CFLAGS) $(INCLUDES) -o $@ $<
+ $(ld_verbose)$(CC) $(LDFLAGS) -o $@ $< $(TYPE_LIBS)
$(OBJDIR)/hipe_mkliterals.o: $(HIPE_ASM) $(TTF_DIR)/erl_alloc_types.h $(DTRACE_HEADERS) \
$(TTF_DIR)/OPCODES-GENERATED $(TARGET)/TABLES-GENERATED
diff --git a/erts/emulator/beam/atom.c b/erts/emulator/beam/atom.c
index d2fad24805..b47739059b 100644
--- a/erts/emulator/beam/atom.c
+++ b/erts/emulator/beam/atom.c
@@ -68,7 +68,7 @@ static Uint atom_space; /* Amount of atom text space used */
/*
* Print info about atom tables
*/
-void atom_info(int to, void *to_arg)
+void atom_info(fmtfn_t to, void *to_arg)
{
int lock = !ERTS_IS_CRASH_DUMPING;
if (lock)
@@ -470,7 +470,7 @@ init_atom_table(void)
}
void
-dump_atoms(int to, void *to_arg)
+dump_atoms(fmtfn_t to, void *to_arg)
{
int i = erts_atom_table.entries;
diff --git a/erts/emulator/beam/atom.h b/erts/emulator/beam/atom.h
index 0d34c47a55..f3b21e1687 100644
--- a/erts/emulator/beam/atom.h
+++ b/erts/emulator/beam/atom.h
@@ -136,8 +136,8 @@ Eterm erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc);
int atom_erase(byte*, int);
int atom_static_put(byte*, int);
void init_atom_table(void);
-void atom_info(int, void *);
-void dump_atoms(int, void *);
+void atom_info(fmtfn_t, void *);
+void dump_atoms(fmtfn_t, void *);
Uint erts_get_atom_limit(void);
int erts_atom_get(const char* name, int len, Eterm* ap, ErtsAtomEncoding enc);
void erts_atom_get_text_space_sizes(Uint *reserved, Uint *used);
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index 099abad4e1..5c3565f498 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -1093,6 +1093,11 @@ check_process_code(Process* rp, Module* modp, int *redsp, int fcalls)
|| ErtsInArea(rp->cp, mod_start, mod_size)) {
return am_true;
}
+
+ *redsp += 1;
+
+ if (erts_check_nif_export_in_area(rp, mod_start, mod_size))
+ return am_true;
*redsp += (STACK_START(rp) - rp->stop) / 32;
@@ -1397,10 +1402,10 @@ erts_purge_state_add_fun(ErlFunEntry *fe)
}
Export *
-erts_suspend_process_on_pending_purge_lambda(Process *c_p)
+erts_suspend_process_on_pending_purge_lambda(Process *c_p, ErlFunEntry* fe)
{
erts_smp_mtx_lock(&purge_state.mtx);
- if (is_value(purge_state.module)) {
+ if (purge_state.module == fe->module) {
/*
* The process c_p is about to call a fun in the code
* that we are trying to purge. Suspend it and call
diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c
index 62464f3864..73158205b3 100644
--- a/erts/emulator/beam/beam_bp.c
+++ b/erts/emulator/beam/beam_bp.c
@@ -1526,7 +1526,7 @@ set_function_break(ErtsCodeInfo *ci, Binary *match_spec, Uint break_flags,
ASSERT((bp->flags & ERTS_BPF_TIME_TRACE) == 0);
bdt = Alloc(sizeof(BpDataTime));
erts_refc_init(&bdt->refc, 1);
- bdt->n = erts_no_schedulers;
+ bdt->n = erts_no_total_schedulers;
bdt->hash = Alloc(sizeof(bp_time_hash_t)*(bdt->n));
for (i = 0; i < bdt->n; i++) {
bp_hash_init(&(bdt->hash[i]), 32);
diff --git a/erts/emulator/beam/beam_bp.h b/erts/emulator/beam/beam_bp.h
index d32a6bcba5..224b46407d 100644
--- a/erts/emulator/beam/beam_bp.h
+++ b/erts/emulator/beam/beam_bp.h
@@ -80,7 +80,7 @@ typedef struct generic_bp {
#define ERTS_BP_CALL_TIME_SCHEDULE_EXITING (2)
#ifdef ERTS_SMP
-#define bp_sched2ix_proc(p) (erts_proc_sched_data(p)->no - 1)
+#define bp_sched2ix_proc(p) (erts_proc_sched_data(p)->thr_id - 1)
#else
#define bp_sched2ix_proc(p) (0)
#endif
diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c
index 68559e3992..e72d7f8de4 100644
--- a/erts/emulator/beam/beam_debug.c
+++ b/erts/emulator/beam/beam_debug.c
@@ -50,8 +50,8 @@
void dbg_bt(Process* p, Eterm* sp);
void dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg);
-static int print_op(int to, void *to_arg, int op, int size, BeamInstr* addr);
-static void print_bif_name(int to, void* to_arg, BifFunction bif);
+static int print_op(fmtfn_t to, void *to_arg, int op, int size, BeamInstr* addr);
+static void print_bif_name(fmtfn_t to, void* to_arg, BifFunction bif);
BIF_RETTYPE
erts_debug_same_2(BIF_ALIST_2)
@@ -380,7 +380,7 @@ dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg)
}
static int
-print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
+print_op(fmtfn_t to, void *to_arg, int op, int size, BeamInstr* addr)
{
int i;
BeamInstr tag;
@@ -747,7 +747,7 @@ print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
return size;
}
-static void print_bif_name(int to, void* to_arg, BifFunction bif)
+static void print_bif_name(fmtfn_t to, void* to_arg, BifFunction bif)
{
int i;
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 84e2d42af6..613bd5c14e 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -5053,7 +5053,7 @@ do { \
} else {
TestHeap(ERTS_SINT64_HEAP_SIZE(ts),0);
r(0) = make_big(HTOP);
-#if defined(ARCH_32) || HALFWORD_HEAP
+#if defined(ARCH_32)
if (ts >= (((Uint64) 1) << 32)) {
*HTOP = make_pos_bignum_header(2);
BIG_DIGIT(HTOP, 0) = (Uint) (ts & ((Uint) 0xffffffff));
@@ -5333,7 +5333,7 @@ void erts_dirty_process_main(ErtsSchedulerData *esdp)
I = c_p->i;
- ASSERT(BeamOp(op_call_nif) == (BeamInstr *) *I);
+ ASSERT(em_call_nif == (BeamInstr *) *I);
/*
* Set fcalls even though we ignore it, so we don't
@@ -6547,7 +6547,7 @@ call_fun(Process* p, /* Current process. */
* and let it try again when the purge operation is
* done (may succeed or not).
*/
- ep = erts_suspend_process_on_pending_purge_lambda(p);
+ ep = erts_suspend_process_on_pending_purge_lambda(p, fe);
ASSERT(ep);
}
else {
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 36cf64e08d..3cd395c2c1 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -4848,7 +4848,7 @@ final_touch(LoaderState* stp, struct erl_module_instance* inst_p)
}
fe->address = code_ptr;
#ifdef HIPE
- hipe_set_closure_stub(fe, stp->lambdas[i].num_free);
+ hipe_set_closure_stub(fe);
#endif
}
}
diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h
index 6a3110d0f5..d420a4346c 100644
--- a/erts/emulator/beam/beam_load.h
+++ b/erts/emulator/beam/beam_load.h
@@ -116,7 +116,8 @@ int erts_is_module_native(BeamCodeHeader* code);
void erts_beam_bif_load_init(void);
struct erl_fun_entry;
void erts_purge_state_add_fun(struct erl_fun_entry *fe);
-Export *erts_suspend_process_on_pending_purge_lambda(Process *c_p);
+Export *erts_suspend_process_on_pending_purge_lambda(Process *c_p,
+ struct erl_fun_entry*);
/*
* Layout of the line table.
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 852b1135fe..32600f4338 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -667,6 +667,7 @@ gcbif erlang:floor/1
gcbif erlang:ceil/1
bif math:floor/1
bif math:ceil/1
+bif math:fmod/2
#
# Obsolete
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 4ee00b53be..6e1e94b95b 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -44,23 +44,22 @@
static void process_killer(void);
void do_break(void);
void erl_crash_dump_v(char *file, int line, char* fmt, va_list args);
-void erl_crash_dump(char* file, int line, char* fmt, ...);
#ifdef DEBUG
static void bin_check(void);
#endif
-static void print_garb_info(int to, void *to_arg, Process* p);
+static void print_garb_info(fmtfn_t to, void *to_arg, Process* p);
#ifdef OPPROF
static void dump_frequencies(void);
#endif
-static void dump_attributes(int to, void *to_arg, byte* ptr, int size);
+static void dump_attributes(fmtfn_t to, void *to_arg, byte* ptr, int size);
extern char* erts_system_version[];
static void
-port_info(int to, void *to_arg)
+port_info(fmtfn_t to, void *to_arg)
{
int i, max = erts_ptab_max(&erts_port);
for (i = 0; i < max; i++) {
@@ -71,7 +70,7 @@ port_info(int to, void *to_arg)
}
void
-process_info(int to, void *to_arg)
+process_info(fmtfn_t to, void *to_arg)
{
int i, max = erts_ptab_max(&erts_proc);
for (i = 0; i < max; i++) {
@@ -148,14 +147,14 @@ process_killer(void)
typedef struct {
int is_first;
- int to;
+ fmtfn_t to;
void *to_arg;
} PrintMonitorContext;
static void doit_print_link(ErtsLink *lnk, void *vpcontext)
{
PrintMonitorContext *pcontext = vpcontext;
- int to = pcontext->to;
+ fmtfn_t to = pcontext->to;
void *to_arg = pcontext->to_arg;
if (pcontext->is_first) {
@@ -170,7 +169,7 @@ static void doit_print_link(ErtsLink *lnk, void *vpcontext)
static void doit_print_monitor(ErtsMonitor *mon, void *vpcontext)
{
PrintMonitorContext *pcontext = vpcontext;
- int to = pcontext->to;
+ fmtfn_t to = pcontext->to;
void *to_arg = pcontext->to_arg;
char *prefix = ", ";
@@ -197,7 +196,7 @@ static void doit_print_monitor(ErtsMonitor *mon, void *vpcontext)
/* Display info about an individual Erlang process */
void
-print_process_info(int to, void *to_arg, Process *p)
+print_process_info(fmtfn_t to, void *to_arg, Process *p)
{
time_t approx_started;
int garbing = 0;
@@ -300,7 +299,7 @@ print_process_info(int to, void *to_arg, Process *p)
/* display the links only if there are any*/
if (ERTS_P_LINKS(p) || ERTS_P_MONITORS(p)) {
- PrintMonitorContext context = {1,to};
+ PrintMonitorContext context = {1, to, to_arg};
erts_print(to, to_arg,"Link list: [");
erts_doforall_links(ERTS_P_LINKS(p), &doit_print_link, &context);
erts_doforall_monitors(ERTS_P_MONITORS(p), &doit_print_monitor, &context);
@@ -348,7 +347,7 @@ print_process_info(int to, void *to_arg, Process *p)
}
static void
-print_garb_info(int to, void *to_arg, Process* p)
+print_garb_info(fmtfn_t to, void *to_arg, Process* p)
{
#ifdef ERTS_SMP
/* ERTS_SMP: A scheduler is probably concurrently doing gc... */
@@ -365,7 +364,7 @@ print_garb_info(int to, void *to_arg, Process* p)
}
void
-info(int to, void *to_arg)
+info(fmtfn_t to, void *to_arg)
{
erts_memory(&to, to_arg, NULL, THE_NON_VALUE);
atom_info(to, to_arg);
@@ -381,7 +380,7 @@ info(int to, void *to_arg)
}
void
-loaded(int to, void *to_arg)
+loaded(fmtfn_t to, void *to_arg)
{
int i;
int old = 0;
@@ -478,7 +477,7 @@ loaded(int to, void *to_arg)
static void
-dump_attributes(int to, void *to_arg, byte* ptr, int size)
+dump_attributes(fmtfn_t to, void *to_arg, byte* ptr, int size)
{
while (size-- > 0) {
erts_print(to, to_arg, "%02X", *ptr++);
@@ -662,6 +661,26 @@ bin_check(void)
#endif
+static Sint64 crash_dump_limit = ERTS_SINT64_MAX;
+static Sint64 crash_dump_written = 0;
+
+static int crash_dump_limited_writer(void* vfdp, char* buf, size_t len)
+{
+ const char stop_msg[] = "\n=abort:CRASH DUMP SIZE LIMIT REACHED\n";
+
+ crash_dump_written += len;
+ if (crash_dump_written <= crash_dump_limit) {
+ return erts_write_fd(vfdp, buf, len);
+ }
+
+ len -= (crash_dump_written - crash_dump_limit);
+ erts_write_fd(vfdp, buf, len);
+ erts_write_fd(vfdp, (char*)stop_msg, sizeof(stop_msg)-1);
+
+ /* We assume that crash dump was called from erts_exit_vv() */
+ erts_exit_epilogue();
+}
+
/* XXX THIS SHOULD BE IN SYSTEM !!!! */
void
erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
@@ -679,6 +698,8 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
int secs;
int env_erl_crash_dump_seconds_set = 1;
int i;
+ fmtfn_t to = &erts_write_fd;
+ void* to_arg;
if (ERTS_SOMEONE_IS_CRASH_DUMPING)
return;
@@ -759,6 +780,21 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
return;
}
+ crash_dump_limit = ERTS_SINT64_MAX;
+ envsz = sizeof(env);
+ if (erts_sys_getenv__("ERL_CRASH_DUMP_BYTES", env, &envsz) == 0) {
+ Sint64 limit;
+ char* endptr;
+ errno = 0;
+ limit = ErtsStrToSint64(env, &endptr, 10);
+ if (errno == 0 && limit >= 0 && endptr != env && *endptr == 0) {
+ if (limit == 0)
+ return;
+ crash_dump_limit = limit;
+ to = &crash_dump_limited_writer;
+ }
+ }
+
if (erts_sys_getenv__("ERL_CRASH_DUMP",&dumpnamebuf[0],&dumpnamebufsize) != 0)
dumpname = "erl_crash.dump";
else
@@ -769,39 +805,40 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
fd = open(dumpname,O_WRONLY | O_CREAT | O_TRUNC,0640);
if (fd < 0)
return; /* Can't create the crash dump, skip it */
+ to_arg = (void*)&fd;
time(&now);
- erts_fdprintf(fd, "=erl_crash_dump:0.3\n%s", ctime(&now));
+ erts_cbprintf(to, to_arg, "=erl_crash_dump:0.3\n%s", ctime(&now));
if (file != NULL)
- erts_fdprintf(fd, "The error occurred in file %s, line %d\n", file, line);
+ erts_cbprintf(to, to_arg, "The error occurred in file %s, line %d\n", file, line);
if (fmt != NULL && *fmt != '\0') {
- erts_fdprintf(fd, "Slogan: ");
- erts_vfdprintf(fd, fmt, args);
+ erts_cbprintf(to, to_arg, "Slogan: ");
+ erts_vcbprintf(to, to_arg, fmt, args);
}
- erts_fdprintf(fd, "System version: ");
- erts_print_system_version(fd, NULL, NULL);
+ erts_cbprintf(to, to_arg, "System version: ");
+ erts_print_system_version(to, to_arg, NULL);
#if ERTS_SAVED_COMPILE_TIME
- erts_fdprintf(fd, "%s\n", "Compiled: " ERLANG_COMPILE_DATE);
+ erts_cbprintf(to, to_arg, "%s\n", "Compiled: " ERLANG_COMPILE_DATE);
#endif
- erts_fdprintf(fd, "Taints: ");
- erts_print_nif_taints(fd, NULL);
- erts_fdprintf(fd, "Atoms: %d\n", atom_table_size());
+ erts_cbprintf(to, to_arg, "Taints: ");
+ erts_print_nif_taints(to, to_arg);
+ erts_cbprintf(to, to_arg, "Atoms: %d\n", atom_table_size());
#ifdef USE_THREADS
/* We want to note which thread it was that called erts_exit */
if (erts_get_scheduler_data()) {
- erts_fdprintf(fd, "Calling Thread: scheduler:%d\n",
+ erts_cbprintf(to, to_arg, "Calling Thread: scheduler:%d\n",
erts_get_scheduler_data()->no);
} else {
if (!erts_thr_getname(erts_thr_self(), dumpnamebuf, MAXPATHLEN))
- erts_fdprintf(fd, "Calling Thread: %s\n", dumpnamebuf);
+ erts_cbprintf(to, to_arg, "Calling Thread: %s\n", dumpnamebuf);
else
- erts_fdprintf(fd, "Calling Thread: %p\n", erts_thr_self());
+ erts_cbprintf(to, to_arg, "Calling Thread: %p\n", erts_thr_self());
}
#else
- erts_fdprintf(fd, "Calling Thread: scheduler:1\n");
+ erts_cbprintf(to, to_arg, "Calling Thread: scheduler:1\n");
#endif
#if defined(ERTS_HAVE_TRY_CATCH)
@@ -816,8 +853,8 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
*/
for (i = 0; i < erts_no_schedulers; i++) {
ERTS_SYS_TRY_CATCH(
- erts_print_scheduler_info(fd, NULL, ERTS_SCHEDULER_IX(i)),
- erts_fdprintf(fd, "** crashed **\n"));
+ erts_print_scheduler_info(to, to_arg, ERTS_SCHEDULER_IX(i)),
+ erts_cbprintf(to, to_arg, "** crashed **\n"));
}
#endif
@@ -848,48 +885,39 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
#ifndef ERTS_HAVE_TRY_CATCH
/* This is safe to call here, as all schedulers are blocked */
for (i = 0; i < erts_no_schedulers; i++) {
- erts_print_scheduler_info(fd, NULL, ERTS_SCHEDULER_IX(i));
+ erts_print_scheduler_info(to, to_arg, ERTS_SCHEDULER_IX(i));
}
#endif
- info(fd, NULL); /* General system info */
+ info(to, to_arg); /* General system info */
if (erts_ptab_initialized(&erts_proc))
- process_info(fd, NULL); /* Info about each process and port */
- db_info(fd, NULL, 0);
- erts_print_bif_timer_info(fd, NULL);
- distribution_info(fd, NULL);
- erts_fdprintf(fd, "=loaded_modules\n");
- loaded(fd, NULL);
- erts_dump_fun_entries(fd, NULL);
- erts_deep_process_dump(fd, NULL);
- erts_fdprintf(fd, "=atoms\n");
- dump_atoms(fd, NULL);
+ process_info(to, to_arg); /* Info about each process and port */
+ db_info(to, to_arg, 0);
+ erts_print_bif_timer_info(to, to_arg);
+ distribution_info(to, to_arg);
+ erts_cbprintf(to, to_arg, "=loaded_modules\n");
+ loaded(to, to_arg);
+ erts_dump_fun_entries(to, to_arg);
+ erts_deep_process_dump(to, to_arg);
+ erts_cbprintf(to, to_arg, "=atoms\n");
+ dump_atoms(to, to_arg);
/* Keep the instrumentation data at the end of the dump */
if (erts_instr_memory_map || erts_instr_stat) {
- erts_fdprintf(fd, "=instr_data\n");
+ erts_cbprintf(to, to_arg, "=instr_data\n");
if (erts_instr_stat) {
- erts_fdprintf(fd, "=memory_status\n");
- erts_instr_dump_stat_to_fd(fd, 0);
+ erts_cbprintf(to, to_arg, "=memory_status\n");
+ erts_instr_dump_stat_to(to, to_arg, 0);
}
if (erts_instr_memory_map) {
- erts_fdprintf(fd, "=memory_map\n");
- erts_instr_dump_memory_map_to_fd(fd);
+ erts_cbprintf(to, to_arg, "=memory_map\n");
+ erts_instr_dump_memory_map_to(to, to_arg);
}
}
- erts_fdprintf(fd, "=end\n");
+ erts_cbprintf(to, to_arg, "=end\n");
close(fd);
erts_fprintf(stderr,"done\n");
}
-void
-erl_crash_dump(char* file, int line, char* fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- erl_crash_dump_v(file, line, fmt, args);
- va_end(args);
-}
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 09c83f1117..990edb274e 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -25,6 +25,7 @@
/* define this to get a lot of debug output */
/* #define ERTS_DIST_MSG_DBG */
+/* #define ERTS_RAW_DIST_MSG_DBG */
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -2402,13 +2403,13 @@ erts_kill_dist_connection(DistEntry *dep, Uint32 connection_id)
}
struct print_to_data {
- int to;
+ fmtfn_t to;
void *arg;
};
static void doit_print_monitor_info(ErtsMonitor *mon, void *vptdp)
{
- int to = ((struct print_to_data *) vptdp)->to;
+ fmtfn_t to = ((struct print_to_data *) vptdp)->to;
void *arg = ((struct print_to_data *) vptdp)->arg;
Process *rp;
ErtsMonitor *rmon;
@@ -2431,7 +2432,7 @@ static void doit_print_monitor_info(ErtsMonitor *mon, void *vptdp)
}
}
-static void print_monitor_info(int to, void *arg, ErtsMonitor *mon)
+static void print_monitor_info(fmtfn_t to, void *arg, ErtsMonitor *mon)
{
struct print_to_data ptd = {to, arg};
erts_doforall_monitors(mon,&doit_print_monitor_info,&ptd);
@@ -2457,7 +2458,7 @@ static void doit_print_link_info(ErtsLink *lnk, void *vptdp)
}
}
-static void print_link_info(int to, void *arg, ErtsLink *lnk)
+static void print_link_info(fmtfn_t to, void *arg, ErtsLink *lnk)
{
struct print_to_data ptd = {to, arg};
erts_doforall_links(lnk, &doit_print_link_info, (void *) &ptd);
@@ -2478,7 +2479,7 @@ static void doit_print_nodelink_info(ErtsLink *lnk, void *vpcontext)
"Remote monitoring: %T %T\n", lnk->pid, pcontext->sysname);
}
-static void print_nodelink_info(int to, void *arg, ErtsLink *lnk, Eterm sysname)
+static void print_nodelink_info(fmtfn_t to, void *arg, ErtsLink *lnk, Eterm sysname)
{
PrintNodeLinkContext context = {{to, arg}, sysname};
erts_doforall_links(lnk, &doit_print_nodelink_info, &context);
@@ -2486,7 +2487,7 @@ static void print_nodelink_info(int to, void *arg, ErtsLink *lnk, Eterm sysname)
static int
-info_dist_entry(int to, void *arg, DistEntry *dep, int visible, int connected)
+info_dist_entry(fmtfn_t to, void *arg, DistEntry *dep, int visible, int connected)
{
if (visible && connected) {
@@ -2535,7 +2536,7 @@ info_dist_entry(int to, void *arg, DistEntry *dep, int visible, int connected)
return 0;
}
-int distribution_info(int to, void *arg) /* Called by break handler */
+int distribution_info(fmtfn_t to, void *arg) /* Called by break handler */
{
DistEntry *dep;
diff --git a/erts/emulator/beam/erl_afit_alloc.c b/erts/emulator/beam/erl_afit_alloc.c
index eda3ad870a..4ebe37ee1d 100644
--- a/erts/emulator/beam/erl_afit_alloc.c
+++ b/erts/emulator/beam/erl_afit_alloc.c
@@ -54,7 +54,7 @@ static void link_free_block (Allctr_t *, Block_t *);
static void unlink_free_block (Allctr_t *, Block_t *);
-static Eterm info_options (Allctr_t *, char *, int *,
+static Eterm info_options (Allctr_t *, char *, fmtfn_t *,
void *arg, Uint **, Uint *);
static void init_atoms (void);
@@ -227,7 +227,7 @@ add_2tup(Uint **hpp, Uint *szp, Eterm *lp, Eterm el1, Eterm el2)
static Eterm
info_options(Allctr_t *allctr,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index 56aa78a08a..40a45c961f 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -2119,7 +2119,7 @@ add_fix_values(UWord *ap, UWord *up, ErtsAlcUFixInfo_t *fi, ErtsAlcType_t type)
}
Eterm
-erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
+erts_memory(fmtfn_t *print_to_p, void *print_to_arg, void *proc, Eterm earg)
{
/*
* NOTE! When updating this function, make sure to also update
@@ -2482,7 +2482,7 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
if (print_to_p) {
int i;
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
/* Print result... */
@@ -2536,7 +2536,7 @@ struct aa_values {
};
Eterm
-erts_allocated_areas(int *print_to_p, void *print_to_arg, void *proc)
+erts_allocated_areas(fmtfn_t *print_to_p, void *print_to_arg, void *proc)
{
#define MAX_AA_VALUES (24)
struct aa_values values[MAX_AA_VALUES];
@@ -2671,7 +2671,7 @@ erts_allocated_areas(int *print_to_p, void *print_to_arg, void *proc)
if (print_to_p) {
/* Print result... */
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
erts_print(to, arg, "=allocated_areas\n");
@@ -2785,7 +2785,7 @@ erts_alloc_util_allocators(void *proc)
}
void
-erts_allocator_info(int to, void *arg)
+erts_allocator_info(fmtfn_t to, void *arg)
{
ErtsAlcType_t a;
@@ -3116,7 +3116,7 @@ reply_alloc_info(void *vair)
Eterm (*info_func)(Allctr_t *,
int,
int,
- int *,
+ fmtfn_t *,
void *,
Uint **,
Uint *) = (air->only_sz
diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h
index 925a081a02..56a3b73bf9 100644
--- a/erts/emulator/beam/erl_alloc.h
+++ b/erts/emulator/beam/erl_alloc.h
@@ -69,11 +69,11 @@ void *erts_sys_aligned_realloc(UWord alignment, void *ptr, UWord size, UWord old
void erts_sys_aligned_free(UWord alignment, void *ptr);
#endif
-Eterm erts_memory(int *, void *, void *, Eterm);
-Eterm erts_allocated_areas(int *, void *, void *);
+Eterm erts_memory(fmtfn_t *, void *, void *, Eterm);
+Eterm erts_allocated_areas(fmtfn_t *, void *, void *);
Eterm erts_alloc_util_allocators(void *proc);
-void erts_allocator_info(int, void *);
+void erts_allocator_info(fmtfn_t, void *);
Eterm erts_allocator_options(void *proc);
struct process;
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 163244237d..61cce224dd 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -4197,9 +4197,9 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp)
ASSERT(IS_LAST_BLK(blk));
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- (*allctr->link_free_block)(allctr, blk, 0);
+ (*allctr->link_free_block)(allctr, blk);
HARD_CHECK_BLK_CARRIER(allctr, blk);
- (*allctr->unlink_free_block)(allctr, blk, 0);
+ (*allctr->unlink_free_block)(allctr, blk);
#endif
}
#endif
@@ -4517,7 +4517,7 @@ add_fix_types(Allctr_t *allctr, int internal, Uint **hpp, Uint *szp,
static Eterm
sz_info_fix(Allctr_t *allctr,
int internal,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -4538,7 +4538,7 @@ sz_info_fix(Allctr_t *allctr,
UWord used = fix->type_size * fix->u.cpool.used;
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
erts_print(to,
arg,
@@ -4566,7 +4566,7 @@ sz_info_fix(Allctr_t *allctr,
UWord used = fix->type_size*fix->u.nocpool.used;
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
erts_print(to,
arg,
@@ -4592,7 +4592,7 @@ static Eterm
sz_info_carriers(Allctr_t *allctr,
CarriersStats_t *cs,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -4601,7 +4601,7 @@ sz_info_carriers(Allctr_t *allctr,
UWord curr_size = cs->curr.norm.mseg.size + cs->curr.norm.sys_alloc.size;
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
erts_print(to,
arg,
@@ -4642,7 +4642,7 @@ static Eterm
info_cpool(Allctr_t *allctr,
int sz_only,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -4659,7 +4659,7 @@ info_cpool(Allctr_t *allctr,
}
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
if (!sz_only)
erts_print(to, arg, "%sblocks: %bpu\n", prefix, nob);
@@ -4696,7 +4696,7 @@ static Eterm
info_carriers(Allctr_t *allctr,
CarriersStats_t *cs,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -4708,7 +4708,7 @@ info_carriers(Allctr_t *allctr,
curr_size = cs->curr.norm.mseg.size + cs->curr.norm.sys_alloc.size;
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
erts_print(to,
arg,
@@ -4834,7 +4834,7 @@ make_name_atoms(Allctr_t *allctr)
static Eterm
info_calls(Allctr_t *allctr,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -4851,7 +4851,7 @@ info_calls(Allctr_t *allctr,
erts_print(TO, TOA, "%s%s calls: %b64u\n",PRFX,NAME,CC)
char *prefix = allctr->name_prefix;
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
PRINT_CC_5(to, arg, prefix, "alloc", allctr->calls.this_alloc);
@@ -4927,7 +4927,7 @@ info_calls(Allctr_t *allctr,
static Eterm
info_options(Allctr_t *allctr,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -5079,7 +5079,7 @@ reset_max_values(CarriersStats_t *cs)
\* */
Eterm
-erts_alcu_au_info_options(int *print_to_p, void *print_to_arg,
+erts_alcu_au_info_options(fmtfn_t *print_to_p, void *print_to_arg,
Uint **hpp, Uint *szp)
{
Eterm res = THE_NON_VALUE;
@@ -5122,7 +5122,7 @@ erts_alcu_au_info_options(int *print_to_p, void *print_to_arg,
Eterm
erts_alcu_info_options(Allctr_t *allctr,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -5154,7 +5154,7 @@ Eterm
erts_alcu_sz_info(Allctr_t *allctr,
int internal,
int begin_max_period,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -5240,7 +5240,7 @@ Eterm
erts_alcu_info(Allctr_t *allctr,
int internal,
int begin_max_period,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -6083,7 +6083,7 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
goto error;
allctr->min_block_size = UNIT_CEILING(allctr->min_block_size
+ sizeof(FreeBlkFtr_t));
-#if ERTS_SMP
+#ifdef ERTS_SMP
if (init->tpref) {
Uint sz = ABLK_HDR_SZ;
sz += (init->fix ?
@@ -6484,11 +6484,6 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk)
ASSERT(SBC2BLK(allctr, sbc) == iblk);
ASSERT(CARRIER_SZ(sbc) - SBC_HEADER_SIZE >= SBC_BLK_SZ(iblk));
-#if HAVE_ERTS_MSEG
- if (IS_MSEG_CARRIER(sbc)) {
- ASSERT(CARRIER_SZ(sbc) % ERTS_SACRR_UNIT_SZ == 0);
- }
-#endif
crr = sbc;
cl = &allctr->sbc_list;
}
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index 2958bdf8d1..f570703f25 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -178,10 +178,10 @@ void * erts_alcu_realloc_mv_thr_pref(ErtsAlcType_t, void *, void *, Uint);
void erts_alcu_free_thr_pref(ErtsAlcType_t, void *, void *);
#endif
#endif
-Eterm erts_alcu_au_info_options(int *, void *, Uint **, Uint *);
-Eterm erts_alcu_info_options(Allctr_t *, int *, void *, Uint **, Uint *);
-Eterm erts_alcu_sz_info(Allctr_t *, int, int, int *, void *, Uint **, Uint *);
-Eterm erts_alcu_info(Allctr_t *, int, int, int *, void *, Uint **, Uint *);
+Eterm erts_alcu_au_info_options(fmtfn_t *, void *, Uint **, Uint *);
+Eterm erts_alcu_info_options(Allctr_t *, fmtfn_t *, void *, Uint **, Uint *);
+Eterm erts_alcu_sz_info(Allctr_t *, int, int, fmtfn_t *, void *, Uint **, Uint *);
+Eterm erts_alcu_info(Allctr_t *, int, int, fmtfn_t *, void *, Uint **, Uint *);
void erts_alcu_init(AlcUInit_t *);
void erts_alcu_current_size(Allctr_t *, AllctrSize_t *,
ErtsAlcUFixInfo_t *, int);
@@ -592,7 +592,7 @@ struct Allctr_t_ {
Block_t *, Uint);
void (*link_free_block) (Allctr_t *, Block_t *);
void (*unlink_free_block) (Allctr_t *, Block_t *);
- Eterm (*info_options) (Allctr_t *, char *, int *,
+ Eterm (*info_options) (Allctr_t *, char *, fmtfn_t *,
void *, Uint **, Uint *);
Uint (*get_next_mbc_size) (Allctr_t *);
diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.c b/erts/emulator/beam/erl_ao_firstfit_alloc.c
index 7e239d1f5d..05ba1f9891 100644
--- a/erts/emulator/beam/erl_ao_firstfit_alloc.c
+++ b/erts/emulator/beam/erl_ao_firstfit_alloc.c
@@ -224,7 +224,7 @@ static AOFF_RBTree_t* rbt_search(AOFF_RBTree_t* root, Uint size);
static int rbt_assert_is_member(AOFF_RBTree_t* root, AOFF_RBTree_t* node);
#endif
-static Eterm info_options(Allctr_t *, char *, int *, void *, Uint **, Uint *);
+static Eterm info_options(Allctr_t *, char *, fmtfn_t *, void *, Uint **, Uint *);
static void init_atoms(void);
@@ -1014,7 +1014,7 @@ add_2tup(Uint **hpp, Uint *szp, Eterm *lp, Eterm el1, Eterm el2)
static Eterm
info_options(Allctr_t *allctr,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
diff --git a/erts/emulator/beam/erl_bestfit_alloc.c b/erts/emulator/beam/erl_bestfit_alloc.c
index 379cee39a1..6173c408e1 100644
--- a/erts/emulator/beam/erl_bestfit_alloc.c
+++ b/erts/emulator/beam/erl_bestfit_alloc.c
@@ -104,7 +104,7 @@ static void bf_link_free_block (Allctr_t *, Block_t *);
static ERTS_INLINE void bf_unlink_free_block (Allctr_t *, Block_t *);
-static Eterm info_options (Allctr_t *, char *, int *,
+static Eterm info_options (Allctr_t *, char *, fmtfn_t *,
void *, Uint **, Uint *);
static void init_atoms (void);
@@ -921,7 +921,7 @@ add_2tup(Uint **hpp, Uint *szp, Eterm *lp, Eterm el1, Eterm el2)
static Eterm
info_options(Allctr_t *allctr,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
diff --git a/erts/emulator/beam/erl_bif_ddll.c b/erts/emulator/beam/erl_bif_ddll.c
index ef77201544..587859e413 100644
--- a/erts/emulator/beam/erl_bif_ddll.c
+++ b/erts/emulator/beam/erl_bif_ddll.c
@@ -1099,7 +1099,7 @@ void erts_ddll_increment_port_count(DE_Handle *dh)
void erts_ddll_decrement_port_count(DE_Handle *dh)
{
assert_drv_list_locked();
-#if DEBUG
+#ifdef DEBUG
ASSERT(erts_smp_atomic32_dec_read_nob(&dh->port_count) >= 0);
#else
erts_smp_atomic32_dec_nob(&dh->port_count);
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 81a72cc4e1..0e0842e139 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -317,7 +317,7 @@ make_link_list(Process *p, ErtsLink *root, Eterm tail)
}
int
-erts_print_system_version(int to, void *arg, Process *c_p)
+erts_print_system_version(fmtfn_t to, void *arg, Process *c_p)
{
int i, rc = -1;
char *rc_str = "";
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index 485f68ca98..fd092015bd 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -201,7 +201,7 @@ static int free_table_cont(Process *p,
DbTable *tb,
int first,
int clean_meta_tab);
-static void print_table(int to, void *to_arg, int show, DbTable* tb);
+static void print_table(fmtfn_t to, void *to_arg, int show, DbTable* tb);
static BIF_RETTYPE ets_select_delete_1(BIF_ALIST_1);
static BIF_RETTYPE ets_select_count_1(BIF_ALIST_1);
static BIF_RETTYPE ets_select_trap_1(BIF_ALIST_1);
@@ -3871,7 +3871,7 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What)
return ret;
}
-static void print_table(int to, void *to_arg, int show, DbTable* tb)
+static void print_table(fmtfn_t to, void *to_arg, int show, DbTable* tb)
{
erts_print(to, to_arg, "Table: %T\n", tb->common.id);
erts_print(to, to_arg, "Name: %T\n", tb->common.the_name);
@@ -3891,7 +3891,7 @@ static void print_table(int to, void *to_arg, int show, DbTable* tb)
erts_print(to, to_arg, "Read Concurrency: %T\n", table_info(NULL, tb, am_read_concurrency));
}
-void db_info(int to, void *to_arg, int show) /* Called by break handler */
+void db_info(fmtfn_t to, void *to_arg, int show) /* Called by break handler */
{
int i;
for (i=0; i < db_max_tabs; i++)
diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h
index f7eb3dc45c..852440ff31 100644
--- a/erts/emulator/beam/erl_db.h
+++ b/erts/emulator/beam/erl_db.h
@@ -74,7 +74,7 @@ typedef enum {
void init_db(ErtsDbSpinCount);
int erts_db_process_exiting(Process *, ErtsProcLocks);
-void db_info(int, void *, int);
+void db_info(fmtfn_t, void *, int);
void erts_db_foreach_table(void (*)(DbTable *, void *), void *);
void erts_db_foreach_offheap(DbTable *,
void (*func)(ErlOffHeap *, void *),
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index 939ae57192..b2a231467b 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -412,7 +412,7 @@ static int db_select_count_continue_hash(Process *p, DbTable *tbl,
static int db_select_delete_continue_hash(Process *p, DbTable *tbl,
Eterm continuation, Eterm *ret);
static int db_take_hash(Process *, DbTable *, Eterm, Eterm *);
-static void db_print_hash(int to,
+static void db_print_hash(fmtfn_t to,
void *to_arg,
int show,
DbTable *tbl);
@@ -2135,7 +2135,7 @@ int db_mark_all_deleted_hash(DbTable *tbl)
/* Display hash table contents (for dump) */
-static void db_print_hash(int to, void *to_arg, int show, DbTable *tbl)
+static void db_print_hash(fmtfn_t to, void *to_arg, int show, DbTable *tbl)
{
DbTableHash *tb = &tbl->hash;
DbHashStats stats;
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index 02d211a4bb..dd9403e132 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -385,7 +385,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
static int db_select_delete_continue_tree(Process *p, DbTable *tbl,
Eterm continuation, Eterm *ret);
static int db_take_tree(Process *, DbTable *, Eterm, Eterm *);
-static void db_print_tree(int to, void *to_arg,
+static void db_print_tree(fmtfn_t to, void *to_arg,
int show, DbTable *tbl);
static int db_free_table_tree(DbTable *tbl);
@@ -1740,7 +1740,7 @@ static int db_take_tree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
/* Display tree contents (for dump) */
-static void db_print_tree(int to, void *to_arg,
+static void db_print_tree(fmtfn_t to, void *to_arg,
int show,
DbTable *tbl)
{
diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h
index 4acedbfed0..49e5f6b4cf 100644
--- a/erts/emulator/beam/erl_db_util.h
+++ b/erts/emulator/beam/erl_db_util.h
@@ -175,7 +175,7 @@ typedef struct db_table_method
int (*db_free_table)(DbTable* db /* [in out] */ );
int (*db_free_table_continue)(DbTable* db); /* [in out] */
- void (*db_print)(int to,
+ void (*db_print)(fmtfn_t to,
void* to_arg,
int show,
DbTable* tb /* [in out] */ );
diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c
index 3e3bfa03a2..3526bb684d 100644
--- a/erts/emulator/beam/erl_debug.c
+++ b/erts/emulator/beam/erl_debug.c
@@ -60,10 +60,10 @@ static const char dashes[PTR_SIZE+3] = {
void pps(Process*, Eterm*);
void ptd(Process*, Eterm);
-void paranoid_display(int, void*, Process*, Eterm);
+void paranoid_display(fmtfn_t, void*, Process*, Eterm);
static int dcount;
-static int pdisplay1(int to, void *to_arg, Process* p, Eterm obj);
+static int pdisplay1(fmtfn_t to, void *to_arg, Process* p, Eterm obj);
void ptd(Process* p, Eterm x)
{
@@ -77,14 +77,14 @@ void ptd(Process* p, Eterm x)
*/
void
-paranoid_display(int to, void *to_arg, Process* p, Eterm obj)
+paranoid_display(fmtfn_t to, void *to_arg, Process* p, Eterm obj)
{
dcount = 100000;
pdisplay1(to, to_arg, p, obj);
}
static int
-pdisplay1(int to, void *to_arg, Process* p, Eterm obj)
+pdisplay1(fmtfn_t to, void *to_arg, Process* p, Eterm obj)
{
int i, k;
Eterm* nobj;
@@ -201,7 +201,7 @@ pdisplay1(int to, void *to_arg, Process* p, Eterm obj)
void
pps(Process* p, Eterm* stop)
{
- int to = ERTS_PRINT_STDOUT;
+ fmtfn_t to = ERTS_PRINT_STDOUT;
void *to_arg = NULL;
Eterm* sp = STACK_START(p) - 1;
diff --git a/erts/emulator/beam/erl_drv_nif.h b/erts/emulator/beam/erl_drv_nif.h
index 6ec5fbb895..2489099b5c 100644
--- a/erts/emulator/beam/erl_drv_nif.h
+++ b/erts/emulator/beam/erl_drv_nif.h
@@ -69,10 +69,6 @@ typedef enum {
# define SIZEOF_LONG_LONG_SAVED__ SIZEOF_LONG_LONG
# undef SIZEOF_LONG_LONG
#endif
-#ifdef HALFWORD_HEAP_EMULATOR
-# define HALFWORD_HEAP_EMULATOR_SAVED__ HALFWORD_HEAP_EMULATOR
-# undef HALFWORD_HEAP_EMULATOR
-#endif
#include "erl_int_sizes_config.h"
#if defined(SIZEOF_CHAR_SAVED__) && SIZEOF_CHAR_SAVED__ != SIZEOF_CHAR
# error SIZEOF_CHAR mismatch
diff --git a/erts/emulator/beam/erl_fun.c b/erts/emulator/beam/erl_fun.c
index 9deec946d5..41097203d4 100644
--- a/erts/emulator/beam/erl_fun.c
+++ b/erts/emulator/beam/erl_fun.c
@@ -31,6 +31,9 @@
static Hash erts_fun_table;
#include "erl_smp.h"
+#ifdef HIPE
+# include "hipe_mode_switch.h"
+#endif
static erts_smp_rwmtx_t erts_fun_table_lock;
@@ -74,7 +77,7 @@ erts_init_fun_table(void)
}
void
-erts_fun_info(int to, void *to_arg)
+erts_fun_info(fmtfn_t to, void *to_arg)
{
int lock = !ERTS_IS_CRASH_DUMPING;
if (lock)
@@ -219,6 +222,10 @@ erts_fun_purge_prepare(BeamInstr* start, BeamInstr* end)
fe->pend_purge_address = addr;
ERTS_SMP_WRITE_MEMORY_BARRIER;
fe->address = unloaded_fun;
+#ifdef HIPE
+ fe->pend_purge_native_address = fe->native_address;
+ hipe_set_closure_stub(fe);
+#endif
erts_purge_state_add_fun(fe);
}
b = b->next;
@@ -234,9 +241,12 @@ erts_fun_purge_abort_prepare(ErlFunEntry **funs, Uint no)
for (ix = 0; ix < no; ix++) {
ErlFunEntry *fe = funs[ix];
- if (fe->address == unloaded_fun)
+ if (fe->address == unloaded_fun) {
fe->address = fe->pend_purge_address;
- fe->pend_purge_address = NULL;
+#ifdef HIPE
+ fe->native_address = fe->pend_purge_native_address;
+#endif
+ }
}
}
@@ -245,8 +255,12 @@ erts_fun_purge_abort_finalize(ErlFunEntry **funs, Uint no)
{
Uint ix;
- for (ix = 0; ix < no; ix++)
+ for (ix = 0; ix < no; ix++) {
funs[ix]->pend_purge_address = NULL;
+#ifdef HIPE
+ funs[ix]->pend_purge_native_address = NULL;
+#endif
+ }
}
void
@@ -257,6 +271,9 @@ erts_fun_purge_complete(ErlFunEntry **funs, Uint no)
for (ix = 0; ix < no; ix++) {
ErlFunEntry *fe = funs[ix];
fe->pend_purge_address = NULL;
+#ifdef HIPE
+ fe->pend_purge_native_address = NULL;
+#endif
if (erts_refc_dectest(&fe->refc, 0) == 0)
erts_erase_fun_entry(fe);
}
@@ -264,7 +281,7 @@ erts_fun_purge_complete(ErlFunEntry **funs, Uint no)
}
void
-erts_dump_fun_entries(int to, void *to_arg)
+erts_dump_fun_entries(fmtfn_t to, void *to_arg)
{
int limit;
HashBucket** bucket;
@@ -325,6 +342,7 @@ fun_alloc(ErlFunEntry* template)
obj->pend_purge_address = NULL;
#ifdef HIPE
obj->native_address = NULL;
+ obj->pend_purge_native_address = NULL;
#endif
return obj;
}
diff --git a/erts/emulator/beam/erl_fun.h b/erts/emulator/beam/erl_fun.h
index 6ba055d92c..83899f24a6 100644
--- a/erts/emulator/beam/erl_fun.h
+++ b/erts/emulator/beam/erl_fun.h
@@ -45,6 +45,9 @@ typedef struct erl_fun_entry {
erts_refc_t refc; /* Reference count: One for code + one for each
fun object in each process. */
BeamInstr *pend_purge_address; /* address stored during a pending purge */
+#ifdef HIPE
+ UWord* pend_purge_native_address;
+#endif
} ErlFunEntry;
/*
@@ -68,7 +71,7 @@ typedef struct erl_fun_thing {
#define ERL_FUN_SIZE ((sizeof(ErlFunThing)/sizeof(Eterm))-1)
void erts_init_fun_table(void);
-void erts_fun_info(int, void *);
+void erts_fun_info(fmtfn_t, void *);
int erts_fun_table_sz(void);
ErlFunEntry* erts_put_fun_entry(Eterm mod, int uniq, int index);
@@ -83,6 +86,6 @@ void erts_fun_purge_prepare(BeamInstr* start, BeamInstr* end);
void erts_fun_purge_abort_prepare(ErlFunEntry **funs, Uint no);
void erts_fun_purge_abort_finalize(ErlFunEntry **funs, Uint no);
void erts_fun_purge_complete(ErlFunEntry **funs, Uint no);
-void erts_dump_fun_entries(int, void *);
+void erts_dump_fun_entries(fmtfn_t, void *);
#endif
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index db262d35c5..28b2b02914 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -35,7 +35,7 @@
#include "error.h"
#include "big.h"
#include "erl_gc.h"
-#if HIPE
+#ifdef HIPE
#include "hipe_stack.h"
#include "hipe_mode_switch.h"
#endif
@@ -395,11 +395,11 @@ erts_gc_after_bif_call_lhf(Process* p, ErlHeapFragment *live_hf_end,
if (is_non_value(result)) {
if (p->freason == TRAP) {
- #if HIPE
+#ifdef HIPE
if (regs == NULL) {
regs = erts_proc_sched_data(p)->x_reg_array;
}
- #endif
+#endif
cost = garbage_collect(p, live_hf_end, 0, regs, p->arity, p->fcalls);
} else {
cost = garbage_collect(p, live_hf_end, 0, regs, arity, p->fcalls);
@@ -2317,6 +2317,11 @@ move_msgq_to_heap(Process *p)
static Uint
setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset)
{
+ /*
+ * NOTE!
+ * Remember to update offset_rootset() when changing
+ * this function.
+ */
Roots* roots;
Uint n;
@@ -2961,6 +2966,12 @@ offset_one_rootset(Process *p, Sint offs, char* area, Uint area_size,
offset_heap_ptr(objv, nobj, offs, area, area_size);
}
offset_off_heap(p, offs, area, area_size);
+ if (ERTS_PROC_GET_NIF_TRAP_EXPORT(p)) {
+ Eterm* argv;
+ int argc;
+ if (erts_setup_nif_gc(p, &argv, &argc))
+ offset_heap_ptr(argv, argc, offs, area, area_size);
+ }
}
static void
diff --git a/erts/emulator/beam/erl_goodfit_alloc.c b/erts/emulator/beam/erl_goodfit_alloc.c
index 223ba193da..50aa41b4d2 100644
--- a/erts/emulator/beam/erl_goodfit_alloc.c
+++ b/erts/emulator/beam/erl_goodfit_alloc.c
@@ -168,7 +168,7 @@ static Block_t * get_free_block (Allctr_t *, Uint,
static void link_free_block (Allctr_t *, Block_t *);
static void unlink_free_block (Allctr_t *, Block_t *);
static void update_last_aux_mbc (Allctr_t *, Carrier_t *);
-static Eterm info_options (Allctr_t *, char *, int *,
+static Eterm info_options (Allctr_t *, char *, fmtfn_t *,
void *, Uint **, Uint *);
static void init_atoms (void);
@@ -551,7 +551,7 @@ add_2tup(Uint **hpp, Uint *szp, Eterm *lp, Eterm el1, Eterm el2)
static Eterm
info_options(Allctr_t *allctr,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
diff --git a/erts/emulator/beam/erl_hl_timer.c b/erts/emulator/beam/erl_hl_timer.c
index f1bef28186..d29d079fc5 100644
--- a/erts/emulator/beam/erl_hl_timer.c
+++ b/erts/emulator/beam/erl_hl_timer.c
@@ -2851,7 +2851,7 @@ erts_read_port_timer(Port *c_prt)
*/
typedef struct {
- int to;
+ fmtfn_t to;
void *to_arg;
ErtsMonotonicTime now;
} ErtsBTMPrint;
@@ -2881,7 +2881,7 @@ btm_print(ErtsHLTimer *tmr, void *vbtmp)
}
void
-erts_print_bif_timer_info(int to, void *to_arg)
+erts_print_bif_timer_info(fmtfn_t to, void *to_arg)
{
ErtsBTMPrint btmp;
int six;
diff --git a/erts/emulator/beam/erl_hl_timer.h b/erts/emulator/beam/erl_hl_timer.h
index 0931bb8965..705be94532 100644
--- a/erts/emulator/beam/erl_hl_timer.h
+++ b/erts/emulator/beam/erl_hl_timer.h
@@ -72,7 +72,7 @@ erts_handle_canceled_timers(void *vesdp,
#endif
Uint erts_bif_timer_memory_size(void);
-void erts_print_bif_timer_info(int to, void *to_arg);
+void erts_print_bif_timer_info(fmtfn_t to, void *to_arg);
void erts_debug_bif_timer_foreach(void (*func)(Eterm,
Eterm,
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index b299ac8d64..c5904b375e 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -795,9 +795,6 @@ early_init(int *argc, char **argv) /*
erts_thr_progress_pre_init();
#endif
-#ifdef ERTS_ENABLE_LOCK_CHECK
- erts_lc_init();
-#endif
#ifdef ERTS_SMP
erts_smp_atomic32_init_nob(&erts_writing_erl_crash_dump, 0L);
erts_tsd_key_create(&erts_is_crash_dumping_key,"erts_is_crash_dumping_key");
@@ -2372,6 +2369,8 @@ system_cleanup(int flush_async)
erts_exit_flush_async();
}
+static int erts_exit_code;
+
static __decl_noreturn void __noreturn
erts_exit_vv(int n, int flush_async, char *fmt, va_list args1, va_list args2)
{
@@ -2383,12 +2382,21 @@ erts_exit_vv(int n, int flush_async, char *fmt, va_list args1, va_list args2)
if (fmt != NULL && *fmt != '\0')
erl_error(fmt, args2); /* Print error message. */
- /* Produce an Erlang core dump if error */
+ erts_exit_code = n;
+
+ /* Produce an Erlang crash dump if error */
if (((n == ERTS_ERROR_EXIT && erts_no_crash_dump == 0) || n == ERTS_DUMP_EXIT)
&& erts_initialized) {
erl_crash_dump_v((char*) NULL, 0, fmt, args1);
}
+ erts_exit_epilogue();
+}
+
+__decl_noreturn void __noreturn erts_exit_epilogue(void)
+{
+ int n = erts_exit_code;
+
sys_tty_reset(n);
if (n == ERTS_INTR_EXIT)
diff --git a/erts/emulator/beam/erl_instrument.c b/erts/emulator/beam/erl_instrument.c
index f84c63e7a4..4d4defd8b5 100644
--- a/erts/emulator/beam/erl_instrument.c
+++ b/erts/emulator/beam/erl_instrument.c
@@ -539,7 +539,7 @@ map_stat_free(ErtsAlcType_t n, void *extra, void *ptr)
}
-static void dump_memory_map_to_stream(FILE *fp)
+static void dump_memory_map_to_stream(fmtfn_t to, void* to_arg)
{
ErtsAlcType_t n;
MapStatBlock_t *bp;
@@ -551,7 +551,7 @@ static void dump_memory_map_to_stream(FILE *fp)
/* Write header */
- fprintf(fp,
+ erts_cbprintf(to, to_arg,
"{instr_hdr,\n"
" %lu,\n"
" %lu,\n"
@@ -574,7 +574,7 @@ static void dump_memory_map_to_stream(FILE *fp)
else
astr = ERTS_ALC_A2AD(ERTS_ALC_A_SYSTEM);
- fprintf(fp,
+ erts_cbprintf(to, to_arg,
"%s{%s,%s,%s}%s",
(n == ERTS_ALC_N_MIN) ? "" : " ",
ERTS_ALC_N2TD(n),
@@ -583,12 +583,12 @@ static void dump_memory_map_to_stream(FILE *fp)
(n == ERTS_ALC_N_MAX) ? "" : ",\n");
}
- fprintf(fp, "}}.\n");
+ erts_cbprintf(to, to_arg, "}}.\n");
/* Write memory data */
for (bp = mem_anchor; bp; bp = bp->next) {
if (is_internal_pid(bp->pid))
- fprintf(fp,
+ erts_cbprintf(to, to_arg,
"{%lu, %lu, %lu, {%lu,%lu,%lu}}.\n",
(UWord) bp->type_no,
(UWord) bp->mem,
@@ -597,7 +597,7 @@ static void dump_memory_map_to_stream(FILE *fp)
(UWord) pid_number(bp->pid),
(UWord) pid_serial(bp->pid));
else
- fprintf(fp,
+ erts_cbprintf(to, to_arg,
"{%lu, %lu, %lu, undefined}.\n",
(UWord) bp->type_no,
(UWord) bp->mem,
@@ -608,40 +608,29 @@ static void dump_memory_map_to_stream(FILE *fp)
erts_mtx_unlock(&instr_mutex);
}
-int erts_instr_dump_memory_map_to_fd(int fd)
+int erts_instr_dump_memory_map_to(fmtfn_t to, void* to_arg)
{
- char buf[BUFSIZ];
- FILE *f;
-
if (!erts_instr_memory_map)
return 0;
- f = fdopen(fd, "w");
- if (f == NULL)
- return 0;
-
- /* Avoid allocating memory; we may have run out of it at this point. */
- setbuf(f, buf);
-
- dump_memory_map_to_stream(f);
- fflush(f);
+ dump_memory_map_to_stream(to, to_arg);
return 1;
}
int erts_instr_dump_memory_map(const char *name)
{
- FILE *f;
+ int fd;
if (!erts_instr_memory_map)
return 0;
- f = fopen(name, "w");
- if (f == NULL)
+ fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0640);
+ if (fd < 0)
return 0;
- dump_memory_map_to_stream(f);
+ dump_memory_map_to_stream(erts_write_fd, (void*)&fd);
- fclose(f);
+ close(fd);
return 1;
}
@@ -998,19 +987,19 @@ erts_instr_get_stat(Process *proc, Eterm what, int begin_max_period)
}
static void
-dump_stat_to_stream(FILE *fp, int begin_max_period)
+dump_stat_to_stream(fmtfn_t to, void* to_arg, int begin_max_period)
{
ErtsAlcType_t i, a_max, a_min;
erts_mtx_lock(&instr_mutex);
- fprintf(fp,
+ erts_cbprintf(to, to_arg,
"{instr_vsn,%lu}.\n",
(unsigned long) ERTS_INSTR_VSN);
update_max_ever_values(&stats->tot, 0, 0);
- fprintf(fp,
+ erts_cbprintf(to, to_arg,
"{total,[{total,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}]}.\n",
(UWord) stats->tot.size,
(UWord) stats->tot.max_size,
@@ -1038,7 +1027,7 @@ dump_stat_to_stream(FILE *fp, int begin_max_period)
for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {
if (erts_allctrs_info[i].enabled) {
- fprintf(fp,
+ erts_cbprintf(to, to_arg,
"%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s",
i == a_min ? "{allocators,\n [" : " ",
ERTS_ALC_A2AD(i),
@@ -1055,7 +1044,7 @@ dump_stat_to_stream(FILE *fp, int begin_max_period)
update_max_ever_values(stats->c, ERTS_ALC_C_MIN, ERTS_ALC_C_MAX);
for (i = ERTS_ALC_C_MIN; i <= ERTS_ALC_C_MAX; i++) {
- fprintf(fp,
+ erts_cbprintf(to, to_arg,
"%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s",
i == ERTS_ALC_C_MIN ? "{classes,\n [" : " ",
ERTS_ALC_C2CD(i),
@@ -1071,7 +1060,7 @@ dump_stat_to_stream(FILE *fp, int begin_max_period)
update_max_ever_values(stats->n, ERTS_ALC_N_MIN, ERTS_ALC_N_MAX);
for (i = ERTS_ALC_N_MIN; i <= ERTS_ALC_N_MAX; i++) {
- fprintf(fp,
+ erts_cbprintf(to, to_arg,
"%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s",
i == ERTS_ALC_N_MIN ? "{types,\n [" : " ",
ERTS_ALC_N2TD(i),
@@ -1095,40 +1084,29 @@ dump_stat_to_stream(FILE *fp, int begin_max_period)
}
-int erts_instr_dump_stat_to_fd(int fd, int begin_max_period)
+int erts_instr_dump_stat_to(fmtfn_t to, void* to_arg, int begin_max_period)
{
- char buf[BUFSIZ];
- FILE *fp;
-
if (!erts_instr_stat)
return 0;
- fp = fdopen(fd, "w");
- if (fp == NULL)
- return 0;
-
- /* Avoid allocating memory; we may have run out of it at this point. */
- setbuf(fp, buf);
-
- dump_stat_to_stream(fp, begin_max_period);
- fflush(fp);
+ dump_stat_to_stream(to, to_arg, begin_max_period);
return 1;
}
int erts_instr_dump_stat(const char *name, int begin_max_period)
{
- FILE *file;
+ int fd;
if (!erts_instr_stat)
return 0;
- file = fopen(name, "w");
- if (file == NULL)
+ fd = open(name, O_WRONLY | O_CREAT | O_TRUNC,0640);
+ if (fd < 0)
return 0;
- dump_stat_to_stream(file, begin_max_period);
+ dump_stat_to_stream(erts_write_fd, (void*)&fd, begin_max_period);
- fclose(file);
+ close(fd);
return 1;
}
diff --git a/erts/emulator/beam/erl_instrument.h b/erts/emulator/beam/erl_instrument.h
index 1f04c91d5e..351172b2fa 100644
--- a/erts/emulator/beam/erl_instrument.h
+++ b/erts/emulator/beam/erl_instrument.h
@@ -29,10 +29,10 @@ extern int erts_instr_memory_map;
extern int erts_instr_stat;
Uint erts_instr_init(int stat, int map_stat);
-int erts_instr_dump_memory_map_to_fd(int fd);
+int erts_instr_dump_memory_map_to(fmtfn_t to, void* to_arg);
int erts_instr_dump_memory_map(const char *name);
Eterm erts_instr_get_memory_map(Process *process);
-int erts_instr_dump_stat_to_fd(int fd, int begin_max_period);
+int erts_instr_dump_stat_to(fmtfn_t to, void* to_arg, int begin_max_period);
int erts_instr_dump_stat(const char *name, int begin_max_period);
Eterm erts_instr_get_stat(Process *proc, Eterm what, int begin_max_period);
Eterm erts_instr_get_type_info(Process *proc);
diff --git a/erts/emulator/beam/erl_lock_count.c b/erts/emulator/beam/erl_lock_count.c
index a00e0f0fff..481e92b2cd 100644
--- a/erts/emulator/beam/erl_lock_count.c
+++ b/erts/emulator/beam/erl_lock_count.c
@@ -274,11 +274,11 @@ void erts_lcnt_init() {
lcnt_unlock();
- /* set start timer and zero statistics */
- erts_lcnt_clear_counters();
}
void erts_lcnt_late_init() {
+ /* set start timer and zero statistics */
+ erts_lcnt_clear_counters();
erts_thr_install_exit_handler(erts_lcnt_thread_exit_handler);
}
diff --git a/erts/emulator/beam/erl_math.c b/erts/emulator/beam/erl_math.c
index 990fa63bd4..1f270eb55f 100644
--- a/erts/emulator/beam/erl_math.c
+++ b/erts/emulator/beam/erl_math.c
@@ -256,3 +256,8 @@ BIF_RETTYPE math_floor_1(BIF_ALIST_1)
{
return math_call_1(BIF_P, floor, BIF_ARG_1);
}
+
+BIF_RETTYPE math_fmod_2(BIF_ALIST_2)
+{
+ return math_call_2(BIF_P, fmod, BIF_ARG_1, BIF_ARG_2);
+}
diff --git a/erts/emulator/beam/erl_msacc.h b/erts/emulator/beam/erl_msacc.h
index ad7c8c5eee..7e02d8e101 100644
--- a/erts/emulator/beam/erl_msacc.h
+++ b/erts/emulator/beam/erl_msacc.h
@@ -22,7 +22,7 @@
#define ERL_MSACC_H__
/* Can be enabled/disabled via configure */
-#if ERTS_ENABLE_MSACC == 2
+#if defined(ERTS_ENABLE_MSACC) && ERTS_ENABLE_MSACC == 2
#define ERTS_MSACC_EXTENDED_STATES 1
#endif
@@ -66,7 +66,7 @@
#define ERTS_MSACC_STATE_COUNT 7
-#if ERTS_MSACC_STATE_STRINGS && ERTS_ENABLE_MSACC
+#if defined(ERTS_MSACC_STATE_STRINGS) && defined(ERTS_ENABLE_MSACC)
static char *erts_msacc_states[] = {
"aux",
"check_io",
@@ -104,7 +104,7 @@ static char *erts_msacc_states[] = {
#define ERTS_MSACC_STATE_COUNT ERTS_MSACC_STATIC_STATE_COUNT
#endif
-#if ERTS_MSACC_STATE_STRINGS
+#ifdef ERTS_MSACC_STATE_STRINGS
static char *erts_msacc_states[] = {
"alloc",
"aux",
@@ -157,7 +157,7 @@ struct erl_msacc_t_ {
};
-#if ERTS_ENABLE_MSACC
+#ifdef ERTS_ENABLE_MSACC
#ifdef USE_THREADS
extern erts_tsd_key_t erts_msacc_key;
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index c5606f72a1..202f713f67 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -71,10 +71,12 @@
struct erl_module_nif {
void* priv_data;
void* handle; /* "dlopen" */
- struct enif_entry_t* entry;
+ struct enif_entry_t entry;
erts_refc_t rt_cnt; /* number of resource types */
erts_refc_t rt_dtor_cnt; /* number of resource types with destructors */
Module* mod; /* Can be NULL if orphan with dtor-resources left */
+
+ ErlNifFunc _funcs_copy_[1]; /* only used for old libs */
};
#ifdef DEBUG
@@ -1958,10 +1960,10 @@ static void close_lib(struct erl_module_nif* lib)
ASSERT(lib->handle != NULL);
ASSERT(erts_refc_read(&lib->rt_dtor_cnt,0) == 0);
- if (lib->entry != NULL && lib->entry->unload != NULL) {
+ if (lib->entry.unload != NULL) {
struct enif_msg_environment_t msg_env;
pre_nif_noproc(&msg_env, lib, NULL);
- lib->entry->unload(&msg_env.env, lib->priv_data);
+ lib->entry.unload(&msg_env.env, lib->priv_data);
post_nif_noproc(&msg_env);
}
if (!erts_is_static_nif(lib->handle))
@@ -2312,6 +2314,17 @@ erts_setup_nif_gc(Process* proc, Eterm** objv, int* nobj)
return gc;
}
+int
+erts_check_nif_export_in_area(Process *p, char *start, Uint size)
+{
+ NifExport *nep = ERTS_PROC_GET_NIF_TRAP_EXPORT(p);
+ if (!nep || !nep->saved_current)
+ return 0;
+ if (ErtsInArea(nep->saved_current, start, size))
+ return 1;
+ return 0;
+}
+
/*
* Allocate a NifExport and set it in proc specific data
*/
@@ -2363,6 +2376,7 @@ init_nif_sched_data(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirec
Eterm* reg;
NifExport* ep;
int i, scheduler;
+ int orig_argc;
execution_state(env, &proc, &scheduler);
@@ -2373,11 +2387,14 @@ init_nif_sched_data(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirec
reg = erts_proc_sched_data(proc)->x_reg_array;
+ ASSERT(!need_save || proc->current);
+ orig_argc = need_save ? (int) proc->current->arity : 0;
+
ep = (NifExport*) ERTS_PROC_GET_NIF_TRAP_EXPORT(proc);
if (!ep)
- ep = allocate_nif_sched_data(proc, argc);
- else if (need_save && ep->rootset_extra < argc) {
- NifExport* new_ep = allocate_nif_sched_data(proc, argc);
+ ep = allocate_nif_sched_data(proc, orig_argc);
+ else if (need_save && ep->rootset_extra < orig_argc) {
+ NifExport* new_ep = allocate_nif_sched_data(proc, orig_argc);
destroy_nif_export(ep);
ep = new_ep;
}
@@ -2390,16 +2407,14 @@ init_nif_sched_data(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirec
}
if (scheduler > 0)
ERTS_VBUMP_ALL_REDS(proc);
- for (i = 0; i < argc; i++) {
- if (need_save)
- ep->rootset[i+1] = reg[i];
- reg[i] = (Eterm) argv[i];
- }
if (need_save) {
- ASSERT(proc->current);
ep->saved_current = proc->current;
- ep->saved_argc = argc;
+ ep->saved_argc = orig_argc;
+ for (i = 0; i < orig_argc; i++)
+ ep->rootset[i+1] = reg[i];
}
+ for (i = 0; i < argc; i++)
+ reg[i] = (Eterm) argv[i];
proc->i = (BeamInstr*) ep->exp.addressv[0];
ep->exp.info.mfa.module = proc->current->module;
ep->exp.info.mfa.function = proc->current->function;
@@ -3073,16 +3088,16 @@ Eterm erts_nif_taints(Process* p)
return list;
}
-void erts_print_nif_taints(int to, void* to_arg)
+void erts_print_nif_taints(fmtfn_t to, void* to_arg)
{
struct tainted_module_t* t;
const char* delim = "";
for (t=first_tainted_module ; t!=NULL; t=t->next) {
const Atom* atom = atom_tab(atom_val(t->module_atom));
- erts_print(to,to_arg,"%s%.*s", delim, atom->len, atom->name);
+ erts_cbprintf(to,to_arg,"%s%.*s", delim, atom->len, atom->name);
delim = ",";
}
- erts_print(to,to_arg,"\n");
+ erts_cbprintf(to,to_arg,"\n");
}
@@ -3115,33 +3130,52 @@ static Eterm load_nif_error(Process* p, const char* atom, const char* format, ..
return ret;
}
+#define AT_LEAST_VERSION(E,MAJ,MIN) \
+ (((E)->major * 0x100 + (E)->minor) >= ((MAJ) * 0x100 + (MIN)))
+
/*
- * The function below is for looping through ErlNifFunc arrays, helping
- * provide backwards compatibility across the version 2.7 change that added
- * the "flags" field to ErlNifFunc.
+ * Allocate erl_module_nif and make a _modern_ copy of the lib entry.
*/
-static ErlNifFunc* next_func(ErlNifEntry* entry, int* incrp, ErlNifFunc* func)
+static struct erl_module_nif* create_lib(const ErlNifEntry* src)
{
- ASSERT(incrp);
- if (!*incrp) {
- if (entry->major > 2 || (entry->major == 2 && entry->minor >= 7))
- *incrp = sizeof(ErlNifFunc);
- else {
- /*
- * ErlNifFuncV1 below is what ErlNifFunc was before the
- * addition of the flags field for 2.7, and is needed to handle
- * backward compatibility.
- */
- typedef struct {
- const char* name;
- unsigned arity;
- ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
- }ErlNifFuncV1;
- *incrp = sizeof(ErlNifFuncV1);
- }
+ struct erl_module_nif* lib;
+ ErlNifEntry* dst;
+ Uint bytes = offsetof(struct erl_module_nif, _funcs_copy_);
+
+ if (!AT_LEAST_VERSION(src, 2, 7))
+ bytes += src->num_of_funcs * sizeof(ErlNifFunc);
+
+ lib = erts_alloc(ERTS_ALC_T_NIF, bytes);
+ dst = &lib->entry;
+
+ sys_memcpy(dst, src, offsetof(ErlNifEntry, vm_variant));
+
+ if (AT_LEAST_VERSION(src, 2, 1)) {
+ dst->vm_variant = src->vm_variant;
+ } else {
+ dst->vm_variant = "beam.vanilla";
}
- return (ErlNifFunc*) ((char*)func + *incrp);
-}
+ if (AT_LEAST_VERSION(src, 2, 7)) {
+ dst->options = src->options;
+ } else {
+ /*
+ * Make a modern copy of the ErlNifFunc array
+ */
+ struct ErlNifFunc_V1 {
+ const char* name;
+ unsigned arity;
+ ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ }*src_funcs = (struct ErlNifFunc_V1*) src->funcs;
+ int i;
+ for (i = 0; i < src->num_of_funcs; ++i) {
+ sys_memcpy(&lib->_funcs_copy_[i], &src_funcs[i], sizeof(*src_funcs));
+ lib->_funcs_copy_[i].flags = 0;
+ }
+ dst->funcs = lib->_funcs_copy_;
+ dst->options = 0;
+ }
+ return lib;
+};
BIF_RETTYPE load_nif_2(BIF_ALIST_2)
@@ -3166,6 +3200,12 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
struct erl_module_instance* this_mi;
struct erl_module_instance* prev_mi;
+ if (BIF_P->flags & F_HIPE_MODE) {
+ ret = load_nif_error(BIF_P, "notsup", "Calling load_nif from HiPE compiled "
+ "modules not supported");
+ BIF_RET(ret);
+ }
+
encoding = erts_get_native_filename_encoding();
if (encoding == ERL_FILENAME_WIN_WCHAR) {
/* Do not convert the lib name to utf-16le yet, do that in win32 specific code */
@@ -3255,7 +3295,7 @@ 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
+ else if (AT_LEAST_VERSION(entry, 2, 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).",
@@ -3266,20 +3306,25 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
" match calling module '%T'", entry->name, mod_atom);
}
else {
- /*erts_fprintf(stderr, "Found module %T\r\n", mod_atom);*/
+ lib = create_lib(entry);
+ entry = &lib->entry; /* Use a guaranteed modern lib entry from now on */
- int maybe_dirty_nifs = ((entry->major > 2 || (entry->major == 2 && entry->minor >= 7))
- && (entry->options & ERL_NIF_DIRTY_NIF_OPTION));
- int incr = 0;
- ErlNifFunc* f = entry->funcs;
- for (i=0; i < entry->num_of_funcs && ret==am_ok; i++) {
+ lib->handle = handle;
+ erts_refc_init(&lib->rt_cnt, 0);
+ erts_refc_init(&lib->rt_dtor_cnt, 0);
+ ASSERT(opened_rt_list == NULL);
+ lib->mod = module_p;
+
+ for (i=0; i < entry->num_of_funcs && ret==am_ok; i++) {
ErtsCodeInfo** ci_pp;
+ ErlNifFunc* f = &entry->funcs[i];
+
if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom, ERTS_ATOM_ENC_LATIN1)
|| (ci_pp = get_func_pp(this_mi->code_hdr, f_atom, f->arity))==NULL) {
ret = load_nif_error(BIF_P,bad_lib,"Function not found %T:%s/%u",
mod_atom, f->name, f->arity);
}
- else if (maybe_dirty_nifs && f->flags) {
+ else if (f->flags) {
/*
* If the flags field is non-zero and this emulator was
* built with dirty scheduler support, check that the flags
@@ -3308,7 +3353,6 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
}
/*erts_fprintf(stderr, "Found NIF %T:%s/%u\r\n",
mod_atom, f->name, f->arity);*/
- f = next_func(entry, &incr, f);
}
}
@@ -3319,14 +3363,6 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
/* Call load or upgrade:
*/
-
- lib = erts_alloc(ERTS_ALC_T_NIF, sizeof(struct erl_module_nif));
- lib->handle = handle;
- lib->entry = entry;
- erts_refc_init(&lib->rt_cnt, 0);
- erts_refc_init(&lib->rt_dtor_cnt, 0);
- ASSERT(opened_rt_list == NULL);
- lib->mod = module_p;
env.mod_nif = lib;
lib->priv_data = NULL;
@@ -3343,8 +3379,6 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
prev_mi->nif->priv_data = prev_old_data;
ret = load_nif_error(BIF_P, upgrade, "Library upgrade-call unsuccessful (%d).", veto);
}
- else
- commit_opened_resource_types(lib);
}
else if (entry->load != NULL) { /********* Initial load ***********/
erts_pre_nif(&env, BIF_P, lib, NULL);
@@ -3353,22 +3387,21 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
if (veto) {
ret = load_nif_error(BIF_P, "load", "Library load-call unsuccessful (%d).", veto);
}
- else
- commit_opened_resource_types(lib);
}
if (ret == am_ok) {
+ commit_opened_resource_types(lib);
+
/*
** Everything ok, patch the beam code with op_call_nif
*/
- int incr = 0;
- ErlNifFunc* f = entry->funcs;
-
this_mi->nif = lib;
for (i=0; i < entry->num_of_funcs; i++)
{
+ ErlNifFunc* f = &entry->funcs[i];
ErtsCodeInfo* ci;
BeamInstr *code_ptr;
+
erts_atom_get(f->name, sys_strlen(f->name), &f_atom, ERTS_ATOM_ENC_LATIN1);
ci = *get_func_pp(this_mi->code_hdr, f_atom, f->arity);
code_ptr = erts_codeinfo_to_code(ci);
@@ -3383,8 +3416,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
g->orig_instr = (BeamInstr) BeamOp(op_call_nif);
}
#ifdef ERTS_DIRTY_SCHEDULERS
- if ((entry->major > 2 || (entry->major == 2 && entry->minor >= 7))
- && (entry->options & ERL_NIF_DIRTY_NIF_OPTION) && f->flags) {
+ if (f->flags) {
code_ptr[3] = (BeamInstr) f->fptr;
code_ptr[1] = (f->flags == ERL_NIF_DIRTY_JOB_IO_BOUND) ?
(BeamInstr) schedule_dirty_io_nif :
@@ -3394,7 +3426,6 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
#endif
code_ptr[1] = (BeamInstr) f->fptr;
code_ptr[2] = (BeamInstr) lib;
- f = next_func(entry, &incr, f);
}
}
else {
@@ -3478,8 +3509,8 @@ void erl_nif_init()
int erts_nif_get_funcs(struct erl_module_nif* mod,
ErlNifFunc **funcs)
{
- *funcs = mod->entry->funcs;
- return mod->entry->num_of_funcs;
+ *funcs = mod->entry.funcs;
+ return mod->entry.num_of_funcs;
}
Eterm erts_nif_call_function(Process *p, Process *tracee,
@@ -3490,10 +3521,10 @@ Eterm erts_nif_call_function(Process *p, Process *tracee,
#ifdef DEBUG
/* Verify that function is part of this module */
int i;
- for (i = 0; i < mod->entry->num_of_funcs; i++)
- if (fun == &(mod->entry->funcs[i]))
+ for (i = 0; i < mod->entry.num_of_funcs; i++)
+ if (fun == &(mod->entry.funcs[i]))
break;
- ASSERT(i < mod->entry->num_of_funcs);
+ ASSERT(i < mod->entry.num_of_funcs);
if (p)
ERTS_SMP_LC_ASSERT(erts_proc_lc_my_proc_locks(p) & ERTS_PROC_LOCK_MAIN
|| erts_smp_thr_progress_is_blocking());
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 494971e118..413b4f7343 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -49,7 +49,7 @@
** 2.8: 18.0 add enif_has_pending_exception
** 2.9: 18.2 enif_getenv
** 2.10: Time API
-** 2.11: 19.0 enif_snprintf
+** 2.11: 19.0 enif_snprintf
*/
#define ERL_NIF_MAJOR_VERSION 2
#define ERL_NIF_MINOR_VERSION 11
@@ -116,12 +116,13 @@ typedef struct enif_entry_t
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);
+
+ /* Added in 2.1 */
const char* vm_variant;
- unsigned options;
-}ErlNifEntry;
-/* Field bits for ErlNifEntry options */
-#define ERL_NIF_DIRTY_NIF_OPTION 1
+ /* Added in 2.7 */
+ unsigned options; /* Unused. Can be set to 0 or 1 (dirty sched config) */
+}ErlNifEntry;
typedef struct
@@ -266,8 +267,6 @@ extern TWinDynNifCallbacks WinDynNifCallbacks;
# define ERL_NIF_INIT_DECL(MODNAME) ERL_NIF_INIT_EXPORT ErlNifEntry* nif_init(ERL_NIF_INIT_ARGS)
#endif
-#define ERL_NIF_ENTRY_OPTIONS ERL_NIF_DIRTY_NIF_OPTION
-
#ifdef __cplusplus
}
# define ERL_NIF_INIT_PROLOGUE extern "C" {
@@ -293,7 +292,7 @@ ERL_NIF_INIT_DECL(NAME) \
FUNCS, \
LOAD, RELOAD, UPGRADE, UNLOAD, \
ERL_NIF_VM_VARIANT, \
- ERL_NIF_ENTRY_OPTIONS \
+ 1 \
}; \
ERL_NIF_INIT_BODY; \
return &entry; \
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index 646f786651..70500ed6e1 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -188,7 +188,7 @@ dist_table_free(void *vdep)
void
-erts_dist_table_info(int to, void *to_arg)
+erts_dist_table_info(fmtfn_t to, void *to_arg)
{
int lock = !ERTS_IS_CRASH_DUMPING;
if (lock)
@@ -564,7 +564,7 @@ erts_node_table_size(void)
}
void
-erts_node_table_info(int to, void *to_arg)
+erts_node_table_info(fmtfn_t to, void *to_arg)
{
int lock = !ERTS_IS_CRASH_DUMPING;
if (lock)
@@ -649,7 +649,7 @@ void erts_schedule_delete_node(ErlNode *enp)
}
struct pn_data {
- int to;
+ fmtfn_t to;
void *to_arg;
Eterm sysname;
int no_sysname;
@@ -679,7 +679,7 @@ static void print_node(void *venp, void *vpndp)
pndp->no_total++;
}
-void erts_print_node_info(int to,
+void erts_print_node_info(fmtfn_t to,
void *to_arg,
Eterm sysname,
int *no_sysname,
diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h
index 7a4434acbf..47a6724c21 100644
--- a/erts/emulator/beam/erl_node_tables.h
+++ b/erts/emulator/beam/erl_node_tables.h
@@ -179,7 +179,7 @@ DistEntry *erts_find_or_insert_dist_entry(Eterm);
DistEntry *erts_find_dist_entry(Eterm);
void erts_schedule_delete_dist_entry(DistEntry *);
Uint erts_dist_table_size(void);
-void erts_dist_table_info(int, void *);
+void erts_dist_table_info(fmtfn_t, void *);
void erts_set_dist_entry_not_connected(DistEntry *);
void erts_set_dist_entry_connected(DistEntry *, Eterm, Uint);
ErlNode *erts_find_or_insert_node(Eterm, Uint32);
@@ -187,8 +187,8 @@ void erts_schedule_delete_node(ErlNode *);
void erts_set_this_node(Eterm, Uint);
Uint erts_node_table_size(void);
void erts_init_node_tables(int);
-void erts_node_table_info(int, void *);
-void erts_print_node_info(int, void *, Eterm, int*, int*);
+void erts_node_table_info(fmtfn_t, void *);
+void erts_print_node_info(fmtfn_t, void *, Eterm, int*, int*);
Eterm erts_get_node_and_dist_references(struct process *);
#if defined(ERTS_SMP) && defined(ERTS_ENABLE_LOCK_CHECK)
int erts_lc_is_de_rwlocked(DistEntry *);
diff --git a/erts/emulator/beam/erl_port.h b/erts/emulator/beam/erl_port.h
index f90844ccc8..206078903d 100644
--- a/erts/emulator/beam/erl_port.h
+++ b/erts/emulator/beam/erl_port.h
@@ -369,7 +369,7 @@ Eterm erts_request_io_bytes(Process *c_p);
#define ERTS_PORT_REDS_INFO (CONTEXT_REDS/100)
#define ERTS_PORT_REDS_TERMINATE (CONTEXT_REDS/50)
-void print_port_info(Port *, int, void *);
+void print_port_info(Port *, fmtfn_t, void *);
void erts_port_free(Port *);
#ifndef ERTS_SMP
void erts_port_cleanup(Port *);
@@ -733,7 +733,7 @@ erts_thr_drvport2port(ErlDrvPort drvport, int lock_pdl)
if (lock_pdl && prt->port_data_lock)
driver_pdl_lock(prt->port_data_lock);
-#if ERTS_ENABLE_LOCK_CHECK
+#ifdef ERTS_ENABLE_LOCK_CHECK
if (!ERTS_IS_CRASH_DUMPING) {
if (erts_lc_is_emu_thr()) {
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index dd5943b5cf..4fb0f9e975 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -154,6 +154,7 @@ int ERTS_WRITE_UNLIKELY(erts_eager_check_io) = 1;
int ERTS_WRITE_UNLIKELY(erts_sched_compact_load);
int ERTS_WRITE_UNLIKELY(erts_sched_balance_util) = 0;
Uint ERTS_WRITE_UNLIKELY(erts_no_schedulers);
+Uint ERTS_WRITE_UNLIKELY(erts_no_total_schedulers);
Uint ERTS_WRITE_UNLIKELY(erts_no_dirty_cpu_schedulers) = 0;
Uint ERTS_WRITE_UNLIKELY(erts_no_dirty_io_schedulers) = 0;
@@ -556,8 +557,8 @@ do { \
*/
static void exec_misc_ops(ErtsRunQueue *);
-static void print_function_from_pc(int to, void *to_arg, BeamInstr* x);
-static int stack_element_dump(int to, void *to_arg, Eterm* sp, int yreg);
+static void print_function_from_pc(fmtfn_t to, void *to_arg, BeamInstr* x);
+static int stack_element_dump(fmtfn_t to, void *to_arg, Eterm* sp, int yreg);
static void aux_work_timeout(void *unused);
static void aux_work_timeout_early_init(int no_schedulers);
@@ -5907,9 +5908,12 @@ erts_init_scheduling(int no_schedulers, int no_schedulers_online
n = (int) no_schedulers;
erts_no_schedulers = n;
+ erts_no_total_schedulers = n;
#ifdef ERTS_DIRTY_SCHEDULERS
erts_no_dirty_cpu_schedulers = no_dirty_cpu_schedulers;
+ erts_no_total_schedulers += no_dirty_cpu_schedulers;
erts_no_dirty_io_schedulers = no_dirty_io_schedulers;
+ erts_no_total_schedulers += no_dirty_io_schedulers;
#endif
/* Create and initialize scheduler sleep info */
@@ -6270,7 +6274,11 @@ check_dirty_enqueue_in_prio_queue(Process *c_p,
return -1*queue;
}
- *newp |= ERTS_PSFLG_IN_RUNQ;
+ /*
+ * Enqueue using process struct.
+ */
+ *newp &= ~ERTS_PSFLGS_PRQ_PRIO_MASK;
+ *newp |= ERTS_PSFLG_IN_RUNQ | (aprio << ERTS_PSFLGS_PRQ_PRIO_OFFSET);
return queue;
}
@@ -6682,15 +6690,8 @@ schedule_process_sys_task(Process *p, erts_aint32_t prio, ErtsProcSysTask *st,
erts_aint32_t fail_state, state, a, n, enq_prio;
int enqueue; /* < 0 -> use proxy */
unsigned int prof_runnable_procs;
- int strict_fail_state;
fail_state = *fail_state_p;
- /*
- * If fail state something other than just exiting process,
- * ensure that the task wont be scheduled when the
- * receiver is in the failure state.
- */
- strict_fail_state = fail_state != ERTS_PSFLG_EXITING;
res = 1; /* prepare for success */
st->next = st->prev = st; /* Prep for empty prio queue */
@@ -6772,7 +6773,7 @@ schedule_process_sys_task(Process *p, erts_aint32_t prio, ErtsProcSysTask *st,
/* Status lock prevents out of order "runnable proc" trace msgs */
ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_STATUS & erts_proc_lc_my_proc_locks(p));
- if (!prof_runnable_procs && !strict_fail_state) {
+ if (!prof_runnable_procs) {
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS);
locked = 0;
}
@@ -6783,11 +6784,6 @@ schedule_process_sys_task(Process *p, erts_aint32_t prio, ErtsProcSysTask *st,
erts_aint32_t e;
n = e = a;
- if (strict_fail_state && (a & fail_state)) {
- *fail_state_p = (a & fail_state);
- goto cleanup;
- }
-
if (a & ERTS_PSFLG_FREE)
goto cleanup; /* We don't want to schedule free processes... */
@@ -12404,6 +12400,8 @@ send_exit_signal(Process *c_p, /* current process if and only
else if (!(state & (ERTS_PSFLG_RUNNING|ERTS_PSFLG_RUNNING_SYS))) {
/* Process not running ... */
ErtsProcLocks need_locks = ~(*rp_locks) & ERTS_PROC_LOCKS_ALL;
+ ErlHeapFragment *bp = NULL;
+ Eterm rsn_cpy;
if (need_locks
&& erts_smp_proc_trylock(rp, need_locks) == EBUSY) {
/* ... but we havn't got all locks on it ... */
@@ -12416,12 +12414,32 @@ send_exit_signal(Process *c_p, /* current process if and only
}
/* ...and we have all locks on it... */
*rp_locks = ERTS_PROC_LOCKS_ALL;
- set_proc_exiting(rp,
- state,
- (is_immed(rsn)
- ? rsn
- : copy_object(rsn, rp)),
- NULL);
+
+ state = erts_smp_atomic32_read_nob(&rp->state);
+
+ if (is_immed(rsn))
+ rsn_cpy = rsn;
+ else {
+ Eterm *hp;
+ ErlOffHeap *ohp;
+ Uint rsn_sz = size_object(rsn);
+#ifdef ERTS_DIRTY_SCHEDULERS
+ if (state & (ERTS_PSFLG_DIRTY_RUNNING
+ | ERTS_PSFLG_DIRTY_RUNNING_SYS)) {
+ bp = new_message_buffer(rsn_sz);
+ ohp = &bp->off_heap;
+ hp = &bp->mem[0];
+ }
+ else
+#endif
+ {
+ hp = HAlloc(rp, rsn_sz);
+ ohp = &rp->off_heap;
+ }
+ rsn_cpy = copy_struct(rsn, rsn_sz, &hp, ohp);
+ }
+
+ set_proc_exiting(rp, state, rsn_cpy, bp);
}
else { /* Process running... */
@@ -13174,7 +13192,7 @@ erts_continue_exit_process(Process *p)
*/
void
-erts_stack_dump(int to, void *to_arg, Process *p)
+erts_stack_dump(fmtfn_t to, void *to_arg, Process *p)
{
Eterm* sp;
int yreg = -1;
@@ -13189,7 +13207,7 @@ erts_stack_dump(int to, void *to_arg, Process *p)
}
void
-erts_program_counter_info(int to, void *to_arg, Process *p)
+erts_program_counter_info(fmtfn_t to, void *to_arg, Process *p)
{
erts_aint32_t state;
int i;
@@ -13219,7 +13237,7 @@ erts_program_counter_info(int to, void *to_arg, Process *p)
}
static void
-print_function_from_pc(int to, void *to_arg, BeamInstr* x)
+print_function_from_pc(fmtfn_t to, void *to_arg, BeamInstr* x)
{
ErtsCodeMFA *cmfa = find_function_from_pc(x);
if (cmfa == NULL) {
@@ -13242,7 +13260,7 @@ print_function_from_pc(int to, void *to_arg, BeamInstr* x)
}
static int
-stack_element_dump(int to, void *to_arg, Eterm* sp, int yreg)
+stack_element_dump(fmtfn_t to, void *to_arg, Eterm* sp, int yreg)
{
Eterm x = *sp;
@@ -13274,7 +13292,7 @@ stack_element_dump(int to, void *to_arg, Eterm* sp, int yreg)
* Print scheduler information
*/
void
-erts_print_scheduler_info(int to, void *to_arg, ErtsSchedulerData *esdp) {
+erts_print_scheduler_info(fmtfn_t to, void *to_arg, ErtsSchedulerData *esdp) {
int i;
erts_aint32_t flg;
Process *p;
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index b266d32e76..1c4b9f149d 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -21,6 +21,8 @@
#ifndef __PROCESS_H__
#define __PROCESS_H__
+#include "sys.h"
+
#undef ERTS_INCLUDE_SCHEDULER_INTERNALS
#if (defined(ERL_PROCESS_C__) \
|| defined(ERL_PORT_TASK_C__) \
@@ -37,8 +39,6 @@
typedef struct process Process;
-#include "sys.h"
-
#define ERTS_PROCESS_LOCK_ONLY_PROC_LOCK_TYPE__
#include "erl_process_lock.h" /* Only pull out important types... */
#undef ERTS_PROCESS_LOCK_ONLY_PROC_LOCK_TYPE__
@@ -107,6 +107,7 @@ extern int erts_eager_check_io;
extern int erts_sched_compact_load;
extern int erts_sched_balance_util;
extern Uint erts_no_schedulers;
+extern Uint erts_no_total_schedulers;
#ifdef ERTS_DIRTY_SCHEDULERS
extern Uint erts_no_dirty_cpu_schedulers;
extern Uint erts_no_dirty_io_schedulers;
@@ -1583,6 +1584,7 @@ Uint64 erts_step_proc_interval(void);
int erts_setup_nif_gc(Process* proc, Eterm** objv, int* nobj); /* see erl_nif.c */
void erts_destroy_nif_export(void *); /* see erl_nif.c */
+int erts_check_nif_export_in_area(Process *p, char *start, Uint size);
ErtsProcList *erts_proclist_create(Process *);
ErtsProcList *erts_proclist_copy(ErtsProcList *);
@@ -1834,12 +1836,12 @@ void erts_cleanup_empty_process(Process* p);
#ifdef DEBUG
void erts_debug_verify_clean_empty_process(Process* p);
#endif
-void erts_stack_dump(int to, void *to_arg, Process *);
-void erts_limited_stack_trace(int to, void *to_arg, Process *);
-void erts_program_counter_info(int to, void *to_arg, Process *);
-void erts_print_scheduler_info(int to, void *to_arg, ErtsSchedulerData *esdp);
-void erts_dump_extended_process_state(int to, void *to_arg, erts_aint32_t psflg);
-void erts_dump_process_state(int to, void *to_arg, erts_aint32_t psflg);
+void erts_stack_dump(fmtfn_t to, void *to_arg, Process *);
+void erts_limited_stack_trace(fmtfn_t to, void *to_arg, Process *);
+void erts_program_counter_info(fmtfn_t to, void *to_arg, Process *);
+void erts_print_scheduler_info(fmtfn_t to, void *to_arg, ErtsSchedulerData *esdp);
+void erts_dump_extended_process_state(fmtfn_t to, void *to_arg, erts_aint32_t psflg);
+void erts_dump_process_state(fmtfn_t to, void *to_arg, erts_aint32_t psflg);
Eterm erts_get_process_priority(Process *p);
Eterm erts_set_process_priority(Process *p, Eterm prio);
@@ -1875,7 +1877,7 @@ void erts_handle_pending_exit(Process *, ErtsProcLocks);
#define ERTS_PROC_PENDING_EXIT(P) 0
#endif
-void erts_deep_process_dump(int, void *);
+void erts_deep_process_dump(fmtfn_t, void *);
Eterm erts_get_reader_groups_map(Process *c_p);
Eterm erts_debug_reader_groups_map(Process *c_p, int groups);
diff --git a/erts/emulator/beam/erl_process_dict.c b/erts/emulator/beam/erl_process_dict.c
index d443fff22c..8311fde025 100644
--- a/erts/emulator/beam/erl_process_dict.c
+++ b/erts/emulator/beam/erl_process_dict.c
@@ -156,7 +156,7 @@ erts_pd_set_initial_size(int size)
* Called from break handler
*/
void
-erts_dictionary_dump(int to, void *to_arg, ProcDict *pd)
+erts_dictionary_dump(fmtfn_t to, void *to_arg, ProcDict *pd)
{
unsigned int i;
#ifdef DEBUG
@@ -196,8 +196,8 @@ erts_dictionary_dump(int to, void *to_arg, ProcDict *pd)
}
void
-erts_deep_dictionary_dump(int to, void *to_arg,
- ProcDict* pd, void (*cb)(int, void *, Eterm))
+erts_deep_dictionary_dump(fmtfn_t to, void *to_arg,
+ ProcDict* pd, void (*cb)(fmtfn_t, void *, Eterm))
{
unsigned int i;
Eterm t;
diff --git a/erts/emulator/beam/erl_process_dict.h b/erts/emulator/beam/erl_process_dict.h
index db5e1c7442..ab58f3c239 100644
--- a/erts/emulator/beam/erl_process_dict.h
+++ b/erts/emulator/beam/erl_process_dict.h
@@ -37,9 +37,9 @@ typedef struct proc_dict {
int erts_pd_set_initial_size(int size);
Uint erts_dicts_mem_size(struct process *p);
void erts_erase_dicts(struct process *p);
-void erts_dictionary_dump(int to, void *to_arg, ProcDict *pd);
-void erts_deep_dictionary_dump(int to, void *to_arg,
- ProcDict* pd, void (*cb)(int, void *, Eterm obj));
+void erts_dictionary_dump(fmtfn_t to, void *to_arg, ProcDict *pd);
+void erts_deep_dictionary_dump(fmtfn_t to, void *to_arg,
+ ProcDict* pd, void (*cb)(fmtfn_t, void *, Eterm obj));
Eterm erts_dictionary_copy(struct process *p, ProcDict *pd);
Eterm erts_pd_hash_get(struct process *p, Eterm id);
diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c
index e7a311b430..e534c33637 100644
--- a/erts/emulator/beam/erl_process_dump.c
+++ b/erts/emulator/beam/erl_process_dump.c
@@ -40,17 +40,17 @@
#define OUR_NIL _make_header(0,_TAG_HEADER_FLOAT)
-static void dump_process_info(int to, void *to_arg, Process *p);
-static void dump_element(int to, void *to_arg, Eterm x);
-static void dump_dist_ext(int to, void *to_arg, ErtsDistExternal *edep);
-static void dump_element_nl(int to, void *to_arg, Eterm x);
-static int stack_element_dump(int to, void *to_arg, Eterm* sp,
+static void dump_process_info(fmtfn_t to, void *to_arg, Process *p);
+static void dump_element(fmtfn_t to, void *to_arg, Eterm x);
+static void dump_dist_ext(fmtfn_t to, void *to_arg, ErtsDistExternal *edep);
+static void dump_element_nl(fmtfn_t to, void *to_arg, Eterm x);
+static int stack_element_dump(fmtfn_t to, void *to_arg, Eterm* sp,
int yreg);
-static void stack_trace_dump(int to, void *to_arg, Eterm* sp);
-static void print_function_from_pc(int to, void *to_arg, BeamInstr* x);
-static void heap_dump(int to, void *to_arg, Eterm x);
-static void dump_binaries(int to, void *to_arg, Binary* root);
-static void dump_externally(int to, void *to_arg, Eterm term);
+static void stack_trace_dump(fmtfn_t to, void *to_arg, Eterm* sp);
+static void print_function_from_pc(fmtfn_t to, void *to_arg, BeamInstr* x);
+static void heap_dump(fmtfn_t to, void *to_arg, Eterm x);
+static void dump_binaries(fmtfn_t to, void *to_arg, Binary* root);
+static void dump_externally(fmtfn_t to, void *to_arg, Eterm term);
static Binary* all_binaries;
@@ -60,7 +60,7 @@ extern BeamInstr beam_continue_exit[];
void
-erts_deep_process_dump(int to, void *to_arg)
+erts_deep_process_dump(fmtfn_t to, void *to_arg)
{
int i, max = erts_ptab_max(&erts_proc);
@@ -117,7 +117,7 @@ Uint erts_process_memory(Process *p, int incl_msg_inq) {
}
static void
-dump_process_info(int to, void *to_arg, Process *p)
+dump_process_info(fmtfn_t to, void *to_arg, Process *p)
{
Eterm* sp;
ErtsMessage* mp;
@@ -176,7 +176,7 @@ dump_process_info(int to, void *to_arg, Process *p)
}
static void
-dump_dist_ext(int to, void *to_arg, ErtsDistExternal *edep)
+dump_dist_ext(fmtfn_t to, void *to_arg, ErtsDistExternal *edep)
{
if (!edep)
erts_print(to, to_arg, "D0:E0:");
@@ -210,7 +210,7 @@ dump_dist_ext(int to, void *to_arg, ErtsDistExternal *edep)
}
static void
-dump_element(int to, void *to_arg, Eterm x)
+dump_element(fmtfn_t to, void *to_arg, Eterm x)
{
if (is_list(x)) {
erts_print(to, to_arg, "H" PTR_FMT, list_val(x));
@@ -240,14 +240,14 @@ dump_element(int to, void *to_arg, Eterm x)
}
static void
-dump_element_nl(int to, void *to_arg, Eterm x)
+dump_element_nl(fmtfn_t to, void *to_arg, Eterm x)
{
dump_element(to, to_arg, x);
erts_putc(to, to_arg, '\n');
}
static void
-stack_trace_dump(int to, void *to_arg, Eterm *sp) {
+stack_trace_dump(fmtfn_t to, void *to_arg, Eterm *sp) {
Eterm x = *sp;
if (is_CP(x)) {
erts_print(to, to_arg, "%p:", sp);
@@ -258,7 +258,7 @@ stack_trace_dump(int to, void *to_arg, Eterm *sp) {
}
void
-erts_limited_stack_trace(int to, void *to_arg, Process *p)
+erts_limited_stack_trace(fmtfn_t to, void *to_arg, Process *p)
{
Eterm* sp;
@@ -304,7 +304,7 @@ erts_limited_stack_trace(int to, void *to_arg, Process *p)
}
static int
-stack_element_dump(int to, void *to_arg, Eterm* sp, int yreg)
+stack_element_dump(fmtfn_t to, void *to_arg, Eterm* sp, int yreg)
{
Eterm x = *sp;
@@ -332,7 +332,7 @@ stack_element_dump(int to, void *to_arg, Eterm* sp, int yreg)
}
static void
-print_function_from_pc(int to, void *to_arg, BeamInstr* x)
+print_function_from_pc(fmtfn_t to, void *to_arg, BeamInstr* x)
{
ErtsCodeMFA* cmfa = find_function_from_pc(x);
if (cmfa == NULL) {
@@ -353,7 +353,7 @@ print_function_from_pc(int to, void *to_arg, BeamInstr* x)
}
static void
-heap_dump(int to, void *to_arg, Eterm x)
+heap_dump(fmtfn_t to, void *to_arg, Eterm x)
{
DeclareTmpHeapNoproc(last,1);
Eterm* next = last;
@@ -513,7 +513,7 @@ heap_dump(int to, void *to_arg, Eterm x)
}
static void
-dump_binaries(int to, void *to_arg, Binary* current)
+dump_binaries(fmtfn_t to, void *to_arg, Binary* current)
{
while (current) {
long i;
@@ -531,7 +531,7 @@ dump_binaries(int to, void *to_arg, Binary* current)
}
static void
-dump_externally(int to, void *to_arg, Eterm term)
+dump_externally(fmtfn_t to, void *to_arg, Eterm term)
{
byte sbuf[1024]; /* encode and hope for the best ... */
byte* s;
@@ -574,7 +574,7 @@ dump_externally(int to, void *to_arg, Eterm term)
}
}
-void erts_dump_process_state(int to, void *to_arg, erts_aint32_t psflg)
+void erts_dump_process_state(fmtfn_t to, void *to_arg, erts_aint32_t psflg)
{
char *s;
switch (erts_process_state2status(psflg)) {
@@ -592,7 +592,7 @@ void erts_dump_process_state(int to, void *to_arg, erts_aint32_t psflg)
}
void
-erts_dump_extended_process_state(int to, void *to_arg, erts_aint32_t psflg) {
+erts_dump_extended_process_state(fmtfn_t to, void *to_arg, erts_aint32_t psflg) {
int i;
diff --git a/erts/emulator/beam/export.c b/erts/emulator/beam/export.c
index 94568e79a9..f397ab6b00 100644
--- a/erts/emulator/beam/export.c
+++ b/erts/emulator/beam/export.c
@@ -83,7 +83,7 @@ static struct export_blob* entry_to_blob(struct export_entry* ee)
}
void
-export_info(int to, void *to_arg)
+export_info(fmtfn_t to, void *to_arg)
{
#ifdef ERTS_SMP
int lock = !ERTS_IS_CRASH_DUMPING;
diff --git a/erts/emulator/beam/export.h b/erts/emulator/beam/export.h
index 198b90c839..7c812b306c 100644
--- a/erts/emulator/beam/export.h
+++ b/erts/emulator/beam/export.h
@@ -51,7 +51,7 @@ typedef struct export
void init_export_table(void);
-void export_info(int, void *);
+void export_info(fmtfn_t, void *);
ERTS_GLB_INLINE Export* erts_active_export_entry(Eterm m, Eterm f, unsigned a);
Export* erts_export_put(Eterm mod, Eterm func, unsigned int arity);
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 98df8a0726..a49b242d7c 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -3748,7 +3748,7 @@ dec_term_atom_common:
funp->arity = arity;
#ifdef HIPE
if (funp->fe->native_address == NULL) {
- hipe_set_closure_stub(funp->fe, num_free);
+ hipe_set_closure_stub(funp->fe);
}
#endif
hp = factory->hp;
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 537aaf3177..2b2f3c5cdc 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -68,7 +68,7 @@ extern void erts_pre_dirty_nif(ErtsSchedulerData *,
extern void erts_post_dirty_nif(struct enif_environment_t* env);
#endif
extern Eterm erts_nif_taints(Process* p);
-extern void erts_print_nif_taints(int to, void* to_arg);
+extern void erts_print_nif_taints(fmtfn_t to, void* to_arg);
void erts_unload_nif(struct erl_module_nif* nif);
extern void erl_nif_init(void);
extern int erts_nif_get_funcs(struct erl_module_nif*,
@@ -773,8 +773,8 @@ do { \
typedef struct ErtsPStack_ {
byte* pstart;
- byte* psp;
- byte* pend;
+ int offs; /* "stack pointer" as byte offset from pstart */
+ int size; /* allocated size in bytes */
ErtsAlcType_t alloc_type;
}ErtsPStack;
@@ -785,8 +785,8 @@ void erl_grow_pstack(ErtsPStack* s, void* default_pstack, unsigned need_bytes);
#define PSTACK_DECLARE(s, DEF_PSTACK_SIZE) \
PSTACK_TYPE PSTK_DEF_STACK(s)[DEF_PSTACK_SIZE]; \
ErtsPStack s = { (byte*)PSTK_DEF_STACK(s), /* pstart */ \
- (byte*)(PSTK_DEF_STACK(s) - 1), /* psp */ \
- (byte*)(PSTK_DEF_STACK(s) + (DEF_PSTACK_SIZE)), /* pend */\
+ -(int)sizeof(PSTACK_TYPE), /* offs */ \
+ DEF_PSTACK_SIZE*sizeof(PSTACK_TYPE), /* size */ \
ERTS_ALC_T_ESTACK /* alloc_type */ \
}
@@ -806,19 +806,21 @@ do { \
} \
} while(0)
-#define PSTACK_IS_EMPTY(s) (s.psp < s.pstart)
+#define PSTACK_IS_EMPTY(s) (s.offs < 0)
-#define PSTACK_COUNT(s) (((PSTACK_TYPE*)s.psp + 1) - (PSTACK_TYPE*)s.pstart)
+#define PSTACK_COUNT(s) ((s.offs + sizeof(PSTACK_TYPE)) / sizeof(PSTACK_TYPE))
-#define PSTACK_TOP(s) (ASSERT(!PSTACK_IS_EMPTY(s)), (PSTACK_TYPE*)(s.psp))
+#define PSTACK_TOP(s) (ASSERT(!PSTACK_IS_EMPTY(s)), \
+ (PSTACK_TYPE*)(s.pstart + s.offs))
-#define PSTACK_PUSH(s) \
- (s.psp += sizeof(PSTACK_TYPE), \
- ((s.psp == s.pend) ? erl_grow_pstack(&s, PSTK_DEF_STACK(s), \
- sizeof(PSTACK_TYPE)) : (void)0), \
- ((PSTACK_TYPE*) s.psp))
+#define PSTACK_PUSH(s) \
+ (s.offs += sizeof(PSTACK_TYPE), \
+ ((s.offs == s.size) ? erl_grow_pstack(&s, PSTK_DEF_STACK(s), \
+ sizeof(PSTACK_TYPE)) : (void)0), \
+ ((PSTACK_TYPE*) (s.pstart + s.offs)))
-#define PSTACK_POP(s) ((PSTACK_TYPE*) (s.psp -= sizeof(PSTACK_TYPE)))
+#define PSTACK_POP(s) ((s.offs -= sizeof(PSTACK_TYPE)), \
+ (PSTACK_TYPE*)(s.pstart + s.offs))
/*
* Do not free the stack after this, it may have pointers into what
@@ -831,8 +833,8 @@ do {\
(dst)->pstart = erts_alloc(s.alloc_type,\
sizeof(PSTK_DEF_STACK(s)));\
sys_memcpy((dst)->pstart, s.pstart, _pbytes);\
- (dst)->psp = (dst)->pstart + _pbytes - sizeof(PSTACK_TYPE);\
- (dst)->pend = (dst)->pstart + sizeof(PSTK_DEF_STACK(s));\
+ (dst)->offs = s.offs;\
+ (dst)->size = s.size;\
(dst)->alloc_type = s.alloc_type;\
} else\
*(dst) = s;\
@@ -847,8 +849,8 @@ do { \
ASSERT(s.pstart == (byte*)PSTK_DEF_STACK(s)); \
s = *(src); /* struct copy */ \
(src)->pstart = NULL; \
- ASSERT(s.psp >= (s.pstart - sizeof(PSTACK_TYPE))); \
- ASSERT(s.psp < s.pend); \
+ ASSERT(s.offs >= -(int)sizeof(PSTACK_TYPE)); \
+ ASSERT(s.offs < s.size); \
} while (0)
#define PSTACK_DESTROY_SAVED(pstack)\
@@ -1063,16 +1065,17 @@ void erts_lookup_function_info(FunctionInfo* fi, BeamInstr* pc, int full_info);
void init_break_handler(void);
void erts_set_ignore_break(void);
void erts_replace_intr(void);
-void process_info(int, void *);
-void print_process_info(int, void *, Process*);
-void info(int, void *);
-void loaded(int, void *);
+void process_info(fmtfn_t, void *);
+void print_process_info(fmtfn_t, void *, Process*);
+void info(fmtfn_t, void *);
+void loaded(fmtfn_t, void *);
/* erl_arith.c */
double erts_get_positive_zero_float(void);
/* config.c */
+__decl_noreturn void __noreturn erts_exit_epilogue(void);
__decl_noreturn void __noreturn erts_exit(int n, char*, ...);
__decl_noreturn void __noreturn erts_flush_async_exit(int n, char*, ...);
void erl_error(char*, va_list);
@@ -1179,7 +1182,7 @@ extern void erts_delete_nodes_monitors(Process *, ErtsProcLocks);
extern Eterm erts_monitor_nodes(Process *, Eterm, Eterm);
extern Eterm erts_processes_monitoring_nodes(Process *);
extern int erts_do_net_exits(DistEntry*, Eterm);
-extern int distribution_info(int, void *);
+extern int distribution_info(fmtfn_t, void *);
extern int is_node_name_atom(Eterm a);
extern int erts_net_message(Port *, DistEntry *,
@@ -1368,7 +1371,7 @@ int erts_utf8_to_latin1(byte* dest, const byte* source, int slen);
#define ERTS_UTF8_ANALYZE_MORE 3
#define ERTS_UTF8_OK_MAX_CHARS 4
-void bin_write(int, void*, byte*, size_t);
+void bin_write(fmtfn_t, void*, byte*, size_t);
Sint intlist_to_buf(Eterm, char*, Sint); /* most callers pass plain char*'s */
struct Sint_buf {
@@ -1472,7 +1475,7 @@ Eterm erts_gc_bnot(Process* p, Eterm* reg, Uint live);
Uint erts_current_reductions(Process* current, Process *p);
-int erts_print_system_version(int to, void *arg, Process *c_p);
+int erts_print_system_version(fmtfn_t to, void *arg, Process *c_p);
int erts_hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg);
diff --git a/erts/emulator/beam/hash.c b/erts/emulator/beam/hash.c
index cd038d100b..8548e30e8b 100644
--- a/erts/emulator/beam/hash.c
+++ b/erts/emulator/beam/hash.c
@@ -95,7 +95,7 @@ void hash_get_info(HashInfo *hi, Hash *h)
**
*/
-void hash_info(int to, void *arg, Hash* h)
+void hash_info(fmtfn_t to, void *arg, Hash* h)
{
HashInfo hi;
diff --git a/erts/emulator/beam/hash.h b/erts/emulator/beam/hash.h
index 4e769c0119..d319aaca83 100644
--- a/erts/emulator/beam/hash.h
+++ b/erts/emulator/beam/hash.h
@@ -37,7 +37,7 @@ typedef void (*HFREE_FUN)(void*);
/* Meta functions */
typedef void* (*HMALLOC_FUN)(int,size_t);
typedef void (*HMFREE_FUN)(int,void*);
-typedef int (*HMPRINT_FUN)(int,void*,char*, ...);
+typedef int (*HMPRINT_FUN)(fmtfn_t,void*,char*, ...);
/*
** This bucket must be placed in top of
@@ -89,7 +89,7 @@ Hash* hash_init(int, Hash*, char*, int, HashFunctions);
void hash_delete(Hash*);
void hash_get_info(HashInfo*, Hash*);
-void hash_info(int, void *, Hash*);
+void hash_info(fmtfn_t, void *, Hash*);
int hash_table_sz(Hash *);
void* hash_get(Hash*, void*);
diff --git a/erts/emulator/beam/index.c b/erts/emulator/beam/index.c
index 26d6c04ea0..c86a2122f6 100644
--- a/erts/emulator/beam/index.c
+++ b/erts/emulator/beam/index.c
@@ -27,7 +27,7 @@
#include "global.h"
#include "index.h"
-void index_info(int to, void *arg, IndexTable *t)
+void index_info(fmtfn_t to, void *arg, IndexTable *t)
{
hash_info(to, arg, &t->htable);
erts_print(to, arg, "=index_table:%s\n", t->htable.name);
diff --git a/erts/emulator/beam/index.h b/erts/emulator/beam/index.h
index 0a109d8699..b2e3c0eab5 100644
--- a/erts/emulator/beam/index.h
+++ b/erts/emulator/beam/index.h
@@ -51,7 +51,7 @@ typedef struct index_table
#define INDEX_PAGE_MASK ((1 << INDEX_PAGE_SHIFT)-1)
IndexTable *erts_index_init(ErtsAlcType_t,IndexTable*,char*,int,int,HashFunctions);
-void index_info(int, void *, IndexTable*);
+void index_info(fmtfn_t, void *, IndexTable*);
int index_table_sz(IndexTable *);
int index_get(IndexTable*, void*);
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 77dbe92241..4f131c74de 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -5480,7 +5480,7 @@ erts_request_io_bytes(Process *c_p)
typedef struct {
- int to;
+ fmtfn_t to;
void *arg;
} prt_one_lnk_data;
@@ -5497,7 +5497,7 @@ static void prt_one_lnk(ErtsLink *lnk, void *vprtd)
}
void
-print_port_info(Port *p, int to, void *arg)
+print_port_info(Port *p, fmtfn_t to, void *arg)
{
erts_aint32_t state = erts_atomic32_read_nob(&p->state);
diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c
index 705dd1d43f..8ab6c713d6 100644
--- a/erts/emulator/beam/module.c
+++ b/erts/emulator/beam/module.c
@@ -51,7 +51,7 @@ static erts_smp_atomic_t tot_module_bytes;
#include "erl_smp.h"
-void module_info(int to, void *to_arg)
+void module_info(fmtfn_t to, void *to_arg)
{
index_info(to, to_arg, &module_tables[erts_active_code_ix()]);
}
diff --git a/erts/emulator/beam/module.h b/erts/emulator/beam/module.h
index 8f44e11f3d..9d258d5dbf 100644
--- a/erts/emulator/beam/module.h
+++ b/erts/emulator/beam/module.h
@@ -56,7 +56,7 @@ Module* erts_put_module(Eterm mod);
void init_module_table(void);
void module_start_staging(void);
void module_end_staging(int commit);
-void module_info(int, void *);
+void module_info(fmtfn_t, void *);
Module *module_code(int, ErtsCodeIndex);
int module_code_size(ErtsCodeIndex);
diff --git a/erts/emulator/beam/register.c b/erts/emulator/beam/register.c
index ac7096745e..acda51c9fc 100644
--- a/erts/emulator/beam/register.c
+++ b/erts/emulator/beam/register.c
@@ -102,7 +102,7 @@ is_proc_alive(Process *p)
return !ERTS_PROC_IS_EXITING(p);
}
-void register_info(int to, void *to_arg)
+void register_info(fmtfn_t to, void *to_arg)
{
int lock = !ERTS_IS_CRASH_DUMPING;
if (lock)
diff --git a/erts/emulator/beam/register.h b/erts/emulator/beam/register.h
index d839f55d6b..27a314ca78 100644
--- a/erts/emulator/beam/register.h
+++ b/erts/emulator/beam/register.h
@@ -44,7 +44,7 @@ typedef struct reg_proc
int process_reg_size(void);
int process_reg_sz(void);
void init_register_table(void);
-void register_info(int, void *);
+void register_info(fmtfn_t, void *);
int erts_register_name(Process *, Eterm, Eterm);
Eterm erts_whereis_name_to_id(Process *, Eterm);
void erts_whereis_name(Process *, ErtsProcLocks,
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 16e6c33367..4b3ac594a0 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -384,6 +384,7 @@ typedef long Sint64;
# ifdef LONG_MIN
# define ERTS_SINT64_MIN LONG_MIN
# endif
+# define ErtsStrToSint64 strtol
# elif SIZEOF_LONG_LONG == 8
# define HAVE_INT64 1
typedef unsigned long long Uint64;
@@ -397,6 +398,7 @@ typedef long long Sint64;
# ifdef LLONG_MIN
# define ERTS_SINT64_MIN LLONG_MIN
# endif
+# define ErtsStrToSint64 strtoll
# else
# error "No 64-bit integer type found"
# endif
@@ -616,22 +618,21 @@ Uint erts_sys_misc_mem_sz(void);
#include "erl_printf.h"
/* Io constants to erts_print and erts_putc */
-#define ERTS_PRINT_STDERR (2)
-#define ERTS_PRINT_STDOUT (1)
-#define ERTS_PRINT_FILE (-1)
-#define ERTS_PRINT_SBUF (-2)
-#define ERTS_PRINT_SNBUF (-3)
-#define ERTS_PRINT_DSBUF (-4)
-
-#define ERTS_PRINT_MIN ERTS_PRINT_DSBUF
+#define ERTS_PRINT_STDERR ((fmtfn_t)0)
+#define ERTS_PRINT_STDOUT ((fmtfn_t)1)
+#define ERTS_PRINT_FILE ((fmtfn_t)2)
+#define ERTS_PRINT_SBUF ((fmtfn_t)3)
+#define ERTS_PRINT_SNBUF ((fmtfn_t)4)
+#define ERTS_PRINT_DSBUF ((fmtfn_t)5)
+#define ERTS_PRINT_FD ((fmtfn_t)6)
typedef struct {
char *buf;
size_t size;
} erts_print_sn_buf;
-int erts_print(int to, void *arg, char *format, ...); /* in utils.c */
-int erts_putc(int to, void *arg, char); /* in utils.c */
+int erts_print(fmtfn_t to, void *arg, char *format, ...); /* in utils.c */
+int erts_putc(fmtfn_t to, void *arg, char); /* in utils.c */
/* logger stuff is declared here instead of in global.h, so sys files
won't have to include global.h */
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index cd7131f5df..ec502d5a78 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -204,9 +204,8 @@ erl_grow_wstack(ErtsWStack* s, Uint need)
void
erl_grow_pstack(ErtsPStack* s, void* default_pstack, unsigned need_bytes)
{
- Uint old_size = s->pend - s->pstart;
+ Uint old_size = s->size;
Uint new_size;
- Uint sp_offs = s->psp - s->pstart;
if (need_bytes < old_size)
new_size = 2 * old_size;
@@ -220,8 +219,7 @@ erl_grow_pstack(ErtsPStack* s, void* default_pstack, unsigned need_bytes)
sys_memcpy(new_ptr, s->pstart, old_size);
s->pstart = new_ptr;
}
- s->pend = s->pstart + new_size;
- s->psp = s->pstart + sp_offs;
+ s->size = new_size;
}
/*
@@ -348,40 +346,41 @@ int erts_fit_in_bits_uint(Uint value)
}
int
-erts_print(int to, void *arg, char *format, ...)
+erts_print(fmtfn_t to, void *arg, char *format, ...)
{
int res;
va_list arg_list;
va_start(arg_list, format);
- if (to < ERTS_PRINT_MIN)
- res = -EINVAL;
- else {
- switch (to) {
- case ERTS_PRINT_STDOUT:
+ {
+ switch ((UWord)to) {
+ case (UWord)ERTS_PRINT_STDOUT:
res = erts_vprintf(format, arg_list);
break;
- case ERTS_PRINT_STDERR:
+ case (UWord)ERTS_PRINT_STDERR:
res = erts_vfprintf(stderr, format, arg_list);
break;
- case ERTS_PRINT_FILE:
+ case (UWord)ERTS_PRINT_FILE:
res = erts_vfprintf((FILE *) arg, format, arg_list);
break;
- case ERTS_PRINT_SBUF:
+ case (UWord)ERTS_PRINT_SBUF:
res = erts_vsprintf((char *) arg, format, arg_list);
break;
- case ERTS_PRINT_SNBUF:
+ case (UWord)ERTS_PRINT_SNBUF:
res = erts_vsnprintf(((erts_print_sn_buf *) arg)->buf,
((erts_print_sn_buf *) arg)->size,
format,
arg_list);
break;
- case ERTS_PRINT_DSBUF:
+ case (UWord)ERTS_PRINT_DSBUF:
res = erts_vdsprintf((erts_dsprintf_buf_t *) arg, format, arg_list);
break;
- default:
- res = erts_vfdprintf((int) to, format, arg_list);
+ case (UWord)ERTS_PRINT_FD:
+ res = erts_vfdprintf((int)(SWord) arg, format, arg_list);
break;
+ default:
+ res = erts_vcbprintf(to, arg, format, arg_list);
+ break;
}
}
@@ -390,7 +389,7 @@ erts_print(int to, void *arg, char *format, ...)
}
int
-erts_putc(int to, void *arg, char c)
+erts_putc(fmtfn_t to, void *arg, char c)
{
return erts_print(to, arg, "%c", c);
}
@@ -3878,7 +3877,7 @@ store_external_or_ref_in_proc_(Process *proc, Eterm ns)
return store_external_or_ref_(&hp, &MSO(proc), ns);
}
-void bin_write(int to, void *to_arg, byte* buf, size_t sz)
+void bin_write(fmtfn_t to, void *to_arg, byte* buf, size_t sz)
{
size_t i;
diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c
index ed95045292..0706f8d2c9 100644
--- a/erts/emulator/hipe/hipe_mode_switch.c
+++ b/erts/emulator/hipe/hipe_mode_switch.c
@@ -718,12 +718,9 @@ void hipe_empty_nstack(Process *p)
p->hipe.nstend = NULL;
}
-void hipe_set_closure_stub(ErlFunEntry *fe, unsigned num_free)
+void hipe_set_closure_stub(ErlFunEntry *fe)
{
- unsigned arity;
-
- arity = fe->arity;
- fe->native_address = (Eterm*) hipe_closure_stub_address(arity);
+ fe->native_address = (Eterm*) hipe_closure_stub_address(fe->arity);
}
Eterm hipe_build_stacktrace(Process *p, struct StackTrace *s)
diff --git a/erts/emulator/hipe/hipe_mode_switch.h b/erts/emulator/hipe/hipe_mode_switch.h
index c40077d558..334e978307 100644
--- a/erts/emulator/hipe/hipe_mode_switch.h
+++ b/erts/emulator/hipe/hipe_mode_switch.h
@@ -59,7 +59,7 @@ void hipe_set_call_trap(Uint *bfun, void *nfun, int is_closure);
Process *hipe_mode_switch(Process*, unsigned, Eterm*);
void hipe_inc_nstack(Process *p);
void hipe_empty_nstack(Process *p);
-void hipe_set_closure_stub(ErlFunEntry *fe, unsigned num_free);
+void hipe_set_closure_stub(ErlFunEntry *fe);
Eterm hipe_build_stacktrace(Process *p, struct StackTrace *s);
ERTS_GLB_INLINE void hipe_reserve_beam_trap_frame(Process*, Eterm reg[], unsigned arity);
diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c
index 50d08b96d3..1a34ce786c 100644
--- a/erts/emulator/hipe/hipe_x86_signal.c
+++ b/erts/emulator/hipe/hipe_x86_signal.c
@@ -51,7 +51,7 @@
#endif
#include "hipe_signal.h"
-#if __GLIBC__ == 2 && (__GLIBC_MINOR__ >= 3)
+#if defined(__GLIBC__) && __GLIBC__ == 2 && (__GLIBC_MINOR__ >= 3)
/*
* __libc_sigaction() is the core routine.
* Without libpthread, sigaction() and __sigaction() are both aliases
diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c
index 3ab03971a5..bb930ff03b 100644
--- a/erts/emulator/sys/common/erl_mmap.c
+++ b/erts/emulator/sys/common/erl_mmap.c
@@ -1878,7 +1878,7 @@ erts_mremap(ErtsMemMapper* mm,
return NULL;
}
-#if ERTS_HAVE_OS_MREMAP || ERTS_HAVE_GENUINE_OS_MMAP
+#if defined(ERTS_HAVE_OS_MREMAP) || defined(ERTS_HAVE_GENUINE_OS_MMAP)
superaligned = (ERTS_MMAPFLG_SUPERALIGNED & flags);
if (superaligned) {
@@ -1898,7 +1898,7 @@ erts_mremap(ErtsMemMapper* mm,
}
}
-#if ERTS_HAVE_GENUINE_OS_MMAP
+#ifdef ERTS_HAVE_GENUINE_OS_MMAP
if (asize < old_size
&& (!superaligned
|| ERTS_IS_SUPERALIGNED(ptr))) {
@@ -1913,7 +1913,7 @@ erts_mremap(ErtsMemMapper* mm,
return ptr;
}
#endif
-#if ERTS_HAVE_OS_MREMAP
+#ifdef ERTS_HAVE_OS_MREMAP
if (superaligned)
return remap_move(mm, flags, new_ptr, old_size, sizep);
else {
@@ -2390,7 +2390,7 @@ add_2tup(Uint **hpp, Uint *szp, Eterm *lp, Eterm el1, Eterm el2)
}
Eterm erts_mmap_info(ErtsMemMapper* mm,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Eterm** hpp, Uint* szp,
struct erts_mmap_info_struct* emis)
@@ -2431,7 +2431,7 @@ Eterm erts_mmap_info(ErtsMemMapper* mm,
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
if (mm->supercarrier) {
const char* prefix = "supercarrier ";
@@ -2485,7 +2485,7 @@ Eterm erts_mmap_info(ErtsMemMapper* mm,
Eterm erts_mmap_info_options(ErtsMemMapper* mm,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -2496,7 +2496,7 @@ Eterm erts_mmap_info_options(ErtsMemMapper* mm,
Eterm res = THE_NON_VALUE;
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
erts_print(to, arg, "%sscs: %bpu\n", prefix, scs);
if (mm->supercarrier) {
diff --git a/erts/emulator/sys/common/erl_mmap.h b/erts/emulator/sys/common/erl_mmap.h
index 1049f7affc..2a07d93c8c 100644
--- a/erts/emulator/sys/common/erl_mmap.h
+++ b/erts/emulator/sys/common/erl_mmap.h
@@ -22,6 +22,7 @@
#define ERL_MMAP_H__
#include "sys.h"
+#include "erl_printf.h"
#define ERTS_MMAP_SUPERALIGNED_BITS (18)
/* Affects hard limits for sbct and lmbcs documented in erts_alloc.xml */
@@ -146,10 +147,10 @@ struct erts_mmap_info_struct
UWord segs[6];
UWord os_used;
};
-Eterm erts_mmap_info(ErtsMemMapper*, int *print_to_p, void *print_to_arg,
+Eterm erts_mmap_info(ErtsMemMapper*, fmtfn_t *print_to_p, void *print_to_arg,
Eterm** hpp, Uint* szp, struct erts_mmap_info_struct*);
Eterm erts_mmap_info_options(ErtsMemMapper*,
- char *prefix, int *print_to_p, void *print_to_arg,
+ char *prefix, fmtfn_t *print_to_p, void *print_to_arg,
Uint **hpp, Uint *szp);
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index e76082177e..4dd986f4c8 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -991,7 +991,7 @@ add_4tup(Uint **hpp, Uint *szp, Eterm *lp,
static Eterm
info_options(ErtsMsegAllctr_t *ma,
char *prefix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
Uint **hpp,
Uint *szp)
@@ -999,7 +999,7 @@ info_options(ErtsMsegAllctr_t *ma,
Eterm res = NIL;
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
erts_print(to, arg, "%samcbf: %beu\n", prefix, ma->abs_max_cache_bad_fit);
erts_print(to, arg, "%srmcbf: %beu\n", prefix, ma->rel_max_cache_bad_fit);
@@ -1027,7 +1027,7 @@ info_options(ErtsMsegAllctr_t *ma,
}
static Eterm
-info_calls(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **hpp, Uint *szp)
+info_calls(ErtsMsegAllctr_t *ma, fmtfn_t *print_to_p, void *print_to_arg, Uint **hpp, Uint *szp)
{
Eterm res = THE_NON_VALUE;
@@ -1040,7 +1040,7 @@ info_calls(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **hpp
erts_print(TO, TOA, "mseg_%s calls: %b32u%09b32u\n", #CC, \
ma->calls.CC.giga_no, ma->calls.CC.no)
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
PRINT_CC(to, arg, alloc);
@@ -1106,7 +1106,7 @@ info_calls(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **hpp
}
static Eterm
-info_status(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg,
+info_status(ErtsMsegAllctr_t *ma, fmtfn_t *print_to_p, void *print_to_arg,
int begin_new_max_period, int only_sz, Uint **hpp, Uint *szp)
{
Eterm res = THE_NON_VALUE;
@@ -1117,7 +1117,7 @@ info_status(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg,
ma->segments.max_ever.sz = ma->segments.max.sz;
if (print_to_p) {
- int to = *print_to_p;
+ fmtfn_t to = *print_to_p;
void *arg = print_to_arg;
if (!only_sz) {
@@ -1165,7 +1165,7 @@ info_status(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg,
return res;
}
-static Eterm info_memkind(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg,
+static Eterm info_memkind(ErtsMsegAllctr_t *ma, fmtfn_t *print_to_p, void *print_to_arg,
int begin_max_per, int only_sz, Uint **hpp, Uint *szp)
{
Eterm res = THE_NON_VALUE;
@@ -1196,7 +1196,7 @@ static Eterm info_memkind(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_
}
static Eterm
-info_version(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **hpp, Uint *szp)
+info_version(ErtsMsegAllctr_t *ma, fmtfn_t *print_to_p, void *print_to_arg, Uint **hpp, Uint *szp)
{
Eterm res = THE_NON_VALUE;
@@ -1218,7 +1218,7 @@ info_version(ErtsMsegAllctr_t *ma, int *print_to_p, void *print_to_arg, Uint **h
Eterm
erts_mseg_info_options(int ix,
- int *print_to_p, void *print_to_arg,
+ fmtfn_t *print_to_p, void *print_to_arg,
Uint **hpp, Uint *szp)
{
ErtsMsegAllctr_t *ma = ERTS_MSEG_ALLCTR_IX(ix);
@@ -1231,7 +1231,7 @@ erts_mseg_info_options(int ix,
Eterm
erts_mseg_info(int ix,
- int *print_to_p,
+ fmtfn_t *print_to_p,
void *print_to_arg,
int begin_max_per,
int only_sz,
diff --git a/erts/emulator/sys/common/erl_mseg.h b/erts/emulator/sys/common/erl_mseg.h
index a43b409e94..bba0dec499 100644
--- a/erts/emulator/sys/common/erl_mseg.h
+++ b/erts/emulator/sys/common/erl_mseg.h
@@ -98,8 +98,8 @@ Uint erts_mseg_unit_size(void);
void erts_mseg_init(ErtsMsegInit_t *init);
void erts_mseg_late_init(void); /* Have to be called after all allocators,
threads and timers have been initialized. */
-Eterm erts_mseg_info_options(int, int *, void*, Uint **, Uint *);
-Eterm erts_mseg_info(int, int *, void*, int, int, Uint **, Uint *);
+Eterm erts_mseg_info_options(int, fmtfn_t*, void*, Uint **, Uint *);
+Eterm erts_mseg_info(int, fmtfn_t *, void*, int, int, Uint **, Uint *);
#endif /* #if HAVE_ERTS_MSEG */
diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h
index b64b0d87f6..bd554238b7 100644
--- a/erts/emulator/sys/unix/erl_unix_sys.h
+++ b/erts/emulator/sys/unix/erl_unix_sys.h
@@ -46,10 +46,10 @@
#include <signal.h>
#include <setjmp.h>
-#if HAVE_SYS_SOCKETIO_H
+#ifdef HAVE_SYS_SOCKETIO_H
# include <sys/socketio.h>
#endif
-#if HAVE_SYS_SOCKIO_H
+#ifdef HAVE_SYS_SOCKIO_H
# include <sys/sockio.h>
#endif
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index b0e623a5b9..4b2edace0a 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -90,8 +90,6 @@ extern void erl_sys_args(int*, char**);
extern void erts_sys_init_float(void);
-extern void erl_crash_dump(char* file, int line, char* fmt, ...);
-
#ifdef DEBUG
static int debug_log = 0;
@@ -414,6 +412,10 @@ erts_sys_pre_init(void)
erts_thr_init(&eid);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ erts_lc_init();
+#endif
+
#ifdef ERTS_ENABLE_LOCK_COUNT
erts_lcnt_init();
#endif
@@ -672,7 +674,7 @@ sigusr1_exit(void)
}
prepare_crash_dump(secs);
- erts_exit(ERTS_ERROR_EXIT, "Received SIGUSR1\n");
+ erts_exit(ERTS_DUMP_EXIT, "Received SIGUSR1\n");
}
#ifdef ETHR_UNUSABLE_SIGUSRX
diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h
index 04fbf23109..78005aada9 100644
--- a/erts/emulator/sys/win32/erl_win_sys.h
+++ b/erts/emulator/sys/win32/erl_win_sys.h
@@ -182,6 +182,8 @@ typedef LONGLONG ErtsMonotonicTime;
typedef LONGLONG ErtsSysHrTime;
#endif
+#define ErtsStrToSint64 _strtoi64
+
typedef ErtsMonotonicTime ErtsSystemTime;
typedef ErtsMonotonicTime ErtsSysPerfCounter;
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index cf821b05cb..f3881e0736 100644
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -40,7 +40,6 @@ void erts_sys_init_float(void);
void erl_start(int, char**);
void erts_exit(int n, char*, ...);
void erl_error(char*, va_list);
-void erl_crash_dump(char*, int, char*, ...);
/*
* Microsoft-specific function to map a WIN32 error code to a Posix errno.
@@ -3187,16 +3186,16 @@ erts_sys_pre_init(void)
eid.thread_create_parent_func = thr_create_cleanup;
erts_thr_init(&eid);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ erts_lc_init();
#endif
-
- erts_init_sys_time_sup();
-
-#ifdef USE_THREADS
#ifdef ERTS_ENABLE_LOCK_COUNT
erts_lcnt_init();
#endif
#endif
+ erts_init_sys_time_sup();
+
erts_smp_atomic_init_nob(&sys_misc_mem_sz, 0);
}
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index d31399e4af..b8d89126fe 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -31,6 +31,7 @@
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, erlang_halt/1,
+ erl_crash_dump_bytes/1,
is_builtin/1]).
suite() ->
@@ -43,6 +44,7 @@ all() ->
t_list_to_existing_atom, os_env, otp_7526,
display,
atom_to_binary, binary_to_atom, binary_to_existing_atom,
+ erl_crash_dump_bytes,
min_max, erlang_halt, is_builtin].
%% Uses erlang:display to test that erts_printf does not do deep recursion
@@ -664,7 +666,7 @@ erlang_halt(Config) when is_list(Config) ->
[available_internal_state, true]),
{badrpc,nodedown} = rpc:call(N4, erts_debug, set_internal_state,
[broken_halt, "Validate correct crash dump"]),
- ok = wait_until_stable_size(CrashDump,-1),
+ {ok,_} = wait_until_stable_size(CrashDump,-1),
{ok, Bin} = file:read_file(CrashDump),
case {string:str(binary_to_list(Bin),"\n=end\n"),
string:str(binary_to_list(Bin),"\r\n=end\r\n")} of
@@ -681,11 +683,34 @@ wait_until_stable_size(File,PrevSz) ->
wait_until_stable_size(File,PrevSz-1);
{ok,#file_info{size = PrevSz }} when PrevSz /= -1 ->
io:format("Crashdump file size was: ~p (~s)~n",[PrevSz,File]),
- ok;
+ {ok,PrevSz};
{ok,#file_info{size = NewSz }} ->
wait_until_stable_size(File,NewSz)
end.
+% Test erlang:halt with ERL_CRASH_DUMP_BYTES
+erl_crash_dump_bytes(Config) when is_list(Config) ->
+ Bytes = 1000,
+ CrashDump = do_limited_crash_dump(Config, Bytes),
+ {ok,ActualBytes} = wait_until_stable_size(CrashDump,-1),
+ true = ActualBytes < (Bytes + 100),
+
+ NoDump = do_limited_crash_dump(Config,0),
+ {error,enoent} = wait_until_stable_size(NoDump,-8),
+ ok.
+
+do_limited_crash_dump(Config, Bytes) ->
+ H = hostname(),
+ {ok,N} = slave:start(H, halt_node),
+ BytesStr = integer_to_list(Bytes),
+ CrashDump = filename:join(proplists:get_value(priv_dir,Config),
+ "erl_crash." ++ BytesStr ++ ".dump"),
+ true = rpc:call(N, os, putenv, ["ERL_CRASH_DUMP",CrashDump]),
+ true = rpc:call(N, os, putenv, ["ERL_CRASH_DUMP_BYTES",BytesStr]),
+ {badrpc,nodedown} = rpc:call(N, erlang, halt, ["Testing ERL_CRASH_DUMP_BYTES"]),
+ CrashDump.
+
+
is_builtin(_Config) ->
Exp0 = [{M,F,A} || {M,_} <- code:all_loaded(),
{F,A} <- M:module_info(exports)],
diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl
index 465ddfa7a8..0742b77a52 100644
--- a/erts/emulator/test/code_SUITE.erl
+++ b/erts/emulator/test/code_SUITE.erl
@@ -153,127 +153,23 @@ call_purged_fun_code_there(Config) when is_list(Config) ->
ok.
call_purged_fun_test(Priv, Data, Type) ->
- File = filename:join(Data, "my_code_test2"),
- Code = filename:join(Priv, "my_code_test2"),
-
- catch erlang:purge_module(my_code_test2),
- catch erlang:delete_module(my_code_test2),
- catch erlang:purge_module(my_code_test2),
-
- {ok,my_code_test2} = c:c(File, [{outdir,Priv}]),
-
- T = ets:new(my_code_test2_fun_table, []),
- ets:insert(T, {my_fun,my_code_test2:make_fun(4711)}),
- ets:insert(T, {my_fun2,my_code_test2:make_fun2()}),
-
- spawn(fun () ->
- [{my_fun2,F2}] = ets:lookup(T, my_fun2),
- F2(fun () ->
- receive after infinity -> ok end
- end,
- fun () -> ok end),
- exit(completed)
- end),
-
- PurgeType = case Type of
- code_gone ->
- ok = file:delete(Code++".beam"),
- true;
- code_reload ->
- true;
- code_there ->
- false
- end,
-
- true = erlang:delete_module(my_code_test2),
-
- Purge = start_purge(my_code_test2, PurgeType),
-
- {P0, M0} = spawn_monitor(fun () ->
- [{my_fun,F}] = ets:lookup(T, my_fun),
- 4712 = F(1),
- exit(completed)
- end),
-
- wait_until(fun () ->
- {status, suspended}
- == process_info(P0, status)
- end),
-
- ok = continue_purge(Purge),
-
- {P1, M1} = spawn_monitor(fun () ->
- [{my_fun,F}] = ets:lookup(T, my_fun),
- 4713 = F(2),
- exit(completed)
- end),
- {P2, M2} = spawn_monitor(fun () ->
- [{my_fun,F}] = ets:lookup(T, my_fun),
- 4714 = F(3),
- exit(completed)
- end),
-
- wait_until(fun () ->
- {status, suspended}
- == process_info(P1, status)
- end),
- wait_until(fun () ->
- {status, suspended}
- == process_info(P2, status)
- end),
-
- {current_function,
- {erts_code_purger,
- pending_purge_lambda,
- 3}} = process_info(P0, current_function),
- {current_function,
- {erts_code_purger,
- pending_purge_lambda,
- 3}} = process_info(P1, current_function),
- {current_function,
- {erts_code_purger,
- pending_purge_lambda,
- 3}} = process_info(P2, current_function),
-
- case Type of
- code_there ->
- false = complete_purge(Purge);
- _ ->
- {true, true} = complete_purge(Purge)
- end,
+ OptsList = case erlang:system_info(hipe_architecture) of
+ undefined -> [[]];
+ _ -> [[], [native,{d,hipe}]]
+ end,
+ [call_purged_fun_test_do(Priv, Data, Type, CO, FO)
+ || CO <- OptsList, FO <- OptsList].
+
+
+call_purged_fun_test_do(Priv, Data, Type, CallerOpts, FunOpts) ->
+ io:format("Compile caller as ~p and funs as ~p\n", [CallerOpts, FunOpts]),
+ SrcFile = filename:join(Data, "call_purged_fun_tester.erl"),
+ ObjFile = filename:join(Priv, "call_purged_fun_tester.beam"),
+ {ok,Mod,Code} = compile:file(SrcFile, [binary, report | CallerOpts]),
+ {module,Mod} = code:load_binary(Mod, ObjFile, Code),
+
+ call_purged_fun_tester:do(Priv, Data, Type, FunOpts).
- case Type of
- code_gone ->
- receive
- {'DOWN', M0, process, P0, Reason0} ->
- {undef, _} = Reason0
- end,
- receive
- {'DOWN', M1, process, P1, Reason1} ->
- {undef, _} = Reason1
- end,
- receive
- {'DOWN', M2, process, P2, Reason2} ->
- {undef, _} = Reason2
- end;
- _ ->
- receive
- {'DOWN', M0, process, P0, Reason0} ->
- completed = Reason0
- end,
- receive
- {'DOWN', M1, process, P1, Reason1} ->
- completed = Reason1
- end,
- receive
- {'DOWN', M2, process, P2, Reason2} ->
- completed = Reason2
- end,
- catch erlang:purge_module(my_code_test2),
- catch erlang:delete_module(my_code_test2),
- catch erlang:purge_module(my_code_test2)
- end,
- ok.
multi_proc_purge(Config) when is_list(Config) ->
%%
@@ -975,35 +871,3 @@ flush() ->
id(I) -> I.
-wait_until(Fun) ->
- case Fun() of
- true ->
- ok;
- false ->
- receive after 100 -> ok end,
- wait_until(Fun)
- end.
-
-start_purge(Mod, Type) when is_atom(Mod)
- andalso ((Type == true)
- orelse (Type == false)) ->
- Ref = make_ref(),
- erts_code_purger ! {test_purge, Mod, self(), Type, Ref},
- receive
- {started, Ref} ->
- Ref
- end.
-
-continue_purge(Ref) when is_reference(Ref) ->
- erts_code_purger ! {continue, Ref},
- receive
- {continued, Ref} ->
- ok
- end.
-
-complete_purge(Ref) when is_reference(Ref) ->
- erts_code_purger ! {complete, Ref},
- receive
- {test_purge, Res, Ref} ->
- Res
- end.
diff --git a/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl b/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl
new file mode 100644
index 0000000000..699f0c1161
--- /dev/null
+++ b/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl
@@ -0,0 +1,186 @@
+-module(call_purged_fun_tester).
+
+-export([do/4]).
+
+%% Resurrect line macro when hipe compiled
+-ifdef(hipe).
+-define(line, put(the_line,?LINE),).
+do(Priv, Data, Type, Opts) ->
+ try do_it(Priv, Data, Type, Opts)
+ catch
+ C:E ->
+ ST = erlang:get_stacktrace(),
+ io:format("Caught exception from line ~p:\n~p\n",
+ [get(the_line), ST]),
+ io:format("Message queue: ~p\n", [process_info(self(), messages)]),
+ erlang:raise(C, E, ST)
+ end.
+-else.
+-define(line,).
+do(P,D,T,O) ->
+ do_it(P,D,T,O).
+-endif.
+
+
+do_it(Priv, Data, Type, Opts) ->
+ File = filename:join(Data, "my_code_test2"),
+ Code = filename:join(Priv, "my_code_test2"),
+
+ catch erlang:purge_module(my_code_test2),
+ catch erlang:delete_module(my_code_test2),
+ catch erlang:purge_module(my_code_test2),
+
+ ?line {ok,my_code_test2} = c:c(File, [{outdir,Priv} | Opts]),
+
+ ?line IsNative = lists:member(native,Opts),
+ ?line IsNative = code:is_module_native(my_code_test2),
+
+ ?line T = ets:new(my_code_test2_fun_table, []),
+ ets:insert(T, {my_fun,my_code_test2:make_fun(4711)}),
+ ets:insert(T, {my_fun2,my_code_test2:make_fun2()}),
+
+ Papa = self(),
+ {P0,M0} = spawn_monitor(fun () ->
+ [{my_fun2,F2}] = ets:lookup(T, my_fun2),
+ F2(fun () ->
+ Papa ! {self(),"going to sleep"},
+ receive {Papa,"wake up"} -> ok end
+ end,
+ fun () -> ok end),
+ exit(completed)
+ end),
+
+ ?line PurgeType = case Type of
+ code_gone ->
+ ok = file:delete(Code++".beam"),
+ true;
+ code_reload ->
+ true;
+ code_there ->
+ false
+ end,
+
+ ?line true = erlang:delete_module(my_code_test2),
+
+ ?line ok = receive {P0, "going to sleep"} -> ok
+ after 1000 -> timeout
+ end,
+
+ ?line Purge = start_purge(my_code_test2, PurgeType),
+
+ ?line {P1, M1} = spawn_monitor(fun () ->
+ ?line [{my_fun,F}] = ets:lookup(T, my_fun),
+ ?line 4712 = F(1),
+ exit(completed)
+ end),
+
+ ?line ok = wait_until(fun () ->
+ {status, suspended}
+ == process_info(P1, status)
+ end),
+
+ ?line ok = continue_purge(Purge),
+
+ ?line {P2, M2} = spawn_monitor(fun () ->
+ ?line [{my_fun,F}] = ets:lookup(T, my_fun),
+ ?line 4713 = F(2),
+ exit(completed)
+ end),
+ ?line {P3, M3} = spawn_monitor(fun () ->
+ ?line [{my_fun,F}] = ets:lookup(T, my_fun),
+ ?line 4714 = F(3),
+ exit(completed)
+ end),
+
+ ?line ok = wait_until(fun () ->
+ {status, suspended}
+ == process_info(P2, status)
+ end),
+ ?line ok = wait_until(fun () ->
+ {status, suspended}
+ == process_info(P3, status)
+ end),
+
+ ?line {current_function,
+ {erts_code_purger,
+ pending_purge_lambda,
+ 3}} = process_info(P1, current_function),
+ ?line {current_function,
+ {erts_code_purger,
+ pending_purge_lambda,
+ 3}} = process_info(P2, current_function),
+ ?line {current_function,
+ {erts_code_purger,
+ pending_purge_lambda,
+ 3}} = process_info(P3, current_function),
+
+ case Type of
+ code_there ->
+ ?line false = complete_purge(Purge),
+ P0 ! {self(), "wake up"},
+ ?line completed = wait_for_down(P0,M0);
+ _ ->
+ ?line {true, true} = complete_purge(Purge),
+ ?line killed = wait_for_down(P0,M0)
+ end,
+
+ case Type of
+ code_gone ->
+ ?line {undef, _} = wait_for_down(P1,M1),
+ ?line {undef, _} = wait_for_down(P2,M2),
+ ?line {undef, _} = wait_for_down(P3,M3);
+ _ ->
+ ?line completed = wait_for_down(P1,M1),
+ ?line completed = wait_for_down(P2,M2),
+ ?line completed = wait_for_down(P3,M3),
+ catch erlang:purge_module(my_code_test2),
+ catch erlang:delete_module(my_code_test2),
+ catch erlang:purge_module(my_code_test2)
+ end,
+ ok.
+
+wait_for_down(P,M) ->
+ receive
+ {'DOWN', M, process, P, Reason} ->
+ Reason
+ after 1000 ->
+ timeout
+ end.
+
+wait_until(Fun) ->
+ wait_until(Fun, 20).
+
+wait_until(Fun, N) ->
+ case {Fun(),N} of
+ {true, _} ->
+ ok;
+ {false, 0} ->
+ timeout;
+ {false, _} ->
+ receive after 100 -> ok end,
+ wait_until(Fun, N-1)
+ end.
+
+start_purge(Mod, Type) when is_atom(Mod)
+ andalso ((Type == true)
+ orelse (Type == false)) ->
+ Ref = make_ref(),
+ erts_code_purger ! {test_purge, Mod, self(), Type, Ref},
+ receive
+ {started, Ref} ->
+ Ref
+ end.
+
+continue_purge(Ref) when is_reference(Ref) ->
+ erts_code_purger ! {continue, Ref},
+ receive
+ {continued, Ref} ->
+ ok
+ end.
+
+complete_purge(Ref) when is_reference(Ref) ->
+ erts_code_purger ! {complete, Ref},
+ receive
+ {test_purge, Res, Ref} ->
+ Res
+ end.
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 306f2091a1..0d3910b2e2 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -21,15 +21,17 @@
-module(nif_SUITE).
%%-define(line_trace,true).
--define(CHECK(Exp,Got), check(Exp,Got,?LINE)).
+-define(CHECK(Exp,Got), Exp = check(Exp,Got,?LINE)).
%%-define(CHECK(Exp,Got), Exp = Got).
-include_lib("common_test/include/ct.hrl").
--export([all/0, suite/0,
+-export([all/0, suite/0, groups/0,
+ init_per_group/2, end_per_group/2,
init_per_testcase/2, end_per_testcase/2,
basic/1, reload_error/1, upgrade/1, heap_frag/1,
t_on_load/1,
+ hipe/1,
types/1, many_args/1, binaries/1, get_string/1, get_atom/1,
maps/1,
api_macros/1,
@@ -52,27 +54,20 @@
-export([many_args_100/100]).
-
-%% -export([lib_version/0,call_history/0,hold_nif_mod_priv_data/1,nif_mod_call_history/0,
-%% list_seq/1,type_test/0,tuple_2_list/1,is_identical/2,compare/2,
-%% clone_bin/1,make_sub_bin/3,string_to_bin/2,atom_to_bin/2,macros/1,
-%% tuple_2_list_and_tuple/1,iolist_2_bin/1,get_resource_type/1,alloc_resource/2,
-%% make_resource/1,get_resource/2,release_resource/1,last_resource_dtor_call/0, 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]).
-
-
-define(nif_stub,nif_stub_error(?LINE)).
suite() -> [{ct_hooks,[ts_install_cth]}].
-all() ->
- [basic, reload_error, upgrade, heap_frag, types, many_args,
- t_on_load,
+all() ->
+ [basic]
+ ++
+ [{group, G} || G <- api_groups()]
+ ++
+ [reload_error, heap_frag, types, many_args,
+ hipe,
binaries, get_string, get_atom, maps, api_macros, from_array,
iolist_as_binary, resource, resource_binary,
- resource_takeover, threading, send, send2, send3,
+ threading, send, send2, send3,
send_threaded, neg, is_checks, get_length, make_atom,
make_string,reverse_list_test,
otp_9828,
@@ -85,9 +80,35 @@ all() ->
nif_port_command,
nif_snprintf].
+groups() ->
+ [{G, [], api_repeaters()} || G <- api_groups()].
+
+api_groups() -> [api_latest, api_2_4, api_2_0].
+
+api_repeaters() -> [upgrade, resource_takeover, t_on_load].
+
+init_per_group(api_latest, Config) -> Config;
+init_per_group(api_2_4, Config) ->
+ [{nif_api_version, ".2_4"} | Config];
+init_per_group(api_2_0, Config) ->
+ case {os:type(),erlang:system_info({wordsize, internal})} of
+ {{win32,_}, 8} ->
+ %% ERL_NIF_TERM was declared as 32-bit 'long' until 2.3
+ {skip, "API 2.0 buggy on Windows 64-bit"};
+ _ ->
+ [{nif_api_version, ".2_0"} | Config]
+ end.
+
+end_per_group(_,_) -> ok.
+
init_per_testcase(t_on_load, Config) ->
ets:new(nif_SUITE, [named_table]),
Config;
+init_per_testcase(hipe, Config) ->
+ case erlang:system_info(hipe_architecture) of
+ undefined -> {skip, "HiPE is disabled"};
+ _ -> Config
+ end;
init_per_testcase(_Case, Config) ->
Config.
@@ -148,7 +169,7 @@ reload_error(Config) when is_list(Config) ->
ok.
%% Test upgrade callback in nif lib
-upgrade(Config) when is_list(Config) ->
+upgrade(Config) when is_list(Config) ->
TmpMem = tmpmem(),
ensure_lib_loaded(Config),
@@ -299,6 +320,8 @@ t_on_load(Config) when is_list(Config) ->
%% Use ETS to tell nif_mod:on_load what to do
ets:insert(nif_SUITE, {data_dir, Data}),
ets:insert(nif_SUITE, {lib_version, 1}),
+ API = proplists:get_value(nif_api_version, Config, ""),
+ ets:insert(nif_SUITE, {nif_api_version, API}),
{module,nif_mod} = code:load_binary(nif_mod,File,Bin),
hold_nif_mod_priv_data(nif_mod:get_priv_data_ptr()),
[{load,1,1,101},{get_priv_data_ptr,1,2,102}] = nif_mod_call_history(),
@@ -411,6 +434,17 @@ t_on_load(Config) when is_list(Config) ->
verify_tmpmem(TmpMem),
ok.
+hipe(Config) when is_list(Config) ->
+ Data = proplists:get_value(data_dir, Config),
+ Priv = proplists:get_value(priv_dir, Config),
+ Src = filename:join(Data, "hipe_compiled"),
+ {ok,hipe_compiled} = c:c(Src, [{outdir,Priv},native]),
+ true = code:is_module_native(hipe_compiled),
+ {error, {notsup,_}} = hipe_compiled:try_load_nif(),
+ true = code:delete(hipe_compiled),
+ false = code:purge(hipe_compiled),
+ ok.
+
%% Test NIF building heap fragments
heap_frag(Config) when is_list(Config) ->
@@ -914,7 +948,7 @@ resource_takeover(Config) when is_list(Config) ->
]),
?CHECK([{upgrade,2,1,201}], nif_mod_call_history()),
true = erlang:purge_module(nif_mod),
- ?CHECK([{unload,1,1,106}], nif_mod_call_history()),
+ ?CHECK([], nif_mod_call_history()), % BGX2 keeping lib loaded
BinA2 = read_resource(0,A2),
ok = forget_resource(A2),
@@ -927,8 +961,8 @@ resource_takeover(Config) when is_list(Config) ->
?CHECK([], nif_mod_call_history()), % no dtor
ok = forget_resource(BGX2), % calling dtor in orphan library v1 still loaded
- ?CHECK([{{resource_dtor_B_v1,BinBGX2},1,6,106}], nif_mod_call_history()),
- % How to test that lib v1 is closed here?
+ ?CHECK([{{resource_dtor_B_v1,BinBGX2},1,6,106}, {unload,1,7,107}],
+ nif_mod_call_history()),
ok = forget_resource(NGX2),
?CHECK([], nif_mod_call_history()), % no dtor
@@ -1151,6 +1185,9 @@ resource_takeover(Config) when is_list(Config) ->
ok = forget_resource(AN7),
[] = nif_mod_call_history(),
+ true = erlang:delete_module(nif_mod),
+ true = erlang:purge_module(nif_mod),
+
true = lists:member(?MODULE, erlang:system_info(taints)),
true = lists:member(nif_mod, erlang:system_info(taints)),
verify_tmpmem(TmpMem),
@@ -1882,7 +1919,8 @@ check(Exp,Got,Line) ->
case Got of
Exp -> Exp;
_ ->
- io:format("CHECK at ~p: Expected ~p but got ~p\n",[Line,Exp,Got]),
+ io:format("CHECK at line ~p\nExpected: ~p\nGot : ~p\n",
+ [Line,Exp,Got]),
Got
end.
diff --git a/erts/emulator/test/nif_SUITE_data/Makefile.src b/erts/emulator/test/nif_SUITE_data/Makefile.src
index fbb8978771..de06026780 100644
--- a/erts/emulator/test/nif_SUITE_data/Makefile.src
+++ b/erts/emulator/test/nif_SUITE_data/Makefile.src
@@ -2,7 +2,13 @@
NIF_LIBS = nif_SUITE.1@dll@ \
nif_mod.1@dll@ \
nif_mod.2@dll@ \
- nif_mod.3@dll@
+ nif_mod.3@dll@ \
+ nif_mod.1.2_0@dll@ \
+ nif_mod.2.2_0@dll@ \
+ nif_mod.3.2_0@dll@ \
+ nif_mod.1.2_4@dll@ \
+ nif_mod.2.2_4@dll@ \
+ nif_mod.3.2_4@dll@
all: $(NIF_LIBS) basic@dll@ rwlock@dll@ tsd@dll@ echo_drv@dll@
diff --git a/erts/emulator/test/nif_SUITE_data/hipe_compiled.erl b/erts/emulator/test/nif_SUITE_data/hipe_compiled.erl
new file mode 100644
index 0000000000..84ddbc8d63
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/hipe_compiled.erl
@@ -0,0 +1,6 @@
+-module(hipe_compiled).
+
+-export([try_load_nif/0]).
+
+try_load_nif() ->
+ erlang:load_nif("doesn't matter", 0).
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index dc6d8cea76..2c93891852 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -104,21 +104,24 @@ struct binary_resource {
static int get_pointer(ErlNifEnv* env, ERL_NIF_TERM term, void** pp)
{
- ErlNifUInt64 i64;
- int r = enif_get_uint64(env, term, &i64);
+ ErlNifBinary bin;
+ int r = enif_inspect_binary(env, term, &bin);
if (r) {
- *pp = (void*)i64;
+ *pp = *(void**)bin.data;
}
return r;
}
static ERL_NIF_TERM make_pointer(ErlNifEnv* env, void* p)
{
- ErlNifUInt64 i64 = (ErlNifUInt64) p;
- return enif_make_uint64(env, i64);
+ void** bin_data;
+ ERL_NIF_TERM res;
+ ADD_CALL("get_priv_data_ptr");
+ bin_data = (void**)enif_make_new_binary(env, sizeof(void*), &res);
+ *bin_data = p;
+ return res;
}
-
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
PrivData* data = enif_alloc(sizeof(PrivData));
diff --git a/erts/emulator/test/nif_SUITE_data/nif_api_2_0/README b/erts/emulator/test/nif_SUITE_data/nif_api_2_0/README
new file mode 100644
index 0000000000..a6ed36f634
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_api_2_0/README
@@ -0,0 +1,5 @@
+These are old genuine header files
+checked out from tag OTP_R14A c1e94fa9a6fe4ae717d35.
+
+I choose this API version (2.0) to test as it's
+before the addition of vm_variant in ErlNifEntry.
diff --git a/erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_drv_nif.h b/erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_drv_nif.h
new file mode 100644
index 0000000000..ea013a49a3
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_drv_nif.h
@@ -0,0 +1,48 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Common structures for both erl_driver.h and erl_nif.h
+ */
+
+#ifndef __ERL_DRV_NIF_H__
+#define __ERL_DRV_NIF_H__
+
+typedef struct {
+ int driver_major_version;
+ int driver_minor_version;
+ char *erts_version;
+ char *otp_release;
+ int thread_support;
+ int smp_support;
+ int async_threads;
+ int scheduler_threads;
+ int nif_major_version;
+ int nif_minor_version;
+} ErlDrvSysInfo;
+
+typedef struct {
+ int suggested_stack_size;
+} ErlDrvThreadOpts;
+
+#endif /* __ERL_DRV_NIF_H__ */
+
+
+
+
diff --git a/erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_nif.h b/erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_nif.h
new file mode 100644
index 0000000000..936f03bce1
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_nif.h
@@ -0,0 +1,206 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2009-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/* Include file for writers of Native Implemented Functions.
+*/
+
+#ifndef __ERL_NIF_H__
+#define __ERL_NIF_H__
+
+
+#include "erl_drv_nif.h"
+
+/* Version history:
+** 0.1: R13B03
+** 1.0: R13B04
+** 2.0: R14A
+*/
+#define ERL_NIF_MAJOR_VERSION 2
+#define ERL_NIF_MINOR_VERSION 0
+
+#include <stdlib.h>
+
+#ifdef SIZEOF_CHAR
+# define SIZEOF_CHAR_SAVED__ SIZEOF_CHAR
+# undef SIZEOF_CHAR
+#endif
+#ifdef SIZEOF_SHORT
+# define SIZEOF_SHORT_SAVED__ SIZEOF_SHORT
+# undef SIZEOF_SHORT
+#endif
+#ifdef SIZEOF_INT
+# define SIZEOF_INT_SAVED__ SIZEOF_INT
+# undef SIZEOF_INT
+#endif
+#ifdef SIZEOF_LONG
+# define SIZEOF_LONG_SAVED__ SIZEOF_LONG
+# undef SIZEOF_LONG
+#endif
+#ifdef SIZEOF_LONG_LONG
+# define SIZEOF_LONG_LONG_SAVED__ SIZEOF_LONG_LONG
+# undef SIZEOF_LONG_LONG
+#endif
+#ifdef HALFWORD_HEAP_EMULATOR
+# define HALFWORD_HEAP_EMULATOR_SAVED__ HALFWORD_HEAP_EMULATOR
+# undef HALFWORD_HEAP_EMULATOR
+#endif
+#include "erl_int_sizes_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HALFWORD_HEAP_EMULATOR
+typedef unsigned int ERL_NIF_TERM;
+#else
+typedef unsigned long ERL_NIF_TERM;
+#endif
+
+struct enif_environment_t;
+typedef struct enif_environment_t ErlNifEnv;
+
+typedef struct
+{
+ const char* name;
+ unsigned arity;
+ ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+}ErlNifFunc;
+
+typedef struct enif_entry_t
+{
+ int major;
+ int minor;
+ const char* name;
+ int num_of_funcs;
+ ErlNifFunc* funcs;
+ 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);
+}ErlNifEntry;
+
+
+
+typedef struct
+{
+ size_t size;
+ unsigned char* data;
+
+ /* Internals (avert your eyes) */
+ ERL_NIF_TERM bin_term;
+ void* ref_bin;
+}ErlNifBinary;
+
+typedef struct enif_resource_type_t ErlNifResourceType;
+typedef void ErlNifResourceDtor(ErlNifEnv*, void*);
+typedef enum
+{
+ ERL_NIF_RT_CREATE = 1,
+ ERL_NIF_RT_TAKEOVER = 2
+}ErlNifResourceFlags;
+
+typedef enum
+{
+ ERL_NIF_LATIN1 = 1
+}ErlNifCharEncoding;
+
+typedef struct
+{
+ ERL_NIF_TERM pid; /* internal, may change */
+}ErlNifPid;
+
+typedef ErlDrvSysInfo ErlNifSysInfo;
+
+typedef struct ErlDrvTid_ *ErlNifTid;
+typedef struct ErlDrvMutex_ ErlNifMutex;
+typedef struct ErlDrvCond_ ErlNifCond;
+typedef struct ErlDrvRWLock_ ErlNifRWLock;
+typedef int ErlNifTSDKey;
+
+typedef ErlDrvThreadOpts ErlNifThreadOpts;
+
+#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
+# define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
+typedef struct {
+# include "erl_nif_api_funcs.h"
+} TWinDynNifCallbacks;
+extern TWinDynNifCallbacks WinDynNifCallbacks;
+# undef ERL_NIF_API_FUNC_DECL
+#endif
+
+#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_)) && !defined(STATIC_ERLANG_DRIVER)
+# define ERL_NIF_API_FUNC_MACRO(NAME) (WinDynNifCallbacks.NAME)
+# include "erl_nif_api_funcs.h"
+/* note that we have to keep ERL_NIF_API_FUNC_MACRO defined */
+
+#else /* non windows or included from emulator itself */
+
+# define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) extern RET_TYPE NAME ARGS
+# include "erl_nif_api_funcs.h"
+# undef ERL_NIF_API_FUNC_DECL
+#endif
+
+
+#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
+# define ERL_NIF_INIT_GLOB TWinDynNifCallbacks WinDynNifCallbacks;
+# define ERL_NIF_INIT_DECL(MODNAME) __declspec(dllexport) ErlNifEntry* nif_init(TWinDynNifCallbacks* callbacks)
+# define ERL_NIF_INIT_BODY memcpy(&WinDynNifCallbacks,callbacks,sizeof(TWinDynNifCallbacks))
+#else
+# define ERL_NIF_INIT_GLOB
+# define ERL_NIF_INIT_BODY
+# if defined(VXWORKS)
+# define ERL_NIF_INIT_DECL(MODNAME) ErlNifEntry* MODNAME ## _init(void)
+# else
+# define ERL_NIF_INIT_DECL(MODNAME) ErlNifEntry* nif_init(void)
+# endif
+#endif
+
+
+#ifdef __cplusplus
+}
+# define ERL_NIF_INIT_PROLOGUE extern "C" {
+# define ERL_NIF_INIT_EPILOGUE }
+#else
+# define ERL_NIF_INIT_PROLOGUE
+# define ERL_NIF_INIT_EPILOGUE
+#endif
+
+
+#define ERL_NIF_INIT(NAME, FUNCS, LOAD, RELOAD, UPGRADE, UNLOAD) \
+ERL_NIF_INIT_PROLOGUE \
+ERL_NIF_INIT_GLOB \
+ERL_NIF_INIT_DECL(NAME) \
+{ \
+ static ErlNifEntry entry = \
+ { \
+ ERL_NIF_MAJOR_VERSION, \
+ ERL_NIF_MINOR_VERSION, \
+ #NAME, \
+ sizeof(FUNCS) / sizeof(*FUNCS), \
+ FUNCS, \
+ LOAD, RELOAD, UPGRADE, UNLOAD \
+ }; \
+ ERL_NIF_INIT_BODY; \
+ return &entry; \
+} \
+ERL_NIF_INIT_EPILOGUE
+
+
+#endif /* __ERL_NIF_H__ */
+
diff --git a/erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_nif_api_funcs.h b/erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_nif_api_funcs.h
new file mode 100644
index 0000000000..ef4e9580b0
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_api_2_0/erl_nif_api_funcs.h
@@ -0,0 +1,257 @@
+/*
+ * %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%
+ */
+
+#if !defined(ERL_NIF_API_FUNC_DECL) && !defined(ERL_NIF_API_FUNC_MACRO)
+# error This file should not be included directly
+#endif
+
+#ifdef ERL_NIF_API_FUNC_DECL
+ERL_NIF_API_FUNC_DECL(void*,enif_priv_data,(ErlNifEnv*));
+ERL_NIF_API_FUNC_DECL(void*,enif_alloc,(size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_free,(void* ptr));
+ERL_NIF_API_FUNC_DECL(int,enif_is_atom,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_binary,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_ref,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_inspect_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(int,enif_alloc_binary,(size_t size, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(int,enif_realloc_binary,(ErlNifBinary* bin, size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_release_binary,(ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(int,enif_get_int,(ErlNifEnv*, ERL_NIF_TERM term, int* ip));
+ERL_NIF_API_FUNC_DECL(int,enif_get_ulong,(ErlNifEnv*, ERL_NIF_TERM term, unsigned long* ip));
+ERL_NIF_API_FUNC_DECL(int,enif_get_double,(ErlNifEnv*, ERL_NIF_TERM term, double* dp));
+ERL_NIF_API_FUNC_DECL(int,enif_get_list_cell,(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM* head, ERL_NIF_TERM* tail));
+ERL_NIF_API_FUNC_DECL(int,enif_get_tuple,(ErlNifEnv* env, ERL_NIF_TERM tpl, int* arity, const ERL_NIF_TERM** array));
+ERL_NIF_API_FUNC_DECL(int,enif_is_identical,(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs));
+ERL_NIF_API_FUNC_DECL(int,enif_compare,(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_binary,(ErlNifEnv* env, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_badarg,(ErlNifEnv* env));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int,(ErlNifEnv* env, int i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ulong,(ErlNifEnv* env, unsigned long i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_double,(ErlNifEnv* env, double d));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_atom,(ErlNifEnv* env, const char* name));
+ERL_NIF_API_FUNC_DECL(int,enif_make_existing_atom,(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_tuple,(ErlNifEnv* env, unsigned cnt, ...));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list,(ErlNifEnv* env, unsigned cnt, ...));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_cell,(ErlNifEnv* env, ERL_NIF_TERM car, ERL_NIF_TERM cdr));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string,(ErlNifEnv* env, const char* string, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ref,(ErlNifEnv* env));
+
+ERL_NIF_API_FUNC_DECL(ErlNifMutex*,enif_mutex_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_mutex_destroy,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(int,enif_mutex_trylock,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(void,enif_mutex_lock,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(void,enif_mutex_unlock,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(ErlNifCond*,enif_cond_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_destroy,(ErlNifCond *cnd));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_signal,(ErlNifCond *cnd));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_broadcast,(ErlNifCond *cnd));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_wait,(ErlNifCond *cnd, ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(ErlNifRWLock*,enif_rwlock_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_destroy,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(int,enif_rwlock_tryrlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_runlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(int,enif_rwlock_tryrwlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rwlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rwunlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(int,enif_tsd_key_create,(char *name, ErlNifTSDKey *key));
+ERL_NIF_API_FUNC_DECL(void,enif_tsd_key_destroy,(ErlNifTSDKey key));
+ERL_NIF_API_FUNC_DECL(void,enif_tsd_set,(ErlNifTSDKey key, void *data));
+ERL_NIF_API_FUNC_DECL(void*,enif_tsd_get,(ErlNifTSDKey key));
+ERL_NIF_API_FUNC_DECL(ErlNifThreadOpts*,enif_thread_opts_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_thread_opts_destroy,(ErlNifThreadOpts *opts));
+ERL_NIF_API_FUNC_DECL(int,enif_thread_create,(char *name,ErlNifTid *tid,void * (*func)(void *),void *args,ErlNifThreadOpts *opts));
+ERL_NIF_API_FUNC_DECL(ErlNifTid,enif_thread_self,(void));
+ERL_NIF_API_FUNC_DECL(int,enif_equal_tids,(ErlNifTid tid1, ErlNifTid tid2));
+ERL_NIF_API_FUNC_DECL(void,enif_thread_exit,(void *resp));
+ERL_NIF_API_FUNC_DECL(int,enif_thread_join,(ErlNifTid, void **respp));
+
+ERL_NIF_API_FUNC_DECL(void*,enif_realloc,(void* ptr, size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_system_info,(ErlNifSysInfo *sip, size_t si_size));
+ERL_NIF_API_FUNC_DECL(int,enif_fprintf,(void/* FILE* */ *filep, const char *format, ...));
+ERL_NIF_API_FUNC_DECL(int,enif_inspect_iolist_as_binary,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_sub_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, size_t pos, size_t size));
+ERL_NIF_API_FUNC_DECL(int,enif_get_string,(ErlNifEnv*, ERL_NIF_TERM list, char* buf, unsigned len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(int,enif_get_atom,(ErlNifEnv*, ERL_NIF_TERM atom, char* buf, unsigned len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(int,enif_is_fun,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_pid,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_port,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_get_uint,(ErlNifEnv*, ERL_NIF_TERM term, unsigned* ip));
+ERL_NIF_API_FUNC_DECL(int,enif_get_long,(ErlNifEnv*, ERL_NIF_TERM term, long* ip));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_uint,(ErlNifEnv*, unsigned i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_long,(ErlNifEnv*, long i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_tuple_from_array,(ErlNifEnv*, const ERL_NIF_TERM arr[], unsigned cnt));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_from_array,(ErlNifEnv*, const ERL_NIF_TERM arr[], unsigned cnt));
+ERL_NIF_API_FUNC_DECL(int,enif_is_empty_list,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(ErlNifResourceType*,enif_open_resource_type,(ErlNifEnv*, const char* module_str, const char* name_str, void (*dtor)(ErlNifEnv*,void *), ErlNifResourceFlags flags, ErlNifResourceFlags* tried));
+ERL_NIF_API_FUNC_DECL(void*,enif_alloc_resource,(ErlNifResourceType* type, size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_release_resource,(void* obj));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource,(ErlNifEnv*, void* obj));
+ERL_NIF_API_FUNC_DECL(int,enif_get_resource,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp));
+ERL_NIF_API_FUNC_DECL(size_t,enif_sizeof_resource,(void* obj));
+ERL_NIF_API_FUNC_DECL(unsigned char*,enif_make_new_binary,(ErlNifEnv*,size_t size,ERL_NIF_TERM* termp));
+ERL_NIF_API_FUNC_DECL(int,enif_is_list,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_tuple,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_get_atom_length,(ErlNifEnv*, ERL_NIF_TERM atom, unsigned* len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(int,enif_get_list_length,(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM, enif_make_atom_len,(ErlNifEnv* env, const char* name, size_t len));
+ERL_NIF_API_FUNC_DECL(int, enif_make_existing_atom_len,(ErlNifEnv* env, const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string_len,(ErlNifEnv* env, const char* string, size_t len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ErlNifEnv*,enif_alloc_env,(void));
+ERL_NIF_API_FUNC_DECL(void,enif_free_env,(ErlNifEnv* env));
+ERL_NIF_API_FUNC_DECL(void,enif_clear_env,(ErlNifEnv* env));
+ERL_NIF_API_FUNC_DECL(int,enif_send,(ErlNifEnv* env, const ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_copy,(ErlNifEnv* dst_env, ERL_NIF_TERM src_term));
+ERL_NIF_API_FUNC_DECL(ErlNifPid*,enif_self,(ErlNifEnv* caller_env, ErlNifPid* pid));
+ERL_NIF_API_FUNC_DECL(int,enif_get_local_pid,(ErlNifEnv* env, ERL_NIF_TERM, ErlNifPid* pid));
+ERL_NIF_API_FUNC_DECL(void,enif_keep_resource,(void* obj));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource_binary,(ErlNifEnv*,void* obj,const void* data, size_t size));
+
+/*
+** Add last to keep compatibility on Windows!!!
+*/
+#endif
+
+#ifdef ERL_NIF_API_FUNC_MACRO
+# define enif_priv_data ERL_NIF_API_FUNC_MACRO(enif_priv_data)
+# define enif_alloc ERL_NIF_API_FUNC_MACRO(enif_alloc)
+# define enif_free ERL_NIF_API_FUNC_MACRO(enif_free)
+# define enif_is_atom ERL_NIF_API_FUNC_MACRO(enif_is_atom)
+# define enif_is_binary ERL_NIF_API_FUNC_MACRO(enif_is_binary)
+# define enif_is_ref ERL_NIF_API_FUNC_MACRO(enif_is_ref)
+# define enif_inspect_binary ERL_NIF_API_FUNC_MACRO(enif_inspect_binary)
+# define enif_alloc_binary ERL_NIF_API_FUNC_MACRO(enif_alloc_binary)
+# define enif_realloc_binary ERL_NIF_API_FUNC_MACRO(enif_realloc_binary)
+# define enif_release_binary ERL_NIF_API_FUNC_MACRO(enif_release_binary)
+# define enif_get_int ERL_NIF_API_FUNC_MACRO(enif_get_int)
+# define enif_get_ulong ERL_NIF_API_FUNC_MACRO(enif_get_ulong)
+# define enif_get_double ERL_NIF_API_FUNC_MACRO(enif_get_double)
+# define enif_get_tuple ERL_NIF_API_FUNC_MACRO(enif_get_tuple)
+# define enif_get_list_cell ERL_NIF_API_FUNC_MACRO(enif_get_list_cell)
+# define enif_is_identical ERL_NIF_API_FUNC_MACRO(enif_is_identical)
+# define enif_compare ERL_NIF_API_FUNC_MACRO(enif_compare)
+
+# define enif_make_binary ERL_NIF_API_FUNC_MACRO(enif_make_binary)
+# define enif_make_badarg ERL_NIF_API_FUNC_MACRO(enif_make_badarg)
+# define enif_make_int ERL_NIF_API_FUNC_MACRO(enif_make_int)
+# define enif_make_ulong ERL_NIF_API_FUNC_MACRO(enif_make_ulong)
+# define enif_make_double ERL_NIF_API_FUNC_MACRO(enif_make_double)
+# define enif_make_atom ERL_NIF_API_FUNC_MACRO(enif_make_atom)
+# define enif_make_existing_atom ERL_NIF_API_FUNC_MACRO(enif_make_existing_atom)
+# define enif_make_tuple ERL_NIF_API_FUNC_MACRO(enif_make_tuple)
+# define enif_make_list ERL_NIF_API_FUNC_MACRO(enif_make_list)
+# define enif_make_list_cell ERL_NIF_API_FUNC_MACRO(enif_make_list_cell)
+# define enif_make_string ERL_NIF_API_FUNC_MACRO(enif_make_string)
+# define enif_make_ref ERL_NIF_API_FUNC_MACRO(enif_make_ref)
+
+# define enif_mutex_create ERL_NIF_API_FUNC_MACRO(enif_mutex_create)
+# define enif_mutex_destroy ERL_NIF_API_FUNC_MACRO(enif_mutex_destroy)
+# define enif_mutex_trylock ERL_NIF_API_FUNC_MACRO(enif_mutex_trylock)
+# define enif_mutex_lock ERL_NIF_API_FUNC_MACRO(enif_mutex_lock)
+# define enif_mutex_unlock ERL_NIF_API_FUNC_MACRO(enif_mutex_unlock)
+# define enif_cond_create ERL_NIF_API_FUNC_MACRO(enif_cond_create)
+# define enif_cond_destroy ERL_NIF_API_FUNC_MACRO(enif_cond_destroy)
+# define enif_cond_signal ERL_NIF_API_FUNC_MACRO(enif_cond_signal)
+# define enif_cond_broadcast ERL_NIF_API_FUNC_MACRO(enif_cond_broadcast)
+# define enif_cond_wait ERL_NIF_API_FUNC_MACRO(enif_cond_wait)
+# define enif_rwlock_create ERL_NIF_API_FUNC_MACRO(enif_rwlock_create)
+# define enif_rwlock_destroy ERL_NIF_API_FUNC_MACRO(enif_rwlock_destroy)
+# define enif_rwlock_tryrlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_tryrlock)
+# define enif_rwlock_rlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rlock)
+# define enif_rwlock_runlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_runlock)
+# define enif_rwlock_tryrwlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_tryrwlock)
+# define enif_rwlock_rwlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rwlock)
+# define enif_rwlock_rwunlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rwunlock)
+# define enif_tsd_key_create ERL_NIF_API_FUNC_MACRO(enif_tsd_key_create)
+# define enif_tsd_key_destroy ERL_NIF_API_FUNC_MACRO(enif_tsd_key_destroy)
+# define enif_tsd_set ERL_NIF_API_FUNC_MACRO(enif_tsd_set)
+# define enif_tsd_get ERL_NIF_API_FUNC_MACRO(enif_tsd_get)
+# define enif_thread_opts_create ERL_NIF_API_FUNC_MACRO(enif_thread_opts_create)
+# define enif_thread_opts_destroy ERL_NIF_API_FUNC_MACRO(enif_thread_opts_destroy)
+# define enif_thread_create ERL_NIF_API_FUNC_MACRO(enif_thread_create)
+# define enif_thread_self ERL_NIF_API_FUNC_MACRO(enif_thread_self)
+# define enif_equal_tids ERL_NIF_API_FUNC_MACRO(enif_equal_tids)
+# define enif_thread_exit ERL_NIF_API_FUNC_MACRO(enif_thread_exit)
+# define enif_thread_join ERL_NIF_API_FUNC_MACRO(enif_thread_join)
+
+# define enif_realloc ERL_NIF_API_FUNC_MACRO(enif_realloc)
+# define enif_system_info ERL_NIF_API_FUNC_MACRO(enif_system_info)
+# define enif_fprintf ERL_NIF_API_FUNC_MACRO(enif_fprintf)
+# define enif_inspect_iolist_as_binary ERL_NIF_API_FUNC_MACRO(enif_inspect_iolist_as_binary)
+# define enif_make_sub_binary ERL_NIF_API_FUNC_MACRO(enif_make_sub_binary)
+# define enif_get_string ERL_NIF_API_FUNC_MACRO(enif_get_string)
+# define enif_get_atom ERL_NIF_API_FUNC_MACRO(enif_get_atom)
+# define enif_is_fun ERL_NIF_API_FUNC_MACRO(enif_is_fun)
+# define enif_is_pid ERL_NIF_API_FUNC_MACRO(enif_is_pid)
+# define enif_is_port ERL_NIF_API_FUNC_MACRO(enif_is_port)
+# define enif_get_uint ERL_NIF_API_FUNC_MACRO(enif_get_uint)
+# define enif_get_long ERL_NIF_API_FUNC_MACRO(enif_get_long)
+# define enif_make_uint ERL_NIF_API_FUNC_MACRO(enif_make_uint)
+# define enif_make_long ERL_NIF_API_FUNC_MACRO(enif_make_long)
+# define enif_make_tuple_from_array ERL_NIF_API_FUNC_MACRO(enif_make_tuple_from_array)
+# define enif_make_list_from_array ERL_NIF_API_FUNC_MACRO(enif_make_list_from_array)
+# define enif_is_empty_list ERL_NIF_API_FUNC_MACRO(enif_is_empty_list)
+# define enif_open_resource_type ERL_NIF_API_FUNC_MACRO(enif_open_resource_type)
+# define enif_alloc_resource ERL_NIF_API_FUNC_MACRO(enif_alloc_resource)
+# define enif_release_resource ERL_NIF_API_FUNC_MACRO(enif_release_resource)
+# define enif_make_resource ERL_NIF_API_FUNC_MACRO(enif_make_resource)
+# define enif_get_resource ERL_NIF_API_FUNC_MACRO(enif_get_resource)
+# define enif_sizeof_resource ERL_NIF_API_FUNC_MACRO(enif_sizeof_resource)
+# define enif_make_new_binary ERL_NIF_API_FUNC_MACRO(enif_make_new_binary)
+# define enif_is_list ERL_NIF_API_FUNC_MACRO(enif_is_list)
+# define enif_is_tuple ERL_NIF_API_FUNC_MACRO(enif_is_tuple)
+# define enif_get_atom_length ERL_NIF_API_FUNC_MACRO(enif_get_atom_length)
+# define enif_get_list_length ERL_NIF_API_FUNC_MACRO(enif_get_list_length)
+# define enif_make_atom_len ERL_NIF_API_FUNC_MACRO(enif_make_atom_len)
+# define enif_make_existing_atom_len ERL_NIF_API_FUNC_MACRO(enif_make_existing_atom_len)
+# define enif_make_string_len ERL_NIF_API_FUNC_MACRO(enif_make_string_len)
+# define enif_alloc_env ERL_NIF_API_FUNC_MACRO(enif_alloc_env)
+# define enif_free_env ERL_NIF_API_FUNC_MACRO(enif_free_env)
+# define enif_clear_env ERL_NIF_API_FUNC_MACRO(enif_clear_env)
+# define enif_send ERL_NIF_API_FUNC_MACRO(enif_send)
+# define enif_make_copy ERL_NIF_API_FUNC_MACRO(enif_make_copy)
+# define enif_self ERL_NIF_API_FUNC_MACRO(enif_self)
+# define enif_get_local_pid ERL_NIF_API_FUNC_MACRO(enif_get_local_pid)
+# define enif_keep_resource ERL_NIF_API_FUNC_MACRO(enif_keep_resource)
+# define enif_make_resource_binary ERL_NIF_API_FUNC_MACRO(enif_make_resource_binary)
+#endif
+
+#ifndef enif_make_list1
+# define enif_make_list1(ENV,E1) enif_make_list(ENV,1,E1)
+# define enif_make_list2(ENV,E1,E2) enif_make_list(ENV,2,E1,E2)
+# define enif_make_list3(ENV,E1,E2,E3) enif_make_list(ENV,3,E1,E2,E3)
+# define enif_make_list4(ENV,E1,E2,E3,E4) enif_make_list(ENV,4,E1,E2,E3,E4)
+# define enif_make_list5(ENV,E1,E2,E3,E4,E5) enif_make_list(ENV,5,E1,E2,E3,E4,E5)
+# define enif_make_list6(ENV,E1,E2,E3,E4,E5,E6) enif_make_list(ENV,6,E1,E2,E3,E4,E5,E6)
+# define enif_make_list7(ENV,E1,E2,E3,E4,E5,E6,E7) enif_make_list(ENV,7,E1,E2,E3,E4,E5,E6,E7)
+# define enif_make_list8(ENV,E1,E2,E3,E4,E5,E6,E7,E8) enif_make_list(ENV,8,E1,E2,E3,E4,E5,E6,E7,E8)
+# define enif_make_list9(ENV,E1,E2,E3,E4,E5,E6,E7,E8,E9) enif_make_list(ENV,9,E1,E2,E3,E4,E5,E6,E7,E8,E9)
+# define enif_make_tuple1(ENV,E1) enif_make_tuple(ENV,1,E1)
+# define enif_make_tuple2(ENV,E1,E2) enif_make_tuple(ENV,2,E1,E2)
+# define enif_make_tuple3(ENV,E1,E2,E3) enif_make_tuple(ENV,3,E1,E2,E3)
+# define enif_make_tuple4(ENV,E1,E2,E3,E4) enif_make_tuple(ENV,4,E1,E2,E3,E4)
+# define enif_make_tuple5(ENV,E1,E2,E3,E4,E5) enif_make_tuple(ENV,5,E1,E2,E3,E4,E5)
+# define enif_make_tuple6(ENV,E1,E2,E3,E4,E5,E6) enif_make_tuple(ENV,6,E1,E2,E3,E4,E5,E6)
+# define enif_make_tuple7(ENV,E1,E2,E3,E4,E5,E6,E7) enif_make_tuple(ENV,7,E1,E2,E3,E4,E5,E6,E7)
+# define enif_make_tuple8(ENV,E1,E2,E3,E4,E5,E6,E7,E8) enif_make_tuple(ENV,8,E1,E2,E3,E4,E5,E6,E7,E8)
+# define enif_make_tuple9(ENV,E1,E2,E3,E4,E5,E6,E7,E8,E9) enif_make_tuple(ENV,9,E1,E2,E3,E4,E5,E6,E7,E8,E9)
+
+# define enif_make_pid(ENV, PID) ((const ERL_NIF_TERM)((PID)->pid))
+#endif
+
diff --git a/erts/emulator/test/nif_SUITE_data/nif_api_2_4/README b/erts/emulator/test/nif_SUITE_data/nif_api_2_4/README
new file mode 100644
index 0000000000..7abd0319a6
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_api_2_4/README
@@ -0,0 +1,6 @@
+These are old genuine header files
+checked out from tag OTP_R16B 05f11890bdfec4bfc3a78e191
+
+I choose this API version (2.4) to test, as it's before
+the addition of 'options' in ErlNifEntry and 'flags' in ErlNifFunc
+and without include of generated erl_native_features_config.h.
diff --git a/erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_drv_nif.h b/erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_drv_nif.h
new file mode 100644
index 0000000000..ea013a49a3
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_drv_nif.h
@@ -0,0 +1,48 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Common structures for both erl_driver.h and erl_nif.h
+ */
+
+#ifndef __ERL_DRV_NIF_H__
+#define __ERL_DRV_NIF_H__
+
+typedef struct {
+ int driver_major_version;
+ int driver_minor_version;
+ char *erts_version;
+ char *otp_release;
+ int thread_support;
+ int smp_support;
+ int async_threads;
+ int scheduler_threads;
+ int nif_major_version;
+ int nif_minor_version;
+} ErlDrvSysInfo;
+
+typedef struct {
+ int suggested_stack_size;
+} ErlDrvThreadOpts;
+
+#endif /* __ERL_DRV_NIF_H__ */
+
+
+
+
diff --git a/erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_nif.h b/erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_nif.h
new file mode 100644
index 0000000000..8006741a63
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_nif.h
@@ -0,0 +1,237 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2009-2013. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/* Include file for writers of Native Implemented Functions.
+*/
+
+#ifndef __ERL_NIF_H__
+#define __ERL_NIF_H__
+
+
+#include "erl_drv_nif.h"
+
+/* Version history:
+** 0.1: R13B03
+** 1.0: R13B04
+** 2.0: R14A
+** 2.1: R14B02 "vm_variant"
+** 2.2: R14B03 enif_is_exception
+** 2.3: R15 enif_make_reverse_list, enif_is_number
+** 2.4: R16 enif_consume_timeslice
+*/
+#define ERL_NIF_MAJOR_VERSION 2
+#define ERL_NIF_MINOR_VERSION 4
+
+#include <stdlib.h>
+
+#ifdef SIZEOF_CHAR
+# define SIZEOF_CHAR_SAVED__ SIZEOF_CHAR
+# undef SIZEOF_CHAR
+#endif
+#ifdef SIZEOF_SHORT
+# define SIZEOF_SHORT_SAVED__ SIZEOF_SHORT
+# undef SIZEOF_SHORT
+#endif
+#ifdef SIZEOF_INT
+# define SIZEOF_INT_SAVED__ SIZEOF_INT
+# undef SIZEOF_INT
+#endif
+#ifdef SIZEOF_LONG
+# define SIZEOF_LONG_SAVED__ SIZEOF_LONG
+# undef SIZEOF_LONG
+#endif
+#ifdef SIZEOF_LONG_LONG
+# define SIZEOF_LONG_LONG_SAVED__ SIZEOF_LONG_LONG
+# undef SIZEOF_LONG_LONG
+#endif
+#ifdef HALFWORD_HEAP_EMULATOR
+# define HALFWORD_HEAP_EMULATOR_SAVED__ HALFWORD_HEAP_EMULATOR
+# undef HALFWORD_HEAP_EMULATOR
+#endif
+#include "erl_int_sizes_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
+typedef unsigned __int64 ErlNifUInt64;
+typedef __int64 ErlNifSInt64;
+#elif SIZEOF_LONG == 8
+typedef unsigned long ErlNifUInt64;
+typedef long ErlNifSInt64;
+#elif SIZEOF_LONG_LONG == 8
+typedef unsigned long long ErlNifUInt64;
+typedef long long ErlNifSInt64;
+#else
+#error No 64-bit integer type
+#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"
+# if SIZEOF_LONG == SIZEOF_VOID_P
+typedef unsigned long ERL_NIF_TERM;
+# elif SIZEOF_LONG_LONG == SIZEOF_VOID_P
+typedef unsigned long long ERL_NIF_TERM;
+# endif
+#endif
+
+struct enif_environment_t;
+typedef struct enif_environment_t ErlNifEnv;
+
+typedef struct
+{
+ const char* name;
+ unsigned arity;
+ ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+}ErlNifFunc;
+
+typedef struct enif_entry_t
+{
+ int major;
+ int minor;
+ const char* name;
+ int num_of_funcs;
+ ErlNifFunc* funcs;
+ 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);
+ const char* vm_variant;
+}ErlNifEntry;
+
+
+
+typedef struct
+{
+ size_t size;
+ unsigned char* data;
+
+ /* Internals (avert your eyes) */
+ ERL_NIF_TERM bin_term;
+ void* ref_bin;
+}ErlNifBinary;
+
+typedef struct enif_resource_type_t ErlNifResourceType;
+typedef void ErlNifResourceDtor(ErlNifEnv*, void*);
+typedef enum
+{
+ ERL_NIF_RT_CREATE = 1,
+ ERL_NIF_RT_TAKEOVER = 2
+}ErlNifResourceFlags;
+
+typedef enum
+{
+ ERL_NIF_LATIN1 = 1
+}ErlNifCharEncoding;
+
+typedef struct
+{
+ ERL_NIF_TERM pid; /* internal, may change */
+}ErlNifPid;
+
+typedef ErlDrvSysInfo ErlNifSysInfo;
+
+typedef struct ErlDrvTid_ *ErlNifTid;
+typedef struct ErlDrvMutex_ ErlNifMutex;
+typedef struct ErlDrvCond_ ErlNifCond;
+typedef struct ErlDrvRWLock_ ErlNifRWLock;
+typedef int ErlNifTSDKey;
+
+typedef ErlDrvThreadOpts ErlNifThreadOpts;
+
+#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
+# define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
+typedef struct {
+# include "erl_nif_api_funcs.h"
+} TWinDynNifCallbacks;
+extern TWinDynNifCallbacks WinDynNifCallbacks;
+# undef ERL_NIF_API_FUNC_DECL
+#endif
+
+#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_)) && !defined(STATIC_ERLANG_DRIVER)
+# define ERL_NIF_API_FUNC_MACRO(NAME) (WinDynNifCallbacks.NAME)
+# include "erl_nif_api_funcs.h"
+/* note that we have to keep ERL_NIF_API_FUNC_MACRO defined */
+
+#else /* non windows or included from emulator itself */
+
+# define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) extern RET_TYPE NAME ARGS
+# include "erl_nif_api_funcs.h"
+# undef ERL_NIF_API_FUNC_DECL
+#endif
+
+
+#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
+# define ERL_NIF_INIT_GLOB TWinDynNifCallbacks WinDynNifCallbacks;
+# define ERL_NIF_INIT_DECL(MODNAME) __declspec(dllexport) ErlNifEntry* nif_init(TWinDynNifCallbacks* callbacks)
+# define ERL_NIF_INIT_BODY memcpy(&WinDynNifCallbacks,callbacks,sizeof(TWinDynNifCallbacks))
+#else
+# define ERL_NIF_INIT_GLOB
+# define ERL_NIF_INIT_BODY
+# define ERL_NIF_INIT_DECL(MODNAME) ErlNifEntry* nif_init(void)
+#endif
+
+
+#ifdef __cplusplus
+}
+# define ERL_NIF_INIT_PROLOGUE extern "C" {
+# define ERL_NIF_INIT_EPILOGUE }
+#else
+# define ERL_NIF_INIT_PROLOGUE
+# define ERL_NIF_INIT_EPILOGUE
+#endif
+
+
+#define ERL_NIF_INIT(NAME, FUNCS, LOAD, RELOAD, UPGRADE, UNLOAD) \
+ERL_NIF_INIT_PROLOGUE \
+ERL_NIF_INIT_GLOB \
+ERL_NIF_INIT_DECL(NAME); \
+ERL_NIF_INIT_DECL(NAME) \
+{ \
+ static ErlNifEntry entry = \
+ { \
+ ERL_NIF_MAJOR_VERSION, \
+ ERL_NIF_MINOR_VERSION, \
+ #NAME, \
+ sizeof(FUNCS) / sizeof(*FUNCS), \
+ FUNCS, \
+ LOAD, RELOAD, UPGRADE, UNLOAD, \
+ ERL_NIF_VM_VARIANT \
+ }; \
+ ERL_NIF_INIT_BODY; \
+ return &entry; \
+} \
+ERL_NIF_INIT_EPILOGUE
+
+#if defined(USE_DYNAMIC_TRACE) && (defined(USE_DTRACE) || defined(USE_SYSTEMTAP))
+#define HAVE_USE_DTRACE 1
+#endif
+
+#ifdef HAVE_USE_DTRACE
+ERL_NIF_TERM erl_nif_user_trace_s1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM erl_nif_user_trace_i4s4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM erl_nif_user_trace_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+#endif
+
+#endif /* __ERL_NIF_H__ */
+
diff --git a/erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_nif_api_funcs.h b/erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_nif_api_funcs.h
new file mode 100644
index 0000000000..2f841645e1
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_api_2_4/erl_nif_api_funcs.h
@@ -0,0 +1,503 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2009-2013. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#if !defined(ERL_NIF_API_FUNC_DECL) && !defined(ERL_NIF_API_FUNC_MACRO)
+# error This file should not be included directly
+#endif
+
+/*
+** WARNING: add new ERL_NIF_API_FUNC_DECL entries at the bottom of the list
+** to keep compatibility on Windows!!!
+**
+** And don't forget to increase ERL_NIF_MINOR_VERSION in erl_nif.h
+** when adding functions to the API.
+*/
+#ifdef ERL_NIF_API_FUNC_DECL
+ERL_NIF_API_FUNC_DECL(void*,enif_priv_data,(ErlNifEnv*));
+ERL_NIF_API_FUNC_DECL(void*,enif_alloc,(size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_free,(void* ptr));
+ERL_NIF_API_FUNC_DECL(int,enif_is_atom,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_binary,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_ref,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_inspect_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(int,enif_alloc_binary,(size_t size, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(int,enif_realloc_binary,(ErlNifBinary* bin, size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_release_binary,(ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(int,enif_get_int,(ErlNifEnv*, ERL_NIF_TERM term, int* ip));
+ERL_NIF_API_FUNC_DECL(int,enif_get_ulong,(ErlNifEnv*, ERL_NIF_TERM term, unsigned long* ip));
+ERL_NIF_API_FUNC_DECL(int,enif_get_double,(ErlNifEnv*, ERL_NIF_TERM term, double* dp));
+ERL_NIF_API_FUNC_DECL(int,enif_get_list_cell,(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM* head, ERL_NIF_TERM* tail));
+ERL_NIF_API_FUNC_DECL(int,enif_get_tuple,(ErlNifEnv* env, ERL_NIF_TERM tpl, int* arity, const ERL_NIF_TERM** array));
+ERL_NIF_API_FUNC_DECL(int,enif_is_identical,(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs));
+ERL_NIF_API_FUNC_DECL(int,enif_compare,(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_binary,(ErlNifEnv* env, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_badarg,(ErlNifEnv* env));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int,(ErlNifEnv* env, int i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ulong,(ErlNifEnv* env, unsigned long i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_double,(ErlNifEnv* env, double d));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_atom,(ErlNifEnv* env, const char* name));
+ERL_NIF_API_FUNC_DECL(int,enif_make_existing_atom,(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_tuple,(ErlNifEnv* env, unsigned cnt, ...));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list,(ErlNifEnv* env, unsigned cnt, ...));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_cell,(ErlNifEnv* env, ERL_NIF_TERM car, ERL_NIF_TERM cdr));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string,(ErlNifEnv* env, const char* string, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ref,(ErlNifEnv* env));
+
+ERL_NIF_API_FUNC_DECL(ErlNifMutex*,enif_mutex_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_mutex_destroy,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(int,enif_mutex_trylock,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(void,enif_mutex_lock,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(void,enif_mutex_unlock,(ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(ErlNifCond*,enif_cond_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_destroy,(ErlNifCond *cnd));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_signal,(ErlNifCond *cnd));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_broadcast,(ErlNifCond *cnd));
+ERL_NIF_API_FUNC_DECL(void,enif_cond_wait,(ErlNifCond *cnd, ErlNifMutex *mtx));
+ERL_NIF_API_FUNC_DECL(ErlNifRWLock*,enif_rwlock_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_destroy,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(int,enif_rwlock_tryrlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_runlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(int,enif_rwlock_tryrwlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rwlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rwunlock,(ErlNifRWLock *rwlck));
+ERL_NIF_API_FUNC_DECL(int,enif_tsd_key_create,(char *name, ErlNifTSDKey *key));
+ERL_NIF_API_FUNC_DECL(void,enif_tsd_key_destroy,(ErlNifTSDKey key));
+ERL_NIF_API_FUNC_DECL(void,enif_tsd_set,(ErlNifTSDKey key, void *data));
+ERL_NIF_API_FUNC_DECL(void*,enif_tsd_get,(ErlNifTSDKey key));
+ERL_NIF_API_FUNC_DECL(ErlNifThreadOpts*,enif_thread_opts_create,(char *name));
+ERL_NIF_API_FUNC_DECL(void,enif_thread_opts_destroy,(ErlNifThreadOpts *opts));
+ERL_NIF_API_FUNC_DECL(int,enif_thread_create,(char *name,ErlNifTid *tid,void * (*func)(void *),void *args,ErlNifThreadOpts *opts));
+ERL_NIF_API_FUNC_DECL(ErlNifTid,enif_thread_self,(void));
+ERL_NIF_API_FUNC_DECL(int,enif_equal_tids,(ErlNifTid tid1, ErlNifTid tid2));
+ERL_NIF_API_FUNC_DECL(void,enif_thread_exit,(void *resp));
+ERL_NIF_API_FUNC_DECL(int,enif_thread_join,(ErlNifTid, void **respp));
+
+ERL_NIF_API_FUNC_DECL(void*,enif_realloc,(void* ptr, size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_system_info,(ErlNifSysInfo *sip, size_t si_size));
+ERL_NIF_API_FUNC_DECL(int,enif_fprintf,(void/* FILE* */ *filep, const char *format, ...));
+ERL_NIF_API_FUNC_DECL(int,enif_inspect_iolist_as_binary,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_sub_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, size_t pos, size_t size));
+ERL_NIF_API_FUNC_DECL(int,enif_get_string,(ErlNifEnv*, ERL_NIF_TERM list, char* buf, unsigned len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(int,enif_get_atom,(ErlNifEnv*, ERL_NIF_TERM atom, char* buf, unsigned len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(int,enif_is_fun,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_pid,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_port,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_get_uint,(ErlNifEnv*, ERL_NIF_TERM term, unsigned* ip));
+ERL_NIF_API_FUNC_DECL(int,enif_get_long,(ErlNifEnv*, ERL_NIF_TERM term, long* ip));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_uint,(ErlNifEnv*, unsigned i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_long,(ErlNifEnv*, long i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_tuple_from_array,(ErlNifEnv*, const ERL_NIF_TERM arr[], unsigned cnt));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_from_array,(ErlNifEnv*, const ERL_NIF_TERM arr[], unsigned cnt));
+ERL_NIF_API_FUNC_DECL(int,enif_is_empty_list,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(ErlNifResourceType*,enif_open_resource_type,(ErlNifEnv*, const char* module_str, const char* name_str, void (*dtor)(ErlNifEnv*,void *), ErlNifResourceFlags flags, ErlNifResourceFlags* tried));
+ERL_NIF_API_FUNC_DECL(void*,enif_alloc_resource,(ErlNifResourceType* type, size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_release_resource,(void* obj));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource,(ErlNifEnv*, void* obj));
+ERL_NIF_API_FUNC_DECL(int,enif_get_resource,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp));
+ERL_NIF_API_FUNC_DECL(size_t,enif_sizeof_resource,(void* obj));
+ERL_NIF_API_FUNC_DECL(unsigned char*,enif_make_new_binary,(ErlNifEnv*,size_t size,ERL_NIF_TERM* termp));
+ERL_NIF_API_FUNC_DECL(int,enif_is_list,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_tuple,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_get_atom_length,(ErlNifEnv*, ERL_NIF_TERM atom, unsigned* len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(int,enif_get_list_length,(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM, enif_make_atom_len,(ErlNifEnv* env, const char* name, size_t len));
+ERL_NIF_API_FUNC_DECL(int, enif_make_existing_atom_len,(ErlNifEnv* env, const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string_len,(ErlNifEnv* env, const char* string, size_t len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ErlNifEnv*,enif_alloc_env,(void));
+ERL_NIF_API_FUNC_DECL(void,enif_free_env,(ErlNifEnv* env));
+ERL_NIF_API_FUNC_DECL(void,enif_clear_env,(ErlNifEnv* env));
+ERL_NIF_API_FUNC_DECL(int,enif_send,(ErlNifEnv* env, const ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_copy,(ErlNifEnv* dst_env, ERL_NIF_TERM src_term));
+ERL_NIF_API_FUNC_DECL(ErlNifPid*,enif_self,(ErlNifEnv* caller_env, ErlNifPid* pid));
+ERL_NIF_API_FUNC_DECL(int,enif_get_local_pid,(ErlNifEnv* env, ERL_NIF_TERM, ErlNifPid* pid));
+ERL_NIF_API_FUNC_DECL(void,enif_keep_resource,(void* obj));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource_binary,(ErlNifEnv*,void* obj,const void* data, size_t size));
+#if SIZEOF_LONG != 8
+ERL_NIF_API_FUNC_DECL(int,enif_get_int64,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifSInt64* ip));
+ERL_NIF_API_FUNC_DECL(int,enif_get_uint64,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifUInt64* ip));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int64,(ErlNifEnv*, ErlNifSInt64));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_uint64,(ErlNifEnv*, ErlNifUInt64));
+#endif
+ERL_NIF_API_FUNC_DECL(int,enif_is_exception,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_make_reverse_list,(ErlNifEnv*, ERL_NIF_TERM term, ERL_NIF_TERM *list));
+ERL_NIF_API_FUNC_DECL(int,enif_is_number,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(void*,enif_dlopen,(const char* lib, void (*err_handler)(void*,const char*), void* err_arg));
+ERL_NIF_API_FUNC_DECL(void*,enif_dlsym,(void* handle, const char* symbol, void (*err_handler)(void*,const char*), void* err_arg));
+ERL_NIF_API_FUNC_DECL(int,enif_consume_timeslice,(ErlNifEnv*, int percent));
+
+/*
+** Add new entries here to keep compatibility on Windows!!!
+*/
+#endif
+
+/*
+** Please keep the ERL_NIF_API_FUNC_MACRO list below in the same order
+** as the ERL_NIF_API_FUNC_DECL list above
+*/
+#ifdef ERL_NIF_API_FUNC_MACRO
+# define enif_priv_data ERL_NIF_API_FUNC_MACRO(enif_priv_data)
+# define enif_alloc ERL_NIF_API_FUNC_MACRO(enif_alloc)
+# define enif_free ERL_NIF_API_FUNC_MACRO(enif_free)
+# define enif_is_atom ERL_NIF_API_FUNC_MACRO(enif_is_atom)
+# define enif_is_binary ERL_NIF_API_FUNC_MACRO(enif_is_binary)
+# define enif_is_ref ERL_NIF_API_FUNC_MACRO(enif_is_ref)
+# define enif_inspect_binary ERL_NIF_API_FUNC_MACRO(enif_inspect_binary)
+# define enif_alloc_binary ERL_NIF_API_FUNC_MACRO(enif_alloc_binary)
+# define enif_realloc_binary ERL_NIF_API_FUNC_MACRO(enif_realloc_binary)
+# define enif_release_binary ERL_NIF_API_FUNC_MACRO(enif_release_binary)
+# define enif_get_int ERL_NIF_API_FUNC_MACRO(enif_get_int)
+# define enif_get_ulong ERL_NIF_API_FUNC_MACRO(enif_get_ulong)
+# define enif_get_double ERL_NIF_API_FUNC_MACRO(enif_get_double)
+# define enif_get_tuple ERL_NIF_API_FUNC_MACRO(enif_get_tuple)
+# define enif_get_list_cell ERL_NIF_API_FUNC_MACRO(enif_get_list_cell)
+# define enif_is_identical ERL_NIF_API_FUNC_MACRO(enif_is_identical)
+# define enif_compare ERL_NIF_API_FUNC_MACRO(enif_compare)
+
+# define enif_make_binary ERL_NIF_API_FUNC_MACRO(enif_make_binary)
+# define enif_make_badarg ERL_NIF_API_FUNC_MACRO(enif_make_badarg)
+# define enif_make_int ERL_NIF_API_FUNC_MACRO(enif_make_int)
+# define enif_make_ulong ERL_NIF_API_FUNC_MACRO(enif_make_ulong)
+# define enif_make_double ERL_NIF_API_FUNC_MACRO(enif_make_double)
+# define enif_make_atom ERL_NIF_API_FUNC_MACRO(enif_make_atom)
+# define enif_make_existing_atom ERL_NIF_API_FUNC_MACRO(enif_make_existing_atom)
+# define enif_make_tuple ERL_NIF_API_FUNC_MACRO(enif_make_tuple)
+# define enif_make_list ERL_NIF_API_FUNC_MACRO(enif_make_list)
+# define enif_make_list_cell ERL_NIF_API_FUNC_MACRO(enif_make_list_cell)
+# define enif_make_string ERL_NIF_API_FUNC_MACRO(enif_make_string)
+# define enif_make_ref ERL_NIF_API_FUNC_MACRO(enif_make_ref)
+
+# define enif_mutex_create ERL_NIF_API_FUNC_MACRO(enif_mutex_create)
+# define enif_mutex_destroy ERL_NIF_API_FUNC_MACRO(enif_mutex_destroy)
+# define enif_mutex_trylock ERL_NIF_API_FUNC_MACRO(enif_mutex_trylock)
+# define enif_mutex_lock ERL_NIF_API_FUNC_MACRO(enif_mutex_lock)
+# define enif_mutex_unlock ERL_NIF_API_FUNC_MACRO(enif_mutex_unlock)
+# define enif_cond_create ERL_NIF_API_FUNC_MACRO(enif_cond_create)
+# define enif_cond_destroy ERL_NIF_API_FUNC_MACRO(enif_cond_destroy)
+# define enif_cond_signal ERL_NIF_API_FUNC_MACRO(enif_cond_signal)
+# define enif_cond_broadcast ERL_NIF_API_FUNC_MACRO(enif_cond_broadcast)
+# define enif_cond_wait ERL_NIF_API_FUNC_MACRO(enif_cond_wait)
+# define enif_rwlock_create ERL_NIF_API_FUNC_MACRO(enif_rwlock_create)
+# define enif_rwlock_destroy ERL_NIF_API_FUNC_MACRO(enif_rwlock_destroy)
+# define enif_rwlock_tryrlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_tryrlock)
+# define enif_rwlock_rlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rlock)
+# define enif_rwlock_runlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_runlock)
+# define enif_rwlock_tryrwlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_tryrwlock)
+# define enif_rwlock_rwlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rwlock)
+# define enif_rwlock_rwunlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rwunlock)
+# define enif_tsd_key_create ERL_NIF_API_FUNC_MACRO(enif_tsd_key_create)
+# define enif_tsd_key_destroy ERL_NIF_API_FUNC_MACRO(enif_tsd_key_destroy)
+# define enif_tsd_set ERL_NIF_API_FUNC_MACRO(enif_tsd_set)
+# define enif_tsd_get ERL_NIF_API_FUNC_MACRO(enif_tsd_get)
+# define enif_thread_opts_create ERL_NIF_API_FUNC_MACRO(enif_thread_opts_create)
+# define enif_thread_opts_destroy ERL_NIF_API_FUNC_MACRO(enif_thread_opts_destroy)
+# define enif_thread_create ERL_NIF_API_FUNC_MACRO(enif_thread_create)
+# define enif_thread_self ERL_NIF_API_FUNC_MACRO(enif_thread_self)
+# define enif_equal_tids ERL_NIF_API_FUNC_MACRO(enif_equal_tids)
+# define enif_thread_exit ERL_NIF_API_FUNC_MACRO(enif_thread_exit)
+# define enif_thread_join ERL_NIF_API_FUNC_MACRO(enif_thread_join)
+
+# define enif_realloc ERL_NIF_API_FUNC_MACRO(enif_realloc)
+# define enif_system_info ERL_NIF_API_FUNC_MACRO(enif_system_info)
+# define enif_fprintf ERL_NIF_API_FUNC_MACRO(enif_fprintf)
+# define enif_inspect_iolist_as_binary ERL_NIF_API_FUNC_MACRO(enif_inspect_iolist_as_binary)
+# define enif_make_sub_binary ERL_NIF_API_FUNC_MACRO(enif_make_sub_binary)
+# define enif_get_string ERL_NIF_API_FUNC_MACRO(enif_get_string)
+# define enif_get_atom ERL_NIF_API_FUNC_MACRO(enif_get_atom)
+# define enif_is_fun ERL_NIF_API_FUNC_MACRO(enif_is_fun)
+# define enif_is_pid ERL_NIF_API_FUNC_MACRO(enif_is_pid)
+# define enif_is_port ERL_NIF_API_FUNC_MACRO(enif_is_port)
+# define enif_get_uint ERL_NIF_API_FUNC_MACRO(enif_get_uint)
+# define enif_get_long ERL_NIF_API_FUNC_MACRO(enif_get_long)
+# define enif_make_uint ERL_NIF_API_FUNC_MACRO(enif_make_uint)
+# define enif_make_long ERL_NIF_API_FUNC_MACRO(enif_make_long)
+# define enif_make_tuple_from_array ERL_NIF_API_FUNC_MACRO(enif_make_tuple_from_array)
+# define enif_make_list_from_array ERL_NIF_API_FUNC_MACRO(enif_make_list_from_array)
+# define enif_is_empty_list ERL_NIF_API_FUNC_MACRO(enif_is_empty_list)
+# define enif_open_resource_type ERL_NIF_API_FUNC_MACRO(enif_open_resource_type)
+# define enif_alloc_resource ERL_NIF_API_FUNC_MACRO(enif_alloc_resource)
+# define enif_release_resource ERL_NIF_API_FUNC_MACRO(enif_release_resource)
+# define enif_make_resource ERL_NIF_API_FUNC_MACRO(enif_make_resource)
+# define enif_get_resource ERL_NIF_API_FUNC_MACRO(enif_get_resource)
+# define enif_sizeof_resource ERL_NIF_API_FUNC_MACRO(enif_sizeof_resource)
+# define enif_make_new_binary ERL_NIF_API_FUNC_MACRO(enif_make_new_binary)
+# define enif_is_list ERL_NIF_API_FUNC_MACRO(enif_is_list)
+# define enif_is_tuple ERL_NIF_API_FUNC_MACRO(enif_is_tuple)
+# define enif_get_atom_length ERL_NIF_API_FUNC_MACRO(enif_get_atom_length)
+# define enif_get_list_length ERL_NIF_API_FUNC_MACRO(enif_get_list_length)
+# define enif_make_atom_len ERL_NIF_API_FUNC_MACRO(enif_make_atom_len)
+# define enif_make_existing_atom_len ERL_NIF_API_FUNC_MACRO(enif_make_existing_atom_len)
+# define enif_make_string_len ERL_NIF_API_FUNC_MACRO(enif_make_string_len)
+# define enif_alloc_env ERL_NIF_API_FUNC_MACRO(enif_alloc_env)
+# define enif_free_env ERL_NIF_API_FUNC_MACRO(enif_free_env)
+# define enif_clear_env ERL_NIF_API_FUNC_MACRO(enif_clear_env)
+# define enif_send ERL_NIF_API_FUNC_MACRO(enif_send)
+# define enif_make_copy ERL_NIF_API_FUNC_MACRO(enif_make_copy)
+# define enif_self ERL_NIF_API_FUNC_MACRO(enif_self)
+# define enif_get_local_pid ERL_NIF_API_FUNC_MACRO(enif_get_local_pid)
+# define enif_keep_resource ERL_NIF_API_FUNC_MACRO(enif_keep_resource)
+# define enif_make_resource_binary ERL_NIF_API_FUNC_MACRO(enif_make_resource_binary)
+#if SIZEOF_LONG != 8
+# define enif_get_int64 ERL_NIF_API_FUNC_MACRO(enif_get_int64)
+# define enif_get_uint64 ERL_NIF_API_FUNC_MACRO(enif_get_uint64)
+# define enif_make_int64 ERL_NIF_API_FUNC_MACRO(enif_make_int64)
+# define enif_make_uint64 ERL_NIF_API_FUNC_MACRO(enif_make_uint64)
+#endif
+
+# define enif_is_exception ERL_NIF_API_FUNC_MACRO(enif_is_exception)
+# define enif_make_reverse_list ERL_NIF_API_FUNC_MACRO(enif_make_reverse_list)
+# define enif_is_number ERL_NIF_API_FUNC_MACRO(enif_is_number)
+# define enif_dlopen ERL_NIF_API_FUNC_MACRO(enif_dlopen)
+# define enif_dlsym ERL_NIF_API_FUNC_MACRO(enif_dlsym)
+# define enif_consume_timeslice ERL_NIF_API_FUNC_MACRO(enif_consume_timeslice)
+
+/*
+** Add new entries here
+*/
+#endif
+
+
+#if defined(__GNUC__) && !(defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
+
+/* Inline functions for compile time type checking of arguments to
+ variadic functions.
+*/
+
+# define ERL_NIF_INLINE __inline__
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_tuple1(ErlNifEnv* env,
+ ERL_NIF_TERM e1)
+{
+ return enif_make_tuple(env, 1, e1);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_tuple2(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2)
+{
+ return enif_make_tuple(env, 2, e1, e2);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_tuple3(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3)
+{
+ return enif_make_tuple(env, 3, e1, e2, e3);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_tuple4(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4)
+{
+ return enif_make_tuple(env, 4, e1, e2, e3, e4);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_tuple5(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4,
+ ERL_NIF_TERM e5)
+{
+ return enif_make_tuple(env, 5, e1, e2, e3, e4, e5);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_tuple6(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4,
+ ERL_NIF_TERM e5,
+ ERL_NIF_TERM e6)
+{
+ return enif_make_tuple(env, 6, e1, e2, e3, e4, e5, e6);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_tuple7(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4,
+ ERL_NIF_TERM e5,
+ ERL_NIF_TERM e6,
+ ERL_NIF_TERM e7)
+{
+ return enif_make_tuple(env, 7, e1, e2, e3, e4, e5, e6, e7);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_tuple8(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4,
+ ERL_NIF_TERM e5,
+ ERL_NIF_TERM e6,
+ ERL_NIF_TERM e7,
+ ERL_NIF_TERM e8)
+{
+ return enif_make_tuple(env, 8, e1, e2, e3, e4, e5, e6, e7, e8);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_tuple9(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4,
+ ERL_NIF_TERM e5,
+ ERL_NIF_TERM e6,
+ ERL_NIF_TERM e7,
+ ERL_NIF_TERM e8,
+ ERL_NIF_TERM e9)
+{
+ return enif_make_tuple(env, 9, e1, e2, e3, e4, e5, e6, e7, e8, e9);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_list1(ErlNifEnv* env,
+ ERL_NIF_TERM e1)
+{
+ return enif_make_list(env, 1, e1);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_list2(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2)
+{
+ return enif_make_list(env, 2, e1, e2);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_list3(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3)
+{
+ return enif_make_list(env, 3, e1, e2, e3);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_list4(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4)
+{
+ return enif_make_list(env, 4, e1, e2, e3, e4);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_list5(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4,
+ ERL_NIF_TERM e5)
+{
+ return enif_make_list(env, 5, e1, e2, e3, e4, e5);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_list6(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4,
+ ERL_NIF_TERM e5,
+ ERL_NIF_TERM e6)
+{
+ return enif_make_list(env, 6, e1, e2, e3, e4, e5, e6);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_list7(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4,
+ ERL_NIF_TERM e5,
+ ERL_NIF_TERM e6,
+ ERL_NIF_TERM e7)
+{
+ return enif_make_list(env, 7, e1, e2, e3, e4, e5, e6, e7);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_list8(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4,
+ ERL_NIF_TERM e5,
+ ERL_NIF_TERM e6,
+ ERL_NIF_TERM e7,
+ ERL_NIF_TERM e8)
+{
+ return enif_make_list(env, 8, e1, e2, e3, e4, e5, e6, e7, e8);
+}
+
+static ERL_NIF_INLINE ERL_NIF_TERM enif_make_list9(ErlNifEnv* env,
+ ERL_NIF_TERM e1,
+ ERL_NIF_TERM e2,
+ ERL_NIF_TERM e3,
+ ERL_NIF_TERM e4,
+ ERL_NIF_TERM e5,
+ ERL_NIF_TERM e6,
+ ERL_NIF_TERM e7,
+ ERL_NIF_TERM e8,
+ ERL_NIF_TERM e9)
+{
+ return enif_make_list(env, 9, e1, e2, e3, e4, e5, e6, e7, e8, e9);
+}
+
+# undef ERL_NIF_INLINE
+
+#else /* fallback with macros */
+
+#ifndef enif_make_list1
+# define enif_make_list1(ENV,E1) enif_make_list(ENV,1,E1)
+# define enif_make_list2(ENV,E1,E2) enif_make_list(ENV,2,E1,E2)
+# define enif_make_list3(ENV,E1,E2,E3) enif_make_list(ENV,3,E1,E2,E3)
+# define enif_make_list4(ENV,E1,E2,E3,E4) enif_make_list(ENV,4,E1,E2,E3,E4)
+# define enif_make_list5(ENV,E1,E2,E3,E4,E5) enif_make_list(ENV,5,E1,E2,E3,E4,E5)
+# define enif_make_list6(ENV,E1,E2,E3,E4,E5,E6) enif_make_list(ENV,6,E1,E2,E3,E4,E5,E6)
+# define enif_make_list7(ENV,E1,E2,E3,E4,E5,E6,E7) enif_make_list(ENV,7,E1,E2,E3,E4,E5,E6,E7)
+# define enif_make_list8(ENV,E1,E2,E3,E4,E5,E6,E7,E8) enif_make_list(ENV,8,E1,E2,E3,E4,E5,E6,E7,E8)
+# define enif_make_list9(ENV,E1,E2,E3,E4,E5,E6,E7,E8,E9) enif_make_list(ENV,9,E1,E2,E3,E4,E5,E6,E7,E8,E9)
+# define enif_make_tuple1(ENV,E1) enif_make_tuple(ENV,1,E1)
+# define enif_make_tuple2(ENV,E1,E2) enif_make_tuple(ENV,2,E1,E2)
+# define enif_make_tuple3(ENV,E1,E2,E3) enif_make_tuple(ENV,3,E1,E2,E3)
+# define enif_make_tuple4(ENV,E1,E2,E3,E4) enif_make_tuple(ENV,4,E1,E2,E3,E4)
+# define enif_make_tuple5(ENV,E1,E2,E3,E4,E5) enif_make_tuple(ENV,5,E1,E2,E3,E4,E5)
+# define enif_make_tuple6(ENV,E1,E2,E3,E4,E5,E6) enif_make_tuple(ENV,6,E1,E2,E3,E4,E5,E6)
+# define enif_make_tuple7(ENV,E1,E2,E3,E4,E5,E6,E7) enif_make_tuple(ENV,7,E1,E2,E3,E4,E5,E6,E7)
+# define enif_make_tuple8(ENV,E1,E2,E3,E4,E5,E6,E7,E8) enif_make_tuple(ENV,8,E1,E2,E3,E4,E5,E6,E7,E8)
+# define enif_make_tuple9(ENV,E1,E2,E3,E4,E5,E6,E7,E8,E9) enif_make_tuple(ENV,9,E1,E2,E3,E4,E5,E6,E7,E8,E9)
+#endif
+
+#endif /* __GNUC__ && !WIN32 */
+
+#ifndef enif_make_pid
+
+# define enif_make_pid(ENV, PID) ((const ERL_NIF_TERM)((PID)->pid))
+
+#if SIZEOF_LONG == 8
+# define enif_get_int64 enif_get_long
+# define enif_get_uint64 enif_get_ulong
+# define enif_make_int64 enif_make_long
+# define enif_make_uint64 enif_make_ulong
+#endif
+
+#endif
+
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.1.2_0.c b/erts/emulator/test/nif_SUITE_data/nif_mod.1.2_0.c
new file mode 100644
index 0000000000..a554cc7f25
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.1.2_0.c
@@ -0,0 +1,4 @@
+#include "nif_api_2_0/erl_nif.h"
+
+#define NIF_LIB_VER 1
+#include "nif_mod.c"
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.1.2_4.c b/erts/emulator/test/nif_SUITE_data/nif_mod.1.2_4.c
new file mode 100644
index 0000000000..6d28dbb8ba
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.1.2_4.c
@@ -0,0 +1,4 @@
+#include "nif_api_2_4/erl_nif.h"
+
+#define NIF_LIB_VER 1
+#include "nif_mod.c"
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.2.2_0.c b/erts/emulator/test/nif_SUITE_data/nif_mod.2.2_0.c
new file mode 100644
index 0000000000..0731e6b5d0
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.2.2_0.c
@@ -0,0 +1,4 @@
+#include "nif_api_2_0/erl_nif.h"
+
+#define NIF_LIB_VER 2
+#include "nif_mod.c"
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.2.2_4.c b/erts/emulator/test/nif_SUITE_data/nif_mod.2.2_4.c
new file mode 100644
index 0000000000..628fd42b52
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.2.2_4.c
@@ -0,0 +1,4 @@
+#include "nif_api_2_4/erl_nif.h"
+
+#define NIF_LIB_VER 2
+#include "nif_mod.c"
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.3.2_0.c b/erts/emulator/test/nif_SUITE_data/nif_mod.3.2_0.c
new file mode 100644
index 0000000000..d7e676b668
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.3.2_0.c
@@ -0,0 +1,4 @@
+#include "nif_api_2_0/erl_nif.h"
+
+#define NIF_LIB_VER 3
+#include "nif_mod.c"
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.3.2_4.c b/erts/emulator/test/nif_SUITE_data/nif_mod.3.2_4.c
new file mode 100644
index 0000000000..bdbe8cf381
--- /dev/null
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.3.2_4.c
@@ -0,0 +1,4 @@
+#include "nif_api_2_4/erl_nif.h"
+
+#define NIF_LIB_VER 3
+#include "nif_mod.c"
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.c b/erts/emulator/test/nif_SUITE_data/nif_mod.c
index 4e94e7901c..e6106b6036 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.c
@@ -237,10 +237,22 @@ static ERL_NIF_TERM lib_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
return enif_make_int(env, NIF_LIB_VER);
}
+static ERL_NIF_TERM nif_api_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ /*ADD_CALL("nif_api_version");*/
+ return enif_make_tuple2(env,
+ enif_make_int(env, ERL_NIF_MAJOR_VERSION),
+ enif_make_int(env, ERL_NIF_MINOR_VERSION));
+}
+
static ERL_NIF_TERM get_priv_data_ptr(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
+ NifModPrivData** bin_data;
+ ERL_NIF_TERM res;
ADD_CALL("get_priv_data_ptr");
- return enif_make_uint64(env, (ErlNifUInt64)priv_data(env));
+ bin_data = (NifModPrivData**)enif_make_new_binary(env, sizeof(void*), &res);
+ *bin_data = priv_data(env);
+ return res;
}
static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
@@ -279,6 +291,7 @@ static ERL_NIF_TERM get_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
static ErlNifFunc nif_funcs[] =
{
{"lib_version", 0, lib_version},
+ {"nif_api_version", 0, nif_api_version},
{"get_priv_data_ptr", 0, get_priv_data_ptr},
{"make_new_resource", 2, make_new_resource},
{"get_resource", 2, get_resource}
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.erl b/erts/emulator/test/nif_SUITE_data/nif_mod.erl
index 1fcc33faa4..8019cfcf82 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.erl
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.erl
@@ -22,7 +22,7 @@
-include_lib("common_test/include/ct.hrl").
--export([load_nif_lib/2, load_nif_lib/3, start/0, lib_version/0, call_history/0,
+-export([load_nif_lib/2, load_nif_lib/3, start/0, lib_version/0,
get_priv_data_ptr/0, make_new_resource/2, get_resource/2]).
-export([loop/0, upgrade/1]).
@@ -35,21 +35,32 @@
on_load() ->
[{data_dir, Path}] = ets:lookup(nif_SUITE, data_dir),
[{lib_version, Ver}] = ets:lookup(nif_SUITE, lib_version),
- erlang:load_nif(filename:join(Path,libname(Ver)), []).
+ [{nif_api_version, API}] = ets:lookup(nif_SUITE, nif_api_version),
+ R = erlang:load_nif(filename:join(Path,libname(Ver,API)), []),
+ check_api_version(R, API).
-endif.
+check_api_version(Err, _) when Err =/= ok -> Err;
+check_api_version(ok, []) -> ok;
+check_api_version(ok, [$., MajC, $_ | MinS]) ->
+ {Maj, Min} = {list_to_integer([MajC]), list_to_integer(MinS)},
+ {Maj, Min} = nif_api_version(),
+ ok.
+
load_nif_lib(Config, Ver) ->
load_nif_lib(Config, Ver, []).
load_nif_lib(Config, Ver, LoadInfo) ->
Path = proplists:get_value(data_dir, Config),
- erlang:load_nif(filename:join(Path,libname(Ver)), LoadInfo).
-
-libname(no_init) -> libname(3);
-libname(Ver) when is_integer(Ver) ->
- "nif_mod." ++ integer_to_list(Ver).
+ API = proplists:get_value(nif_api_version, Config, ""),
+ R = erlang:load_nif(filename:join(Path,libname(Ver,API)), LoadInfo),
+ check_api_version(R, API).
+libname(no_init,API) -> libname(3,API);
+libname(Ver,API) when is_integer(Ver) ->
+ "nif_mod." ++ integer_to_list(Ver) ++ API.
+
start() ->
spawn_opt(?MODULE,loop,[],
[link, monitor]).
@@ -72,7 +83,9 @@ upgrade(Pid) ->
lib_version() -> % NIF
undefined.
-call_history() -> ?nif_stub.
+nif_api_version() -> %NIF
+ {undefined,undefined}.
+
get_priv_data_ptr() -> ?nif_stub.
make_new_resource(_,_) -> ?nif_stub.
get_resource(_,_) -> ?nif_stub.
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index 4323849465..d4e77d634a 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.erl
@@ -976,21 +976,21 @@ try_bad_env(Env) ->
%% Test that we can handle a very very large environment gracefully.
huge_env(Config) when is_list(Config) ->
ct:timetrap({minutes, 2}),
- Vars = case os:type() of
- {win32,_} -> 500;
- _ ->
- %% We create a huge environment,
- %% 20000 variables is about 25MB
- %% which seems to be the limit on Linux.
- 20000
- end,
+ {Vars, Cmd} = case os:type() of
+ {win32,_} -> {500, "cmd /q /c ls"};
+ _ ->
+ %% We create a huge environment,
+ %% 20000 variables is about 25MB
+ %% which seems to be the limit on Linux.
+ {20000, "ls"}
+ end,
Env = [{[$a + I div (25*25*25*25) rem 25,
$a + I div (25*25*25) rem 25,
$a + I div (25*25) rem 25,
$a+I div 25 rem 25, $a+I rem 25],
lists:duplicate(100,$a+I rem 25)}
|| I <- lists:seq(1,Vars)],
- try erlang:open_port({spawn,"ls"},[exit_status, {env, Env}]) of
+ try erlang:open_port({spawn,Cmd},[exit_status, {env, Env}]) of
P ->
receive
{P, {exit_status,N}} = M ->
@@ -1009,7 +1009,10 @@ huge_env(Config) when is_list(Config) ->
%% Test to spawn program with command payload buffer
%% just around pipe capacity (9f779819f6bda734c5953468f7798)
pipe_limit_env(Config) when is_list(Config) ->
- Cmd = "true",
+ Cmd = case os:type() of
+ {win32,_} -> "cmd /q /c true";
+ _ -> "true"
+ end,
CmdSize = command_payload_size(Cmd),
Limits = [4096, 16384, 65536], % Try a couple of common pipe buffer sizes
@@ -1026,7 +1029,7 @@ pipe_limit_env_do(Bytes, Cmd, CmdSize) ->
try erlang:open_port({spawn,Cmd},[exit_status, {env, Env}]) of
P ->
receive
- {P, {exit_status,N}} = M ->
+ {P, {exit_status,N}} ->
%% Bug caused exit_status 150 (EINVAL+128)
0 = N
end
diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in
index 0e7193daf9..0990fcf8a7 100644
--- a/erts/etc/unix/etp-commands.in
+++ b/erts/etc/unix/etp-commands.in
@@ -2456,46 +2456,36 @@ define etp-schedulers
if (!erts_initialized)
printf "No schedulers, since system isn't initialized!\n"
else
+ set $sched_type = 0
set $sched_ix = 0
while $sched_ix < erts_no_schedulers
- printf "--- Scheduler %d ---\n", $sched_ix+1
- printf " IX: %d\n", $sched_ix
- if (erts_aligned_scheduler_data[$sched_ix].esd.cpu_id < 0)
- printf " CPU Binding: unbound\n"
- else
- printf " CPU Binding: %d\n", erts_aligned_scheduler_data[$sched_ix].esd.cpu_id
- end
- printf " Aux work Flags:"
- set $aux_work_flags = *((Uint32 *) &erts_aligned_scheduler_data[$sched_ix].esd.ssi->aux_work)
- etp-aux-work-flags $aux_work_flags
- printf " Sleep Info Flags:"
- set $ssi_flags = *((Uint32 *) &erts_aligned_scheduler_data[$sched_ix].esd.ssi->flags)
- etp-ssi-flags $ssi_flags
- printf " Pointer: (ErtsSchedulerData *) %p\n", &erts_aligned_scheduler_data[$sched_ix].esd
- printf " - Run Queue -\n"
- if (etp_smp_compiled)
- set $runq = erts_aligned_scheduler_data[$sched_ix].esd.run_queue
- else
- set $runq = &erts_aligned_run_queues[0].runq
- end
- printf " Length: total=%d", *((Uint32 *) &($runq->len))
- printf ", max=%d", *((Uint32 *) &($runq->procs.prio_info[0].len))
- printf ", high=%d", *((Uint32 *) &($runq->procs.prio_info[1].len))
- printf ", normal=%d", *((Uint32 *) &($runq->procs.prio_info[2].len))
- printf ", low=%d", *((Uint32 *) &($runq->procs.prio_info[3].len))
- printf ", port=%d\n", *((Uint32 *) &($runq->ports.info.len))
- if ($runq->misc.start)
- printf " Misc Jobs: yes\n"
- else
- printf " Misc Jobs: no\n"
- end
- set $rq_flags = *((Uint32 *) &($runq->flags))
- etp-rq-flags-int $rq_flags
- printf " Pointer: (ErtsRunQueue *) %p\n", $runq
-
+ etp-scheduler-info-internal
+ etp-run-queue-info-internal
set $sched_ix++
end
- printf "-------------------\n",
+ printf "---------------------\n"
+ if (erts_no_dirty_cpu_schedulers)
+ printf "\n\n"
+ set $sched_type = 1
+ set $sched_ix = 0
+ while $sched_ix < erts_no_dirty_cpu_schedulers
+ etp-scheduler-info-internal
+ set $sched_ix++
+ end
+ etp-run-queue-info-internal
+ printf "---------------------\n"
+ end
+ if (erts_no_dirty_io_schedulers)
+ printf "\n\n"
+ set $sched_type = 2
+ set $sched_ix = 0
+ while $sched_ix < erts_no_dirty_io_schedulers
+ etp-scheduler-info-internal
+ set $sched_ix++
+ end
+ etp-run-queue-info-internal
+ printf "---------------------\n"
+ end
end
end
@@ -2507,6 +2497,67 @@ document etp-schedulers
%---------------------------------------------------------------------------
end
+define etp-scheduler-info-internal
+ if ($sched_type == 0)
+ printf "--- Scheduler %d ---\n", $sched_ix+1
+ set $sched_data=&erts_aligned_scheduler_data[$sched_ix].esd
+ else
+ if ($sched_type == 1)
+ printf "--- Dirty CPU Scheduler %d ---\n", $sched_ix+1
+ set $sched_data=&erts_aligned_dirty_cpu_scheduler_data[$sched_ix].esd
+ else
+ printf "--- Dirty I/O Scheduler %d ---\n", $sched_ix+1
+ set $sched_data=&erts_aligned_dirty_io_scheduler_data[$sched_ix].esd
+ end
+ end
+ printf " IX: %d\n", $sched_ix
+ if ($sched_data->cpu_id < 0)
+ printf " CPU Binding: unbound\n"
+ else
+ printf " CPU Binding: %d\n", $sched_data->cpu_id
+ end
+ printf " Aux work Flags:"
+ set $aux_work_flags = *((Uint32 *) &$sched_data->ssi->aux_work)
+ etp-aux-work-flags $aux_work_flags
+ printf " Sleep Info Flags:"
+ set $ssi_flags = *((Uint32 *) &$sched_data->ssi->flags)
+ etp-ssi-flags $ssi_flags
+ printf " Pointer: (ErtsSchedulerData *) %p\n", $sched_data
+end
+
+define etp-run-queue-info-internal
+ if ($sched_type == 0)
+ printf " - Run Queue -\n"
+ if (etp_smp_compiled)
+ set $runq = erts_aligned_scheduler_data[$sched_ix].esd.run_queue
+ else
+ set $runq = &erts_aligned_run_queues[0].runq
+ end
+ else
+ if ($sched_type == 1)
+ printf "\n--- Dirty CPU Run Queue ---\n"
+ set $runq = &erts_aligned_run_queues[-1].runq
+ else
+ printf "\n--- Dirty I/O Run Queue ---\n"
+ set $runq = &erts_aligned_run_queues[-2].runq
+ end
+ end
+ printf " Length: total=%d", *((Uint32 *) &($runq->len))
+ printf ", max=%d", *((Uint32 *) &($runq->procs.prio_info[0].len))
+ printf ", high=%d", *((Uint32 *) &($runq->procs.prio_info[1].len))
+ printf ", normal=%d", *((Uint32 *) &($runq->procs.prio_info[2].len))
+ printf ", low=%d", *((Uint32 *) &($runq->procs.prio_info[3].len))
+ printf ", port=%d\n", *((Uint32 *) &($runq->ports.info.len))
+ if ($runq->misc.start)
+ printf " Misc Jobs: yes\n"
+ else
+ printf " Misc Jobs: no\n"
+ end
+ set $rq_flags = *((Uint32 *) &($runq->flags))
+ etp-rq-flags-int $rq_flags
+ printf " Pointer: (ErtsRunQueue *) %p\n", $runq
+
+
define etp-disasm-1
set $code_ptr = ((BeamInstr*)$arg0)
set $addr = *$code_ptr
diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c
index 6a92e18648..a997297f65 100644
--- a/erts/etc/unix/run_erl.c
+++ b/erts/etc/unix/run_erl.c
@@ -863,7 +863,7 @@ static int open_log(int log_num, int flags)
if (write_all(lfd, buf, strlen(buf)) < 0)
status("Error in writing to log.\n");
-#if USE_FSYNC
+#ifdef USE_FSYNC
fsync(lfd);
#endif
@@ -893,7 +893,7 @@ static void write_to_log(int* lfd, int* log_num, char* buf, int len)
status("Error in writing to log.\n");
}
-#if USE_FSYNC
+#ifdef USE_FSYNC
fsync(*lfd);
#endif
}
diff --git a/erts/include/internal/erl_printf.h b/erts/include/internal/erl_printf.h
index c4565dfafc..f180a53f18 100644
--- a/erts/include/internal/erl_printf.h
+++ b/erts/include/internal/erl_printf.h
@@ -41,12 +41,18 @@ struct erts_dsprintf_buf_t_ {
#define ERTS_DSPRINTF_BUF_INITER(GFUNC) {NULL, 0, 0, (GFUNC)}
+typedef int (*fmtfn_t)(void*, char*, size_t);
+
+int erts_write_fd(void *vfdp, char* buf, size_t len);
+int erts_write_ds(void *vdsbufp, char* buf, size_t len);
+
int erts_printf(const char *, ...);
int erts_fprintf(FILE *, const char *, ...);
int erts_fdprintf(int, const char *, ...);
int erts_sprintf(char *, const char *, ...);
int erts_snprintf(char *, size_t, const char *, ...);
int erts_dsprintf(erts_dsprintf_buf_t *, const char *, ...);
+int erts_cbprintf(fmtfn_t, void*, const char*, ...);
int erts_vprintf(const char *, va_list);
int erts_vfprintf(FILE *, const char *, va_list);
@@ -54,5 +60,6 @@ int erts_vfdprintf(int, const char *, va_list);
int erts_vsprintf(char *, const char *, va_list);
int erts_vsnprintf(char *, size_t, const char *, va_list);
int erts_vdsprintf(erts_dsprintf_buf_t *, const char *, va_list);
+int erts_vcbprintf(fmtfn_t, void*, const char*, va_list);
#endif /* #ifndef ERL_PRINTF_H_ */
diff --git a/erts/include/internal/erl_printf_format.h b/erts/include/internal/erl_printf_format.h
index 4f969bdbcb..56ec032bd1 100644
--- a/erts/include/internal/erl_printf_format.h
+++ b/erts/include/internal/erl_printf_format.h
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include "erl_int_sizes_config.h"
+#include "erl_printf.h"
#if SIZEOF_VOID_P == SIZEOF_LONG
typedef unsigned long ErlPfUWord;
@@ -44,8 +45,6 @@ typedef long long ErlPfSWord;
#error Found no appropriate type to use for 'Eterm', 'Uint' and 'Sint'
#endif
-typedef int (*fmtfn_t)(void*, char*, size_t);
-
extern int erts_printf_format(fmtfn_t, void*, char*, va_list);
extern int erts_printf_char(fmtfn_t, void*, char);
diff --git a/erts/lib_src/common/erl_printf.c b/erts/lib_src/common/erl_printf.c
index b5e90dfeef..7781fc2196 100644
--- a/erts/lib_src/common/erl_printf.c
+++ b/erts/lib_src/common/erl_printf.c
@@ -165,8 +165,8 @@ write_f(void *vfp, char* buf, size_t len)
return len;
}
-static int
-write_fd(void *vfdp, char* buf, size_t len)
+int
+erts_write_fd(void *vfdp, char* buf, size_t len)
{
ssize_t size;
size_t res = len;
@@ -226,8 +226,8 @@ write_sn(void *vwsnap, char* buf, size_t len)
return rv;
}
-static int
-write_ds(void *vdsbufp, char* buf, size_t len)
+int
+erts_write_ds(void *vdsbufp, char* buf, size_t len)
{
erts_dsprintf_buf_t *dsbufp = (erts_dsprintf_buf_t *) vdsbufp;
size_t need_len = len + 1; /* Also trailing '\0' */
@@ -301,7 +301,7 @@ erts_fdprintf(int fd, const char *format, ...)
va_list arglist;
va_start(arglist, format);
errno = 0;
- res = erts_printf_format(write_fd,(void *)&fd,(char *)format,arglist);
+ res = erts_printf_format(erts_write_fd,(void *)&fd,(char *)format,arglist);
va_end(arglist);
return res;
}
@@ -355,7 +355,7 @@ erts_dsprintf(erts_dsprintf_buf_t *dsbufp, const char *format, ...)
return -EINVAL;
va_start(arglist, format);
errno = 0;
- res = erts_printf_format(write_ds, (void *)dsbufp, (char *)format, arglist);
+ res = erts_printf_format(erts_write_ds, (void *)dsbufp, (char *)format, arglist);
if (dsbufp->str) {
if (res < 0)
dsbufp->str[0] = '\0';
@@ -366,6 +366,20 @@ erts_dsprintf(erts_dsprintf_buf_t *dsbufp, const char *format, ...)
return res;
}
+/*
+ * Callback printf
+ */
+int erts_cbprintf(fmtfn_t cb_fn, void* cb_arg, const char* format, ...)
+{
+ int res;
+ va_list arglist;
+ va_start(arglist, format);
+ errno = 0;
+ res = erts_printf_format(cb_fn, cb_arg, (char *)format, arglist);
+ va_end(arglist);
+ return res;
+}
+
int
erts_vprintf(const char *format, va_list arglist)
{
@@ -411,7 +425,7 @@ erts_vfdprintf(int fd, const char *format, va_list arglist)
{
int res;
errno = 0;
- res = erts_printf_format(write_fd,(void *)&fd,(char *)format,arglist);
+ res = erts_printf_format(erts_write_fd,(void *)&fd,(char *)format,arglist);
return res;
}
@@ -456,7 +470,7 @@ erts_vdsprintf(erts_dsprintf_buf_t *dsbufp, const char *format, va_list arglist)
if (!dsbufp)
return -EINVAL;
errno = 0;
- res = erts_printf_format(write_ds, (void *)dsbufp, (char *)format, arglist);
+ res = erts_printf_format(erts_write_ds, (void *)dsbufp, (char *)format, arglist);
if (dsbufp->str) {
if (res < 0)
dsbufp->str[0] = '\0';
@@ -465,3 +479,10 @@ erts_vdsprintf(erts_dsprintf_buf_t *dsbufp, const char *format, va_list arglist)
}
return res;
}
+
+int
+erts_vcbprintf(fmtfn_t cb_fn, void* cb_arg, const char *format, va_list arglist)
+{
+ errno = 0;
+ return erts_printf_format(cb_fn, cb_arg, (char *)format, arglist);
+}
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index 796cbd74c5..64d1a70e61 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 fa5960dffd..8247c399a4 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam
index 0a78c5b6c3..aae3976298 100644
--- a/erts/preloaded/ebin/erts_internal.beam
+++ b/erts/preloaded/ebin/erts_internal.beam
Binary files differ
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index b3ec73a60e..1d09aeded9 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -555,17 +555,18 @@ efile_gm_get(Paths, Mod, ParentRef, Process) ->
efile_gm_get_1([P|Ps], File0, Mod, {Parent,Ref}=PR, Process) ->
File = join(P, File0),
- Res = try prim_file:read_file(File) of
- {ok,Bin} ->
- gm_process(Mod, File, Bin, Process);
- Error ->
- _ = check_file_result(get_modules, File, Error),
- efile_gm_get_1(Ps, File0, Mod, PR, Process)
- catch
- _:Reason ->
- {error,{crash,Reason}}
- end,
- Parent ! {Ref,Mod,Res};
+ try prim_file:read_file(File) of
+ {ok,Bin} ->
+ Res = gm_process(Mod, File, Bin, Process),
+ Parent ! {Ref,Mod,Res};
+ Error ->
+ _ = check_file_result(get_modules, File, Error),
+ efile_gm_get_1(Ps, File0, Mod, PR, Process)
+ catch
+ _:Reason ->
+ Res = {error,{crash,Reason}},
+ Parent ! {Ref,Mod,Res}
+ end;
efile_gm_get_1([], _, Mod, {Parent,Ref}, _Process) ->
Parent ! {Ref,Mod,{error,enoent}}.
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index da08ab383b..15c3e01653 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -983,9 +983,10 @@ get_keys(_Val) ->
erlang:nif_error(undefined).
%% get_module_info/1
--spec erlang:get_module_info(P1) -> [{atom(), [{atom(), term()}]}] when
- P1 :: atom().
-get_module_info(_P1) ->
+-spec erlang:get_module_info(Module) -> [{Item, term()}] when
+ Item :: module | exports | attributes | compile | native | md5,
+ Module :: atom().
+get_module_info(_Module) ->
erlang:nif_error(undefined).
%% get_stacktrace/0
@@ -1882,10 +1883,12 @@ element(_N, _Tuple) ->
erlang:nif_error(undefined).
%% Not documented
+-type module_info_key() :: attributes | compile | exports | functions | md5
+ | module | native | native_addresses.
-spec erlang:get_module_info(Module, Item) -> ModuleInfo when
Module :: atom(),
- Item :: module | exports | functions | attributes | compile | native_addresses | md5,
- ModuleInfo :: atom() | [] | [{atom(), arity()}] | [{atom(), term()}] | [{atom(), arity(), integer()}].
+ Item :: module_info_key(),
+ ModuleInfo :: term().
get_module_info(_Module, _Item) ->
erlang:nif_error(undefined).
@@ -2428,10 +2431,11 @@ term_to_binary(_Term, _Options) ->
tl(_List) ->
erlang:nif_error(undefined).
+-type match_variable() :: atom(). % Approximation of '$1' | '$2' | ...
-type trace_pattern_mfa() ::
{atom(),atom(),arity() | '_'} | on_load.
-type trace_match_spec() ::
- [{[term()] | '_' ,[term()],[term()]}].
+ [{[term()] | '_' | match_variable() ,[term()],[term()]}].
-spec erlang:trace_pattern(MFA, MatchSpec) -> non_neg_integer() when
MFA :: trace_pattern_mfa() | send | 'receive',
diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl
index fecdfc348c..a27cb2ba38 100644
--- a/erts/preloaded/src/erts_internal.erl
+++ b/erts/preloaded/src/erts_internal.erl
@@ -436,10 +436,11 @@ microstate_accounting(Ref, Threads) ->
trace(_PidSpec, _How, _FlagList) ->
erlang:nif_error(undefined).
+-type match_variable() :: atom(). % Approximation of '$1' | '$2' | ...
-type trace_pattern_mfa() ::
{atom(),atom(),arity() | '_'} | on_load.
-type trace_match_spec() ::
- [{[term()] | '_' ,[term()],[term()]}].
+ [{[term()] | '_' | match_variable() ,[term()],[term()]}].
-spec trace_pattern(MFA, MatchSpec, FlagList) -> non_neg_integer() when
MFA :: trace_pattern_mfa(),
diff --git a/erts/vsn.mk b/erts/vsn.mk
index ad9148f61f..317d731cd7 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 8.1
+VSN = 8.1.1
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff --git a/lib/common_test/src/Makefile b/lib/common_test/src/Makefile
index 0f9e044f9e..9d751996ad 100644
--- a/lib/common_test/src/Makefile
+++ b/lib/common_test/src/Makefile
@@ -80,6 +80,7 @@ MODULES= \
ct_groups \
ct_property_test \
ct_release_test \
+ ct_default_gl \
erl2html2 \
test_server_ctrl \
test_server_gl \
diff --git a/lib/common_test/src/ct_default_gl.erl b/lib/common_test/src/ct_default_gl.erl
new file mode 100644
index 0000000000..d1b52e5f4f
--- /dev/null
+++ b/lib/common_test/src/ct_default_gl.erl
@@ -0,0 +1,83 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ct_default_gl).
+-export([start_link/1, stop/0]).
+
+-export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2]).
+
+%% start_link()
+%% Start a new group leader process.
+start_link(ParentGL) ->
+ do_start(ParentGL, 3).
+
+do_start(_ParentGL, 0) ->
+ exit({?MODULE,startup});
+do_start(ParentGL, Retries) ->
+ case whereis(?MODULE) of
+ undefined ->
+ case gen_server:start_link(?MODULE, [ParentGL], []) of
+ {ok,Pid} ->
+ {ok,Pid};
+ Other ->
+ Other
+ end;
+ Pid ->
+ exit(Pid, kill),
+ timer:sleep(1000),
+ do_start(ParentGL, Retries-1)
+ end.
+
+%% stop(Pid)
+%% Stop a group leader process.
+stop() ->
+ gen_server:cast(whereis(?MODULE), stop).
+
+
+%%% Internal functions.
+
+init([ParentGL]) ->
+ register(?MODULE, self()),
+ {ok,#{parent_gl_pid => ParentGL,
+ parent_gl_monitor => erlang:monitor(process,ParentGL)}}.
+
+handle_cast(stop, St) ->
+ {stop,normal,St}.
+
+%% If the parent group leader dies, fall back on using the local user process
+handle_info({'DOWN',Ref,process,_,_Reason}, #{parent_gl_monitor := Ref} = St) ->
+ User = whereis(user),
+ {noreply,St#{parent_gl_pid => User,
+ parent_gl_monitor => erlang:monitor(process,User)}};
+
+handle_info({io_request,_From,_ReplyAs,_Req} = IoReq,
+ #{parent_gl_pid := ParentGL} = St) ->
+ ParentGL ! IoReq,
+ {noreply,St};
+
+handle_info(Msg, St) ->
+ io:format(user, "Common Test Group Leader process got: ~tp~n", [Msg]),
+ {noreply,St}.
+
+handle_call(_Req, _From, St) ->
+ {reply,ok,St}.
+
+terminate(_, _) ->
+ ok.
diff --git a/lib/common_test/src/ct_framework.erl b/lib/common_test/src/ct_framework.erl
index 104515e57e..291a4d716c 100644
--- a/lib/common_test/src/ct_framework.erl
+++ b/lib/common_test/src/ct_framework.erl
@@ -307,7 +307,7 @@ add_defaults(Mod,Func, GroupPath) ->
"~w:suite/0 failed: ~p~n",
[Suite,Reason]),
io:format(ErrStr, []),
- io:format(user, ErrStr, []),
+ io:format(?def_gl, ErrStr, []),
{suite0_failed,{exited,Reason}};
SuiteInfo when is_list(SuiteInfo) ->
case lists:all(fun(E) when is_tuple(E) -> true;
@@ -330,7 +330,7 @@ add_defaults(Mod,Func, GroupPath) ->
"~w:suite/0: ~p~n",
[Suite,SuiteInfo]),
io:format(ErrStr, []),
- io:format(user, ErrStr, []),
+ io:format(?def_gl, ErrStr, []),
{suite0_failed,bad_return_value}
end;
SuiteInfo ->
@@ -338,7 +338,7 @@ add_defaults(Mod,Func, GroupPath) ->
"Invalid return value from "
"~w:suite/0: ~p~n", [Suite,SuiteInfo]),
io:format(ErrStr, []),
- io:format(user, ErrStr, []),
+ io:format(?def_gl, ErrStr, []),
{suite0_failed,bad_return_value}
end.
@@ -366,7 +366,7 @@ add_defaults1(Mod,Func, GroupPath, SuiteInfo) ->
"~w:group(~w): ~p~n",
[Mod,GrName,BadGr0Val]),
io:format(Gr0ErrStr, []),
- io:format(user, Gr0ErrStr, []),
+ io:format(?def_gl, Gr0ErrStr, []),
{group0_failed,bad_return_value};
_ ->
Args = if Func == init_per_group ; Func == end_per_group ->
@@ -388,7 +388,7 @@ add_defaults1(Mod,Func, GroupPath, SuiteInfo) ->
"~w:~w/0: ~p~n",
[Mod,Func,BadTC0Val]),
io:format(TC0ErrStr, []),
- io:format(user, TC0ErrStr, []),
+ io:format(?def_gl, TC0ErrStr, []),
{testcase0_failed,bad_return_value};
_ ->
%% let test case info (also for all config funcs) override
@@ -927,7 +927,7 @@ error_notification(Mod,Func,_Args,{Error,Loc}) ->
Div = "~n- - - - - - - - - - - - - - - - - - - "
"- - - - - - - - - - - - - - - - - - - - -~n",
ErrorStr2 = io_lib:format(ErrorFormat, ErrorArgs),
- io:format(user, lists:concat([Div,ErrorStr2,Div,"~n"]),
+ io:format(?def_gl, lists:concat([Div,ErrorStr2,Div,"~n"]),
[]),
Link =
"\n\n<a href=\"#end\">"
@@ -1133,7 +1133,7 @@ get_all(Mod, ConfTests) ->
ErrStr = io_lib:format("~n*** ERROR *** "
"~w:all/0 failed: ~p~n",
[Mod,ExitReason]),
- io:format(user, ErrStr, []),
+ io:format(?def_gl, ErrStr, []),
%% save the error info so it doesn't get printed twice
ct_util:set_testdata_async({{error_in_suite,Mod},
ExitReason});
diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl
index 9282a9f81d..0daed60dba 100644
--- a/lib/common_test/src/ct_logs.erl
+++ b/lib/common_test/src/ct_logs.erl
@@ -531,8 +531,13 @@ tc_print(Category,Importance,Format,Args) ->
Val
end,
if Importance >= (100-VLvl) ->
- Head = get_heading(Category),
- io:format(user, lists:concat([Head,Format,"\n\n"]), Args),
+ Str = lists:concat([get_heading(Category),Format,"\n\n"]),
+ try
+ io:format(?def_gl, Str, Args)
+ catch
+ %% default group leader probably not started, or has stopped
+ _:_ -> io:format(user, Str, Args)
+ end,
ok;
true ->
ok
@@ -679,7 +684,7 @@ logger(Parent, Mode, Verbosity) ->
PrivFilesDestRun = [filename:join(AbsDir, F) || F <- PrivFiles],
case copy_priv_files(PrivFilesSrc, PrivFilesDestTop) of
{error,Src1,Dest1,Reason1} ->
- io:format(user, "ERROR! "++
+ io:format(?def_gl, "ERROR! "++
"Priv file ~p could not be copied to ~p. "++
"Reason: ~p~n",
[Src1,Dest1,Reason1]),
@@ -687,7 +692,7 @@ logger(Parent, Mode, Verbosity) ->
ok ->
case copy_priv_files(PrivFilesSrc, PrivFilesDestRun) of
{error,Src2,Dest2,Reason2} ->
- io:format(user,
+ io:format(?def_gl,
"ERROR! "++
"Priv file ~p could not be copied to ~p. "
++"Reason: ~p~n",
diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl
index fbb9c7ab60..a049ef5695 100644
--- a/lib/common_test/src/ct_run.erl
+++ b/lib/common_test/src/ct_run.erl
@@ -2155,8 +2155,8 @@ continue(_MakeErrors, true) ->
false;
continue(_MakeErrors, _AbortIfMissingSuites) ->
io:nl(),
- OldGl = group_leader(),
- case set_group_leader_same_as_shell() of
+ OldGL = group_leader(),
+ case set_group_leader_same_as_shell(OldGL) of
true ->
S = self(),
io:format("Failed to compile or locate one "
@@ -2172,7 +2172,7 @@ continue(_MakeErrors, _AbortIfMissingSuites) ->
S ! false
end
end),
- group_leader(OldGl, self()),
+ group_leader(OldGL, self()),
receive R when R==true; R==false ->
R
after 15000 ->
@@ -2184,7 +2184,9 @@ continue(_MakeErrors, _AbortIfMissingSuites) ->
true
end.
-set_group_leader_same_as_shell() ->
+set_group_leader_same_as_shell(OldGL) ->
+ %% find the group leader process on the node in a dirty fashion
+ %% (check initial function call and look in the process dictionary)
GS2or3 = fun(P) ->
case process_info(P,initial_call) of
{initial_call,{group,server,X}} when X == 2 ; X == 3 ->
@@ -2197,7 +2199,10 @@ set_group_leader_same_as_shell() ->
true == lists:keymember(shell,1,
element(2,process_info(P,dictionary)))] of
[GL|_] ->
- group_leader(GL, self());
+ %% check if started from remote node (skip interaction)
+ if node(OldGL) /= node(GL) -> false;
+ true -> group_leader(GL, self())
+ end;
[] ->
false
end.
diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl
index 82a8743cf0..4d3a2ae7e3 100644
--- a/lib/common_test/src/ct_util.erl
+++ b/lib/common_test/src/ct_util.erl
@@ -188,6 +188,8 @@ do_start(Parent, Mode, LogDir, Verbosity) ->
ok
end,
+ ct_default_gl:start_link(group_leader()),
+
{StartTime,TestLogDir} = ct_logs:init(Mode, Verbosity),
ct_event:notify(#event{name=test_start,
@@ -474,6 +476,7 @@ loop(Mode,TestData,StartDir) ->
ct_logs:close(Info, StartDir),
ct_event:stop(),
ct_config:stop(),
+ ct_default_gl:stop(),
ok = file:set_cwd(StartDir),
return(From, Info);
{Ref, _Msg} when is_reference(Ref) ->
@@ -926,7 +929,8 @@ warn_duplicates(Suites) ->
[] ->
ok;
_ ->
- io:format(user,"~nWARNING! Deprecated function: ~w:sequences/0.~n"
+ io:format(?def_gl,
+ "~nWARNING! Deprecated function: ~w:sequences/0.~n"
" Use group with sequence property instead.~n",[Mod])
end
end,
@@ -980,12 +984,12 @@ get_profile_data(Profile, Key, StartDir) ->
end,
case Result of
{error,enoent} when Profile /= default ->
- io:format(user, "~nERROR! Missing profile file ~p~n", [File]),
+ io:format(?def_gl, "~nERROR! Missing profile file ~p~n", [File]),
undefined;
{error,enoent} when Profile == default ->
undefined;
{error,Reason} ->
- io:format(user,"~nERROR! Error in profile file ~p: ~p~n",
+ io:format(?def_gl,"~nERROR! Error in profile file ~p: ~p~n",
[WhichFile,Reason]),
undefined;
{ok,Data} ->
@@ -995,7 +999,7 @@ get_profile_data(Profile, Key, StartDir) ->
_ when is_list(Data) ->
Data;
_ ->
- io:format(user,
+ io:format(?def_gl,
"~nERROR! Invalid profile data in ~p~n",
[WhichFile]),
[]
@@ -1082,10 +1086,10 @@ open_url(iexplore, Args, URL) ->
Path = proplists:get_value(default, Paths),
[Cmd | _] = string:tokens(Path, "%"),
Cmd1 = Cmd ++ " " ++ Args ++ " " ++ URL,
- io:format(user, "~nOpening ~ts with command:~n ~ts~n", [URL,Cmd1]),
+ io:format(?def_gl, "~nOpening ~ts with command:~n ~ts~n", [URL,Cmd1]),
open_port({spawn,Cmd1}, []);
_ ->
- io:format("~nNo path to iexplore.exe~n",[])
+ io:format(?def_gl, "~nNo path to iexplore.exe~n",[])
end,
win32reg:close(R),
ok;
@@ -1095,6 +1099,6 @@ open_url(Prog, Args, URL) ->
is_list(Prog) -> Prog
end,
Cmd = ProgStr ++ " " ++ Args ++ " " ++ URL,
- io:format(user, "~nOpening ~ts with command:~n ~ts~n", [URL,Cmd]),
+ io:format(?def_gl, "~nOpening ~ts with command:~n ~ts~n", [URL,Cmd]),
open_port({spawn,Cmd},[]),
ok.
diff --git a/lib/common_test/src/ct_util.hrl b/lib/common_test/src/ct_util.hrl
index d7efa26863..039c8168ec 100644
--- a/lib/common_test/src/ct_util.hrl
+++ b/lib/common_test/src/ct_util.hrl
@@ -23,6 +23,7 @@
-define(board_table,ct_boards).
-define(suite_table,ct_suite_data).
-define(verbosity_table,ct_verbosity_table).
+-define(def_gl, ct_default_gl).
-record(conn, {handle,
targetref,
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index b5ca6c3c49..c37f731d8c 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -49,7 +49,6 @@ MODULES = \
beam_a \
beam_asm \
beam_block \
- beam_bool \
beam_bs \
beam_bsm \
beam_clean \
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
deleted file mode 100644
index 99e4ccb1e9..0000000000
--- a/lib/compiler/src/beam_bool.erl
+++ /dev/null
@@ -1,765 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% Purpose: Optimizes booleans in guards.
-
--module(beam_bool).
-
--export([module/2]).
-
--import(lists, [reverse/1,reverse/2,foldl/3,mapfoldl/3,map/2]).
-
--record(st,
- {next, %Next label number.
- ll %Live regs at labels.
- }).
-
-module({Mod,Exp,Attr,Fs0,Lc}, _Opts) ->
- %%io:format("~p:\n", [Mod]),
- {Fs,_} = mapfoldl(fun(Fn, Lbl) -> function(Fn, Lbl) end, 100000000, Fs0),
- {ok,{Mod,Exp,Attr,Fs,Lc}}.
-
-function({function,Name,Arity,CLabel,Is0}, Lbl0) ->
- try
- {Is,#st{next=Lbl}} = bool_opt(Is0, Lbl0),
- {{function,Name,Arity,CLabel,Is},Lbl}
- catch
- Class:Error ->
- Stack = erlang:get_stacktrace(),
- io:fwrite("Function: ~w/~w\n", [Name,Arity]),
- erlang:raise(Class, Error, Stack)
- end.
-
-%%
-%% Optimize boolean expressions that use guard bifs. Rewrite to
-%% use test instructions if possible.
-%%
-
-bool_opt(Asm, Lbl) ->
- LiveInfo = beam_utils:index_labels(Asm),
- bopt(Asm, [], #st{next=Lbl,ll=LiveInfo}).
-
-bopt([{block,Bl0}=Block|
- [{jump,{f,Succ}},
- {label,Fail},
- {block,[{set,[Dst],[{atom,false}],move}]},
- {label,Succ}|Is]=Is0], Acc0, St) ->
- case split_block(Bl0, Dst, Fail, Acc0, true) of
- failed ->
- bopt(Is0, [Block|Acc0], St);
- {Bl,PreBlock} ->
- Acc1 = case PreBlock of
- [] -> Acc0;
- _ -> [{block,PreBlock}|Acc0]
- end,
- Acc = [{protected,[Dst],Bl,{Fail,Succ}}|Acc1],
- bopt(Is, Acc, St)
- end;
-bopt([{test,is_eq_exact,{f,Fail},[Reg,{atom,true}]}=I|Is], [{block,_}|_]=Acc0, St0) ->
- case bopt_block(Reg, Fail, Is, Acc0, St0) of
- failed -> bopt(Is, [I|Acc0], St0);
- {Acc,St} -> bopt(Is, Acc, St)
- end;
-bopt([I|Is], Acc, St) ->
- bopt(Is, [I|Acc], St);
-bopt([], Acc, St) ->
- {bopt_reverse(Acc, []),St}.
-
-bopt_reverse([{protected,[Dst],Block,{Fail,Succ}}|Is], Acc0) ->
- Acc = [{block,Block},{jump,{f,Succ}},
- {label,Fail},
- {block,[{set,[Dst],[{atom,false}],move}]},
- {label,Succ}|Acc0],
- bopt_reverse(Is, Acc);
-bopt_reverse([I|Is], Acc) ->
- bopt_reverse(Is, [I|Acc]);
-bopt_reverse([], Acc) -> Acc.
-
-%% bopt_block(Reg, Fail, OldIs, Accumulator, St) -> failed | {NewAcc,St}
-%% Attempt to optimized a block of guard BIFs followed by a test
-%% instruction.
-bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) ->
- case split_block(Bl0, Reg, Fail, Acc0, false) of
- failed ->
- %% Reason for failure: The block either contained no
- %% guard BIFs with the failure label Fail, or the final
- %% instruction in the block did not assign the Reg register.
-
- %%io:format("split ~p: ~P\n", [Reg,Bl0,20]),
- failed;
- {Bl1,BlPre} ->
- %% The block has been splitted. Bl1 is a non-empty list
- %% of guard BIF instructions having the failure label Fail.
- %% BlPre is a (possibly empty list) of instructions preceeding
- %% Bl1.
- Acc1 = make_block(BlPre, Acc0),
- {Bl,Acc} = extend_block(Bl1, Fail, Acc1),
- try
- {NewCode,St} = bopt_tree_cg(Bl, Fail, St0),
- ensure_opt_safe(Bl, NewCode, OldIs, Fail, Acc, St),
- {NewCode++Acc,St}
- catch
- %% Not possible to rewrite because a boolean value is
- %% passed to another guard bif, e.g. 'abs(A > B)'
- %% (in this case, obviously nonsense code). Rare in
- %% practice.
- throw:mixed ->
- failed;
-
- %% There was a reference to a boolean expression
- %% from inside a protected block (try/catch), to
- %% a boolean expression outside.
- throw:protected_barrier ->
- failed;
-
- %% The 'xor' operator was used. We currently don't
- %% find it worthwile to translate 'xor' operators
- %% (the code would be clumsy).
- throw:'xor' ->
- failed;
-
- %% The block does not contain a boolean expression,
- %% but only a call to a guard BIF.
- %% For instance: ... when element(1, T) ->
- throw:not_boolean_expr ->
- failed;
-
- %% The optimization is not safe. (A register
- %% used by the instructions following the
- %% optimized code is either not assigned a
- %% value at all or assigned a different value.)
- throw:all_registers_not_killed ->
- failed;
- throw:registers_used ->
- failed;
-
- %% A protected block refered to the value
- %% returned by another protected block,
- %% probably because the Core Erlang code
- %% used nested try/catches in the guard.
- %% (v3_core never produces nested try/catches
- %% in guards, so it must have been another
- %% Core Erlang translator.)
- throw:protected_violation ->
- failed;
-
- %% Failed to work out the live registers for a GC
- %% BIF. For example, if the number of live registers
- %% needed to be 4 because {x,3} was a source register,
- %% but {x,2} was not known to be initialized, this
- %% exception would be thrown.
- throw:gc_bif_alloc_failure ->
- failed
-
- end
- end.
-
-%% ensure_opt_safe(OriginalCode, OptCode, FollowingCode, Fail,
-%% ReversedPrecedingCode, State) -> ok
-%% Comparing the original code to the optimized code, determine
-%% whether the optimized code is guaranteed to work in the same
-%% way as the original code.
-%%
-%% Throw an exception if the optimization is not safe.
-%%
-ensure_opt_safe(Bl, NewCode, OldIs, Fail, PrecedingCode, St) ->
- %% Here are the conditions that must be true for the
- %% optimization to be safe.
- %%
- %% 1. If a register is INITIALIZED by PrecedingCode,
- %% then if that register assigned a value in the original
- %% code, but not in the optimized code, it must be UNUSED or KILLED
- %% in the code that follows.
- %%
- %% 2. If a register is not known to be INITIALIZED by PreccedingCode,
- %% then if that register assigned a value in the original
- %% code, but not in the optimized code, it must be KILLED
- %% by the code that follows.
- %%
- %% 3. Any register that is assigned a value in the optimized
- %% code must be UNUSED or KILLED in the following code,
- %% unless we can be sure that it is always assigned the same
- %% value.
-
- InitInPreceding = initialized_regs(PrecedingCode),
-
- PrevDst = dst_regs(Bl),
- NewDst = dst_regs(NewCode),
- NotSet = ordsets:subtract(PrevDst, NewDst),
- MustBeKilled = ordsets:subtract(NotSet, InitInPreceding),
-
- case all_killed(MustBeKilled, OldIs, Fail, St) of
- false -> throw(all_registers_not_killed);
- true -> ok
- end,
- MustBeUnused = ordsets:subtract(ordsets:union(NotSet, NewDst),
- MustBeKilled),
- case none_used(MustBeUnused, OldIs, Fail, St) of
- false -> throw(registers_used);
- true -> ok
- end,
- ok.
-
-update_fail_label([{set,Ds,As,{bif,N,{f,_}}}|Is], Fail, Acc) ->
- update_fail_label(Is, Fail, [{set,Ds,As,{bif,N,{f,Fail}}}|Acc]);
-update_fail_label([{set,Ds,As,{alloc,Regs,{gc_bif,N,{f,_}}}}|Is], Fail, Acc) ->
- update_fail_label(Is, Fail,
- [{set,Ds,As,{alloc,Regs,{gc_bif,N,{f,Fail}}}}|Acc]);
-update_fail_label([], _, Acc) -> reverse(Acc).
-
-make_block(Bl) ->
- make_block(Bl, []).
-
-make_block([], Acc) -> Acc;
-make_block(Bl, Acc) -> [{block,Bl}|Acc].
-
-extend_block(BlAcc, Fail, [{protected,_,_,_}=Prot|OldAcc]) ->
- extend_block([Prot|BlAcc], Fail, OldAcc);
-extend_block(BlAcc0, Fail, [{block,Is0}|OldAcc]) ->
- case extend_block_1(reverse(Is0), Fail, BlAcc0) of
- {BlAcc,[]} -> extend_block(BlAcc, Fail, OldAcc);
- {BlAcc,Is} -> {BlAcc,[{block,Is}|OldAcc]}
- end;
-extend_block(BlAcc, _, OldAcc) -> {BlAcc,OldAcc}.
-
-extend_block_1([{set,[{x,_}],_,{bif,_,{f,Fail}}}=I|Is], Fail, Acc) ->
- extend_block_1(Is, Fail, [I|Acc]);
-extend_block_1([{set,[{x,_}],As,{bif,Bif,_}}=I|Is]=Is0, Fail, Acc) ->
- case safe_bool_op(Bif, length(As)) of
- false -> {Acc,reverse(Is0)};
- true -> extend_block_1(Is, Fail, [I|Acc])
- end;
-extend_block_1([_|_]=Is, _, Acc) -> {Acc,reverse(Is)};
-extend_block_1([], _, Acc) -> {Acc,[]}.
-
-%% split_block([Instruction], Destination, FailLabel, [PreInstruction],
-%% ProhibitFailLabelInPreBlock) -> failed | {Block,PreBlock}
-%% Split a sequence of instructions into two blocks - one containing
-%% all guard bif instructions and a pre-block all instructions before
-%% the guard BIFs.
-
-split_block(Is0, Dst, Fail, PreIs, ProhibitFailLabel) ->
- case ProhibitFailLabel andalso beam_jump:is_label_used_in(Fail, PreIs) of
- true ->
- %% The failure label was used in one of the instructions (most
- %% probably bit syntax construction) preceeding the block,
- %% the caller might eliminate the label.
- failed;
- false ->
- case reverse(Is0) of
- [{set,[Dst],_,_}|_]=Is ->
- split_block_1(Is, Fail, ProhibitFailLabel);
- _ -> failed
- end
- end.
-
-split_block_1(Is, Fail, ProhibitFailLabel) ->
- case split_block_2(Is, Fail, []) of
- {[],_} -> failed;
- {_,PreBlock}=Res ->
- case ProhibitFailLabel andalso
- split_block_label_used(PreBlock, Fail) of
- true ->
- %% The failure label was used in the pre-block;
- %% not allowed, because the label may be removed.
- failed;
- false ->
- Res
- end
- end.
-
-split_block_2([{set,[_],_,{bif,_,{f,Fail}}}=I|Is], Fail, Acc) ->
- split_block_2(Is, Fail, [I|Acc]);
-split_block_2([{set,[_],_,{alloc,_,{gc_bif,_,{f,Fail}}}}=I|Is], Fail, Acc) ->
- split_block_2(Is, Fail, [I|Acc]);
-split_block_2(Is0, _, Acc) ->
- Is = reverse(Is0),
- {Acc,Is}.
-
-split_block_label_used([{set,[_],_,{bif,_,{f,Fail}}}|_], Fail) ->
- true;
-split_block_label_used([{set,[_],_,{alloc,_,{gc_bif,_,{f,Fail}}}}|_], Fail) ->
- true;
-split_block_label_used([{set,[_],_,{alloc,_,{put_map,_,{f,Fail}}}}|_], Fail) ->
- true;
-split_block_label_used([_|Is], Fail) ->
- split_block_label_used(Is, Fail);
-split_block_label_used([], _) -> false.
-
-dst_regs(Is) ->
- dst_regs(Is, []).
-
-dst_regs([{block,Bl}|Is], Acc) ->
- dst_regs(Bl, dst_regs(Is, Acc));
-dst_regs([{set,[D],_,{bif,_,{f,_}}}|Is], Acc) ->
- dst_regs(Is, [D|Acc]);
-dst_regs([{set,[D],_,{alloc,_,{gc_bif,_,{f,_}}}}|Is], Acc) ->
- dst_regs(Is, [D|Acc]);
-dst_regs([{protected,_,Bl,_}|Is], Acc) ->
- dst_regs(Bl, dst_regs(Is, Acc));
-dst_regs([_|Is], Acc) ->
- dst_regs(Is, Acc);
-dst_regs([], Acc) -> ordsets:from_list(Acc).
-
-all_killed([R|Rs], OldIs, Fail, St) ->
- case is_killed(R, OldIs, Fail, St) of
- false -> false;
- true -> all_killed(Rs, OldIs, Fail, St)
- end;
-all_killed([], _, _, _) -> true.
-
-none_used([R|Rs], OldIs, Fail, St) ->
- case is_not_used(R, OldIs, Fail, St) of
- false -> false;
- true -> none_used(Rs, OldIs, Fail, St)
- end;
-none_used([], _, _, _) -> true.
-
-bopt_tree_cg(Block0, Fail, St) ->
- Free = free_variables(Block0),
- Block = ssa_block(Block0),
-%% io:format("~p\n", [Block0]),
-%% io:format("~p\n", [Block]),
-%% io:format("~p\n", [gb_trees:to_list(Free)]),
- case bopt_tree(Block, Free, []) of
- {Pre0,[{_,Tree}]} ->
- Pre1 = update_fail_label(Pre0, Fail, []),
- Regs0 = init_regs(gb_trees:keys(Free)),
-%% io:format("~p\n", [dst_regs(Block0)]),
-%% io:format("~p\n", [Pre1]),
-%% io:format("~p\n", [Tree]),
-%% io:nl(),
- {Pre,Regs} = rename_regs(Pre1, Regs0),
-%% io:format("~p\n", [Regs0]),
-%% io:format("~p\n", [Pre]),
- bopt_cg(Tree, Fail, Regs, make_block(Pre), St);
- _Res ->
- throw(not_boolean_expr)
- end.
-
-bopt_tree([{set,[Dst],As0,{bif,'not',_}}|Is], Forest0, Pre) ->
- {[Arg],Forest1} = bopt_bool_args(As0, Forest0),
- Forest = gb_trees:enter(Dst, {'not',Arg}, Forest1),
- bopt_tree(Is, Forest, Pre);
-bopt_tree([{set,[Dst],As0,{bif,'and',_}}|Is], Forest0, Pre) ->
- {As,Forest1} = bopt_bool_args(As0, Forest0),
- Node = make_and_node(As),
- Forest = gb_trees:enter(Dst, Node, Forest1),
- bopt_tree(Is, Forest, Pre);
-bopt_tree([{set,[Dst],As0,{bif,'or',_}}|Is], Forest0, Pre) ->
- {As,Forest1} = bopt_bool_args(As0, Forest0),
- Node = make_or_node(As),
- Forest = gb_trees:enter(Dst, Node, Forest1),
- bopt_tree(Is, Forest, Pre);
-bopt_tree([{set,_,_,{bif,'xor',_}}|_], _, _) ->
- throw('xor');
-bopt_tree([{protected,[Dst],Code,_}|Is], Forest0, Pre) ->
- ProtForest0 = gb_trees:from_orddict([P || {_,any}=P <- gb_trees:to_list(Forest0)]),
- case bopt_tree(Code, ProtForest0, []) of
- {ProtPre,[{_,ProtTree}]} ->
- Prot = {prot,ProtPre,ProtTree},
- Forest = gb_trees:enter(Dst, Prot, Forest0),
- bopt_tree(Is, Forest, Pre);
- _Res ->
- throw(not_boolean_expr)
- end;
-bopt_tree([{set,[Dst],As,{bif,N,_}}=Bif|Is], Forest0, Pre) ->
- Ar = length(As),
- case safe_bool_op(N, Ar) of
- false ->
- bopt_good_args(As, Forest0),
- Forest = gb_trees:enter(Dst, any, Forest0),
- bopt_tree(Is, Forest, [Bif|Pre]);
- true ->
- bopt_good_args(As, Forest0),
- Test = bif_to_test(Dst, N, As),
- Forest = gb_trees:enter(Dst, Test, Forest0),
- bopt_tree(Is, Forest, Pre)
- end;
-bopt_tree([{set,[Dst],As,{alloc,_,{gc_bif,_,_}}}=Bif|Is], Forest0, Pre) ->
- bopt_good_args(As, Forest0),
- Forest = gb_trees:enter(Dst, any, Forest0),
- bopt_tree(Is, Forest, [Bif|Pre]);
-bopt_tree([], Forest, Pre) ->
- {reverse(Pre),[R || {_,V}=R <- gb_trees:to_list(Forest), V =/= any]}.
-
-safe_bool_op(N, Ar) ->
- erl_internal:new_type_test(N, Ar) orelse erl_internal:comp_op(N, Ar).
-
-bopt_bool_args([V0,V0], Forest0) ->
- {V,Forest} = bopt_bool_arg(V0, Forest0),
- {[V,V],Forest};
-bopt_bool_args(As, Forest) ->
- mapfoldl(fun bopt_bool_arg/2, Forest, As).
-
-bopt_bool_arg({T,_}=R, Forest) when T =:= x; T =:= y; T =:= tmp ->
- Val = case gb_trees:lookup(R, Forest) of
- {value,any} -> {test,is_eq_exact,fail,[R,{atom,true}]};
- {value,Val0} -> Val0;
- none -> throw(mixed)
- end,
- {Val,gb_trees:delete(R, Forest)};
-bopt_bool_arg(Term, Forest) ->
- {Term,Forest}.
-
-bopt_good_args([A|As], Regs) ->
- bopt_good_arg(A, Regs),
- bopt_good_args(As, Regs);
-bopt_good_args([], _) -> ok.
-
-bopt_good_arg({Tag,_}=X, Regs) when Tag =:= x; Tag =:= tmp ->
- case gb_trees:lookup(X, Regs) of
- {value,any} -> ok;
- {value,_} -> throw(mixed);
- none -> throw(protected_barrier)
- end;
-bopt_good_arg(_, _) -> ok.
-
-bif_to_test(_, N, As) ->
- beam_utils:bif_to_test(N, As, fail).
-
-make_and_node(Is) ->
- AndList0 = make_and_list(Is),
- case simplify_and_list(AndList0) of
- [] -> {atom,true};
- [Op] -> Op;
- AndList -> {'and',AndList}
- end.
-
-make_and_list([{'and',As}|Is]) ->
- make_and_list(As++Is);
-make_and_list([I|Is]) ->
- [I|make_and_list(Is)];
-make_and_list([]) -> [].
-
-simplify_and_list([{atom,true}|T]) ->
- simplify_and_list(T);
-simplify_and_list([{atom,false}=False|_]) ->
- [False];
-simplify_and_list([H|T]) ->
- [H|simplify_and_list(T)];
-simplify_and_list([]) -> [].
-
-make_or_node(Is) ->
- OrList0 = make_or_list(Is),
- case simplify_or_list(OrList0) of
- [] -> {atom,false};
- [Op] -> Op;
- OrList -> {'or',OrList}
- end.
-
-make_or_list([{'or',As}|Is]) ->
- make_or_list(As++Is);
-make_or_list([I|Is]) ->
- [I|make_or_list(Is)];
-make_or_list([]) -> [].
-
-simplify_or_list([{atom,false}|T]) ->
- simplify_or_list(T);
-simplify_or_list([{atom,true}=True|_]) ->
- [True];
-simplify_or_list([H|T]) ->
- [H|simplify_or_list(T)];
-simplify_or_list([]) -> [].
-
-%% Code generation for a boolean tree.
-
-bopt_cg({'not',Arg}, Fail, Rs, Acc, St) ->
- I = bopt_cg_not(Arg),
- bopt_cg(I, Fail, Rs, Acc, St);
-bopt_cg({'and',As}, Fail, Rs, Acc, St) ->
- bopt_cg_and(As, Fail, Rs, Acc, St);
-bopt_cg({'or',As}, Fail, Rs, Acc, St0) ->
- {Succ,St} = new_label(St0),
- bopt_cg_or(As, Succ, Fail, Rs, Acc, St);
-bopt_cg({test,N,fail,As0}, Fail, Rs, Acc, St) ->
- As = rename_sources(As0, Rs),
- Test = {test,N,{f,Fail},As},
- {[Test|Acc],St};
-bopt_cg({inverted_test,N,fail,As0}, Fail, Rs, Acc, St0) ->
- As = rename_sources(As0, Rs),
- {Lbl,St} = new_label(St0),
- {[{label,Lbl},{jump,{f,Fail}},{test,N,{f,Lbl},As}|Acc],St};
-bopt_cg({prot,Pre0,Tree}, Fail, Rs0, Acc, St0) ->
- Pre1 = update_fail_label(Pre0, Fail, []),
- {Pre,Rs} = rename_regs(Pre1, Rs0),
- bopt_cg(Tree, Fail, Rs, make_block(Pre, Acc), St0);
-bopt_cg({atom,true}, _Fail, _Rs, Acc, St) ->
- {Acc,St};
-bopt_cg({atom,false}, Fail, _Rs, Acc, St) ->
- {[{jump,{f,Fail}}|Acc],St};
-bopt_cg(_, _, _, _, _) ->
- throw(not_boolean_expr).
-
-bopt_cg_not({'and',As0}) ->
- As = [bopt_cg_not(A) || A <- As0],
- {'or',As};
-bopt_cg_not({'or',As0}) ->
- As = [bopt_cg_not(A) || A <- As0],
- {'and',As};
-bopt_cg_not({'not',Arg}) ->
- bopt_cg_not_not(Arg);
-bopt_cg_not({test,Test,Fail,As}) ->
- {inverted_test,Test,Fail,As};
-bopt_cg_not({atom,Bool}) when is_boolean(Bool) ->
- {atom,not Bool};
-bopt_cg_not(_) ->
- throw(not_boolean_expr).
-
-bopt_cg_not_not({'and',As}) ->
- {'and',[bopt_cg_not_not(A) || A <- As]};
-bopt_cg_not_not({'or',As}) ->
- {'or',[bopt_cg_not_not(A) || A <- As]};
-bopt_cg_not_not({'not',Arg}) ->
- bopt_cg_not(Arg);
-bopt_cg_not_not(Leaf) -> Leaf.
-
-bopt_cg_and([I|Is], Fail, Rs, Acc0, St0) ->
- {Acc,St} = bopt_cg(I, Fail, Rs, Acc0, St0),
- bopt_cg_and(Is, Fail, Rs, Acc, St);
-bopt_cg_and([], _, _, Acc, St) -> {Acc,St}.
-
-bopt_cg_or([I], Succ, Fail, Rs, Acc0, St0) ->
- {Acc,St} = bopt_cg(I, Fail, Rs, Acc0, St0),
- {[{label,Succ}|Acc],St};
-bopt_cg_or([I|Is], Succ, Fail, Rs, Acc0, St0) ->
- {Lbl,St1} = new_label(St0),
- {Acc,St} = bopt_cg(I, Lbl, Rs, Acc0, St1),
- bopt_cg_or(Is, Succ, Fail, Rs, [{label,Lbl},{jump,{f,Succ}}|Acc], St).
-
-new_label(#st{next=LabelNum}=St) when is_integer(LabelNum) ->
- {LabelNum,St#st{next=LabelNum+1}}.
-
-free_variables(Is) ->
- E = gb_sets:empty(),
- free_vars_1(Is, E, E, E).
-
-free_vars_1([{set,Ds,As,{bif,_,_}}|Is], F0, N0, A) ->
- F = gb_sets:union(F0, gb_sets:difference(var_list(As), N0)),
- N = gb_sets:union(N0, var_list(Ds)),
- free_vars_1(Is, F, N, A);
-free_vars_1([{set,Ds,As,{alloc,Regs,{gc_bif,_,_}}}|Is], F0, N0, A0) ->
- A = gb_sets:union(A0, gb_sets:from_list(free_vars_regs(Regs))),
- F = gb_sets:union(F0, gb_sets:difference(var_list(As), N0)),
- N = gb_sets:union(N0, var_list(Ds)),
- free_vars_1(Is, F, N, A);
-free_vars_1([{protected,_,Pa,_}|Is], F, N, A) ->
- free_vars_1(Pa++Is, F, N, A);
-free_vars_1([], F0, N, A) ->
- F = case gb_sets:is_empty(A) of
- true ->
- %% No GC BIFs.
- {x,X} = gb_sets:smallest(N),
- P = ordsets:from_list(free_vars_regs(X)),
- ordsets:union(gb_sets:to_list(F0), P);
- false ->
- %% At least one GC BIF.
- gb_sets:to_list(gb_sets:union(F0, gb_sets:difference(A, N)))
- end,
- gb_trees:from_orddict([{K,any} || K <- F]).
-
-var_list(Is) ->
- var_list_1(Is, gb_sets:empty()).
-
-var_list_1([{Tag,_}=X|Is], D) when Tag =:= x; Tag =:= y ->
- var_list_1(Is, gb_sets:add(X, D));
-var_list_1([_|Is], D) ->
- var_list_1(Is, D);
-var_list_1([], D) -> D.
-
-free_vars_regs(0) -> [];
-free_vars_regs(X) -> [{x,X-1}|free_vars_regs(X-1)].
-
-rename_regs(Is, Regs) ->
- rename_regs(Is, Regs, []).
-
-rename_regs([{set,[Dst0],Ss0,{alloc,_,Info}}|Is], Regs0, Acc) ->
- Live = live_regs(Regs0),
- Ss = rename_sources(Ss0, Regs0),
- Regs = put_reg(Dst0, Regs0),
- Dst = fetch_reg(Dst0, Regs),
- rename_regs(Is, Regs, [{set,[Dst],Ss,{alloc,Live,Info}}|Acc]);
-rename_regs([{set,[Dst0],Ss0,Info}|Is], Regs0, Acc) ->
- Ss = rename_sources(Ss0, Regs0),
- Regs = put_reg(Dst0, Regs0),
- Dst = fetch_reg(Dst0, Regs),
- rename_regs(Is, Regs, [{set,[Dst],Ss,Info}|Acc]);
-rename_regs([], Regs, Acc) -> {reverse(Acc),Regs}.
-
-rename_sources(Ss, Regs) ->
- map(fun({x,_}=R) -> fetch_reg(R, Regs);
- ({tmp,_}=R) -> fetch_reg(R, Regs);
- (E) -> E
- end, Ss).
-
-%%%
-%%% Keeping track of register assignments.
-%%%
-
-init_regs(Free) ->
- init_regs_1(Free, 0).
-
-init_regs_1([{x,I}=V|T], I) ->
- [{I,V}|init_regs_1(T, I+1)];
-init_regs_1([{x,X}|_]=T, I) when I < X ->
- [{I,reserved}|init_regs_1(T, I+1)];
-init_regs_1([{y,_}|_], _) -> [];
-init_regs_1([], _) -> [].
-
-put_reg(V, Rs) -> put_reg_1(V, Rs, 0).
-
-put_reg_1(V, [R|Rs], I) -> [R|put_reg_1(V, Rs, I+1)];
-put_reg_1(V, [], I) -> [{I,V}].
-
-fetch_reg(V, [{I,V}|_]) -> {x,I};
-fetch_reg(V, [_|SRs]) -> fetch_reg(V, SRs).
-
-live_regs([{_,reserved}|_]) ->
- %% We are not sure that this register is initialized, so we must
- %% abort the optimization.
- throw(gc_bif_alloc_failure);
-live_regs([{I,_}]) ->
- I+1;
-live_regs([{_,_}|Regs]) ->
- live_regs(Regs);
-live_regs([]) ->
- 0.
-
-
-%%%
-%%% Convert a block to Static Single Assignment (SSA) form.
-%%%
-
--record(ssa,
- {live=0, %Variable counter.
- sub=gb_trees:empty(), %Substitution table.
- prot=gb_sets:empty(), %Targets assigned by protecteds.
- in_prot=false %Inside a protected.
- }).
-
-ssa_block(Is0) ->
- {Is,_} = ssa_block_1(Is0, #ssa{}, []),
- Is.
-
-ssa_block_1([{protected,[_],Pa0,Pb}|Is], Sub0, Acc) ->
- {Pa,Sub1} = ssa_block_1(Pa0, Sub0#ssa{in_prot=true}, []),
- Dst = ssa_last_target(Pa),
- Sub = Sub1#ssa{prot=gb_sets:insert(Dst, Sub1#ssa.prot),
- in_prot=Sub0#ssa.in_prot},
- ssa_block_1(Is, Sub, [{protected,[Dst],Pa,Pb}|Acc]);
-ssa_block_1([{set,[Dst],As,Bif}|Is], Sub0, Acc0) ->
- Sub1 = ssa_in_use_list(As, Sub0),
- Sub = ssa_assign(Dst, Sub1),
- Acc = [{set,[ssa_sub(Dst, Sub)],ssa_sub_list(As, Sub0),Bif}|Acc0],
- ssa_block_1(Is, Sub, Acc);
-ssa_block_1([], Sub, Acc) -> {reverse(Acc),Sub}.
-
-ssa_in_use_list(As, Sub) ->
- foldl(fun ssa_in_use/2, Sub, As).
-
-ssa_in_use({x,_}=R, #ssa{sub=Sub0}=Ssa) ->
- case gb_trees:is_defined(R, Sub0) of
- true -> Ssa;
- false ->
- Sub = gb_trees:insert(R, R, Sub0),
- Ssa#ssa{sub=Sub}
- end;
-ssa_in_use(_, Ssa) -> Ssa.
-
-ssa_assign({x,_}=R, #ssa{sub=Sub0}=Ssa0) ->
- {NewReg,Ssa} = ssa_new_reg(Ssa0),
- case gb_trees:is_defined(R, Sub0) of
- false ->
- Sub = gb_trees:insert(R, NewReg, Sub0),
- Ssa#ssa{sub=Sub};
- true ->
- Sub1 = gb_trees:update(R, NewReg, Sub0),
- Sub = gb_trees:insert(NewReg, NewReg, Sub1),
- Ssa#ssa{sub=Sub}
- end.
-
-ssa_sub_list(List, Sub) ->
- [ssa_sub(E, Sub) || E <- List].
-
-ssa_sub(R0, #ssa{sub=Sub,prot=Prot,in_prot=InProt}) ->
- case gb_trees:lookup(R0, Sub) of
- none -> R0;
- {value,R} ->
- case InProt andalso gb_sets:is_element(R, Prot) of
- true ->
- throw(protected_violation);
- false ->
- R
- end
- end.
-
-ssa_new_reg(#ssa{live=Reg}=Ssa) ->
- {{tmp,Reg},Ssa#ssa{live=Reg+1}}.
-
-ssa_last_target([{set,[Dst],_,_}]) -> Dst;
-ssa_last_target([_|Is]) -> ssa_last_target(Is).
-
-%% is_killed(Register, [Instruction], FailLabel, State) -> true|false
-%% Determine whether a register is killed in the instruction sequence.
-%% The state is used to allow us to determine the kill state
-%% across branches.
-
-is_killed(R, Is, Label, #st{ll=Ll}) ->
- beam_utils:is_killed(R, Is, Ll) andalso
- beam_utils:is_killed_at(R, Label, Ll).
-
-%% is_not_used(Register, [Instruction], FailLabel, State) -> true|false
-%% Determine whether a register is never used in the instruction sequence
-%% (it could still referenced by an allocate instruction, meaning that
-%% it MUST be initialized).
-%% The state is used to allow us to determine the usage state
-%% across branches.
-
-is_not_used(R, Is, Label, #st{ll=Ll}) ->
- beam_utils:is_not_used(R, Is, Ll) andalso
- beam_utils:is_not_used_at(R, Label, Ll).
-
-%% initialized_regs([Instruction]) -> [Register])
-%% Given a REVERSED instruction sequence, return a list of the registers
-%% that are guaranteed to be initialized (not contain garbage).
-
-initialized_regs(Is) ->
- initialized_regs(Is, ordsets:new()).
-
-initialized_regs([{set,Dst,_Src,{alloc,Live,_}}|_], Regs0) ->
- Regs = add_init_regs(free_vars_regs(Live), Regs0),
- add_init_regs(Dst, Regs);
-initialized_regs([{set,Dst,Src,_}|Is], Regs) ->
- initialized_regs(Is, add_init_regs(Dst, add_init_regs(Src, Regs)));
-initialized_regs([{test,_,_,Src}|Is], Regs) ->
- initialized_regs(Is, add_init_regs(Src, Regs));
-initialized_regs([{block,Bl}|Is], Regs) ->
- initialized_regs(reverse(Bl, Is), Regs);
-initialized_regs([{bs_context_to_binary,Src}|Is], Regs) ->
- initialized_regs(Is, add_init_regs([Src], Regs));
-initialized_regs([{label,_},{func_info,_,_,Arity}|_], Regs) ->
- InitRegs = free_vars_regs(Arity),
- add_init_regs(InitRegs, Regs);
-initialized_regs([_|_], Regs) -> Regs.
-
-add_init_regs([{x,_}=X|T], Regs) ->
- add_init_regs(T, ordsets:add_element(X, Regs));
-add_init_regs([_|T], Regs) ->
- add_init_regs(T, Regs);
-add_init_regs([], Regs) -> Regs.
diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl
index 3606af9d75..9087586b58 100644
--- a/lib/compiler/src/beam_dead.erl
+++ b/lib/compiler/src/beam_dead.erl
@@ -266,12 +266,30 @@ backward([{jump,{f,To0}},{move,Src,Reg}=Move|Is], D, Acc) ->
false -> backward([Move|Is], D, [Jump|Acc]);
true -> backward([Jump|Is], D, Acc)
end;
-backward([{jump,{f,To}}=J|[{bif,Op,_,Ops,Reg}|Is]=Is0], D, Acc) ->
+backward([{jump,{f,To}}=J|[{bif,Op,{f,BifFail},Ops,Reg}|Is]=Is0], D, Acc) ->
try replace_comp_op(To, Reg, Op, Ops, D) of
I -> backward(Is, D, I++Acc)
catch
- throw:not_possible -> backward(Is0, D, [J|Acc])
+ throw:not_possible ->
+ case To =:= BifFail of
+ true ->
+ %% The bif instruction is redundant. See the comment
+ %% in the next clause for why there is no need to
+ %% test for liveness of Reg at label To.
+ backward([J|Is], D, Acc);
+ false ->
+ backward(Is0, D, [J|Acc])
+ end
end;
+backward([{jump,{f,To}}=J|[{gc_bif,_,{f,To},_,_,_Dst}|Is]], D, Acc) ->
+ %% The gc_bif instruction is redundant, since either the gc_bif
+ %% instruction itself or the jump instruction will transfer control
+ %% to label To. Note that a gc_bif instruction does not assign its
+ %% destination register if the failure branch is taken; therefore,
+ %% the code at label To is not allowed to assume that the destination
+ %% register is initialized, and it is therefore no need to test
+ %% for liveness of the destination register at label To.
+ backward([J|Is], D, Acc);
backward([{test,bs_start_match2,F,Live,[R,_]=Args,Ctxt}|Is], D,
[{test,bs_match_string,F,[Ctxt,Bs]},
{test,bs_test_tail2,F,[Ctxt,0]}|Acc0]=Acc) ->
@@ -361,6 +379,14 @@ backward([{kill,_}=I|Is], D, [{line,_},Exit|_]=Acc) ->
false -> backward(Is, D, [I|Acc]);
true -> backward(Is, D, Acc)
end;
+backward([{bif,'or',{f,To0},[Dst,{atom,false}],Dst}=I|Is], D,
+ [{test,is_eq_exact,{f,To},[Dst,{atom,true}]}|_]=Acc) ->
+ case shortcut_label(To0, D) of
+ To ->
+ backward(Is, D, Acc);
+ _ ->
+ backward(Is, D, [I|Acc])
+ end;
backward([I|Is], D, Acc) ->
backward(Is, D, [I|Acc]);
backward([], _D, Acc) -> Acc.
@@ -379,6 +405,8 @@ shortcut_select_list([Lit,{f,To0}|T], Reg, D, Acc) ->
shortcut_select_list(T, Reg, D, [{f,To},Lit|Acc]);
shortcut_select_list([], _, _, Acc) -> reverse(Acc).
+shortcut_label(0, _) ->
+ 0;
shortcut_label(To0, D) ->
case beam_utils:code_at(To0, D) of
[{jump,{f,To}}|_] -> shortcut_label(To, D);
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index 5311ce7379..e096270d8c 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -23,7 +23,7 @@
-export([module/2,
is_unreachable_after/1,is_exit_instruction/1,
- remove_unused_labels/1,is_label_used_in/2]).
+ remove_unused_labels/1]).
%%% The following optimisations are done:
%%%
@@ -473,36 +473,6 @@ is_exit_instruction({try_case_end,_}) -> true;
is_exit_instruction({badmatch,_}) -> true;
is_exit_instruction(_) -> false.
-%% is_label_used_in(LabelNumber, [Instruction]) -> boolean()
-%% Check whether the label is used in the instruction sequence
-%% (including inside blocks).
-
-is_label_used_in(Lbl, Is) ->
- is_label_used_in_1(Is, Lbl, cerl_sets:new()).
-
-is_label_used_in_1([{block,Block}|Is], Lbl, Empty) ->
- lists:any(fun(I) -> is_label_used_in_block(I, Lbl) end, Block)
- orelse is_label_used_in_1(Is, Lbl, Empty);
-is_label_used_in_1([I|Is], Lbl, Empty) ->
- Used = ulbl(I, Empty),
- cerl_sets:is_element(Lbl, Used) orelse is_label_used_in_1(Is, Lbl, Empty);
-is_label_used_in_1([], _, _) -> false.
-
-is_label_used_in_block({set,_,_,Info}, Lbl) ->
- case Info of
- {bif,_,{f,F}} -> F =:= Lbl;
- {alloc,_,{gc_bif,_,{f,F}}} -> F =:= Lbl;
- {alloc,_,{put_map,_,{f,F}}} -> F =:= Lbl;
- {get_map_elements,{f,F}} -> F =:= Lbl;
- {try_catch,_,{f,F}} -> F =:= Lbl;
- {alloc,_,_} -> false;
- {put_tuple,_} -> false;
- {get_tuple_element,_} -> false;
- {set_tuple_element,_} -> false;
- {line,_} -> false;
- _ when is_atom(Info) -> false
- end.
-
%% remove_unused_labels(Instructions0) -> Instructions
%% Remove all unused labels. Also remove unreachable
%% instructions following labels that are removed.
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl
index b4776294be..d324580cba 100644
--- a/lib/compiler/src/beam_type.erl
+++ b/lib/compiler/src/beam_type.erl
@@ -594,6 +594,7 @@ is_math_bif(atan2, 2) -> true;
is_math_bif(pow, 2) -> true;
is_math_bif(ceil, 1) -> true;
is_math_bif(floor, 1) -> true;
+is_math_bif(fmod, 2) -> true;
is_math_bif(pi, 0) -> true;
is_math_bif(_, _) -> false.
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 564a62a7f2..74e3d7e38a 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -22,7 +22,7 @@
-module(beam_utils).
-export([is_killed_block/2,is_killed/3,is_killed_at/3,
- is_not_used/3,is_not_used_at/3,
+ is_not_used/3,
empty_label_index/0,index_label/3,index_labels/1,
code_at/2,bif_to_test/3,is_pure_test/1,
live_opt/1,delete_live_annos/1,combine_heap_needs/2,
@@ -96,20 +96,6 @@ is_not_used(R, Is, D) ->
{_,_} -> true
end.
-%% is_not_used(Register, [Instruction], State) -> true|false
-%% Determine whether a register is never used in the instruction sequence
-%% (it could still be referenced by an allocate instruction, meaning that
-%% it MUST be initialized, but that its value does not matter).
-%% The state is used to allow us to determine the usage state
-%% across branches.
-
-is_not_used_at(R, Lbl, D) ->
- St = #live{lbl=D,res=gb_trees:empty()},
- case check_liveness_at(R, Lbl, St) of
- {used,_} -> false;
- {_,_} -> true
- end.
-
%% index_labels(FunctionIs) -> State
%% Index the instruction sequence so that we can quickly
%% look up the instruction following a specific label.
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 6e53f53a20..5659077c5d 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1646,6 +1646,7 @@ return_type_math(atan2, 2) -> {float,[]};
return_type_math(pow, 2) -> {float,[]};
return_type_math(ceil, 1) -> {float,[]};
return_type_math(floor, 1) -> {float,[]};
+return_type_math(fmod, 2) -> {float,[]};
return_type_math(pi, 0) -> {float,[]};
return_type_math(F, A) when is_atom(F), is_integer(A), A >= 0 -> term.
diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl
index 61abae344c..b1be6ffc6d 100644
--- a/lib/compiler/src/cerl.erl
+++ b/lib/compiler/src/cerl.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +10,8 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-
-%% =====================================================================
+%% @copyright 1999-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Core Erlang abstract syntax trees.
%%
%% <p> This module defines an abstract data type for representing Core
diff --git a/lib/compiler/src/cerl_clauses.erl b/lib/compiler/src/cerl_clauses.erl
index 805095e30c..7d6518c3c6 100644
--- a/lib/compiler/src/cerl_clauses.erl
+++ b/lib/compiler/src/cerl_clauses.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +10,8 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-
+%% @copyright 1999-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Utility functions for Core Erlang case/receive clauses.
%%
%% <p>Syntax trees are defined in the module <a
diff --git a/lib/compiler/src/cerl_inline.erl b/lib/compiler/src/cerl_inline.erl
index 2a8cf2e758..f5afa75b16 100644
--- a/lib/compiler/src/cerl_inline.erl
+++ b/lib/compiler/src/cerl_inline.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +10,9 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% Core Erlang inliner.
+%% @copyright 1999-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
+%% @doc Core Erlang inliner.
%% =====================================================================
%%
diff --git a/lib/compiler/src/cerl_trees.erl b/lib/compiler/src/cerl_trees.erl
index b3decbec1f..f30a0b33ac 100644
--- a/lib/compiler/src/cerl_trees.erl
+++ b/lib/compiler/src/cerl_trees.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +10,8 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-
+%% @copyright 1999-2002 Richard Carlsson.
+%% @author Richard Carlsson <[email protected]>
%% @doc Basic functions on Core Erlang abstract syntax trees.
%%
%% <p>Syntax trees are defined in the module <a
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index e4fb703939..3868b971a3 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -684,7 +684,7 @@ kernel_passes() ->
{iff,core,?pass(save_core_code)},
%% Kernel Erlang and code generation.
- {pass,v3_kernel},
+ ?pass(v3_kernel),
{iff,dkern,{listing,"kernel"}},
{iff,'to_kernel',{done,"kernel"}},
{pass,v3_life},
@@ -707,8 +707,6 @@ asm_passes() ->
{iff,dexcept,{listing,"except"}},
{unless,no_bs_opt,{pass,beam_bs}},
{iff,dbs,{listing,"bs"}},
- {unless,no_bopt,{pass,beam_bool}},
- {iff,dbool,{listing,"bool"}},
{unless,no_topt,{pass,beam_type}},
{iff,dtype,{listing,"type"}},
{pass,beam_split},
@@ -1245,6 +1243,17 @@ core_fold_module_after_inlining(#compile{code=Code0,options=Opts}=St) ->
{ok,Code,_Ws} = sys_core_fold:module(Code0, Opts),
{ok,St#compile{code=Code}}.
+v3_kernel(#compile{code=Code0,options=Opts,warnings=Ws0}=St) ->
+ {ok,Code,Ws} = v3_kernel:module(Code0, Opts),
+ case Ws =:= [] orelse test_core_inliner(St) of
+ false ->
+ {ok,St#compile{code=Code,warnings=Ws0++Ws}};
+ true ->
+ %% cerl_inline may produce code that generates spurious
+ %% warnings. Ignore any such warnings.
+ {ok,St#compile{code=Code}}
+ end.
+
test_old_inliner(#compile{options=Opts}) ->
%% The point of this test is to avoid loading the old inliner
%% if we know that it will not be used.
@@ -1780,7 +1789,6 @@ pre_load() ->
L = [beam_a,
beam_asm,
beam_block,
- beam_bool,
beam_bs,
beam_bsm,
beam_clean,
diff --git a/lib/compiler/src/compiler.app.src b/lib/compiler/src/compiler.app.src
index 20195ac36f..3cb991687b 100644
--- a/lib/compiler/src/compiler.app.src
+++ b/lib/compiler/src/compiler.app.src
@@ -24,7 +24,6 @@
beam_a,
beam_asm,
beam_block,
- beam_bool,
beam_bs,
beam_bsm,
beam_clean,
diff --git a/lib/compiler/src/core_parse.yrl b/lib/compiler/src/core_parse.yrl
index 8028aa99bb..79a7cccd98 100644
--- a/lib/compiler/src/core_parse.yrl
+++ b/lib/compiler/src/core_parse.yrl
@@ -432,6 +432,21 @@ timeout ->
%% ====================================================================== %%
+Header
+"%% This file was automatically generated from the file \"core_parse.yrl\"."
+"%%"
+"%% Copyright Ericsson AB 1999-2009. All Rights Reserved."
+"%%"
+"%% Licensed under the Apache License, Version 2.0 (the \"License\"); you may"
+"%% not use this file except in compliance with the License. You may obtain"
+"%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>"
+"%%"
+"%% Unless required by applicable law or agreed to in writing, software"
+"%% distributed under the License is distributed on an \"AS IS\" BASIS,"
+"%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."
+"%% See the License for the specific language governing permissions and"
+"%% limitations under the License."
+"".
Erlang code.
diff --git a/lib/compiler/src/erl_bifs.erl b/lib/compiler/src/erl_bifs.erl
index 831730ba48..d60f73d421 100644
--- a/lib/compiler/src/erl_bifs.erl
+++ b/lib/compiler/src/erl_bifs.erl
@@ -138,6 +138,7 @@ is_pure(math, erf, 1) -> true;
is_pure(math, erfc, 1) -> true;
is_pure(math, exp, 1) -> true;
is_pure(math, floor, 1) -> true;
+is_pure(math, fmod, 2) -> true;
is_pure(math, log, 1) -> true;
is_pure(math, log2, 1) -> true;
is_pure(math, log10, 1) -> true;
diff --git a/lib/compiler/src/rec_env.erl b/lib/compiler/src/rec_env.erl
index cdc513e57c..48d39776dc 100644
--- a/lib/compiler/src/rec_env.erl
+++ b/lib/compiler/src/rec_env.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,10 +10,8 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% @author Richard Carlsson <[email protected]>
%% @copyright 1999-2004 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Abstract environments, supporting self-referential bindings and
%% automatic new-key generation.
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index feb34b364f..50d28c0a5f 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -172,13 +172,23 @@ guard(Expr, Sub) ->
%%
opt_guard_try(#c_seq{arg=Arg,body=Body0}=Seq) ->
Body = opt_guard_try(Body0),
- case {Arg,Body} of
- {#c_call{module=#c_literal{val=Mod},
- name=#c_literal{val=Name},
- args=Args},#c_literal{val=false}} ->
+ WillFail = case Body of
+ #c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=error},
+ args=[_]} ->
+ true;
+ #c_literal{val=false} ->
+ true;
+ _ ->
+ false
+ end,
+ case Arg of
+ #c_call{module=#c_literal{val=Mod},
+ name=#c_literal{val=Name},
+ args=Args} when WillFail ->
%% We have sequence consisting of a call (evaluated
%% for a possible exception and/or side effect only),
- %% followed by 'false'.
+ %% followed by 'false' or a call to error/1.
%% Since the sequence is inside a try block that will
%% default to 'false' if any exception occurs, not
%% evalutating the call will not change the behaviour
@@ -193,7 +203,7 @@ opt_guard_try(#c_seq{arg=Arg,body=Body0}=Seq) ->
%% be safely removed.
Body
end;
- {_,_} ->
+ _ ->
Seq#c_seq{body=Body}
end;
opt_guard_try(#c_case{clauses=Cs}=Term) ->
@@ -363,7 +373,7 @@ expr(#c_case{}=Case0, Ctxt, Sub) ->
%% (in addition to any warnings that may have been emitted
%% according to the rules above).
%%
- case opt_bool_case(Case0) of
+ case opt_bool_case(Case0, Sub) of
#c_case{arg=Arg0,clauses=Cs0}=Case1 ->
Arg1 = body(Arg0, value, Sub),
LitExpr = cerl:is_literal(Arg1),
@@ -1142,7 +1152,13 @@ clause_1(#c_clause{guard=G0,body=B0}=Cl, Ps1, Cexpr, Ctxt, Sub1) ->
%%
%% case A of NewVar when true -> ...
%%
- sub_set_var(Var, Cexpr, Sub2);
+ case cerl:is_c_fname(Cexpr) of
+ false ->
+ sub_set_var(Var, Cexpr, Sub2);
+ true ->
+ %% We must not copy funs, and especially not into guards.
+ Sub2
+ end;
_ ->
Sub2
end,
@@ -1538,9 +1554,11 @@ will_match(E, [P]) ->
will_match_1({false,_}) -> maybe;
will_match_1({true,_}) -> yes.
-%% opt_bool_case(CoreExpr) - CoreExpr'.
-%% Do various optimizations to case statement that has a
-%% boolean case expression.
+%% opt_bool_case(CoreExpr, Sub) - CoreExpr'.
+%%
+%% In bodies, do various optimizations to case statements that have
+%% boolean case expressions. We don't do the optimizations in guards,
+%% because they would thwart the optimization in v3_kernel.
%%
%% We start with some simple optimizations and normalization
%% to facilitate later optimizations.
@@ -1549,7 +1567,7 @@ will_match_1({true,_}) -> yes.
%% (or fail), we can remove any clause that cannot
%% possibly match 'true' or 'false'. Also, any clause
%% following both 'true' and 'false' clause can
-%% be removed. If successful, we will end up this:
+%% be removed. If successful, we will end up like this:
%%
%% case BoolExpr of case BoolExpr of
%% true -> false ->
@@ -1560,8 +1578,11 @@ will_match_1({true,_}) -> yes.
%%
%% We give up if there are clauses with guards, or if there
%% is a variable clause that matches anything.
-%%
-opt_bool_case(#c_case{arg=Arg}=Case0) ->
+
+opt_bool_case(#c_case{}=Case, #sub{in_guard=true}) ->
+ %% v3_kernel does a better job without "help".
+ Case;
+opt_bool_case(#c_case{arg=Arg}=Case0, #sub{in_guard=false}) ->
case is_bool_expr(Arg) of
false ->
Case0;
@@ -1573,8 +1594,7 @@ opt_bool_case(#c_case{arg=Arg}=Case0) ->
impossible ->
Case0
end
- end;
-opt_bool_case(Core) -> Core.
+ end.
opt_bool_clauses(#c_case{clauses=Cs}=Case) ->
Case#c_case{clauses=opt_bool_clauses(Cs, false, false)}.
@@ -1590,16 +1610,14 @@ opt_bool_clauses(Cs, true, true) ->
[]
end;
opt_bool_clauses([#c_clause{pats=[#c_literal{val=Lit}],
- guard=#c_literal{val=true},
- body=B}=C0|Cs], SeenT, SeenF) ->
+ guard=#c_literal{val=true}}=C|Cs], SeenT, SeenF) ->
case is_boolean(Lit) of
false ->
%% Not a boolean - this clause can't match.
- add_warning(C0, nomatch_clause_type),
+ add_warning(C, nomatch_clause_type),
opt_bool_clauses(Cs, SeenT, SeenF);
true ->
%% This clause will match.
- C = C0#c_clause{body=opt_bool_case(B)},
case {Lit,SeenT,SeenF} of
{false,_,false} ->
[C|opt_bool_clauses(Cs, SeenT, true)];
@@ -2135,7 +2153,7 @@ letify(Bs, Body) ->
-spec opt_not_in_let(cerl:c_let()) -> cerl:cerl().
opt_not_in_let(#c_let{vars=[_]=Vs0,arg=Arg0,body=Body0}=Let) ->
- case opt_not_in_let(Vs0, Arg0, Body0) of
+ case opt_not_in_let_0(Vs0, Arg0, Body0) of
{[],#c_values{es=[]},Body} ->
Body;
{Vs,Arg,Body} ->
@@ -2143,13 +2161,7 @@ opt_not_in_let(#c_let{vars=[_]=Vs0,arg=Arg0,body=Body0}=Let) ->
end;
opt_not_in_let(Let) -> Let.
-%% opt_not_in_let(Vs, Arg, Body) -> {Vs',Arg',Body'}
-%% Try to optimize away a 'not' operator in a 'let'.
-
--spec opt_not_in_let([cerl:c_var()], cerl:cerl(), cerl:cerl()) ->
- {[cerl:c_var()],cerl:cerl(),cerl:cerl()}.
-
-opt_not_in_let([#c_var{name=V}]=Vs0, Arg0, Body0) ->
+opt_not_in_let_0([#c_var{name=V}]=Vs0, Arg0, Body0) ->
case cerl:type(Body0) of
call ->
%% let <V> = Expr in not V ==>
@@ -2180,9 +2192,7 @@ opt_not_in_let([#c_var{name=V}]=Vs0, Arg0, Body0) ->
end;
_ ->
{Vs0,Arg0,Body0}
- end;
-opt_not_in_let(Vs, Arg, Body) ->
- {Vs,Arg,Body}.
+ end.
opt_not_in_let_1(V, Call, Body) ->
case Call of
@@ -2230,14 +2240,14 @@ inverse_rel_op(_) -> no.
%% opt_bool_case_in_let(LetExpr) -> Core
-opt_bool_case_in_let(#c_let{vars=Vs,arg=Arg,body=B}=Let) ->
- opt_bool_case_in_let_1(Vs, Arg, B, Let).
+opt_bool_case_in_let(#c_let{vars=Vs,arg=Arg,body=B}=Let, Sub) ->
+ opt_bool_case_in_let_1(Vs, Arg, B, Let, Sub).
opt_bool_case_in_let_1([#c_var{name=V}], Arg,
- #c_case{arg=#c_var{name=V}}=Case0, Let) ->
+ #c_case{arg=#c_var{name=V}}=Case0, Let, Sub) ->
case is_simple_case_arg(Arg) of
true ->
- Case = opt_bool_case(Case0#c_case{arg=Arg}),
+ Case = opt_bool_case(Case0#c_case{arg=Arg}, Sub),
case core_lib:is_var_used(V, Case) of
false -> Case;
true -> Let
@@ -2245,7 +2255,7 @@ opt_bool_case_in_let_1([#c_var{name=V}], Arg,
false ->
Let
end;
-opt_bool_case_in_let_1(_, _, _, Let) -> Let.
+opt_bool_case_in_let_1(_, _, _, Let, _) -> Let.
%% is_simple_case_arg(Expr) -> true|false
%% Determine whether the Expr is simple enough to be worth
@@ -2378,9 +2388,7 @@ is_safe_bool_expr_list([], _, _) -> true.
%% as a let or a sequence, move the original let body into the complex
%% expression.
-simplify_let(#c_let{arg=Arg0}=Let0, Sub) ->
- Arg = opt_bool_case(Arg0),
- Let = Let0#c_let{arg=Arg},
+simplify_let(#c_let{arg=Arg}=Let, Sub) ->
move_let_into_expr(Let, Arg, Sub).
move_let_into_expr(#c_let{vars=InnerVs0,body=InnerBody0}=Inner,
@@ -2636,11 +2644,10 @@ opt_simple_let_0(#c_let{arg=Arg0}=Let, Ctxt, Sub) ->
opt_simple_let_1(#c_let{vars=Vs0,body=B0}=Let, Arg0, Ctxt, Sub0) ->
%% Optimise let and add new substitutions.
- {Vs1,Args,Sub1} = let_substs(Vs0, Arg0, Sub0),
- BodySub = update_let_types(Vs1, Args, Sub1),
- B1 = body(B0, Ctxt, BodySub),
- Arg1 = core_lib:make_values(Args),
- {Vs,Arg,B} = opt_not_in_let(Vs1, Arg1, B1),
+ {Vs,Args,Sub1} = let_substs(Vs0, Arg0, Sub0),
+ BodySub = update_let_types(Vs, Args, Sub1),
+ B = body(B0, Ctxt, BodySub),
+ Arg = core_lib:make_values(Args),
opt_simple_let_2(Let, Vs, Arg, B, B0, Ctxt, Sub1).
opt_simple_let_2(Let0, Vs0, Arg0, Body, PrevBody, Ctxt, Sub) ->
@@ -2681,8 +2688,7 @@ opt_simple_let_2(Let0, Vs0, Arg0, Body, PrevBody, Ctxt, Sub) ->
#c_seq{arg=Arg,body=Body};
true ->
Let1 = Let0#c_let{vars=Vs,arg=Arg1,body=Body},
- Let2 = opt_bool_case_in_let(Let1),
- opt_case_in_let_arg(Let2, Ctxt, Sub)
+ opt_bool_case_in_let(Let1, Sub)
end
end.
@@ -2810,48 +2816,6 @@ move_case_into_arg(#c_case{arg=#c_seq{arg=OuterArg,body=InnerArg}=Outer,
move_case_into_arg(_, _) ->
impossible.
-%% In guards only, rewrite a case in a let argument like
-%%
-%% let <Var> = case <> of
-%% <> when AnyGuard -> Literal1;
-%% <> when AnyGuard -> Literal2
-%% end
-%% in LetBody
-%%
-%% to
-%%
-%% case <> of
-%% <> when AnyGuard ->
-%% let <Var> = Literal1 in LetBody
-%% <> when 'true' ->
-%% let <Var> = Literal2 in LetBody
-%% end
-%%
-%% In the worst case, the size of the code could increase.
-%% In practice, though, substituting the literals into
-%% LetBody and doing constant folding will decrease the code
-%% size. (Doing this transformation outside of guards could
-%% lead to a substantational increase in code size.)
-%%
-opt_case_in_let_arg(#c_let{arg=#c_case{}=Case}=Let, Ctxt,
- #sub{in_guard=true}=Sub) ->
- opt_case_in_let_arg_1(Let, Case, Ctxt, Sub);
-opt_case_in_let_arg(Let, _, _) -> Let.
-
-opt_case_in_let_arg_1(Let0, #c_case{arg=#c_values{es=[]},
- clauses=Cs}=Case0, _Ctxt, _Sub) ->
- Let = mark_compiler_generated(Let0),
- case Cs of
- [#c_clause{body=#c_literal{}=BodyA}=Ca0,
- #c_clause{body=#c_literal{}=BodyB}=Cb0] ->
- Ca = Ca0#c_clause{body=Let#c_let{arg=BodyA}},
- Cb = Cb0#c_clause{body=Let#c_let{arg=BodyB}},
- Case0#c_case{clauses=[Ca,Cb]};
- _ ->
- Let
- end;
-opt_case_in_let_arg_1(Let, _, _, _) -> Let.
-
is_any_var_used([#c_var{name=V}|Vs], Expr) ->
case core_lib:is_var_used(V, Expr) of
false -> is_any_var_used(Vs, Expr);
@@ -3282,13 +3246,6 @@ bsm_problem(Where, What) ->
%%% Handling of warnings.
%%%
-mark_compiler_generated(Term) ->
- cerl_trees:map(fun mark_compiler_generated_1/1, Term).
-
-mark_compiler_generated_1(#c_call{anno=Anno}=Term) ->
- Term#c_call{anno=[compiler_generated|Anno--[compiler_generated]]};
-mark_compiler_generated_1(Term) -> Term.
-
init_warnings() ->
put({?MODULE,warnings}, []).
diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl
index c2e0c2bd1a..3627cdb7cd 100644
--- a/lib/compiler/src/v3_codegen.erl
+++ b/lib/compiler/src/v3_codegen.erl
@@ -363,7 +363,7 @@ bsm_rename_ctx(#l{ke={match,Ms0,Rs}}=L, Old, New, InProt) ->
bsm_rename_ctx(#l{ke={guard_match,Ms0,Rs}}=L, Old, New, InProt) ->
Ms = bsm_rename_ctx(Ms0, Old, New, InProt),
L#l{ke={guard_match,Ms,Rs}};
-bsm_rename_ctx(#l{ke={test,_,_}}=L, _, _, _) -> L;
+bsm_rename_ctx(#l{ke={test,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={bif,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={gc_bif,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={set,_,_}}=L, _, _, _) -> L;
@@ -1051,8 +1051,15 @@ guard_cg(#l{ke={protected,Ts,Rs},i=I,vdb=Pdb}, Fail, _Vdb, Bef, St) ->
protected_cg(Ts, Rs, Fail, I, Pdb, Bef, St);
guard_cg(#l{ke={block,Ts},i=I,vdb=Bdb}, Fail, _Vdb, Bef, St) ->
guard_cg_list(Ts, Fail, I, Bdb, Bef, St);
-guard_cg(#l{ke={test,Test,As},i=I,vdb=_Tdb}, Fail, Vdb, Bef, St) ->
- test_cg(Test, As, Fail, I, Vdb, Bef, St);
+guard_cg(#l{ke={test,Test,As,Inverted},i=I,vdb=_Tdb}, Fail, Vdb, Bef, St0) ->
+ case Inverted of
+ false ->
+ test_cg(Test, As, Fail, I, Vdb, Bef, St0);
+ true ->
+ {Psucc,St1} = new_label(St0),
+ {Is,Aft,St2} = test_cg(Test, As, Psucc, I, Vdb, Bef, St1),
+ {Is++[{jump,{f,Fail}},{label,Psucc}],Aft,St2}
+ end;
guard_cg(G, _Fail, Vdb, Bef, St) ->
%%ok = io:fwrite("cg ~w: ~p~n", [?LINE,{G,Fail,Vdb,Bef}]),
{Gis,Aft,St1} = cg(G, Vdb, Bef, St),
@@ -1103,6 +1110,13 @@ test_cg(is_map, [A], Fail, I, Vdb, Bef, St) ->
Arg = cg_reg_arg_prefer_y(A, Bef),
Aft = clear_dead(Bef, I, Vdb),
{[{test,is_map,{f,Fail},[Arg]}],Aft,St};
+test_cg(is_boolean, [{atom,Val}], Fail, I, Vdb, Bef, St) ->
+ Aft = clear_dead(Bef, I, Vdb),
+ Is = case is_boolean(Val) of
+ true -> [];
+ false -> [{jump,{f,Fail}}]
+ end,
+ {Is,Aft,St};
test_cg(Test, As, Fail, I, Vdb, Bef, St) ->
Args = cg_reg_args(As, Bef),
Aft = clear_dead(Bef, I, Vdb),
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index f40cf97f57..14cd41ae27 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -883,19 +883,33 @@ badmap_term(Map, #core{in_guard=false}) ->
c_tuple([#c_literal{val=badmap},Map]).
map_build_pairs(Map, Es0, Ann, St0) ->
- {Es,Pre,St1} = map_build_pairs_1(Es0, St0),
+ {Es,Pre,_,St1} = map_build_pairs_1(Es0, cerl_sets:new(), St0),
{ann_c_map(Ann, Map, Es),Pre,St1}.
-map_build_pairs_1([{Op0,L,K0,V0}|Es], St0) ->
+map_build_pairs_1([{Op0,L,K0,V0}|Es], Used0, St0) ->
{K,Pre0,St1} = safe(K0, St0),
{V,Pre1,St2} = safe(V0, St1),
- {Pairs,Pre2,St3} = map_build_pairs_1(Es, St2),
+ {Pairs,Pre2,Used1,St3} = map_build_pairs_1(Es, Used0, St2),
As = lineno_anno(L, St3),
Op = map_op(Op0),
+ {Used2,St4} = maybe_warn_repeated_keys(K, L, Used1, St3),
Pair = cerl:ann_c_map_pair(As, Op, K, V),
- {[Pair|Pairs],Pre0++Pre1++Pre2,St3};
-map_build_pairs_1([], St) ->
- {[],[],St}.
+ {[Pair|Pairs],Pre0++Pre1++Pre2,Used2,St4};
+map_build_pairs_1([], Used, St) ->
+ {[],[],Used,St}.
+
+maybe_warn_repeated_keys(Ck,Line,Used,St) ->
+ case cerl:is_literal(Ck) of
+ false -> {Used,St};
+ true ->
+ K = cerl:concrete(Ck),
+ case cerl_sets:is_element(K,Used) of
+ true ->
+ {Used, add_warning(Line, {map_key_repeated,K}, St)};
+ false ->
+ {cerl_sets:add_element(K,Used), St}
+ end
+ end.
map_op(map_field_assoc) -> #c_literal{val=assoc};
map_op(map_field_exact) -> #c_literal{val=exact}.
@@ -2603,7 +2617,11 @@ format_error(nomatch) ->
format_error(bad_binary) ->
"binary construction will fail because of a type mismatch";
format_error(badmap) ->
- "map construction will fail because of a type mismatch".
+ "map construction will fail because of a type mismatch";
+format_error({map_key_repeated,Key}) when is_atom(Key) ->
+ io_lib:format("key '~w' will be overridden in expression", [Key]);
+format_error({map_key_repeated,Key}) ->
+ io_lib:format("key ~p will be overridden in expression", [Key]).
add_warning(Anno, Term, #core{ws=Ws,file=[{file,File}]}=St) ->
case erl_anno:generated(Anno) of
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index f8e99905b5..2bfa610628 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -82,7 +82,7 @@
-export([module/2,format_error/1]).
-import(lists, [map/2,foldl/3,foldr/3,mapfoldl/3,splitwith/2,member/2,
- keymember/3,keyfind/3,partition/2,droplast/1,last/1]).
+ keymember/3,keyfind/3,partition/2,droplast/1,last/1,sort/1]).
-import(ordsets, [add_element/2,del_element/2,union/2,union/1,subtract/2]).
-import(cerl, [c_tuple/1]).
@@ -190,9 +190,479 @@ body(Ce, Sub, St0) ->
guard(G0, Sub, St0) ->
{G1,St1} = wrap_guard(G0, St0),
{Ge0,Pre,St2} = expr(G1, Sub, St1),
- {Ge,St} = gexpr_test(Ge0, St2),
+ {Ge1,St3} = gexpr_test(Ge0, St2),
+ {Ge,St} = guard_opt(Ge1, St3),
{pre_seq(Pre, Ge),St}.
+%% guard_opt(Kexpr, State) -> {Kexpr,State}.
+%% Optimize the Kexpr for the guard. Instead of evaluating a boolean
+%% expression comparing it to 'true' in a final #k_test{},
+%% replace BIF calls with #k_test{} in the expression.
+%%
+%% As an example, take the guard:
+%%
+%% when is_integer(V0), is_atom(V1) ->
+%%
+%% The unoptimized Kexpr translated to pseudo BEAM assembly
+%% code would look like:
+%%
+%% bif is_integer V0 => Bool0
+%% bif is_atom V1 => Bool1
+%% bif and Bool0 Bool1 => Bool
+%% test Bool =:= true else goto Fail
+%% ...
+%% Fail:
+%% ...
+%%
+%% The optimized code would look like:
+%%
+%% test is_integer V0 else goto Fail
+%% test is_atom V1 else goto Fail
+%% ...
+%% Fail:
+%% ...
+%%
+%% An 'or' operation is only slightly more complicated:
+%%
+%% test is_integer V0 else goto NotFailedYet
+%% goto Success
+%%
+%% NotFailedYet:
+%% test is_atom V1 else goto Fail
+%%
+%% Success:
+%% ...
+%% Fail:
+%% ...
+
+guard_opt(G, St0) ->
+ {Root,Forest0,St1} = make_forest(G, St0),
+ {Exprs,Forest,St} = rewrite_bool(Root, Forest0, false, St1),
+ E = forest_pre_seq(Exprs, Forest),
+ {G#k_try{arg=E},St}.
+
+%% rewrite_bool(Kexpr, Forest, Inv, St) -> {[Kexpr],Forest,St}.
+%% Rewrite Kexpr to use #k_test{} operations instead of comparison
+%% and type test BIFs.
+%%
+%% If Kexpr is a #k_test{} operation, the call will always
+%% succeed. Otherwise, a 'not_possible' exception will be
+%% thrown if Kexpr cannot be rewritten.
+
+rewrite_bool(#k_test{op=#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val='=:='}},
+ args=[#k_var{}=V,#k_atom{val=true}]}=Test, Forest0, Inv, St0) ->
+ try rewrite_bool_var(V, Forest0, Inv, St0) of
+ {_,_,_}=Res ->
+ Res
+ catch
+ throw:not_possible ->
+ {[Test],Forest0,St0}
+ end;
+rewrite_bool(#k_test{op=#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val='=:='}},
+ args=[#k_var{}=V,#k_atom{val=false}]}=Test, Forest0, Inv, St0) ->
+ try rewrite_bool_var(V, Forest0, not Inv, St0) of
+ {_,_,_}=Res ->
+ Res
+ catch
+ throw:not_possible ->
+ {[Test],Forest0,St0}
+ end;
+rewrite_bool(#k_test{op=#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val='=:='}},
+ args=[#k_atom{val=V1},#k_atom{val=V2}]}, Forest0, false, St0) ->
+ case V1 =:= V2 of
+ true ->
+ {[make_test(is_boolean, [#k_atom{val=true}])],Forest0,St0};
+ false ->
+ {[make_failing_test()],Forest0,St0}
+ end;
+rewrite_bool(#k_test{}=Test, Forest, false, St) ->
+ {[Test],Forest,St};
+rewrite_bool(#k_try{vars=[#k_var{name=X}],body=#k_var{name=X},
+ handler=#k_atom{val=false},ret=[]}=Prot,
+ Forest0, Inv, St0) ->
+ {Root,Forest1,St1} = make_forest(Prot, Forest0, St0),
+ {Exprs,Forest2,St} = rewrite_bool(Root, Forest1, Inv, St1),
+ InnerForest = maps:without(maps:keys(Forest0), Forest2),
+ Forest = maps:without(maps:keys(InnerForest), Forest2),
+ E = forest_pre_seq(Exprs, InnerForest),
+ {[Prot#k_try{arg=E}],Forest,St};
+rewrite_bool(#k_match{body=Body,ret=[]}, Forest, Inv, St) ->
+ rewrite_match(Body, Forest, Inv, St);
+rewrite_bool(Other, Forest, Inv, St) ->
+ case extract_bif(Other) of
+ {Name,Args} ->
+ rewrite_bif(Name, Args, Forest, Inv, St);
+ error ->
+ throw(not_possible)
+ end.
+
+%% rewrite_bool_var(Var, Forest, Inv, St) -> {[Kexpr],Forest,St}.
+%% Rewrite the boolean expression whose key in Forest is
+%% given by Var. Throw a 'not_possible' expression if something
+%% prevents the rewriting.
+
+rewrite_bool_var(Arg, Forest0, Inv, St) ->
+ {Expr,Forest} = forest_take_expr(Arg, Forest0),
+ rewrite_bool(Expr, Forest, Inv, St).
+
+%% rewrite_bool_args([Kexpr], Forest, Inv, St) -> {[[Kexpr]],Forest,St}.
+%% Rewrite each Kexpr in the list. The input Kexpr should be variables
+%% or boolean values. Throw a 'not_possible' expression if something
+%% prevents the rewriting.
+%%
+%% This function is suitable for handling the arguments for both
+%% 'and' and 'or'.
+
+rewrite_bool_args([#k_atom{val=B}=A|Vs], Forest0, false=Inv, St0) when is_boolean(B) ->
+ {Tail,Forest1,St1} = rewrite_bool_args(Vs, Forest0, Inv, St0),
+ Bif = make_bif('=:=', [A,#k_atom{val=true}]),
+ {Exprs,Forest,St} = rewrite_bool(Bif, Forest1, Inv, St1),
+ {[Exprs|Tail],Forest,St};
+rewrite_bool_args([#k_var{}=Var|Vs], Forest0, false=Inv, St0) ->
+ {Tail,Forest1,St1} = rewrite_bool_args(Vs, Forest0, Inv, St0),
+ {Exprs,Forest,St} =
+ case is_bool_expr(Var, Forest0) of
+ true ->
+ rewrite_bool_var(Var, Forest1, Inv, St1);
+ false ->
+ Bif = make_bif('=:=', [Var,#k_atom{val=true}]),
+ rewrite_bool(Bif, Forest1, Inv, St1)
+ end,
+ {[Exprs|Tail],Forest,St};
+rewrite_bool_args([_|_], _Forest, _Inv, _St) ->
+ throw(not_possible);
+rewrite_bool_args([], Forest, _Inv, St) ->
+ {[],Forest,St}.
+
+%% rewrite_bif(Name, [Kexpr], Forest, Inv, St) -> {[Kexpr],Forest,St}.
+%% Rewrite a BIF. Throw a 'not_possible' expression if something
+%% prevents the rewriting.
+
+rewrite_bif('or', Args, Forest, true, St) ->
+ rewrite_not_args('and', Args, Forest, St);
+rewrite_bif('and', Args, Forest, true, St) ->
+ rewrite_not_args('or', Args, Forest, St);
+rewrite_bif('and', [#k_atom{val=Val},Arg], Forest0, Inv, St0) ->
+ false = Inv, %Assertion.
+ case Val of
+ true ->
+ %% The result only depends on Arg.
+ rewrite_bool_var(Arg, Forest0, Inv, St0);
+ _ ->
+ %% Will fail. There is no need to evalute the expression
+ %% represented by Arg. Take it out from the forest and
+ %% discard the expression.
+ Failing = make_failing_test(),
+ try rewrite_bool_var(Arg, Forest0, Inv, St0) of
+ {_,Forest,St} ->
+ {[Failing],Forest,St}
+ catch
+ throw:not_possible ->
+ try forest_take_expr(Arg, Forest0) of
+ {_,Forest} ->
+ {[Failing],Forest,St0}
+ catch
+ throw:not_possible ->
+ %% Arg is probably a variable bound in an
+ %% outer scope.
+ {[Failing],Forest0,St0}
+ end
+ end
+ end;
+rewrite_bif('and', [Arg,#k_atom{}=Atom], Forest, Inv, St) ->
+ false = Inv, %Assertion.
+ rewrite_bif('and', [Atom,Arg], Forest, Inv, St);
+rewrite_bif('and', Args, Forest0, Inv, St0) ->
+ false = Inv, %Assertion.
+ {[Es1,Es2],Forest,St} = rewrite_bool_args(Args, Forest0, Inv, St0),
+ {Es1 ++ Es2,Forest,St};
+rewrite_bif('or', Args, Forest0, Inv, St0) ->
+ false = Inv, %Assertion.
+ {[First,Then],Forest,St} = rewrite_bool_args(Args, Forest0, Inv, St0),
+ Alt = make_alt(First, Then),
+ {[Alt],Forest,St};
+rewrite_bif('xor', [_,_], _Forest, _Inv, _St) ->
+ %% Rewriting 'xor' is not practical. Fortunately, 'xor' is
+ %% almost never used in practice.
+ throw(not_possible);
+rewrite_bif('not', [Arg], Forest0, Inv, St) ->
+ {Expr,Forest} = forest_take_expr(Arg, Forest0),
+ rewrite_bool(Expr, Forest, not Inv, St);
+rewrite_bif(Op, Args, Forest, Inv, St) ->
+ case is_test(Op, Args) of
+ true ->
+ rewrite_bool(make_test(Op, Args, Inv), Forest, false, St);
+ false ->
+ throw(not_possible)
+ end.
+
+rewrite_not_args(Op, [A0,B0], Forest0, St0) ->
+ {A,Forest1,St1} = rewrite_not_args_1(A0, Forest0, St0),
+ {B,Forest2,St2} = rewrite_not_args_1(B0, Forest1, St1),
+ rewrite_bif(Op, [A,B], Forest2, false, St2).
+
+rewrite_not_args_1(Arg, Forest, St) ->
+ Not = make_bif('not', [Arg]),
+ forest_add_expr(Not, Forest, St).
+
+%% rewrite_match(Kvar, TypeClause, Forest, Inv, St) ->
+%% {[Kexpr],Forest,St}.
+%% Try to rewrite a #k_match{} originating from an 'andalso' or an 'orelse'.
+
+rewrite_match(#k_alt{first=First,then=Then}, Forest, Inv, St) ->
+ case {First,Then} of
+ {#k_select{var=#k_var{name=V}=Var,types=[TypeClause]},#k_var{name=V}} ->
+ rewrite_match_1(Var, TypeClause, Forest, Inv, St);
+ {_,_} ->
+ throw(not_possible)
+ end.
+
+rewrite_match_1(Var, #k_type_clause{values=Cs0}, Forest0, Inv, St0) ->
+ Cs = sort([{Val,B} || #k_val_clause{val=#k_atom{val=Val},body=B} <- Cs0]),
+ case Cs of
+ [{false,False},{true,True}] ->
+ rewrite_match_2(Var, False, True, Forest0, Inv, St0);
+ _ ->
+ throw(not_possible)
+ end.
+
+rewrite_match_2(Var, False, #k_atom{val=true}, Forest0, Inv, St0) ->
+ %% Originates from an 'orelse'.
+ case False of
+ #k_atom{val=NotBool} when not is_boolean(NotBool) ->
+ rewrite_bool(Var, Forest0, Inv, St0);
+ _ ->
+ {CodeVar,Forest1,St1} = add_protected_expr(False, Forest0, St0),
+ rewrite_bif('or', [Var,CodeVar], Forest1, Inv, St1)
+ end;
+rewrite_match_2(Var, #k_atom{val=false}, True, Forest0, Inv, St0) ->
+ %% Originates from an 'andalso'.
+ {CodeVar,Forest1,St1} = add_protected_expr(True, Forest0, St0),
+ rewrite_bif('and', [Var,CodeVar], Forest1, Inv, St1);
+rewrite_match_2(_V, _, _, _Forest, _Inv, _St) ->
+ throw(not_possible).
+
+%% is_bool_expr(#k_var{}, Forest) -> true|false.
+%% Return true if the variable refers to a boolean expression
+%% that does not need an explicit '=:= true' test.
+
+is_bool_expr(V, Forest) ->
+ case forest_peek_expr(V, Forest) of
+ error ->
+ %% Defined outside of the guard. We can't know.
+ false;
+ Expr ->
+ case extract_bif(Expr) of
+ {Name,Args} ->
+ is_test(Name, Args) orelse
+ erl_internal:bool_op(Name, length(Args));
+ error ->
+ %% Not a BIF. Should be possible to rewrite
+ %% to a boolean. Definitely does not need
+ %% a '=:= true' test.
+ true
+ end
+ end.
+
+make_bif(Op, Args) ->
+ #k_bif{op=#k_remote{mod=#k_atom{val=erlang},
+ name=#k_atom{val=Op},
+ arity=length(Args)},
+ args=Args}.
+
+extract_bif(#k_bif{op=#k_remote{mod=#k_atom{val=erlang},
+ name=#k_atom{val=Name}},
+ args=Args}) ->
+ {Name,Args};
+extract_bif(_) ->
+ error.
+
+%% make_alt(First, Then) -> KMatch.
+%% Make a #k_alt{} within a #k_match{} to implement
+%% 'or' or 'orelse'.
+
+make_alt(First0, Then0) ->
+ First1 = pre_seq(droplast(First0), last(First0)),
+ Then1 = pre_seq(droplast(Then0), last(Then0)),
+ First2 = make_protected(First1),
+ Then2 = make_protected(Then1),
+ Body = #k_atom{val=ignored},
+ First3 = #k_guard_clause{guard=First2,body=Body},
+ Then3 = #k_guard_clause{guard=Then2,body=Body},
+ First = #k_guard{clauses=[First3]},
+ Then = #k_guard{clauses=[Then3]},
+ Alt = #k_alt{first=First,then=Then},
+ #k_match{vars=[],body=Alt}.
+
+add_protected_expr(#k_atom{}=Atom, Forest, St) ->
+ {Atom,Forest,St};
+add_protected_expr(#k_var{}=Var, Forest, St) ->
+ {Var,Forest,St};
+add_protected_expr(E0, Forest, St) ->
+ E = make_protected(E0),
+ forest_add_expr(E, Forest, St).
+
+make_protected(#k_try{}=Try) ->
+ Try;
+make_protected(B) ->
+ #k_try{arg=B,vars=[#k_var{name=''}],body=#k_var{name=''},
+ handler=#k_atom{val=false}}.
+
+make_failing_test() ->
+ make_test(is_boolean, [#k_atom{val=fail}]).
+
+make_test(Op, Args) ->
+ make_test(Op, Args, false).
+
+make_test(Op, Args, Inv) ->
+ Remote = #k_remote{mod=#k_atom{val=erlang},
+ name=#k_atom{val=Op},
+ arity=length(Args)},
+ #k_test{op=Remote,args=Args,inverted=Inv}.
+
+is_test(Op, Args) ->
+ A = length(Args),
+ erl_internal:new_type_test(Op, A) orelse erl_internal:comp_op(Op, A).
+
+%% make_forest(Kexpr, St) -> {RootKexpr,Forest,St}.
+%% Build a forest out of Kexpr. RootKexpr is the final expression
+%% nested inside Kexpr.
+
+make_forest(G, St) ->
+ make_forest_1(G, #{}, 0, St).
+
+%% make_forest(Kexpr, St) -> {RootKexpr,Forest,St}.
+%% Add to Forest from Kexpr. RootKexpr is the final expression
+%% nested inside Kexpr.
+
+make_forest(G, Forest0, St) ->
+ N = forest_next_index(Forest0),
+ make_forest_1(G, Forest0, N, St).
+
+make_forest_1(#k_try{arg=B}, Forest, I, St) ->
+ make_forest_1(B, Forest, I, St);
+make_forest_1(#iset{vars=[]}=Iset0, Forest, I, St0) ->
+ {UnrefVar,St} = new_var(St0),
+ Iset = Iset0#iset{vars=[UnrefVar]},
+ make_forest_1(Iset, Forest, I, St);
+make_forest_1(#iset{vars=[#k_var{name=V}],arg=Arg,body=B}, Forest0, I, St) ->
+ Forest = Forest0#{V => {I,Arg}, {untaken,V} => true},
+ make_forest_1(B, Forest, I+1, St);
+make_forest_1(Innermost, Forest, _I, St) ->
+ {Innermost,Forest,St}.
+
+%% forest_take_expr(Kexpr, Forest) -> {Expr,Forest}.
+%% If Kexpr is a variable, take out the expression corresponding
+%% to variable in Forest. Expressions that have been taken out
+%% of the forest will not be included the Kexpr returned
+%% by forest_pre_seq/2.
+%%
+%% Throw a 'not_possible' exception if Kexpr is not a variable or
+%% if the name of the variable is not a key in Forest.
+
+forest_take_expr(#k_var{name=V}, Forest0) ->
+ %% v3_core currently always generates guard expressions that can
+ %% be represented as a tree. Other code generators (such as LFE)
+ %% could generate guard expressions that can only be represented
+ %% as a DAG (i.e. some nodes are referenced more than once). To
+ %% handle DAGs, we must never remove a node from the forest, but
+ %% just remove the {untaken,V} marker. That will effectively convert
+ %% the DAG to a tree by duplicating the shared nodes and their
+ %% descendants.
+
+ case maps:find(V, Forest0) of
+ {ok,{_,Expr}} ->
+ Forest = maps:remove({untaken,V}, Forest0),
+ {Expr,Forest};
+ error ->
+ throw(not_possible)
+ end;
+forest_take_expr(_, _) ->
+ throw(not_possible).
+
+%% forest_peek_expr(Kvar, Forest) -> Kexpr | error.
+%% Return the expression corresponding to Kvar in Forest or
+%% return 'error' if there is a corresponding expression.
+
+forest_peek_expr(#k_var{name=V}, Forest0) ->
+ case maps:find(V, Forest0) of
+ {ok,{_,Expr}} -> Expr;
+ error -> error
+ end.
+
+%% forest_add_expr(Kexpr, Forest, St) -> {Kvar,Forest,St}.
+%% Add a new expression to Forest.
+
+forest_add_expr(Expr, Forest0, St0) ->
+ {#k_var{name=V}=Var,St} = new_var(St0),
+ N = forest_next_index(Forest0),
+ Forest = Forest0#{V => {N,Expr}},
+ {Var,Forest,St}.
+
+forest_next_index(Forest) ->
+ 1 + lists:max([N || {N,_} <- maps:values(Forest),
+ is_integer(N)] ++ [0]).
+
+%% forest_pre_seq([Kexpr], Forest) -> Kexpr.
+%% Package the list of Kexprs into a nested Kexpr, prepending all
+%% expressions in Forest that have not been taken out using
+%% forest_take_expr/2.
+
+forest_pre_seq(Exprs, Forest) ->
+ Es0 = [#k_var{name=V} || {untaken,V} <- maps:keys(Forest)],
+ Es = Es0 ++ Exprs,
+ Vs = extract_all_vars(Es, Forest, []),
+ Pre0 = sort([{maps:get(V, Forest),V} || V <- Vs]),
+ Pre = [#iset{vars=[#k_var{name=V}],arg=A} ||
+ {{_,A},V} <- Pre0],
+ pre_seq(Pre++droplast(Exprs), last(Exprs)).
+
+extract_all_vars(Es, Forest, Acc0) ->
+ case extract_var_list(Es) of
+ [] ->
+ Acc0;
+ [_|_]=Vs0 ->
+ Vs = [V || V <- Vs0, maps:is_key(V, Forest)],
+ NewVs = ordsets:subtract(Vs, Acc0),
+ NewEs = [begin
+ {_,E} = maps:get(V, Forest),
+ E
+ end || V <- NewVs],
+ Acc = union(NewVs, Acc0),
+ extract_all_vars(NewEs, Forest, Acc)
+ end.
+
+extract_vars(#iset{arg=A,body=B}) ->
+ union(extract_vars(A), extract_vars(B));
+extract_vars(#k_bif{args=Args}) ->
+ ordsets:from_list(lit_list_vars(Args));
+extract_vars(#k_call{}) ->
+ [];
+extract_vars(#k_test{args=Args}) ->
+ ordsets:from_list(lit_list_vars(Args));
+extract_vars(#k_match{body=Body}) ->
+ extract_vars(Body);
+extract_vars(#k_alt{first=First,then=Then}) ->
+ union(extract_vars(First), extract_vars(Then));
+extract_vars(#k_guard{clauses=Cs}) ->
+ extract_var_list(Cs);
+extract_vars(#k_guard_clause{guard=G}) ->
+ extract_vars(G);
+extract_vars(#k_select{var=Var,types=Types}) ->
+ union(ordsets:from_list(lit_vars(Var)),
+ extract_var_list(Types));
+extract_vars(#k_type_clause{values=Values}) ->
+ extract_var_list(Values);
+extract_vars(#k_val_clause{body=Body}) ->
+ extract_vars(Body);
+extract_vars(#k_try{arg=Arg}) ->
+ extract_vars(Arg);
+extract_vars(Lit) ->
+ ordsets:from_list(lit_vars(Lit)).
+
+extract_var_list(L) ->
+ union([extract_vars(E) || E <- L]).
+
%% Wrap the entire guard in a try/catch if needed.
wrap_guard(#c_try{}=Try, St) -> {Try,St};
diff --git a/lib/compiler/src/v3_kernel.hrl b/lib/compiler/src/v3_kernel.hrl
index 1169a69117..7cd30b25a8 100644
--- a/lib/compiler/src/v3_kernel.hrl
+++ b/lib/compiler/src/v3_kernel.hrl
@@ -58,7 +58,7 @@
-record(k_seq, {anno=[],arg,body}).
-record(k_put, {anno=[],arg,ret=[]}).
-record(k_bif, {anno=[],op,args,ret=[]}).
--record(k_test, {anno=[],op,args}).
+-record(k_test, {anno=[],op,args,inverted=false}).
-record(k_call, {anno=[],op,args,ret=[]}).
-record(k_enter, {anno=[],op,args}).
-record(k_receive, {anno=[],var,body,timeout,action,ret=[]}).
diff --git a/lib/compiler/src/v3_kernel_pp.erl b/lib/compiler/src/v3_kernel_pp.erl
index 45065b7e11..d5f6ee19c9 100644
--- a/lib/compiler/src/v3_kernel_pp.erl
+++ b/lib/compiler/src/v3_kernel_pp.erl
@@ -235,8 +235,13 @@ format_1(#k_bif{op=Op,args=As,ret=Rs}, Ctxt) ->
[Txt,format_args(As, Ctxt1),
format_ret(Rs, Ctxt1)
];
-format_1(#k_test{op=Op,args=As}, Ctxt) ->
- Txt = ["test (",format(Op, ctxt_bump_indent(Ctxt, 6)),$)],
+format_1(#k_test{op=Op,args=As,inverted=Inverted}, Ctxt) ->
+ Txt = case Inverted of
+ false ->
+ ["test (",format(Op, ctxt_bump_indent(Ctxt, 6)),$)];
+ true ->
+ ["inverted_test (",format(Op, ctxt_bump_indent(Ctxt, 6)),$)]
+ end,
Ctxt1 = ctxt_bump_indent(Ctxt, 2),
[Txt,format_args(As, Ctxt1)];
format_1(#k_put{arg=A,ret=Rs}, Ctxt) ->
diff --git a/lib/compiler/src/v3_life.erl b/lib/compiler/src/v3_life.erl
index 4337ec732c..0f2aeda87f 100644
--- a/lib/compiler/src/v3_life.erl
+++ b/lib/compiler/src/v3_life.erl
@@ -118,8 +118,8 @@ protected(#k_protected{anno=A,arg=Ts,ret=Rs}, I, Vdb) ->
%% expr(Kexpr, I, Vdb) -> Expr.
-expr(#k_test{anno=A,op=Op,args=As}, I, _Vdb) ->
- #l{ke={test,test_op(Op),atomic_list(As)},i=I,a=A#k.a};
+expr(#k_test{anno=A,op=Op,args=As,inverted=Inverted}, I, _Vdb) ->
+ #l{ke={test,test_op(Op),atomic_list(As),Inverted},i=I,a=A#k.a};
expr(#k_call{anno=A,op=Op,args=As,ret=Rs}, I, _Vdb) ->
#l{ke={call,call_op(Op),atomic_list(As),var_list(Rs)},i=I,a=A#k.a};
expr(#k_enter{anno=A,op=Op,args=As}, I, _Vdb) ->
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index de06e8760f..e338dbb4e3 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -9,7 +9,6 @@ MODULES= \
andor_SUITE \
apply_SUITE \
beam_block_SUITE \
- beam_bool_SUITE \
beam_validator_SUITE \
beam_disasm_SUITE \
beam_except_SUITE \
@@ -49,7 +48,6 @@ NO_OPT= \
andor \
apply \
beam_block \
- beam_bool \
beam_except \
beam_jump \
beam_reorder \
@@ -76,7 +74,6 @@ INLINE= \
andor \
apply \
beam_block \
- beam_bool \
beam_utils \
bif \
bs_bincomp \
@@ -96,6 +93,10 @@ INLINE= \
receive \
record
+CORE_MODULES = \
+ lfe_andor_SUITE \
+ lfe_guard_SUITE
+
NO_OPT_MODULES= $(NO_OPT:%=%_no_opt_SUITE)
NO_OPT_ERL_FILES= $(NO_OPT_MODULES:%=%.erl)
POST_OPT_MODULES= $(NO_OPT:%=%_post_opt_SUITE)
@@ -104,6 +105,8 @@ INLINE_MODULES= $(INLINE:%=%_inline_SUITE)
INLINE_ERL_FILES= $(INLINE_MODULES:%=%.erl)
ERL_FILES= $(MODULES:%=%.erl)
+CORE_FILES= $(CORE_MODULES:%=%.core)
+ERL_DUMMY_FILES= $(CORE_MODULES:%=%.erl)
##TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
##INSTALL_PROGS= $(TARGET_FILES)
@@ -137,6 +140,8 @@ make_emakefile: $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) $(INLINE_ERL_FILES)
-o$(EBIN) $(POST_OPT_MODULES) >> $(EMAKEFILE)
$(ERL_TOP)/make/make_emakefile +inline $(ERL_COMPILE_FLAGS) \
-o$(EBIN) $(INLINE_MODULES) >> $(EMAKEFILE)
+ $(ERL_TOP)/make/make_emakefile +from_core $(ERL_COMPILE_FLAGS) \
+ -o$(EBIN) $(CORE_MODULES) >> $(EMAKEFILE)
tests debug opt: make_emakefile
erl $(ERL_MAKE_FLAGS) -make
@@ -174,6 +179,12 @@ release_tests_spec: make_emakefile
$(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)"
$(INSTALL_DATA) $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) \
$(INLINE_ERL_FILES) "$(RELSYSDIR)"
+ $(INSTALL_DATA) $(CORE_FILES) "$(RELSYSDIR)"
+ for file in $(ERL_DUMMY_FILES); do \
+ module=`basename $$file .erl`; \
+ echo "-module($$module). %% dummy .erl file" >$$file; \
+ done
+ $(INSTALL_DATA) $(ERL_DUMMY_FILES) "$(RELSYSDIR)"
chmod -R u+w "$(RELSYSDIR)"
@tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
diff --git a/lib/compiler/test/beam_bool_SUITE.erl b/lib/compiler/test/beam_bool_SUITE.erl
deleted file mode 100644
index e585eaedb5..0000000000
--- a/lib/compiler/test/beam_bool_SUITE.erl
+++ /dev/null
@@ -1,197 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(beam_bool_SUITE).
-
--export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
- init_per_group/2,end_per_group/2,
- before_and_inside_if/1,
- scotland/1,y_registers/1,protected/1,
- maps/1]).
-
-suite() ->
- [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- test_lib:recompile(?MODULE),
- [{group,p}].
-
-groups() ->
- [{p,[parallel],
- [before_and_inside_if,
- scotland,
- y_registers,
- protected,
- maps
- ]}].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-before_and_inside_if(_Config) ->
- no = before_and_inside_if([a], [b], delete),
- no = before_and_inside_if([a], [b], x),
- no = before_and_inside_if([a], [], delete),
- no = before_and_inside_if([a], [], x),
- no = before_and_inside_if([], [], delete),
- yes = before_and_inside_if([], [], x),
- yes = before_and_inside_if([], [b], delete),
- yes = before_and_inside_if([], [b], x),
-
- {ch1,ch2} = before_and_inside_if_2([a], [b], blah),
- {ch1,ch2} = before_and_inside_if_2([a], [b], xx),
- {ch1,ch2} = before_and_inside_if_2([a], [], blah),
- {ch1,ch2} = before_and_inside_if_2([a], [], xx),
- {no,no} = before_and_inside_if_2([], [b], blah),
- {no,no} = before_and_inside_if_2([], [b], xx),
- {ch1,no} = before_and_inside_if_2([], [], blah),
- {no,ch2} = before_and_inside_if_2([], [], xx),
- ok.
-
-%% Thanks to Simon Cornish and Kostis Sagonas.
-%% Used to crash beam_bool.
-before_and_inside_if(XDo1, XDo2, Do3) ->
- Do1 = (XDo1 =/= []),
- Do2 = (XDo2 =/= []),
- if
- %% This expression occurs in a try/catch (protected)
- %% block, which cannot refer to variables outside of
- %% the block that are boolean expressions.
- Do1 =:= true;
- Do1 =:= false, Do2 =:= false, Do3 =:= delete ->
- no;
- true ->
- yes
- end.
-
-%% Thanks to Simon Cornish.
-%% Used to generate code that would not set {y,0} on
-%% all paths before its use (and therefore fail
-%% validation by the beam_validator).
-before_and_inside_if_2(XDo1, XDo2, Do3) ->
- Do1 = (XDo1 =/= []),
- Do2 = (XDo2 =/= []),
- CH1 = if Do1 == true;
- Do1 == false,Do2==false,Do3 == blah ->
- ch1;
- true ->
- no
- end,
- CH2 = if Do1 == true;
- Do1 == false,Do2==false,Do3 == xx ->
- ch2;
- true ->
- no
- end,
- {CH1,CH2}.
-
-
-%% beam_bool would remove the initialization of {y,0}.
-%% (Thanks to Thomas Arts and QuickCheck.)
-
-scotland(_Config) ->
- million = do_scotland(placed),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(false)),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(true)),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(echo)),
- ok.
-
-do_scotland(Echo) ->
- found(case Echo of
- Echo when true; Echo, Echo, Echo ->
- Echo;
- echo ->
- []
- end,
- Echo = placed).
-
-found(_, _) -> million.
-
-
-%% ERL-143: beam_bool could not handle Y registers as a destination.
-y_registers(_Config) ->
- {'EXIT',{badarith,[_|_]}} = (catch baker(valentine)),
- {'EXIT',{badarith,[_|_]}} = (catch baker(clementine)),
-
- {not_ok,true} = potter([]),
- {ok,false} = potter([{encoding,any}]),
-
- ok.
-
-%% Thanks to Quickcheck.
-baker(Baker) ->
- (valentine == Baker) +
- case Baker of
- Baker when Baker; Baker ->
- Baker;
- Baker ->
- []
- end.
-
-%% Thanks to Jose Valim.
-potter(Modes) ->
- Raw = lists:keyfind(encoding, 1, Modes) == false,
- Final = case Raw of
- X when X == false; X == nil -> ok;
- _ -> not_ok
- end,
- {Final,Raw}.
-
-protected(_Config) ->
- {'EXIT',{if_clause,_}} = (catch photographs({1, surprise, true}, opinions)),
-
- {{true}} = welcome({perfect, true}),
- {'EXIT',{if_clause,_}} = (catch welcome({perfect, false})),
- ok.
-
-photographs({_Violation, surprise, Deep}, opinions) ->
- {if
- 0; "here", Deep ->
- Deep = Deep
- end}.
-
-welcome({perfect, Profit}) ->
- if
- Profit, Profit, Profit; 0 ->
- {id({Profit})}
- end.
-
-maps(_Config) ->
- ok = evidence(#{0 => 42}).
-
-%% Cover handling of put_map in in split_block_label_used/2.
-evidence(#{0 := Charge}) when 0; #{[] => Charge} == #{[] => 42} ->
- ok.
-
-
-%%%
-%%% Common utilities.
-%%%
-
-id(I) ->
- I.
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 6742571b86..89f851ac3b 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -887,28 +887,41 @@ matching_and_andalso(Config) when is_list(Config) ->
{'EXIT',{function_clause,_}} = (catch matching_and_andalso_1(<<1,2,3>>, blurf)),
{'EXIT',{function_clause,_}} = (catch matching_and_andalso_1(<<1,2,3>>, 19)),
- {"abc",<<"xyz">>} = matching_and_andalso_2("abc", <<"-xyz">>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($a-1)>>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($z+1)>>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($A-1)>>),
- {"abc",<<"">>} = matching_and_andalso_2("abc", <<($Z+1)>>),
- error = matching_and_andalso_2([], <<>>),
- error = matching_and_andalso_2([], <<$A>>),
- error = matching_and_andalso_2([], <<$Z>>),
- error = matching_and_andalso_2([], <<$a>>),
- error = matching_and_andalso_2([], <<$z>>),
+ {"abc",<<"xyz">>} = matching_and_andalso_23("abc", <<"-xyz">>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($a-1)>>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($z+1)>>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($A-1)>>),
+ {"abc",<<"">>} = matching_and_andalso_23("abc", <<($Z+1)>>),
+ error = matching_and_andalso_23([], <<>>),
+ error = matching_and_andalso_23([], <<$A>>),
+ error = matching_and_andalso_23([], <<$Z>>),
+ error = matching_and_andalso_23([], <<$a>>),
+ error = matching_and_andalso_23([], <<$z>>),
ok.
matching_and_andalso_1(<<Bitmap/binary>>, K)
when is_integer(K) andalso size(Bitmap) >= K andalso 0 < K ->
ok.
+matching_and_andalso_23(Datetime, Bin) ->
+ Res = matching_and_andalso_2(Datetime, Bin),
+ Res = matching_and_andalso_3(Datetime, Bin),
+ Res.
+
matching_and_andalso_2(Datetime, <<H,T/binary>>)
when not ((H >= $a) andalso (H =< $z)) andalso
not ((H >= $A) andalso (H =< $Z)) ->
{Datetime,T};
matching_and_andalso_2(_, _) -> error.
+%% Contrived example to ensure we cover the handling of 'call' instructions
+%% in v3_codegen:bsm_rename_ctx/4.
+matching_and_andalso_3(Datetime, <<H,T/binary>>)
+ when not ((abs(H) >= $a) andalso (abs(H) =< $z)) andalso
+ not ((abs(H) >= $A) andalso (abs(H) =< $Z)) ->
+ {Datetime,T};
+matching_and_andalso_3(_, _) -> error.
+
%% Thanks to Tomas Stejskal.
otp_7188(Config) when is_list(Config) ->
MP3 = <<84,65,71,68,117,154,105,232,107,121,0,0,0,0,0,0,0,0,0,0,
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index 28a353d27b..e2988b18dc 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_SUITE.erl
@@ -29,10 +29,10 @@
app_test/1,appup_test/1,
file_1/1, forms_2/1, module_mismatch/1, big_file/1, outdir/1,
binary/1, makedep/1, cond_and_ifdef/1, listings/1, listings_big/1,
- other_output/1, encrypted_abstr/1,
+ other_output/1, kernel_listing/1, encrypted_abstr/1,
strict_record/1,
cover/1, env/1, core/1,
- core_roundtrip/1, asm/1,
+ core_roundtrip/1, asm/1, optimized_guards/1,
sys_pre_attributes/1, dialyzer/1,
warnings/1, pre_load_check/1, env_compiler_options/1
]).
@@ -47,9 +47,9 @@ all() ->
test_lib:recompile(?MODULE),
[app_test, appup_test, file_1, forms_2, module_mismatch, big_file, outdir,
binary, makedep, cond_and_ifdef, listings, listings_big,
- other_output, encrypted_abstr,
+ other_output, kernel_listing, encrypted_abstr,
strict_record,
- cover, env, core, core_roundtrip, asm,
+ cover, env, core, core_roundtrip, asm, optimized_guards,
sys_pre_attributes, dialyzer, warnings, pre_load_check,
env_compiler_options].
@@ -342,7 +342,6 @@ do_file_listings(DataDir, PrivDir, [File|Files]) ->
do_listing(Simple, TargetDir, dblk, ".block"),
do_listing(Simple, TargetDir, dexcept, ".except"),
do_listing(Simple, TargetDir, dbs, ".bs"),
- do_listing(Simple, TargetDir, dbool, ".bool"),
do_listing(Simple, TargetDir, dtype, ".type"),
do_listing(Simple, TargetDir, ddead, ".dead"),
do_listing(Simple, TargetDir, djmp, ".jump"),
@@ -430,6 +429,32 @@ other_output(Config) when is_list(Config) ->
ok.
+%% Smoke test and cover of pretty-printing of Kernel code.
+kernel_listing(_Config) ->
+ TestBeams = get_unique_beam_files(),
+ Abstr = [begin {ok,{Mod,[{abstract_code,
+ {raw_abstract_v1,Abstr}}]}} =
+ beam_lib:chunks(Beam, [abstract_code]),
+ {Mod,Abstr} end || Beam <- TestBeams],
+ test_lib:p_run(fun(F) -> do_kernel_listing(F) end, Abstr).
+
+do_kernel_listing({M,A}) ->
+ try
+ {ok,M,Kern} = compile:forms(A, [to_kernel]),
+ IoList = v3_kernel_pp:format(Kern),
+ _ = iolist_size(IoList),
+ ok
+ catch
+ throw:{error,Error} ->
+ io:format("*** compilation failure '~p' for module ~s\n",
+ [Error,M]),
+ error;
+ Class:Error ->
+ io:format("~p: ~p ~p\n~p\n",
+ [M,Class,Error,erlang:get_stacktrace()]),
+ error
+ end.
+
encrypted_abstr(Config) when is_list(Config) ->
{Simple,Target} = get_files(Config, simple, "encrypted_abstr"),
@@ -901,6 +926,96 @@ do_asm(Beam, Outdir) ->
error
end.
+%% Make sure that guards are fully optimized. Guards should
+%% should use 'test' instructions, not 'bif' instructions.
+
+optimized_guards(_Config) ->
+ TestBeams = get_unique_beam_files(),
+ test_lib:p_run(fun(F) -> do_opt_guards(F) end, TestBeams).
+
+do_opt_guards(Beam) ->
+ {ok,{M,[{abstract_code,{raw_abstract_v1,A}}]}} =
+ beam_lib:chunks(Beam, [abstract_code]),
+ try
+ {ok,M,Asm} = compile:forms(A, ['S']),
+ do_opt_guards_mod(Asm)
+ catch Class:Error ->
+ io:format("~p: ~p ~p\n~p\n",
+ [M,Class,Error,erlang:get_stacktrace()]),
+ error
+ end.
+
+do_opt_guards_mod({Mod,_Exp,_Attr,Asm,_NumLabels}) ->
+ case do_opt_guards_fs(Mod, Asm) of
+ [] ->
+ ok;
+ [_|_]=Bifs ->
+ io:format("ERRORS FOR ~p:\n~p\n", [Mod,Bifs]),
+ error
+ end.
+
+do_opt_guards_fs(Mod, [{function,Name,Arity,_,Is}|Fs]) ->
+ Bifs0 = do_opt_guards_fun(Is),
+
+ %% The compiler does not attempt to optimize 'xor'.
+ %% Therefore, ignore all functions that use 'xor' in
+ %% a guard.
+ Bifs = case lists:any(fun({bif,'xor',_,_,_}) -> true;
+ (_) -> false
+ end, Bifs0) of
+ true -> [];
+ false -> Bifs0
+ end,
+
+ %% Filter out the allowed exceptions.
+ FA = {Name,Arity},
+ case {Bifs,is_exception(Mod, FA)} of
+ {[_|_],true} ->
+ io:format("~p:~p/~p IGNORED:\n~p\n",
+ [Mod,Name,Arity,Bifs]),
+ do_opt_guards_fs(Mod, Fs);
+ {[_|_],false} ->
+ [{FA,Bifs}|do_opt_guards_fs(Mod, Fs)];
+ {[],false} ->
+ do_opt_guards_fs(Mod, Fs);
+ {[],true} ->
+ io:format("Redundant exception for ~p:~p/~p\n",
+ [Mod,Name,Arity]),
+ error(redundant)
+ end;
+do_opt_guards_fs(_, []) -> [].
+
+do_opt_guards_fun([{bif,Name,{f,F},As,_}=I|Is]) when F =/= 0 ->
+ Arity = length(As),
+ case erl_internal:comp_op(Name, Arity) orelse
+ erl_internal:bool_op(Name, Arity) orelse
+ erl_internal:new_type_test(Name, Arity) of
+ true ->
+ [I|do_opt_guards_fun(Is)];
+ false ->
+ do_opt_guards_fun(Is)
+ end;
+do_opt_guards_fun([_|Is]) ->
+ do_opt_guards_fun(Is);
+do_opt_guards_fun([]) -> [].
+
+is_exception(bs_match_SUITE, {matching_and_andalso_2,2}) -> true;
+is_exception(bs_match_SUITE, {matching_and_andalso_3,2}) -> true;
+is_exception(guard_SUITE, {'-complex_not/1-fun-4-',1}) -> true;
+is_exception(guard_SUITE, {'-complex_not/1-fun-5-',1}) -> true;
+is_exception(guard_SUITE, {basic_andalso_orelse,1}) -> true;
+is_exception(guard_SUITE, {bad_guards,1}) -> true;
+is_exception(guard_SUITE, {bad_guards_2,2}) -> true;
+is_exception(guard_SUITE, {bad_guards_3,2}) -> true;
+is_exception(guard_SUITE, {cqlc,4}) -> true;
+is_exception(guard_SUITE, {csemi7,3}) -> true;
+is_exception(guard_SUITE, {misc,1}) -> true;
+is_exception(guard_SUITE, {nested_not_2b,4}) -> true;
+is_exception(guard_SUITE, {tricky_1,2}) -> true;
+is_exception(map_SUITE, {map_guard_update,2}) -> true;
+is_exception(map_SUITE, {map_guard_update_variables,3}) -> true;
+is_exception(_, _) -> false.
+
sys_pre_attributes(Config) ->
DataDir = proplists:get_value(data_dir, Config),
File = filename:join(DataDir, "attributes.erl"),
@@ -1126,8 +1241,15 @@ get_unique_beam_files() ->
get_unique_files(Ext) ->
Wc = filename:join(filename:dirname(code:which(?MODULE)), "*"++Ext),
- [F || F <- filelib:wildcard(Wc), not is_cloned(F, Ext)].
+ [F || F <- filelib:wildcard(Wc),
+ not is_cloned(F, Ext), not is_lfe_module(F, Ext)].
is_cloned(File, Ext) ->
Mod = list_to_atom(filename:basename(File, Ext)),
test_lib:is_cloned_mod(Mod).
+
+is_lfe_module(File, Ext) ->
+ case filename:basename(File, Ext) of
+ "lfe_" ++ _ -> true;
+ _ -> false
+ end.
diff --git a/lib/compiler/test/core_SUITE.erl b/lib/compiler/test/core_SUITE.erl
index b768f49e2c..f8839da42f 100644
--- a/lib/compiler/test/core_SUITE.erl
+++ b/lib/compiler/test/core_SUITE.erl
@@ -26,8 +26,9 @@
seq_in_guard/1,make_effect_seq/1,eval_is_boolean/1,
unsafe_case/1,nomatch_shadow/1,reversed_annos/1,
map_core_test/1,eval_case/1,bad_boolean_guard/1,
- bs_shadowed_size_var/1
- ]).
+ bs_shadowed_size_var/1,
+ cover_v3_kernel_1/1,cover_v3_kernel_2/1,cover_v3_kernel_3/1,
+ cover_v3_kernel_4/1,cover_v3_kernel_5/1]).
-include_lib("common_test/include/ct.hrl").
@@ -53,8 +54,10 @@ groups() ->
[dehydrated_itracer,nested_tries,seq_in_guard,make_effect_seq,
eval_is_boolean,unsafe_case,nomatch_shadow,reversed_annos,
map_core_test,eval_case,bad_boolean_guard,
- bs_shadowed_size_var
- ]}].
+ bs_shadowed_size_var,
+ cover_v3_kernel_1,cover_v3_kernel_2,cover_v3_kernel_3,
+ cover_v3_kernel_4,cover_v3_kernel_5
+ ]}].
init_per_suite(Config) ->
@@ -64,10 +67,10 @@ end_per_suite(_Config) ->
ok.
init_per_group(_GroupName, Config) ->
- Config.
+ Config.
end_per_group(_GroupName, Config) ->
- Config.
+ Config.
?comp(dehydrated_itracer).
@@ -82,6 +85,11 @@ end_per_group(_GroupName, Config) ->
?comp(eval_case).
?comp(bad_boolean_guard).
?comp(bs_shadowed_size_var).
+?comp(cover_v3_kernel_1).
+?comp(cover_v3_kernel_2).
+?comp(cover_v3_kernel_3).
+?comp(cover_v3_kernel_4).
+?comp(cover_v3_kernel_5).
try_it(Mod, Conf) ->
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core
new file mode 100644
index 0000000000..9e5788796f
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_1.core
@@ -0,0 +1,147 @@
+module 'cover_v3_kernel_1' ['cover_v3_kernel_1'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_1'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'bad_and_args'/1
+ ('x') of
+ <'error'> when 'true' ->
+ %% Line 7
+ case apply 'bad_and_args'/2
+ (1, 2) of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'bad_and_args'/2
+ (1, 'true') of
+ <'error'> when 'true' ->
+ %% Line 9
+ case apply 'bad_and_args'/2
+ ('true', 42) of
+ <'error'> when 'true' ->
+ %% Line 10
+ case apply 'bad_and_args'/2
+ ('true', 'false') of
+ <'error'> when 'true' ->
+ %% Line 11
+ case apply 'bad_and_args'/2
+ ('false', 'true') of
+ <'error'> when 'true' ->
+ %% Line 12
+ case apply 'bad_and_args'/2
+ ('true', 'true') of
+ <'ok'> when 'true' ->
+ %% Line 14
+ 'ok'
+ ( <_@c6> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c6})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c5> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c5})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c4})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c3})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c2})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c1})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_1',0}}] )
+ -| ['compiler_generated'] )
+ end
+'bad_and_args'/1 =
+ %% Line 16
+ fun (_@c0) ->
+ case _@c0 of
+ <A>
+ when try
+ call 'erlang':'and'(A, 42)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ %% Line 17
+ <_@c4> when 'true' ->
+ 'error'
+ ( <_@c3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_@c3})
+ -| [{'function_name',{'bad_and_args',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bad_and_args'/2 =
+ %% Line 19
+ fun (_@c1,_@c0) ->
+ case <_@c1,_@c0> of
+ <X,Y>
+ when try
+ call 'erlang':'and'(X, Y)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ %% Line 20
+ <_@c6,_@c7> when 'true' ->
+ 'error'
+ ( <_@c5,_@c4> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_@c5,_@c4})
+ -| [{'function_name',{'bad_and_args',2}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_1')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_@c0) ->
+ case _@c0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_1', X)
+ ( <_@c1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_@c1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core
new file mode 100644
index 0000000000..165aacd691
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_2.core
@@ -0,0 +1,98 @@
+module 'cover_v3_kernel_2' ['cover_v3_kernel_2'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_2'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'strange_case'/1
+ ('a') of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'strange_case'/1
+ ('b') of
+ <'ok'> when 'true' ->
+ %% Line 7
+ case apply 'strange_case'/1
+ ('c') of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'strange_case'/1
+ (42) of
+ <'error'> when 'true' ->
+ %% Line 9
+ 'ok'
+ ( <_cor3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor3})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor2})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor1})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_2',0}}] )
+ -| ['compiler_generated'] )
+ end
+'strange_case'/1 =
+ %% Line 12
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when
+ case X of
+ <'a'> when 'true' -> 'true'
+ <'b'> when 'true' -> 'true'
+ <Other> when 'true' -> 'false'
+ end ->
+ 'ok'
+ %% Line 13
+ <_cor4> when 'true' ->
+ 'error'
+ ( <_cor3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor3})
+ -| [{'function_name',{'strange_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_2')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_2', X)
+ ( <_cor1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core
new file mode 100644
index 0000000000..88a9edc354
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_3.core
@@ -0,0 +1,98 @@
+module 'cover_v3_kernel_3' ['cover_v3_kernel_3'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_3'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'strange_case'/1
+ (1) of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'strange_case'/1
+ (2) of
+ <'ok'> when 'true' ->
+ %% Line 7
+ case apply 'strange_case'/1
+ (42) of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'strange_case'/1
+ ('atom') of
+ <'error'> when 'true' ->
+ %% Line 9
+ 'ok'
+ ( <_cor3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor3})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor2})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor1})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_3',0}}] )
+ -| ['compiler_generated'] )
+ end
+'strange_case'/1 =
+ %% Line 12
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when
+ case X of
+ <1> when 'true' -> 'true'
+ <2> when 'true' -> 'true'
+ <Other> when 'true' -> 'false'
+ end ->
+ 'ok'
+ %% Line 13
+ <_cor4> when 'true' ->
+ 'error'
+ ( <_cor3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor3})
+ -| [{'function_name',{'strange_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_3')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_3', X)
+ ( <_cor1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core
new file mode 100644
index 0000000000..905e236f26
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_4.core
@@ -0,0 +1,82 @@
+module 'cover_v3_kernel_4' ['cover_v3_kernel_4'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_4'/0 =
+ %% Line 4
+ fun () ->
+ %% Line 5
+ case apply 'turned_case'/1
+ (20) of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'turned_case'/1
+ (0) of
+ <'error'> when 'true' ->
+ %% Line 7
+ 'ok'
+ ( <_@c1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c1})
+ -| ['compiler_generated'] )
+ end
+ ( <_@c0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_@c0})
+ -| ['compiler_generated'] )
+ end
+'turned_case'/1 =
+ %% Line 9
+ fun (_@c0) ->
+ let <True> =
+ apply %% Line 10
+ 'id'/1
+ (%% Line 10
+ 'true')
+ in %% Line 11
+ case <> of
+ %% Line 12
+ <>
+ when try
+ ( let <_@c4> =
+ case call 'erlang':'<'
+ (_@c0, 10) of
+ ( <( 'false'
+ -| ['compiler_generated'] )> when 'true' ->
+ True
+ -| ['compiler_generated'] )
+ ( <( 'true'
+ -| ['compiler_generated'] )> when 'true' ->
+ 'false'
+ -| ['compiler_generated'] )
+ ( <_@c2> when 'true' ->
+ _@c2
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (( _@c4
+ -| ['compiler_generated'] ), 'true')
+ -| ['compiler_generated'] )
+ -| ['compiler_generated'] )
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ %% Line 13
+ <> when 'true' ->
+ 'error'
+ end
+'id'/1 =
+ %% Line 16
+ fun (_@c0) ->
+ _@c0
+'module_info'/0 =
+ fun () ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_4')
+'module_info'/1 =
+ fun (_@c0) ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_4', _@c0)
+end \ No newline at end of file
diff --git a/lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core
new file mode 100644
index 0000000000..48c1bb84e6
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/cover_v3_kernel_5.core
@@ -0,0 +1,98 @@
+module 'cover_v3_kernel_5' ['cover_v3_kernel_5'/0,
+ 'module_info'/0,
+ 'module_info'/1]
+ attributes []
+'cover_v3_kernel_5'/0 =
+ %% Line 4
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ %% Line 5
+ case apply 'strange_case'/1
+ (1) of
+ <'ok'> when 'true' ->
+ %% Line 6
+ case apply 'strange_case'/1
+ (2) of
+ <'ok'> when 'true' ->
+ %% Line 7
+ case apply 'strange_case'/1
+ (42) of
+ <'error'> when 'true' ->
+ %% Line 8
+ case apply 'strange_case'/1
+ ('atom') of
+ <'error'> when 'true' ->
+ %% Line 9
+ 'ok'
+ ( <_cor3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor3})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor2})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor1})
+ -| ['compiler_generated'] )
+ end
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'cover_v3_kernel_5',0}}] )
+ -| ['compiler_generated'] )
+ end
+'strange_case'/1 =
+ %% Line 12
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when
+ case X of
+ <1> when 'true' -> 'true'
+ <2> when 'true' -> 'true'
+ <Other> when 'true' -> X
+ end ->
+ 'ok'
+ %% Line 13
+ <_cor4> when 'true' ->
+ 'error'
+ ( <_cor3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor3})
+ -| [{'function_name',{'strange_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_5')
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'module_info',0}}] )
+ -| ['compiler_generated'] )
+ end
+'module_info'/1 =
+ fun (_cor0) ->
+ case _cor0 of
+ <X> when 'true' ->
+ call 'erlang':'get_module_info'
+ ('cover_v3_kernel_5', X)
+ ( <_cor1> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_cor1})
+ -| [{'function_name',{'module_info',1}}] )
+ -| ['compiler_generated'] )
+ end
+end
diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl
index ced0e39d06..0097e28d4d 100644
--- a/lib/compiler/test/core_fold_SUITE.erl
+++ b/lib/compiler/test/core_fold_SUITE.erl
@@ -26,7 +26,7 @@
unused_multiple_values_error/1,unused_multiple_values/1,
multiple_aliases/1,redundant_boolean_clauses/1,
mixed_matching_clauses/1,unnecessary_building/1,
- no_no_file/1,configuration/1]).
+ no_no_file/1,configuration/1,supplies/1]).
-export([foo/0,foo/1,foo/2,foo/3]).
@@ -45,7 +45,7 @@ groups() ->
unused_multiple_values_error,unused_multiple_values,
multiple_aliases,redundant_boolean_clauses,
mixed_matching_clauses,unnecessary_building,
- no_no_file,configuration]}].
+ no_no_file,configuration,supplies]}].
init_per_suite(Config) ->
@@ -511,4 +511,20 @@ configuration() ->
art() ->
creating.
+%% core_lint would complain after optimization. A call to error/1
+%% must not occur unconditionally in a guard.
+supplies(_Config) ->
+ case ?MODULE of
+ core_fold_inline_SUITE ->
+ %% Other error behaviour when inlined.
+ ok;
+ _ ->
+ {'EXIT',{function_clause,_}} = (catch do_supplies(#{1 => <<1,2,3>>})),
+ {'EXIT',{function_clause,_}} = (catch do_supplies(#{1 => a})),
+ {'EXIT',{function_clause,_}} = (catch do_supplies(42)),
+ ok
+ end.
+
+do_supplies(#{1 := Value}) when byte_size(Value), byte_size(kg) -> working.
+
id(I) -> I.
diff --git a/lib/compiler/test/float_SUITE.erl b/lib/compiler/test/float_SUITE.erl
index 0ebc71eb9b..08c3dd8593 100644
--- a/lib/compiler/test/float_SUITE.erl
+++ b/lib/compiler/test/float_SUITE.erl
@@ -155,6 +155,13 @@ math_functions(Config) when is_list(Config) ->
5.0 = math:floor(id(5.4)),
6.0 = math:ceil(id(5.4)),
+ 0.0 = math:fmod(42, 42),
+ 0.25 = math:fmod(1, 0.75),
+ -1.0 = math:fmod(-4.0, 1.5),
+ -0.375 = math:fmod(-3.0, -0.875),
+ 0.125 = math:fmod(8.125, -4),
+ {'EXIT',{badarith,_}} = (catch math:fmod(5.0, 0.0)),
+
%% Only for coverage (of beam_type.erl).
{'EXIT',{undef,_}} = (catch math:fnurfla(0)),
{'EXIT',{undef,_}} = (catch math:fnurfla(0, 0)),
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 6302f82f29..a662d85272 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -35,7 +35,7 @@
basic_andalso_orelse/1,traverse_dcd/1,
check_qlc_hrl/1,andalso_semi/1,t_tuple_size/1,binary_part/1,
bad_constants/1,bad_guards/1,
- guard_in_catch/1]).
+ guard_in_catch/1,beam_bool_SUITE/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -54,7 +54,7 @@ groups() ->
rel_ops,rel_op_combinations,
literal_type_tests,basic_andalso_orelse,traverse_dcd,
check_qlc_hrl,andalso_semi,t_tuple_size,binary_part,
- bad_constants,bad_guards,guard_in_catch]}].
+ bad_constants,bad_guards,guard_in_catch,beam_bool_SUITE]}].
init_per_suite(Config) ->
Config.
@@ -87,8 +87,32 @@ misc(Config) when is_list(Config) ->
{ok,buf,<<>>} = get_data({o,true,0}, 42, buf),
{ok,buf,<<>>} = get_data({o,false,0}, 0, buf),
error = get_data({o,false,0}, 42, buf),
+
+ relief = misc_2(0),
+ error = misc_2(1),
+ error = misc_2(true),
+
+ if
+ is_integer(Config) =/= true ->
+ ok
+ end,
+
+ true = misc_3(1, 0),
+ true = misc_3(0, 0),
+ false = misc_3(0, 2),
+
+ %% Abuse of boolean values.
+
+ Zero = id(0),
+ One = id(1),
+ ok = if (Zero == 0) > false -> ok end,
+ ok = if (Zero == 0) =:= (One == 1) -> ok end,
+ ok = if (Zero == 0) =:= (One == 1) -> ok end,
+ ok = if is_atom(Zero > One) -> ok end,
+ error = if abs(Zero > One) -> ok; true -> error end,
+ ok = if is_integer(Zero) >= is_integer(One) -> ok end,
+
ok.
-
misc_1([{W},{X},{Y},{Z}]) ->
if
@@ -98,6 +122,17 @@ misc_1([{W},{X},{Y},{Z}]) ->
none
end.
+misc_2(0) -> relief;
+misc_2(Adapter = 1) when Adapter -> franklin;
+misc_2(_) -> error.
+
+misc_3(LenUp, LenDw) ->
+ if
+ %% Cover handling of #k_alt{}.
+ LenUp >= 1 orelse ((LenDw >= 2) xor true) -> true;
+ true -> false
+ end.
+
get_data({o,Active,Raw}, BytesToRead, Buffer)
when Raw =:= raw; Raw =:= 0 ->
if
@@ -163,6 +198,12 @@ basic_not(Config) when is_list(Config) ->
check(fun() -> if not glurf -> ok; true -> error end end, error),
check(fun() -> if not Glurf -> ok; true -> error end end, error),
+ check(fun() -> if not (not true) -> broken end end, broken),
+
+ check(fun() -> if not (True xor True) -> ok end end, ok),
+ check(fun() -> if not (True xor False) -> ok;
+ true -> error end end, error),
+
ok.
complex_not(Config) when is_list(Config) ->
@@ -187,8 +228,60 @@ complex_not(Config) when is_list(Config) ->
check(fun() -> if not(element(1, ATuple) orelse element(3, ATuple)) -> ok;
true -> error end end, error),
+ %% complex_not_1/4
+ ok = complex_not_1(1, 1, 1, a),
+ error = complex_not_1(1, 1, 1, []),
+ error = complex_not_1(1, 1, 3, a),
+ error = complex_not_1(1, 1, 3, []),
+ error = complex_not_1(1, 2, 1, a),
+ error = complex_not_1(1, 2, 1, []),
+ error = complex_not_1(1, 2, 3, a),
+ error = complex_not_1(1, 2, 3, []),
+
+ %% complex_not_2/4
+ ok = complex_not_2(1, 2, 0, x),
+ error = complex_not_2(1, 2, 0, []),
+ error = complex_not_2(1, 2, 3, x),
+ error = complex_not_2(1, 2, 3, []),
+ error = complex_not_2(1, 1, 0, x),
+ error = complex_not_2(1, 1, 0, []),
+ error = complex_not_2(1, 1, 3, x),
+ error = complex_not_2(1, 1, 3, []),
+
ok.
+complex_not_1(A, B, C, D) ->
+ Res = complex_not_1a(A, B, C, D),
+ Res = complex_not_1b(A, B, C, D).
+
+complex_not_1a(A, B, C, D)
+ when (not (A < B)) andalso (not (B < C)) andalso (not is_list(D)) ->
+ ok;
+complex_not_1a(_, _, _, _) ->
+ error.
+
+complex_not_1b(A, B, C, D)
+ when (not (A < B)) and (not (B < C)) and (not is_list(D)) ->
+ ok;
+complex_not_1b(_, _, _, _) ->
+ error.
+
+complex_not_2(A, B, C, D) ->
+ Res = complex_not_2a(A, B, C, D),
+ Res = complex_not_2b(A, B, C, D).
+
+complex_not_2a(A, B, C, D)
+ when A < B andalso not (B < C) andalso not is_list(D) ->
+ ok;
+complex_not_2a(_, _, _, _) ->
+ error.
+
+complex_not_2b(A, B, C, D)
+ when A < B, not (B < C), not is_list(D) ->
+ ok;
+complex_not_2b(_, _, _, _) ->
+ error.
+
nested_nots(Config) when is_list(Config) ->
true = nested_not_1(0, 0),
true = nested_not_1(0, 1),
@@ -209,19 +302,36 @@ nested_nots(Config) when is_list(Config) ->
false = nested_not_2(true, true, atom),
ok.
-nested_not_1(X, Y) when not (((X>Y) or not(is_atom(X))) and
+nested_not_1(X, Y) ->
+ Res = nested_not_1a(X, Y),
+ Res = nested_not_1b(X, Y).
+
+nested_not_1a(X, Y) when not (((X>Y) or not(is_atom(X))) and
(is_atom(Y) or (X==3.4))) ->
true;
-nested_not_1(_, _) ->
+nested_not_1a(_, _) ->
+ false.
+
+nested_not_1b(X, Y) when not (((X>Y) orelse not(is_atom(X))) andalso
+ (is_atom(Y) orelse (X==3.4))) ->
+ true;
+nested_not_1b(_, _) ->
false.
nested_not_2(X, Y, Z) ->
- nested_not_2(X, Y, Z, true).
+ Res = nested_not_2a(X, Y, Z, true),
+ Res = nested_not_2b(X, Y, Z, true).
-nested_not_2(X, Y, Z, True)
+nested_not_2a(X, Y, Z, True)
when not(True and not((not(X) and not(Y)) or not(is_atom(Z)))) ->
true;
-nested_not_2(_, _, _, _) ->
+nested_not_2a(_, _, _, _) ->
+ false.
+
+nested_not_2b(X, Y, Z, True)
+ when not(True andalso not((not(X) andalso not(Y)) orelse not(is_atom(Z)))) ->
+ true;
+nested_not_2b(_, _, _, _) ->
false.
semicolon(Config) when is_list(Config) ->
@@ -343,6 +453,11 @@ complex_semicolon(Config) when is_list(Config) ->
ok = csemi7(#{a=>1}, 3, 3),
ok = csemi7(#{a=>1, b=>3}, 0, 0),
+ %% 8: Make sure that funs cannot be copied into guards.
+ ok = csemi8(true),
+ error = csemi8(false),
+ error = csemi8(42),
+
ok.
csemi1(Type, Val) when is_list(Val), Type == float;
@@ -457,6 +572,13 @@ csemi6(_, _) -> error.
csemi7(A, B, C) when A#{a:=B} > #{a=>1}; abs(C) > 2 -> ok;
csemi7(_, _, _) -> error.
+csemi8(Together) ->
+ case fun csemi8/1 of
+ Typically when Together; Typically, Together -> ok;
+ _ -> error
+ end.
+
+
comma(Config) when is_list(Config) ->
%% ',' combinations of literal true/false.
@@ -1081,6 +1203,13 @@ tricky(Config) when is_list(Config) ->
false = rb(100000, [1], 42),
true = rb(100000, [], 42),
true = rb(555, [a,b,c], 19),
+
+ error = tricky_3(42),
+ error = tricky_3(42.0),
+ error = tricky_3(<<>>),
+ error = tricky_3(#{}),
+ error = tricky_3({a,b}),
+
ok.
tricky_1(X, Y) when abs((X == 1) or (Y == 2)) -> ok;
@@ -1089,6 +1218,15 @@ tricky_1(_, _) -> not_ok.
tricky_2(X) when float(X) or float(X) -> ok;
tricky_2(_) -> error.
+tricky_3(X)
+ when abs(X) or bit_size(X) or byte_size(X) or ceil(X) or
+ float(X) or floor(X) or length(X) or
+ map_size(X) or node() or node(X) or round(X) or
+ self() or size(X) or tl(X) or trunc(X) or tuple_size(X) ->
+ ok;
+tricky_3(_) ->
+ error.
+
%% From dets_v9:read_buckets/11, simplified.
rb(Size, ToRead, SoFar) when SoFar + Size < 81920; ToRead == [] -> true;
@@ -1912,6 +2050,155 @@ do_guard_in_catch_bin(From) ->
saint
end.
+%%%
+%%% The beam_bool pass has been eliminated. Here are the tests from
+%%% beam_bool_SUITE.
+%%%
+
+beam_bool_SUITE(_Config) ->
+ before_and_inside_if(),
+ scotland(),
+ y_registers(),
+ protected(),
+ maps(),
+ ok.
+
+before_and_inside_if() ->
+ no = before_and_inside_if([a], [b], delete),
+ no = before_and_inside_if([a], [b], x),
+ no = before_and_inside_if([a], [], delete),
+ no = before_and_inside_if([a], [], x),
+ no = before_and_inside_if([], [], delete),
+ yes = before_and_inside_if([], [], x),
+ yes = before_and_inside_if([], [b], delete),
+ yes = before_and_inside_if([], [b], x),
+
+ {ch1,ch2} = before_and_inside_if_2([a], [b], blah),
+ {ch1,ch2} = before_and_inside_if_2([a], [b], xx),
+ {ch1,ch2} = before_and_inside_if_2([a], [], blah),
+ {ch1,ch2} = before_and_inside_if_2([a], [], xx),
+ {no,no} = before_and_inside_if_2([], [b], blah),
+ {no,no} = before_and_inside_if_2([], [b], xx),
+ {ch1,no} = before_and_inside_if_2([], [], blah),
+ {no,ch2} = before_and_inside_if_2([], [], xx),
+ ok.
+
+%% Thanks to Simon Cornish and Kostis Sagonas.
+%% Used to crash beam_bool.
+before_and_inside_if(XDo1, XDo2, Do3) ->
+ Do1 = (XDo1 =/= []),
+ Do2 = (XDo2 =/= []),
+ if
+ %% This expression occurs in a try/catch (protected)
+ %% block, which cannot refer to variables outside of
+ %% the block that are boolean expressions.
+ Do1 =:= true;
+ Do1 =:= false, Do2 =:= false, Do3 =:= delete ->
+ no;
+ true ->
+ yes
+ end.
+
+%% Thanks to Simon Cornish.
+%% Used to generate code that would not set {y,0} on
+%% all paths before its use (and therefore fail
+%% validation by the beam_validator).
+before_and_inside_if_2(XDo1, XDo2, Do3) ->
+ Do1 = (XDo1 =/= []),
+ Do2 = (XDo2 =/= []),
+ CH1 = if Do1 == true;
+ Do1 == false,Do2==false,Do3 == blah ->
+ ch1;
+ true ->
+ no
+ end,
+ CH2 = if Do1 == true;
+ Do1 == false,Do2==false,Do3 == xx ->
+ ch2;
+ true ->
+ no
+ end,
+ {CH1,CH2}.
+
+
+%% beam_bool would remove the initialization of {y,0}.
+%% (Thanks to Thomas Arts and QuickCheck.)
+
+scotland() ->
+ million = do_scotland(placed),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(false)),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(true)),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(echo)),
+ ok.
+
+do_scotland(Echo) ->
+ found(case Echo of
+ Echo when true; Echo, Echo, Echo ->
+ Echo;
+ echo ->
+ []
+ end,
+ Echo = placed).
+
+found(_, _) -> million.
+
+
+%% ERL-143: beam_bool could not handle Y registers as a destination.
+y_registers() ->
+ {'EXIT',{badarith,[_|_]}} = (catch baker(valentine)),
+ {'EXIT',{badarith,[_|_]}} = (catch baker(clementine)),
+
+ {not_ok,true} = potter([]),
+ {ok,false} = potter([{encoding,any}]),
+
+ ok.
+
+%% Thanks to Quickcheck.
+baker(Baker) ->
+ (valentine == Baker) +
+ case Baker of
+ Baker when Baker; Baker ->
+ Baker;
+ Baker ->
+ []
+ end.
+
+%% Thanks to Jose Valim.
+potter(Modes) ->
+ Raw = lists:keyfind(encoding, 1, Modes) == false,
+ Final = case Raw of
+ X when X == false; X == nil -> ok;
+ _ -> not_ok
+ end,
+ {Final,Raw}.
+
+protected() ->
+ {'EXIT',{if_clause,_}} = (catch photographs({1, surprise, true}, opinions)),
+
+ {{true}} = welcome({perfect, true}),
+ {'EXIT',{if_clause,_}} = (catch welcome({perfect, false})),
+ ok.
+
+photographs({_Violation, surprise, Deep}, opinions) ->
+ {if
+ 0; "here", Deep ->
+ Deep = Deep
+ end}.
+
+welcome({perfect, Profit}) ->
+ if
+ Profit, Profit, Profit; 0 ->
+ {id({Profit})}
+ end.
+
+maps() ->
+ ok = evidence(#{0 => 42}).
+
+%% Cover handling of put_map in in split_block_label_used/2.
+evidence(#{0 := Charge}) when 0; #{[] => Charge} == #{[] => 42} ->
+ ok.
+
+
%% Call this function to turn off constant propagation.
id(I) -> I.
diff --git a/lib/compiler/test/lfe-core.patch b/lib/compiler/test/lfe-core.patch
new file mode 100644
index 0000000000..756d131e2c
--- /dev/null
+++ b/lib/compiler/test/lfe-core.patch
@@ -0,0 +1,97 @@
+Date: Sun, 13 Nov 2016 10:11:11 +0100
+Subject: [PATCH] Fix invalid variable names
+
+---
+ test/lfe_andor_SUITE.core | 16 ++++++++--------
+ test/lfe_guard_SUITE.core | 14 +++++++-------
+ 2 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/test/lfe_andor_SUITE.core b/test/lfe_andor_SUITE.core
+index 96ff765..df58b39 100644
+--- a/test/lfe_andor_SUITE.core
++++ b/test/lfe_andor_SUITE.core
+@@ -288,19 +288,19 @@ module 'lfe_andor_SUITE' ['$handle_undefined_function'/2,
+ 'lc$^0'/1 =
+ fun (_2) ->
+ case <_2> of
+- <[_x|_|-0-|]> when 'true' ->
++ <[_x|_lfe0]> when 'true' ->
+ letrec
+ 'lc$^1'/1 =
+ fun (_3) ->
+ case <_3> of
+- <[_y|_|-1-|]> when 'true' ->
++ <[_y|_lfe1]> when 'true' ->
+ let <_4> =
+ apply 'lc$^1'/1
+- (_|-1-|)
++ (_lfe1)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^0'/1
+- (_|-0-|)
++ (_lfe0)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+@@ -455,19 +455,19 @@ module 'lfe_andor_SUITE' ['$handle_undefined_function'/2,
+ 'lc$^2'/1 =
+ fun (_2) ->
+ case <_2> of
+- <[_x|_|-2-|]> when 'true' ->
++ <[_x|_lfe2]> when 'true' ->
+ letrec
+ 'lc$^3'/1 =
+ fun (_3) ->
+ case <_3> of
+- <[_y|_|-3-|]> when 'true' ->
++ <[_y|_lfe3]> when 'true' ->
+ let <_4> =
+ apply 'lc$^3'/1
+- (_|-3-|)
++ (_lfe3)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^2'/1
+- (_|-2-|)
++ (_lfe2)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+diff --git a/test/lfe_guard_SUITE.core b/test/lfe_guard_SUITE.core
+index 38f1d99..920be82 100644
+--- a/test/lfe_guard_SUITE.core
++++ b/test/lfe_guard_SUITE.core
+@@ -2857,22 +2857,22 @@ module 'lfe_guard_SUITE' ['$handle_undefined_function'/2,
+ 'false' ->
+ case <_t> of
+ <{_a,_b,_c,_d}> when 'true' ->
+- let <_|-0-|> =
++ let <_lfe0> =
+ <_a>
+- in let <_|-1-|> =
++ in let <_lfe1> =
+ <_b>
+- in let <_|-2-|> =
++ in let <_lfe2> =
+ <_c>
+- in let <_|-3-|> =
++ in let <_lfe3> =
+ <_d>
+ in let <_4> =
+ let <_3> =
+ call 'erlang':'+'
+- (_|-0-|, _|-1-|)
++ (_lfe0, _lfe1)
+ in call 'erlang':'+'
+- (_3, _|-2-|)
++ (_3, _lfe2)
+ in call 'erlang':'+'
+- (_4, _|-3-|)
++ (_4, _lfe3)
+ ( <_5> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_5}})
+--
+2.7.4 (Apple Git-66)
+
diff --git a/lib/compiler/test/lfe-source.patch b/lib/compiler/test/lfe-source.patch
new file mode 100644
index 0000000000..cbd6748bc9
--- /dev/null
+++ b/lib/compiler/test/lfe-source.patch
@@ -0,0 +1,117 @@
+Date: Sun, 13 Nov 2016 09:40:36 +0100
+Subject: [PATCH] Rename and fix up LFE test suites
+
+---
+ test/{andor_SUITE.lfe => lfe_andor_SUITE.lfe} | 16 ++++++++--------
+ test/{guard_SUITE.lfe => lfe_guard_SUITE.lfe} | 8 ++++----
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+ rename test/{andor_SUITE.lfe => lfe_andor_SUITE.lfe} (97%)
+ rename test/{guard_SUITE.lfe => lfe_guard_SUITE.lfe} (99%)
+
+diff --git a/test/andor_SUITE.lfe b/test/lfe_andor_SUITE.lfe
+similarity index 97%
+rename from test/andor_SUITE.lfe
+rename to test/lfe_andor_SUITE.lfe
+index 64feddd..1802b3f 100644
+--- a/test/andor_SUITE.lfe
++++ b/test/lfe_andor_SUITE.lfe
+@@ -26,14 +26,14 @@
+
+ (include-file "test_server.lfe")
+
+-(defmodule andor_SUITE
++(defmodule lfe_andor_SUITE
+ (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)
+ ))
+
+-(defmacro MODULE () `'andor_SUITE)
++(defmacro MODULE () `'lfe_andor_SUITE)
+
+ (defun all ()
+ ;; (: test_lib recompile (MODULE))
+@@ -206,7 +206,7 @@
+
+ (defun t-andalso-1
+ ([(tuple x y)]
+- (: lfe_io format '"(andalso ~w ~w): " (list x y))
++ (: io format '"(andalso ~w ~w): " (list x y))
+ (let* ((v0 (andalso (echo x) (echo y)))
+ (v1 (when (=:= v0 v1))
+ (eif (andalso x y) 'true 'true 'false)))
+@@ -248,7 +248,7 @@
+
+ (defun t-orelse-1
+ ([(tuple x y)]
+- (: lfe_io format '"(orelse ~w ~w): " (list x y))
++ (: io format '"(orelse ~w ~w): " (list x y))
+ (let* ((v0 (orelse (echo x) (echo y)))
+ (v1 (when (=:= v0 v1))
+ (eif (orelse x y) 'true 'true 'false)))
+@@ -289,7 +289,7 @@
+ (when (=:= r1 r2) (=:= xm xm2) (=:= ym ym2) (=:= x x2)
+ (=:= y y2) (=:= w w2) (=:= h h2))
+ (inside-guard xm ym x y w h)))
+- (: lfe_io fwrite
++ (: io fwrite
+ '"(andalso (=< ~p ~p) (< ~p ~p) (=< ~p ~p) (< ~p ~p)) ==> ~p\n"
+ (list x xm xm (+ x w) y ym ym (+ y h) r1)))
+ r1))
+@@ -499,12 +499,12 @@
+ ;; Utilities
+
+ (defun check (v1 v0)
+- (eif (/= v1 v0) (progn (: lfe_io fwrite '"error: ~w.\n" (list v1))
++ (eif (/= v1 v0) (progn (: io fwrite '"error: ~w.\n" (list v1))
+ (exit 'suite_failed))
+- 'true (: lfe_io fwrite '"ok: ~w.\n" (list v1))))
++ 'true (: io fwrite '"ok: ~w.\n" (list v1))))
+
+ (defun echo (x)
+- (: lfe_io fwrite '"(eval ~w); " (list x))
++ (: io fwrite '"(eval ~w); " (list x))
+ x)
+
+ ;; Call this function to turn off constant propagation.
+diff --git a/test/guard_SUITE.lfe b/test/lfe_guard_SUITE.lfe
+similarity index 99%
+rename from test/guard_SUITE.lfe
+rename to test/lfe_guard_SUITE.lfe
+index 33b1344..2eeb1a6 100644
+--- a/test/guard_SUITE.lfe
++++ b/test/lfe_guard_SUITE.lfe
+@@ -26,7 +26,7 @@
+
+ (include-file "test_server.lfe")
+
+-(defmodule guard_SUITE
++(defmodule lfe_guard_SUITE
+ (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)
+@@ -42,7 +42,7 @@
+ (check_qlc_hrl 1) (andalso_semi 1) (t_tuple_size 1) (binary_part 1)
+ ))
+
+-(defmacro MODULE () `'guard_SUITE)
++(defmacro MODULE () `'lfe_guard_SUITE)
+
+ (defun all ()
+ ;; (: test_lib recompile (MODULE))
+@@ -764,9 +764,9 @@
+
+ (defun is_function_2
+ ([config] (when (is_list config))
+- (line (test-pat 'true (is_function (id (function guard_SUITE all 1)) 1)))
++ (line (test-pat 'true (is_function (id (function lfe_guard_SUITE all 1)) 1)))
+ (line (test-pat 'true (is_function (id (lambda () 'ok)) 0)))
+- (line (test-pat 'false (is_function (id (function guard_SUITE all 1)) 0)))
++ (line (test-pat 'false (is_function (id (function lfe_guard_SUITE all 1)) 0)))
+ (line (test-pat 'false (is_function (id (lambda () 'ok)) 1)))
+
+ (let ((F (lambda (_) 'ok)))
+--
+2.7.4 (Apple Git-66)
+
diff --git a/lib/compiler/test/lfe.readme b/lib/compiler/test/lfe.readme
new file mode 100644
index 0000000000..2fc88e0252
--- /dev/null
+++ b/lib/compiler/test/lfe.readme
@@ -0,0 +1,31 @@
+Creating the LFE-derived test suites
+====================================
+
+Here is how to create `lfe_andor_SUITE.core` and `lfe_guard_SUITE.core`
+files.
+
+First clone and build LFE.
+
+ git clone https://github.com/rvirding/lfe.git
+ cd lfe
+ git checkout v1.2.0
+ MAKEFLAGS='' make compile
+ export PATH=$(pwd)/bin:$PATH
+
+Apply the source patch to rename and fix up the LFE source code:
+
+ cd test
+ git apply $ERL_TOP/lib/compiler/test/lfe-source.patch
+ git reset --hard HEAD
+
+Compile the modules to Core Erlang:
+
+ lfec +to-core0 lfe*.lfe
+
+Apply the core patch to correct some invalid variable names:
+
+ git apply $ERL_TOP/lib/compiler/test/lfe-core.patch
+
+Copy the patched .core file to the test suite:
+
+ cp lfe*.core $ERL_TOP/lib/compiler/test
diff --git a/lib/compiler/test/lfe_andor_SUITE.core b/lib/compiler/test/lfe_andor_SUITE.core
new file mode 100644
index 0000000000..df58b39ae6
--- /dev/null
+++ b/lib/compiler/test/lfe_andor_SUITE.core
@@ -0,0 +1,2014 @@
+module 'lfe_andor_SUITE' ['$handle_undefined_function'/2,
+ 'LFE-EXPAND-EXPORTED-MACRO'/3,
+ 'all'/0,
+ 'before_and_inside_if'/1,
+ 'combined'/1,
+ 'end_per_group'/2,
+ 'end_per_suite'/1,
+ 'groups'/0,
+ 'in_case'/1,
+ 'init_per_group'/2,
+ 'init_per_suite'/1,
+ 'inside'/1,
+ 'module_info'/0,
+ 'module_info'/1,
+ 'overlap'/1,
+ 'suite'/0,
+ 't_and_or'/1,
+ 't_andalso'/1,
+ 't_case'/1,
+ 't_orelse'/1]
+ attributes []
+'all'/0 =
+ %% Line 38
+ fun () ->
+ ['t_case'|['t_and_or'|['t_andalso'|['t_orelse'|['inside'|['overlap'|['combined'|['in_case'|['before_and_inside_if']]]]]]]]]
+'suite'/0 =
+ %% Line 44
+ fun () ->
+ []
+'groups'/0 =
+ %% Line 46
+ fun () ->
+ []
+'init_per_suite'/1 =
+ %% Line 48
+ fun (_config) ->
+ _config
+'end_per_suite'/1 =
+ %% Line 50
+ fun (_config) ->
+ 'ok'
+'init_per_group'/2 =
+ %% Line 52
+ fun (_name,_config) ->
+ _config
+'end_per_group'/2 =
+ %% Line 54
+ fun (_name,_config) ->
+ _config
+'t_case'/1 =
+ %% Line 56
+ fun (_0) ->
+ case <_0> of
+ <'suite'> when 'true' ->
+ []
+ <'doc'> when 'true' ->
+ [84|[101|[115|[116|[32|[105|[110|[32|[99|[97|[115|[101|[46]]]]]]]]]]]]]
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['less']]|[['t-case-a'|[1|[2]]]]]]})
+ let <_val> =
+ <apply 't-case-a'/2
+ (1, 2)>
+ in case <_val> of
+ <'less'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_25> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_25})
+ -| [{'function_name',{'t_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t-case-a'/2 =
+ %% Line 94
+ fun (_a,_b) ->
+ case call 'erlang':'<'
+ (_a, _b) of
+ <[_0|_1]> when 'true' ->
+ 'ok'
+ <'true'> when 'true' ->
+ 'less'
+ <'false'> when 'true' ->
+ 'not_less'
+ <{'a','b','c'}> when 'true' ->
+ 'ok'
+ <_2> when 'true' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-b'/2 =
+ %% Line 102
+ fun (_a,_b) ->
+ case call 'erlang':'=:='
+ (_a, _b) of
+ <'blurf'> when 'true' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-c'/2 =
+ %% Line 106
+ fun (_a,_b) ->
+ case let <_0> =
+ call 'erlang':'=:='
+ (_a, _b)
+ in call 'erlang':'not'
+ (_0) of
+ <'true'> when 'true' ->
+ 'ne'
+ <'false'> when 'true' ->
+ 'eq'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-d'/3 =
+ %% Line 111
+ fun (_a,_b,_x) ->
+ case let <_0> =
+ call 'erlang':'=:='
+ (_a, _b)
+ in call 'erlang':'and'
+ (_0, _x) of
+ <'true'> when 'true' ->
+ 't'
+ <'false'> when 'true' ->
+ 'f'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-e'/2 =
+ %% Line 116
+ fun (_a,_b) ->
+ case call 'erlang':'=:='
+ (_a, _b) of
+ <_bool>
+ when try
+ let <_0> =
+ call 'erlang':'is_tuple'
+ (_a)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_bool)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-xy'/3 =
+ %% Line 120
+ fun (_x,_y,_z) ->
+ let <_r0> =
+ <apply 't-case-x'/3
+ (_x, _y, _z)>
+ in case <apply 't-case-y'/3
+ (_x, _y, _z)> of
+ <_res>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_res, _r0)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _res
+ ( <_1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_1}})
+ -| ['compiler_generated'] )
+ end
+'t-case-x'/3 =
+ %% Line 125
+ fun (_x,_y,_z) ->
+ case let <_0> =
+ call 'erlang':'abs'
+ (_x)
+ in call 'erlang':'=:='
+ (_0, 42) of
+ <'true'> when 'true' ->
+ call 'erlang':'=:='
+ (_y, 100)
+ <'false'> when 'true' ->
+ call 'erlang':'=:='
+ (_z, 700)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t-case-y'/3 =
+ %% Line 130
+ fun (_x,_y,_z) ->
+ case let <_0> =
+ call 'erlang':'abs'
+ (_x)
+ in call 'erlang':'=:='
+ (_0, 42) of
+ <'false'> when 'true' ->
+ call 'erlang':'=:='
+ (_z, 700)
+ <'true'> when 'true' ->
+ call 'erlang':'=:='
+ (_y, 100)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'t_and_or'/1 =
+ %% Line 135
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['and'|[['quote'|['true']]|[['quote'|['true']]]]]]]]})
+ let <_val> =
+ <call 'erlang':'and'
+ ('true', 'true')>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_42> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_42})
+ -| [{'function_name',{'t_and_or',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t_andalso'/1 =
+ %% Line 172
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_bs> =
+ <['true'|['false']]>
+ in let <_ps> =
+ <letrec
+ 'lc$^0'/1 =
+ fun (_2) ->
+ case <_2> of
+ <[_x|_lfe0]> when 'true' ->
+ letrec
+ 'lc$^1'/1 =
+ fun (_3) ->
+ case <_3> of
+ <[_y|_lfe1]> when 'true' ->
+ let <_4> =
+ apply 'lc$^1'/1
+ (_lfe1)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^0'/1
+ (_lfe0)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'t_andalso',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^1'/1
+ (_bs)
+ <[]> when 'true' ->
+ []
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'t_andalso',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^0'/1
+ (_bs)>
+ in let <_7> =
+ fun (_p) ->
+ apply 't-andalso-1'/1
+ (_p)
+ in call 'lists':'foreach'
+ (_7, _ps)
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['andalso'|[['quote'|['true']]|[['quote'|['true']]]]]]]]})
+ let <_val> =
+ <case 'true' of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_8> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_8}})
+ -| ['compiler_generated'] )
+ end
+ ( <_57> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_57})
+ -| [{'function_name',{'t_andalso',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t-andalso-1'/1 =
+ %% Line 207
+ fun (_0) ->
+ case <_0> of
+ <{_x,_y}> when 'true' ->
+ do call 'io':'format'
+ ([40|[97|[110|[100|[97|[108|[115|[111|[32|[126|[119|[32|[126|[119|[41|[58|[32]]]]]]]]]]]]]]]]], [_x,_y])
+ let <_v0> =
+ <case apply 'echo'/1
+ (_x) of
+ <'true'> when 'true' ->
+ apply 'echo'/1
+ (_y)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <case 1 of
+ <_1>
+ when try
+ let <_3> =
+ let <_2> =
+ case _x of
+ <'true'> when 'true' ->
+ _y
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_v1>
+ when try
+ let <_5> =
+ call 'erlang':'=:='
+ (_v0, _v1)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_6> =
+ call 'erlang':'and'
+ (_x, _y)
+ in apply 'check'/2
+ (_v1, _6)
+ ( <_7> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_7}})
+ -| ['compiler_generated'] )
+ end
+ ( <_8> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_8})
+ -| [{'function_name',{'t-andalso-1',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t_orelse'/1 =
+ %% Line 215
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_bs> =
+ <['true'|['false']]>
+ in let <_ps> =
+ <letrec
+ 'lc$^2'/1 =
+ fun (_2) ->
+ case <_2> of
+ <[_x|_lfe2]> when 'true' ->
+ letrec
+ 'lc$^3'/1 =
+ fun (_3) ->
+ case <_3> of
+ <[_y|_lfe3]> when 'true' ->
+ let <_4> =
+ apply 'lc$^3'/1
+ (_lfe3)
+ in [{_x,_y}|_4]
+ <[]> when 'true' ->
+ apply 'lc$^2'/1
+ (_lfe2)
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'t_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^3'/1
+ (_bs)
+ <[]> when 'true' ->
+ []
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'t_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+ in apply 'lc$^2'/1
+ (_bs)>
+ in let <_7> =
+ fun (_p) ->
+ apply 't-orelse-1'/1
+ (_p)
+ in call 'lists':'foreach'
+ (_7, _ps)
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['orelse'|[['quote'|['true']]|[['quote'|['true']]]]]]]]})
+ let <_val> =
+ <case 'true' of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'true'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_8> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_8}})
+ -| ['compiler_generated'] )
+ end
+ ( <_57> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_57})
+ -| [{'function_name',{'t_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t-orelse-1'/1 =
+ %% Line 249
+ fun (_0) ->
+ case <_0> of
+ <{_x,_y}> when 'true' ->
+ do call 'io':'format'
+ ([40|[111|[114|[101|[108|[115|[101|[32|[126|[119|[32|[126|[119|[41|[58|[32]]]]]]]]]]]]]]]], [_x,_y])
+ let <_v0> =
+ <case apply 'echo'/1
+ (_x) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ apply 'echo'/1
+ (_y)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <case 1 of
+ <_1>
+ when try
+ let <_3> =
+ let <_2> =
+ case _x of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _y
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_v1>
+ when try
+ let <_5> =
+ call 'erlang':'=:='
+ (_v0, _v1)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_6> =
+ call 'erlang':'or'
+ (_x, _y)
+ in apply 'check'/2
+ (_v1, _6)
+ ( <_7> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_7}})
+ -| ['compiler_generated'] )
+ end
+ ( <_8> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_8})
+ -| [{'function_name',{'t-orelse-1',1}}] )
+ -| ['compiler_generated'] )
+ end
+'inside'/1 =
+ %% Line 257
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['inside'|[-8|[1]]]]]]})
+ let <_val> =
+ <apply 'inside'/2
+ (-8, 1)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12})
+ -| [{'function_name',{'inside',1}}] )
+ -| ['compiler_generated'] )
+ end
+'inside'/2 =
+ %% Line 272
+ fun (_xm,_ym) ->
+ let <_x> =
+ <-1.00000000000000000000e+01>
+ in let <_y> =
+ <-2.00000000000000000000e+00>
+ in let <_w> =
+ <2.00000000000000000000e+01>
+ in let <_h> =
+ <4.00000000000000000000e+00>
+ in let <_r0> =
+ <apply 'inside'/6
+ (_xm, _ym, _x, _y, _w, _h)>
+ in case <case 1 of
+ <_0>
+ when try
+ let <_4> =
+ let <_3> =
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_1> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _1) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_2> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _2)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r1>
+ when try
+ let <_6> =
+ call 'erlang':'=:='
+ (_r0, _r1)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do case let <_7> =
+ apply 'id'/1
+ (_r1)
+ in call 'erlang':'not'
+ (_7) of
+ <_o0> when 'true' ->
+ case <case 1 of
+ <_8>
+ when try
+ let <_12> =
+ let <_11> =
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_9> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _9) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_10> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _10)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in call 'erlang':'not'
+ (_11)
+ in _12
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_13>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_o1>
+ when try
+ let <_14> =
+ call 'erlang':'=:='
+ (_o0, _o1)
+ in _14
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _o1
+ ( <_15> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_15}})
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ do case <apply 'inside-guard'/6
+ (_xm, _ym, _x, _y, _w, _h)> of
+ <{_r2,_xm2,_ym2,_x2,_y2,_w2,_h2}>
+ when try
+ let <_16> =
+ call 'erlang':'=:='
+ (_r1, _r2)
+ in let <_17> =
+ call 'erlang':'=:='
+ (_xm, _xm2)
+ in let <_18> =
+ call 'erlang':'=:='
+ (_ym, _ym2)
+ in let <_19> =
+ call 'erlang':'=:='
+ (_x, _x2)
+ in let <_20> =
+ call 'erlang':'=:='
+ (_y, _y2)
+ in let <_21> =
+ call 'erlang':'=:='
+ (_w, _w2)
+ in let <_22> =
+ call 'erlang':'=:='
+ (_h, _h2)
+ in let <_23> =
+ call 'erlang':'and'
+ (_16, _17)
+ in let <_24> =
+ call 'erlang':'and'
+ (_23, _18)
+ in let <_25> =
+ call 'erlang':'and'
+ (_24, _19)
+ in let <_26> =
+ call 'erlang':'and'
+ (_25, _20)
+ in let <_27> =
+ call 'erlang':'and'
+ (_26, _21)
+ in call 'erlang':'and'
+ (_27, _22)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_30> =
+ let <_28> =
+ call 'erlang':'+'
+ (_x, _w)
+ in let <_29> =
+ call 'erlang':'+'
+ (_y, _h)
+ in [_x,_xm,_xm,_28,_y,_ym,_ym,_29,_r1]
+ in call 'io':'fwrite'
+ ([40|[97|[110|[100|[97|[108|[115|[111|[32|[40|[61|[60|[32|[126|[112|[32|[126|[112|[41|[32|[40|[60|[32|[126|[112|[32|[126|[112|[41|[32|[40|[61|[60|[32|[126|[112|[32|[126|[112|[41|[32|[40|[60|[32|[126|[112|[32|[126|[112|[41|[41|[32|[61|[61|[62|[32|[126|[112|[10]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]], _30)
+ ( <_31> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_31}})
+ -| ['compiler_generated'] )
+ end
+ _r1
+ ( <_32> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_32}})
+ -| ['compiler_generated'] )
+ end
+'inside'/6 =
+ %% Line 297
+ fun (_xm,_ym,_x,_y,_w,_h) ->
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_0> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _0) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_1> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _1)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+'inside-guard'/6 =
+ %% Line 300
+ fun (_5,_4,_3,_2,_1,_0) ->
+ case <_5,_4,_3,_2,_1,_0> of
+ <_xm,_ym,_x,_y,_w,_h>
+ when try
+ let <_9> =
+ let <_8> =
+ case call 'erlang':'=<'
+ (_x, _xm) of
+ <'true'> when 'true' ->
+ case let <_6> =
+ call 'erlang':'+'
+ (_x, _w)
+ in call 'erlang':'<'
+ (_xm, _6) of
+ <'true'> when 'true' ->
+ case call 'erlang':'=<'
+ (_y, _ym) of
+ <'true'> when 'true' ->
+ let <_7> =
+ call 'erlang':'+'
+ (_y, _h)
+ in call 'erlang':'<'
+ (_ym, _7)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_8, 'true')
+ -| ['compiler_generated'] )
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ {'true',_xm,_ym,_x,_y,_w,_h}
+ <_xm,_ym,_x,_y,_w,_h> when 'true' ->
+ {'false',_xm,_ym,_x,_y,_w,_h}
+ ( <_15,_14,_13,_12,_11,_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_15,_14,_13,_12,_11,_10})
+ -| [{'function_name',{'inside-guard',6}}] )
+ -| ['compiler_generated'] )
+ end
+'overlap'/1 =
+ %% Line 307
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['true']]|[['overlap'|[7.00000000000000000000e+00|[2.00000000000000000000e+00|[8.00000000000000000000e+00|[5.00000000000000000000e-01]]]]]]]]})
+ let <_val> =
+ <apply 'overlap'/4
+ (7.00000000000000000000e+00, 2.00000000000000000000e+00, 8.00000000000000000000e+00, 5.00000000000000000000e-01)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_10})
+ -| [{'function_name',{'overlap',1}}] )
+ -| ['compiler_generated'] )
+ end
+'overlap'/4 =
+ %% Line 321
+ fun (_pos1,_len1,_pos2,_len2) ->
+ let <_r0> =
+ <case _pos1 of
+ <_pos1>
+ when try
+ let <_3> =
+ let <_2> =
+ case case call 'erlang':'=<'
+ (_pos2, _pos1) of
+ <'true'> when 'true' ->
+ let <_0> =
+ call 'erlang':'+'
+ (_pos2, _len2)
+ in call 'erlang':'<'
+ (_pos1, _0)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_pos1, _pos2) of
+ <'true'> when 'true' ->
+ let <_1> =
+ call 'erlang':'+'
+ (_pos1, _len1)
+ in call 'erlang':'<'
+ (_pos2, _1)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_pos1> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <case case call 'erlang':'=<'
+ (_pos2, _pos1) of
+ <'true'> when 'true' ->
+ let <_4> =
+ call 'erlang':'+'
+ (_pos2, _len2)
+ in call 'erlang':'<'
+ (_pos1, _4)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_pos1, _pos2) of
+ <'true'> when 'true' ->
+ let <_5> =
+ call 'erlang':'+'
+ (_pos1, _len1)
+ in call 'erlang':'<'
+ (_pos2, _5)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end> of
+ <_r1>
+ when try
+ let <_6> =
+ call 'erlang':'=:='
+ (_r0, _r1)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case _pos1 of
+ <_pos1>
+ when try
+ let <_10> =
+ let <_9> =
+ case case call 'erlang':'=<'
+ (_pos2, _pos1) of
+ <'true'> when 'true' ->
+ let <_7> =
+ call 'erlang':'+'
+ (_pos2, _len2)
+ in call 'erlang':'<'
+ (_pos1, _7)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_pos1, _pos2) of
+ <'true'> when 'true' ->
+ let <_8> =
+ call 'erlang':'+'
+ (_pos1, _len1)
+ in call 'erlang':'<'
+ (_pos2, _8)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_9, 'true')
+ -| ['compiler_generated'] )
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_pos1> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r2>
+ when try
+ let <_11> =
+ call 'erlang':'=:='
+ (_r2, _r1)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_r2)
+ ( <_12> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_12}})
+ -| ['compiler_generated'] )
+ end
+ ( <_13> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_13}})
+ -| ['compiler_generated'] )
+ end
+'combined'/1 =
+ %% Line 348
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['false']]|[['comb'|[['quote'|['false']]|[['quote'|['false']]|[['quote'|['false']]]]]]]]]})
+ let <_val> =
+ <apply 'comb'/3
+ ('false', 'false', 'false')>
+ in case <_val> of
+ <'false'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_26> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_26})
+ -| [{'function_name',{'combined',1}}] )
+ -| ['compiler_generated'] )
+ end
+'comb'/3 =
+ %% Line 383
+ fun (_a,_b,_c) ->
+ let <_r0> =
+ <case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end>
+ in case <case 1 of
+ <_0>
+ when try
+ let <_2> =
+ let <_1> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_1, 'true')
+ -| ['compiler_generated'] )
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_3>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r1>
+ when try
+ let <_4> =
+ call 'erlang':'=:='
+ (_r0, _r1)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_n0> =
+ <case 1 of
+ <_5>
+ when try
+ let <_7> =
+ let <_6> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in call 'erlang':'not'
+ (_6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <let <_9> =
+ call 'erlang':'not'
+ (_r1)
+ in apply 'id'/1
+ (_9)> of
+ <_n1>
+ when try
+ let <_10> =
+ call 'erlang':'=:='
+ (_n0, _n1)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end> of
+ <_r2>
+ when try
+ let <_11> =
+ call 'erlang':'=:='
+ (_r1, _r2)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case 1 of
+ <_12>
+ when try
+ let <_14> =
+ let <_13> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_13, 'true')
+ -| ['compiler_generated'] )
+ in _14
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_15>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r3>
+ when try
+ let <_16> =
+ call 'erlang':'=:='
+ (_r2, _r3)
+ in _16
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <let <_17> =
+ call 'erlang':'not'
+ (_r3)
+ in apply 'id'/1
+ (_17)> of
+ <_n2>
+ when try
+ let <_18> =
+ call 'erlang':'=:='
+ (_n1, _n2)
+ in _18
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <case 1 of
+ <_19>
+ when try
+ let <_21> =
+ let <_20> =
+ case case _a of
+ <'true'> when 'true' ->
+ _b
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ _c
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_20, 'true')
+ -| ['compiler_generated'] )
+ in _21
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_22>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <_r4>
+ when try
+ let <_23> =
+ call 'erlang':'=:='
+ (_r3, _r4)
+ in _23
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_r4)
+ ( <_24> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_24}})
+ -| ['compiler_generated'] )
+ end
+ ( <_25> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_25}})
+ -| ['compiler_generated'] )
+ end
+ ( <_26> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_26}})
+ -| ['compiler_generated'] )
+ end
+ ( <_27> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_27}})
+ -| ['compiler_generated'] )
+ end
+ ( <_28> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_28}})
+ -| ['compiler_generated'] )
+ end
+ ( <_29> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_29}})
+ -| ['compiler_generated'] )
+ end
+'in_case'/1 =
+ %% Line 402
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['edge_rings']]|[['in-case-1'|[1|[1|[1|[1|[1]]]]]]]]]})
+ let <_val> =
+ <apply 'in-case-1'/5
+ (1, 1, 1, 1, 1)>
+ in case <_val> of
+ <'edge_rings'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_13> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13})
+ -| [{'function_name',{'in_case',1}}] )
+ -| ['compiler_generated'] )
+ end
+'in-case-1'/5 =
+ %% Line 419
+ fun (_lenup,_lendw,_lenn,_rot,_count) ->
+ let <_r0> =
+ <apply 'in-case-1-body'/5
+ (_lenup, _lendw, _lenn, _rot, _count)>
+ in case <apply 'in-case-1-guard'/5
+ (_lenup, _lendw, _lenn, _rot, _count)> of
+ <_res>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_r0, _res)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _res
+ ( <_1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_1}})
+ -| ['compiler_generated'] )
+ end
+'in-case-1-body'/5 =
+ %% Line 425
+ fun (_lenup,_lendw,_lenn,_rot,_count) ->
+ case let <_5> =
+ let <_2> =
+ let <_0> =
+ call 'erlang':'/'
+ (_lenup, _count)
+ in call 'erlang':'>'
+ (_0, 7.06999999999999961808e-01)
+ in let <_3> =
+ let <_1> =
+ call 'erlang':'/'
+ (_lenn, _count)
+ in call 'erlang':'>'
+ (_1, 7.06999999999999961808e-01)
+ in call 'erlang':'and'
+ (_2, _3)
+ in let <_6> =
+ let <_4> =
+ call 'erlang':'abs'
+ (_rot)
+ in call 'erlang':'>'
+ (_4, 7.06999999999999961808e-01)
+ in call 'erlang':'and'
+ (_5, _6) of
+ <'true'> when 'true' ->
+ 'edge_rings'
+ <'false'> when 'true' ->
+ case let <_11> =
+ let <_9> =
+ let <_7> =
+ call 'erlang':'>='
+ (_lenup, 1)
+ in let <_8> =
+ call 'erlang':'>='
+ (_lendw, 1)
+ in call 'erlang':'or'
+ (_7, _8)
+ in let <_10> =
+ call 'erlang':'=<'
+ (_lenn, 1)
+ in call 'erlang':'or'
+ (_9, _10)
+ in let <_12> =
+ call 'erlang':'>'
+ (_count, 4)
+ in call 'erlang':'or'
+ (_11, _12) of
+ <'true'> when 'true' ->
+ 'not_loop'
+ <'false'> when 'true' ->
+ 'loop'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'in-case-1-guard'/5 =
+ %% Line 435
+ fun (_lenup,_lendw,_lenn,_rot,_count) ->
+ case case let <_0> =
+ call 'erlang':'/'
+ (_lenup, _count)
+ in call 'erlang':'>'
+ (_0, 7.06999999999999961808e-01) of
+ <'true'> when 'true' ->
+ case let <_1> =
+ call 'erlang':'/'
+ (_lenn, _count)
+ in call 'erlang':'>'
+ (_1, 7.06999999999999961808e-01) of
+ <'true'> when 'true' ->
+ let <_2> =
+ call 'erlang':'abs'
+ (_rot)
+ in call 'erlang':'>'
+ (_2, 7.06999999999999961808e-01)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ('if_clause')
+ -| ['compiler_generated'] )
+ end of
+ <'true'> when 'true' ->
+ 'edge_rings'
+ <'false'>
+ when try
+ let <_4> =
+ let <_3> =
+ case call 'erlang':'>='
+ (_lenup, 1) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'>='
+ (_lendw, 1) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ case call 'erlang':'=<'
+ (_lenn, 1) of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ call 'erlang':'<'
+ (_count, 4)
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'not_loop'
+ <'false'> when 'true' ->
+ 'loop'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'before_and_inside_if'/1 =
+ %% Line 443
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_andor_SUITE',['test-pat'|[['quote'|['no']]|[['before-and-inside-if'|[['quote'|[['a']]]|[['quote'|[['b']]]|[['quote'|['delete']]]]]]]]]})
+ let <_val> =
+ <apply 'before-and-inside-if'/3
+ (['a'], ['b'], 'delete')>
+ in case <_val> of
+ <'no'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_18> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_18})
+ -| [{'function_name',{'before_and_inside_if',1}}] )
+ -| ['compiler_generated'] )
+ end
+'before-and-inside-if'/3 =
+ %% Line 468
+ fun (XDo1,XDo2,Do3) ->
+ let <Do1> =
+ <call 'erlang':'=/='
+ (XDo1, [])>
+ in let <Do2> =
+ <call 'erlang':'=/='
+ (XDo2, [])>
+ in case 1 of
+ <_0>
+ when try
+ let <_7> =
+ let <_5> =
+ call 'erlang':'=:='
+ (Do1, 'true')
+ in let <_6> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'=:='
+ (Do1, 'false')
+ in let <_2> =
+ call 'erlang':'=:='
+ (Do2, 'false')
+ in call 'erlang':'and'
+ (_1, _2)
+ in let <_4> =
+ call 'erlang':'=:='
+ (Do3, 'delete')
+ in call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'or'
+ (_5, _6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'no'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'yes'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'before-and-inside-if-2'/3 =
+ %% Line 484
+ fun (XDo1,XDo2,Do3) ->
+ let <Do1> =
+ <call 'erlang':'=/='
+ (XDo1, [])>
+ in let <Do2> =
+ <call 'erlang':'=/='
+ (XDo2, [])>
+ in let <CH1> =
+ <case 1 of
+ <_0>
+ when try
+ let <_7> =
+ let <_5> =
+ call 'erlang':'=='
+ (Do1, 'true')
+ in let <_6> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'=='
+ (Do1, 'false')
+ in let <_2> =
+ call 'erlang':'=='
+ (Do2, 'false')
+ in call 'erlang':'and'
+ (_1, _2)
+ in let <_4> =
+ call 'erlang':'=='
+ (Do3, 'blah')
+ in call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'or'
+ (_5, _6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ch1'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'no'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in let <CH2> =
+ <case 1 of
+ <_9>
+ when try
+ let <_16> =
+ let <_14> =
+ call 'erlang':'=='
+ (Do1, 'true')
+ in let <_15> =
+ let <_12> =
+ let <_10> =
+ call 'erlang':'=='
+ (Do1, 'false')
+ in let <_11> =
+ call 'erlang':'=='
+ (Do2, 'false')
+ in call 'erlang':'and'
+ (_10, _11)
+ in let <_13> =
+ call 'erlang':'=='
+ (Do3, 'xx')
+ in call 'erlang':'and'
+ (_12, _13)
+ in call 'erlang':'or'
+ (_14, _15)
+ in _16
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ch2'
+ <_17>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'no'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in {CH1,CH2}
+'check'/2 =
+ %% Line 501
+ fun (_v1,_v0) ->
+ case 1 of
+ <_0>
+ when try
+ let <_1> =
+ call 'erlang':'/='
+ (_v1, _v0)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'io':'fwrite'
+ ([101|[114|[114|[111|[114|[58|[32|[126|[119|[46|[10]]]]]]]]]]], [_v1])
+ call 'erlang':'exit'
+ ('suite_failed')
+ <_2>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ call 'io':'fwrite'
+ ([111|[107|[58|[32|[126|[119|[46|[10]]]]]]]], [_v1])
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'echo'/1 =
+ %% Line 506
+ fun (_x) ->
+ do call 'io':'fwrite'
+ ([40|[101|[118|[97|[108|[32|[126|[119|[41|[59|[32]]]]]]]]]]], [_x])
+ _x
+'id'/1 =
+ %% Line 511
+ fun (_i) ->
+ _i
+'$handle_undefined_function'/2 =
+ %% Line 29
+ fun (_f,_as) ->
+ case let <_0> =
+ call 'lfe_env':'new'
+ ()
+ in apply 'LFE-EXPAND-EXPORTED-MACRO'/3
+ (_f, _as, _0) of
+ <{'yes',_exp}> when 'true' ->
+ call 'lfe_eval':'expr'
+ (_exp)
+ <'no'> when 'true' ->
+ let <_a,_b> =
+ <_f,_as>
+ in call 'error_handler':'raise_undef_exception'
+ ('lfe_andor_SUITE', _a, _b)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'LFE-EXPAND-EXPORTED-MACRO'/3 =
+ %% Line 29
+ fun (_2,_1,_0) ->
+ 'no'
+'module_info'/0 =
+ fun () ->
+ call 'erlang':'get_module_info'
+ ('lfe_andor_SUITE')
+'module_info'/1 =
+ fun (_x) ->
+ call 'erlang':'get_module_info'
+ ('lfe_andor_SUITE', _x)
+end
diff --git a/lib/compiler/test/lfe_guard_SUITE.core b/lib/compiler/test/lfe_guard_SUITE.core
new file mode 100644
index 0000000000..920be82f61
--- /dev/null
+++ b/lib/compiler/test/lfe_guard_SUITE.core
@@ -0,0 +1,3438 @@
+module 'lfe_guard_SUITE' ['$handle_undefined_function'/2,
+ 'LFE-EXPAND-EXPORTED-MACRO'/3,
+ 'all'/0,
+ 'and_guard'/1,
+ 'andalso_semi'/1,
+ 'basic_andalso_orelse'/1,
+ 'basic_not'/1,
+ 'binary_part'/1,
+ 'build_in_guard'/1,
+ 'check_qlc_hrl'/1,
+ 'comma'/1,
+ 'complex_not'/1,
+ 'complex_or_guards'/1,
+ 'complex_semicolon'/1,
+ 'const_cond'/1,
+ 'end_per_group'/2,
+ 'end_per_suite'/1,
+ 'gbif'/1,
+ 'groups'/0,
+ 'init_per_group'/2,
+ 'init_per_suite'/1,
+ 'is_function_2'/1,
+ 'literal_type_tests'/1,
+ 'misc'/1,
+ 'module_info'/0,
+ 'module_info'/1,
+ 'more_or_guards'/1,
+ 'more_xor_guards'/1,
+ 'nested_nots'/1,
+ 'old_guard_tests'/1,
+ 'or_guard'/1,
+ 'rel_ops'/1,
+ 'semicolon'/1,
+ 'suite'/0,
+ 't_is_boolean'/1,
+ 't_tuple_size'/1,
+ 'traverse_dcd'/1,
+ 'tricky'/1,
+ 'xor_guard'/1]
+ attributes []
+'all'/0 =
+ %% Line 47
+ fun () ->
+ ['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'/0 =
+ %% Line 58
+ fun () ->
+ []
+'groups'/0 =
+ %% Line 60
+ fun () ->
+ []
+'init_per_suite'/1 =
+ %% Line 62
+ fun (_config) ->
+ _config
+'end_per_suite'/1 =
+ %% Line 64
+ fun (_config) ->
+ 'ok'
+'init_per_group'/2 =
+ %% Line 66
+ fun (_name,_config) ->
+ _config
+'end_per_group'/2 =
+ %% Line 68
+ fun (_name,_config) ->
+ _config
+'misc'/1 =
+ %% Line 70
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[42|[['case'|[['id'|[42]]|[['x'|[['when'|[['-'|['x']]]]|[['quote'|['ok']]]]]|[['x'|['x']]]]]]]]]})
+ let <_val> =
+ <case apply 'id'/1
+ (42) of
+ <_x>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'-'
+ (_x)
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_x> when 'true' ->
+ _x
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <42> when 'true' ->
+ _val
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_17> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_17})
+ -| [{'function_name',{'misc',1}}] )
+ -| ['compiler_generated'] )
+ end
+'misc-1'/1 =
+ %% Line 93
+ fun (_0) ->
+ case <_0> of
+ <[{_w},{_x},{_y},{_z}]> when 'true' ->
+ case 1 of
+ <_1>
+ when try
+ let <_4> =
+ let <_3> =
+ case call 'erlang':'>'
+ (_x, _y) of
+ <'true'> when 'true' ->
+ let <_2> =
+ call 'erlang':'abs'
+ (_z)
+ in call 'erlang':'=:='
+ (_2, 2)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'id'/1
+ (_w)
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'none'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'misc-1',1}}] )
+ -| ['compiler_generated'] )
+ end
+'get-data'/3 =
+ %% Line 99
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <{'o',_active,_raw},_bytes,_buffer>
+ when try
+ let <_5> =
+ let <_3> =
+ call 'erlang':'=:='
+ (_raw, 'raw')
+ in let <_4> =
+ call 'erlang':'=:='
+ (_raw, 0)
+ in call 'erlang':'or'
+ (_3, _4)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case 1 of
+ <_6>
+ when try
+ let <_8> =
+ let <_7> =
+ case call 'erlang':'=/='
+ (_active, 'false') of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ call 'erlang':'=:='
+ (_bytes, 0)
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_7, 'true')
+ -| ['compiler_generated'] )
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ {'ok',_buffer,#{}#}
+ <_9>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_12,_11,_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12,_11,_10})
+ -| [{'function_name',{'get-data',3}}] )
+ -| ['compiler_generated'] )
+ end
+'const_cond'/1 =
+ %% Line 104
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['const-cond'|[{}|[0]]]]]]})
+ let <_val> =
+ <apply 'const-cond'/2
+ ({}, 0)>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_7> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_7})
+ -| [{'function_name',{'const_cond',1}}] )
+ -| ['compiler_generated'] )
+ end
+'const-cond'/2 =
+ %% Line 113
+ fun (_t,_sz) ->
+ case _t of
+ <_0>
+ when try
+ 'false'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'never'
+ <_1>
+ when try
+ let <_3> =
+ call 'erlang':'is_tuple'
+ (_t)
+ in let <_4> =
+ call 'erlang':'=='
+ ('eq', 'eq')
+ in let <_5> =
+ let <_2> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=='
+ (_2, _sz)
+ in let <_6> =
+ call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'and'
+ (_6, _5)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_7>
+ when try
+ let <_9> =
+ call 'erlang':'is_tuple'
+ (_t)
+ in let <_10> =
+ call 'erlang':'=='
+ ('eq', 'leq')
+ in let <_11> =
+ let <_8> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=='
+ (_8, _sz)
+ in let <_12> =
+ call 'erlang':'and'
+ (_9, _10)
+ in call 'erlang':'and'
+ (_12, _11)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_13> when 'true' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'basic_not'/1 =
+ %% Line 120
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_true> =
+ <apply 'id'/1
+ ('true')>
+ in let <_false> =
+ <apply 'id'/1
+ ('false')>
+ in let <_glurf> =
+ <apply 'id'/1
+ ('glurf')>
+ in let <_a> =
+ <apply 'id'/1
+ (5)>
+ in let <_b> =
+ <apply 'id'/1
+ (3.75000000000000000000e+01)>
+ in let <_c> =
+ <apply 'id'/1
+ (-1)>
+ in let <_d> =
+ <apply 'id'/1
+ (5)>
+ in let <_atuple> =
+ <{_false,_true,_glurf}>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['not'|[['quote'|['false']]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['ok']]]]]})
+ let <_5> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'not'
+ ('false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_5, 'ok')
+ ( <_128> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_128})
+ -| [{'function_name',{'basic_not',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex_not'/1 =
+ %% Line 164
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_atuple> =
+ <apply 'id'/1
+ ({'false','true','gurka'})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['not'|[['element'|[1|['atuple']]]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['ok']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'element'
+ (1, _atuple)
+ in call 'erlang':'not'
+ (_3)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'ok')
+ ( <_50> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_50})
+ -| [{'function_name',{'complex_not',1}}] )
+ -| ['compiler_generated'] )
+ end
+'nested_nots'/1 =
+ %% Line 191
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['true']]|[['nested-not-1'|[0|[0]]]]]]})
+ let <_val> =
+ <apply 'nested-not-1'/2
+ (0, 0)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_18> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_18})
+ -| [{'function_name',{'nested_nots',1}}] )
+ -| ['compiler_generated'] )
+ end
+'nested-not-1'/2 =
+ %% Line 213
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_x,_y>
+ when try
+ let <_10> =
+ let <_9> =
+ let <_7> =
+ let <_3> =
+ call 'erlang':'>'
+ (_x, _y)
+ in let <_4> =
+ let <_2> =
+ call 'erlang':'is_atom'
+ (_x)
+ in call 'erlang':'not'
+ (_2)
+ in call 'erlang':'or'
+ (_3, _4)
+ in let <_8> =
+ let <_5> =
+ call 'erlang':'is_atom'
+ (_y)
+ in let <_6> =
+ call 'erlang':'=='
+ (_x, 3.39999999999999991118e+00)
+ in call 'erlang':'or'
+ (_5, _6)
+ in call 'erlang':'and'
+ (_7, _8)
+ in call 'erlang':'not'
+ (_9)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_11,_12> when 'true' ->
+ 'false'
+ ( <_14,_13> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_14,_13})
+ -| [{'function_name',{'nested-not-1',2}}] )
+ -| ['compiler_generated'] )
+ end
+'nested-not-2'/3 =
+ %% Line 219
+ fun (_x,_y,_z) ->
+ apply 'nested-not-2'/4
+ (_x, _y, _z, 'true')
+'nested-not-2'/4 =
+ %% Line 222
+ fun (_3,_2,_1,_0) ->
+ case <_3,_2,_1,_0> of
+ <_x,_y,_z,_true>
+ when try
+ let <_12> =
+ let <_11> =
+ let <_10> =
+ let <_9> =
+ let <_7> =
+ let <_4> =
+ call 'erlang':'not'
+ (_x)
+ in let <_5> =
+ call 'erlang':'not'
+ (_y)
+ in call 'erlang':'and'
+ (_4, _5)
+ in let <_8> =
+ let <_6> =
+ call 'erlang':'is_atom'
+ (_z)
+ in call 'erlang':'not'
+ (_6)
+ in call 'erlang':'or'
+ (_7, _8)
+ in call 'erlang':'not'
+ (_9)
+ in call 'erlang':'and'
+ (_true, _10)
+ in call 'erlang':'not'
+ (_11)
+ in _12
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_13,_14,_15,_16> when 'true' ->
+ 'false'
+ ( <_20,_19,_18,_17> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_20,_19,_18,_17})
+ -| [{'function_name',{'nested-not-2',4}}] )
+ -| ['compiler_generated'] )
+ end
+'semicolon'/1 =
+ %% Line 228
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'semicolon',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex_semicolon'/1 =
+ %% Line 233
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'complex_semicolon',1}}] )
+ -| ['compiler_generated'] )
+ end
+'comma'/1 =
+ %% Line 239
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['progn'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'and'
+ ('true', 'false')
+ in ( call 'erlang':'=:='
+ (_3, 'true')
+ -| ['compiler_generated'] )
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'error')
+ ( <_181> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_181})
+ -| [{'function_name',{'comma',1}}] )
+ -| ['compiler_generated'] )
+ end
+'or_guard'/1 =
+ %% Line 305
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_true,_false,_glurf> =
+ <apply 'id'/1
+ ('true'),apply 'id'/1
+ ('false'),apply 'id'/1
+ ('glurf')>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['or'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]]]]]]]|[['quote'|['ok']]]]]})
+ let <_4> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'or'
+ ('true', 'false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_4, 'ok')
+ 'ok'
+ ( <_64> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_64})
+ -| [{'function_name',{'or_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'more_or_guards'/1 =
+ %% Line 346
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do let <_true> =
+ <apply 'id'/1
+ ('true')>
+ in let <_false> =
+ <apply 'id'/1
+ ('false')>
+ in let <_atuple> =
+ <apply 'id'/1
+ ({'false','true','gurks'})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['or'|[['element'|[42|['atuple']]]|['false']]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'element'
+ (42, _atuple)
+ in call 'erlang':'or'
+ (_3, _false)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'error')
+ 'ok'
+ ( <_68> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_68})
+ -| [{'function_name',{'more_or_guards',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex_or_guards'/1 =
+ %% Line 409
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['complex-or-1'|[{'a','b','c','d'}|[{1,2,3}]]]]]]})
+ let <_val> =
+ <apply 'complex-or-1'/2
+ ({'a','b','c','d'}, {1,2,3})>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_55> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_55})
+ -| [{'function_name',{'complex_or_guards',1}}] )
+ -| ['compiler_generated'] )
+ end
+'complex-or-1'/2 =
+ %% Line 487
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_11> =
+ let <_9> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'tuple_size'
+ (_a)
+ in call 'erlang':'<'
+ (3, _1)
+ in let <_4> =
+ let <_2> =
+ call 'erlang':'tuple_size'
+ (_a)
+ in call 'erlang':'<'
+ (_2, 9)
+ in call 'erlang':'and'
+ (_3, _4)
+ in let <_10> =
+ let <_7> =
+ let <_5> =
+ call 'erlang':'tuple_size'
+ (_b)
+ in call 'erlang':'<'
+ (2, _5)
+ in let <_8> =
+ let <_6> =
+ call 'erlang':'tuple_size'
+ (_b)
+ in call 'erlang':'<'
+ (_6, 7)
+ in call 'erlang':'and'
+ (_7, _8)
+ in call 'erlang':'or'
+ (_9, _10)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_12>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-2'/1 =
+ %% Line 492
+ fun (_tuple) ->
+ case 1 of
+ <_0>
+ when try
+ let <_6> =
+ let <_4> =
+ call 'erlang':'element'
+ (1, _tuple)
+ in let <_5> =
+ let <_3> =
+ let <_2> =
+ let <_1> =
+ call 'erlang':'element'
+ (2, _tuple)
+ in call 'erlang':'tuple_size'
+ (_1)
+ in call 'erlang':'>'
+ (_2, 3)
+ in call 'erlang':'not'
+ (_3)
+ in call 'erlang':'or'
+ (_4, _5)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_7>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-3'/2 =
+ %% Line 496
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_5> =
+ let <_3> =
+ let <_2> =
+ let <_1> =
+ call 'erlang':'size'
+ (_b)
+ in call 'erlang':'>'
+ (_1, 3)
+ in call 'erlang':'not'
+ (_2)
+ in let <_4> =
+ call 'erlang':'element'
+ (1, _a)
+ in call 'erlang':'or'
+ (_3, _4)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_6>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-4'/2 =
+ %% Line 499
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_7> =
+ let <_5> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'is_tuple'
+ (_a)
+ in let <_3> =
+ let <_1> =
+ call 'erlang':'size'
+ (_a)
+ in call 'erlang':'>'
+ (_1, 3)
+ in call 'erlang':'and'
+ (_2, _3)
+ in call 'erlang':'not'
+ (_4)
+ in let <_6> =
+ call 'erlang':'element'
+ (1, _b)
+ in call 'erlang':'or'
+ (_5, _6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-5'/2 =
+ %% Line 503
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_8> =
+ let <_6> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'is_tuple'
+ (_a)
+ in let <_3> =
+ let <_1> =
+ call 'erlang':'size'
+ (_a)
+ in call 'erlang':'>'
+ (_1, 3)
+ in call 'erlang':'and'
+ (_2, _3)
+ in call 'erlang':'not'
+ (_4)
+ in let <_7> =
+ let <_5> =
+ call 'erlang':'element'
+ (1, _b)
+ in call 'erlang':'not'
+ (_5)
+ in call 'erlang':'or'
+ (_6, _7)
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_9>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'complex-or-6'/2 =
+ %% Line 507
+ fun (_a,_b) ->
+ case 1 of
+ <_0>
+ when try
+ let <_11> =
+ let <_9> =
+ let <_5> =
+ let <_3> =
+ let <_1> =
+ call 'erlang':'element'
+ (1, _a)
+ in call 'erlang':'not'
+ (_1)
+ in let <_4> =
+ let <_2> =
+ call 'erlang':'element'
+ (2, _a)
+ in call 'erlang':'not'
+ (_2)
+ in call 'erlang':'and'
+ (_3, _4)
+ in call 'erlang':'not'
+ (_5)
+ in let <_10> =
+ let <_8> =
+ let <_7> =
+ let <_6> =
+ call 'erlang':'size'
+ (_b)
+ in call 'erlang':'>'
+ (_6, 3)
+ in call 'erlang':'not'
+ (_7)
+ in call 'erlang':'not'
+ (_8)
+ in call 'erlang':'or'
+ (_9, _10)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_12>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'and_guard'/1 =
+ %% Line 512
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['and'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_5> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'and'
+ ('true', 'false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_5, 'error')
+ ( <_120> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_120})
+ -| [{'function_name',{'and_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'relprod'/2 =
+ %% Line 588
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_r1,_r2>
+ when try
+ let <_10> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'size'
+ (_r1)
+ in call 'erlang':'=:='
+ (_2, 3)
+ in let <_5> =
+ let <_3> =
+ call 'erlang':'element'
+ (1, _r1)
+ in call 'erlang':'=:='
+ (_3, 'Set')
+ in call 'erlang':'and'
+ (_4, _5)
+ in let <_11> =
+ let <_8> =
+ let <_6> =
+ call 'erlang':'size'
+ (_r2)
+ in call 'erlang':'=:='
+ (_6, 3)
+ in let <_9> =
+ let <_7> =
+ call 'erlang':'element'
+ (1, _r2)
+ in call 'erlang':'=:='
+ (_7, 'Set')
+ in call 'erlang':'and'
+ (_8, _9)
+ in call 'erlang':'and'
+ (_10, _11)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'relprod',2}}] )
+ -| ['compiler_generated'] )
+ end
+'xor_guard'/1 =
+ %% Line 595
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['xor'|[['quote'|['true']]|[['quote'|['false']]]]]|[['quote'|['ok']]]]]]]]|[['quote'|['ok']]]]]})
+ let <_4> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'xor'
+ ('true', 'false')
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_4, 'ok')
+ ( <_54> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_54})
+ -| [{'function_name',{'xor_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'more_xor_guards'/1 =
+ %% Line 636
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_true,_false,_atuple> =
+ <apply 'id'/1
+ ('true'),apply 'id'/1
+ ('false'),apply 'id'/1
+ ({'false','true','gurka'})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['check'|[['lambda'|[[]|[['eif'|[['xor'|[['element'|[42|['atuple']]]|['false']]]|[['quote'|['ok']]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]|[['quote'|['error']]]]]})
+ let <_6> =
+ fun () ->
+ case 1 of
+ <_2>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'element'
+ (42, _atuple)
+ in call 'erlang':'xor'
+ (_3, _false)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_5>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ in apply 'check'/2
+ (_6, 'error')
+ ( <_29> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_29})
+ -| [{'function_name',{'more_xor_guards',1}}] )
+ -| ['compiler_generated'] )
+ end
+'build_in_guard'/1 =
+ %% Line 666
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_subbin> =
+ <#{#<64>(8,1,'integer',['unsigned'|['big']]),
+ #<20>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']]),
+ #<0>(8,1,'integer',['unsigned'|['big']])}#>
+ in let <_b> =
+ <#{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<_subbin>('all',8,'binary',['unsigned'|['big']]),
+ #<3.50000000000000000000e+00>(64,1,'float',['unsigned'|['big']])}#>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['eif'|[['=:='|['b'|[['binary'|[1|[['subbin'|['binary']]|[[3.50000000000000000000e+00|['float']]]]]]]]]|[['quote'|['ok']]]]]]]]})
+ let <_val> =
+ <case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'=:='
+ (_b, #{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<_subbin>('all',8,'binary',['unsigned'|['big']]),
+ #<3.50000000000000000000e+00>(64,1,'float',['unsigned'|['big']])}#)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'build_in_guard',1}}] )
+ -| ['compiler_generated'] )
+ end
+'old_guard_tests'/1 =
+ %% Line 674
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'old_guard_tests',1}}] )
+ -| ['compiler_generated'] )
+ end
+'gbif'/1 =
+ %% Line 679
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['error']]|[['gbif-1'|[1|[{'false','true'}]]]]]]})
+ let <_val> =
+ <apply 'gbif-1'/2
+ (1, {'false','true'})>
+ in case <_val> of
+ <'error'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_4> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_4})
+ -| [{'function_name',{'gbif',1}}] )
+ -| ['compiler_generated'] )
+ end
+'gbif-1'/2 =
+ %% Line 685
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_p,_t>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'element'
+ (_p, _t)
+ in ( call 'erlang':'=:='
+ (_2, 'true')
+ -| ['compiler_generated'] )
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4,_5> when 'true' ->
+ 'error'
+ ( <_7,_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_7,_6})
+ -| [{'function_name',{'gbif-1',2}}] )
+ -| ['compiler_generated'] )
+ end
+'t_is_boolean'/1 =
+ %% Line 690
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['true']]|[['is_boolean'|[['quote'|['true']]]]]]]})
+ let <_val> =
+ <call 'erlang':'is_boolean'
+ ('true')>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_70> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_70})
+ -| [{'function_name',{'t_is_boolean',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bool'/1 =
+ %% Line 744
+ fun (_0) ->
+ case <_0> of
+ <_x>
+ when try
+ let <_1> =
+ call 'erlang':'is_boolean'
+ (_x)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_2> when 'true' ->
+ 'error'
+ ( <_3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_3})
+ -| [{'function_name',{'bool',1}}] )
+ -| ['compiler_generated'] )
+ end
+'my-is-bool'/1 =
+ %% Line 748
+ fun (_v) ->
+ let <_r0> =
+ <apply 'my-is-bool-a'/1
+ (_v)>
+ in case <apply 'my-is-bool-b'/1
+ (_v)> of
+ <_res>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_res, _r0)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ _res
+ ( <_1> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_1}})
+ -| ['compiler_generated'] )
+ end
+'my-is-bool-a'/1 =
+ %% Line 753
+ fun (_v) ->
+ case _v of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'true'
+ <_0> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'my-is-bool-b'/1 =
+ %% Line 759
+ fun (_v) ->
+ case _v of
+ <'false'> when 'true' ->
+ 'true'
+ <'true'> when 'true' ->
+ 'true'
+ <_0> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'is_function_2'/1 =
+ %% Line 765
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['true']]|[['is_function'|[['id'|[['function'|['lfe_guard_SUITE'|['all'|[1]]]]]]|[1]]]]]]})
+ let <_val> =
+ <let <_3> =
+ let <_2> =
+ call 'erlang':'make_fun'
+ ('lfe_guard_SUITE', 'all', 1)
+ in apply 'id'/1
+ (_2)
+ in call 'erlang':'is_function'
+ (_3, 1)>
+ in case <_val> of
+ <'true'> when 'true' ->
+ _val
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_17> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_17})
+ -| [{'function_name',{'is_function_2',1}}] )
+ -| ['compiler_generated'] )
+ end
+'tricky'/1 =
+ %% Line 775
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['not_ok']]|[['tricky-1'|[1|[2]]]]]]})
+ let <_val> =
+ <apply 'tricky-1'/2
+ (1, 2)>
+ in case <_val> of
+ <'not_ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12})
+ -| [{'function_name',{'tricky',1}}] )
+ -| ['compiler_generated'] )
+ end
+'tricky-1'/2 =
+ %% Line 791
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_x,_y>
+ when try
+ let <_6> =
+ let <_5> =
+ let <_4> =
+ let <_2> =
+ call 'erlang':'=='
+ (_x, 1)
+ in let <_3> =
+ call 'erlang':'=='
+ (_y, 2)
+ in call 'erlang':'or'
+ (_2, _3)
+ in call 'erlang':'abs'
+ (_4)
+ in ( call 'erlang':'=:='
+ (_5, 'true')
+ -| ['compiler_generated'] )
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_7,_8> when 'true' ->
+ 'not_ok'
+ ( <_10,_9> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_10,_9})
+ -| [{'function_name',{'tricky-1',2}}] )
+ -| ['compiler_generated'] )
+ end
+'tricky-2'/1 =
+ %% Line 795
+ fun (_0) ->
+ case <_0> of
+ <_x>
+ when try
+ let <_3> =
+ let <_1> =
+ call 'erlang':'float'
+ (_x)
+ in let <_2> =
+ call 'erlang':'float'
+ (_x)
+ in call 'erlang':'or'
+ (_1, _2)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4> when 'true' ->
+ 'error'
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'tricky-2',1}}] )
+ -| ['compiler_generated'] )
+ end
+'rb'/3 =
+ %% Line 801
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <_size,_toread,_sofar>
+ when try
+ let <_6> =
+ let <_4> =
+ let <_3> =
+ call 'erlang':'+'
+ (_sofar, _size)
+ in call 'erlang':'<'
+ (_3, 81920)
+ in let <_5> =
+ call 'erlang':'=='
+ (_toread, [])
+ in call 'erlang':'or'
+ (_4, _5)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'true'
+ <_7,_8,_9> when 'true' ->
+ 'false'
+ ( <_12,_11,_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12,_11,_10})
+ -| [{'function_name',{'rb',3}}] )
+ -| ['compiler_generated'] )
+ end
+'rel_ops'/1 =
+ %% Line 830
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['T'|['=/='|[1|[1.00000000000000000000e+00]]]]})
+ case <case 1 of
+ <_2>
+ when try
+ let <_3> =
+ call 'erlang':'=/='
+ (1, 1.00000000000000000000e+00)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_4>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_5>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'=/='
+ (1, 1.00000000000000000000e+00)
+ in call 'erlang':'not'
+ (_6)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ <_8>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ let <_x,_y,_true,_false> =
+ <apply 'id'/1
+ (1),apply 'id'/1
+ (1.00000000000000000000e+00),apply 'id'/1
+ ('true'),apply 'id'/1
+ ('false')>
+ in case <case 1 of
+ <_9>
+ when try
+ let <_10> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_11>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_12>
+ when try
+ let <_15> =
+ let <_14> =
+ let <_13> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'or'
+ (_false, _13)
+ in call 'erlang':'or'
+ (_14, _false)
+ in _15
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_16>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_17>
+ when try
+ let <_19> =
+ let <_18> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'and'
+ (_18, _true)
+ in _19
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_20>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_21>
+ when try
+ let <_23> =
+ let <_22> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'not'
+ (_22)
+ in _23
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ <_24>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ case <case 1 of
+ <_25>
+ when try
+ let <_29> =
+ let <_28> =
+ let <_27> =
+ let <_26> =
+ call 'erlang':'=/='
+ (_x, _y)
+ in call 'erlang':'not'
+ (_26)
+ in call 'erlang':'or'
+ (_false, _27)
+ in call 'erlang':'or'
+ (_28, _false)
+ in _29
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ <_30>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end> of
+ <'ok'> when 'true' ->
+ 'ok'
+ ( <_31> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_31}})
+ -| ['compiler_generated'] )
+ end
+ ( <_32> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_32}})
+ -| ['compiler_generated'] )
+ end
+ ( <_33> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_33}})
+ -| ['compiler_generated'] )
+ end
+ ( <_34> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_34}})
+ -| ['compiler_generated'] )
+ end
+ ( <_35> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_35}})
+ -| ['compiler_generated'] )
+ end
+ ( <_36> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_36}})
+ -| ['compiler_generated'] )
+ end
+ ( <_37> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_37}})
+ -| ['compiler_generated'] )
+ end
+ ( <_769> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_769})
+ -| [{'function_name',{'rel_ops',1}}] )
+ -| ['compiler_generated'] )
+ end
+'literal_type_tests'/1 =
+ %% Line 873
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case 'guard_suite' of
+ <'guard_suite'> when 'true' ->
+ apply 'literal-type-tests-1'/1
+ (_config)
+ <_2> when 'true' ->
+ {'skip',[69|[110|[111|[117|[103|[104|[32|[116|[111|[32|[114|[117|[110|[32|[116|[104|[105|[115|[32|[99|[97|[115|[101|[32|[111|[110|[99|[101|[46]]]]]]]]]]]]]]]]]]]]]]]]]]]]]}
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_3})
+ -| [{'function_name',{'literal_type_tests',1}}] )
+ -| ['compiler_generated'] )
+ end
+'literal-type-tests-1'/1 =
+ %% Line 879
+ fun (_config) ->
+ 'ok'
+'basic_andalso_orelse'/1 =
+ %% Line 967
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_t> =
+ <apply 'id'/1
+ ({'type','integers',23,42})>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[65|[['eif'|[['andalso'|[['=:='|[['element'|[1|['t']]]|[['quote'|['type']]]]]|[['=:='|[['tuple_size'|['t']]|[4]]]|[['=:='|[['element'|[2|['t']]]|[['quote'|['integers']]]]]]]]]|[['+'|[['element'|[3|['t']]]|[['element'|[4|['t']]]]]]|[['quote'|['true']]|[['quote'|['error']]]]]]]]]]})
+ let <_val> =
+ <case 1 of
+ <_2>
+ when try
+ let <_7> =
+ let <_6> =
+ case let <_3> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_3, 'type') of
+ <'true'> when 'true' ->
+ case let <_4> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_4, 4) of
+ <'true'> when 'true' ->
+ let <_5> =
+ call 'erlang':'element'
+ (2, _t)
+ in call 'erlang':'=:='
+ (_5, 'integers')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_6, 'true')
+ -| ['compiler_generated'] )
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_8> =
+ call 'erlang':'element'
+ (3, _t)
+ in let <_9> =
+ call 'erlang':'element'
+ (4, _t)
+ in call 'erlang':'+'
+ (_8, _9)
+ <_10>
+ when try
+ 'true'
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'error'
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end>
+ in case <_val> of
+ <65> when 'true' ->
+ _val
+ ( <_11> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_11}})
+ -| ['compiler_generated'] )
+ end
+ ( <_47> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_47})
+ -| [{'function_name',{'basic_andalso_orelse',1}}] )
+ -| ['compiler_generated'] )
+ end
+'basic-rt'/1 =
+ %% Line 1020
+ fun (_0) ->
+ case <_0> of
+ <_t>
+ when try
+ let <_5> =
+ let <_4> =
+ case call 'erlang':'is_tuple'
+ (_t) of
+ <'true'> when 'true' ->
+ case let <_1> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_1, 4) of
+ <'true'> when 'true' ->
+ case let <_2> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_2, 'type') of
+ <'true'> when 'true' ->
+ let <_3> =
+ call 'erlang':'element'
+ (2, _t)
+ in call 'erlang':'=='
+ (_3, 'integers')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_4, 'true')
+ -| ['compiler_generated'] )
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_6> =
+ call 'erlang':'element'
+ (3, _t)
+ in let <_7> =
+ call 'erlang':'element'
+ (4, _t)
+ in call 'erlang':'+'
+ (_6, _7)
+ <_t>
+ when try
+ let <_11> =
+ let <_10> =
+ case call 'erlang':'is_tuple'
+ (_t) of
+ <'true'> when 'true' ->
+ case let <_8> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_8, 2) of
+ <'true'> when 'true' ->
+ let <_9> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_9, 'vector')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_10, 'true')
+ -| ['compiler_generated'] )
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <call 'erlang':'element'
+ (2, _t)> of
+ <{_x,_y}> when 'true' ->
+ case 1 of
+ <_12>
+ when try
+ let <_16> =
+ let <_15> =
+ let <_13> =
+ call 'erlang':'is_float'
+ (_x)
+ in let <_14> =
+ call 'erlang':'is_float'
+ (_y)
+ in call 'erlang':'and'
+ (_13, _14)
+ in ( call 'erlang':'=:='
+ (_15, 'true')
+ -| ['compiler_generated'] )
+ in _16
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_19> =
+ let <_17> =
+ call 'erlang':'*'
+ (_x, _x)
+ in let <_18> =
+ call 'erlang':'*'
+ (_y, _y)
+ in call 'erlang':'+'
+ (_17, _18)
+ in call 'math':'sqrt'
+ (_19)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+ ( <_20> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_20}})
+ -| ['compiler_generated'] )
+ end
+ <['+',_a,_b]> when 'true' ->
+ let <_22> =
+ let <_21> =
+ call 'erlang':'+'
+ (_a, _b)
+ in apply 'id'/1
+ (_21)
+ in call 'erlang':'*'
+ (_22, 2)
+ <{_r1,_r2}>
+ when try
+ let <_28> =
+ let <_27> =
+ case let <_23> =
+ call 'erlang':'size'
+ (_r1)
+ in call 'erlang':'=:='
+ (_23, 3) of
+ <'true'> when 'true' ->
+ case let <_24> =
+ call 'erlang':'element'
+ (1, _r1)
+ in call 'erlang':'=:='
+ (_24, 'Set') of
+ <'true'> when 'true' ->
+ case let <_25> =
+ call 'erlang':'size'
+ (_r2)
+ in call 'erlang':'=:='
+ (_25, 3) of
+ <'true'> when 'true' ->
+ let <_26> =
+ call 'erlang':'element'
+ (1, _r2)
+ in call 'erlang':'=:='
+ (_26, 'Set')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_27, 'true')
+ -| ['compiler_generated'] )
+ in _28
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_r1> =
+ <apply 'id'/1
+ (_r1)>
+ in let <_r2> =
+ <apply 'id'/1
+ (_r2)>
+ in _r1
+ <_t>
+ when try
+ let <_32> =
+ let <_31> =
+ case call 'erlang':'is_tuple'
+ (_t) of
+ <'true'> when 'true' ->
+ case let <_29> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_29, 2) of
+ <'true'> when 'true' ->
+ let <_30> =
+ call 'erlang':'element'
+ (1, _t)
+ in call 'erlang':'=:='
+ (_30, 'klurf')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_31, 'true')
+ -| ['compiler_generated'] )
+ in _32
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_34> =
+ let <_33> =
+ call 'erlang':'element'
+ (2, _t)
+ in apply 'id'/1
+ (_33)
+ in call 'erlang':'*'
+ (3, _34)
+ <_35> when 'true' ->
+ 'error'
+ ( <_36> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_36})
+ -| [{'function_name',{'basic-rt',1}}] )
+ -| ['compiler_generated'] )
+ end
+'traverse_dcd'/1 =
+ %% Line 1043
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_l0> =
+ <[{'log_header','dcd_log',[49|[46|[48]]],'a','b','c'}|[{'log_header','dcd_log',[50|[46|[48]]],'a','b','c'}|[{'log_header','dcd_log',[48|[46|[48]]],'a','b','c'}|['blurf']]]]>
+ in case <apply 'traverse-dcd'/3
+ ({'cont',_l0}, 'log', 'funny')> of
+ <{'cont',[{'log_header','dcd_log',[48|[46|[48]]],'a','b','c'}|['blurf']],'log','funny'}> when 'true' ->
+ let <_l1> =
+ <[{'log_header','dcd_log',[49|[46|[48]]]}]>
+ in case <apply 'traverse-dcd'/3
+ ({'cont',_l1}, 'log', 'funny')> of
+ <{'cont',_l1,'log','funny'}> when 'true' ->
+ let <_l2> =
+ <[{'a','tuple'}]>
+ in case <apply 'traverse-dcd'/3
+ ({'cont',_l2}, 'log', 'funny')> of
+ <{'cont',_l2,'log','funny'}> when 'true' ->
+ 'ok'
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_3> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_3}})
+ -| ['compiler_generated'] )
+ end
+ ( <_4> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_4}})
+ -| ['compiler_generated'] )
+ end
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'traverse_dcd',1}}] )
+ -| ['compiler_generated'] )
+ end
+'traverse-dcd'/3 =
+ %% Line 1066
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <{_cont,[_logh|_rest]},_log,_fun>
+ when try
+ let <_11> =
+ let <_6> =
+ case call 'erlang':'is_tuple'
+ (_logh) of
+ <'true'> when 'true' ->
+ case let <_3> =
+ call 'erlang':'tuple_size'
+ (_logh)
+ in call 'erlang':'=:='
+ (_3, 6) of
+ <'true'> when 'true' ->
+ case let <_4> =
+ call 'erlang':'element'
+ (1, _logh)
+ in call 'erlang':'=:='
+ (_4, 'log_header') of
+ <'true'> when 'true' ->
+ let <_5> =
+ call 'erlang':'element'
+ (2, _logh)
+ in call 'erlang':'=='
+ (_5, 'dcd_log')
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_6, 'true')
+ -| ['compiler_generated'] )
+ in let <_12> =
+ let <_10> =
+ case call 'erlang':'is_tuple'
+ (_logh) of
+ <'true'> when 'true' ->
+ case let <_7> =
+ call 'erlang':'tuple_size'
+ (_logh)
+ in call 'erlang':'=:='
+ (_7, 6) of
+ <'true'> when 'true' ->
+ case let <_8> =
+ call 'erlang':'element'
+ (1, _logh)
+ in call 'erlang':'=:='
+ (_8, 'log_header') of
+ <'true'> when 'true' ->
+ let <_9> =
+ call 'erlang':'element'
+ (3, _logh)
+ in call 'erlang':'>='
+ (_9, [49|[46|[48]]])
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in ( call 'erlang':'=:='
+ (_10, 'true')
+ -| ['compiler_generated'] )
+ in call 'erlang':'and'
+ (_11, _12)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ apply 'traverse-dcd'/3
+ ({_cont,_rest}, _log, _fun)
+ <{_cont,_recs},_log,_fun> when 'true' ->
+ {_cont,_recs,_log,_fun}
+ ( <_15,_14,_13> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_15,_14,_13})
+ -| [{'function_name',{'traverse-dcd',3}}] )
+ -| ['compiler_generated'] )
+ end
+'check_qlc_hrl'/1 =
+ %% Line 1078
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ let <_st> =
+ <{'r1','false','dum'}>
+ in do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['foo']]|[['cqlc'|[['quote'|['qlc']]|[['quote'|['q']]|[['quote'|[[{'lc',1,2,3}]]]|['st']]]]]]]]})
+ let <_val> =
+ <apply 'cqlc'/4
+ ('qlc', 'q', [{'lc',1,2,3}], _st)>
+ in case <_val> of
+ <'foo'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'check_qlc_hrl',1}}] )
+ -| ['compiler_generated'] )
+ end
+'cqlc'/4 =
+ %% Line 1094
+ fun (_m,_f,_as,_st) ->
+ let <_arity> =
+ <call 'erlang':'length'
+ (_as)>
+ in case _as of
+ <[{'lc',_0,_1,_2}|_3]>
+ when try
+ let <_11> =
+ call 'erlang':'=:='
+ (_m, 'qlc')
+ in let <_12> =
+ call 'erlang':'=:='
+ (_f, 'q')
+ in let <_13> =
+ call 'erlang':'<'
+ (_arity, 3)
+ in let <_14> =
+ let <_10> =
+ let <_8> =
+ case let <_4> =
+ call 'erlang':'element'
+ (1, _st)
+ in call 'erlang':'=:='
+ (_4, 'r1') of
+ <'true'> when 'true' ->
+ 'true'
+ <'false'> when 'true' ->
+ 'fail'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in let <_9> =
+ let <_6> =
+ let <_5> =
+ call 'erlang':'tuple_size'
+ (_st)
+ in call 'erlang':'=:='
+ (_5, 3)
+ in let <_7> =
+ call 'erlang':'element'
+ (2, _st)
+ in call 'erlang':'and'
+ (_6, _7)
+ in call 'erlang':'and'
+ (_8, _9)
+ in call 'erlang':'not'
+ (_10)
+ in let <_15> =
+ call 'erlang':'and'
+ (_11, _12)
+ in let <_16> =
+ call 'erlang':'and'
+ (_15, _13)
+ in call 'erlang':'and'
+ (_16, _14)
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'foo'
+ <_17> when 'true' ->
+ _st
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'andalso_semi'/1 =
+ %% Line 1106
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[['quote'|['ok']]|[['andalso-semi-foo'|[0]]]]]})
+ let <_val> =
+ <apply 'andalso-semi-foo'/1
+ (0)>
+ in case <_val> of
+ <'ok'> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_8> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_8})
+ -| [{'function_name',{'andalso_semi',1}}] )
+ -| ['compiler_generated'] )
+ end
+'andalso-semi-foo'/1 =
+ %% Line 1117
+ fun (_0) ->
+ case <_0> of
+ <_bar>
+ when try
+ let <_3> =
+ let <_1> =
+ case call 'erlang':'is_integer'
+ (_bar) of
+ <'true'> when 'true' ->
+ call 'erlang':'=:='
+ (_bar, 0)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in let <_2> =
+ call 'erlang':'=:='
+ (_bar, 1)
+ in call 'erlang':'or'
+ (_1, _2)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_4> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_4})
+ -| [{'function_name',{'andalso-semi-foo',1}}] )
+ -| ['compiler_generated'] )
+ end
+'andalso-semi-bar'/1 =
+ %% Line 1121
+ fun (_0) ->
+ case <_0> of
+ <_bar>
+ when try
+ let <_4> =
+ let <_2> =
+ case call 'erlang':'is_list'
+ (_bar) of
+ <'true'> when 'true' ->
+ let <_1> =
+ call 'erlang':'length'
+ (_bar)
+ in call 'erlang':'=:='
+ (_1, 3)
+ <'false'> when 'true' ->
+ 'false'
+ ( <_omega> when 'true' ->
+ _omega
+ -| ['compiler_generated'] )
+ end
+ in let <_3> =
+ call 'erlang':'=:='
+ (_bar, 1)
+ in call 'erlang':'or'
+ (_2, _3)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ ( <_5> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_5})
+ -| [{'function_name',{'andalso-semi-bar',1}}] )
+ -| ['compiler_generated'] )
+ end
+'t_tuple_size'/1 =
+ %% Line 1125
+ fun (_0) ->
+ case <_0> of
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat'|[10|[['do-tuple-size'|[{1,2,3,4}]]]]]})
+ let <_val> =
+ <apply 'do-tuple-size'/1
+ ({1,2,3,4})>
+ in case <_val> of
+ <10> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_7> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_7})
+ -| [{'function_name',{'t_tuple_size',1}}] )
+ -| ['compiler_generated'] )
+ end
+'do-tuple-size'/1 =
+ %% Line 1139
+ fun (_0) ->
+ case <_0> of
+ <_t>
+ when try
+ let <_2> =
+ let <_1> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_1, 4)
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ case <_t> of
+ <{_a,_b,_c,_d}> when 'true' ->
+ let <_lfe0> =
+ <_a>
+ in let <_lfe1> =
+ <_b>
+ in let <_lfe2> =
+ <_c>
+ in let <_lfe3> =
+ <_d>
+ in let <_4> =
+ let <_3> =
+ call 'erlang':'+'
+ (_lfe0, _lfe1)
+ in call 'erlang':'+'
+ (_3, _lfe2)
+ in call 'erlang':'+'
+ (_4, _lfe3)
+ ( <_5> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_5}})
+ -| ['compiler_generated'] )
+ end
+ ( <_6> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_6})
+ -| [{'function_name',{'do-tuple-size',1}}] )
+ -| ['compiler_generated'] )
+ end
+'ludicrous-tuple-size'/1 =
+ %% Line 1144
+ fun (_0) ->
+ case <_0> of
+ <_t>
+ when try
+ let <_2> =
+ let <_1> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_1, 40652400101488115101757819767848575661943)
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_t>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_3, 18446744073709551616)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_t>
+ when try
+ let <_8> =
+ let <_6> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in let <_7> =
+ let <_5> =
+ call 'erlang':'bsl'
+ (1, 64)
+ in call 'erlang':'-'
+ (_5, 1)
+ in call 'erlang':'=:='
+ (_6, _7)
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_t>
+ when try
+ let <_10> =
+ let <_9> =
+ call 'erlang':'tuple_size'
+ (_t)
+ in call 'erlang':'=:='
+ (_9, 18446744073709551615)
+ in _10
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_11> when 'true' ->
+ 'error'
+ ( <_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_12})
+ -| [{'function_name',{'ludicrous-tuple-size',1}}] )
+ -| ['compiler_generated'] )
+ end
+'mask-error'/1 =
+ %% Line 1152
+ fun (_0) ->
+ case <_0> of
+ <{'EXIT',{_err,_1}}> when 'true' ->
+ _err
+ <_else> when 'true' ->
+ _else
+ ( <_2> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_2})
+ -| [{'function_name',{'mask-error',1}}] )
+ -| ['compiler_generated'] )
+ end
+'binary_part'/1 =
+ %% Line 1156
+ fun (_0) ->
+ case <_0> of
+ <'doc'> when 'true' ->
+ [84|[101|[115|[116|[115|[32|[116|[104|[101|[32|[98|[105|[110|[97|[114|[121|[95|[112|[97|[114|[116|[47|[50|[44|[51|[32|[103|[117|[97|[114|[100|[32|[40|[71|[67|[41|[32|[98|[105|[102|[39|[115]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
+ <_config>
+ when try
+ let <_1> =
+ call 'erlang':'is_list'
+ (_config)
+ in _1
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ do call 'erlang':'put'
+ ('test_server_loc', {'lfe_guard_SUITE',['test-pat',1,['bp-test',#{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<2>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#]]})
+ let <_val> =
+ <apply 'bp-test'/1
+ (#{#<1>(8,1,'integer',['unsigned'|['big']]),
+ #<2>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)>
+ in case <_val> of
+ <1> when 'true' ->
+ _val
+ ( <_2> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',{_2}})
+ -| ['compiler_generated'] )
+ end
+ ( <_53> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_53})
+ -| [{'function_name',{'binary_part',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test'/1 =
+ %% Line 1225
+ fun (_0) ->
+ case <_0> of
+ <_b>
+ when try
+ let <_2> =
+ let <_1> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_1, 137)
+ in _2
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b>
+ when try
+ let <_4> =
+ let <_3> =
+ call 'erlang':'binary_part'
+ (_b, {1,1})
+ in call 'erlang':'=:='
+ (_3, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _4
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b>
+ when try
+ let <_6> =
+ let <_5> =
+ call 'erlang':'binary_part'
+ (_b, 1, 1)
+ in call 'erlang':'=:='
+ (_5, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _6
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b>
+ when try
+ let <_8> =
+ let <_7> =
+ call 'erlang':'binary_part'
+ (_b, {1,2})
+ in call 'erlang':'=:='
+ (_7, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _8
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_9> when 'true' ->
+ 'error'
+ ( <_10> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_10})
+ -| [{'function_name',{'bp-test',1}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test'/2 =
+ %% Line 1232
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_b,_a>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_2, _a)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'binary_part'
+ (_b, {_a,1})
+ in call 'erlang':'=:='
+ (_4, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, _a, 1)
+ in call 'erlang':'=:='
+ (_6, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, {_a,2})
+ in call 'erlang':'=:='
+ (_8, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_10,_11> when 'true' ->
+ 'error'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'bp-test',2}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test-x'/2 =
+ %% Line 1239
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_b,_a>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_2, _a)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'binary_part'
+ (_b, _a)
+ in call 'erlang':'=:='
+ (_4, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, _a)
+ in call 'erlang':'=:='
+ (_6, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, _a)
+ in call 'erlang':'=:='
+ (_8, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_10,_11> when 'true' ->
+ 'error'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'bp-test-x',2}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test-y'/2 =
+ %% Line 1246
+ fun (_1,_0) ->
+ case <_1,_0> of
+ <_b,_a>
+ when try
+ let <_3> =
+ let <_2> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_2, _a)
+ in _3
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'binary_part'
+ (_b, {1,_a})
+ in call 'erlang':'=:='
+ (_4, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, 1, _a)
+ in call 'erlang':'=:='
+ (_6, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, {1,_a})
+ in call 'erlang':'=:='
+ (_8, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_10,_11> when 'true' ->
+ 'error'
+ ( <_13,_12> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_13,_12})
+ -| [{'function_name',{'bp-test-y',2}}] )
+ -| ['compiler_generated'] )
+ end
+'bp-test'/3 =
+ %% Line 1253
+ fun (_2,_1,_0) ->
+ case <_2,_1,_0> of
+ <_b,_a,_3>
+ when try
+ let <_5> =
+ let <_4> =
+ call 'erlang':'length'
+ (_b)
+ in call 'erlang':'=:='
+ (_4, _a)
+ in _5
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a,_c>
+ when try
+ let <_7> =
+ let <_6> =
+ call 'erlang':'binary_part'
+ (_b, {_a,_c})
+ in call 'erlang':'=:='
+ (_6, #{#<2>(8,1,'integer',['unsigned'|['big']])}#)
+ in _7
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 1
+ <_b,_a,_c>
+ when try
+ let <_9> =
+ let <_8> =
+ call 'erlang':'binary_part'
+ (_b, _a, _c)
+ in call 'erlang':'=:='
+ (_8, #{#<1>(8,1,'integer',['unsigned'|['big']])}#)
+ in _9
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 2
+ <_b,_a,_c>
+ when try
+ let <_11> =
+ let <_10> =
+ call 'erlang':'binary_part'
+ (_b, {_a,_c})
+ in call 'erlang':'=:='
+ (_10, #{#<3>(8,1,'integer',['unsigned'|['big']]),
+ #<3>(8,1,'integer',['unsigned'|['big']])}#)
+ in _11
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 3
+ <_12,_13,_14> when 'true' ->
+ 'error'
+ ( <_17,_16,_15> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_17,_16,_15})
+ -| [{'function_name',{'bp-test',3}}] )
+ -| ['compiler_generated'] )
+ end
+'id'/1 =
+ %% Line 1262
+ fun (_i) ->
+ _i
+'check'/2 =
+ %% Line 1264
+ fun (_f,_result) ->
+ case apply _f
+ () of
+ <_r>
+ when try
+ let <_0> =
+ call 'erlang':'=:='
+ (_r, _result)
+ in _0
+ of <Try> ->
+ Try
+ catch <T,R> ->
+ 'false' ->
+ 'ok'
+ <_other> when 'true' ->
+ do call 'lfe_io':'format'
+ ([69|[120|[112|[101|[99|[116|[101|[100|[58|[32|[126|[112|[10]]]]]]]]]]]]], [_result])
+ do call 'lfe_io':'format'
+ ([32|[32|[32|[32|[32|[71|[111|[116|[58|[32|[126|[112|[10]]]]]]]]]]]]], [_other])
+ call 'test_server':'fail'
+ ()
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'fc'/1 =
+ %% Line 1272
+ fun (_0) ->
+ case <_0> of
+ <{'EXIT',{'function_clause'}}> when 'true' ->
+ 'ok'
+ <{'EXIT',{{'case_clause',_1},_2}}> when 'true' ->
+ 'ok'
+ ( <_3> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause',_3})
+ -| [{'function_name',{'fc',1}}] )
+ -| ['compiler_generated'] )
+ end
+'$handle_undefined_function'/2 =
+ %% Line 29
+ fun (_f,_as) ->
+ case let <_0> =
+ call 'lfe_env':'new'
+ ()
+ in apply 'LFE-EXPAND-EXPORTED-MACRO'/3
+ (_f, _as, _0) of
+ <{'yes',_exp}> when 'true' ->
+ call 'lfe_eval':'expr'
+ (_exp)
+ <'no'> when 'true' ->
+ let <_a,_b> =
+ <_f,_as>
+ in call 'error_handler':'raise_undef_exception'
+ ('lfe_guard_SUITE', _a, _b)
+ ( <_omega> when 'true' ->
+ primop 'match_fail'
+ ({'case_clause',_omega})
+ -| ['compiler_generated'] )
+ end
+'LFE-EXPAND-EXPORTED-MACRO'/3 =
+ %% Line 29
+ fun (_2,_1,_0) ->
+ 'no'
+'module_info'/0 =
+ fun () ->
+ call 'erlang':'get_module_info'
+ ('lfe_guard_SUITE')
+'module_info'/1 =
+ fun (_x) ->
+ call 'erlang':'get_module_info'
+ ('lfe_guard_SUITE', _x)
+end
diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl
index f543f0d4de..621524114f 100644
--- a/lib/compiler/test/misc_SUITE.erl
+++ b/lib/compiler/test/misc_SUITE.erl
@@ -229,14 +229,6 @@ silly_coverage(Config) when is_list(Config) ->
{label,2}|non_proper_list]}],99},
expect_error(fun() -> beam_except:module(ExceptInput, []) end),
- %% beam_bool
- BoolInput = {?MODULE,[{foo,0}],[],
- [{function,foo,0,2,
- [{label,1},
- {func_info,{atom,?MODULE},{atom,foo},0},
- {label,2}|non_proper_list]}],99},
- expect_error(fun() -> beam_bool:module(BoolInput, []) end),
-
%% beam_dead. This is tricky. Our function must look OK to
%% beam_utils:clean_labels/1, but must crash beam_dead.
DeadInput = {?MODULE,[{foo,0}],[],
diff --git a/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl b/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl
index 9b72432246..dbd2419ad2 100644
--- a/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl
+++ b/lib/compiler/test/record_SUITE_data/record_access_in_guards.erl
@@ -27,12 +27,12 @@
-record(r3, {a = fun(_) -> #r1{} end(1), b}).
t() ->
- foo = fun(A) when A#r1.a > A#r1.b -> foo end(#r1{b = 2}),
- 0 = fun(A) when A#r2.a -> 0 end(#r2{a = true}),
+ foo = rec_call(fun(A) when A#r1.a > A#r1.b -> foo end, #r1{b = 2}),
+ 0 = rec_call(fun(A) when A#r2.a -> 0 end, #r2{a = true}),
1 = fun(A) when (#r1{a = A})#r1.a > 2 -> 1 end(3),
2 = fun(N) when ((#r2{a = #r{a = 4}, b = length([a,b,c])})#r2.a)#r.a > N ->
- 2 end(2),
- 3 = fun(A) when (A#r2.a)#r1.a =:= 3 -> 3 end(#r2{a = #r1{a = 3}}),
+ 2 end(2),
+ 3 = rec_call(fun(A) when (A#r2.a)#r1.a =:= 3 -> 3 end, #r2{a = #r1{a = 3}}),
ok = fun() ->
F = fun(A) when record(A#r.a, r1) -> 4;
(A) when record(A#r1.a, r1) -> 5
@@ -41,9 +41,9 @@ t() ->
4 = F(#r{a = #r1{}}),
ok
end(),
- 3 = fun(A) when record(A#r1.a, r),
- (A#r1.a)#r.a > 3 -> 3
- end(#r1{a = #r{a = 4}}),
+ 3 = rec_call(fun(A) when record(A#r1.a, r),
+ (A#r1.a)#r.a > 3 -> 3
+ end, #r1{a = #r{a = 4}}),
7 = fun(A) when record(A#r3.a, r1) -> 7 end(#r3{}),
[#r1{a = 2,b = 1}] =
fun() ->
@@ -71,9 +71,10 @@ t() ->
(_) -> p
end(#r1{a = 2}),
- 3 = fun(A) when A#r1.a > 3,
- record(A, r1) -> 3
- end(#r1{a = 5}),
+ o = rec_call(fun(A) when (A#r1.a =:= 2) orelse (A#r2.a =:= 1) -> o end, #r1{a = 2}),
+ o = rec_call(fun(A) when A#r1.a =:= 2; A#r2.a =:= 1 -> o end, #r2{a = 1}),
+
+ 3 = rec_call(fun(A) when A#r1.a > 3, record(A, r1) -> 3 end, #r1{a = 5}),
ok = fun() ->
F = fun(A) when (A#r2.a =:= 1) orelse (A#r2.a) -> 2;
@@ -93,6 +94,8 @@ t() ->
(_) -> b
end(#r1{a = 1}),
+ a = rec_call(fun(A) when not (A#r.a =:= 1) or false -> a end, #r{a = 42}),
+
ok = fun() ->
F = fun(A) when not (A#r.a =:= 1) -> yes;
(_) -> no
@@ -103,14 +106,14 @@ t() ->
ok
end(),
- a = fun(A) when record(A, r),
- A#r.a =:= 1,
- A#r.b =:= 2 ->a
- end(#r{a = 1, b = 2}),
- a = fun(A) when erlang:is_record(A, r),
- A#r.a =:= 1,
- A#r.b =:= 2 -> a
- end(#r{a = 1, b = 2}),
+ a = rec_call(fun(A) when record(A, r),
+ A#r.a =:= 1,
+ A#r.b =:= 2 -> a
+ end, #r{a = 1, b = 2}),
+ a = rec_call(fun(A) when erlang:is_record(A, r),
+ A#r.a =:= 1,
+ A#r.b =:= 2 -> a
+ end, #r{a = 1, b = 2}),
a = fun(A) when is_record(A, r),
A#r.a =:= 1,
A#r.b =:= 2 -> a
@@ -144,8 +147,7 @@ t() ->
ok
end(),
- both = fun(A) when A#r.a, A#r.b -> both
- end(#r{a = true, b = true}),
+ both = rec_call(fun(A) when A#r.a, A#r.b -> both end, #r{a = true, b = true}),
ok = fun() ->
F = fun(A, B) when ((A#r1.a) orelse (B#r2.a))
@@ -176,3 +178,24 @@ t() ->
ok.
+rec_call(F, Rec) ->
+ Corrupted1 = setelement(1, Rec, wrong),
+ Corrupted2 = erlang:append_element(Rec, extra),
+ Corrupted3 = erlang:append_element(Corrupted1, extra),
+ fc(F, Corrupted1),
+ fc(F, Corrupted2),
+ fc(F, Corrupted3),
+ F(Rec).
+
+fc(F, Term) ->
+ try
+ F(Term),
+ error(expected_to_fail)
+ catch
+ error:function_clause ->
+ ok;
+ error:{case_clause,_} ->
+ Comp = ?MODULE:module_info(compile),
+ {_,Opts} = lists:keyfind(options, 1, Comp),
+ true = lists:member(inline, Opts)
+ end.
diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl
index f884e6e7d6..7c27750556 100644
--- a/lib/compiler/test/warnings_SUITE.erl
+++ b/lib/compiler/test/warnings_SUITE.erl
@@ -42,7 +42,7 @@
comprehensions/1,maps/1,maps_bin_opt_info/1,
redundant_boolean_clauses/1,
latin1_fallback/1,underscore/1,no_warnings/1,
- bit_syntax/1]).
+ bit_syntax/1,inlining/1]).
init_per_testcase(_Case, Config) ->
Config.
@@ -65,7 +65,7 @@ groups() ->
bin_opt_info,bin_construction,comprehensions,maps,
maps_bin_opt_info,
redundant_boolean_clauses,latin1_fallback,
- underscore,no_warnings,bit_syntax]}].
+ underscore,no_warnings,bit_syntax,inlining]}].
init_per_suite(Config) ->
Config.
@@ -281,7 +281,6 @@ bad_arith(Config) when is_list(Config) ->
{3,sys_core_fold,{eval_failure,badarith}},
{9,sys_core_fold,nomatch_guard},
{9,sys_core_fold,{eval_failure,badarith}},
- {9,sys_core_fold,{no_effect,{erlang,is_integer,1}}},
{10,sys_core_fold,nomatch_guard},
{10,sys_core_fold,{eval_failure,badarith}},
{15,sys_core_fold,{eval_failure,badarith}}
@@ -629,7 +628,112 @@ maps(Config) when is_list(Config) ->
id(I) -> I.
">>,
[],
- []}],
+ []},
+ {repeated_keys1,
+ <<"
+ foo1() ->
+ #{a=>1,
+ b=> 2,
+ a=>3}.
+
+ bar1(M) ->
+ M#{a=>1, b=> 2, a:=3}.
+
+ baz1(M) ->
+ M#{a=>1, b=> 2, a:=3}.
+
+ foo2() ->
+ #{\"a\"=>1, \"b\"=> 2, \"a\"=>3}.
+
+ bar2(M) ->
+ M#{\"a\"=>1, \"b\"=> 2, \"a\":=3}.
+
+ baz2(M) ->
+ M#{\"a\"=>1, \"b\"=> 2, \"a\":=3}.
+
+ foo3() ->
+ #{\"a\"=>1,
+ \"b\"=> 2,
+ \"a\"=>3}.
+
+ bar3(M) ->
+ M#{\"a\"=>1, \"b\"=> 2, \"a\":=3}.
+
+ baz3(M) ->
+ M#{<<\"a\">>=>1, <<\"b\">>=> 2, <<\"a\">>:=3}.
+ ">>,
+ [],
+ {warnings,[{3,v3_core,{map_key_repeated,a}},
+ {8,v3_core,{map_key_repeated,a}},
+ {11,v3_core,{map_key_repeated,a}},
+ {14,v3_core,{map_key_repeated,"a"}},
+ {17,v3_core,{map_key_repeated,"a"}},
+ {20,v3_core,{map_key_repeated,"a"}},
+ {23,v3_core,{map_key_repeated,"a"}},
+ {28,v3_core,{map_key_repeated,"a"}},
+ {31,v3_core,{map_key_repeated,<<"a">>}}]}},
+ {repeated_keys2,
+ <<"
+ foo4(K) ->
+ #{\"a\"=>1, K => 1, \"b\"=> 2, \"a\"=>3, K=>2}.
+
+ bar4(M,K) ->
+ M#{a=>1, K =>1, b=> 2, a:=3, K=>2}.
+
+ baz4(M,K) ->
+ M#{<<\"a\">>=>1,
+ K => 1, <<\"b\">>=> 2,
+ <<\"a\">>:=3, K=>2}.
+
+ foo5(K) ->
+ #{{\"a\",1}=>1, K => 1, \"b\"=> 2, {\"a\",1}=>3, K=>2}.
+
+ bar5(M,K) ->
+ M#{{\"a\",<<\"b\">>}=>1, K =>1,
+ \"b\"=> 2, {\"a\",<<\"b\">>}:=3, K=>2}.
+
+ baz5(M,K) ->
+ M#{{<<\"a\">>,1}=>1, K => 1,
+ <<\"b\">>=> 2, {<<\"a\">>,1}:=3,K=>2}.
+
+ foo6(K) ->
+ #{#{\"a\"=>1}=>1, K => 1, \"b\"=> 2, #{\"a\"=>1}=>3, K=>2}.
+
+ bar6(M,K) ->
+ M#{#{\"a\"=><<\"b\">>}=>1, K =>1,
+ \"b\"=> 2, #{\"a\"=><<\"b\">>}:=3, K=>2}.
+
+ baz6(M,K) ->
+ M#{#{<<\"a\">>=>1}=>1,
+ K => 1,
+ <<\"b\">>=> 2,
+ #{<<\"a\">>=>1}:=3,K=>2}.
+
+ foo7(K) ->
+ M1 = #{#{\"a\"=>1}=>1, K => 1, \"b\"=> 2},
+ M1#{#{\"a\"=>1}=>3, K=>2}.
+
+ bar7(M,K) ->
+ M1 = M#{#{\"a\"=><<\"b\">>}=>1, K =>1, \"b\"=> 2},
+ M1#{#{\"a\"=><<\"b\">>}:=3, K=>2}.
+
+ baz7(M,K) ->
+ M1 = M#{#{<<\"a\">>=>1}=>1,
+ K => 1,
+ <<\"b\">>=> 2},
+ M1#{#{<<\"a\">>=>1}:=3,K=>2}.
+ ">>,
+ [],
+ {warnings,[{3,v3_core,{map_key_repeated,"a"}},
+ {6,v3_core,{map_key_repeated,a}},
+ {9,v3_core,{map_key_repeated,<<"a">>}},
+ {14,v3_core,{map_key_repeated,{"a",1}}},
+ {17,v3_core,{map_key_repeated,{"a",<<"b">>}}},
+ {21,v3_core,{map_key_repeated,{<<"a">>,1}}},
+ {25,v3_core,{map_key_repeated,#{"a" => 1}}},
+ {28,v3_core,{map_key_repeated,#{"a" => <<"b">>}}},
+ {32,v3_core,{map_key_repeated,#{<<"a">> => 1}}}]}}
+ ],
run(Config, Ts),
ok.
@@ -823,6 +927,30 @@ bit_syntax(Config) ->
run(Config, Ts),
ok.
+inlining(Config) ->
+ %% Make sure that no spurious warnings are generated
+ %% when inlining.
+ Ts = [{inlining_1,
+ <<"-compile(inline).
+ compute1(X) -> add(X, 0).
+ add(1, 0) -> 1;
+ add(1, Y) -> 1 + Y;
+ add(X, Y) -> X + Y.
+ ">>,
+ [],
+ []},
+ {inlining_2,
+ <<"-compile({inline,[add/2]}).
+ compute1(X) -> add(X, 0).
+ add(1, 0) -> 1;
+ add(1, Y) -> 1 + Y;
+ add(X, Y) -> X + Y.
+ ">>,
+ [],
+ []}
+ ],
+ run(Config, Ts),
+ ok.
%%%
%%% End of test cases.
diff --git a/lib/cosProperty/doc/src/notes.xml b/lib/cosProperty/doc/src/notes.xml
index d5219fc110..e5d22982c5 100644
--- a/lib/cosProperty/doc/src/notes.xml
+++ b/lib/cosProperty/doc/src/notes.xml
@@ -32,6 +32,22 @@
<file>notes.xml</file>
</header>
+
+ <section><title>cosProperty 1.2.2</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Fix dialyzer warnings.</p>
+ <p>
+ Own Id: OTP-14006</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
+
<section><title>cosProperty 1.2.1</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
index bf046530d8..371e72cf72 100644
--- a/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
+++ b/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
@@ -913,8 +913,6 @@ mnesia_read(State) ->
case mnesia:wread({oe_CosPropertyService, ?get_DBKey(State)}) of
[#oe_CosPropertyService{properties = X}] ->
X;
- {atomic, []} ->
- {'EXCEPTION', #'OBJECT_NOT_EXIST'{completion_status=?COMPLETED_NO}};
_Other ->
{'EXCEPTION', #'INTERNAL'{completion_status=?COMPLETED_NO}}
end.
diff --git a/lib/cosProperty/vsn.mk b/lib/cosProperty/vsn.mk
index 1a8e42ffdb..78ba88445d 100644
--- a/lib/cosProperty/vsn.mk
+++ b/lib/cosProperty/vsn.mk
@@ -1,2 +1,2 @@
-COSPROPERTY_VSN = 1.2.1
+COSPROPERTY_VSN = 1.2.2
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index c835f6dcf4..86b839eddb 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -241,18 +241,14 @@ static ERL_NIF_TERM cmac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
static ERL_NIF_TERM block_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_cfb_8_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_ige_crypt_nif(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 aes_ctr_stream_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_ctr_stream_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 strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM strong_rand_mpint_nif(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[]);
static ERL_NIF_TERM mod_exp_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM dss_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM do_exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-static ERL_NIF_TERM rc4_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rc4_set_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rc4_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
@@ -314,21 +310,15 @@ static ErlNifFunc nif_funcs[] = {
{"block_crypt_nif", 5, block_crypt_nif},
{"block_crypt_nif", 4, block_crypt_nif},
{"aes_ige_crypt_nif", 4, aes_ige_crypt_nif},
-
- {"aes_ctr_encrypt", 3, aes_ctr_encrypt},
- {"aes_ctr_decrypt", 3, aes_ctr_encrypt},
{"aes_ctr_stream_init", 2, aes_ctr_stream_init},
{"aes_ctr_stream_encrypt", 2, aes_ctr_stream_encrypt},
{"aes_ctr_stream_decrypt", 2, aes_ctr_stream_encrypt},
- {"rand_bytes", 1, rand_bytes_1},
{"strong_rand_bytes_nif", 1, strong_rand_bytes_nif},
- {"strong_rand_mpint_nif", 3, strong_rand_mpint_nif},
{"rand_uniform_nif", 2, rand_uniform_nif},
{"mod_exp_nif", 4, mod_exp_nif},
{"dss_verify_nif", 4, dss_verify_nif},
{"rsa_verify_nif", 4, rsa_verify_nif},
{"do_exor", 2, do_exor},
- {"rc4_encrypt", 2, rc4_encrypt},
{"rc4_set_key", 1, rc4_set_key},
{"rc4_encrypt_with_state", 2, rc4_encrypt_with_state},
{"rsa_sign_nif", 3, rsa_sign_nif},
@@ -355,8 +345,6 @@ static ErlNifFunc nif_funcs[] = {
{"chacha20_poly1305_encrypt", 4, chacha20_poly1305_encrypt},
{"chacha20_poly1305_decrypt", 5, chacha20_poly1305_decrypt}
-
-
};
ERL_NIF_INIT(crypto,nif_funcs,load,NULL,upgrade,unload)
@@ -1673,64 +1661,6 @@ static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TE
#endif
}
-/* 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;
-#ifdef HAVE_EVP_AES_CTR
- const EVP_CIPHER *cipher;
- EVP_CIPHER_CTX ctx;
- unsigned char *out;
- int outl = 0;
-#else
- AES_KEY aes_key;
- unsigned char ivec_clone[16]; /* writable copy */
- unsigned char ecount_buf[AES_BLOCK_SIZE];
- unsigned int num = 0;
-#endif
- ERL_NIF_TERM ret;
-
- if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
-#ifndef HAVE_EVP_AES_CTR
- || AES_set_encrypt_key(key.data, key.size*8, &aes_key) != 0
-#endif
- || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16
- || !enif_inspect_iolist_as_binary(env, argv[2], &text)) {
- return enif_make_badarg(env);
- }
-#ifdef HAVE_EVP_AES_CTR
- switch (key.size)
- {
- case 16: cipher = EVP_aes_128_ctr(); break;
- case 24: cipher = EVP_aes_192_ctr(); break;
- case 32: cipher = EVP_aes_256_ctr(); break;
- default: return enif_make_badarg(env);
- }
-
- out = enif_make_new_binary(env,text.size,&ret);
- EVP_CIPHER_CTX_init(&ctx);
- EVP_CipherInit_ex(&ctx, cipher, NULL,
- key.data, ivec.data, (argv[3] == atom_true));
- EVP_CIPHER_CTX_set_padding(&ctx, 0);
- EVP_CipherUpdate(&ctx, out, &outl, text.data, text.size);
- ASSERT(outl == text.size);
- EVP_CipherFinal_ex(&ctx, out + outl, &outl);
- ASSERT(outl == 0);
- EVP_CIPHER_CTX_cleanup(&ctx);
-#else
- 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);
-#endif
- CONSUME_REDS(env,text);
-
- /* To do an incremental {en|de}cryption, the state to to keep between calls
- must include ivec_clone, ecount_buf and num. */
- return ret;
-}
/* Initializes state for ctr streaming (de)encryption
*/
@@ -2151,20 +2081,6 @@ static ERL_NIF_TERM chacha20_poly1305_decrypt(ErlNifEnv* env, int argc, const ER
#endif
}
-static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Bytes) */
- unsigned bytes;
- unsigned char* data;
- ERL_NIF_TERM ret;
-
- if (!enif_get_uint(env, argv[0], &bytes)) {
- return enif_make_badarg(env);
- }
- data = enif_make_new_binary(env, bytes, &ret);
- RAND_pseudo_bytes(data, bytes);
- ERL_VALGRIND_MAKE_MEM_DEFINED(data, bytes);
- return ret;
-}
static ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Bytes) */
unsigned bytes;
@@ -2183,49 +2099,6 @@ static ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NI
}
-static ERL_NIF_TERM strong_rand_mpint_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Bytes, TopMask, BottomMask) */
- unsigned bits;
- BIGNUM *bn_rand;
- int top, bottom;
- unsigned char* data;
- unsigned dlen;
- ERL_NIF_TERM ret;
-
- if (!enif_get_uint(env, argv[0], &bits)
- || !enif_get_int(env, argv[1], &top)
- || !enif_get_int(env, argv[2], &bottom)) {
- return enif_make_badarg(env);
- }
- if (! (top == -1 || top == 0 || top == 1) ) {
- return enif_make_badarg(env);
- }
- if (! (bottom == 0 || bottom == 1) ) {
- return enif_make_badarg(env);
- }
-
- bn_rand = BN_new();
- if (! bn_rand ) {
- return enif_make_badarg(env);
- }
-
- /* Get a (bits) bit random number */
- if (!BN_rand(bn_rand, bits, top, bottom)) {
- ret = atom_false;
- }
- else {
- /* Copy the bignum into an erlang mpint binary. */
- dlen = BN_num_bytes(bn_rand);
- data = enif_make_new_binary(env, dlen+4, &ret);
- put_int32(data, dlen);
- BN_bn2bin(bn_rand, data+4);
- ERL_VALGRIND_MAKE_MEM_DEFINED(data+4, dlen);
- }
- BN_free(bn_rand);
-
- return ret;
-}
-
static int get_bn_from_mpint(ErlNifEnv* env, ERL_NIF_TERM term, BIGNUM** bnp)
{
ErlNifBinary bin;
@@ -2492,29 +2365,6 @@ static ERL_NIF_TERM do_exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
return ret;
}
-static ERL_NIF_TERM rc4_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (Key, Data) */
-#ifndef OPENSSL_NO_RC4
- ErlNifBinary key, data;
- RC4_KEY rc4_key;
- ERL_NIF_TERM ret;
-
- CHECK_NO_FIPS_MODE();
-
- if (!enif_inspect_iolist_as_binary(env,argv[0], &key)
- || !enif_inspect_iolist_as_binary(env,argv[1], &data)) {
- return enif_make_badarg(env);
- }
- RC4_set_key(&rc4_key, key.size, key.data);
- RC4(&rc4_key, data.size, data.data,
- enif_make_new_binary(env, data.size, &ret));
- CONSUME_REDS(env,data);
- return ret;
-#else
- return enif_raise_exception(env, atom_notsup);
-#endif
-}
-
static ERL_NIF_TERM rc4_set_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key) */
#ifndef OPENSSL_NO_RC4
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 43f9a0f9e7..0b62964efa 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -40,146 +40,10 @@
-export([ec_curve/1, ec_curves/0]).
-export([rand_seed/1]).
-%% DEPRECATED
--export([rand_bytes/1]).
--deprecated({rand_bytes, 1, next_major_release}).
-
-%% Replaced by hash_*
--export([md4/1, md4_init/0, md4_update/2, md4_final/1]).
--export([md5/1, md5_init/0, md5_update/2, md5_final/1]).
--export([sha/1, sha_init/0, sha_update/2, sha_final/1]).
--deprecated({md4, 1, next_major_release}).
--deprecated({md5, 1, next_major_release}).
--deprecated({sha, 1, next_major_release}).
--deprecated({md4_init, 0, next_major_release}).
--deprecated({md5_init, 0, next_major_release}).
--deprecated({sha_init, 0, next_major_release}).
--deprecated({md4_update, 2, next_major_release}).
--deprecated({md5_update, 2, next_major_release}).
--deprecated({sha_update, 2, next_major_release}).
--deprecated({md4_final, 1, next_major_release}).
--deprecated({md5_final, 1, next_major_release}).
--deprecated({sha_final, 1, next_major_release}).
-
-%% Replaced by hmac_*
--export([md5_mac/2, md5_mac_96/2, sha_mac/2, sha_mac/3, sha_mac_96/2]).
--deprecated({md5_mac, 2, next_major_release}).
--deprecated({md5_mac_96, 2, next_major_release}).
--deprecated({sha_mac, 2, next_major_release}).
--deprecated({sha_mac, 3, next_major_release}).
--deprecated({sha_mac_96, 2, next_major_release}).
-
-%% Replaced by sign/verify
--export([dss_verify/3, dss_verify/4, rsa_verify/3, rsa_verify/4]).
--export([dss_sign/2, dss_sign/3, rsa_sign/2, rsa_sign/3]).
--deprecated({dss_verify, 3, next_major_release}).
--deprecated({dss_verify, 4, next_major_release}).
--deprecated({rsa_verify, 3, next_major_release}).
--deprecated({rsa_verify, 4, next_major_release}).
--deprecated({dss_sign, 2, next_major_release}).
--deprecated({dss_sign, 3, next_major_release}).
--deprecated({rsa_sign, 2, next_major_release}).
--deprecated({rsa_sign, 3, next_major_release}).
-
-%% Replaced by generate_key
--export([dh_generate_key/1, dh_generate_key/2, dh_compute_key/3]).
--deprecated({dh_generate_key, 1, next_major_release}).
--deprecated({dh_generate_key, 2, next_major_release}).
--deprecated({dh_compute_key, 3, next_major_release}).
-
-%% Replaced by mod_exp_prim and no longer needed
--export([mod_exp/3, mpint/1, erlint/1, strong_rand_mpint/3]).
--deprecated({mod_exp, 3, next_major_release}).
--deprecated({mpint, 1, next_major_release}).
--deprecated({erlint, 1, next_major_release}).
--deprecated({strong_rand_mpint, 3, next_major_release}).
-
-%% Replaced by block_*
--export([des_cbc_encrypt/3, des_cbc_decrypt/3, des_cbc_ivec/1]).
--export([des3_cbc_encrypt/5, des3_cbc_decrypt/5]).
--export([des_ecb_encrypt/2, des_ecb_decrypt/2]).
--export([des_ede3_cbc_encrypt/5, des_ede3_cbc_decrypt/5]).
--export([des_cfb_encrypt/3, des_cfb_decrypt/3, des_cfb_ivec/2]).
--export([des3_cfb_encrypt/5, des3_cfb_decrypt/5]).
--deprecated({des_cbc_encrypt, 3, next_major_release}).
--deprecated({des_cbc_decrypt, 3, next_major_release}).
--deprecated({des_cbc_ivec, 1, next_major_release}).
--deprecated({des3_cbc_encrypt, 5, next_major_release}).
--deprecated({des3_cbc_decrypt, 5, next_major_release}).
--deprecated({des_ecb_encrypt, 2, next_major_release}).
--deprecated({des_ecb_decrypt, 2, next_major_release}).
--deprecated({des_ede3_cbc_encrypt, 5, next_major_release}).
--deprecated({des_ede3_cbc_decrypt, 5, next_major_release}).
--deprecated({des_cfb_encrypt, 3, next_major_release}).
--deprecated({des_cfb_decrypt, 3, next_major_release}).
--deprecated({des_cfb_ivec, 2, next_major_release}).
--deprecated({des3_cfb_encrypt, 5, next_major_release}).
--deprecated({des3_cfb_decrypt, 5, next_major_release}).
--export([blowfish_ecb_encrypt/2, blowfish_ecb_decrypt/2]).
--export([blowfish_cbc_encrypt/3, blowfish_cbc_decrypt/3]).
--export([blowfish_cfb64_encrypt/3, blowfish_cfb64_decrypt/3]).
--export([blowfish_ofb64_encrypt/3]).
--deprecated({blowfish_ecb_encrypt, 2, next_major_release}).
--deprecated({blowfish_ecb_decrypt, 2, next_major_release}).
--deprecated({blowfish_cbc_encrypt, 3, next_major_release}).
--deprecated({blowfish_cbc_decrypt, 3, next_major_release}).
--deprecated({blowfish_cfb64_encrypt, 3, next_major_release}).
--deprecated({blowfish_cfb64_decrypt, 3, next_major_release}).
--deprecated({blowfish_ofb64_encrypt, 3, next_major_release}).
--export([aes_cfb_128_encrypt/3, aes_cfb_128_decrypt/3]).
--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]).
--deprecated({aes_cfb_128_encrypt, 3, next_major_release}).
--deprecated({aes_cfb_128_decrypt, 3, next_major_release}).
--deprecated({aes_cbc_128_encrypt, 3, next_major_release}).
--deprecated({aes_cbc_128_decrypt, 3, next_major_release}).
--deprecated({aes_cbc_256_encrypt, 3, next_major_release}).
--deprecated({aes_cbc_256_decrypt, 3, next_major_release}).
--deprecated({aes_cbc_ivec, 1, next_major_release}).
--export([rc2_cbc_encrypt/3, rc2_cbc_decrypt/3]).
--export([rc2_40_cbc_encrypt/3, rc2_40_cbc_decrypt/3]).
--deprecated({rc2_cbc_encrypt, 3, next_major_release}).
--deprecated({rc2_cbc_decrypt, 3, next_major_release}).
-%% allready replaced by above!
--deprecated({rc2_40_cbc_encrypt, 3, next_major_release}).
--deprecated({rc2_40_cbc_decrypt, 3, next_major_release}).
-
-%% Replaced by stream_*
--export([aes_ctr_stream_init/2, aes_ctr_stream_encrypt/2, aes_ctr_stream_decrypt/2]).
--export([rc4_set_key/1, rc4_encrypt_with_state/2]).
--deprecated({aes_ctr_stream_init, 2, next_major_release}).
--deprecated({aes_ctr_stream_encrypt, 2, next_major_release}).
--deprecated({aes_ctr_stream_decrypt, 2, next_major_release}).
--deprecated({rc4_set_key, 1, next_major_release}).
--deprecated({rc4_encrypt_with_state, 2, next_major_release}).
-
-%% Not needed special case of stream_*
--export([aes_ctr_encrypt/3, aes_ctr_decrypt/3, rc4_encrypt/2]).
--deprecated({aes_ctr_encrypt, 3, next_major_release}).
--deprecated({aes_ctr_decrypt, 3, next_major_release}).
--deprecated({rc4_encrypt, 2, next_major_release}).
-
-%% Replace by public/private_encrypt/decrypt
--export([rsa_public_encrypt/3, rsa_private_decrypt/3]).
--export([rsa_private_encrypt/3, rsa_public_decrypt/3]).
--deprecated({rsa_public_encrypt, 3, next_major_release}).
--deprecated({rsa_private_decrypt, 3, next_major_release}).
--deprecated({rsa_public_decrypt, 3, next_major_release}).
--deprecated({rsa_private_encrypt, 3, next_major_release}).
-
-%% Replaced by crypto:module_info()
--export([info/0]).
--deprecated({info, 0, next_major_release}).
-
%% This should correspond to the similar macro in crypto.c
-define(MAX_BYTES_TO_NIF, 20000). %% Current value is: erlang:system_info(context_reductions) * 10
--type mpint() :: binary().
--type rsa_digest_type() :: 'md5' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'.
--type dss_digest_type() :: 'none' | 'sha'.
%%-type ecdsa_digest_type() :: 'md5' | 'sha' | 'sha256' | 'sha384' | 'sha512'.
--type data_or_digest() :: binary() | {digest, binary()}.
-type crypto_integer() :: binary() | integer().
%%-type ec_named_curve() :: atom().
%%-type ec_point() :: crypto_integer().
@@ -420,13 +284,10 @@ stream_decrypt(State, Data0) ->
%%
%% RAND - pseudo random numbers using RN_ functions in crypto lib
%%
--spec rand_bytes(non_neg_integer()) -> binary().
-spec strong_rand_bytes(non_neg_integer()) -> binary().
-spec rand_uniform(crypto_integer(), crypto_integer()) ->
crypto_integer().
-rand_bytes(_Bytes) -> ?nif_stub.
-
strong_rand_bytes(Bytes) ->
case strong_rand_bytes_nif(Bytes) of
false -> erlang:error(low_entropy);
@@ -694,7 +555,7 @@ path2bin(Path) when is_list(Path) ->
end.
%%--------------------------------------------------------------------
-%%% Internal functions (some internal API functions are part of the deprecated API)
+%%% Internal functions
%%--------------------------------------------------------------------
max_bytes() ->
?MAX_BYTES_TO_NIF.
@@ -724,59 +585,6 @@ hash_init_nif(_Hash) -> ?nif_stub.
hash_update_nif(_State, _Data) -> ?nif_stub.
hash_final_nif(_State) -> ?nif_stub.
-
-%%
-%% MD5
-%%
-
--spec md5(iodata()) -> binary().
--spec md5_init() -> binary().
--spec md5_update(binary(), iodata()) -> binary().
--spec md5_final(binary()) -> binary().
-
-md5(Data) ->
- hash(md5, Data).
-md5_init() ->
- hash_init(md5).
-md5_update(Context, Data) ->
- hash_update(Context, Data).
-md5_final(Context) ->
- hash_final(Context).
-
-%%
-%% MD4
-%%
--spec md4(iodata()) -> binary().
--spec md4_init() -> binary().
--spec md4_update(binary(), iodata()) -> binary().
--spec md4_final(binary()) -> binary().
-
-md4(Data) ->
- hash(md4, Data).
-md4_init() ->
- hash_init(md4).
-md4_update(Context, Data) ->
- hash_update(Context, Data).
-md4_final(Context) ->
- hash_final(Context).
-
-%%
-%% SHA
-%%
--spec sha(iodata()) -> binary().
--spec sha_init() -> binary().
--spec sha_update(binary(), iodata()) -> binary().
--spec sha_final(binary()) -> binary().
-
-sha(Data) ->
- hash(sha, Data).
-sha_init() ->
- hash_init(sha).
-sha_update(Context, Data) ->
- hash_update(Context, Data).
-sha_final(Context) ->
- hash_final(Context).
-
%% HMAC --------------------------------------------------------------------
hmac(Type, Key, Data, MacSize, Size, MaxBytes) when Size =< MaxBytes ->
@@ -811,28 +619,6 @@ hmac_final_nif(_Context, _MacSize) -> ?nif_stub.
cmac_nif(_Type, _Key, _Data) -> ?nif_stub.
-%%
-%% MD5_MAC
-%%
--spec md5_mac(iodata(), iodata()) -> binary().
--spec md5_mac_96(iodata(), iodata()) -> binary().
-
-md5_mac(Key, Data) -> hmac(md5, Key, Data).
-
-md5_mac_96(Key, Data) -> hmac(md5, Key, Data, 12).
-
-%%
-%% SHA_MAC
-%%
--spec sha_mac(iodata(), iodata()) -> binary().
--spec sha_mac_96(iodata(), iodata()) -> binary().
-
-sha_mac(Key, Data) -> hmac(sha, Key, Data).
-
-sha_mac(Key, Data, Size) -> hmac(sha, Key, Data, Size).
-
-sha_mac_96(Key, Data) -> hmac(sha, Key, Data, 12).
-
%% CIPHERS --------------------------------------------------------------------
block_crypt_nif(_Type, _Key, _Ivec, _Text, _IsEncrypt) -> ?nif_stub.
@@ -849,94 +635,6 @@ check_des3_key(Key) ->
end.
%%
-%% DES - in electronic codebook mode (ECB)
-%%
--spec des_ecb_encrypt(iodata(), iodata()) -> binary().
--spec des_ecb_decrypt(iodata(), iodata()) -> binary().
-
-des_ecb_encrypt(Key, Data) ->
- block_encrypt(des_ecb, Key, Data).
-des_ecb_decrypt(Key, Data) ->
- block_decrypt(des_ecb, Key, Data).
-
-%%
-%% DES3 - in cipher block chaining mode (CBC)
-%%
--spec des3_cbc_encrypt(iodata(), iodata(), iodata(), binary(), iodata()) ->
- binary().
--spec des3_cbc_decrypt(iodata(), iodata(), iodata(), binary(), iodata()) ->
- binary().
-
-des3_cbc_encrypt(Key1, Key2, Key3, IVec, Data) ->
- block_encrypt(des3_cbc, [Key1, Key2, Key3], IVec, Data).
-des_ede3_cbc_encrypt(Key1, Key2, Key3, IVec, Data) ->
- block_encrypt(des_ede3, [Key1, Key2, Key3], IVec, Data).
-
-des3_cbc_decrypt(Key1, Key2, Key3, IVec, Data) ->
- block_decrypt(des3_cbc, [Key1, Key2, Key3], IVec, Data).
-des_ede3_cbc_decrypt(Key1, Key2, Key3, IVec, Data) ->
- block_decrypt(des_ede3, [Key1, Key2, Key3], IVec, Data).
-
-%%
-%% DES3 - in 8-bits cipher feedback mode (CFB)
-%%
--spec des3_cfb_encrypt(iodata(), iodata(), iodata(), binary(), iodata()) ->
- binary().
--spec des3_cfb_decrypt(iodata(), iodata(), iodata(), binary(), iodata()) ->
- binary().
-
-des3_cfb_encrypt(Key1, Key2, Key3, IVec, Data) ->
- block_encrypt(des3_cfb, [Key1, Key2, Key3], IVec, Data).
-
-des3_cfb_decrypt(Key1, Key2, Key3, IVec, Data) ->
- block_decrypt(des3_cfb, [Key1, Key2, Key3], IVec, Data).
-
-%%
-%% Blowfish
-%%
--spec blowfish_ecb_encrypt(iodata(), iodata()) -> binary().
--spec blowfish_ecb_decrypt(iodata(), iodata()) -> binary().
--spec blowfish_cbc_encrypt(iodata(), binary(), iodata()) -> binary().
--spec blowfish_cbc_decrypt(iodata(), binary(), iodata()) -> binary().
--spec blowfish_cfb64_encrypt(iodata(), binary(), iodata()) -> binary().
--spec blowfish_cfb64_decrypt(iodata(), binary(), iodata()) -> binary().
--spec blowfish_ofb64_encrypt(iodata(), binary(), iodata()) -> binary().
-
-blowfish_ecb_encrypt(Key, Data) ->
- block_encrypt(blowfish_ecb, Key, Data).
-
-blowfish_ecb_decrypt(Key, Data) ->
- block_decrypt(blowfish_ecb, Key, Data).
-
-blowfish_cbc_encrypt(Key, IVec, Data) ->
- block_encrypt(blowfish_cbc, Key, IVec, Data).
-
-blowfish_cbc_decrypt(Key, IVec, Data) ->
- block_decrypt(blowfish_cbc, Key, IVec, Data).
-
-blowfish_cfb64_encrypt(Key, IVec, Data) ->
- block_encrypt(blowfish_cfb64, Key, IVec, Data).
-
-blowfish_cfb64_decrypt(Key, IVec, Data) ->
- block_decrypt(blowfish_cfb64, Key, IVec, Data).
-
-blowfish_ofb64_encrypt(Key, IVec, Data) ->
- block_encrypt(blowfish_ofb64, Key, IVec, Data).
-
-
-%%
-%% AES in cipher feedback mode (CFB) - 128 bit shift
-%%
--spec aes_cfb_128_encrypt(iodata(), binary(), iodata()) -> binary().
--spec aes_cfb_128_decrypt(iodata(), binary(), iodata()) -> binary().
-
-aes_cfb_128_encrypt(Key, IVec, Data) ->
- block_encrypt(aes_cfb128, Key, IVec, Data).
-
-aes_cfb_128_decrypt(Key, IVec, Data) ->
- block_decrypt(aes_cfb128, Key, IVec, Data).
-
-%%
%% AES - in Galois/Counter Mode (GCM)
%%
%% The default tag length is EVP_GCM_TLS_TAG_LEN(16),
@@ -952,88 +650,6 @@ chacha20_poly1305_encrypt(_Key, _Ivec, _AAD, _In) -> ?nif_stub.
chacha20_poly1305_decrypt(_Key, _Ivec, _AAD, _In, _Tag) -> ?nif_stub.
%%
-%% DES - in cipher block chaining mode (CBC)
-%%
--spec des_cbc_encrypt(iodata(), binary(), iodata()) -> binary().
--spec des_cbc_decrypt(iodata(), binary(), iodata()) -> binary().
-
-des_cbc_encrypt(Key, IVec, Data) ->
- block_encrypt(des_cbc, Key, IVec, Data).
-
-des_cbc_decrypt(Key, IVec, Data) ->
- block_decrypt(des_cbc, Key, IVec, Data).
-
-%%
-%% dec_cbc_ivec(Data) -> binary()
-%%
-%% Returns the IVec to be used in the next iteration of
-%% des_cbc_[encrypt|decrypt].
-%%
--spec des_cbc_ivec(iodata()) -> binary().
-
-des_cbc_ivec(Data) ->
- next_iv(des_cbc, Data).
-
-%%
-%% DES - in 8-bits cipher feedback mode (CFB)
-%%
--spec des_cfb_encrypt(iodata(), binary(), iodata()) -> binary().
--spec des_cfb_decrypt(iodata(), binary(), iodata()) -> binary().
-
-des_cfb_encrypt(Key, IVec, Data) ->
- block_encrypt(des_cfb, Key, IVec, Data).
-
-des_cfb_decrypt(Key, IVec, Data) ->
- block_decrypt(des_cfb, Key, IVec, Data).
-
-%%
-%% dec_cfb_ivec(IVec, Data) -> binary()
-%%
-%% Returns the IVec to be used in the next iteration of
-%% des_cfb_[encrypt|decrypt].
-%%
-
--spec des_cfb_ivec(iodata(), iodata()) -> binary().
-
-des_cfb_ivec(IVec, Data) ->
- next_iv(des_cfb, Data, IVec).
-
-
-%%
-%% AES - with 128 or 256 bit key in cipher block chaining mode (CBC)
-%%
--spec aes_cbc_128_encrypt(iodata(), binary(), iodata()) ->
- binary().
--spec aes_cbc_128_decrypt(iodata(), binary(), iodata()) ->
- binary().
--spec aes_cbc_256_encrypt(iodata(), binary(), iodata()) ->
- binary().
--spec aes_cbc_256_decrypt(iodata(), binary(), iodata()) ->
- binary().
-
-aes_cbc_128_encrypt(Key, IVec, Data) ->
- block_encrypt(aes_cbc128, Key, IVec, Data).
-
-aes_cbc_128_decrypt(Key, IVec, Data) ->
- block_decrypt(aes_cbc128, Key, IVec, Data).
-
-aes_cbc_256_encrypt(Key, IVec, Data) ->
- block_encrypt(aes_cbc256, Key, IVec, Data).
-
-aes_cbc_256_decrypt(Key, IVec, Data) ->
- block_decrypt(aes_cbc256, Key, IVec, Data).
-
-%%
-%% aes_cbc_ivec(Data) -> binary()
-%%
-%% Returns the IVec to be used in the next iteration of
-%% aes_cbc_*_[encrypt|decrypt].
-%% IVec size: 16 bytes
-%%
-aes_cbc_ivec(Data) ->
- next_iv(aes_cbc, Data).
-
-%%
%% AES - with 256 bit key in infinite garble extension mode (IGE)
%%
@@ -1066,17 +682,6 @@ do_stream_decrypt({rc4, State0}, Data) ->
{State, Text} = rc4_encrypt_with_state(State0, Data),
{{rc4, State}, Text}.
-%%
-%% 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.
-
%%
%% AES - in counter mode (CTR) with state maintained for multi-call streaming
@@ -1096,31 +701,9 @@ aes_ctr_stream_decrypt(_State, _Cipher) -> ?nif_stub.
%%
%% RC4 - symmetric stream cipher
%%
--spec rc4_encrypt(iodata(), iodata()) -> binary().
-
-rc4_encrypt(_Key, _Data) -> ?nif_stub.
rc4_set_key(_Key) -> ?nif_stub.
rc4_encrypt_with_state(_State, _Data) -> ?nif_stub.
-
-%% RC2 block cipher
-
-rc2_cbc_encrypt(Key, IVec, Data) ->
- notsup_to_error(block_encrypt(rc2_cbc, Key, IVec, Data)).
-
-rc2_cbc_decrypt(Key, IVec, Data) ->
- notsup_to_error(block_decrypt(rc2_cbc, Key, IVec, Data)).
-
-%%
-%% RC2 - 40 bits block cipher - Backwards compatibility not documented.
-%%
-rc2_40_cbc_encrypt(Key, IVec, Data) when erlang:byte_size(Key) == 5 ->
- notsup_to_error(block_encrypt(rc2_cbc, Key, IVec, Data)).
-
-rc2_40_cbc_decrypt(Key, IVec, Data) when erlang:byte_size(Key) == 5 ->
- notsup_to_error(block_decrypt(rc2_cbc, Key, IVec, Data)).
-
-
%% Secure remote password -------------------------------------------------------------------
user_srp_gen_key(Private, Generator, Prime) ->
@@ -1168,7 +751,7 @@ srp_scrambler(Version, UserPublic, HostPublic, Prime) when Version == '6'; Versi
srp_scrambler('3', _, HostPublic, _Prime) ->
%% The parameter u is a 32-bit unsigned integer which takes its value
%% from the first 32 bits of the SHA1 hash of B, MSB first.
- <<U:32/bits, _/binary>> = sha(HostPublic),
+ <<U:32/bits, _/binary>> = hash(sha, HostPublic),
U.
srp_pad_length(Width, Length) ->
@@ -1223,26 +806,10 @@ dh_check([_Prime,_Gen]) -> ?nif_stub.
%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()]
%% PrivKey = mpint()
--spec dh_generate_key([binary()]) -> {binary(),binary()}.
--spec dh_generate_key(binary()|undefined, [binary()]) ->
- {binary(),binary()}.
-
-dh_generate_key(DHParameters) ->
- dh_generate_key_nif(undefined, map_mpint_to_bin(DHParameters), 4).
-dh_generate_key(PrivateKey, DHParameters) ->
- dh_generate_key_nif(mpint_to_bin(PrivateKey), map_mpint_to_bin(DHParameters), 4).
-
dh_generate_key_nif(_PrivateKey, _DHParameters, _Mpint) -> ?nif_stub.
%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()]
%% MyPrivKey, OthersPublicKey = mpint()
--spec dh_compute_key(binary(), binary(), [binary()]) -> binary().
-
-dh_compute_key(OthersPublicKey, MyPrivateKey, DHParameters) ->
- compute_key(dh, mpint_to_bin(OthersPublicKey), mpint_to_bin(MyPrivateKey),
- map_mpint_to_bin(DHParameters)).
-
-
dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub.
ec_key_generate(_Curve, _Key) -> ?nif_stub.
@@ -1322,137 +889,19 @@ ensure_int_as_bin(Int) when is_integer(Int) ->
ensure_int_as_bin(Bin) ->
Bin.
-map_to_norm_bin([H|_]=List) when is_integer(H) ->
- lists:map(fun(E) -> int_to_bin(E) end, List);
-map_to_norm_bin(List) ->
- lists:map(fun(E) -> mpint_to_bin(E) end, List).
-
-%%--------------------------------------------------------------------
-%%% Deprecated
%%--------------------------------------------------------------------
%%
-%% rsa_public_encrypt
-%% rsa_private_decrypt
-type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' | 'rsa_no_padding'.
--spec rsa_public_encrypt(binary(), [binary()], rsa_padding()) ->
- binary().
--spec rsa_public_decrypt(binary(), [integer() | mpint()], rsa_padding()) ->
- binary().
--spec rsa_private_encrypt(binary(), [integer() | mpint()], rsa_padding()) ->
- binary().
--spec rsa_private_decrypt(binary(), [integer() | mpint()], rsa_padding()) ->
- binary().
-
-%% Binary, Key = [E,N]
-rsa_public_encrypt(BinMesg, Key, Padding) ->
- case rsa_public_crypt(BinMesg, map_to_norm_bin(Key), Padding, true) of
- error ->
- erlang:error(encrypt_failed, [BinMesg,Key, Padding]);
- Sign -> Sign
- end.
-
rsa_public_crypt(_BinMsg, _Key, _Padding, _IsEncrypt) -> ?nif_stub.
-%% Binary, Key = [E,N,D]
-rsa_private_decrypt(BinMesg, Key, Padding) ->
- case rsa_private_crypt(BinMesg, map_to_norm_bin(Key), Padding, false) of
- error ->
- erlang:error(decrypt_failed, [BinMesg,Key, Padding]);
- Sign -> Sign
- end.
-
rsa_private_crypt(_BinMsg, _Key, _Padding, _IsEncrypt) -> ?nif_stub.
-
-%% Binary, Key = [E,N,D]
-rsa_private_encrypt(BinMesg, Key, Padding) ->
- case rsa_private_crypt(BinMesg, map_to_norm_bin(Key), Padding, true) of
- error ->
- erlang:error(encrypt_failed, [BinMesg,Key, Padding]);
- Sign -> Sign
- end.
-
-%% Binary, Key = [E,N]
-rsa_public_decrypt(BinMesg, Key, Padding) ->
- case rsa_public_crypt(BinMesg, map_to_norm_bin(Key), Padding, false) of
- error ->
- erlang:error(decrypt_failed, [BinMesg,Key, Padding]);
- Sign -> Sign
- end.
-
-map_mpint_to_bin(List) ->
- lists:map(fun(E) -> mpint_to_bin(E) end, List ).
-
-%%
-%% DSS, RSA - sign
-%%
-%% Key = [P,Q,G,X] P,Q,G=DSSParams X=PrivateKey
--spec dss_sign(data_or_digest(), [binary()]) -> binary().
--spec dss_sign(dss_digest_type(), data_or_digest(), [binary()]) -> binary().
--spec rsa_sign(data_or_digest(), [binary()]) -> binary().
--spec rsa_sign(rsa_digest_type(), data_or_digest(), [binary()]) -> binary().
-
-dss_sign(DataOrDigest,Key) ->
- dss_sign(sha,DataOrDigest,Key).
-dss_sign(Type, Data, Key) when is_binary(Data), Type=/=none ->
- sign(dss, Type, mpint_to_bin(Data), map_mpint_to_bin(Key));
-dss_sign(Type, Digest, Key) ->
- sign(dss, Type, Digest, map_mpint_to_bin(Key)).
-
-
-%% Key = [E,N,D] E=PublicExponent N=PublicModulus D=PrivateExponent
-rsa_sign(DataOrDigest,Key) ->
- rsa_sign(sha, DataOrDigest, Key).
-
-rsa_sign(Type, Data, Key) when is_binary(Data) ->
- sign(rsa, Type, mpint_to_bin(Data), map_mpint_to_bin(Key));
-rsa_sign(Type, Digest, Key) ->
- sign(rsa, Type, Digest, map_mpint_to_bin(Key)).
-
-%%
-%% DSS, RSA - verify
-%%
--spec dss_verify(data_or_digest(), binary(), [binary()]) -> boolean().
--spec dss_verify(dss_digest_type(), data_or_digest(), binary(), [binary()]) -> boolean().
--spec rsa_verify(data_or_digest(), binary(), [binary()]) -> boolean().
--spec rsa_verify(rsa_digest_type(), data_or_digest(), binary(), [binary()]) ->
- boolean().
-
-%% Key = [P,Q,G,Y] P,Q,G=DSSParams Y=PublicKey
-dss_verify(Data,Signature,Key) ->
- dss_verify(sha, Data, Signature, Key).
-
-dss_verify(Type,Data,Signature,Key) when is_binary(Data), Type=/=none ->
- verify(dss,Type,mpint_to_bin(Data),mpint_to_bin(Signature),map_mpint_to_bin(Key));
-dss_verify(Type,Digest,Signature,Key) ->
- verify(dss,Type,Digest,mpint_to_bin(Signature),map_mpint_to_bin(Key)).
-
-% Key = [E,N] E=PublicExponent N=PublicModulus
-rsa_verify(Data,Signature,Key) ->
- rsa_verify(sha, Data,Signature,Key).
-rsa_verify(Type, Data, Signature, Key) when is_binary(Data) ->
- verify(rsa, Type, mpint_to_bin(Data), mpint_to_bin(Signature), map_mpint_to_bin(Key));
-rsa_verify(Type, Digest, Signature, Key) ->
- verify(rsa, Type, Digest, mpint_to_bin(Signature), map_mpint_to_bin(Key)).
-
--spec strong_rand_mpint(Bits::non_neg_integer(),
- Top::-1..1,
- Bottom::0..1) -> binary().
-
-strong_rand_mpint(Bits, Top, Bottom) ->
- case strong_rand_mpint_nif(Bits,Top,Bottom) of
- false -> erlang:error(low_entropy);
- Bin -> Bin
- end.
-strong_rand_mpint_nif(_Bits, _Top, _Bottom) -> ?nif_stub.
-
-
%% large integer in a binary with 32bit length
%% MP representaion (SSH2)
mpint(X) when X < 0 -> mpint_neg(X);
mpint(X) -> mpint_pos(X).
-
+
-define(UINT32(X), X:32/unsigned-big-integer).
@@ -1477,76 +926,8 @@ erlint(<<MPIntSize:32/integer,MPIntValue/binary>>) ->
<<Integer:Bits/integer>> = MPIntValue,
Integer.
-mpint_to_bin(<<Len:32, Bin:Len/binary>>) ->
- Bin.
-
%%
%% mod_exp - utility for rsa generation and SRP
%%
-mod_exp(Base, Exponent, Modulo)
- when is_integer(Base), is_integer(Exponent), is_integer(Modulo) ->
- bin_to_int(mod_exp_nif(int_to_bin(Base), int_to_bin(Exponent), int_to_bin(Modulo), 0));
-
-mod_exp(Base, Exponent, Modulo) ->
- mod_exp_nif(mpint_to_bin(Base),mpint_to_bin(Exponent),mpint_to_bin(Modulo), 4).
-
mod_exp_nif(_Base,_Exp,_Mod,_bin_hdr) -> ?nif_stub.
--define(FUNC_LIST, [hash, hash_init, hash_update, hash_final,
- hmac, hmac_init, hmac_update, hmac_final, hmac_final_n,
- cmac,
- %% deprecated
- md4, md4_init, md4_update, md4_final,
- md5, md5_init, md5_update, md5_final,
- sha, sha_init, sha_update, sha_final,
- md5_mac, md5_mac_96,
- sha_mac, sha_mac_96,
- %%
- block_encrypt, block_decrypt,
- %% deprecated
- des_cbc_encrypt, des_cbc_decrypt,
- des_cfb_encrypt, des_cfb_decrypt,
- des_ecb_encrypt, des_ecb_decrypt,
- des3_cbc_encrypt, des3_cbc_decrypt,
- des3_cfb_encrypt, des3_cfb_decrypt,
- aes_cfb_128_encrypt, aes_cfb_128_decrypt,
- rc2_cbc_encrypt, rc2_cbc_decrypt,
- rc2_40_cbc_encrypt, rc2_40_cbc_decrypt,
- aes_cbc_128_encrypt, aes_cbc_128_decrypt,
- aes_cbc_256_encrypt, aes_cbc_256_decrypt,
- blowfish_cbc_encrypt, blowfish_cbc_decrypt,
- blowfish_cfb64_encrypt, blowfish_cfb64_decrypt,
- blowfish_ecb_encrypt, blowfish_ecb_decrypt, blowfish_ofb64_encrypt,
- %%
- rand_bytes,
- strong_rand_bytes,
- rand_uniform,
- rand_seed,
- mod_pow,
- exor,
- %% deprecated
- mod_exp,strong_rand_mpint,erlint, mpint,
- %%
- sign, verify, generate_key, compute_key,
- %% deprecated
- dss_verify,dss_sign,
- rsa_verify,rsa_sign,
- rsa_public_encrypt,rsa_private_decrypt,
- rsa_private_encrypt,rsa_public_decrypt,
- dh_generate_key, dh_compute_key,
- %%
- stream_init, stream_encrypt, stream_decrypt,
- %% deprecated
- rc4_encrypt, rc4_set_key, rc4_encrypt_with_state,
- aes_ctr_encrypt, aes_ctr_decrypt,
- aes_ctr_stream_init, aes_ctr_stream_encrypt, aes_ctr_stream_decrypt,
- %%
- next_iv,
- %% deprecated
- aes_cbc_ivec,
- des_cbc_ivec, des_cfb_ivec,
- info,
- %%
- info_lib, info_fips, supports]).
-info() ->
- ?FUNC_LIST.
diff --git a/lib/crypto/test/Makefile b/lib/crypto/test/Makefile
index 928a1b1d73..5a81c84558 100644
--- a/lib/crypto/test/Makefile
+++ b/lib/crypto/test/Makefile
@@ -7,8 +7,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
MODULES = \
blowfish_SUITE \
- crypto_SUITE \
- old_crypto_SUITE
+ crypto_SUITE
ERL_FILES= $(MODULES:%=%.erl)
diff --git a/lib/crypto/test/blowfish_SUITE.erl b/lib/crypto/test/blowfish_SUITE.erl
index a78f8fe39a..c2d0d2621b 100644
--- a/lib/crypto/test/blowfish_SUITE.erl
+++ b/lib/crypto/test/blowfish_SUITE.erl
@@ -151,7 +151,7 @@ end_per_group(_GroupName, Config) ->
ecb_test(KeyBytes, ClearBytes, CipherBytes) ->
{Key, Clear, Cipher} =
{to_bin(KeyBytes), to_bin(ClearBytes), to_bin(CipherBytes)},
- ?line m(crypto:blowfish_ecb_encrypt(Key, Clear), Cipher),
+ ?line m(crypto:block_encrypt(blowfish_ecb, Key, Clear), Cipher),
true.
ecb(doc) ->
@@ -200,7 +200,7 @@ cbc(doc) ->
cbc(suite) ->
[];
cbc(Config) when is_list(Config) ->
- true = crypto:blowfish_cbc_encrypt(?KEY, ?IVEC, ?DATA_PADDED) =:=
+ true = crypto:block_encrypt(blowfish_cbc, ?KEY, ?IVEC, ?DATA_PADDED) =:=
to_bin("6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC"),
ok.
@@ -209,7 +209,7 @@ cfb64(doc) ->
cfb64(suite) ->
[];
cfb64(Config) when is_list(Config) ->
- true = crypto:blowfish_cfb64_encrypt(?KEY, ?IVEC, ?DATA) =:=
+ true = crypto:block_encrypt(blowfish_cfb64, ?KEY, ?IVEC, ?DATA) =:=
to_bin("E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3"),
ok.
@@ -218,7 +218,7 @@ ofb64(doc) ->
ofb64(suite) ->
[];
ofb64(Config) when is_list(Config) ->
- true = crypto:blowfish_ofb64_encrypt(?KEY, ?IVEC, ?DATA) =:=
+ true = crypto:block_encrypt(blowfish_ofb64, ?KEY, ?IVEC, ?DATA) =:=
to_bin("E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA"),
ok.
@@ -227,8 +227,9 @@ no_ecb(doc) ->
no_ecb(suite) ->
[];
no_ecb(Config) when is_list(Config) ->
- notsup(fun crypto:blowfish_ecb_encrypt/2,
- [to_bin("0000000000000000"),
+ notsup(fun crypto:block_encrypt/3,
+ [blowfish_ecb,
+ to_bin("0000000000000000"),
to_bin("FFFFFFFFFFFFFFFF")]).
no_cbc(doc) ->
@@ -236,16 +237,16 @@ no_cbc(doc) ->
no_cbc(suite) ->
[];
no_cbc(Config) when is_list(Config) ->
- notsup(fun crypto:blowfish_cbc_encrypt/3,
- [?KEY, ?IVEC, ?DATA_PADDED]).
+ notsup(fun crypto:block_encrypt/4,
+ [blowfish_cbc, ?KEY, ?IVEC, ?DATA_PADDED]).
no_cfb64(doc) ->
"Test that CFB64 mode is disabled";
no_cfb64(suite) ->
[];
no_cfb64(Config) when is_list(Config) ->
- notsup(fun crypto:blowfish_cfb64_encrypt/3,
- [?KEY, ?IVEC, ?DATA]),
+ notsup(fun crypto:block_encrypt/4,
+ [blowfish_cfb64, ?KEY, ?IVEC, ?DATA]),
ok.
no_ofb64(doc) ->
@@ -253,8 +254,8 @@ no_ofb64(doc) ->
no_ofb64(suite) ->
[];
no_ofb64(Config) when is_list(Config) ->
- notsup(fun crypto:blowfish_ofb64_encrypt/3,
- [?KEY, ?IVEC, ?DATA]).
+ notsup(fun crypto:block_encrypt/4,
+ [blowfish_ofb64, ?KEY, ?IVEC, ?DATA]).
%% Helper functions
diff --git a/lib/crypto/test/old_crypto_SUITE.erl b/lib/crypto/test/old_crypto_SUITE.erl
deleted file mode 100644
index 324ed39c6d..0000000000
--- a/lib/crypto/test/old_crypto_SUITE.erl
+++ /dev/null
@@ -1,2350 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(old_crypto_SUITE).
-
--include_lib("common_test/include/ct.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,
- info/1,
- link_test/1,
- md5/1,
- md5_update/1,
- md4/1,
- md4_update/1,
- sha/1,
- sha_update/1,
- hmac_update_sha/1,
- hmac_update_sha_n/1,
- hmac_update_sha256/1,
- hmac_update_sha512/1,
- hmac_update_md5/1,
- hmac_update_md5_io/1,
- hmac_update_md5_n/1,
- hmac_rfc2202/1,
- hmac_rfc4231_sha224/1,
- hmac_rfc4231_sha256/1,
- hmac_rfc4231_sha384/1,
- hmac_rfc4231_sha512/1,
- ripemd160/1,
- ripemd160_update/1,
- sha256/1,
- sha256_update/1,
- sha512/1,
- sha512_update/1,
- md5_mac/1,
- md5_mac_io/1,
- des_cbc/1,
- des_cbc_iter/1,
- des_cfb/1,
- des_cfb_iter/1,
- des_ecb/1,
- des3_cbc/1,
- des3_cbf/1,
- des3_cfb/1,
- rc2_cbc/1,
- aes_cfb/1,
- aes_cbc/1,
- aes_cbc_iter/1,
- aes_ctr/1,
- aes_ctr_stream/1,
- mod_exp_test/1,
- rand_uniform_test/1,
- strong_rand_test/1,
- rsa_verify_test/1,
- dsa_verify_test/1,
- rsa_sign_test/1,
- rsa_sign_hash_test/1,
- dsa_sign_test/1,
- dsa_sign_hash_test/1,
- rsa_encrypt_decrypt/1,
- dh/1,
- srp3/1, srp6/1, srp6a/1,
- ec/1,
- exor_test/1,
- rc4_test/1,
- rc4_stream_test/1,
- blowfish_cfb64/1,
- smp/1]).
-
--export([hexstr2bin/1]).
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [link_test, {group, info}].
-
-groups() ->
- [{info, [sequence],[info, {group, rest}]},
- {rest, [],
- [md5, md5_update, md4, md4_update, md5_mac,
- md5_mac_io, ripemd160, ripemd160_update, sha, sha_update,
- sha256, sha256_update, sha512, sha512_update,
- hmac_update_sha, hmac_update_sha_n, hmac_update_sha256, hmac_update_sha512,
- hmac_update_md5_n, hmac_update_md5_io, hmac_update_md5,
- hmac_rfc2202, hmac_rfc4231_sha224, hmac_rfc4231_sha256,
- hmac_rfc4231_sha384, hmac_rfc4231_sha512,
- des_cbc, aes_cfb, aes_cbc,
- des_cfb, des_cfb_iter, des3_cbc, des3_cbf, des3_cfb, rc2_cbc,
- aes_cbc_iter, aes_ctr, aes_ctr_stream, des_cbc_iter, des_ecb,
- rand_uniform_test, strong_rand_test,
- rsa_verify_test, dsa_verify_test, rsa_sign_test,
- rsa_sign_hash_test, dsa_sign_test, dsa_sign_hash_test,
- rsa_encrypt_decrypt, dh, srp3, srp6, srp6a, ec, exor_test,
- rc4_test, rc4_stream_test, mod_exp_test, blowfish_cfb64,
- smp]}].
-
-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(info, Config) ->
- Config;
-init_per_testcase(_Name,Config) ->
- io:format("init_per_testcase\n"),
- ?line crypto:start(),
- Config.
-
-end_per_testcase(info, Config) ->
- Config;
-end_per_testcase(_Name,Config) ->
- io:format("end_per_testcase\n"),
- ?line crypto:stop(),
- Config.
-
-%%
-%%
-link_test(doc) ->
- ["Test that the library is statically linked to libcrypto.a."];
-link_test(suite) ->
- [];
-link_test(Config) when is_list(Config) ->
- ?line case os:type() of
- {unix,darwin} -> {skipped,"Darwin cannot link statically"};
- {unix,_} -> link_test_1();
- _ -> {skip,"Only runs on Unix"}
- end.
-
-link_test_1() ->
- ?line CryptoPriv = code:priv_dir(crypto),
- ?line Wc = filename:join([CryptoPriv,"lib","crypto.*"]),
- ?line case filelib:wildcard(Wc) of
- [] -> {skip,"Didn't find the crypto driver"};
- [Drv] -> link_test_2(Drv)
- end.
-
-link_test_2(Drv) ->
- case ldd_program() of
- none ->
- {skip,"No ldd-like program found"};
- Ldd ->
- Cmd = Ldd ++ " " ++ Drv,
- Libs = os:cmd(Cmd),
- io:format("~p\n", [Libs]),
- case string:str(Libs, "libcrypto") of
- 0 ->
- case ?t:is_commercial() of
- true ->
- ?t:fail({libcrypto,statically_linked});
- false ->
- {comment,"Statically linked (OK for open-source platform)"}
- end;
- _ ->
- ok
- end
- end.
-
-ldd_program() ->
- case os:find_executable("ldd") of
- false ->
- case os:type() of
- {unix,darwin} ->
- case os:find_executable("otool") of
- false -> none;
- Otool -> Otool ++ " -L"
- end;
- _ ->
- none
- end;
- Ldd when is_list(Ldd) -> Ldd
- end.
-
-
-
-info(doc) ->
- ["Call the info function."];
-info(suite) ->
- [];
-info(Config) when is_list(Config) ->
- case {code:lib_dir(crypto),?t:is_commercial()} of
- {{error,bad_name},false} ->
- {skip,"Missing crypto application"};
- {_,_} ->
- ?line crypto:start(),
- ?line Info = crypto:info(),
- ?line Exports = lists:usort([F || {F,_} <- crypto:module_info(exports)]),
- ?line [] = Info -- Exports,
- ?line NotInInfo = Exports -- Info,
- io:format("NotInInfo = ~p\n", [NotInInfo]),
- %% BlackList = lists:sort([des_ede3_cbc_decrypt, des_ede3_cbc_encrypt,
- %% dh_check, dh_generate_parameters,
- %% module_info, start, stop, version]),
- %% ?line BlackList = NotInInfo,
-
- ?line InfoLib = crypto:info_lib(),
- ?line [_|_] = InfoLib,
- F = fun([{Name,VerN,VerS}|T],Me) ->
- ?line true = is_binary(Name),
- ?line true = is_integer(VerN),
- ?line true = is_binary(VerS),
- Me(T,Me);
- ([],_) ->
- ok
- end,
- ?line F(InfoLib,F),
- ?line crypto:stop()
- end.
-
-%%
-%%
-md5(doc) ->
- ["Generate MD5 message digests and check the result. Examples are "
- "from RFC-1321."];
-md5(suite) ->
- [];
-md5(Config) when is_list(Config) ->
- ?line m(crypto:md5(""),
- hexstr2bin("d41d8cd98f00b204e9800998ecf8427e")),
- ?line m(crypto:md5("a"),
- hexstr2bin("0cc175b9c0f1b6a831c399e269772661")),
- ?line m(crypto:md5("abc"),
- hexstr2bin("900150983cd24fb0d6963f7d28e17f72")),
- ?line m(crypto:md5("message digest"),
- hexstr2bin("f96b697d7cb7938d525a2f31aaf161d0")),
- ?line m(crypto:md5("abcdefghijklmnopqrstuvwxyz"),
- hexstr2bin("c3fcd3d76192e4007dfb496cca67e13b")),
- ?line m(crypto:md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
- "0123456789"),
- hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f")),
- ?line m(crypto:md5("12345678901234567890123456789012345678901234567890"
- "123456789012345678901234567890"),
- hexstr2bin("57edf4a22be3c955ac49da2e2107b67a")).
-
-%%
-%%
-md5_update(doc) ->
- ["Generate MD5 message using md5_init, md5_update, and md5_final, and"
- "check the result. Examples are from RFC-1321."];
-md5_update(suite) ->
- [];
-md5_update(Config) when is_list(Config) ->
- ?line Ctx = crypto:md5_init(),
- ?line Ctx1 = crypto:md5_update(Ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
- ?line Ctx2 = crypto:md5_update(Ctx1, "abcdefghijklmnopqrstuvwxyz"
- "0123456789"),
- ?line m(crypto:md5_final(Ctx2),
- hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f")).
-
-%%
-%%
-md4(doc) ->
- ["Generate MD4 message digests and check the result. Examples are "
- "from RFC-1321."];
-md4(suite) ->
- [];
-md4(Config) when is_list(Config) ->
- ?line m(crypto:md4(""),
- hexstr2bin("31d6cfe0d16ae931b73c59d7e0c089c0")),
- ?line m(crypto:md4("a"),
- hexstr2bin("bde52cb31de33e46245e05fbdbd6fb24")),
- ?line m(crypto:md4("abc"),
- hexstr2bin("a448017aaf21d8525fc10ae87aa6729d")),
- ?line m(crypto:md4("message digest"),
- hexstr2bin("d9130a8164549fe818874806e1c7014b")),
- ?line m(crypto:md4("abcdefghijklmnopqrstuvwxyz"),
- hexstr2bin("d79e1c308aa5bbcdeea8ed63df412da9")),
- ?line m(crypto:md4("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
- "0123456789"),
- hexstr2bin("043f8582f241db351ce627e153e7f0e4")),
- ?line m(crypto:md4("12345678901234567890123456789012345678901234567890"
- "123456789012345678901234567890"),
- hexstr2bin("e33b4ddc9c38f2199c3e7b164fcc0536")).
-
-%%
-%%
-md4_update(doc) ->
- ["Generate MD5 message using md5_init, md5_update, and md5_final, and"
- "check the result. Examples are from RFC-1321."];
-md4_update(suite) ->
- [];
-md4_update(Config) when is_list(Config) ->
- ?line Ctx = crypto:md4_init(),
- ?line Ctx1 = crypto:md4_update(Ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
- ?line Ctx2 = crypto:md4_update(Ctx1, "abcdefghijklmnopqrstuvwxyz"
- "0123456789"),
- ?line m(crypto:md4_final(Ctx2),
- hexstr2bin("043f8582f241db351ce627e153e7f0e4")).
-
-%%
-%%
-sha(doc) ->
- ["Generate SHA message digests and check the result. Examples are "
- "from FIPS-180-1."];
-sha(suite) ->
- [];
-sha(Config) when is_list(Config) ->
- ?line m(crypto:sha("abc"),
- hexstr2bin("A9993E364706816ABA3E25717850C26C9CD0D89D")),
- ?line m(crypto:sha("abcdbcdecdefdefgefghfghighijhijkijkljklmklm"
- "nlmnomnopnopq"),
- hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")).
-
-
-%%
-hmac_update_sha_n(doc) ->
- ["Request a larger-than-allowed SHA1 HMAC using hmac_init, hmac_update, and hmac_final_n. "
- "Expected values for examples are generated using crypto:sha_mac." ];
-hmac_update_sha_n(suite) ->
- [];
-hmac_update_sha_n(Config) when is_list(Config) ->
- ?line Key = hexstr2bin("00010203101112132021222330313233"
- "04050607141516172425262734353637"
- "08090a0b18191a1b28292a2b38393a3b"
- "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f"),
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(sha, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final_n(Ctx3, 1024),
- ?line Exp = crypto:sha_mac(Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac),
- ?line m(size(Exp), size(Mac)).
-
-
-hmac_update_sha(doc) ->
- ["Generate an SHA1 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:sha_mac." ];
-hmac_update_sha(suite) ->
- [];
-hmac_update_sha(Config) when is_list(Config) ->
- ?line Key = hexstr2bin("00010203101112132021222330313233"
- "04050607141516172425262734353637"
- "08090a0b18191a1b28292a2b38393a3b"
- "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f"),
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(sha, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final(Ctx3),
- ?line Exp = crypto:hmac(sha, Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac).
-
-hmac_update_sha256(doc) ->
- ["Generate an SHA256 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:sha256_mac." ];
-hmac_update_sha256(suite) ->
- [];
-hmac_update_sha256(Config) when is_list(Config) ->
- if_supported(sha256, fun() -> hmac_update_sha256_do() end).
-
-hmac_update_sha256_do() ->
- ?line Key = hexstr2bin("00010203101112132021222330313233"
- "04050607141516172425262734353637"
- "08090a0b18191a1b28292a2b38393a3b"
- "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f"),
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(sha256, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final(Ctx3),
- ?line Exp = crypto:hmac(sha256, Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac).
-
-hmac_update_sha512(doc) ->
- ["Generate an SHA512 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:sha512_mac." ];
-hmac_update_sha512(suite) ->
- [];
-hmac_update_sha512(Config) when is_list(Config) ->
- if_supported(sha512, fun() -> hmac_update_sha512_do() end).
-
-hmac_update_sha512_do() ->
- ?line Key = hexstr2bin("00010203101112132021222330313233"
- "04050607141516172425262734353637"
- "08090a0b18191a1b28292a2b38393a3b"
- "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f"),
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(sha512, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final(Ctx3),
- ?line Exp = crypto:hmac(sha512, Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac).
-
-hmac_update_md5(doc) ->
- ["Generate an MD5 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:md5_mac." ];
-hmac_update_md5(suite) ->
- [];
-hmac_update_md5(Config) when is_list(Config) ->
- % ?line Key2 = ["A fine speach", "by a fine man!"],
- Key2 = "A fine speach by a fine man!",
- ?line Long1 = "Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal.",
- ?line Long2 = "Now we are engaged in a great civil war, testing whether that nation, or any nation, so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.",
- ?line Long3 = "But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us-that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion that we here highly resolve that these dead shall not have died in vain-that this nation, under God, shall have a new birth of freedom-and that government of the people, by the people, for the people, shall not perish from the earth.",
- ?line CtxA = crypto:hmac_init(md5, Key2),
- ?line CtxB = crypto:hmac_update(CtxA, Long1),
- ?line CtxC = crypto:hmac_update(CtxB, Long2),
- ?line CtxD = crypto:hmac_update(CtxC, Long3),
- ?line Mac2 = crypto:hmac_final(CtxD),
- ?line Exp2 = crypto:md5_mac(Key2, lists:flatten([Long1, Long2, Long3])),
- ?line m(Exp2, Mac2).
-
-hmac_rfc2202(doc) ->
- ["Generate an HMAC using hmac, md5_mac, and sha_mac."
- "Test vectors are taken from RFC-2202."];
-hmac_rfc2202(suite) ->
- [];
-hmac_rfc2202(Config) when is_list(Config) ->
- hmac_rfc2202_md5(),
- hmac_rfc2202_sha().
-
-hmac_rfc2202_md5() ->
- %% Test case 1
- Case1Key = binary:copy(<<16#0b>>, 16),
- Case1Data = <<"Hi There">>,
- Case1Exp = hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d"),
-
- ?line Case1Mac_1 = crypto:md5_mac(Case1Key, Case1Data),
- ?line Case1Mac_2 = crypto:hmac(md5, Case1Key, Case1Data),
- ?line m(Case1Exp, Case1Mac_1),
- ?line m(Case1Exp, Case1Mac_2),
-
- %% Test case 2
- Case2Key = <<"Jefe">>,
- Case2Data = <<"what do ya want for nothing?">>,
- Case2Exp = hexstr2bin("750c783e6ab0b503eaa86e310a5db738"),
-
- ?line Case2Mac_1 = crypto:md5_mac(Case2Key, Case2Data),
- ?line Case2Mac_2 = crypto:hmac(md5, Case2Key, Case2Data),
- ?line m(Case2Exp, Case2Mac_1),
- ?line m(Case2Exp, Case2Mac_2),
-
- %% Test case 3
- Case3Key = binary:copy(<<16#aa>>, 16),
- Case3Data = binary:copy(<<16#dd>>, 50),
- Case3Exp = hexstr2bin("56be34521d144c88dbb8c733f0e8b3f6"),
-
- ?line Case3Mac_1 = crypto:md5_mac(Case3Key, Case3Data),
- ?line Case3Mac_2 = crypto:hmac(md5, Case3Key, Case3Data),
- ?line m(Case3Exp, Case3Mac_1),
- ?line m(Case3Exp, Case3Mac_2),
-
- %% Test case 4
- Case4Key = list_to_binary(lists:seq(1, 16#19)),
- Case4Data = binary:copy(<<16#cd>>, 50),
- Case4Exp = hexstr2bin("697eaf0aca3a3aea3a75164746ffaa79"),
-
- ?line Case4Mac_1 = crypto:md5_mac(Case4Key, Case4Data),
- ?line Case4Mac_2 = crypto:hmac(md5, Case4Key, Case4Data),
- ?line m(Case4Exp, Case4Mac_1),
- ?line m(Case4Exp, Case4Mac_2),
-
- %% Test case 5
- Case5Key = binary:copy(<<16#0c>>, 16),
- Case5Data = "Test With Truncation",
- Case5Exp = hexstr2bin("56461ef2342edc00f9bab995690efd4c"),
- Case5Exp96 = hexstr2bin("56461ef2342edc00f9bab995"),
-
- ?line Case5Mac_1 = crypto:md5_mac(Case5Key, Case5Data),
- ?line Case5Mac_2 = crypto:hmac(md5, Case5Key, Case5Data),
- ?line Case5Mac96_1 = crypto:md5_mac_96(Case5Key, Case5Data),
- ?line Case5Mac96_2 = crypto:hmac(md5, Case5Key, Case5Data, 12),
- ?line m(Case5Exp, Case5Mac_1),
- ?line m(Case5Exp, Case5Mac_2),
- ?line m(Case5Exp96, Case5Mac96_1),
- ?line m(Case5Exp96, Case5Mac96_2),
-
- %% Test case 6
- Case6Key = binary:copy(<<16#aa>>, 80),
- Case6Data = <<"Test Using Larger Than Block-Size Key - Hash Key First">>,
- Case6Exp = hexstr2bin("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"),
-
- ?line Case6Mac_1 = crypto:md5_mac(Case6Key, Case6Data),
- ?line Case6Mac_2 = crypto:hmac(md5, Case6Key, Case6Data),
- ?line m(Case6Exp, Case6Mac_1),
- ?line m(Case6Exp, Case6Mac_2),
-
- %% Test case 7
- Case7Key = binary:copy(<<16#aa>>, 80),
- Case7Data = <<"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data">>,
- Case7Exp = hexstr2bin("6f630fad67cda0ee1fb1f562db3aa53e"),
-
- ?line Case7Mac_1 = crypto:md5_mac(Case7Key, Case7Data),
- ?line Case7Mac_2 = crypto:hmac(md5, Case7Key, Case7Data),
- ?line m(Case7Exp, Case7Mac_1),
- ?line m(Case7Exp, Case7Mac_2).
-
-hmac_rfc2202_sha() ->
- %% Test case 1
- Case1Key = binary:copy(<<16#0b>>, 20),
- Case1Data = <<"Hi There">>,
- Case1Exp = hexstr2bin("b617318655057264e28bc0b6fb378c8ef146be00"),
-
- ?line Case1Mac_1 = crypto:sha_mac(Case1Key, Case1Data),
- ?line Case1Mac_2 = crypto:hmac(sha, Case1Key, Case1Data),
- ?line m(Case1Exp, Case1Mac_1),
- ?line m(Case1Exp, Case1Mac_2),
-
- %% Test case 2
- Case2Key = <<"Jefe">>,
- Case2Data = <<"what do ya want for nothing?">>,
- Case2Exp = hexstr2bin("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"),
-
- ?line Case2Mac_1 = crypto:sha_mac(Case2Key, Case2Data),
- ?line Case2Mac_2 = crypto:hmac(sha, Case2Key, Case2Data),
- ?line m(Case2Exp, Case2Mac_1),
- ?line m(Case2Exp, Case2Mac_2),
-
- %% Test case 3
- Case3Key = binary:copy(<<16#aa>>, 20),
- Case3Data = binary:copy(<<16#dd>>, 50),
- Case3Exp = hexstr2bin("125d7342b9ac11cd91a39af48aa17b4f63f175d3"),
-
- ?line Case3Mac_1 = crypto:sha_mac(Case3Key, Case3Data),
- ?line Case3Mac_2 = crypto:hmac(sha, Case3Key, Case3Data),
- ?line m(Case3Exp, Case3Mac_1),
- ?line m(Case3Exp, Case3Mac_2),
-
- %% Test case 4
- Case4Key = list_to_binary(lists:seq(1, 16#19)),
- Case4Data = binary:copy(<<16#cd>>, 50),
- Case4Exp = hexstr2bin("4c9007f4026250c6bc8414f9bf50c86c2d7235da"),
-
- ?line Case4Mac_1 = crypto:sha_mac(Case4Key, Case4Data),
- ?line Case4Mac_2 = crypto:hmac(sha, Case4Key, Case4Data),
- ?line m(Case4Exp, Case4Mac_1),
- ?line m(Case4Exp, Case4Mac_2),
-
- %% Test case 5
- Case5Key = binary:copy(<<16#0c>>, 20),
- Case5Data = "Test With Truncation",
- Case5Exp = hexstr2bin("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04"),
- Case5Exp96 = hexstr2bin("4c1a03424b55e07fe7f27be1"),
-
- ?line Case5Mac_1 = crypto:sha_mac(Case5Key, Case5Data),
- ?line Case5Mac_2 = crypto:hmac(sha, Case5Key, Case5Data),
- ?line Case5Mac96_1 = crypto:sha_mac_96(Case5Key, Case5Data),
- ?line Case5Mac96_2 = crypto:hmac(sha, Case5Key, Case5Data, 12),
- ?line m(Case5Exp, Case5Mac_1),
- ?line m(Case5Exp, Case5Mac_2),
- ?line m(Case5Exp96, Case5Mac96_1),
- ?line m(Case5Exp96, Case5Mac96_2),
-
- %% Test case 6
- Case6Key = binary:copy(<<16#aa>>, 80),
- Case6Data = <<"Test Using Larger Than Block-Size Key - Hash Key First">>,
- Case6Exp = hexstr2bin("aa4ae5e15272d00e95705637ce8a3b55ed402112"),
-
- ?line Case6Mac_1 = crypto:sha_mac(Case6Key, Case6Data),
- ?line Case6Mac_2 = crypto:hmac(sha, Case6Key, Case6Data),
- ?line m(Case6Exp, Case6Mac_1),
- ?line m(Case6Exp, Case6Mac_2),
-
- %% Test case 7
- Case7Key = binary:copy(<<16#aa>>, 80),
- Case7Data = <<"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data">>,
- Case7Exp = hexstr2bin("e8e99d0f45237d786d6bbaa7965c7808bbff1a91"),
-
- ?line Case7Mac_1 = crypto:sha_mac(Case7Key, Case7Data),
- ?line Case7Mac_2 = crypto:hmac(sha, Case7Key, Case7Data),
- ?line m(Case7Exp, Case7Mac_1),
- ?line m(Case7Exp, Case7Mac_2).
-
-hmac_rfc4231_sha224(doc) ->
- ["Generate an HMAC using crypto:sha224_mac, hmac, and hmac_init, hmac_update, and hmac_final. "
- "Testvectors are take from RFC4231." ];
-hmac_rfc4231_sha224(suite) ->
- [];
-hmac_rfc4231_sha224(Config) when is_list(Config) ->
- if_supported(sha224, fun() -> hmac_rfc4231_sha224_do() end).
-
-hmac_rfc4231_sha256(doc) ->
- ["Generate an HMAC using crypto:sha256_mac, hmac, and hmac_init, hmac_update, and hmac_final. "
- "Testvectors are take from RFC4231." ];
-hmac_rfc4231_sha256(suite) ->
- [];
-hmac_rfc4231_sha256(Config) when is_list(Config) ->
- if_supported(sha256, fun() -> hmac_rfc4231_sha256_do() end).
-
-hmac_rfc4231_sha384(doc) ->
- ["Generate an HMAC using crypto:sha384_mac, hmac, and hmac_init, hmac_update, and hmac_final. "
- "Testvectors are take from RFC4231." ];
-hmac_rfc4231_sha384(suite) ->
- [];
-hmac_rfc4231_sha384(Config) when is_list(Config) ->
- if_supported(sha384, fun() -> hmac_rfc4231_sha384_do() end).
-
-hmac_rfc4231_sha512(doc) ->
- ["Generate an HMAC using crypto:sha512_mac, hmac, and hmac_init, hmac_update, and hmac_final. "
- "Testvectors are take from RFC4231." ];
-hmac_rfc4231_sha512(suite) ->
- [];
-hmac_rfc4231_sha512(Config) when is_list(Config) ->
- if_supported(sha512, fun() -> hmac_rfc4231_sha512_do() end).
-
-hmac_rfc4231_case(Hash, case1, Exp) ->
- %% Test 1
- Key = binary:copy(<<16#0b>>, 20),
- Data = <<"Hi There">>,
- hmac_rfc4231_case(Hash, Key, Data, Exp);
-
-hmac_rfc4231_case(Hash, case2, Exp) ->
- %% Test 2
- Key = <<"Jefe">>,
- Data = <<"what do ya want for nothing?">>,
- hmac_rfc4231_case(Hash, Key, Data, Exp);
-
-hmac_rfc4231_case(Hash, case3, Exp) ->
- %% Test 3
- Key = binary:copy(<<16#aa>>, 20),
- Data = binary:copy(<<16#dd>>, 50),
- hmac_rfc4231_case(Hash, Key, Data, Exp);
-
-hmac_rfc4231_case(Hash, case4, Exp) ->
- %% Test 4
- Key = list_to_binary(lists:seq(1, 16#19)),
- Data = binary:copy(<<16#cd>>, 50),
- hmac_rfc4231_case(Hash, Key, Data, Exp);
-
-hmac_rfc4231_case(Hash, case5, Exp) ->
- %% Test 5
- Key = binary:copy(<<16#0c>>, 20),
- Data = <<"Test With Truncation">>,
- hmac_rfc4231_case(Hash, Key, Data, 16, Exp);
-
-hmac_rfc4231_case(Hash, case6, Exp) ->
- %% Test 6
- Key = binary:copy(<<16#aa>>, 131),
- Data = <<"Test Using Larger Than Block-Size Key - Hash Key First">>,
- hmac_rfc4231_case(Hash, Key, Data, Exp);
-
-hmac_rfc4231_case(Hash, case7, Exp) ->
- %% Test Case 7
- Key = binary:copy(<<16#aa>>, 131),
- Data = <<"This is a test using a larger than block-size key and a larger t",
- "han block-size data. The key needs to be hashed before being use",
- "d by the HMAC algorithm.">>,
- hmac_rfc4231_case(Hash, Key, Data, Exp).
-
-hmac_rfc4231_case(Hash, Key, Data, Exp) ->
- ?line Ctx = crypto:hmac_init(Hash, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Mac1 = crypto:hmac_final(Ctx2),
- ?line Mac3 = crypto:hmac(Hash, Key, Data),
- ?line m(Exp, Mac1),
- ?line m(Exp, Mac3).
-
-hmac_rfc4231_case(Hash, Key, Data, Trunc, Exp) ->
- ?line Ctx = crypto:hmac_init(Hash, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Mac1 = crypto:hmac_final_n(Ctx2, Trunc),
- ?line Mac3 = crypto:hmac(Hash, Key, Data, Trunc),
- ?line m(Exp, Mac1),
- ?line m(Exp, Mac3).
-
-hmac_rfc4231_sha224_do() ->
- Case1 = hexstr2bin("896fb1128abbdf196832107cd49df33f"
- "47b4b1169912ba4f53684b22"),
- Case2 = hexstr2bin("a30e01098bc6dbbf45690f3a7e9e6d0f"
- "8bbea2a39e6148008fd05e44"),
- Case3 = hexstr2bin("7fb3cb3588c6c1f6ffa9694d7d6ad264"
- "9365b0c1f65d69d1ec8333ea"),
- Case4 = hexstr2bin("6c11506874013cac6a2abc1bb382627c"
- "ec6a90d86efc012de7afec5a"),
- Case5 = hexstr2bin("0e2aea68a90c8d37c988bcdb9fca6fa8"),
- Case6 = hexstr2bin("95e9a0db962095adaebe9b2d6f0dbce2"
- "d499f112f2d2b7273fa6870e"),
- Case7 = hexstr2bin("3a854166ac5d9f023f54d517d0b39dbd"
- "946770db9c2b95c9f6f565d1"),
- hmac_rfc4231_cases_do(sha224, [Case1, Case2, Case3, Case4, Case5, Case6, Case7]).
-
-hmac_rfc4231_sha256_do() ->
- Case1 = hexstr2bin("b0344c61d8db38535ca8afceaf0bf12b"
- "881dc200c9833da726e9376c2e32cff7"),
- Case2 = hexstr2bin("5bdcc146bf60754e6a042426089575c7"
- "5a003f089d2739839dec58b964ec3843"),
- Case3 = hexstr2bin("773ea91e36800e46854db8ebd09181a7"
- "2959098b3ef8c122d9635514ced565fe"),
- Case4 = hexstr2bin("82558a389a443c0ea4cc819899f2083a"
- "85f0faa3e578f8077a2e3ff46729665b"),
- Case5 = hexstr2bin("a3b6167473100ee06e0c796c2955552b"),
- Case6 = hexstr2bin("60e431591ee0b67f0d8a26aacbf5b77f"
- "8e0bc6213728c5140546040f0ee37f54"),
- Case7 = hexstr2bin("9b09ffa71b942fcb27635fbcd5b0e944"
- "bfdc63644f0713938a7f51535c3a35e2"),
- hmac_rfc4231_cases_do(sha256, [Case1, Case2, Case3, Case4, Case5, Case6, Case7]).
-
-hmac_rfc4231_sha384_do() ->
- Case1 = hexstr2bin("afd03944d84895626b0825f4ab46907f"
- "15f9dadbe4101ec682aa034c7cebc59c"
- "faea9ea9076ede7f4af152e8b2fa9cb6"),
- Case2 = hexstr2bin("af45d2e376484031617f78d2b58a6b1b"
- "9c7ef464f5a01b47e42ec3736322445e"
- "8e2240ca5e69e2c78b3239ecfab21649"),
- Case3 = hexstr2bin("88062608d3e6ad8a0aa2ace014c8a86f"
- "0aa635d947ac9febe83ef4e55966144b"
- "2a5ab39dc13814b94e3ab6e101a34f27"),
- Case4 = hexstr2bin("3e8a69b7783c25851933ab6290af6ca7"
- "7a9981480850009cc5577c6e1f573b4e"
- "6801dd23c4a7d679ccf8a386c674cffb"),
- Case5 = hexstr2bin("3abf34c3503b2a23a46efc619baef897"),
- Case6 = hexstr2bin("4ece084485813e9088d2c63a041bc5b4"
- "4f9ef1012a2b588f3cd11f05033ac4c6"
- "0c2ef6ab4030fe8296248df163f44952"),
- Case7 = hexstr2bin("6617178e941f020d351e2f254e8fd32c"
- "602420feb0b8fb9adccebb82461e99c5"
- "a678cc31e799176d3860e6110c46523e"),
- hmac_rfc4231_cases_do(sha384, [Case1, Case2, Case3, Case4, Case5, Case6, Case7]).
-
-hmac_rfc4231_sha512_do() ->
- Case1 = hexstr2bin("87aa7cdea5ef619d4ff0b4241a1d6cb0"
- "2379f4e2ce4ec2787ad0b30545e17cde"
- "daa833b7d6b8a702038b274eaea3f4e4"
- "be9d914eeb61f1702e696c203a126854"),
- Case2 = hexstr2bin("164b7a7bfcf819e2e395fbe73b56e0a3"
- "87bd64222e831fd610270cd7ea250554"
- "9758bf75c05a994a6d034f65f8f0e6fd"
- "caeab1a34d4a6b4b636e070a38bce737"),
- Case3 = hexstr2bin("fa73b0089d56a284efb0f0756c890be9"
- "b1b5dbdd8ee81a3655f83e33b2279d39"
- "bf3e848279a722c806b485a47e67c807"
- "b946a337bee8942674278859e13292fb"),
- Case4 = hexstr2bin("b0ba465637458c6990e5a8c5f61d4af7"
- "e576d97ff94b872de76f8050361ee3db"
- "a91ca5c11aa25eb4d679275cc5788063"
- "a5f19741120c4f2de2adebeb10a298dd"),
- Case5 = hexstr2bin("415fad6271580a531d4179bc891d87a6"),
- Case6 = hexstr2bin("80b24263c7c1a3ebb71493c1dd7be8b4"
- "9b46d1f41b4aeec1121b013783f8f352"
- "6b56d037e05f2598bd0fd2215d6a1e52"
- "95e64f73f63f0aec8b915a985d786598"),
- Case7 = hexstr2bin("e37b6a775dc87dbaa4dfa9f96e5e3ffd"
- "debd71f8867289865df5a32d20cdc944"
- "b6022cac3c4982b10d5eeb55c3e4de15"
- "134676fb6de0446065c97440fa8c6a58"),
- hmac_rfc4231_cases_do(sha512, [Case1, Case2, Case3, Case4, Case5, Case6, Case7]).
-
-hmac_rfc4231_cases_do(Hash, CasesData) ->
- hmac_rfc4231_cases_do(Hash, [case1, case2, case3, case4, case5, case6, case7], CasesData).
-
-hmac_rfc4231_cases_do(_Hash, _, []) ->
- ok;
-hmac_rfc4231_cases_do(Hash, [C|Cases], [D|CasesData]) ->
- hmac_rfc4231_case(Hash, C, D),
- hmac_rfc4231_cases_do(Hash, Cases, CasesData).
-
-hmac_update_md5_io(doc) ->
- ["Generate an MD5 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:md5_mac." ];
-hmac_update_md5_io(suite) ->
- [];
-hmac_update_md5_io(Config) when is_list(Config) ->
- ?line Key = ["A fine speach", "by a fine man!"],
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(md5, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final(Ctx3),
- ?line Exp = crypto:md5_mac(Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac).
-
-
-hmac_update_md5_n(doc) ->
- ["Generate a shortened MD5 HMAC using hmac_init, hmac_update, and hmac_final. "
- "Expected values for examples are generated using crypto:md5_mac." ];
-hmac_update_md5_n(suite) ->
- [];
-hmac_update_md5_n(Config) when is_list(Config) ->
- ?line Key = ["A fine speach", "by a fine man!"],
- ?line Data = "Sampl",
- ?line Data2 = "e #1",
- ?line Ctx = crypto:hmac_init(md5, Key),
- ?line Ctx2 = crypto:hmac_update(Ctx, Data),
- ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
- ?line Mac = crypto:hmac_final_n(Ctx3, 12),
- ?line Exp = crypto:md5_mac_96(Key, lists:flatten([Data, Data2])),
- ?line m(Exp, Mac).
-%%
-%%
-ripemd160(doc) ->
- ["Generate RIPEMD160 message digests and check the result."];
-ripemd160(suite) ->
- [];
-ripemd160(Config) when is_list(Config) ->
- ?line m(crypto:hash(ripemd160,"abc"),
- hexstr2bin("8EB208F7E05D987A9B044A8E98C6B087F15A0BFC")),
- ?line m(crypto:hash(ripemd160,"abcdbcdecdefdefgefghfghighijhijkijkljklmklm"
- "nlmnomnopnopq"),
- hexstr2bin("12A053384A9C0C88E405A06C27DCF49ADA62EB2B")).
-
-
-%%
-%%
-ripemd160_update(doc) ->
- ["Generate RIPEMD160 message digests by using ripemd160_init,"
- "ripemd160_update, and ripemd160_final and check the result."];
-ripemd160_update(suite) ->
- [];
-ripemd160_update(Config) when is_list(Config) ->
- ?line Ctx = crypto:hash_init(ripemd160),
- ?line Ctx1 = crypto:hash_update(Ctx, "abcdbcdecdefdefgefghfghighi"),
- ?line Ctx2 = crypto:hash_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"),
- ?line m(crypto:hash_final(Ctx2),
- hexstr2bin("12A053384A9C0C88E405A06C27DCF49ADA62EB2B")).
-
-%%
-%%
-sha_update(doc) ->
- ["Generate SHA message digests by using sha_init, sha_update, and"
- "sha_final, and check the result. Examples are from FIPS-180-1."];
-sha_update(suite) ->
- [];
-sha_update(Config) when is_list(Config) ->
- ?line Ctx = crypto:sha_init(),
- ?line Ctx1 = crypto:sha_update(Ctx, "abcdbcdecdefdefgefghfghighi"),
- ?line Ctx2 = crypto:sha_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"),
- ?line m(crypto:sha_final(Ctx2),
- hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")).
-
-%%
-%%
-sha256(doc) ->
- ["Generate SHA-256 message digests and check the result. Examples are "
- "from rfc-4634."];
-sha256(suite) ->
- [];
-sha256(Config) when is_list(Config) ->
- if_supported(sha256, fun() -> sha256_do() end).
-
-sha256_do() ->
- ?line m(crypto:hash(sha256, "abc"),
- hexstr2bin("BA7816BF8F01CFEA4141"
- "40DE5DAE2223B00361A396177A9CB410FF61F20015AD")),
- ?line m(crypto:hash(sha256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklm"
- "nlmnomnopnopq"),
- hexstr2bin("248D6A61D20638B8"
- "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")).
-
-%%
-%%
-sha256_update(doc) ->
- ["Generate SHA256 message digests by using sha256_init, sha256_update, and"
- "sha256_final, and check the result. Examples are from rfc-4634."];
-sha256_update(suite) ->
- [];
-sha256_update(Config) when is_list(Config) ->
- if_supported(sha256, fun() -> sha256_update_do() end).
-
-sha256_update_do() ->
- ?line Ctx = crypto:hash_init(sha256),
- ?line Ctx1 = crypto:hash_update(Ctx, "abcdbcdecdefdefgefghfghighi"),
- ?line Ctx2 = crypto:hash_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"),
- ?line m(crypto:hash_final(Ctx2),
- hexstr2bin("248D6A61D20638B8"
- "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")).
-
-
-%%
-%%
-sha512(doc) ->
- ["Generate SHA-512 message digests and check the result. Examples are "
- "from rfc-4634."];
-sha512(suite) ->
- [];
-sha512(Config) when is_list(Config) ->
- if_supported(sha512, fun() -> sha512_do() end).
-
-sha512_do() ->
- ?line m(crypto:hash(sha512, "abc"),
- hexstr2bin("DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2"
- "0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD"
- "454D4423643CE80E2A9AC94FA54CA49F")),
- ?line m(crypto:hash(sha512, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
- hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1"
- "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A"
- "C7D329EEB6DD26545E96E55B874BE909")).
-
-%%
-%%
-sha512_update(doc) ->
- ["Generate SHA512 message digests by using sha512_init, sha512_update, and"
- "sha512_final, and check the result. Examples are from rfc=4634."];
-sha512_update(suite) ->
- [];
-sha512_update(Config) when is_list(Config) ->
- if_supported(sha512, fun() -> sha512_update_do() end).
-
-sha512_update_do() ->
- ?line Ctx = crypto:hash_init(sha512),
- ?line Ctx1 = crypto:hash_update(Ctx, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"),
- ?line Ctx2 = crypto:hash_update(Ctx1, "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
- ?line m(crypto:hash_final(Ctx2),
- hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1"
- "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A"
- "C7D329EEB6DD26545E96E55B874BE909")).
-
-%%
-%%
-md5_mac(doc) ->
- ["Generate some HMACs, using MD5, and check the result. Examples are "
- "from RFC-2104."];
-md5_mac(suite) ->
- [];
-md5_mac(Config) when is_list(Config) ->
- ?line m(crypto:md5_mac(hexstr2bin("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"),
- "Hi There"),
- hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d")),
- ?line m(crypto:md5_mac(list_to_binary("Jefe"),
- "what do ya want for nothing?"),
- hexstr2bin("750c783e6ab0b503eaa86e310a5db738")),
- ?line m(crypto:md5_mac(hexstr2bin("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
- hexstr2bin("DDDDDDDDDDDDDDDDDDDD"
- "DDDDDDDDDDDDDDDDDDDD"
- "DDDDDDDDDDDDDDDDDDDD"
- "DDDDDDDDDDDDDDDDDDDD"
- "DDDDDDDDDDDDDDDDDDDD")),
- hexstr2bin("56be34521d144c88dbb8c733f0e8b3f6")).
-
-%%
-%%
-md5_mac_io(doc) ->
- ["Generate some HMACs, using MD5, with Key an IO-list, and check the "
- "result. Examples are from RFC-2104."];
-md5_mac_io(suite) ->
- [];
-md5_mac_io(Config) when is_list(Config) ->
- ?line Key1 = hexstr2bin("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"),
- ?line {B11, B12} = split_binary(Key1, 4),
- ?line Key11 = [B11,binary_to_list(B12)],
- ?line m(crypto:md5_mac(Key11, "Hi There"),
- hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d")).
-
-%%
-%%
-des_cbc(doc) ->
- "Encrypt and decrypt according to CBC DES. and check the result. "
- "Example are from FIPS-81.";
-des_cbc(suite) ->
- [];
-des_cbc(Config) when is_list(Config) ->
- if_supported(des_cbc, fun des_cbc_do/0).
-
-des_cbc_do() ->
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain = "Now is the time for all ",
- ?line Cipher = crypto:des_cbc_encrypt(Key, IVec, Plain),
- ?line m(Cipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c"
- "0f683788499a7c05f6")),
- ?line m(list_to_binary(Plain),
- crypto:des_cbc_decrypt(Key, IVec, Cipher)),
- ?line Plain2 = "7654321 Now is the time for " ++ [0, 0, 0, 0],
- ?line Cipher2 = crypto:des_cbc_encrypt(Key, IVec, Plain2),
- ?line m(Cipher2, hexstr2bin("b9916b8ee4c3da64b4f44e3cbefb9"
- "9484521388fa59ae67d58d2e77e86062733")),
- ?line m(list_to_binary(Plain2),
- crypto:des_cbc_decrypt(Key, IVec, Cipher2)).
-
-%%
-%%
-des_cbc_iter(doc) ->
- "Encrypt and decrypt according to CBC DES in two steps, and "
- "check the result. Example are from FIPS-81.";
-des_cbc_iter(suite) ->
- [];
-des_cbc_iter(Config) when is_list(Config) ->
- if_supported(des_cbc, fun des_cbc_iter_do/0).
-
-des_cbc_iter_do() ->
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain1 = "Now is the time ",
- ?line Plain2 = "for all ",
- ?line Cipher1 = crypto:des_cbc_encrypt(Key, IVec, Plain1),
- ?line IVec2 = crypto:des_cbc_ivec(Cipher1),
- ?line Cipher2 = crypto:des_cbc_encrypt(Key, IVec2, Plain2),
- ?line Cipher = list_to_binary([Cipher1, Cipher2]),
- ?line m(Cipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c"
- "0f683788499a7c05f6")).
-
-%%
-%%
-des_cfb(doc) ->
- "Encrypt and decrypt according to CFB DES. and check the result. "
- "Example is from FIPS-81.";
-des_cfb(suite) ->
- [];
-des_cfb(Config) when is_list(Config) ->
- if_supported(des_cfb, fun des_cfb_do/0).
-
-des_cfb_do() ->
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain = "Now is the",
- ?line Cipher = crypto:des_cfb_encrypt(Key, IVec, Plain),
- ?line m(Cipher, hexstr2bin("f31fda07011462ee187f")),
- ?line m(list_to_binary(Plain),
- crypto:des_cfb_decrypt(Key, IVec, Cipher)).
-
-%%
-%%
-des_cfb_iter(doc) ->
- "Encrypt and decrypt according to CFB DES in two steps, and "
- "check the result. Example is from FIPS-81.";
-des_cfb_iter(suite) ->
- [];
-des_cfb_iter(Config) when is_list(Config) ->
- if_supported(des_cfb, fun des_cfb_iter_do/0).
-
-des_cfb_iter_do() ->
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain1 = "Now i",
- ?line Plain2 = "s the",
- ?line Cipher1 = crypto:des_cfb_encrypt(Key, IVec, Plain1),
- ?line IVec2 = crypto:des_cfb_ivec(IVec, Cipher1),
- ?line Cipher2 = crypto:des_cfb_encrypt(Key, IVec2, Plain2),
- ?line Cipher = list_to_binary([Cipher1, Cipher2]),
- ?line m(Cipher, hexstr2bin("f31fda07011462ee187f")).
-
-%%
-%%
-des_ecb(doc) ->
- "Encrypt and decrypt according to ECB DES and check the result. "
- "Example are from FIPS-81.";
-des_ecb(suite) ->
- [];
-des_ecb(Config) when is_list(Config) ->
- if_supported(des_ecb, fun des_ecb_do/0).
-
-des_ecb_do() ->
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line Cipher1 = crypto:des_ecb_encrypt(Key, "Now is t"),
- ?line m(Cipher1, hexstr2bin("3fa40e8a984d4815")),
- ?line Cipher2 = crypto:des_ecb_encrypt(Key, "he time "),
- ?line m(Cipher2, hexstr2bin("6a271787ab8883f9")),
- ?line Cipher3 = crypto:des_ecb_encrypt(Key, "for all "),
- ?line m(Cipher3, hexstr2bin("893d51ec4b563b53")),
- ?line Cipher4 = crypto:des_ecb_decrypt(Key, hexstr2bin("3fa40e8a984d4815")),
- ?line m(Cipher4, <<"Now is t">>),
- ?line Cipher5 = crypto:des_ecb_decrypt(Key, hexstr2bin("6a271787ab8883f9")),
- ?line m(Cipher5, <<"he time ">>),
- ?line Cipher6 = crypto:des_ecb_decrypt(Key, hexstr2bin("893d51ec4b563b53")),
- ?line m(Cipher6, <<"for all ">>).
-%%
-%%
-rc2_cbc(doc) ->
- "Encrypt and decrypt according to RC2 CBC and check the result. "
- "Example stripped out from public_key application test";
-rc2_cbc(Config) when is_list(Config) ->
- if_supported(rc2_cbc, fun rc2_cbc_do/0).
-
-rc2_cbc_do() ->
- Key = <<146,210,160,124,215,227,153,239,227,17,222,140,3,93,27,191>>,
- IV = <<72,91,135,182,25,42,35,210>>,
-
- Cipher = <<36,245,206,158,168,230,58,69,148,137,32,192,250,41,237,181,181,251, 192,2,175,135,177,171,57,30,111,117,159,149,15,28,88,158,28,81,28,115, 85,219,241,82,117,222,91,85,73,117,164,25,182,52,191,64,123,57,26,19, 211,27,253,31,194,219,231,104,247,240,172,130,119,21,225,154,101,247, 32,216,42,216,133,169,78,22,97,27,227,26,196,224,172,168,17,9,148,55, 203,91,252,40,61,226,236,221,215,160,78,63,13,181,68,57,196,241,185, 207, 116,129,152,237,60,139,247,153,27,146,161,246,222,98,185,222,152, 187,135, 236,86,34,7,110,91,230,173,34,160,242,202,222,121,127,181,140, 101,203,195, 190,88,250,86,147,127,87,72,126,171,16,71,47,110,248,88, 14,29,143,161,152, 129,236,148,22,152,186,208,119,70,8,174,193,203,100, 193,203,200,117,102,242, 134,142,96,125,135,200,217,190,76,117,50,70, 209,186,101,241,200,91,40,193,54, 90,195,38,47,59,197,38,234,86,223,16, 51,253,204,129,20,171,66,21,241,26,135,216, 196,114,110,91,15,53,40, 164,201,136,113,95,247,51,181,208,241,68,168,98,151,36, 155,72,24,57, 42,191,14,125,204,10,167,214,233,138,115,125,234,121,134,227,26,247, 77,200,117,110,117,111,168,156,206,67,159,149,189,173,150,193,91,199, 216,153,22, 189,137,185,89,160,13,131,132,58,109,28,110,246,252,251,14, 232,91,38,52,29,101,188,69,123,50,0,130,178,93,73,239,118,7,77,35,59, 253,10,159,45,86,142,37,78,232,48>>,
- Text = <<48,130,1,85,2,1,0,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,4,130,1,63,48,130, 1,59,2,1,0,2,65,0,222,187,252,44,9,214,27,173,162,169,70,47,36,34,78,84,204, 107,60,192,117,95,21,206,49,142,245,126,121,223,23,2,107,106,133,204,161,36, 40,2,114,69,4,93,242,5,42,50,154,47,154,211,209,123,120,161,5,114,173,155,34, 191,52,59,2,3,1,0,1,2,64,45,144,169,106,220,236,71,39,67,82,123,192,35,21,61, 143,13,110,150,180,12,142,210,40,39,109,70,125,132,51,6,66,159,134,112,85, 155,243,118,221,65,133,127,99,151,194,252,141,149,224,229,62,214,45,228,32, 184,85,67,14,228,161,184,161,2,33,0,255,202,240,131,130,57,49,224,115,255,83, 79,6,165,212,21,179,212,20,188,97,74,69,68,163,223,247,237,39,24,23,235,2,33, 0,222,234,48,36,33,23,219,45,59,136,55,245,143,29,165,48,255,131,207,146,131, 104,13,163,54,131,236,78,88,54,16,241,2,33,0,230,2,99,129,173,176,166,131, 241,106,143,76,9,107,70,41,121,185,228,39,124,200,159,62,216,169,5,180,111, 169,255,159,2,33,0,151,193,70,212,209,210,179,219,175,83,165,4,255,81,103,76, 92,39,24,0,222,132,208,3,244,241,10,198,171,54,227,129,2,32,43,250,20,31,16, 189,168,116,225,1,125,132,94,130,118,124,28,56,232,39,69,218,244,33,240,200, 205,9,215,101,35,135,7,7,7,7,7,7,7>>,
-
- Text = crypto:rc2_cbc_decrypt(Key, IV, Cipher),
- Cipher = crypto:rc2_cbc_encrypt(Key, IV, Text).
-
-%%
-%%
-des3_cbc(doc) ->
- "Encrypt and decrypt according to CBC 3DES, and check the result.";
-des3_cbc(suite) ->
- [];
-des3_cbc(Config) when is_list(Config) ->
- if_supported(des3_cbc, fun des3_cbc_do/0).
-
-des3_cbc_do() ->
- ?line Key1 = hexstr2bin("0123456789abcdef"),
- ?line Key2 = hexstr2bin("fedcba9876543210"),
- ?line Key3 = hexstr2bin("0f2d4b6987a5c3e1"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain = "Now is the time for all ",
- ?line Cipher = crypto:des3_cbc_encrypt(Key1, Key2, Key3, IVec, Plain),
- ?line m(Cipher, hexstr2bin("8a2667ee5577267cd9b1af2c5a0480"
- "0bac1ae66970fb2b89")),
- ?line m(list_to_binary(Plain),
- crypto:des3_cbc_decrypt(Key1, Key2, Key3, IVec, Cipher)),
- ?line Plain2 = "7654321 Now is the time for " ++ [0, 0, 0, 0],
- ?line Cipher2 = crypto:des3_cbc_encrypt(Key1, Key2, Key3, IVec, Plain2),
- ?line m(Cipher2, hexstr2bin("eb33ec6ede2c8e90f6877e77b95d5"
- "4c83cee22907f7f0041ca1b7abe202bfafe")),
- ?line m(list_to_binary(Plain2),
- crypto:des3_cbc_decrypt(Key1, Key2, Key3, IVec, Cipher2)),
-
- ?line Key = hexstr2bin("0123456789abcdef"),
- ?line DESCipher = crypto:des3_cbc_encrypt(Key, Key, Key, IVec, Plain),
- ?line m(DESCipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c"
- "0f683788499a7c05f6")),
- ?line m(list_to_binary(Plain),
- crypto:des3_cbc_decrypt(Key, Key, Key, IVec, DESCipher)),
- ?line DESCipher2 = crypto:des3_cbc_encrypt(Key, Key, Key, IVec, Plain2),
- ?line m(DESCipher2, hexstr2bin("b9916b8ee4c3da64b4f44e3cbefb9"
- "9484521388fa59ae67d58d2e77e86062733")),
- ?line m(list_to_binary(Plain2),
- crypto:des3_cbc_decrypt(Key, Key, Key, IVec, DESCipher2)).
-
-%%
-%%
-des3_cbf(doc) ->
- "Encrypt and decrypt according to CFB 3DES, and check the result.";
-des3_cbf(suite) ->
- [];
-des3_cbf(Config) when is_list(Config) ->
- case openssl_version() of
- V when V < 16#90705F -> {skipped,"OpenSSL version too old"};
- _ ->
- if_supported(des3_cbf, fun des3_cfb_do/0)
- end.
-
-%%
-%%
-des3_cfb(doc) ->
- "Encrypt and decrypt according to CFB 3DES, and check the result.";
-des3_cfb(suite) ->
- [];
-des3_cfb(Config) when is_list(Config) ->
- case openssl_version() of
- V when V < 16#90705F -> {skipped,"OpenSSL version too old"};
- _ ->
- if_supported(des3_cfb, fun des3_cfb_do/0)
- end.
-
-des3_cfb_do() ->
- ?line Key1 = hexstr2bin("0123456789abcdef"),
- ?line Key2 = hexstr2bin("fedcba9876543210"),
- ?line Key3 = hexstr2bin("0f2d4b6987a5c3e1"),
- ?line IVec = hexstr2bin("1234567890abcdef"),
- ?line Plain = "Now is the time for all ",
- ?line Cipher = crypto:des3_cfb_encrypt(Key1, Key2, Key3, IVec, Plain),
- ?line m(Cipher, hexstr2bin("fc0ba7a20646ba53cc8bff263f0937"
- "1deab42a00666db02c")),
- ?line m(list_to_binary(Plain),
- crypto:des3_cfb_decrypt(Key1, Key2, Key3, IVec, Cipher)),
- ?line Plain2 = "7654321 Now is the time for " ++ [0, 0, 0, 0],
- ?line Cipher2 = crypto:des3_cfb_encrypt(Key1, Key2, Key3, IVec, Plain2),
- ?line m(Cipher2, hexstr2bin("8582c59ac01897422632c0accb66c"
- "e413f5efab838fce7e41e2ba67705bad5bc")),
- ?line m(list_to_binary(Plain2),
- crypto:des3_cfb_decrypt(Key1, Key2, Key3, IVec, Cipher2)).
-
-%%
-%%
-aes_cfb(doc) ->
- "Encrypt and decrypt according to AES CFB 128 bit and check "
- "the result. Example are from NIST SP 800-38A.";
-
-aes_cfb(suite) ->
- [];
-aes_cfb(Config) when is_list(Config) ->
-
-%% Sample data from NIST Spec.Publ. 800-38A
-%% F.3.13 CFB128-AES128.Encrypt
-%% Key 2b7e151628aed2a6abf7158809cf4f3c
-%% IV 000102030405060708090a0b0c0d0e0f
-%% Segment #1
-%% Input Block 000102030405060708090a0b0c0d0e0f
-%% Output Block 50fe67cc996d32b6da0937e99bafec60
-%% Plaintext 6bc1bee22e409f96e93d7e117393172a
-%% Ciphertext 3b3fd92eb72dad20333449f8e83cfb4a
-%% Segment #2
-%% Input Block 3b3fd92eb72dad20333449f8e83cfb4a
-%% Output Block 668bcf60beb005a35354a201dab36bda
-%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
-%% Ciphertext c8a64537a0b3a93fcde3cdad9f1ce58b
-%% Segment #3
-%% Input Block c8a64537a0b3a93fcde3cdad9f1ce58b
-%% Output Block 16bd032100975551547b4de89daea630
-%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
-%% Ciphertext 26751f67a3cbb140b1808cf187a4f4df
-%% Segment #4
-%% Input Block 26751f67a3cbb140b1808cf187a4f4df
-%% Output Block 36d42170a312871947ef8714799bc5f6
-%% Plaintext f69f2445df4f9b17ad2b417be66c3710
-%% Ciphertext c04b05357c5d1c0eeac4c66f9ff7f2e6
-
- ?line Key = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- ?line IVec = hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- ?line Plain = hexstr2bin("6bc1bee22e409f96e93d7e117393172a"),
- ?line Cipher = hexstr2bin("3b3fd92eb72dad20333449f8e83cfb4a"),
-
- %% Try all prefixes of plain and cipher.
- aes_cfb_do(byte_size(Plain), Plain, Cipher, Key, IVec).
-
-aes_cfb_do(N, Plain, Cipher, Key, IVec) when N >= 0 ->
- <<P:N/binary, _/binary>> = Plain,
- <<C:N/binary, _/binary>> = Cipher,
- ?line C = crypto:aes_cfb_128_encrypt(Key, IVec, P),
- ?line P = crypto:aes_cfb_128_decrypt(Key, IVec, C),
- aes_cfb_do(N-1, Plain, Cipher, Key, IVec);
-aes_cfb_do(_, _, _, _, _) -> ok.
-
-
-%%
-%%
-aes_cbc(doc) ->
- "Encrypt and decrypt according to AES CBC 128 bit. and check the result. "
- "Example are from NIST SP 800-38A.";
-
-aes_cbc(suite) ->
- [];
-aes_cbc(Config) when is_list(Config) ->
-
-%% Sample data from NIST Spec.Publ. 800-38A
-%% F.2.1 CBC-AES128.Encrypt
-%% Key 2b7e151628aed2a6abf7158809cf4f3c
-%% IV 000102030405060708090a0b0c0d0e0f
-%% Block #1
-%% Plaintext 6bc1bee22e409f96e93d7e117393172a
-%% Input Block 6bc0bce12a459991e134741a7f9e1925
-%% Output Block 7649abac8119b246cee98e9b12e9197d
-%% Ciphertext 7649abac8119b246cee98e9b12e9197d
-%% Block #2
-%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
-%% Input Block d86421fb9f1a1eda505ee1375746972c
-%% Output Block 5086cb9b507219ee95db113a917678b2
-%% Ciphertext 5086cb9b507219ee95db113a917678b2
-%% Block #3
-%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
-%% Input Block 604ed7ddf32efdff7020d0238b7c2a5d
-%% Output Block 73bed6b8e3c1743b7116e69e22229516
-%% Ciphertext 73bed6b8e3c1743b7116e69e22229516
-%% Block #4
-%% Plaintext f69f2445df4f9b17ad2b417be66c3710
-%% Input Block 8521f2fd3c8eef2cdc3da7e5c44ea206
-%% Output Block 3ff1caa1681fac09120eca307586e1a7
-%% Ciphertext 3ff1caa1681fac09120eca307586e1a7
-%%
-%% F.2.2 CBC-AES128.Decrypt
-%% Key 2b7e151628aed2a6abf7158809cf4f3c
-%% IV 000102030405060708090a0b0c0d0e0f
- %% Block #1
-%% Ciphertext 7649abac8119b246cee98e9b12e9197d
-%% Input Block 7649abac8119b246cee98e9b12e9197d
-%% Output Block 6bc0bce12a459991e134741a7f9e1925
-%% Plaintext 6bc1bee22e409f96e93d7e117393172a
-%% Block #2
-%% Ciphertext 5086cb9b507219ee95db113a917678b2
-%% Input Block 5086cb9b507219ee95db113a917678b2
-%% Output Block d86421fb9f1a1eda505ee1375746972c
-%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
-%% Block #3
-%% Ciphertext 73bed6b8e3c1743b7116e69e22229516
-%% Input Block 73bed6b8e3c1743b7116e69e22229516
-%% Output Block 604ed7ddf32efdff7020d0238b7c2a5d
-%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
-%% Block #4
-%% Ciphertext 3ff1caa1681fac09120eca307586e1a7
-%% Input Block 3ff1caa1681fac09120eca307586e1a7
-%% Output Block 8521f2fd3c8eef2cdc3da7e5c44ea206
-%% Plaintext f69f2445df4f9b17ad2b417be66c3710
-
- ?line Key = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
- ?line IVec = hexstr2bin("000102030405060708090a0b0c0d0e0f"),
- ?line Plain = hexstr2bin("6bc1bee22e409f96e93d7e117393172a"),
- ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Plain),
- ?line m(Cipher, hexstr2bin("7649abac8119b246cee98e9b12e9197d")),
- ?line m(Plain,
- crypto:aes_cbc_128_decrypt(Key, IVec, Cipher)).
-
-aes_cbc_iter(doc) ->
- "Encrypt and decrypt according to CBC AES in steps";
-aes_cbc_iter(suite) -> [];
-aes_cbc_iter(Config) when is_list(Config) ->
- Key = list_to_binary(lists:seq(255,256-16*17,-17)),
- IVec = list_to_binary(lists:seq(1,16*7,7)),
- Plain = <<"One, two, three o'clock, four o'clock, rock"
- "Five, six, seven o'clock, eight o'clock, rock"
- "Nine, ten, eleven o'clock, twelve o'clock, rock"
- "We're gonna rock around the clock tonight">>,
- ?line 0 = size(Plain) rem 16,
-
- ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Plain),
- ?line Plain = crypto:aes_cbc_128_decrypt(Key, IVec, Cipher),
-
- ?line Cipher = aes_cbc_encrypt_iter(Key,IVec,Plain,<<>>),
- ?line Plain = aes_cbc_decrypt_iter(Key,IVec,Cipher,<<>>),
- ok.
-
-aes_cbc_encrypt_iter(_,_,<<>>, Acc) ->
- Acc;
-aes_cbc_encrypt_iter(Key,IVec,Data, Acc) ->
- Bytes = 16 * (1 + size(Data) div (16*3)),
- <<Chunk:Bytes/binary, Rest/binary>> = Data,
- %%io:format("encrypt iter Chunk=~p Rest=~p\n",[Chunk,Rest]),
- ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Chunk),
- ?line IVec2 = crypto:aes_cbc_ivec(Cipher),
- aes_cbc_encrypt_iter(Key,IVec2,Rest, <<Acc/binary, Cipher/binary>>).
-
-aes_cbc_decrypt_iter(_,_,<<>>, Acc) ->
- Acc;
-aes_cbc_decrypt_iter(Key,IVec,Data, Acc) ->
- Bytes = 16 * (1 + size(Data) div (16*5)),
- <<Chunk:Bytes/binary, Rest/binary>> = Data,
- %%io:format("decrypt iter Chunk=~p Rest=~p\n",[Chunk,Rest]),
- ?line Plain = crypto:aes_cbc_128_decrypt(Key, IVec, Chunk),
- ?line IVec2 = crypto:aes_cbc_ivec(Chunk),
- aes_cbc_decrypt_iter(Key,IVec2,Rest, <<Acc/binary, Plain/binary>>).
-
-
-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)).
-
-aes_ctr_stream(doc) -> "CTR Streaming";
-aes_ctr_stream(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
- ["6bc1bee22e409f", "96e93d7e117393172a"], % Plaintext
- ["874d6191b620e3261bef6864990db6ce"]}, % Ciphertext
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- ["ae2d8a57", "1e03ac9c", "9eb76fac", "45af8e51"],
- ["9806f66b7970fdff","8617187bb9fffdff"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- ["30c81c46a35c", "e411e5fbc119", "1a0a52ef"],
- ["5ae4df3e","dbd5d3","5e5b4f0902","0db03eab"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
- ["f69f2445df4f9b17ad2b417be66c3710"],
- ["1e031dda2fbe","03d1792170a0","f3009cee"]}],
- lists:foreach(fun(S) -> aes_ctr_stream_do(Key128,S) end, Samples128),
-
- %% F.5.3 CTR-AES192.Encrypt
- Key192 = hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
- Samples192 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
- ["6bc1bee22e409f96e93d7e117393172a"], % Plaintext
- ["1abc9324","17521c","a24f2b04","59fe7e6e0b"]}, % Ciphertext
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- ["ae2d8a57", "1e03ac9c9eb76fac", "45af8e51"],
- ["090339ec0aa6faefd5ccc2c6f4ce8e94"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- ["30c81c46a35ce411", "e5fbc1191a0a52ef"],
- ["1e36b26bd1","ebc670d1bd1d","665620abf7"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
- ["f69f2445", "df4f9b17ad", "2b417be6", "6c3710"],
- ["4f78a7f6d2980958","5a97daec58c6b050"]}],
- lists:foreach(fun(S) -> aes_ctr_stream_do(Key192,S) end, Samples192),
-
- %% F.5.5 CTR-AES256.Encrypt
- Key256 = hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
- Samples256 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
- ["6bc1bee22e409f96", "e93d7e117393172a"], % Plaintext
- ["601ec313775789", "a5b7a7f504bbf3d228"]}, % Ciphertext
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
- ["ae2d8a571e03ac9c9eb76fac45af8e51"],
- ["f443e3ca","4d62b59aca84","e990cacaf5c5"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
- ["30c81c46","a35ce411","e5fbc119","1a0a52ef"],
- ["2b0930daa23de94ce87017ba2d84988d"]},
- {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
- ["f69f2445df4f","9b17ad2b41","7be66c3710"],
- ["dfc9c5","8db67aada6","13c2dd08","457941a6"]}],
- lists:foreach(fun(S) -> aes_ctr_stream_do(Key256,S) end, Samples256).
-
-
-aes_ctr_stream_do(Key,{IVec, PlainList, CipherList}) ->
- ?line I = hexstr2bin(IVec),
- ?line S = crypto:aes_ctr_stream_init(Key, I),
- ?line C = aes_ctr_stream_do_iter(
- S, PlainList, [],
- fun(S2,P) -> crypto:aes_ctr_stream_encrypt(S2, P) end),
- ?line m(C, hexstr2bin(lists:flatten(CipherList))),
- ?line P = aes_ctr_stream_do_iter(
- S, CipherList, [],
- fun(S2,C2) -> crypto:aes_ctr_stream_decrypt(S2, C2) end),
- ?line m(P, hexstr2bin(lists:flatten(PlainList))).
-
-aes_ctr_stream_do_iter(_State, [], Acc, _CipherFun) ->
- iolist_to_binary(lists:reverse(Acc));
-aes_ctr_stream_do_iter(State, [Plain|Rest], Acc, CipherFun) ->
- ?line P = hexstr2bin(Plain),
- ?line {S2, C} = CipherFun(State, P),
- aes_ctr_stream_do_iter(S2, Rest, [C | Acc], CipherFun).
-
-%%
-%%
-mod_exp_test(doc) ->
- "mod_exp testing (A ^ M % P with bignums)";
-mod_exp_test(suite) ->
- [];
-mod_exp_test(Config) when is_list(Config) ->
- mod_exp_aux_test(2, 5, 10, 8).
-
-mod_exp_aux_test(_, _, _, 0) ->
- ok;
-mod_exp_aux_test(B, E, M, N) ->
- ?line R1 = crypto:mod_exp(B, E, M),
- ?line R2 = ipow(B, E, M),
- ?line m(R1, R2),
- ?line mod_exp_aux_test(B, E*E+1, M*M+1, N-1).
-
-%%
-%%
-rand_uniform_test(doc) ->
- "rand_uniform and random_bytes testing";
-rand_uniform_test(suite) ->
- [];
-rand_uniform_test(Config) when is_list(Config) ->
- rand_uniform_aux_test(10),
- ?line 10 = size(crypto:rand_bytes(10)).
-
-rand_uniform_aux_test(0) ->
- ok;
-rand_uniform_aux_test(N) ->
- ?line L = N*1000,
- ?line H = N*100000+1,
- ?line crypto_rand_uniform(L, H),
- ?line crypto_rand_uniform(-L, L),
- ?line crypto_rand_uniform(-H, -L),
- ?line crypto_rand_uniform(-H, L),
- ?line rand_uniform_aux_test(N-1).
-
-crypto_rand_uniform(L,H) ->
- ?line R1 = crypto:rand_uniform(L, H),
- ?line t(R1 >= L),
- ?line t(R1 < H).
-
-
-%%
-%%
-strong_rand_test(doc) ->
- "strong_rand_mpint and strong_random_bytes testing";
-strong_rand_test(suite) ->
- [];
-strong_rand_test(Config) when is_list(Config) ->
- strong_rand_aux_test(180),
- ?line 10 = byte_size(crypto:strong_rand_bytes(10)).
-
-strong_rand_aux_test(0) ->
- ?line t(crypto:strong_rand_mpint(0,0,0) =:= <<0,0,0,0>>),
- ok;
-strong_rand_aux_test(1) ->
- ?line t(crypto:erlint(crypto:strong_rand_mpint(1,0,1)) =:= 1),
- ?line strong_rand_aux_test(0);
-strong_rand_aux_test(N) ->
- ?line t(sru_length(crypto:strong_rand_mpint(N,-1,0)) =< N),
- ?line t(sru_length(crypto:strong_rand_mpint(N,0,0)) =:= N),
- ?line t(crypto:erlint(crypto:strong_rand_mpint(N,0,1)) band 1 =:= 1),
- ?line t(crypto:erlint(crypto:strong_rand_mpint(N,1,0)) bsr (N - 2) =:= 2#11),
- ?line strong_rand_aux_test(N-1).
-
-sru_length(Mpint) ->
- I = crypto:erlint(Mpint),
- length(erlang:integer_to_list(I, 2)).
-
-%%
-%%
-%%
-%%
-rsa_verify_test(doc) ->
- "rsa_verify testing (A ^ M % P with bignums)";
-rsa_verify_test(suite) ->
- [];
-rsa_verify_test(Config) when is_list(Config) ->
- ?line H = <<178,28,54,104,36,80,144,66,140,201,135,17,36,97,114,124,
- 194,164,172,147>>,
- ?line SigBlob = <<153,44,121,71,132,1,192,159,78,33,29,62,153,64,191,70,
- 208,239,166,208,220,167,49,111,128,67,91,253,24,63,194,241,
- 97,157,135,226,121,162,150,156,60,49,236,90,151,67,239,23,
- 92,103,89,254,17,165,78,181,64,128,13,210,86,111,209,76,
- 115,34,107,227,151,47,80,185,143,85,202,55,245,163,226,26,
- 139,104,196,6,96,82,108,197,13,0,12,70,153,109,107,180,
- 130,246,156,182,56,96,31,220,227,218,136,211,252,43,8,14,
- 145,155,191,206,72,194,80,52,54,206,53,27,6,188,195,29>>,
- ?line BadSigBlob = <<153,44,121,71,132,1,192,159,78,33,29,62,153,64,191,70,
- 208,239,166,208,220,167,49,111,128,67,91,253,24,63,194,241,
- 97,157,135,226,121,162,150,156,60,49,236,90,151,67,239,23,
- 92,103,89,254,17,165,78,181,64,128,13,210,86,111,209,76,
- 115,107,34,227,151,47,80,185,143,85,202,55,245,163,226,26,
- 139,104,196,6,96,82,108,197,13,0,12,70,153,109,107,180,
- 130,246,156,182,56,96,31,220,227,218,136,211,252,43,8,14,
- 145,155,191,206,72,194,80,52,54,206,53,27,6,188,195,29>>,
- ?line E = <<35>>,
- ?line N = <<0,199,209,142,191,86,92,148,103,37,250,217,175,169,109,10,
- 130,139,34,237,174,90,97,118,7,185,57,137,252,236,177,193,
- 228,16,62,29,153,144,64,207,152,240,152,206,136,89,64,6,
- 3,187,89,57,241,219,88,215,75,70,120,20,145,229,37,1,
- 67,138,204,17,39,231,249,239,116,142,169,99,149,41,65,123,
- 26,225,133,0,41,85,77,181,35,100,162,223,92,220,207,50,
- 63,168,193,171,174,199,23,214,201,63,157,76,125,6,54,73,
- 76,89,40,33,147,208,189,76,98,24,61,8,10,110,165,119,165>>,
- ?line Nbad = <<0,199,209,142,191,86,92,148,103,37,250,217,175,169,109,10,
- 130,139,34,237,174,90,97,118,7,185,57,137,252,236,177,193,
- 228,16,62,29,153,144,64,207,152,240,152,206,136,89,64,6,
- 3,187,89,57,241,219,88,215,75,70,120,20,145,229,37,1,
- 67,138,204,17,39,231,249,239,116,142,169,99,149,41,65,123,
- 26,225,133,0,41,85,77,181,35,100,162,223,92,220,207,50,
- 63,168,193,171,174,199,23,214,201,63,157,76,125,6,54,73,
- 76,89,40,33,147,189,208,76,98,24,61,8,10,110,165,119,165>>,
- ?line Ebad = <<77>>,
- ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob),
- [sized_binary(E), sized_binary(N)]), true),
- ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob),
- [sized_binary(Ebad), sized_binary(N)]), false),
- ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob),
- [sized_binary(E), sized_binary(Nbad)]), false),
- ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(BadSigBlob),
- [sized_binary(E), sized_binary(N)]), false).
-
-%%
-%%
-dsa_verify_test(doc) ->
- "dsa_verify testing (A ^ M % P with bignums)";
-dsa_verify_test(suite) ->
- [];
-dsa_verify_test(Config) when is_list(Config) ->
- ?line Msg = <<48,130,2,245,160,3,2,1,2,2,1,1,48,9,6,7,42,134,72,206,56,4,3,48,
- 58,49,11,48,9,6,3,85,4,6,19,2,85,83,49,26,48,24,6,3,85,4,10,19,17,
- 84,101,115,116,32,67,101,114,116,105,102,105,99,97,116,101,115,49,
- 15,48,13,6,3,85,4,3,19,6,68,83,65,32,67,65,48,30,23,13,48,49,48,
- 52,49,57,49,52,53,55,50,48,90,23,13,49,49,48,52,49,57,49,52,53,55,
- 50,48,90,48,93,49,11,48,9,6,3,85,4,6,19,2,85,83,49,26,48,24,6,3,
- 85,4,10,19,17,84,101,115,116,32,67,101,114,116,105,102,105,99,97,
- 116,101,115,49,50,48,48,6,3,85,4,3,19,41,86,97,108,105,100,32,68,
- 83,65,32,83,105,103,110,97,116,117,114,101,115,32,69,69,32,67,101,
- 114,116,105,102,105,99,97,116,101,32,84,101,115,116,52,48,130,1,
- 182,48,130,1,43,6,7,42,134,72,206,56,4,1,48,130,1,30,2,129,129,0,
- 228,139,175,64,140,21,215,61,124,238,3,150,18,104,193,32,5,232,23,
- 202,158,116,101,75,154,84,151,42,120,51,218,165,197,114,234,52,
- 179,148,104,66,213,27,253,119,240,168,66,158,100,147,144,182,194,
- 2,49,70,19,122,3,105,204,152,45,86,157,94,35,95,40,191,173,127,15,
- 208,105,149,98,92,26,7,42,94,140,115,73,126,253,18,34,142,85,229,
- 86,233,174,114,41,150,135,8,39,215,119,67,240,134,184,9,10,27,20,
- 165,230,3,230,69,121,77,233,250,83,95,193,9,189,126,197,195,2,21,
- 0,128,63,228,252,243,76,229,62,203,15,23,10,42,84,108,208,103,108,
- 13,59,2,129,128,102,212,22,138,32,173,254,209,50,159,165,127,167,
- 179,208,234,119,63,235,108,162,228,41,216,216,188,33,221,154,247,
- 204,229,180,119,77,223,236,218,162,140,156,117,18,90,31,254,102,
- 211,17,194,239,132,67,236,169,136,110,76,186,76,63,53,150,199,103,
- 252,153,189,15,153,41,19,145,78,216,2,174,254,107,175,80,86,170,
- 47,30,181,42,200,238,34,71,37,120,107,33,221,20,63,206,240,16,129,
- 247,150,29,156,65,187,94,68,146,93,46,198,30,184,205,105,200,143,
- 63,59,62,208,79,162,206,217,3,129,132,0,2,129,128,15,83,40,172,56,
- 47,61,243,17,97,65,195,61,167,214,122,247,246,1,50,211,33,113,16,
- 20,213,195,62,77,235,25,162,140,175,158,8,61,65,10,255,204,162,71,
- 130,122,86,161,163,253,236,178,139,183,57,181,202,160,25,133,130,
- 155,150,104,168,187,107,186,144,164,225,173,101,182,68,49,210,30,
- 34,47,83,65,79,250,156,248,47,232,44,67,36,22,126,43,216,100,247,
- 100,250,240,121,72,29,185,2,109,144,54,204,235,54,15,242,57,171,
- 125,39,236,247,71,111,221,51,196,126,77,238,36,87,163,107,48,105,
- 48,29,6,3,85,29,14,4,22,4,20,179,51,215,81,162,4,13,68,251,157,64,
- 241,18,98,113,176,83,246,105,13,48,31,6,3,85,29,35,4,24,48,22,128,
- 20,116,21,213,36,28,189,94,101,136,31,225,139,9,126,127,234,25,72,
- 78,97,48,23,6,3,85,29,32,4,16,48,14,48,12,6,10,96,134,72,1,101,3,
- 2,1,48,1,48,14,6,3,85,29,15,1,1,255,4,4,3,2,6,192>>,
-
- ?line SigBlob = <<48,45,2,21,0,140,167,200,210,153,212,64,155,249,33,146,104,243,
- 39,38,9,115,162,89,24,2,20,76,254,31,128,187,48,128,215,216,
- 112,198,78,118,160,217,157,180,246,64,234>>,
- ?line P_p = 157224271412839155721795253728878055347359513988016145491388196653004661857517720927482198111104095793441029858267073789634147217022008635826863307553453131345099940951090826856271796188522037524757740796268675508118348391218066949174594918958269259937813776150149068811425194955973128428675945283593831134219,
- ?line Q_p = 1181895316321540581845959276009400765315408342791,
- ?line G_p = 143872196713149000950547166575757355261637863805587906227228163275557375159769599033632918292482002186641475268486598023281100659643528846513898847919251032731261718358900479488287933293278745715922865499005559197328388506945134386346185262919258658109015074718441639029135304654725637911172671711310801418648,
-
- ?line Key = 12603618348903387232593303690286336220738319446775939686476278478034365380027994899970214309288018488811754534229198764622077544117034174589418477472887827980332636062691833965078594576024299807057520016043084384987871640003684704483975314128362610573625803532737054022545217931847268776098203204571431581966,
-
- ValidKey = [crypto:mpint(P_p),
- crypto:mpint(Q_p),
- crypto:mpint(G_p),
- crypto:mpint(Key)
- ],
-
- ?line m(my_dss_verify(sized_binary(Msg), sized_binary(SigBlob),
- ValidKey), true),
-
- BadMsg = one_bit_wrong(Msg),
- ?line m(my_dss_verify(sized_binary(BadMsg), sized_binary(SigBlob),
- ValidKey), false),
- BadSig = one_bit_wrong(SigBlob),
- ?line m(my_dss_verify(sized_binary(Msg), sized_binary(BadSig),
- ValidKey), false),
- SizeErr = size(SigBlob) - 13,
-
- BadArg = (catch my_dss_verify(sized_binary(Msg), <<SizeErr:32, SigBlob/binary>>,
- ValidKey)),
- badarg = case element(1,element(2,BadArg)) of
- badarg -> badarg;
- function_clause -> badarg;
- X -> X
- end,
- InValidKey = [crypto:mpint(P_p),
- crypto:mpint(Q_p),
- crypto:mpint(G_p),
- crypto:mpint(Key+17)
- ],
-
- ?line m(my_dss_verify(sized_binary(Msg), sized_binary(SigBlob),
- InValidKey), false).
-
-
-one_bit_wrong(List) when is_list(List) ->
- lists:map(fun(Bin) -> one_bit_wrong(Bin) end, List);
-one_bit_wrong(Bin) ->
- Half = size(Bin) div 2,
- <<First:Half/binary, Byte:8, Last/binary>> = Bin,
- <<First/binary, (Byte+1):8, Last/binary>>.
-
-
-%%
-%% Sign tests
-
-rsa_sign_test(doc) ->
- "rsa_sign testing";
-rsa_sign_test(suite) ->
- [];
-rsa_sign_test(Config) when is_list(Config) ->
- PubEx = 65537,
- PrivEx = 7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945,
- Mod = 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123,
- Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
- "09812312908312378623487263487623412039812 huagasd">>,
-
- PrivKey = [PubEx, Mod, PrivEx],
- PubKey = [PubEx, Mod],
- PubKeyMpint = map_int_to_mpint(PubKey),
- Sig1 = crypto:rsa_sign(sized_binary(Msg), map_int_to_mpint(PrivKey)),
- Sig1 = crypto:sign(rsa, sha, Msg, PrivKey),
- true = crypto:rsa_verify(sized_binary(Msg), sized_binary(Sig1), PubKeyMpint),
- true = crypto:verify(rsa, sha, Msg, Sig1, PubKey),
-
- Sig2 = crypto:rsa_sign(md5, sized_binary(Msg), map_int_to_mpint(PrivKey)),
- Sig2 = crypto:sign(rsa, md5, Msg, PrivKey),
- true = crypto:rsa_verify(md5, sized_binary(Msg), sized_binary(Sig2), PubKeyMpint),
- true = crypto:verify(rsa, md5, Msg, Sig2, PubKey),
-
- false = (Sig1 =:= Sig2),
- false = crypto:rsa_verify(md5, sized_binary(Msg), sized_binary(Sig1), PubKeyMpint),
- false = crypto:verify(rsa, md5, Msg, Sig1, PubKey),
- true = crypto:rsa_verify(sha, sized_binary(Msg), sized_binary(Sig1), PubKeyMpint),
- true = crypto:verify(rsa, sha, Msg, Sig1, PubKey),
-
- ok.
-map_int_to_mpint(List) ->
- lists:map(fun(E) -> crypto:mpint(E) end, List).
-
-rsa_sign_hash_test(doc) ->
- "rsa_sign_hash testing";
-rsa_sign_hash_test(suite) ->
- [];
-rsa_sign_hash_test(Config) when is_list(Config) ->
- PubEx = 65537,
- PrivEx = 7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945,
- Mod = 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123,
- Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
- "09812312908312378623487263487623412039812 huagasd">>,
-
- PrivKey = [crypto:mpint(PubEx), crypto:mpint(Mod), crypto:mpint(PrivEx)],
- PubKey = [crypto:mpint(PubEx), crypto:mpint(Mod)],
- MD5 = crypto:md5(sized_binary(Msg)),
- SHA = crypto:sha(sized_binary(Msg)),
- ?line Sig1 = crypto:rsa_sign(sha, {digest,SHA}, PrivKey),
- ?line m(crypto:rsa_verify(sha, {digest,SHA}, sized_binary(Sig1),PubKey), true),
-
- ?line Sig2 = crypto:rsa_sign(md5, {digest,MD5}, PrivKey),
- ?line m(crypto:rsa_verify(md5, {digest,MD5}, sized_binary(Sig2),PubKey), true),
-
- ?line m(Sig1 =:= Sig2, false),
- ?line m(crypto:rsa_verify(md5, {digest,MD5}, sized_binary(Sig1),PubKey), false),
- ?line m(crypto:rsa_verify(sha, {digest,SHA}, sized_binary(Sig2),PubKey), false),
-
- ok.
-
-dsa_sign_test(doc) ->
- "dsa_sign testing";
-dsa_sign_test(suite) ->
- [];
-dsa_sign_test(Config) when is_list(Config) ->
- Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
- "09812312908312378623487263487623412039812 huagasd">>,
-
- PubKey = _Y = 25854665488880835237281628794585130313500176551981812527054397586638455298000483144002221850980183404910190346416063318160497344811383498859129095184158800144312512447497510551471331451396405348497845813002058423110442376886564659959543650802132345311573634832461635601376738282831340827591903548964194832978,
- PrivKey = _X = 441502407453038284293378221372000880210588566361,
- ParamP = 109799869232806890760655301608454668257695818999841877165019612946154359052535682480084145133201304812979481136659521529774182959764860329095546511521488413513097576425638476458000255392402120367876345280670101492199681798674053929238558140260669578407351853803102625390950534052428162468100618240968893110797,
- ParamQ = 1349199015905534965792122312016505075413456283393,
- ParamG = 18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669,
-
- Params = [crypto:mpint(ParamP), crypto:mpint(ParamQ), crypto:mpint(ParamG)],
- ?line Sig1 = my_dss_sign(sized_binary(Msg), Params ++ [crypto:mpint(PrivKey)]),
-
- ?line m(my_dss_verify(sized_binary(Msg), Sig1,
- Params ++ [crypto:mpint(PubKey)]), true),
-
- ?line m(my_dss_verify(sized_binary(one_bit_wrong(Msg)), Sig1,
- Params ++ [crypto:mpint(PubKey)]), false),
-
- ?line m(my_dss_verify(sized_binary(Msg), one_bit_wrong(Sig1),
- Params ++ [crypto:mpint(PubKey)]), false),
-
- %%?line Bad = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PubKey)]),
-
- ok.
-
-dsa_sign_hash_test(doc) ->
- "dsa_sign_hash testing";
-dsa_sign_hash_test(suite) ->
- [];
-dsa_sign_hash_test(Config) when is_list(Config) ->
- Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
- "09812312908312378623487263487623412039812 huagasd">>,
- SHA = crypto:sha(sized_binary(Msg)),
-
- PubKey = _Y = 25854665488880835237281628794585130313500176551981812527054397586638455298000483144002221850980183404910190346416063318160497344811383498859129095184158800144312512447497510551471331451396405348497845813002058423110442376886564659959543650802132345311573634832461635601376738282831340827591903548964194832978,
- PrivKey = _X = 441502407453038284293378221372000880210588566361,
- ParamP = 109799869232806890760655301608454668257695818999841877165019612946154359052535682480084145133201304812979481136659521529774182959764860329095546511521488413513097576425638476458000255392402120367876345280670101492199681798674053929238558140260669578407351853803102625390950534052428162468100618240968893110797,
- ParamQ = 1349199015905534965792122312016505075413456283393,
- ParamG = 18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669,
-
- Params = [crypto:mpint(ParamP), crypto:mpint(ParamQ), crypto:mpint(ParamG)],
- ?line Sig1 = crypto:dss_sign(sha, {digest,SHA}, Params ++ [crypto:mpint(PrivKey)]),
-
- ?line m(crypto:dss_verify(none, SHA, sized_binary(Sig1),
- Params ++ [crypto:mpint(PubKey)]), true),
-
- ?line m(crypto:dss_verify(sized_binary(one_bit_wrong(Msg)), sized_binary(Sig1),
- Params ++ [crypto:mpint(PubKey)]), false),
-
- ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(one_bit_wrong(Sig1)),
- Params ++ [crypto:mpint(PubKey)]), false),
-
- %%?line Bad = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PubKey)]),
-
- ok.
-
-
-rsa_encrypt_decrypt(doc) ->
- ["Test rsa_public_encrypt and rsa_private_decrypt functions."];
-rsa_encrypt_decrypt(suite) -> [];
-rsa_encrypt_decrypt(Config) when is_list(Config) ->
- PubEx = 65537,
- PrivEx = 7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945,
- Mod = 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123,
-
- PrivKey = [PubEx, Mod, PrivEx],
- PubKey = [PubEx, Mod],
-
- Msg = <<"7896345786348 Asldi">>,
-
- ?line PKCS1 = rsa_public_encrypt(Msg, PubKey, rsa_pkcs1_padding),
- ?line PKCS1Dec = rsa_private_decrypt(PKCS1, PrivKey, rsa_pkcs1_padding),
- io:format("PKCS1Dec ~p~n",[PKCS1Dec]),
- ?line Msg = PKCS1Dec,
-
- ?line OAEP = rsa_public_encrypt(Msg, PubKey, rsa_pkcs1_oaep_padding),
- ?line Msg = rsa_private_decrypt(OAEP, PrivKey, rsa_pkcs1_oaep_padding),
-
- <<Msg2Len:32,_/binary>> = crypto:mpint(Mod),
- Msg2 = list_to_binary(lists:duplicate(Msg2Len-1, $X)),
- ?line NoPad = rsa_public_encrypt(Msg2, PubKey, rsa_no_padding),
- ?line NoPadDec = rsa_private_decrypt(NoPad, PrivKey, rsa_no_padding),
- ?line NoPadDec = Msg2,
-
- ShouldBeError = (catch rsa_public_encrypt(Msg, PubKey, rsa_no_padding)),
- ?line {'EXIT', {encrypt_failed,_}} = ShouldBeError,
-
-%% ?line SSL = rsa_public_encrypt(Msg, PubKey, rsa_sslv23_padding),
-%% ?line Msg = rsa_private_decrypt(SSL, PrivKey, rsa_sslv23_padding),
-
- ?line PKCS1_2 = rsa_private_encrypt(Msg, PrivKey, rsa_pkcs1_padding),
- ?line PKCS1_2Dec = rsa_public_decrypt(PKCS1_2, PubKey, rsa_pkcs1_padding),
- io:format("PKCS2Dec ~p~n",[PKCS1_2Dec]),
- ?line Msg = PKCS1_2Dec,
-
- ?line PKCS1_3 = rsa_private_encrypt(Msg2, PrivKey, rsa_no_padding),
- ?line PKCS1_3Dec = rsa_public_decrypt(PKCS1_3, PubKey, rsa_no_padding),
- io:format("PKCS2Dec ~p~n",[PKCS1_3Dec]),
- ?line Msg2 = PKCS1_3Dec,
-
- ?line {'EXIT', {encrypt_failed,_}} =
- (catch rsa_private_encrypt(Msg, PrivKey, rsa_no_padding)),
-
- ok.
-
-rsa_public_encrypt(Msg, Key, Pad) ->
- C1 = crypto:rsa_public_encrypt(Msg, Key, Pad),
- C2 = crypto:rsa_public_encrypt(Msg, lists:map(fun(E) -> crypto:mpint(E) end, Key), Pad),
- {C1,C2}.
-
-rsa_public_decrypt(Msg, Key, Pad) ->
- R = crypto:rsa_public_decrypt(Msg, Key, Pad),
- R = crypto:rsa_public_decrypt(Msg, lists:map(fun(E) -> crypto:mpint(E) end, Key), Pad).
-
-rsa_private_encrypt(Msg, Key, Pad) ->
- R = crypto:rsa_private_encrypt(Msg, Key, Pad),
- R = crypto:rsa_private_encrypt(Msg, lists:map(fun(E) -> crypto:mpint(E) end, Key), Pad).
-
-rsa_private_decrypt({C1,C2}, Key, Pad) ->
- R = crypto:rsa_private_decrypt(C1, Key, Pad),
- R = crypto:rsa_private_decrypt(C2, Key, Pad),
- R = crypto:rsa_private_decrypt(C1, lists:map(fun(E) -> crypto:mpint(E) end, Key), Pad),
- R = crypto:rsa_private_decrypt(C2, lists:map(fun(E) -> crypto:mpint(E) end, Key), Pad).
-
-
-dh(doc) ->
- ["Test dh (Diffie-Hellman) functions."];
-dh(suite) -> [];
-dh(Config) when is_list(Config) ->
- Self = self(),
- GenP = fun() ->
- %% Gen Param may take arbitrary long time to finish
- %% That's not a bug in erlang crypto application.
- ?line DHPs = crypto:dh_generate_parameters(512,2),
- ?line ok = crypto:dh_check(DHPs),
- Self ! {param, DHPs}
- end,
- Pid = spawn(GenP),
- receive
- {param, DHPs} ->
- timer:sleep(100),
- io:format("DHP ~p~n", [DHPs]),
- DHPs_mpint = lists:map(fun(E) -> sized_binary(E) end, DHPs),
- ?line {Pub1,Priv1} = crypto:generate_key(dh, DHPs),
- io:format("Key1:~n~p~n~p~n~n", [Pub1,Priv1]),
- ?line {Pub2,Priv2} = crypto:dh_generate_key(DHPs_mpint),
- io:format("Key2:~n~p~n~p~n~n", [Pub2,Priv2]),
- ?line A = crypto:compute_key(dh, Pub1, unsized_binary(Priv2), DHPs),
- ?line A = crypto:dh_compute_key(sized_binary(Pub1), Priv2, DHPs_mpint),
- timer:sleep(100), %% Get another thread see if that triggers problem
- ?line B = crypto:compute_key(dh, unsized_binary(Pub2), Priv1, DHPs),
- ?line B = crypto:dh_compute_key(Pub2, sized_binary(Priv1), DHPs_mpint),
- io:format("A ~p~n",[A]),
- io:format("B ~p~n",[B]),
- ?line A = B
- after 50000 ->
- io:format("Killing Param generation which took to long ~p~n",[Pid]),
- exit(Pid, kill)
- end.
-
-
-ec(doc) ->
- ["Test ec (Ecliptic Curve) functions."];
-ec(suite) -> [];
-ec(Config) when is_list(Config) ->
- if_supported(ecdh, fun() -> ec_do() end).
-
-ec_do() ->
- %% test for a name curve
- NamedCurve = hd(crypto:ec_curves()),
- {D2_pub, D2_priv} = crypto:generate_key(ecdh, NamedCurve),
- PrivECDH = [D2_priv, NamedCurve],
- PubECDH = [D2_pub, NamedCurve],
- %%TODO: find a published test case for a EC key
-
- Msg = <<99,234,6,64,190,237,201,99,80,248,58,40,70,45,149,218,5,246,242,63>>,
- Sign = crypto:sign(ecdsa, sha, Msg, PrivECDH),
- ?line true = crypto:verify(ecdsa, sha, Msg, Sign, PubECDH),
- ?line false = crypto:verify(ecdsa, sha, Msg, <<10,20>>, PubECDH),
-
- ok.
-
-srp3(doc) ->
- ["SRP-3 test vectors generated by http://srp.stanford.edu/demo/demo.html"];
-srp3(suite) -> [];
-srp3(Config) when is_list(Config) ->
- Username = <<"alice">>,
- Password = <<"password123">>,
- Salt = hexstr2bin("2857827A19266A1F2BC6"),
- Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
- "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
- "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
- "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
- "FD5138FE8376435B9FC61D2FC0EB06E3"),
- Generator = <<2>>,
- Version = '3',
- Scrambler = hexstr2bin("02E2476A"),
-
- %% X = hexstr2bin("96E54AB0CD4C5123EDCFA4A1502918AAD3C9E2A8"),
- Verifier = hexstr2bin("96EB5F13621D911AA1CA405DE9C64217D4108EEEECAFFE500034FE0E"
- "C031E42C8714667C161BCE0E7996F7DDE1B63824C130D2D7286C08C0"
- "49758420735961347112AE102A3F23B3F687F8FEE0DF2BFAF933C608"
- "D6FE5B5EEE3116FE54016E065BF8E8C9FDBBC08719231AC215149140"
- "519E8FDD9AA4F410C28A58AF42974D2D"),
- ClientPrivate = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
- "49C75C7B"),
- ServerPrivate = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
- "9AADCF8B"),
- ClientPublic = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
- "55C79E7A118865DC59B9D0353362C2A8261E7C1B0D221A0E233C2AD1"
- "640DACBB8664CBC9733EAC392DA7800142860380C3FC573C3C064329"
- "CF54063FD114C7210E9CB3A611EA8002B1844B698F930D95D143899B"
- "948A090E0C25938E5F84067D1883DC63"),
- ServerPublic = hexstr2bin("93A8C4D8B7F7395ADCFD4ABA37B015124513D3F37B3E85EB23064BE5"
- "F53C0AE32FFB9D8C0AA0DCFFA74D632DD67DEBB5C35AAE9812286CC8"
- "C43CC176ECBC6D3F447594D9554E995B2509127BF88FADDDA4982D03"
- "8EC3001320712D3B1269308CE70F319B2295FA57674F03A2D993CFB1"
- "F84C35B7D0C012FA73CD4C8F7D5A71C7"),
-
- SessionKey = hexstr2bin("C29A986C4D521BBC66428ED11D994CD7431574A6184B83CDCC345092"
- "791E75748A1D38CAC4BD14760F0D2694B711236419240FF2F172454C"
- "46ABF4FF39498DAFDD2C82924F7D7BD76CDFCE688C77D93F18A65409"
- "9176A9192615DC0277AE7C12F1F6A7F6563FCA11675D809AF578BDE5"
- "2B51E05D440B63099A017A0B45044801"),
- UserPassHash = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
- Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
- ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
-
- {ClientPublic, ClientPrivate} = crypto:generate_key(srp, {user, [Generator, Prime, Version]}, ClientPrivate),
- {ServerPublic, ServerPrivate} = crypto:generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, ServerPrivate),
- SessionKey = crypto:compute_key(srp, ServerPublic, {ClientPublic, ClientPrivate},
- {user, [UserPassHash, Prime, Generator, Version, Scrambler]}),
- SessionKey = crypto:compute_key(srp, ClientPublic, {ServerPublic, ServerPrivate},
- {host, [Verifier, Prime, Version, Scrambler]}).
-
-srp6(doc) ->
- ["SRP-6 test vectors generated by http://srp.stanford.edu/demo/demo.html"];
-srp6(suite) -> [];
-srp6(Config) when is_list(Config) ->
- Username = <<"alice">>,
- Password = <<"password123">>,
- Salt = hexstr2bin("2857827A19266A1F2BC6"),
- Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
- "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
- "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
- "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
- "FD5138FE8376435B9FC61D2FC0EB06E3"),
- Generator = <<2>>,
- Version = '6',
- Scrambler = hexstr2bin("0A2534C0BF52A0DA9001EEC62CF2A546AB0908A7"),
- Verifier = hexstr2bin("96EB5F13621D911AA1CA405DE9C64217D4108EEEECAFFE500034FE0E"
- "C031E42C8714667C161BCE0E7996F7DDE1B63824C130D2D7286C08C0"
- "49758420735961347112AE102A3F23B3F687F8FEE0DF2BFAF933C608"
- "D6FE5B5EEE3116FE54016E065BF8E8C9FDBBC08719231AC215149140"
- "519E8FDD9AA4F410C28A58AF42974D2D"),
- ClientPrivate = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
- "49C75C7B"),
- ServerPrivate = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
- "9AADCF8B"),
- ClientPublic = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
- "55C79E7A118865DC59B9D0353362C2A8261E7C1B0D221A0E233C2AD1"
- "640DACBB8664CBC9733EAC392DA7800142860380C3FC573C3C064329"
- "CF54063FD114C7210E9CB3A611EA8002B1844B698F930D95D143899B"
- "948A090E0C25938E5F84067D1883DC63"),
- ServerPublic = hexstr2bin("D2D07845CE7ECDB9845DD36B10ACD3598CC29049DE9F467F84CE16B6"
- "D97A6DC567AF8B0F9FEDF74962400AD5C357951E64E67B641246F264"
- "C8DE6D9A72E554D6C8D3194548780A0C438A0FCC509CA88A14AA1DEB"
- "C0F09E4B37A965D1545DB4AD361346F3189B0EA569C06D326C4E4797"
- "9E381C748293B7C0591BE0BE419E053E"),
-
- SessionKey = hexstr2bin("19D22C19612874EBF1F2581F8EFCFDC44C6FDA3B87B0A73823D7E962"
- "554295D4E48D3A336523ADBDDD0EC8FB0F02687109E97E01C17C93CC"
- "7216F9CD8A4AC39F0429857D8D1023066614BDFCBCB89F59A0FEB81C"
- "72E992AAD89095A84B6A5FADA152369AB1E350A03693BEF044DF3EDF"
- "0C34741F4696C30E9F675D09F58ACBEB"),
- UserPassHash = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
- Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
- ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
-
- {ClientPublic, ClientPrivate} = crypto:generate_key(srp, {user, [Generator, Prime, Version]}, ClientPrivate),
- {ServerPublic, ServerPrivate} = crypto:generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, ServerPrivate),
- SessionKey = crypto:compute_key(srp, ServerPublic, {ClientPublic, ClientPrivate},
- {user, [UserPassHash, Prime, Generator, Version, Scrambler]}),
- SessionKey = crypto:compute_key(srp, ClientPublic, {ServerPublic, ServerPrivate},
- {host, [Verifier, Prime, Version, Scrambler]}).
-
-srp6a(doc) ->
- ["SRP-6a test vectors from RFC5054."];
-srp6a(suite) -> [];
-srp6a(Config) when is_list(Config) ->
- Username = <<"alice">>,
- Password = <<"password123">>,
- Salt = hexstr2bin("BEB25379D1A8581EB5A727673A2441EE"),
- Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
- "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
- "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
- "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
- "FD5138FE8376435B9FC61D2FC0EB06E3"),
- Generator = <<2>>,
- Version = '6a',
- Scrambler = hexstr2bin("CE38B9593487DA98554ED47D70A7AE5F462EF019"),
- Verifier = hexstr2bin("7E273DE8696FFC4F4E337D05B4B375BEB0DDE1569E8FA00A9886D812"
- "9BADA1F1822223CA1A605B530E379BA4729FDC59F105B4787E5186F5"
- "C671085A1447B52A48CF1970B4FB6F8400BBF4CEBFBB168152E08AB5"
- "EA53D15C1AFF87B2B9DA6E04E058AD51CC72BFC9033B564E26480D78"
- "E955A5E29E7AB245DB2BE315E2099AFB"),
- ClientPrivate = hexstr2bin("60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DD"
- "DA2D4393"),
- ServerPrivate = hexstr2bin("E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D1"
- "05284D20"),
- ClientPublic = hexstr2bin("61D5E490F6F1B79547B0704C436F523DD0E560F0C64115BB72557EC4"
- "4352E8903211C04692272D8B2D1A5358A2CF1B6E0BFCF99F921530EC"
- "8E39356179EAE45E42BA92AEACED825171E1E8B9AF6D9C03E1327F44"
- "BE087EF06530E69F66615261EEF54073CA11CF5858F0EDFDFE15EFEA"
- "B349EF5D76988A3672FAC47B0769447B"),
- ServerPublic = hexstr2bin("BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011"
- "BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC99"
- "6C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA"
- "37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAE"
- "EB4012B7D7665238A8E3FB004B117B58"),
-
- SessionKey = hexstr2bin("B0DC82BABCF30674AE450C0287745E7990A3381F63B387AAF271A10D"
- "233861E359B48220F7C4693C9AE12B0A6F67809F0876E2D013800D6C"
- "41BB59B6D5979B5C00A172B4A2A5903A0BDCAF8A709585EB2AFAFA8F"
- "3499B200210DCC1F10EB33943CD67FC88A2F39A4BE5BEC4EC0A3212D"
- "C346D7E474B29EDE8A469FFECA686E5A"),
- UserPassHash = crypto:sha([Salt, crypto:sha([Username, <<$:>>, Password])]),
- Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
-
- {ClientPublic, ClientPrivate} = crypto:generate_key(srp, {user, [Generator, Prime, Version]}, ClientPrivate),
- {ServerPublic, ServerPrivate} = crypto:generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, ServerPrivate),
-
- SessionKey = crypto:compute_key(srp, ServerPublic, {ClientPublic, ClientPrivate},
- {user, [UserPassHash, Prime, Generator, Version, Scrambler]}),
- SessionKey = crypto:compute_key(srp, ClientPublic, {ServerPublic, ServerPrivate},
- {host, [Verifier, Prime, Version, Scrambler]}).
-
-%%
-%%
-exor_test(doc) ->
- ["Test the exor function."];
-exor_test(suite) ->
- [];
-exor_test(Config) when is_list(Config) ->
- B = <<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>,
- Z1 = zero_bin(B),
- Z1 = crypto:exor(B, B),
- B1 = crypto:strong_rand_bytes(100),
- B2 = crypto:strong_rand_bytes(100),
- Z2 = zero_bin(B1),
- Z2 = crypto:exor(B1, B1),
- Z2 = crypto:exor(B2, B2),
- R = xor_bytes(B1, B2),
- R = crypto:exor(B1, B2),
- ok.
-
-%%
-%%
-rc4_test(doc) ->
- ["Test rc4 encryption ."];
-rc4_test(suite) ->
- [];
-rc4_test(Config) when is_list(Config) ->
- if_supported(rc4, fun rc4_test_do/0).
-
-rc4_test_do() ->
- CT1 = <<"Yo baby yo">>,
- R1 = <<118,122,68,110,157,166,141,212,139,39>>,
- K = "apaapa",
- R1 = crypto:rc4_encrypt(K, CT1),
- CT1 = crypto:rc4_encrypt(K, R1),
- CT2 = lists:seq(0, 255),
- R2 = crypto:rc4_encrypt(K, CT2),
- CT2 = binary_to_list(crypto:rc4_encrypt(K, R2)),
- ok.
-
-rc4_stream_test(doc) ->
- ["Test rc4 stream encryption ."];
-rc4_stream_test(suite) ->
- [];
-rc4_stream_test(Config) when is_list(Config) ->
- if_supported(rc4, fun rc4_stream_test_do/0).
-
-rc4_stream_test_do() ->
- CT1 = <<"Yo ">>,
- CT2 = <<"baby yo">>,
- K = "apaapa",
- State0 = crypto:rc4_set_key(K),
- {State1, R1} = crypto:rc4_encrypt_with_state(State0, CT1),
- {_State2, R2} = crypto:rc4_encrypt_with_state(State1, CT2),
- R = list_to_binary([R1, R2]),
- <<118,122,68,110,157,166,141,212,139,39>> = R,
- ok.
-
-blowfish_cfb64(doc) -> ["Test Blowfish encrypt/decrypt."];
-blowfish_cfb64(suite) -> [];
-blowfish_cfb64(Config) when is_list(Config) ->
- Key = <<1,35,69,103,137,171,205,239,240,225,210,195,180,165,150,135>>,
-
- IVec = <<254,220,186,152,118,84,50,16>>,
- Plain = <<"7654321 Now is the time for ">>,
- Enc = <<231,50,20,162,130,33,57,202,242,110,207,109,46,185,231,110,61,163,222,4,209,81,114,0,81,157,87,166>>,
-
- Enc = crypto:blowfish_cfb64_encrypt(Key, IVec, Plain),
- Plain = crypto:blowfish_cfb64_decrypt(Key, IVec, Enc),
-
- Key2 = <<"A2B4C">>,
- IVec2 = <<"12345678">>,
- Plain2 = <<"badger at my table....!">>,
- Enc2 = <<173,76,128,155,70,81,79,228,4,162,188,92,119,53,144,89,93,236,28,164,176,16,138>>,
-
- Enc2 = crypto:blowfish_cfb64_encrypt(Key2, IVec2, Plain2),
- Plain2 = crypto:blowfish_cfb64_decrypt(Key2, IVec2, Enc2).
-
-
-smp(doc) -> "Check concurrent access to crypto driver";
-smp(suite) -> [];
-smp(Config) ->
- case erlang:system_info(smp_support) of
- true ->
- NumOfProcs = erlang:system_info(schedulers),
- io:format("smp starting ~p workers\n",[NumOfProcs]),
- Seeds = [random:uniform(9999) || _ <- lists:seq(1,NumOfProcs)],
- Parent = self(),
- Pids = [spawn_link(fun()-> worker(Seed,Config,Parent) end)
- || Seed <- Seeds],
- wait_pids(Pids);
-
- false ->
- {skipped,"No smp support"}
- end.
-
-worker(Seed, Config, Parent) ->
- io:format("smp worker ~p, seed=~p~n",[self(),Seed]),
- random:seed(Seed,Seed,Seed),
- worker_loop(100, Config),
- %%io:format("worker ~p done\n",[self()]),
- Parent ! self().
-
-worker_loop(0, _) ->
- ok;
-worker_loop(N, Config) ->
- Funcs = { md5, md5_update, md5_mac, md5_mac_io, sha, sha_update, des_cbc,
- aes_cfb, aes_cbc, des_cbc_iter, rand_uniform_test, strong_rand_test,
- rsa_verify_test, exor_test, rc4_test, rc4_stream_test, mod_exp_test,
- hmac_update_md5, hmac_update_sha, hmac_update_sha256, hmac_update_sha512,
- hmac_rfc2202, hmac_rfc4231_sha224, hmac_rfc4231_sha256, hmac_rfc4231_sha384,
- hmac_rfc4231_sha512, aes_ctr_stream },
-
- F = element(random:uniform(size(Funcs)),Funcs),
- %%io:format("worker ~p calling ~p\n",[self(),F]),
- ?MODULE:F(Config),
- worker_loop(N-1,Config).
-
-wait_pids([]) ->
- ok;
-wait_pids(Pids) ->
- receive
- Pid ->
- ?line true = lists:member(Pid,Pids),
- Others = lists:delete(Pid,Pids),
- io:format("wait_pid got ~p, still waiting for ~p\n",[Pid,Others]),
- wait_pids(Others)
- end.
-
-%%
-%% Help functions
-%%
-
-% match
-m(X, X) ->
- ?line true.
-t(true) ->
- true.
-
-% hexstr2bin
-hexstr2bin(S) ->
- list_to_binary(hexstr2list(S)).
-
-hexstr2list([X,Y|T]) ->
- [mkint(X)*16 + mkint(Y) | hexstr2list(T)];
-hexstr2list([]) ->
- [].
-
-mkint(C) when $0 =< C, C =< $9 ->
- C - $0;
-mkint(C) when $A =< C, C =< $F ->
- C - $A + 10;
-mkint(C) when $a =< C, C =< $f ->
- C - $a + 10.
-
-%% mod_exp in erlang (copied from jungerl's ssh_math.erl)
-ipow(A, B, M) when M > 0, B >= 0 ->
- if A == 1 ->
- 1;
- true ->
- ipow(A, B, M, 1)
- end.
-
-ipow(A, 1, M, Prod) ->
- (A*Prod) rem M;
-ipow(_A, 0, _M, Prod) ->
- Prod;
-ipow(A, B, M, Prod) ->
- B1 = B bsr 1,
- A1 = (A*A) rem M,
- if B - B1 == B1 ->
- ipow(A1, B1, M, Prod);
- true ->
- ipow(A1, B1, M, (A*Prod) rem M)
- end.
-
-%%
-%% Invert an element X mod P
-%% Calculated as {1, {A,B}} = egcd(X,P),
-%% 1 == P*A + X*B == X*B (mod P) i.e B is the inverse element
-%%
-%% X > 0, P > 0, X < P (P should be prime)
-%%
-%% invert(X,P) when X > 0, P > 0, X < P ->
-%% I = inv(X,P,1,0),
-%% if
-%% I < 0 -> P + I;
-%% true -> I
-%% end.
-
-%% inv(0,_,_,Q) -> Q;
-%% inv(X,P,R1,Q1) ->
-%% D = P div X,
-%% inv(P rem X, X, Q1 - D*R1, R1).
-
-sized_binary(Binary) when is_binary(Binary) ->
- <<(size(Binary)):32/integer, Binary/binary>>;
-sized_binary(List) ->
- sized_binary(list_to_binary(List)).
-
-unsized_binary(<<Sz:32/integer, Binary:Sz/binary>>) ->
- Binary.
-
-xor_bytes(Bin1, Bin2) when is_binary(Bin1), is_binary(Bin2) ->
- L1 = binary_to_list(Bin1),
- L2 = binary_to_list(Bin2),
- list_to_binary(xor_bytes(L1, L2));
-xor_bytes(L1, L2) ->
- xor_bytes(L1, L2, []).
-
-xor_bytes([], [], Acc) ->
- lists:reverse(Acc);
-xor_bytes([N1 | Tl1], [N2 | Tl2], Acc) ->
- xor_bytes(Tl1, Tl2, [N1 bxor N2 | Acc]).
-
-zero_bin(N) when is_integer(N) ->
- N8 = N * 8,
- <<0:N8/integer>>;
-zero_bin(B) when is_binary(B) ->
- zero_bin(size(B)).
-
-my_dss_verify(Data,[Sign|Tail],Key) ->
- Res = my_dss_verify(Data,sized_binary(Sign),Key),
- case Tail of
- [] -> Res;
- _ -> ?line Res = my_dss_verify(Data,Tail,Key)
- end;
-my_dss_verify(Data,Sign,Key) ->
- ?line Res = crypto:dss_verify(Data, Sign, Key),
- ?line Res = crypto:dss_verify(sha, Data, Sign, Key),
- ?line <<_:32,Raw/binary>> = Data,
- ?line Res = crypto:dss_verify(none, crypto:sha(Raw), Sign, Key),
- Res.
-
-my_dss_sign(Data,Key) ->
- ?line S1 = crypto:dss_sign(Data, Key),
- ?line S2 = crypto:dss_sign(sha, Data, Key),
- ?line <<_:32,Raw/binary>> = Data,
- ?line S3 = crypto:dss_sign(none, crypto:sha(Raw), Key),
- [S1,S2,S3].
-
-openssl_version() ->
- case crypto:info_lib() of
- [{<<"OpenSSL">>,LibVer,_}] when is_integer(LibVer) ->
- LibVer;
- _ ->
- undefined
- end.
-
-if_supported(Algorithm, Fun) ->
- case lists:member(Algorithm, lists:append([Algo || {_, Algo} <- crypto:supports()])) of
- true ->
- Fun();
- _ ->
- {skipped, io:format("~s not spupported", [Algorithm])}
- end.
diff --git a/lib/dialyzer/RELEASE_NOTES b/lib/dialyzer/RELEASE_NOTES
index 4e311bb543..2457faa07a 100644
--- a/lib/dialyzer/RELEASE_NOTES
+++ b/lib/dialyzer/RELEASE_NOTES
@@ -135,7 +135,7 @@ Version 1.9.1 (in Erlang/OTP R13B)
Version 1.9.0 (in Erlang/OTP R13A)
----------------------------------
- The analysis accepts opaque type declarations and detects violations of
- opaqueness of terms of such types. Starting with R13, many Erlang/OTP
+ opacity of terms of such types. Starting with R13, many Erlang/OTP
standard libraries (array, dict, digraph, ets, gb_sets, gb_trees, queue,
and sets) contain opaque type declarations of their main data types.
Dialyzer will spit out warnings in code that explicitly depends on the
diff --git a/lib/dialyzer/doc/manual.txt b/lib/dialyzer/doc/manual.txt
index be1fd2f8bc..a571cd2e2b 100644
--- a/lib/dialyzer/doc/manual.txt
+++ b/lib/dialyzer/doc/manual.txt
@@ -255,7 +255,7 @@ Warning options:
-Wno_match
Suppress warnings for patterns that are unused or cannot match.
-Wno_opaque
- Suppress warnings for violations of opaqueness of data types.
+ Suppress warnings for violations of opacity of data types.
-Wunmatched_returns ***
Include warnings for function calls which ignore a structured return
value or do not match against one of many possible return value(s).
diff --git a/lib/dialyzer/doc/src/dialyzer.xml b/lib/dialyzer/doc/src/dialyzer.xml
index 553bfef41b..4b7eb4ad68 100644
--- a/lib/dialyzer/doc/src/dialyzer.xml
+++ b/lib/dialyzer/doc/src/dialyzer.xml
@@ -346,7 +346,7 @@ dialyzer --plts plt_1 ... plt_n -- files_to_analyze</code>
</item>
<tag><c>-Wno_opaque</c></tag>
<item>
- <p>Suppress warnings for violations of opaqueness of data types.</p>
+ <p>Suppress warnings for violations of opacity of data types.</p>
</item>
<tag><c>-Wno_return</c></tag>
<item>
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index b0f0a9aef0..d86deba48d 100644
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -522,7 +522,7 @@
or modifying opaque types within the scope of a module.
</p> <p> Hitherto the shape of terms (tuple, list, etc.)
has been used to determine the opaque terms, but now the
- contracts are used for decorating types with opaqueness.
+ contracts are used for decorating types with opacity.
</p>
<p>
Own Id: OTP-10397</p>
@@ -1505,7 +1505,7 @@
<list>
<item>
<p>The analysis accepts opaque type declarations and
- detects violations of opaqueness of terms of such types.
+ detects violations of opacity of terms of such types.
Starting with R13, many Erlang/OTP standard libraries
(array, dict, digraph, ets, gb_sets, gb_trees, queue, and
sets) contain opaque type declarations of their main data
diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl
index 7f86520c06..ab137bd170 100644
--- a/lib/dialyzer/src/dialyzer.erl
+++ b/lib/dialyzer/src/dialyzer.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer.erl
@@ -407,6 +400,10 @@ message_to_string({contract_range, [Contract, M, F, ArgStrings, Line, CRet]}) ->
message_to_string({invalid_contract, [M, F, A, Sig]}) ->
io_lib:format("Invalid type specification for function ~w:~w/~w."
" The success typing is ~s\n", [M, F, A, Sig]);
+message_to_string({contract_with_opaque, [M, F, A, OpaqueType, SigType]}) ->
+ io_lib:format("The specification for ~w:~w/~w"
+ " has an opaque subtype ~s which is violated by the"
+ " success typing ~s\n", [M, F, A, OpaqueType, SigType]);
message_to_string({extra_range, [M, F, A, ExtraRanges, SigRange]}) ->
io_lib:format("The specification for ~w:~w/~w states that the function"
" might also return ~s but the inferred return is ~s\n",
@@ -432,25 +429,25 @@ message_to_string({opaque_guard, [Arg1, Infix, Arg2, ArgNs]}) ->
io_lib:format("Guard test ~s ~s ~s contains ~s\n",
[Arg1, Infix, Arg2, form_positions(ArgNs)]);
message_to_string({opaque_guard, [Guard, Args]}) ->
- io_lib:format("Guard test ~w~s breaks the opaqueness of its argument\n",
+ io_lib:format("Guard test ~w~s breaks the opacity of its argument\n",
[Guard, Args]);
message_to_string({opaque_match, [Pat, OpaqueType, OpaqueTerm]}) ->
Term = if OpaqueType =:= OpaqueTerm -> "the term";
true -> OpaqueTerm
end,
io_lib:format("The attempt to match a term of type ~s against the ~s"
- " breaks the opaqueness of ~s\n", [OpaqueType, Pat, Term]);
+ " breaks the opacity of ~s\n", [OpaqueType, Pat, Term]);
message_to_string({opaque_neq, [Type, _Op, OpaqueType]}) ->
io_lib:format("Attempt to test for inequality between a term of type ~s"
" and a term of opaque type ~s\n", [Type, OpaqueType]);
message_to_string({opaque_type_test, [Fun, Args, Arg, ArgType]}) ->
- io_lib:format("The type test ~s~s breaks the opaqueness of the term ~s~s\n",
+ io_lib:format("The type test ~s~s breaks the opacity of the term ~s~s\n",
[Fun, Args, Arg, ArgType]);
message_to_string({opaque_size, [SizeType, Size]}) ->
- io_lib:format("The size ~s breaks the opaqueness of ~s\n",
+ io_lib:format("The size ~s breaks the opacity of ~s\n",
[SizeType, Size]);
message_to_string({opaque_call, [M, F, Args, Culprit, OpaqueType]}) ->
- io_lib:format("The call ~s:~s~s breaks the opaqueness of the term ~s :: ~s\n",
+ io_lib:format("The call ~s:~s~s breaks the opacity of the term ~s :: ~s\n",
[M, F, Args, Culprit, OpaqueType]);
%%----- Warnings for concurrency errors --------------------
message_to_string({race_condition, [M, F, Args, Reason]}) ->
diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl
index ea6a71217c..e7cf2860b7 100644
--- a/lib/dialyzer/src/dialyzer.hrl
+++ b/lib/dialyzer/src/dialyzer.hrl
@@ -1,9 +1,5 @@
%%% This is an -*- Erlang -*- file.
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
%%%
-%%% %CopyrightEnd%
-%%%
%%%-------------------------------------------------------------------
%%% File : dialyzer.hrl
%%% Author : Tobias Lindahl <[email protected]>
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index 08e55a78bd..b5510731e0 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%--------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_analysis_callgraph.erl
diff --git a/lib/dialyzer/src/dialyzer_behaviours.erl b/lib/dialyzer/src/dialyzer_behaviours.erl
index 5623929a43..e79a5d1cd9 100644
--- a/lib/dialyzer/src/dialyzer_behaviours.erl
+++ b/lib/dialyzer/src/dialyzer_behaviours.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_behaviours.erl
diff --git a/lib/dialyzer/src/dialyzer_callgraph.erl b/lib/dialyzer/src/dialyzer_callgraph.erl
index 50abb22009..227ee2a892 100644
--- a/lib/dialyzer/src/dialyzer_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_callgraph.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_callgraph.erl
diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl
index fc56693ea3..b43711446b 100644
--- a/lib/dialyzer/src/dialyzer_cl.erl
+++ b/lib/dialyzer/src/dialyzer_cl.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_cl.erl
diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl
index 934351aeeb..baeffe99d8 100644
--- a/lib/dialyzer/src/dialyzer_cl_parse.erl
+++ b/lib/dialyzer/src/dialyzer_cl_parse.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(dialyzer_cl_parse).
@@ -510,7 +503,7 @@ warning_options_msg() ->
-Wno_match
Suppress warnings for patterns that are unused or cannot match.
-Wno_opaque
- Suppress warnings for violations of opaqueness of data types.
+ Suppress warnings for violations of opacity of data types.
-Wno_fail_call
Suppress warnings for failing calls.
-Wno_contracts
diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl
index 03cd9671af..dd383ea828 100644
--- a/lib/dialyzer/src/dialyzer_codeserver.erl
+++ b/lib/dialyzer/src/dialyzer_codeserver.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_codeserver.erl
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index a72368f9f8..7cc4a9d3eb 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(dialyzer_contracts).
@@ -232,7 +225,7 @@ check_contract(#contract{contracts = Contracts}, SuccType, Opaques) ->
error ->
{error, {overlapping_contract, []}};
ok ->
- InfList = [erl_types:t_inf(Contract, SuccType, Opaques)
+ InfList = [{Contract, erl_types:t_inf(Contract, SuccType, Opaques)}
|| Contract <- Contracts2],
case check_contract_inf_list(InfList, SuccType, Opaques) of
{error, _} = Invalid -> Invalid;
@@ -256,10 +249,21 @@ check_domains([Dom|Doms]) ->
%% Allow a contract if one of the overloaded contracts is possible.
%% We used to be more strict, e.g., all overloaded contracts had to be
%% possible.
-check_contract_inf_list([FunType|Left], SuccType, Opaques) ->
+check_contract_inf_list(List, SuccType, Opaques) ->
+ case check_contract_inf_list(List, SuccType, Opaques, []) of
+ ok -> ok;
+ {error, []} -> {error, invalid_contract};
+ {error, [{SigRange, ContrRange}|_]} ->
+ case erl_types:t_find_opaque_mismatch(SigRange, ContrRange, Opaques) of
+ error -> {error, invalid_contract};
+ {ok, _T1, T2} -> {error, {opaque_mismatch, T2}}
+ end
+ end.
+
+check_contract_inf_list([{Contract, FunType}|Left], SuccType, Opaques, OM) ->
FunArgs = erl_types:t_fun_args(FunType),
case lists:any(fun erl_types:t_is_none_or_unit/1, FunArgs) of
- true -> check_contract_inf_list(Left, SuccType, Opaques);
+ true -> check_contract_inf_list(Left, SuccType, Opaques, OM);
false ->
STRange = erl_types:t_fun_range(SuccType),
case erl_types:t_is_none_or_unit(STRange) of
@@ -267,13 +271,16 @@ check_contract_inf_list([FunType|Left], SuccType, Opaques) ->
false ->
Range = erl_types:t_fun_range(FunType),
case erl_types:t_is_none(erl_types:t_inf(STRange, Range)) of
- true -> check_contract_inf_list(Left, SuccType, Opaques);
+ true ->
+ CR = erl_types:t_fun_range(Contract),
+ NewOM = [{STRange, CR}|OM],
+ check_contract_inf_list(Left, SuccType, Opaques, NewOM);
false -> ok
end
end
end;
-check_contract_inf_list([], _SuccType, _Opaques) ->
- {error, invalid_contract}.
+check_contract_inf_list([], _SuccType, _Opaques, OM) ->
+ {error, OM}.
check_extraneous([], _SuccType) -> ok;
check_extraneous([C|Cs], SuccType) ->
@@ -687,6 +694,9 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract, _Xtra}}|Left],
case check_contract(Contract, Sig, Opaques) of
{error, invalid_contract} ->
[invalid_contract_warning(MFA, WarningInfo, Sig, RecDict)|Acc];
+ {error, {opaque_mismatch, T2}} ->
+ W = contract_opaque_warning(MFA, WarningInfo, T2, Sig, RecDict),
+ [W|Acc];
{error, {overlapping_contract, []}} ->
[overlapping_contract_warning(MFA, WarningInfo)|Acc];
{error, {extra_range, ExtraRanges, STRange}} ->
@@ -740,6 +750,12 @@ invalid_contract_warning({M, F, A}, WarningInfo, SuccType, RecDict) ->
SuccTypeStr = dialyzer_utils:format_sig(SuccType, RecDict),
{?WARN_CONTRACT_TYPES, WarningInfo, {invalid_contract, [M, F, A, SuccTypeStr]}}.
+contract_opaque_warning({M, F, A}, WarningInfo, OpType, SuccType, RecDict) ->
+ OpaqueStr = erl_types:t_to_string(OpType),
+ SuccTypeStr = dialyzer_utils:format_sig(SuccType, RecDict),
+ {?WARN_CONTRACT_TYPES, WarningInfo,
+ {contract_with_opaque, [M, F, A, OpaqueStr, SuccTypeStr]}}.
+
overlapping_contract_warning({M, F, A}, WarningInfo) ->
{?WARN_CONTRACT_TYPES, WarningInfo, {overlapping_contract, [M, F, A]}}.
diff --git a/lib/dialyzer/src/dialyzer_coordinator.erl b/lib/dialyzer/src/dialyzer_coordinator.erl
index 87cbd25b30..99f95a4dca 100644
--- a/lib/dialyzer/src/dialyzer_coordinator.erl
+++ b/lib/dialyzer/src/dialyzer_coordinator.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_coordinator.erl
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl
index c0372a47e8..fdcf8269e4 100644
--- a/lib/dialyzer/src/dialyzer_dataflow.erl
+++ b/lib/dialyzer/src/dialyzer_dataflow.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%--------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_dataflow.erl
@@ -1211,7 +1204,7 @@ handle_tuple(Tree, Map, State) ->
TagVal = cerl:atom_val(Tag),
case state__lookup_record(TagVal, length(Left), State1) of
error -> {State1, Map1, TupleType};
- {ok, RecType} ->
+ {ok, RecType, FieldNames} ->
InfTupleType = t_inf(RecType, TupleType),
case t_is_none(InfTupleType) of
true ->
@@ -1232,10 +1225,13 @@ handle_tuple(Tree, Map, State) ->
Tree, Msg),
{State2, Map1, t_none()};
{error, opaque, ErrorPat, ErrorType, OpaqueType} ->
+ OpaqueStr = format_type(OpaqueType, State1),
+ Name = field_name(Elements, ErrorPat, FieldNames),
Msg = {opaque_match,
- [format_patterns(ErrorPat),
- format_type(ErrorType, State1),
- format_type(OpaqueType, State1)]},
+ ["record field" ++ Name ++
+ " declared to be of type " ++
+ format_type(ErrorType, State1),
+ OpaqueStr, OpaqueStr]},
State2 = state__add_warning(State1, ?WARN_OPAQUE,
Tree, Msg),
{State2, Map1, t_none()};
@@ -1252,6 +1248,15 @@ handle_tuple(Tree, Map, State) ->
end
end.
+field_name(Elements, ErrorPat, FieldNames) ->
+ try
+ [Pat] = ErrorPat,
+ Take = lists:takewhile(fun(X) -> X =/= Pat end, Elements),
+ " " ++ format_atom(lists:nth(length(Take), FieldNames))
+ catch
+ _:_ -> ""
+ end.
+
%%----------------------------------------
%% Clauses
%%
@@ -1632,7 +1637,7 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) ->
TagAtom = cerl:atom_val(Tag),
case state__lookup_record(TagAtom, length(Left), State) of
error -> {false, t_tuple(length(Es))};
- {ok, Record} ->
+ {ok, Record, _FieldNames} ->
[_Head|AnyTail] = [t_any() || _ <- Es],
UntypedRecord = t_tuple([t_atom(TagAtom)|AnyTail]),
{not t_is_equal(Record, UntypedRecord), Record}
@@ -2160,7 +2165,7 @@ handle_guard_is_record(Guard, Map, Env, Eval, State) ->
TupleType =
case state__lookup_record(Tag, ArityMin1, State) of
error -> Tuple;
- {ok, Prototype} -> Prototype
+ {ok, Prototype, _FieldNames} -> Prototype
end,
Type = t_inf(TupleType, RecType, State#state.opaques),
case t_is_none(Type) of
@@ -2610,7 +2615,7 @@ bind_guard_case_clauses(Arg, Clauses, Map0, Env, Eval, State) ->
Map = join_maps_begin(Map0),
{GenMap, GenArgType} = bind_guard(Arg, Map, Env, dont_know, State),
bind_guard_case_clauses(GenArgType, GenMap, Arg, Clauses1, Map, Env, Eval,
- t_none(), [], State).
+ t_none(), [], [], State).
filter_fail_clauses([Clause|Left]) ->
case (cerl:clause_pats(Clause) =:= []) of
@@ -2629,7 +2634,7 @@ filter_fail_clauses([]) ->
[].
bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left],
- Map, Env, Eval, AccType, AccMaps, State) ->
+ Map, Env, Eval, AccType, AccMaps, Throws, State) ->
Pats = cerl:clause_pats(Clause),
{NewMap0, ArgType} =
case Pats of
@@ -2673,9 +2678,9 @@ bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left],
case (NewMap1 =:= none) orelse t_is_none(GenArgType) of
true ->
bind_guard_case_clauses(NewGenArgType, GenMap, ArgExpr, Left, Map, Env,
- Eval, AccType, AccMaps, State);
+ Eval, AccType, AccMaps, Throws, State);
false ->
- {NewAccType, NewAccMaps} =
+ {NewAccType, NewAccMaps, NewThrows} =
try
{NewMap2, GuardType} = bind_guard(Guard, NewMap1, Env, pos, State),
case t_is_none(t_inf(t_atom(true), GuardType)) of
@@ -2699,17 +2704,26 @@ bind_guard_case_clauses(GenArgType, GenMap, ArgExpr, [Clause|Left],
dont_know ->
ok
end,
- {t_sup(AccType, CType), [NewMap3|AccMaps]}
+ {t_sup(AccType, CType), [NewMap3|AccMaps], Throws}
catch
- throw:{fail, _What} -> {AccType, AccMaps}
+ throw:{fail, Reason} ->
+ Throws1 = case Reason of
+ none -> Throws;
+ _ -> Throws ++ [Reason]
+ end,
+ {AccType, AccMaps, Throws1}
end,
bind_guard_case_clauses(NewGenArgType, GenMap, ArgExpr, Left, Map, Env,
- Eval, NewAccType, NewAccMaps, State)
+ Eval, NewAccType, NewAccMaps, NewThrows, State)
end;
bind_guard_case_clauses(_GenArgType, _GenMap, _ArgExpr, [], Map, _Env, _Eval,
- AccType, AccMaps, _State) ->
+ AccType, AccMaps, Throws, _State) ->
case t_is_none(AccType) of
- true -> throw({fail, none});
+ true ->
+ case Throws of
+ [Throw|_] -> throw({fail, Throw});
+ [] -> throw({fail, none})
+ end;
false -> {join_maps_end(AccMaps, Map), AccType}
end.
@@ -3207,7 +3221,8 @@ state__lookup_record(Tag, Arity, #state{records = Records}) ->
RecType =
t_tuple([t_atom(Tag)|
[FieldType || {_FieldName, _Abstr, FieldType} <- Fields]]),
- {ok, RecType};
+ FieldNames = [FieldName || {FieldName, _Abstr, _FieldType} <- Fields],
+ {ok, RecType, FieldNames};
error ->
error
end.
@@ -3662,6 +3677,9 @@ map_pats(Pats) ->
fold_literals(TreeList) ->
[cerl:fold_literal(Tree) || Tree <- TreeList].
+format_atom(A) ->
+ format_cerl(cerl:c_atom(A)).
+
type(Tree) ->
Folded = cerl:fold_literal(Tree),
case cerl:type(Folded) of
diff --git a/lib/dialyzer/src/dialyzer_dep.erl b/lib/dialyzer/src/dialyzer_dep.erl
index 273c05c54c..36cdc0876c 100644
--- a/lib/dialyzer/src/dialyzer_dep.erl
+++ b/lib/dialyzer/src/dialyzer_dep.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_dep.erl
diff --git a/lib/dialyzer/src/dialyzer_explanation.erl b/lib/dialyzer/src/dialyzer_explanation.erl
index 968f8df78e..10b3ef8ea5 100644
--- a/lib/dialyzer/src/dialyzer_explanation.erl
+++ b/lib/dialyzer/src/dialyzer_explanation.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
-%%
+%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_explanation.erl
@@ -50,4 +43,3 @@ expl_loop(Parent, CServer, Plt) ->
send_explanation(Parent, Expl) ->
Parent ! {self(), explanation, Expl},
ok.
-
diff --git a/lib/dialyzer/src/dialyzer_gui_wx.erl b/lib/dialyzer/src/dialyzer_gui_wx.erl
index 30d2bdeca4..91f7fbe467 100644
--- a/lib/dialyzer/src/dialyzer_gui_wx.erl
+++ b/lib/dialyzer/src/dialyzer_gui_wx.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%------------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-----------------------------------------------------------------------
%%% File : dialyzer_gui_wx.erl
@@ -310,7 +303,7 @@ createWarningsMenu() ->
addCheckedItem(WarningsMenu, ?menuID_WARN_FAIL_FUN_CALLS,
"Failing function calls"),
addCheckedItem(WarningsMenu, ?menuID_WARN_BAD_FUN, "Bad fun applications"),
- addCheckedItem(WarningsMenu, ?menuID_WARN_OPAQUE, "Opaqueness violations"),
+ addCheckedItem(WarningsMenu, ?menuID_WARN_OPAQUE, "Opacity violations"),
addCheckedItem(WarningsMenu, ?menuID_WARN_LIST_CONSTR,
"Improper list constructions"),
addCheckedItem(WarningsMenu, ?menuID_WARN_UNUSED_FUN, "Unused functions"),
diff --git a/lib/dialyzer/src/dialyzer_gui_wx.hrl b/lib/dialyzer/src/dialyzer_gui_wx.hrl
index e81eeb1ab5..fe763a9abc 100644
--- a/lib/dialyzer/src/dialyzer_gui_wx.hrl
+++ b/lib/dialyzer/src/dialyzer_gui_wx.hrl
@@ -1,3 +1,15 @@
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
-include_lib("wx/include/wx.hrl").
diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl
index add660eae9..616e8834f5 100644
--- a/lib/dialyzer/src/dialyzer_options.erl
+++ b/lib/dialyzer/src/dialyzer_options.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -16,16 +12,9 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-
-%%%----------------------------------------------------------------------
-%%% File : dialyzer_options.erl
-%%% Authors : Richard Carlsson <[email protected]>
-%%% Description : Provides a better way to start Dialyzer from a script.
-%%%
-%%% Created : 17 Oct 2004 by Richard Carlsson <[email protected]>
-%%%----------------------------------------------------------------------
+%% @copyright 2004 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
+%% @doc Provides a better way to start Dialyzer from a script.
-module(dialyzer_options).
diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl
index cf2f0e919e..64b10af1ba 100644
--- a/lib/dialyzer/src/dialyzer_plt.erl
+++ b/lib/dialyzer/src/dialyzer_plt.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_plt.erl
diff --git a/lib/dialyzer/src/dialyzer_race_data_server.erl b/lib/dialyzer/src/dialyzer_race_data_server.erl
index 3600491809..953cebfdf1 100644
--- a/lib/dialyzer/src/dialyzer_race_data_server.erl
+++ b/lib/dialyzer/src/dialyzer_race_data_server.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_race_data_server.erl
diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl
index bb43d1dcb8..7fe64c3e11 100644
--- a/lib/dialyzer/src/dialyzer_races.erl
+++ b/lib/dialyzer/src/dialyzer_races.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%----------------------------------------------------------------------
%%% File : dialyzer_races.erl
diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl
index 987da3aecf..df12796dd4 100644
--- a/lib/dialyzer/src/dialyzer_succ_typings.erl
+++ b/lib/dialyzer/src/dialyzer_succ_typings.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_succ_typings.erl
diff --git a/lib/dialyzer/src/dialyzer_timing.erl b/lib/dialyzer/src/dialyzer_timing.erl
index aa71318d8e..056ccd51d8 100644
--- a/lib/dialyzer/src/dialyzer_timing.erl
+++ b/lib/dialyzer/src/dialyzer_timing.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_timing.erl
diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl
index 1787b66192..457db9df83 100644
--- a/lib/dialyzer/src/dialyzer_typesig.erl
+++ b/lib/dialyzer/src/dialyzer_typesig.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_typesig.erl
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index 1f2d3e3aaa..8480129dab 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_utils.erl
diff --git a/lib/dialyzer/src/dialyzer_worker.erl b/lib/dialyzer/src/dialyzer_worker.erl
index b9ab27c11d..418c9798b3 100644
--- a/lib/dialyzer/src/dialyzer_worker.erl
+++ b/lib/dialyzer/src/dialyzer_worker.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(dialyzer_worker).
diff --git a/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2 b/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2
index f6fb98a863..46e2e8d36c 100644
--- a/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2
+++ b/lib/dialyzer/test/map_SUITE_data/results/map_in_guard2
@@ -2,11 +2,11 @@
map_in_guard2.erl:10: The call map_in_guard2:assoc_guard_clause('not_a_map') will never return since it differs in the 1st argument from the success typing arguments: (map())
map_in_guard2.erl:12: The pattern 'true' can never match the type 'false'
map_in_guard2.erl:14: The call map_in_guard2:exact_guard_clause(#{}) will never return since it differs in the 1st argument from the success typing arguments: (#{'a':=_, _=>_})
-map_in_guard2.erl:17: Clause guard cannot succeed. The variable M was matched against the type 'not_a_map'
+map_in_guard2.erl:17: Guard test is_map(M::'not_a_map') can never succeed
map_in_guard2.erl:20: Function assoc_update/1 has no local return
map_in_guard2.erl:20: Guard test is_map(M::'not_a_map') can never succeed
-map_in_guard2.erl:22: Clause guard cannot succeed. The variable M was matched against the type 'not_a_map'
map_in_guard2.erl:22: Function assoc_guard_clause/1 has no local return
+map_in_guard2.erl:22: Guard test is_map(M::'not_a_map') can never succeed
map_in_guard2.erl:24: Clause guard cannot succeed. The variable M was matched against the type #{}
map_in_guard2.erl:27: Clause guard cannot succeed. The variable M was matched against the type #{}
map_in_guard2.erl:27: Function exact_guard_clause/1 has no local return
diff --git a/lib/dialyzer/test/map_SUITE_data/results/opaque_key b/lib/dialyzer/test/map_SUITE_data/results/opaque_key
index fb7080cdc5..2ae0e0c5c6 100644
--- a/lib/dialyzer/test/map_SUITE_data/results/opaque_key
+++ b/lib/dialyzer/test/map_SUITE_data/results/opaque_key
@@ -6,10 +6,10 @@ opaque_key_adt.erl:59: Invalid type specification for function opaque_key_adt:sm
opaque_key_use.erl:13: The test opaque_key_use:t() =:= opaque_key_use:t(integer()) can never evaluate to 'true'
opaque_key_use.erl:24: Attempt to test for equality between a term of type opaque_key_adt:t(integer()) and a term of opaque type opaque_key_adt:t()
opaque_key_use.erl:37: Function adt_mm1/0 has no local return
-opaque_key_use.erl:40: The attempt to match a term of type opaque_key_adt:m() against the pattern #{A:=R} breaks the opaqueness of the term
+opaque_key_use.erl:40: The attempt to match a term of type opaque_key_adt:m() against the pattern #{A:=R} breaks the opacity of the term
opaque_key_use.erl:48: Function adt_mu1/0 has no local return
-opaque_key_use.erl:51: Guard test is_map(M::opaque_key_adt:m()) breaks the opaqueness of its argument
+opaque_key_use.erl:51: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument
opaque_key_use.erl:53: Function adt_mu2/0 has no local return
-opaque_key_use.erl:56: Guard test is_map(M::opaque_key_adt:m()) breaks the opaqueness of its argument
+opaque_key_use.erl:56: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument
opaque_key_use.erl:58: Function adt_mu3/0 has no local return
-opaque_key_use.erl:60: Guard test is_map(M::opaque_key_adt:m()) breaks the opaqueness of its argument
+opaque_key_use.erl:60: Guard test is_map(M::opaque_key_adt:m()) breaks the opacity of its argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/array b/lib/dialyzer/test/opaque_SUITE_data/results/array
index 9921b61669..6f1aa1ce3d 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/array
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/array
@@ -1,3 +1,3 @@
-array_use.erl:12: The type test is_tuple(array:array(_)) breaks the opaqueness of the term array:array(_)
-array_use.erl:9: The attempt to match a term of type array:array(_) against the pattern {'array', _, _, 'undefined', _} breaks the opaqueness of the term
+array_use.erl:12: The type test is_tuple(array:array(_)) breaks the opacity of the term array:array(_)
+array_use.erl:9: The attempt to match a term of type array:array(_) against the pattern {'array', _, _, 'undefined', _} breaks the opacity of the term
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/dict b/lib/dialyzer/test/opaque_SUITE_data/results/dict
index 42f6663191..3f8242c72d 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/dict
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/dict
@@ -1,15 +1,15 @@
-dict_use.erl:41: The attempt to match a term of type dict:dict(_,_) against the pattern 'gazonk' breaks the opaqueness of the term
-dict_use.erl:45: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opaqueness of the term
-dict_use.erl:46: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opaqueness of the term
-dict_use.erl:51: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opaqueness of the term
-dict_use.erl:52: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opaqueness of the term
+dict_use.erl:41: The attempt to match a term of type dict:dict(_,_) against the pattern 'gazonk' breaks the opacity of the term
+dict_use.erl:45: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opacity of the term
+dict_use.erl:46: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opacity of the term
+dict_use.erl:51: The attempt to match a term of type dict:dict(_,_) against the pattern [] breaks the opacity of the term
+dict_use.erl:52: The attempt to match a term of type dict:dict(_,_) against the pattern 42 breaks the opacity of the term
dict_use.erl:58: Attempt to test for equality between a term of type maybe_improper_list() and a term of opaque type dict:dict(_,_)
dict_use.erl:60: Attempt to test for inequality between a term of type atom() and a term of opaque type dict:dict(_,_)
-dict_use.erl:64: Guard test length(D::dict:dict(_,_)) breaks the opaqueness of its argument
-dict_use.erl:65: Guard test is_atom(D::dict:dict(_,_)) breaks the opaqueness of its argument
-dict_use.erl:66: Guard test is_list(D::dict:dict(_,_)) breaks the opaqueness of its argument
-dict_use.erl:70: The type test is_list(dict:dict(_,_)) breaks the opaqueness of the term dict:dict(_,_)
+dict_use.erl:64: Guard test length(D::dict:dict(_,_)) breaks the opacity of its argument
+dict_use.erl:65: Guard test is_atom(D::dict:dict(_,_)) breaks the opacity of its argument
+dict_use.erl:66: Guard test is_list(D::dict:dict(_,_)) breaks the opacity of its argument
+dict_use.erl:70: The type test is_list(dict:dict(_,_)) breaks the opacity of the term dict:dict(_,_)
dict_use.erl:73: The call dict:fetch('foo',[1 | 2 | 3,...]) does not have an opaque term of type dict:dict(_,_) as 2nd argument
dict_use.erl:76: The call dict:merge(Fun::any(),42,[1 | 2,...]) does not have opaque terms as 2nd and 3rd arguments
dict_use.erl:79: The call dict:store(42,'elli',{'dict',0,16,16,8,80,48,{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},{{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}) does not have an opaque term of type dict:dict(_,_) as 3rd argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/ets b/lib/dialyzer/test/opaque_SUITE_data/results/ets
index e11c7a8352..5dde23fb15 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/ets
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/ets
@@ -1,4 +1,4 @@
-ets_use.erl:12: Guard test is_integer(T::atom() | ets:tid()) breaks the opaqueness of its argument
-ets_use.erl:20: The type test is_integer(atom() | ets:tid()) breaks the opaqueness of the term atom() | ets:tid()
-ets_use.erl:7: Guard test is_integer(T::ets:tid()) breaks the opaqueness of its argument
+ets_use.erl:12: Guard test is_integer(T::atom() | ets:tid()) breaks the opacity of its argument
+ets_use.erl:20: The type test is_integer(atom() | ets:tid()) breaks the opacity of the term atom() | ets:tid()
+ets_use.erl:7: Guard test is_integer(T::ets:tid()) breaks the opacity of its argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/my_queue b/lib/dialyzer/test/opaque_SUITE_data/results/my_queue
index 1f25a6f9c3..67999b0e20 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/my_queue
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/my_queue
@@ -1,7 +1,7 @@
my_queue_use.erl:15: The call my_queue_adt:is_empty([]) does not have an opaque term of type my_queue_adt:my_queue() as 1st argument
my_queue_use.erl:19: The call my_queue_adt:add(42,Q0::[]) does not have an opaque term of type my_queue_adt:my_queue() as 2nd argument
-my_queue_use.erl:24: The attempt to match a term of type my_queue_adt:my_queue() against the pattern [42 | Q2] breaks the opaqueness of the term
+my_queue_use.erl:24: The attempt to match a term of type my_queue_adt:my_queue() against the pattern [42 | Q2] breaks the opacity of the term
my_queue_use.erl:30: Attempt to test for equality between a term of type [] and a term of opaque type my_queue_adt:my_queue()
my_queue_use.erl:34: Cons will produce an improper list since its 2nd argument is my_queue_adt:my_queue()
my_queue_use.erl:34: The call my_queue_adt:dequeue(nonempty_maybe_improper_list(42,my_queue_adt:my_queue())) does not have an opaque term of type my_queue_adt:my_queue() as 1st argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/opaque b/lib/dialyzer/test/opaque_SUITE_data/results/opaque
index 5747f9061f..864e0d853c 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/opaque
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/opaque
@@ -1,3 +1,3 @@
opaque_bug3.erl:19: The pattern 'a' can never match the type #c{}
-opaque_bug4.erl:20: The attempt to match a term of type opaque_adt:abc() against the pattern 'a' breaks the opaqueness of the term
+opaque_bug4.erl:20: The attempt to match a term of type opaque_adt:abc() against the pattern 'a' breaks the opacity of the term
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/para b/lib/dialyzer/test/opaque_SUITE_data/results/para
index b23d0cae3a..37b5b7b44e 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/para
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/para
@@ -16,9 +16,9 @@ para2.erl:88: The test para2:circ(integer()) =:= para2:circ(integer(),integer())
para3.erl:28: Invalid type specification for function para3:ot2/0. The success typing is () -> 'foo'
para3.erl:36: The pattern {{{17}}} can never match the type {{{{{{_,_,_,_,_}}}}}}
para3.erl:55: Invalid type specification for function para3:t2/0. The success typing is () -> 'foo'
-para3.erl:65: The attempt to match a term of type {{{{{para3_adt:ot1(_,_,_,_,_)}}}}} against the pattern {{{{{17}}}}} breaks the opaqueness of para3_adt:ot1(_,_,_,_,_)
+para3.erl:65: The attempt to match a term of type {{{{{para3_adt:ot1(_,_,_,_,_)}}}}} against the pattern {{{{{17}}}}} breaks the opacity of para3_adt:ot1(_,_,_,_,_)
para3.erl:68: The pattern {{{{17}}}} can never match the type {{{{{para3_adt:ot1(_,_,_,_,_)}}}}}
-para3.erl:74: Invalid type specification for function para3:exp_adt/0. The success typing is () -> 3
+para3.erl:74: The specification for para3:exp_adt/0 has an opaque subtype para3_adt:exp1(para3_adt:exp2()) which is violated by the success typing () -> 3
para4.erl:21: Invalid type specification for function para4:a/1. The success typing is (para4:d_all() | para4:d_atom()) -> [{atom() | integer(),atom() | integer()}]
para4.erl:26: Invalid type specification for function para4:i/1. The success typing is (para4:d_all() | para4:d_integer()) -> [{atom() | integer(),atom() | integer()}]
para4.erl:31: Invalid type specification for function para4:t/1. The success typing is (para4:d_all() | para4:d_tuple()) -> [{atom() | integer(),atom() | integer()}]
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/queue b/lib/dialyzer/test/opaque_SUITE_data/results/queue
index 5b3813c418..9822b7168f 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/queue
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/queue
@@ -1,11 +1,11 @@
queue_use.erl:18: The call queue:is_empty({[],[]}) does not have an opaque term of type queue:queue(_) as 1st argument
queue_use.erl:22: The call queue:in(42,Q0::{[],[]}) does not have an opaque term of type queue:queue(_) as 2nd argument
-queue_use.erl:27: The attempt to match a term of type queue:queue(_) against the pattern {"*", Q2} breaks the opaqueness of the term
+queue_use.erl:27: The attempt to match a term of type queue:queue(_) against the pattern {"*", Q2} breaks the opacity of the term
queue_use.erl:33: Attempt to test for equality between a term of type {[42,...],[]} and a term of opaque type queue:queue(_)
-queue_use.erl:36: The attempt to match a term of type queue:queue(_) against the pattern {F, _R} breaks the opaqueness of the term
+queue_use.erl:36: The attempt to match a term of type queue:queue(_) against the pattern {F, _R} breaks the opacity of the term
queue_use.erl:40: The call queue:out({[42,...],[]}) does not have an opaque term of type queue:queue(_) as 1st argument
queue_use.erl:51: The call queue_use:is_in_queue(E::42,DB::#db{p::[],q::queue:queue(_)}) contains an opaque term as 2nd argument when terms of different types are expected in these positions
-queue_use.erl:56: The attempt to match a term of type #db{p::[],q::queue:queue(_)} against the pattern {'db', _, {L1, L2}} breaks the opaqueness of queue:queue(_)
+queue_use.erl:56: The attempt to match a term of type #db{p::[],q::queue:queue(_)} against the pattern {'db', _, {L1, L2}} breaks the opacity of queue:queue(_)
queue_use.erl:62: The call queue_use:tuple_queue({42,'gazonk'}) does not have a term of type {_,queue:queue(_)} (with opaque subterms) as 1st argument
queue_use.erl:65: The call queue:in(F::42,Q::'gazonk') does not have an opaque term of type queue:queue(_) as 2nd argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/rec b/lib/dialyzer/test/opaque_SUITE_data/results/rec
index 72736b3b3c..e9b217a93f 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/rec
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/rec
@@ -1,6 +1,6 @@
-rec_use.erl:17: The attempt to match a term of type rec_adt:rec() against the pattern {'rec', _, 42} breaks the opaqueness of the term
-rec_use.erl:18: Guard test tuple_size(R::rec_adt:rec()) breaks the opaqueness of its argument
+rec_use.erl:17: The attempt to match a term of type rec_adt:rec() against the pattern {'rec', _, 42} breaks the opacity of the term
+rec_use.erl:18: Guard test tuple_size(R::rec_adt:rec()) breaks the opacity of its argument
rec_use.erl:23: The call rec_adt:get_a(R::tuple()) does not have an opaque term of type rec_adt:rec() as 1st argument
rec_use.erl:27: Attempt to test for equality between a term of type {'rec','gazonk',42} and a term of opaque type rec_adt:rec()
rec_use.erl:30: The call erlang:tuple_size(rec_adt:rec()) contains an opaque term as 1st argument when a structured term of type tuple() is expected
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/simple b/lib/dialyzer/test/opaque_SUITE_data/results/simple
index 391c37664e..5cd8916aee 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/simple
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/simple
@@ -1,29 +1,29 @@
exact_api.erl:17: The call exact_api:set_type(A::#digraph{vtab::'notable',etab::'notable',ntab::'notable',cyclic::'true'}) does not have an opaque term of type digraph:graph() as 1st argument
exact_api.erl:23: The call digraph:delete(G::#digraph{vtab::'notable',etab::'notable',ntab::'notable',cyclic::'true'}) does not have an opaque term of type digraph:graph() as 1st argument
-exact_api.erl:55: The attempt to match a term of type exact_adt:exact_adt() against the pattern {'exact_adt'} breaks the opaqueness of the term
+exact_api.erl:55: The attempt to match a term of type exact_adt:exact_adt() against the pattern {'exact_adt'} breaks the opacity of the term
exact_api.erl:59: The call exact_adt:exact_adt_set_type2(A::#exact_adt{}) does not have an opaque term of type exact_adt:exact_adt() as 1st argument
is_rec.erl:10: The call erlang:is_record(simple1_adt:d1(),'r',2) contains an opaque term as 1st argument when terms of different types are expected in these positions
is_rec.erl:15: The call erlang:is_record(A::simple1_adt:d1(),'r',I::1 | 2 | 3) contains an opaque term as 1st argument when terms of different types are expected in these positions
-is_rec.erl:19: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opaqueness of its argument
-is_rec.erl:23: Guard test is_record({simple1_adt:d1(),1},'r',2) breaks the opaqueness of its argument
+is_rec.erl:19: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opacity of its argument
+is_rec.erl:23: Guard test is_record({simple1_adt:d1(),1},'r',2) breaks the opacity of its argument
is_rec.erl:41: The call erlang:is_record(A::simple1_adt:d1(),R::'a') contains an opaque term as 1st argument when terms of different types are expected in these positions
is_rec.erl:45: The call erlang:is_record(A::simple1_adt:d1(),A::simple1_adt:d1(),1) contains an opaque term as 2nd argument when terms of different types are expected in these positions
is_rec.erl:49: The call erlang:is_record(A::simple1_adt:d1(),any(),1) contains an opaque term as 1st argument when terms of different types are expected in these positions
is_rec.erl:53: The call erlang:is_record(A::simple1_adt:d1(),A::simple1_adt:d1(),any()) contains an opaque term as 2nd argument when terms of different types are expected in these positions
-is_rec.erl:57: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opaqueness of its argument
+is_rec.erl:57: Guard test is_record(A::simple1_adt:d1(),'r',2) breaks the opacity of its argument
is_rec.erl:61: The record #r{f1::simple1_adt:d1()} violates the declared type for #r{}
is_rec.erl:65: The call erlang:is_record({simple1_adt:d1(),1},'r',2) contains an opaque term as 1st argument when terms of different types are expected in these positions
rec_api.erl:104: Matching of pattern {'r2', 10} tagged with a record name violates the declared type of #r2{f1::10}
-rec_api.erl:113: The attempt to match a term of type #r3{f1::queue:queue(_)} against the pattern {'r3', 'a'} breaks the opaqueness of queue:queue(_)
+rec_api.erl:113: The attempt to match a term of type #r3{f1::queue:queue(_)} against the pattern {'r3', 'a'} breaks the opacity of queue:queue(_)
rec_api.erl:118: Record construction #r3{f1::10} violates the declared type of field f1::queue:queue(_)
-rec_api.erl:123: The attempt to match a term of type #r3{f1::10} against the pattern {'r3', 10} breaks the opaqueness of queue:queue(_)
+rec_api.erl:123: The attempt to match a term of type #r3{f1::10} against the pattern {'r3', 10} breaks the opacity of queue:queue(_)
rec_api.erl:24: Record construction #r1{f1::10} violates the declared type of field f1::rec_api:a()
rec_api.erl:29: Matching of pattern {'r1', 10} tagged with a record name violates the declared type of #r1{f1::10}
-rec_api.erl:33: The attempt to match a term of type rec_adt:r1() against the pattern {'r1', 'a'} breaks the opaqueness of the term
+rec_api.erl:33: The attempt to match a term of type rec_adt:r1() against the pattern {'r1', 'a'} breaks the opacity of the term
rec_api.erl:35: Invalid type specification for function rec_api:adt_t1/1. The success typing is (#r1{f1::'a'}) -> #r1{f1::'a'}
-rec_api.erl:40: Invalid type specification for function rec_api:adt_r1/0. The success typing is () -> #r1{f1::'a'}
-rec_api.erl:85: The attempt to match a term of type rec_api:f() against the variable _ breaks the opaqueness of rec_adt:f()
+rec_api.erl:40: The specification for rec_api:adt_r1/0 has an opaque subtype rec_adt:r1() which is violated by the success typing () -> #r1{f1::'a'}
+rec_api.erl:85: The attempt to match a term of type rec_adt:f() against the record field 'f' declared to be of type rec_api:f() breaks the opacity of the term
rec_api.erl:99: Record construction #r2{f1::10} violates the declared type of field f1::rec_api:a()
simple1_api.erl:113: The test simple1_api:d1() =:= simple1_api:d2() can never evaluate to 'true'
simple1_api.erl:118: Guard test simple1_api:d2() =:= A::simple1_api:d1() can never succeed
@@ -35,20 +35,20 @@ simple1_api.erl:165: Attempt to test for equality between a term of type simple1
simple1_api.erl:181: Guard test A::simple1_adt:d1() =< B::simple1_adt:d2() contains opaque terms as 1st and 2nd arguments
simple1_api.erl:185: Guard test 'a' =< B::simple1_adt:d2() contains an opaque term as 2nd argument
simple1_api.erl:189: Guard test A::simple1_adt:d1() =< 'd' contains an opaque term as 1st argument
-simple1_api.erl:197: The type test is_integer(A::simple1_adt:d1()) breaks the opaqueness of the term A::simple1_adt:d1()
+simple1_api.erl:197: The type test is_integer(A::simple1_adt:d1()) breaks the opacity of the term A::simple1_adt:d1()
simple1_api.erl:221: Guard test A::simple1_api:i1() > 3 can never succeed
simple1_api.erl:225: Guard test A::simple1_adt:i1() > 3 contains an opaque term as 1st argument
simple1_api.erl:233: Guard test A::simple1_adt:i1() < 3 contains an opaque term as 1st argument
simple1_api.erl:239: Guard test A::1 > 3 can never succeed
simple1_api.erl:243: Guard test A::1 > 3 can never succeed
simple1_api.erl:257: Guard test is_function(T::simple1_api:o1()) can never succeed
-simple1_api.erl:265: Guard test is_function(T::simple1_adt:o1()) breaks the opaqueness of its argument
-simple1_api.erl:269: The type test is_function(T::simple1_adt:o1()) breaks the opaqueness of the term T::simple1_adt:o1()
+simple1_api.erl:265: Guard test is_function(T::simple1_adt:o1()) breaks the opacity of its argument
+simple1_api.erl:269: The type test is_function(T::simple1_adt:o1()) breaks the opacity of the term T::simple1_adt:o1()
simple1_api.erl:274: Guard test is_function(T::simple1_api:o1(),A::simple1_api:i1()) can never succeed
-simple1_api.erl:284: Guard test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opaqueness of its argument
-simple1_api.erl:289: The type test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opaqueness of the term T::simple1_adt:o1()
+simple1_api.erl:284: Guard test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opacity of its argument
+simple1_api.erl:289: The type test is_function(T::simple1_adt:o1(),A::simple1_adt:i1()) breaks the opacity of the term T::simple1_adt:o1()
simple1_api.erl:294: The call erlang:is_function(T::simple1_api:o1(),A::simple1_adt:i1()) contains an opaque term as 2nd argument when terms of different types are expected in these positions
-simple1_api.erl:300: The type test is_function(T::simple1_adt:o1(),A::simple1_api:i1()) breaks the opaqueness of the term T::simple1_adt:o1()
+simple1_api.erl:300: The type test is_function(T::simple1_adt:o1(),A::simple1_api:i1()) breaks the opacity of the term T::simple1_adt:o1()
simple1_api.erl:306: Guard test B::simple1_api:b2() =:= 'true' can never succeed
simple1_api.erl:315: Guard test A::simple1_api:b1() =:= 'false' can never succeed
simple1_api.erl:319: Guard test not('and'('true','true')) can never succeed
@@ -60,14 +60,14 @@ simple1_api.erl:365: Clause guard cannot succeed.
simple1_api.erl:368: Invalid type specification for function simple1_api:bool_adt_t8/2. The success typing is (boolean(),boolean()) -> 1
simple1_api.erl:378: Clause guard cannot succeed.
simple1_api.erl:381: Invalid type specification for function simple1_api:bool_adt_t9/2. The success typing is ('false','false') -> 1
-simple1_api.erl:407: The size simple1_adt:i1() breaks the opaqueness of A
-simple1_api.erl:418: The attempt to match a term of type non_neg_integer() against the variable A breaks the opaqueness of simple1_adt:i1()
-simple1_api.erl:425: The attempt to match a term of type non_neg_integer() against the variable B breaks the opaqueness of simple1_adt:i1()
+simple1_api.erl:407: The size simple1_adt:i1() breaks the opacity of A
+simple1_api.erl:418: The attempt to match a term of type non_neg_integer() against the variable A breaks the opacity of simple1_adt:i1()
+simple1_api.erl:425: The attempt to match a term of type non_neg_integer() against the variable B breaks the opacity of simple1_adt:i1()
simple1_api.erl:432: The pattern <<_:B/integer-unit:1>> can never match the type any()
-simple1_api.erl:448: The attempt to match a term of type non_neg_integer() against the variable Sz breaks the opaqueness of simple1_adt:i1()
-simple1_api.erl:460: The attempt to match a term of type simple1_adt:bit1() against the pattern <<_/binary-unit:8>> breaks the opaqueness of the term
-simple1_api.erl:478: The call 'foo':A(A::simple1_adt:a()) breaks the opaqueness of the term A :: simple1_adt:a()
-simple1_api.erl:486: The call A:'foo'(A::simple1_adt:a()) breaks the opaqueness of the term A :: simple1_adt:a()
+simple1_api.erl:448: The attempt to match a term of type non_neg_integer() against the variable Sz breaks the opacity of simple1_adt:i1()
+simple1_api.erl:460: The attempt to match a term of type simple1_adt:bit1() against the pattern <<_/binary-unit:8>> breaks the opacity of the term
+simple1_api.erl:478: The call 'foo':A(A::simple1_adt:a()) breaks the opacity of the term A :: simple1_adt:a()
+simple1_api.erl:486: The call A:'foo'(A::simple1_adt:a()) breaks the opacity of the term A :: simple1_adt:a()
simple1_api.erl:499: The call 'foo':A(A::simple1_api:i()) requires that A is of type atom() not simple1_api:i()
simple1_api.erl:503: The call 'foo':A(A::simple1_adt:i()) requires that A is of type atom() not simple1_adt:i()
simple1_api.erl:507: The call A:'foo'(A::simple1_api:i()) requires that A is of type atom() not simple1_api:i()
@@ -79,7 +79,7 @@ simple1_api.erl:538: Guard test A::simple1_adt:d1() =:= 3 contains an opaque ter
simple1_api.erl:548: The call erlang:'<'(A::simple1_adt:d1(),3) contains an opaque term as 1st argument when terms of different types are expected in these positions
simple1_api.erl:558: The call erlang:'=<'(A::simple1_adt:d1(),B::simple1_adt:d2()) contains opaque terms as 1st and 2nd arguments when terms of different types are expected in these positions
simple1_api.erl:565: Guard test {digraph:graph(),3} > {digraph:graph(),atom() | ets:tid()} contains an opaque term as 2nd argument
-simple1_api.erl:91: Invalid type specification for function simple1_api:tup/0. The success typing is () -> {'a','b'}
+simple1_api.erl:91: The specification for simple1_api:tup/0 has an opaque subtype simple1_adt:tuple1() which is violated by the success typing () -> {'a','b'}
simple2_api.erl:100: The call lists:flatten(A::simple1_adt:tuple1()) contains an opaque term as 1st argument when a structured term of type [any()] is expected
simple2_api.erl:116: The call lists:flatten({simple1_adt:tuple1()}) will never return since it differs in the 1st argument from the success typing arguments: ([any()])
simple2_api.erl:121: Guard test {simple1_adt:d1(),3} > {simple1_adt:d1(),simple1_adt:tuple1()} contains an opaque term as 2nd argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/timer b/lib/dialyzer/test/opaque_SUITE_data/results/timer
index b1cfcd4e9f..46c5a86307 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/timer
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/timer
@@ -1,4 +1,4 @@
timer_use.erl:16: The pattern 'gazonk' can never match the type {'error',_} | {'ok',timer:tref()}
-timer_use.erl:17: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {'ok', 42} breaks the opaqueness of timer:tref()
-timer_use.erl:18: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {Tag, 'gazonk'} breaks the opaqueness of timer:tref()
+timer_use.erl:17: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {'ok', 42} breaks the opacity of timer:tref()
+timer_use.erl:18: The attempt to match a term of type {'error',_} | {'ok',timer:tref()} against the pattern {Tag, 'gazonk'} breaks the opacity of timer:tref()
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/union b/lib/dialyzer/test/opaque_SUITE_data/results/union
index 98829b424a..8763088bf0 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/union
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/union
@@ -1,5 +1,5 @@
-union_use.erl:12: The attempt to match a term of type union_adt:u() against the pattern 'aaa' breaks the opaqueness of the term
-union_use.erl:16: The type test is_tuple(union_adt:u()) breaks the opaqueness of the term union_adt:u()
-union_use.erl:7: Guard test is_atom(A::union_adt:u()) breaks the opaqueness of its argument
-union_use.erl:8: Guard test is_tuple(T::union_adt:u()) breaks the opaqueness of its argument
+union_use.erl:12: The attempt to match a term of type union_adt:u() against the pattern 'aaa' breaks the opacity of the term
+union_use.erl:16: The type test is_tuple(union_adt:u()) breaks the opacity of the term union_adt:u()
+union_use.erl:7: Guard test is_atom(A::union_adt:u()) breaks the opacity of its argument
+union_use.erl:8: Guard test is_tuple(T::union_adt:u()) breaks the opacity of its argument
diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/wings b/lib/dialyzer/test/opaque_SUITE_data/results/wings
index 511263b70a..391501d86f 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/results/wings
+++ b/lib/dialyzer/test/opaque_SUITE_data/results/wings
@@ -1,11 +1,11 @@
-wings_dissolve.erl:103: Guard test is_list(List::gb_sets:set(_)) breaks the opaqueness of its argument
-wings_dissolve.erl:19: Guard test is_list(Faces::gb_sets:set(_)) breaks the opaqueness of its argument
-wings_dissolve.erl:272: Guard test is_list(Faces::gb_sets:set(_)) breaks the opaqueness of its argument
+wings_dissolve.erl:103: Guard test is_list(List::gb_sets:set(_)) breaks the opacity of its argument
+wings_dissolve.erl:19: Guard test is_list(Faces::gb_sets:set(_)) breaks the opacity of its argument
+wings_dissolve.erl:272: Guard test is_list(Faces::gb_sets:set(_)) breaks the opacity of its argument
wings_dissolve.erl:31: The call gb_sets:is_empty(Faces::[any(),...]) does not have an opaque term of type gb_sets:set(_) as 1st argument
wings_edge.erl:205: The pattern <Edge, 'hard', Htab> can never match the type <_,'soft',_>
wings_edge_cmd.erl:30: The call gb_trees:size(P::gb_sets:set(_)) does not have an opaque term of type gb_trees:tree(_,_) as 1st argument
wings_edge_cmd.erl:32: The pattern [_ | Parts] can never match the type []
wings_edge_cmd.erl:32: The pattern [{_, P} | _] can never match the type []
-wings_io.erl:30: The attempt to match a term of type {'empty',queue:queue(_)} against the pattern {'empty', {In, Out}} breaks the opaqueness of queue:queue(_)
+wings_io.erl:30: The attempt to match a term of type {'empty',queue:queue(_)} against the pattern {'empty', {In, Out}} breaks the opacity of queue:queue(_)
wings_we.erl:155: The call wings_util:gb_trees_largest_key(Etab::gb_trees:tree(_,_)) contains an opaque term as 1st argument when a structured term of type {_,{_,_,_,'nil' | {_,_,_,'nil' | {_,_,_,_}}}} is expected
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl b/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl
index a4cec065ab..2527f166f2 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/dict/dict_use.erl
@@ -34,7 +34,7 @@ middle() ->
{w1(), w2()}.
%%---------------------------------------------------------------------
-%% Cases that are problematic w.r.t. opaqueness of types
+%% Cases that are problematic w.r.t. opacity of types
%%---------------------------------------------------------------------
w1() ->
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_ig_moves.erl b/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_ig_moves.erl
index 2a70606dab..94768e77e7 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_ig_moves.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_ig_moves.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,10 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%=============================================================================
-module(hipe_ig_moves).
-export([new/1,
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_vectors.erl b/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_vectors.erl
index 279f244586..1890b86c8d 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_vectors.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/hipe_vectors/hipe_vectors.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% VECTORS IN ERLANG
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl b/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl
index 102215b28d..d8c1f561f7 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/para/para3.erl
@@ -62,7 +62,7 @@ t2() ->
%% Shows that the list TypeNames in t_from_form must include ArgsLen.
t1_adt() ->
- {{{{{17}}}}} = para3_adt:t1(3). % breaks the opaqueness
+ {{{{{17}}}}} = para3_adt:t1(3). % breaks the opacity
t2_adt() ->
{{{{17}}}} = para3_adt:t1(3). % can never match
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/cerl.erl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/cerl.erl
index a4fdbfd5f0..299ebe60d6 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/cerl.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/cerl.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%% =====================================================================
%% @doc Core Erlang abstract syntax trees.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/core_parse.hrl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/core_parse.hrl
index 5823622f05..14a53d0d2d 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/core_parse.hrl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/core_parse.hrl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% Purpose : Core Erlang syntax trees as records.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer.hrl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer.hrl
index ea6a71217c..c0f287893e 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer.hrl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer.hrl
@@ -1,9 +1,5 @@
%%% This is an -*- Erlang -*- file.
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
-%%%
%%%-------------------------------------------------------------------
%%% File : dialyzer.hrl
%%% Author : Tobias Lindahl <[email protected]>
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_dataflow.erl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_dataflow.erl
index 9399789464..6a5b593db0 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_dataflow.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_dataflow.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%--------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : dialyzer_dataflow.erl
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_races.erl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_races.erl
index bb43d1dcb8..7fe64c3e11 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_races.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/dialyzer_races.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%----------------------------------------------------------------------
%%% File : dialyzer_races.erl
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/erl_types.erl b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/erl_types.erl
index 7826dada9d..41e3d4be27 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/recrec/erl_types.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/recrec/erl_types.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%% ======================================================================
%% Copyright (C) 2000-2003 Richard Carlsson
%%
@@ -4366,7 +4360,7 @@ record_field_diffs_to_string(?tuple([_|Fs], Arity, Tag), RecDict) ->
string:join(FieldDiffs, " and ").
field_diffs([F|Fs], [{FName, _Abstr, DefType}|FDefs], RecDict, Acc) ->
- %% Don't care about opaqueness for now.
+ %% Don't care about opacity for now.
NewAcc =
case not t_is_none(t_inf(F, DefType)) of
true -> Acc;
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl
index c19330eb30..597460ce77 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/exact_api.erl
@@ -52,7 +52,7 @@ exact_api_set_type(#exact_api{}=E) -> E.
-record(exact_adt, {}).
exact_adt_test(X) ->
- #exact_adt{} = exact_adt:exact_adt_set_type(X). % breaks the opaqueness
+ #exact_adt{} = exact_adt:exact_adt_set_type(X). % breaks the opacity
exact_adt_new(A) ->
A = #exact_adt{},
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/is_rec.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/is_rec.erl
index 2b157483bc..b906431b44 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/is_rec.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/is_rec.erl
@@ -16,11 +16,11 @@ ri11() ->
ri13() ->
A = simple1_adt:d1(),
- if is_record(A, r) -> true end. % breaks the opaqueness
+ if is_record(A, r) -> true end. % breaks the opacity
ri14() ->
A = simple1_adt:d1(),
- if is_record({A, 1}, r) -> true end. % breaks the opaqueness
+ if is_record({A, 1}, r) -> true end. % breaks the opacity
-type '1-3-t'() :: 1..3.
@@ -54,7 +54,7 @@ ri5() ->
ri6() ->
A = simple1_adt:d1(),
- if is_record(A, r) -> true end. % breaks opaqueness
+ if is_record(A, r) -> true end. % breaks opacity
ri7() ->
A = simple1_adt:d1(),
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl
index fb6d59d263..59b9e0fec4 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/rec_api.erl
@@ -30,7 +30,7 @@ t3() ->
adt_t1() ->
R = rec_adt:r1(),
- {r1, a} = R. % breaks the opaqueness
+ {r1, a} = R. % breaks the opacity
-spec adt_t1(rec_adt:r1()) -> rec_adt:r1(). % invalid type spec
@@ -82,7 +82,7 @@ f() ->
r_adt() ->
{{r, rec_adt:f(), 2},
- #r{f = rec_adt:f(), o = 2}}. % breaks the opaqueness
+ #r{f = rec_adt:f(), o = 2}}. % breaks the opacity
-record(r2, % like #r1{}, but with initial value
{f1 = a :: a()}).
@@ -110,7 +110,7 @@ u3() ->
v1() ->
A = #r3{f1 = queue:new()},
- {r3, a} = A. % breaks the opaqueness
+ {r3, a} = A. % breaks the opacity
v2() ->
A = {r3, 10},
@@ -120,4 +120,4 @@ v2() ->
v3() ->
A = {r3, 10},
- #r3{f1 = 10} = A. % breaks the opaqueness
+ #r3{f1 = 10} = A. % breaks the opacity
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl b/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl
index 7db1100597..d67aa913d8 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/simple/simple1_api.erl
@@ -194,7 +194,7 @@ tt1() ->
tt2() ->
A = simple1_adt:d1(),
- is_integer(A). % breaks the opaqueness
+ is_integer(A). % breaks the opacity
%% Comparison with integers
@@ -262,11 +262,11 @@ f2() ->
adt_f1() ->
T = simple1_adt:n1(),
- if is_function(T) -> ok end. % breaks the opaqueness
+ if is_function(T) -> ok end. % breaks the opacity
adt_f2() ->
T = simple1_adt:n1(),
- is_function(T). % breaks the opaqueness
+ is_function(T). % breaks the opacity
f3() ->
A = i1(),
@@ -281,12 +281,12 @@ f4() ->
adt_f3() ->
A = simple1_adt:i1(),
T = simple1_adt:n1(),
- if is_function(T, A) -> ok end. % breaks the opaqueness
+ if is_function(T, A) -> ok end. % breaks the opacity
adt_f4() ->
A = simple1_adt:i1(),
T = simple1_adt:n1(),
- is_function(T, A). % breaks the opaqueness
+ is_function(T, A). % breaks the opacity
adt_f4_a() ->
A = simple1_adt:i1(),
@@ -297,7 +297,7 @@ adt_f4_a() ->
adt_f4_b() ->
A = i1(),
T = simple1_adt:n1(),
- is_function(T, A). % breaks the opaqueness
+ is_function(T, A). % breaks the opacity
%% A few Boolean examples
@@ -404,7 +404,7 @@ bit_t1() ->
bit_adt_t1() ->
A = simple1_adt:i1(),
- <<100:(A)>>. % breaks the opaqueness
+ <<100:(A)>>. % breaks the opacity
bit_t3(A) ->
B = i1(),
@@ -415,14 +415,14 @@ bit_t3(A) ->
bit_adt_t2() ->
A = simple1_adt:i1(),
case <<"hej">> of
- <<_:A>> -> ok % breaks the opaqueness (but the message is strange)
+ <<_:A>> -> ok % breaks the opacity (but the message is strange)
end.
bit_adt_t3(A) ->
B = simple1_adt:i1(),
case none:none() of
- <<A: % breaks the opaqueness (the message is less than perfect)
+ <<A: % breaks the opacity (the message is less than perfect)
B>> -> 1
end.
@@ -445,7 +445,7 @@ bit_t4(A) ->
bit_adt_t4(A) ->
Sz = simple1_adt:i1(),
case A of
- <<_:Sz>> -> 1 % breaks the opaqueness
+ <<_:Sz>> -> 1 % breaks the opacity
end.
bit_t5() ->
@@ -457,7 +457,7 @@ bit_t5() ->
bit_adt_t5() ->
A = simple1_adt:bit1(),
case A of
- <<_/binary>> -> 1 % breaks the opaqueness
+ <<_/binary>> -> 1 % breaks the opacity
end.
-opaque bit1() :: binary().
@@ -475,7 +475,7 @@ call_f(A) ->
call_f_adt(A) ->
A = simple1_adt:a(),
- foo:A(A). % breaks the opaqueness
+ foo:A(A). % breaks the opacity
call_m(A) ->
A = a(),
@@ -483,7 +483,7 @@ call_m(A) ->
call_m_adt(A) ->
A = simple1_adt:a(),
- A:foo(A). % breaks the opaqueness
+ A:foo(A). % breaks the opacity
-opaque a() :: atom().
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/timer/timer_use.erl b/lib/dialyzer/test/opaque_SUITE_data/src/timer/timer_use.erl
index 9c8ea0af1c..ed6810634f 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/timer/timer_use.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/timer/timer_use.erl
@@ -1,8 +1,8 @@
%%---------------------------------------------------------------------------
%% A test case with:
%% - a genuine matching error -- 1st branch
-%% - a violation of the opaqueness of timer:tref() -- 2nd branch
-%% - a subtle violation of the opaqueness of timer:tref() -- 3rd branch
+%% - a violation of the opacity of timer:tref() -- 2nd branch
+%% - a subtle violation of the opacity of timer:tref() -- 3rd branch
%% The test is supposed to check that these cases are treated properly.
%%---------------------------------------------------------------------------
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl b/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl
index ca6bc0ab4a..6b825d85fe 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/wings/wings_util.erl
@@ -14,12 +14,12 @@
rel2fam(Rel) ->
sofs:to_external(sofs:relation_to_family(sofs:relation(Rel))).
-%% a definition that does not violate the opaqueness of gb_trees:tree()
+%% a definition that does not violate the opacity of gb_trees:tree()
gb_trees_smallest_key(Tree) ->
{Key, _V} = gb_trees:smallest(Tree),
Key.
-%% a definition that violates the opaqueness of gb_trees:tree()
+%% a definition that violates the opacity of gb_trees:tree()
gb_trees_largest_key({_, Tree}) ->
largest_key1(Tree).
diff --git a/lib/dialyzer/test/small_SUITE_data/results/guards b/lib/dialyzer/test/small_SUITE_data/results/guards
index 824a7cfa24..cd0d3cace0 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/guards
+++ b/lib/dialyzer/test/small_SUITE_data/results/guards
@@ -10,8 +10,8 @@ guards.erl:136: The call guards:t16('a') will never return since it differs in t
guards.erl:136: The call guards:t16('c') will never return since it differs in the 1st argument from the success typing arguments: ('b')
guards.erl:55: Function t5/1 has no local return
guards.erl:55: Guard test is_integer(A::atom()) can never succeed
-guards.erl:59: Clause guard cannot succeed. The variable A was matched against the type any()
guards.erl:59: Function t6/1 has no local return
+guards.erl:59: Guard test is_integer(A::atom()) can never succeed
guards.erl:67: The call guards:t7({42}) will never return since it differs in the 1st argument from the success typing arguments: (atom() | integer())
guards.erl:75: The call guards:t8({42}) will never return since it differs in the 1st argument from the success typing arguments: (atom() | integer())
guards.erl:92: The variable _ can never match since previous clauses completely covered the type {'true','true'}
diff --git a/lib/dialyzer/test/small_SUITE_data/src/ms.erl b/lib/dialyzer/test/small_SUITE_data/src/ms.erl
new file mode 100644
index 0000000000..47a5e886cf
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/ms.erl
@@ -0,0 +1,8 @@
+-module(ms).
+-export([t/0]).
+
+-include_lib("stdlib/include/ms_transform.hrl").
+
+t() ->
+ MS = dbg:fun2ms(fun(All) -> message(All) end),
+ erlang:trace_pattern({m, f, '_'}, MS).
diff --git a/lib/edoc/COPYING b/lib/edoc/COPYING
deleted file mode 100644
index 223ede7de3..0000000000
--- a/lib/edoc/COPYING
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/lib/edoc/doc/overview.edoc b/lib/edoc/doc/overview.edoc
index 3a2118928a..981320f1fc 100644
--- a/lib/edoc/doc/overview.edoc
+++ b/lib/edoc/doc/overview.edoc
@@ -276,11 +276,11 @@ The following tags can be used before a module declaration:
```%% @author Richard Carlsson'''
```%% @author Richard Carlsson <[email protected]>
- %% [http://user.it.uu.se/~richardc/]'''
+ %% [http://example.net/richardc/]'''
```%% @author <[email protected]>'''
-```%% @author [email protected] [http://user.it.uu.se/~richardc/]'''
+```%% @author [email protected] [http://example.net/richardc/]'''
</dd>
<dt><a name="mtag-copyright">`@copyright'</a></dt>
diff --git a/lib/edoc/include/edoc_doclet.hrl b/lib/edoc/include/edoc_doclet.hrl
index ac6763fb33..1429ee5971 100644
--- a/lib/edoc/include/edoc_doclet.hrl
+++ b/lib/edoc/include/edoc_doclet.hrl
@@ -3,20 +3,25 @@
%%
%% Copyright (C) 2001-2004 Richard Carlsson
%%
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% Author contact: [email protected]
%% =====================================================================
diff --git a/lib/edoc/src/edoc.erl b/lib/edoc/src/edoc.erl
index 94013bb5ac..7276a57268 100644
--- a/lib/edoc/src/edoc.erl
+++ b/lib/edoc/src/edoc.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2001-2007 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/edoc/src/edoc.hrl b/lib/edoc/src/edoc.hrl
index 5b0fb68cf9..1ec64561a1 100644
--- a/lib/edoc/src/edoc.hrl
+++ b/lib/edoc/src/edoc.hrl
@@ -3,20 +3,25 @@
%%
%% Copyright (C) 2001-2004 Richard Carlsson
%%
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% Author contact: [email protected]
%% =====================================================================
diff --git a/lib/edoc/src/edoc_data.erl b/lib/edoc/src/edoc_data.erl
index b797d74a71..7c077d3acd 100644
--- a/lib/edoc/src/edoc_data.erl
+++ b/lib/edoc/src/edoc_data.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2003 Richard Carlsson
diff --git a/lib/edoc/src/edoc_doclet.erl b/lib/edoc/src/edoc_doclet.erl
index 5961ca8cc0..006b07574b 100644
--- a/lib/edoc/src/edoc_doclet.erl
+++ b/lib/edoc/src/edoc_doclet.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2003-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/edoc/src/edoc_extract.erl b/lib/edoc/src/edoc_extract.erl
index 2d6cb04a6d..68edad1a3e 100644
--- a/lib/edoc/src/edoc_extract.erl
+++ b/lib/edoc/src/edoc_extract.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/edoc/src/edoc_layout.erl b/lib/edoc/src/edoc_layout.erl
index ef57b7b084..9407ae1321 100644
--- a/lib/edoc/src/edoc_layout.erl
+++ b/lib/edoc/src/edoc_layout.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2001-2006 Richard Carlsson
diff --git a/lib/edoc/src/edoc_lib.erl b/lib/edoc/src/edoc_lib.erl
index cc0a8d0b94..ebdb0f79f6 100644
--- a/lib/edoc/src/edoc_lib.erl
+++ b/lib/edoc/src/edoc_lib.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/edoc/src/edoc_macros.erl b/lib/edoc/src/edoc_macros.erl
index e1a54d5090..d5a11d438b 100644
--- a/lib/edoc/src/edoc_macros.erl
+++ b/lib/edoc/src/edoc_macros.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2001-2005 Richard Carlsson
diff --git a/lib/edoc/src/edoc_parser.yrl b/lib/edoc/src/edoc_parser.yrl
index 68a3439f10..30e09444b0 100644
--- a/lib/edoc/src/edoc_parser.yrl
+++ b/lib/edoc/src/edoc_parser.yrl
@@ -7,20 +7,25 @@
%%
%% Copyright (C) 2002-2005 Richard Carlsson
%%
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% Author contact: [email protected]
%% =====================================================================
@@ -238,58 +243,37 @@ throws -> etype where_defs:
#t_throws{type = '$1',
defs = '$2'}.
-%% (commented out for now)
-%% Header
-%% "%% ========================== -*-Erlang-*- ============================="
-%% "%% EDoc function specification parser, generated from the file"
-%% "%% \"edoc_parser.yrl\" by the Yecc parser generator."
-%% "%%"
-%% "%% Copyright (C) 2002-2005 Richard Carlsson"
-%% "%%"
-%% "%% This library is free software; you can redistribute it and/or modify"
-%% "%% it under the terms of the GNU Lesser General Public License as"
-%% "%% published by the Free Software Foundation; either version 2 of the"
-%% "%% License, or (at your option) any later version."
-%% "%%"
-%% "%% This library is distributed in the hope that it will be useful, but"
-%% "%% WITHOUT ANY WARRANTY; without even the implied warranty of"
-%% "%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU"
-%% "%% Lesser General Public License for more details."
-%% "%%"
-%% "%% You should have received a copy of the GNU Lesser General Public"
-%% "%% License along with this library; if not, write to the Free Software"
-%% "%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307"
-%% "%% USA"
-%% "%%"
-%% "%% @private"
-%% "%% @author Richard Carlsson <[email protected]>"
-%% "%% ===================================================================="
-%% .
+Header
+"%% EDoc function specification parser, generated from the file"
+"%% \"edoc_parser.yrl\" by the Yecc parser generator."
+"%%"
+"%% Licensed under the Apache License, Version 2.0 (the \"License\"); you may"
+"%% not use this file except in compliance with the License. You may obtain"
+"%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>"
+"%%"
+"%% Unless required by applicable law or agreed to in writing, software"
+"%% distributed under the License is distributed on an \"AS IS\" BASIS,"
+"%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."
+"%% See the License for the specific language governing permissions and"
+"%% limitations under the License."
+"%%"
+"%% Alternatively, you may use this file under the terms of the GNU Lesser"
+"%% General Public License (the \"LGPL\") as published by the Free Software"
+"%% Foundation; either version 2.1, or (at your option) any later version."
+"%% If you wish to allow use of your version of this file only under the"
+"%% terms of the LGPL, you should delete the provisions above and replace"
+"%% them with the notice and other provisions required by the LGPL; see"
+"%% <http://www.gnu.org/licenses/>. If you do not delete the provisions"
+"%% above, a recipient may use your version of this file under the terms of"
+"%% either the Apache License or the LGPL."
+"%%"
+"%% @private"
+"%% @copyright 2002-2005 Richard Carlsson"
+"%% @author Richard Carlsson <[email protected]>"
+"".
Erlang code.
-%% ========================== -*-Erlang-*- =============================
-%% EDoc function specification parser, generated from the file
-%% "edoc_parser.yrl" by the Yecc parser generator.
-%%
-%% Copyright (C) 2002-2005 Richard Carlsson
-%%
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
-%% ====================================================================
-
-export([parse_spec/2, parse_typedef/2, parse_throws/2, parse_ref/2,
parse_see/2, parse_param/2]).
diff --git a/lib/edoc/src/edoc_refs.erl b/lib/edoc/src/edoc_refs.erl
index b9a9391053..6ff0da0b75 100644
--- a/lib/edoc/src/edoc_refs.erl
+++ b/lib/edoc/src/edoc_refs.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2003 Richard Carlsson
diff --git a/lib/edoc/src/edoc_report.erl b/lib/edoc/src/edoc_report.erl
index dc6320df6d..ed778c8112 100644
--- a/lib/edoc/src/edoc_report.erl
+++ b/lib/edoc/src/edoc_report.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
diff --git a/lib/edoc/src/edoc_run.erl b/lib/edoc/src/edoc_run.erl
index 261a649c70..c88c6cfd78 100644
--- a/lib/edoc/src/edoc_run.erl
+++ b/lib/edoc/src/edoc_run.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @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 93f423b906..7e59f373b2 100644
--- a/lib/edoc/src/edoc_tags.erl
+++ b/lib/edoc/src/edoc_tags.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
diff --git a/lib/edoc/src/edoc_types.erl b/lib/edoc/src/edoc_types.erl
index 5bb68e79fb..ccc3169767 100644
--- a/lib/edoc/src/edoc_types.erl
+++ b/lib/edoc/src/edoc_types.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
diff --git a/lib/edoc/src/edoc_types.hrl b/lib/edoc/src/edoc_types.hrl
index 3e5e91484f..99719793d0 100644
--- a/lib/edoc/src/edoc_types.hrl
+++ b/lib/edoc/src/edoc_types.hrl
@@ -3,20 +3,25 @@
%%
%% Copyright (C) 2001-2005 Richard Carlsson
%%
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% Author contact: [email protected]
%% =====================================================================
diff --git a/lib/edoc/src/edoc_wiki.erl b/lib/edoc/src/edoc_wiki.erl
index 5d0d78bf3c..574880703c 100644
--- a/lib/edoc/src/edoc_wiki.erl
+++ b/lib/edoc/src/edoc_wiki.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
diff --git a/lib/edoc/src/otpsgml_layout.erl b/lib/edoc/src/otpsgml_layout.erl
index 052c75b9d4..295daed551 100644
--- a/lib/edoc/src/otpsgml_layout.erl
+++ b/lib/edoc/src/otpsgml_layout.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @author Kenneth Lundin <[email protected]>
diff --git a/lib/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml
index 43873e44e2..f2c7889e58 100644
--- a/lib/eldap/doc/src/eldap.xml
+++ b/lib/eldap/doc/src/eldap.xml
@@ -197,7 +197,7 @@
</type>
<desc>
<p> Add an entry. The entry must not exist.</p>
- <pre>
+ <code>
add(Handle,
"cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com",
[{"objectclass", ["person"]},
@@ -205,7 +205,7 @@
{"sn", ["Valentine"]},
{"telephoneNumber", ["545 555 00"]}]
)
- </pre>
+ </code>
</desc>
</func>
<func>
@@ -216,9 +216,9 @@
</type>
<desc>
<p> Delete an entry.</p>
- <pre>
+ <code>
delete(Handle, "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com")
- </pre>
+ </code>
</desc>
</func>
@@ -259,11 +259,11 @@
</type>
<desc>
<p> Modify an entry.</p>
- <pre>
+ <code>
modify(Handle, "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com",
[eldap:mod_replace("telephoneNumber", ["555 555 00"]),
eldap:mod_add("description", ["LDAP Hacker"]) ])
- </pre>
+ </code>
</desc>
</func>
<func>
@@ -320,10 +320,10 @@
whether the current RDN should be removed from the attribute list after the after operation.
<c>NewSupDN</c> is the new parent that the RDN shall be moved to. If the old parent should
remain as parent, <c>NewSupDN</c> shall be "".</p>
- <pre>
+ <code>
modify_dn(Handle, "cn=Bill Valentine, ou=people, o=Example Org, dc=example, dc=com ",
"cn=Bill Jr Valentine", true, "")
- </pre>
+ </code>
</desc>
</func>
<func>
@@ -342,10 +342,10 @@
Default values: scope is <c>wholeSubtree()</c>, deref is <c>derefAlways()</c>,
types_only is <c>false</c> and timeout is <c>0</c> (meaning infinity).
</p>
- <pre>
+ <code>
Filter = eldap:substrings("cn", [{any,"V"}]),
search(Handle, [{base, "dc=example, dc=com"}, {filter, Filter}, {attributes, ["cn"]}]),
- </pre>
+ </code>
<p>The <c>timeout</c> option in the <c>SearchOptions</c> is for the ldap server, while
the timeout in <seealso marker="#open/2">eldap:open/2</seealso> is used for each
individual request in the search operation.
@@ -454,7 +454,7 @@
</type>
<desc> <p>Creates an extensible match filter. For example, </p>
<code>
- eldap:extensibleMatch("Bar", [{type,"sn"}, {matchingRule,"caseExactMatch"}]))
+ eldap:extensibleMatch("Bar", [{type,"sn"}, {matchingRule,"caseExactMatch"}]))
</code>
<p>creates a filter which performs a <c>caseExactMatch</c> on the attribute <c>sn</c> and matches with the value <c>"Bar"</c>. The default value of <c>dnAttributes</c> is <c>false</c>.</p> </desc>
</func>
diff --git a/lib/erl_docgen/src/docgen_edoc_xml_cb.erl b/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
index 13ff0a139d..7cdbb502d9 100644
--- a/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
+++ b/lib/erl_docgen/src/docgen_edoc_xml_cb.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +10,10 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
+%% Copyright (c) 2001-2016 Richard Carlsson. Parts written by Ericsson
+%% are Copyright (c) Ericsson AB 2001-2012. All Rights Reserved.
%%
+
-module(docgen_edoc_xml_cb).
%% This is the EDoc callback module for creating erlref
@@ -27,7 +24,7 @@
%% {preprocess,true}]).
%%
%% The origin of this file is the edoc module otpsgml_layout.erl
-%% written by Richard Carlsson.
+%% written by Richard Carlsson and Kenneth Lundin.
-export([module/2, overview/2]).
diff --git a/lib/eunit/COPYING b/lib/eunit/COPYING
deleted file mode 100644
index 223ede7de3..0000000000
--- a/lib/eunit/COPYING
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/lib/eunit/include/eunit.hrl b/lib/eunit/include/eunit.hrl
index 8a4cad1e7e..3cc36a27bc 100644
--- a/lib/eunit/include/eunit.hrl
+++ b/lib/eunit/include/eunit.hrl
@@ -1,17 +1,26 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
+%%
+%% NOTE: An object file that uses the macros in this header file shall
+%% never be considered a derived work under the the LGPL; these macros
+%% shall be regarded as "small" regardless of the exact line count.
%%
%% Copyright (C) 2004-2006 Mickaël Rémond, Richard Carlsson
diff --git a/lib/eunit/src/eunit.erl b/lib/eunit/src/eunit.erl
index fbfd123c43..2c832a7f7a 100644
--- a/lib/eunit/src/eunit.erl
+++ b/lib/eunit/src/eunit.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2004-2009 Mickaël Rémond, Richard Carlsson
%% @author Mickaël Rémond <[email protected]>
diff --git a/lib/eunit/src/eunit_autoexport.erl b/lib/eunit/src/eunit_autoexport.erl
index 7bb78f5ea8..6d52620629 100644
--- a/lib/eunit/src/eunit_autoexport.erl
+++ b/lib/eunit/src/eunit_autoexport.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_data.erl b/lib/eunit/src/eunit_data.erl
index cc002cb449..a16faf2e80 100644
--- a/lib/eunit/src/eunit_data.erl
+++ b/lib/eunit/src/eunit_data.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_internal.hrl b/lib/eunit/src/eunit_internal.hrl
index 8e1e27811f..65f4c433e7 100644
--- a/lib/eunit/src/eunit_internal.hrl
+++ b/lib/eunit/src/eunit_internal.hrl
@@ -1,5 +1,22 @@
-%% -------------------------------------------------------------------
-%% File: eunit_internal.hrl
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% Copyright (C) 2006 Richard Carlsson <[email protected]>
diff --git a/lib/eunit/src/eunit_lib.erl b/lib/eunit/src/eunit_lib.erl
index 9dbb4835f8..aa2cffc66d 100644
--- a/lib/eunit/src/eunit_lib.erl
+++ b/lib/eunit/src/eunit_lib.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2004-2007 Mickaël Rémond, Richard Carlsson
%% @author Mickaël Rémond <[email protected]>
diff --git a/lib/eunit/src/eunit_listener.erl b/lib/eunit/src/eunit_listener.erl
index c34eacb1d6..e652c5b2f6 100644
--- a/lib/eunit/src/eunit_listener.erl
+++ b/lib/eunit/src/eunit_listener.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2009 Richard Carlsson
diff --git a/lib/eunit/src/eunit_proc.erl b/lib/eunit/src/eunit_proc.erl
index 8bdf94c877..e075005238 100644
--- a/lib/eunit/src/eunit_proc.erl
+++ b/lib/eunit/src/eunit_proc.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_serial.erl b/lib/eunit/src/eunit_serial.erl
index da76064a53..d85cc520f2 100644
--- a/lib/eunit/src/eunit_serial.erl
+++ b/lib/eunit/src/eunit_serial.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_server.erl b/lib/eunit/src/eunit_server.erl
index 387976eba1..e46394d88c 100644
--- a/lib/eunit/src/eunit_server.erl
+++ b/lib/eunit/src/eunit_server.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_striptests.erl b/lib/eunit/src/eunit_striptests.erl
index c6ade389ba..2911c90022 100644
--- a/lib/eunit/src/eunit_striptests.erl
+++ b/lib/eunit/src/eunit_striptests.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @author Eric Merritt <[email protected]>
diff --git a/lib/eunit/src/eunit_surefire.erl b/lib/eunit/src/eunit_surefire.erl
index 1b468551d8..6b306c51d3 100644
--- a/lib/eunit/src/eunit_surefire.erl
+++ b/lib/eunit/src/eunit_surefire.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Mickaël Rémond <[email protected]>
%% @copyright 2009 Mickaël Rémond, Paul Guyot
diff --git a/lib/eunit/src/eunit_test.erl b/lib/eunit/src/eunit_test.erl
index 62d30b1930..6036537178 100644
--- a/lib/eunit/src/eunit_test.erl
+++ b/lib/eunit/src/eunit_test.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006 Richard Carlsson
diff --git a/lib/eunit/src/eunit_tests.erl b/lib/eunit/src/eunit_tests.erl
index 5dee1cb49e..07a415eeb1 100644
--- a/lib/eunit/src/eunit_tests.erl
+++ b/lib/eunit/src/eunit_tests.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2007 Richard Carlsson
diff --git a/lib/eunit/src/eunit_tty.erl b/lib/eunit/src/eunit_tty.erl
index f604ca5ba3..77a7cf1fd5 100644
--- a/lib/eunit/src/eunit_tty.erl
+++ b/lib/eunit/src/eunit_tty.erl
@@ -1,17 +1,22 @@
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2006-2009 Richard Carlsson
diff --git a/lib/hipe/amd64/hipe_amd64_assemble.erl b/lib/hipe/amd64/hipe_amd64_assemble.erl
index a7b11f7c72..1379850515 100644
--- a/lib/hipe/amd64/hipe_amd64_assemble.erl
+++ b/lib/hipe/amd64/hipe_amd64_assemble.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,7 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
+
-include("../x86/hipe_x86_assemble.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_defuse.erl b/lib/hipe/amd64/hipe_amd64_defuse.erl
index 907f078f3f..9074c3e05e 100644
--- a/lib/hipe/amd64/hipe_amd64_defuse.erl
+++ b/lib/hipe/amd64/hipe_amd64_defuse.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_defuse.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_encode.erl b/lib/hipe/amd64/hipe_amd64_encode.erl
index df15732cea..f8cc0c7d83 100644
--- a/lib/hipe/amd64/hipe_amd64_encode.erl
+++ b/lib/hipe/amd64/hipe_amd64_encode.erl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Copyright (C) 2000-2004 Mikael Pettersson
%%% Copyright (C) 2004 Daniel Luna
@@ -63,7 +56,7 @@
-export([% condition codes
cc/1,
% 8-bit registers
- %% al/0, cl/0, dl/0, bl/0, ah/0, ch/0, dh/0, bh/0,
+ %% al/0, cl/0, dl/0, bl/0,
% 32-bit registers
%% eax/0, ecx/0, edx/0, ebx/0, esp/0, ebp/0, esi/0, edi/0,
% operands
@@ -127,19 +120,15 @@ cc(g) -> ?CC_G.
-define(CL, 2#001).
-define(DL, 2#010).
-define(BL, 2#011).
--define(AH, 2#100).
--define(CH, 2#101).
--define(DH, 2#110).
--define(BH, 2#111).
+-define(SPL, 2#100).
+-define(BPL, 2#101).
+-define(SIL, 2#110).
+-define(DIL, 2#111).
%% al() -> ?AL.
%% cl() -> ?CL.
%% dl() -> ?DL.
%% bl() -> ?BL.
-%% ah() -> ?AH.
-%% ch() -> ?CH.
-%% dh() -> ?DH.
-%% bh() -> ?BH.
%%% 32-bit registers
@@ -208,6 +197,7 @@ rex_([]) -> 0;
rex_([{r8, Reg8}| Rest]) -> % 8 bit registers
case Reg8 of
{rm_mem, _} -> rex_(Rest);
+ {rm_reg, R} -> rex_([{r8, R} | Rest]);
4 -> (1 bsl 8) bor rex_(Rest);
5 -> (1 bsl 8) bor rex_(Rest);
6 -> (1 bsl 8) bor rex_(Rest);
@@ -825,12 +815,26 @@ shd_op_encode(Opcode, Opnds) ->
test_encode(Opnds) ->
case Opnds of
+ {al, {imm8,Imm8}} ->
+ [16#A8, Imm8];
+ {ax, {imm16,Imm16}} ->
+ [?PFX_OPND_16BITS, 16#A9 | le16(Imm16, [])];
{eax, {imm32,Imm32}} ->
[16#A9 | le32(Imm32, [])];
+ {rax, {imm32,Imm32}} ->
+ [rex([{w,1}]), 16#A9 | le32(Imm32, [])];
+ {{rm8,RM8}, {imm8,Imm8}} ->
+ [rex([{r8,RM8}]), 16#F6 | encode_rm(RM8, 2#000, [Imm8])];
+ {{rm16,RM16}, {imm16,Imm16}} ->
+ [?PFX_OPND_16BITS, 16#F7 | encode_rm(RM16, 2#000, le16(Imm16, []))];
{{rm32,RM32}, {imm32,Imm32}} ->
[16#F7 | encode_rm(RM32, 2#000, le32(Imm32, []))];
+ {{rm64,RM64}, {imm32,Imm32}} ->
+ [rex([{w,1}]), 16#F7 | encode_rm(RM64, 2#000, le32(Imm32, []))];
{{rm32,RM32}, {reg32,Reg32}} ->
- [16#85 | encode_rm(RM32, Reg32, [])]
+ [16#85 | encode_rm(RM32, Reg32, [])];
+ {{rm64,RM64}, {reg64,Reg64}} ->
+ [rex([{w,1}]), 16#85 | encode_rm(RM64, Reg64, [])]
end.
%% test_sizeof(Opnds) ->
@@ -1309,18 +1313,21 @@ dotest1(OS) ->
Imm32 = {imm32,Word32},
Imm16 = {imm16,Word16},
Imm8 = {imm8,Word8},
+ RM64 = {rm64,rm_reg(?EDX)},
RM32 = {rm32,rm_reg(?EDX)},
RM16 = {rm16,rm_reg(?EDX)},
RM8 = {rm8,rm_reg(?EDX)},
+ RM8REX = {rm8,rm_reg(?SIL)},
Rel32 = {rel32,Word32},
Rel8 = {rel8,Word8},
Moffs32 = {moffs32,Word32},
Moffs16 = {moffs16,Word32},
Moffs8 = {moffs8,Word32},
CC = {cc,?CC_G},
+ Reg64 = {reg64,?EAX},
Reg32 = {reg32,?EAX},
Reg16 = {reg16,?EAX},
- Reg8 = {reg8,?AH},
+ Reg8 = {reg8,?SPL},
EA = {ea,ea_base(?ECX)},
% exercise each instruction definition
t(OS,'adc',{eax,Imm32}),
@@ -1465,9 +1472,17 @@ dotest1(OS) ->
t(OS,'sub',{RM32,Imm8}),
t(OS,'sub',{RM32,Reg32}),
t(OS,'sub',{Reg32,RM32}),
+ t(OS,'test',{al,Imm8}),
+ t(OS,'test',{ax,Imm16}),
t(OS,'test',{eax,Imm32}),
+ t(OS,'test',{rax,Imm32}),
+ t(OS,'test',{RM8,Imm8}),
+ t(OS,'test',{RM8REX,Imm8}),
+ t(OS,'test',{RM16,Imm16}),
t(OS,'test',{RM32,Imm32}),
+ t(OS,'test',{RM64,Imm32}),
t(OS,'test',{RM32,Reg32}),
+ t(OS,'test',{RM64,Reg64}),
t(OS,'xor',{eax,Imm32}),
t(OS,'xor',{RM32,Imm32}),
t(OS,'xor',{RM32,Imm8}),
diff --git a/lib/hipe/amd64/hipe_amd64_frame.erl b/lib/hipe/amd64/hipe_amd64_frame.erl
index f3bcdf302a..800f1c1a08 100644
--- a/lib/hipe/amd64/hipe_amd64_frame.erl
+++ b/lib/hipe/amd64/hipe_amd64_frame.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_frame.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_liveness.erl b/lib/hipe/amd64/hipe_amd64_liveness.erl
index 5cfdbb0f3e..a1e8403df1 100644
--- a/lib/hipe/amd64/hipe_amd64_liveness.erl
+++ b/lib/hipe/amd64/hipe_amd64_liveness.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_liveness.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_main.erl b/lib/hipe/amd64/hipe_amd64_main.erl
index c22c6cd73b..75b7746500 100644
--- a/lib/hipe/amd64/hipe_amd64_main.erl
+++ b/lib/hipe/amd64/hipe_amd64_main.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_main.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_pp.erl b/lib/hipe/amd64/hipe_amd64_pp.erl
index 7c3ee8458a..9dfe571122 100644
--- a/lib/hipe/amd64/hipe_amd64_pp.erl
+++ b/lib/hipe/amd64/hipe_amd64_pp.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_pp.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra.erl b/lib/hipe/amd64/hipe_amd64_ra.erl
index 1d8453d54d..052e9c1e63 100644
--- a/lib/hipe/amd64/hipe_amd64_ra.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_ra.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra_finalise.erl b/lib/hipe/amd64/hipe_amd64_ra_finalise.erl
index d835c3ec14..82d462fad7 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_finalise.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_finalise.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_ra_finalise.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra_ls.erl b/lib/hipe/amd64/hipe_amd64_ra_ls.erl
index 9361b91f04..9fa0edca47 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_ls.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_ls.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_ra_ls.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra_naive.erl b/lib/hipe/amd64/hipe_amd64_ra_naive.erl
index 38218a65dc..1aa40121c9 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_naive.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_naive.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_ra_naive.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl b/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl
index 2d03239ea6..9359e0db0a 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_postconditions.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_ra_postconditions.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl b/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
index d062c0b37c..8a3ea92156 100644
--- a/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
+++ b/lib/hipe/amd64/hipe_amd64_ra_sse2_postconditions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_amd64_ra_sse2_postconditions).
diff --git a/lib/hipe/amd64/hipe_amd64_registers.erl b/lib/hipe/amd64/hipe_amd64_registers.erl
index 7c6965b938..a4cb71a106 100644
--- a/lib/hipe/amd64/hipe_amd64_registers.erl
+++ b/lib/hipe/amd64/hipe_amd64_registers.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_amd64_registers).
diff --git a/lib/hipe/amd64/hipe_amd64_spill_restore.erl b/lib/hipe/amd64/hipe_amd64_spill_restore.erl
index 61e2dfa26d..915ac1adc4 100644
--- a/lib/hipe/amd64/hipe_amd64_spill_restore.erl
+++ b/lib/hipe/amd64/hipe_amd64_spill_restore.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_spill_restore.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_sse2.erl b/lib/hipe/amd64/hipe_amd64_sse2.erl
index ea6b6cb9ba..1a2d3eac48 100644
--- a/lib/hipe/amd64/hipe_amd64_sse2.erl
+++ b/lib/hipe/amd64/hipe_amd64_sse2.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% Fix {mem, mem} floating point operations that result from linear scan
%% allocated floats.
diff --git a/lib/hipe/amd64/hipe_amd64_subst.erl b/lib/hipe/amd64/hipe_amd64_subst.erl
index 7d0f06684b..b0b9ccbe38 100644
--- a/lib/hipe/amd64/hipe_amd64_subst.erl
+++ b/lib/hipe/amd64/hipe_amd64_subst.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_subst.erl").
diff --git a/lib/hipe/amd64/hipe_amd64_x87.erl b/lib/hipe/amd64/hipe_amd64_x87.erl
index 1f42e4749d..afb3aa63e7 100644
--- a/lib/hipe/amd64/hipe_amd64_x87.erl
+++ b/lib/hipe/amd64/hipe_amd64_x87.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_x86_x87.erl").
diff --git a/lib/hipe/amd64/hipe_rtl_to_amd64.erl b/lib/hipe/amd64/hipe_rtl_to_amd64.erl
index d55b5b2c22..7243e75f84 100644
--- a/lib/hipe/amd64/hipe_rtl_to_amd64.erl
+++ b/lib/hipe/amd64/hipe_rtl_to_amd64.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,5 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-include("../x86/hipe_rtl_to_x86.erl").
diff --git a/lib/hipe/arm/hipe_arm.erl b/lib/hipe/arm/hipe_arm.erl
index f34525fa3b..e34a00f561 100644
--- a/lib/hipe/arm/hipe_arm.erl
+++ b/lib/hipe/arm/hipe_arm.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm).
-export([
diff --git a/lib/hipe/arm/hipe_arm.hrl b/lib/hipe/arm/hipe_arm.hrl
index 558174e3fc..67bc07634e 100644
--- a/lib/hipe/arm/hipe_arm.hrl
+++ b/lib/hipe/arm/hipe_arm.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%--------------------------------------------------------------------
%%% Basic Values:
diff --git a/lib/hipe/arm/hipe_arm_assemble.erl b/lib/hipe/arm/hipe_arm_assemble.erl
index 4a245cd853..713c148742 100644
--- a/lib/hipe/arm/hipe_arm_assemble.erl
+++ b/lib/hipe/arm/hipe_arm_assemble.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_assemble).
-export([assemble/4]).
diff --git a/lib/hipe/arm/hipe_arm_cfg.erl b/lib/hipe/arm/hipe_arm_cfg.erl
index 2fb6675da9..ea6da67317 100644
--- a/lib/hipe/arm/hipe_arm_cfg.erl
+++ b/lib/hipe/arm/hipe_arm_cfg.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_cfg).
diff --git a/lib/hipe/arm/hipe_arm_defuse.erl b/lib/hipe/arm/hipe_arm_defuse.erl
index f92cf4f82a..0e62070c6c 100644
--- a/lib/hipe/arm/hipe_arm_defuse.erl
+++ b/lib/hipe/arm/hipe_arm_defuse.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_defuse).
-export([insn_def_all/1, insn_use_all/1]).
diff --git a/lib/hipe/arm/hipe_arm_encode.erl b/lib/hipe/arm/hipe_arm_encode.erl
index 9368cbf628..dedb6547bb 100644
--- a/lib/hipe/arm/hipe_arm_encode.erl
+++ b/lib/hipe/arm/hipe_arm_encode.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Encode symbolic ARM instructions to binary form.
%%% Copyright (C) 2005 Mikael Pettersson
diff --git a/lib/hipe/arm/hipe_arm_finalise.erl b/lib/hipe/arm/hipe_arm_finalise.erl
index 55651d7180..3a6fd5a2dd 100644
--- a/lib/hipe/arm/hipe_arm_finalise.erl
+++ b/lib/hipe/arm/hipe_arm_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_finalise).
-export([finalise/2]).
diff --git a/lib/hipe/arm/hipe_arm_frame.erl b/lib/hipe/arm/hipe_arm_frame.erl
index 9a349b47d3..e323907e31 100644
--- a/lib/hipe/arm/hipe_arm_frame.erl
+++ b/lib/hipe/arm/hipe_arm_frame.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_frame).
-export([frame/1]).
diff --git a/lib/hipe/arm/hipe_arm_liveness_gpr.erl b/lib/hipe/arm/hipe_arm_liveness_gpr.erl
index 82cc5a7a67..ae845e5385 100644
--- a/lib/hipe/arm/hipe_arm_liveness_gpr.erl
+++ b/lib/hipe/arm/hipe_arm_liveness_gpr.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_liveness_gpr).
-export([analyse/1]).
diff --git a/lib/hipe/arm/hipe_arm_main.erl b/lib/hipe/arm/hipe_arm_main.erl
index 8a7fa86394..b87a300a9d 100644
--- a/lib/hipe/arm/hipe_arm_main.erl
+++ b/lib/hipe/arm/hipe_arm_main.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_main).
-export([rtl_to_arm/3]).
diff --git a/lib/hipe/arm/hipe_arm_pp.erl b/lib/hipe/arm/hipe_arm_pp.erl
index 18aca1fc6b..f49e998d06 100644
--- a/lib/hipe/arm/hipe_arm_pp.erl
+++ b/lib/hipe/arm/hipe_arm_pp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_pp).
-export([pp/1, pp/2, pp_insn/1]).
diff --git a/lib/hipe/arm/hipe_arm_ra.erl b/lib/hipe/arm/hipe_arm_ra.erl
index bfb649326c..b360fc05c4 100644
--- a/lib/hipe/arm/hipe_arm_ra.erl
+++ b/lib/hipe/arm/hipe_arm_ra.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_ra).
-export([ra/2]).
diff --git a/lib/hipe/arm/hipe_arm_ra_finalise.erl b/lib/hipe/arm/hipe_arm_ra_finalise.erl
index 2a3fded147..9bfe0a9a83 100644
--- a/lib/hipe/arm/hipe_arm_ra_finalise.erl
+++ b/lib/hipe/arm/hipe_arm_ra_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_ra_finalise).
-export([finalise/3]).
diff --git a/lib/hipe/arm/hipe_arm_ra_ls.erl b/lib/hipe/arm/hipe_arm_ra_ls.erl
index 0aa888da99..bbb75f9c55 100644
--- a/lib/hipe/arm/hipe_arm_ra_ls.erl
+++ b/lib/hipe/arm/hipe_arm_ra_ls.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Linear Scan register allocator for ARM
diff --git a/lib/hipe/arm/hipe_arm_ra_naive.erl b/lib/hipe/arm/hipe_arm_ra_naive.erl
index 395beff292..e3fe9877ad 100644
--- a/lib/hipe/arm/hipe_arm_ra_naive.erl
+++ b/lib/hipe/arm/hipe_arm_ra_naive.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_ra_naive).
-export([ra/4]).
diff --git a/lib/hipe/arm/hipe_arm_ra_postconditions.erl b/lib/hipe/arm/hipe_arm_ra_postconditions.erl
index 412524e2e6..8d1ee1cb94 100644
--- a/lib/hipe/arm/hipe_arm_ra_postconditions.erl
+++ b/lib/hipe/arm/hipe_arm_ra_postconditions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_ra_postconditions).
diff --git a/lib/hipe/arm/hipe_arm_registers.erl b/lib/hipe/arm/hipe_arm_registers.erl
index 3ecf2f2fdb..59545c2e64 100644
--- a/lib/hipe/arm/hipe_arm_registers.erl
+++ b/lib/hipe/arm/hipe_arm_registers.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_registers).
diff --git a/lib/hipe/arm/hipe_arm_subst.erl b/lib/hipe/arm/hipe_arm_subst.erl
index 4d077f3cd6..7510c197bd 100644
--- a/lib/hipe/arm/hipe_arm_subst.erl
+++ b/lib/hipe/arm/hipe_arm_subst.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_subst).
-export([insn_temps/2]).
diff --git a/lib/hipe/arm/hipe_rtl_to_arm.erl b/lib/hipe/arm/hipe_rtl_to_arm.erl
index 2f9181d517..59e0a79b0d 100644
--- a/lib/hipe/arm/hipe_rtl_to_arm.erl
+++ b/lib/hipe/arm/hipe_rtl_to_arm.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_rtl_to_arm).
-export([translate/1]).
@@ -62,7 +55,6 @@ conv_insn(I, Map, Data) ->
case I of
#alu{} -> conv_alu(I, Map, Data);
#alub{} -> conv_alub(I, Map, Data);
- #branch{} -> conv_branch(I, Map, Data);
#call{} -> conv_call(I, Map, Data);
#comment{} -> conv_comment(I, Map, Data);
#enter{} -> conv_enter(I, Map, Data);
@@ -111,6 +103,17 @@ commute_arithop(ArithOp) ->
_ -> ArithOp
end.
+conv_cmpop('add') -> 'cmn';
+conv_cmpop('sub') -> 'cmp';
+conv_cmpop('and') -> 'tst';
+conv_cmpop('xor') -> 'teq';
+conv_cmpop(_) -> none.
+
+cmpop_commutes('cmp') -> false;
+cmpop_commutes('cmn') -> true;
+cmpop_commutes('tst') -> true;
+cmpop_commutes('teq') -> true.
+
mk_alu(S, Dst, Src1, RtlAluOp, Src2) ->
case hipe_rtl:is_shift_op(RtlAluOp) of
true ->
@@ -223,71 +226,77 @@ fix_aluop_imm(AluOp, Imm) -> % {FixAm1,NewAluOp,Am1}
conv_alub(I, Map, Data) ->
%% dst = src1 aluop src2; if COND goto label
- {Dst, Map0} = conv_dst(hipe_rtl:alub_dst(I), Map),
- {Src1, Map1} = conv_src(hipe_rtl:alub_src1(I), Map0),
- {Src2, Map2} = conv_src(hipe_rtl:alub_src2(I), Map1),
+ {Src1, Map0} = conv_src(hipe_rtl:alub_src1(I), Map),
+ {Src2, Map1} = conv_src(hipe_rtl:alub_src2(I), Map0),
RtlAluOp = hipe_rtl:alub_op(I),
- Cond0 = conv_alub_cond(RtlAluOp, hipe_rtl:alub_cond(I)),
- Cond =
- case {RtlAluOp,Cond0} of
- {'mul','vs'} -> 'ne'; % overflow becomes not-equal
- {'mul','vc'} -> 'eq'; % no-overflow becomes equal
- {'mul',_} -> exit({?MODULE,I});
- {_,_} -> Cond0
- end,
- I2 = mk_pseudo_bc(
- Cond,
- hipe_rtl:alub_true_label(I),
- hipe_rtl:alub_false_label(I),
- hipe_rtl:alub_pred(I)),
- S = true,
- I1 = mk_alu(S, Dst, Src1, RtlAluOp, Src2),
- {I1 ++ I2, Map2, Data}.
-
-conv_branch(I, Map, Data) ->
- %% <unused> = src1 - src2; if COND goto label
- {Src1, Map0} = conv_src(hipe_rtl:branch_src1(I), Map),
- {Src2, Map1} = conv_src(hipe_rtl:branch_src2(I), Map0),
- Cond = conv_branch_cond(hipe_rtl:branch_cond(I)),
- I2 = mk_branch(Src1, Cond, Src2,
- hipe_rtl:branch_true_label(I),
- hipe_rtl:branch_false_label(I),
- hipe_rtl:branch_pred(I)),
- {I2, Map1, Data}.
+ RtlCond = hipe_rtl:alub_cond(I),
+ HasDst = hipe_rtl:alub_has_dst(I),
+ CmpOp = conv_cmpop(RtlAluOp),
+ Cond0 = conv_alub_cond(RtlAluOp, RtlCond),
+ case (not HasDst) andalso CmpOp =/= none of
+ true ->
+ I1 = mk_branch(Src1, CmpOp, Src2, Cond0,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I)),
+ {I1, Map1, Data};
+ false ->
+ {Dst, Map2} =
+ case HasDst of
+ false -> {new_untagged_temp(), Map1};
+ true -> conv_dst(hipe_rtl:alub_dst(I), Map1)
+ end,
+ Cond =
+ case {RtlAluOp,Cond0} of
+ {'mul','vs'} -> 'ne'; % overflow becomes not-equal
+ {'mul','vc'} -> 'eq'; % no-overflow becomes equal
+ {'mul',_} -> exit({?MODULE,I});
+ {_,_} -> Cond0
+ end,
+ I2 = mk_pseudo_bc(
+ Cond,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I)),
+ S = true,
+ I1 = mk_alu(S, Dst, Src1, RtlAluOp, Src2),
+ {I1 ++ I2, Map2, Data}
+ end.
-mk_branch(Src1, Cond, Src2, TrueLab, FalseLab, Pred) ->
+mk_branch(Src1, CmpOp, Src2, Cond, TrueLab, FalseLab, Pred) ->
case hipe_arm:is_temp(Src1) of
true ->
case hipe_arm:is_temp(Src2) of
true ->
- mk_branch_rr(Src1, Src2, Cond, TrueLab, FalseLab, Pred);
+ mk_branch_rr(Src1, CmpOp, Src2, Cond, TrueLab, FalseLab, Pred);
_ ->
- mk_branch_ri(Src1, Cond, Src2, TrueLab, FalseLab, Pred)
+ mk_branch_ri(Src1, CmpOp, Src2, Cond, TrueLab, FalseLab, Pred)
end;
_ ->
case hipe_arm:is_temp(Src2) of
true ->
- NewCond = commute_cond(Cond),
- mk_branch_ri(Src2, NewCond, Src1, TrueLab, FalseLab, Pred);
+ NewCond =
+ case cmpop_commutes(CmpOp) of
+ true -> Cond;
+ false -> commute_cond(Cond)
+ end,
+ mk_branch_ri(Src2, CmpOp, Src1, NewCond, TrueLab, FalseLab, Pred);
_ ->
- mk_branch_ii(Src1, Cond, Src2, TrueLab, FalseLab, Pred)
+ mk_branch_ii(Src1, CmpOp, Src2, Cond, TrueLab, FalseLab, Pred)
end
end.
-mk_branch_ii(Imm1, Cond, Imm2, TrueLab, FalseLab, Pred) ->
+mk_branch_ii(Imm1, CmpOp, Imm2, Cond, TrueLab, FalseLab, Pred) ->
Tmp = new_untagged_temp(),
mk_li(Tmp, Imm1,
- mk_branch_ri(Tmp, Cond, Imm2,
+ mk_branch_ri(Tmp, CmpOp, Imm2, Cond,
TrueLab, FalseLab, Pred)).
-mk_branch_ri(Src, Cond, Imm, TrueLab, FalseLab, Pred) ->
- {FixAm1,NewCmpOp,Am1} = fix_aluop_imm('cmp', Imm),
- FixAm1 ++ mk_cmp_bc(NewCmpOp, Src, Am1, Cond, TrueLab, FalseLab, Pred).
-
-mk_branch_rr(Src1, Src2, Cond, TrueLab, FalseLab, Pred) ->
- mk_cmp_bc('cmp', Src1, Src2, Cond, TrueLab, FalseLab, Pred).
+mk_branch_ri(Src, CmpOp, Imm, Cond, TrueLab, FalseLab, Pred) ->
+ {FixAm1,NewCmpOp,Am1} = fix_aluop_imm(CmpOp, Imm),
+ FixAm1 ++ mk_branch_rr(Src, NewCmpOp, Am1, Cond, TrueLab, FalseLab, Pred).
-mk_cmp_bc(CmpOp, Src, Am1, Cond, TrueLab, FalseLab, Pred) ->
+mk_branch_rr(Src, CmpOp, Am1, Cond, TrueLab, FalseLab, Pred) ->
[hipe_arm:mk_cmp(CmpOp, Src, Am1) |
mk_pseudo_bc(Cond, TrueLab, FalseLab, Pred)].
@@ -637,6 +646,7 @@ conv_alub_cond(RtlAluOp, Cond) -> % may be unsigned, depends on aluop
case {RtlAluOp, Cond} of % handle allowed alub unsigned conditions
{'add', 'ltu'} -> 'hs'; % add+ltu == unsigned overflow == carry set == hs
%% add more cases when needed
+ {'sub', _} -> conv_branch_cond(Cond);
_ -> conv_cond(Cond)
end.
diff --git a/lib/hipe/cerl/cerl_cconv.erl b/lib/hipe/cerl/cerl_cconv.erl
index ac9d01ab0e..122e6ef039 100644
--- a/lib/hipe/cerl/cerl_cconv.erl
+++ b/lib/hipe/cerl/cerl_cconv.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,11 +9,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-%% @author Richard Carlsson <[email protected]>
%% @copyright 2000-2004 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Closure conversion of Core Erlang modules. This is done as a
%% step in the translation from Core Erlang down to HiPE Icode, and is
%% very much tied to the calling conventions used in HiPE native code.
diff --git a/lib/hipe/cerl/cerl_closurean.erl b/lib/hipe/cerl/cerl_closurean.erl
index d37c91e5c6..a2bd7fe0f0 100644
--- a/lib/hipe/cerl/cerl_closurean.erl
+++ b/lib/hipe/cerl/cerl_closurean.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,15 +10,9 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% =====================================================================
-%% Closure analysis of Core Erlang programs.
-%%
-%% Copyright (C) 2001-2002 Richard Carlsson
-%%
-%% Author contact: [email protected]
-%% =====================================================================
+%% @copyright 2001-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
+%% @doc Closure analysis of Core Erlang programs.
%% TODO: might need a "top" (`any') element for any-length value lists.
diff --git a/lib/hipe/cerl/cerl_hipe_primops.hrl b/lib/hipe/cerl/cerl_hipe_primops.hrl
index 3efb9a3bdd..6e4d830b61 100644
--- a/lib/hipe/cerl/cerl_hipe_primops.hrl
+++ b/lib/hipe/cerl/cerl_hipe_primops.hrl
@@ -1,9 +1,3 @@
-%% ========================-*-erlang-*-=================================
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,15 +9,10 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% Predefined Core Erlang primitive operations used by HiPE
-%%
-%% Copyright (C) 2000 Richard Carlsson
%%
-%% Author contact: [email protected]
-%% =====================================================================
+%% @copyright 2000 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
+%% @doc Predefined Core Erlang primitive operations used by HiPE.
%% These definitions give the names of Core Erlang primops recognized by
%% HiPE. Many of them (e.g., 'not'/'and'/'or', and the type tests), are
diff --git a/lib/hipe/cerl/cerl_hipeify.erl b/lib/hipe/cerl/cerl_hipeify.erl
index 6611abd204..137a54ba32 100644
--- a/lib/hipe/cerl/cerl_hipeify.erl
+++ b/lib/hipe/cerl/cerl_hipeify.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,11 +9,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-%% @author Richard Carlsson <[email protected]>
%% @copyright 2000-2004 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc HiPE-ification of Core Erlang code. Prepares Core Erlang code
%% for translation to ICode.
%% @see cerl_to_icode
diff --git a/lib/hipe/cerl/cerl_lib.erl b/lib/hipe/cerl/cerl_lib.erl
index 0bc77909d9..3a6fb1cf51 100644
--- a/lib/hipe/cerl/cerl_lib.erl
+++ b/lib/hipe/cerl/cerl_lib.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,10 +9,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-
+%% @copyright 1999-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Utility functions for Core Erlang abstract syntax trees.
%%
%% <p>Syntax trees are defined in the module <a
diff --git a/lib/hipe/cerl/cerl_messagean.erl b/lib/hipe/cerl/cerl_messagean.erl
index 7df0a245fb..c79e045bd0 100644
--- a/lib/hipe/cerl/cerl_messagean.erl
+++ b/lib/hipe/cerl/cerl_messagean.erl
@@ -1,8 +1,3 @@
-%% =====================================================================
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,14 +10,9 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% Message analysis of Core Erlang programs.
-%%
-%% Copyright (C) 2002 Richard Carlsson
-%%
-%% Author contact: [email protected]
-%% =====================================================================
+%% @copyright 2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
+%% @doc Message analysis of Core Erlang programs.
%% TODO: might need a "top" (`any') element for any-length value lists.
diff --git a/lib/hipe/cerl/cerl_pmatch.erl b/lib/hipe/cerl/cerl_pmatch.erl
index ca27fff1dd..fd7f589f08 100644
--- a/lib/hipe/cerl/cerl_pmatch.erl
+++ b/lib/hipe/cerl/cerl_pmatch.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,11 +9,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-%% @author Richard Carlsson <[email protected]>
%% @copyright 2000-2006 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%%
%% @doc Core Erlang pattern matching compiler.
%%
diff --git a/lib/hipe/cerl/cerl_prettypr.erl b/lib/hipe/cerl/cerl_prettypr.erl
index f0acab99e3..c1c7250bbd 100644
--- a/lib/hipe/cerl/cerl_prettypr.erl
+++ b/lib/hipe/cerl/cerl_prettypr.erl
@@ -1,8 +1,3 @@
-%% =====================================================================
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,16 +9,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% Core Erlang prettyprinter, using the 'prettypr' module.
-%%
-%% Copyright (C) 1999-2002 Richard Carlsson
-%%
-%% Author contact: [email protected]
-%% =====================================================================
%%
+%% @copyright 1999-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Core Erlang prettyprinter.
%%
%% <p>This module is a front end to the pretty-printing library module
diff --git a/lib/hipe/cerl/cerl_to_icode.erl b/lib/hipe/cerl/cerl_to_icode.erl
index ab131c2d01..acad8a9da4 100644
--- a/lib/hipe/cerl/cerl_to_icode.erl
+++ b/lib/hipe/cerl/cerl_to_icode.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 4 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,11 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-%% @author Richard Carlsson <[email protected]>
%% @copyright 2000-2006 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Translation from Core Erlang to HiPE Icode.
%% TODO: annotate Icode leaf functions as such.
diff --git a/lib/hipe/cerl/cerl_typean.erl b/lib/hipe/cerl/cerl_typean.erl
index ddc48c7915..c5d84bdf2b 100644
--- a/lib/hipe/cerl/cerl_typean.erl
+++ b/lib/hipe/cerl/cerl_typean.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 4 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,15 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% Type analysis of Core Erlang programs.
-%%
-%% Copyright (C) 2001-2002 Richard Carlsson
-%%
-%% Author contact: [email protected]
%%
+%% @copyright 2001-2002 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Type analysis of Core Erlang programs.
%% TODO: filters must handle conjunctions for better precision!
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 9344eb33fe..8c96e60229 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,16 +12,12 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% =====================================================================
-%% Type information for Erlang Built-in functions (implemented in C)
-%%
-%% Copyright (C) 2002 Richard Carlsson
-%% Copyright (C) 2006 Richard Carlsson, Tobias Lindahl and Kostis Sagonas
-%%
-%% =====================================================================
+%% @doc Type information for Erlang Built-in functions (implemented in C)
+%% @copyright 2002 Richard Carlsson, 2006 Richard Carlsson, Tobias Lindahl
+%% and Kostis Sagonas
+%% @author Richard Carlsson <[email protected]>
+%% @author Tobias Lindahl <[email protected]>
+%% @author Kostis Sagonas <[email protected]>
-module(erl_bif_types).
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 9ef119ba46..5a4cf77b81 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,14 +12,13 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% ======================================================================
-%% Copyright (C) 2000-2003 Richard Carlsson
-%%
-%% ======================================================================
-%% Provides a representation of Erlang types.
-%%
+%% @copyright 2000-2003 Richard Carlsson, 2006-2009 Tobias Lindahl
+%% @author Richard Carlsson <[email protected]>
+%% @author Tobias Lindahl <[email protected]>
+%% @author Kostis Sagonas <[email protected]>
+%% @author Manouk Manoukian
+%% @doc Provides a representation of Erlang types.
+
%% The initial author of this file is Richard Carlsson (2000-2004).
%% In July 2006, the type representation was totally re-designed by
%% Tobias Lindahl. This is the representation which is used currently.
@@ -31,9 +26,6 @@
%% opaque types to the structure-based representation of types.
%% During February and March 2009, Kostis Sagonas significantly
%% cleaned up the type representation and added spec declarations.
-%%
-%% ======================================================================
-module(erl_types).
@@ -4377,7 +4369,7 @@ record_field_diffs_to_string(?tuple([_|Fs], Arity, Tag), RecDict) ->
string:join(FieldDiffs, " and ").
field_diffs([F|Fs], [{FName, _Abstr, DefType}|FDefs], RecDict, Acc) ->
- %% Don't care about opaqueness for now.
+ %% Don't care about opacity for now.
NewAcc =
case not t_is_none(t_inf(F, DefType)) of
true -> Acc;
diff --git a/lib/hipe/flow/cfg.hrl b/lib/hipe/flow/cfg.hrl
index 2575b9e38a..8d0f8855bb 100644
--- a/lib/hipe/flow/cfg.hrl
+++ b/lib/hipe/flow/cfg.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,15 +11,11 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%============================================================================
%% File : cfg.hrl
%% Author : Kostis Sagonas <[email protected]>
%% Purpose : Contains typed record declarations for the CFG data structures
-%%
-%% $Id$
%%============================================================================
-type cfg_lbl() :: non_neg_integer().
diff --git a/lib/hipe/flow/cfg.inc b/lib/hipe/flow/cfg.inc
index cb5f397f64..362c5b697c 100644
--- a/lib/hipe/flow/cfg.inc
+++ b/lib/hipe/flow/cfg.inc
@@ -2,10 +2,6 @@
%% -*- erlang-indent-level: 2 -*-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -17,8 +13,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/flow/ebb.inc b/lib/hipe/flow/ebb.inc
index 529be72dc8..58213e44d5 100644
--- a/lib/hipe/flow/ebb.inc
+++ b/lib/hipe/flow/ebb.inc
@@ -1,9 +1,5 @@
%% -*- Erlang -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/flow/hipe_bb.erl b/lib/hipe/flow/hipe_bb.erl
index 08f5e0a0cb..f4dad59e61 100644
--- a/lib/hipe/flow/hipe_bb.erl
+++ b/lib/hipe/flow/hipe_bb.erl
@@ -1,8 +1,4 @@
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +10,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/flow/hipe_bb.hrl b/lib/hipe/flow/hipe_bb.hrl
index cd4d788aef..5cb5c1b370 100644
--- a/lib/hipe/flow/hipe_bb.hrl
+++ b/lib/hipe/flow/hipe_bb.hrl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%-------------------------------------------------------------------
%%% File : bb.hrl
diff --git a/lib/hipe/flow/hipe_dominators.erl b/lib/hipe/flow/hipe_dominators.erl
index 72c16b5688..570452c14e 100644
--- a/lib/hipe/flow/hipe_dominators.erl
+++ b/lib/hipe/flow/hipe_dominators.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%------------------------------------------------------------------------
%% File : hipe_dominators.erl
%% Author : Christoffer Vikström <[email protected]>
diff --git a/lib/hipe/flow/hipe_gen_cfg.erl b/lib/hipe/flow/hipe_gen_cfg.erl
index a6d053f505..cc3a1b5b73 100644
--- a/lib/hipe/flow/hipe_gen_cfg.erl
+++ b/lib/hipe/flow/hipe_gen_cfg.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,9 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_gen_cfg).
@@ -35,4 +27,3 @@
-spec pred(cfg(), cfg_lbl()) -> [cfg_lbl()].
-include("cfg.inc").
-
diff --git a/lib/hipe/flow/liveness.inc b/lib/hipe/flow/liveness.inc
index bffaa4e3df..3e9d7b3c96 100644
--- a/lib/hipe/flow/liveness.inc
+++ b/lib/hipe/flow/liveness.inc
@@ -1,10 +1,6 @@
%% -*- Erlang -*-
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index 224aacd8d7..100bc0b0e2 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%=======================================================================
%% File : hipe_beam_to_icode.erl
%% Author : Kostis Sagonas
@@ -763,32 +757,10 @@ trans_fun([{test,bs_test_unit,{f,Lbl},[Ms,Unit]}|
[MsVar], [], Env, Instructions);
trans_fun([{test,bs_match_string,{f,Lbl},[Ms,BitSize,Bin]}|
Instructions], Env) ->
- True = mk_label(new),
- FalseLabName = map_label(Lbl),
- TrueLabName = hipe_icode:label_name(True),
+ %% the current match buffer
MsVar = mk_var(Ms),
- TmpVar = mk_var(new),
- ByteSize = BitSize div 8,
- ExtraBits = BitSize rem 8,
- WordSize = hipe_rtl_arch:word_size(),
- if ExtraBits =:= 0 ->
- trans_op_call({hipe_bs_primop,{bs_match_string,Bin,ByteSize}}, Lbl,
- [MsVar], [MsVar], Env, Instructions);
- BitSize =< ((WordSize * 8) - 5) ->
- <<Int:BitSize, _/bits>> = Bin,
- {I1,Env1} = trans_one_op_call({hipe_bs_primop,{bs_get_integer,BitSize,0}}, Lbl,
- [MsVar], [TmpVar, MsVar], Env),
- I2 = hipe_icode:mk_type([TmpVar], {integer,Int}, TrueLabName, FalseLabName),
- I1 ++ [I2,True] ++ trans_fun(Instructions, Env1);
- true ->
- <<RealBin:ByteSize/binary, Int:ExtraBits, _/bits>> = Bin,
- {I1,Env1} = trans_one_op_call({hipe_bs_primop,{bs_match_string,RealBin,ByteSize}}, Lbl,
- [MsVar], [MsVar], Env),
- {I2,Env2} = trans_one_op_call({hipe_bs_primop,{bs_get_integer,ExtraBits,0}}, Lbl,
- [MsVar], [TmpVar, MsVar], Env1),
- I3 = hipe_icode:mk_type([TmpVar], {integer,Int}, TrueLabName, FalseLabName),
- I1 ++ I2 ++ [I3,True] ++ trans_fun(Instructions, Env2)
- end;
+ Primop = {hipe_bs_primop, {bs_match_string, Bin, BitSize}},
+ trans_op_call(Primop, Lbl, [MsVar], [MsVar], Env, Instructions);
trans_fun([{bs_context_to_binary,Var}|Instructions], Env) ->
%% the current match buffer
IVars = [trans_arg(Var)],
diff --git a/lib/hipe/icode/hipe_icode.erl b/lib/hipe/icode/hipe_icode.erl
index 78508dff22..24b7ac4783 100644
--- a/lib/hipe/icode/hipe_icode.erl
+++ b/lib/hipe/icode/hipe_icode.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% HiPE Intermediate Code
%% ====================================================================
@@ -30,9 +24,6 @@
%% 2003-03-15 ES ([email protected]):
%% Started commenting in Edoc.
%% Moved pretty printer to separate file.
-%%
-%% $Id$
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%@doc
@@ -438,6 +429,7 @@
if_true_label/1,
if_false_label/1,
if_args/1,
+ if_args_update/2,
if_pred/1,
%% is_if/1,
@@ -594,6 +586,7 @@
uses/1,
defines/1,
is_safe/1,
+ reduce_unused/1,
strip_comments/1,
subst/2,
subst_uses/2,
@@ -713,6 +706,9 @@ if_op_update(IF, NewOp) -> IF#icode_if{op=NewOp}.
-spec if_args(#icode_if{}) -> [icode_term_arg()].
if_args(#icode_if{args=Args}) -> Args.
+-spec if_args_update(#icode_if{}, [icode_term_arg()]) -> #icode_if{}.
+if_args_update(IF, Args) -> IF#icode_if{args=Args}.
+
-spec if_true_label(#icode_if{}) -> icode_lbl().
if_true_label(#icode_if{true_label=TrueLbl}) -> TrueLbl.
@@ -1765,6 +1761,18 @@ is_safe(Instr) ->
#icode_end_try{} -> false
end.
+%% @doc Produces a simplified instruction sequence that is equivalent to [Instr]
+%% under the assumption that all results of Instr are unused, or 'false' if
+%% there is no such sequence (other than [Instr] itself).
+
+-spec reduce_unused(icode_instr()) -> false | [icode_instr()].
+
+reduce_unused(Instr) ->
+ case is_safe(Instr) of
+ true -> [];
+ false -> false
+ end.
+
%%-----------------------------------------------------------------------
-spec highest_var(icode_instrs()) -> non_neg_integer().
diff --git a/lib/hipe/icode/hipe_icode.hrl b/lib/hipe/icode/hipe_icode.hrl
index b2e0d86b28..380ddd8371 100644
--- a/lib/hipe/icode/hipe_icode.hrl
+++ b/lib/hipe/icode/hipe_icode.hrl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%=====================================================================
%%
diff --git a/lib/hipe/icode/hipe_icode_bincomp.erl b/lib/hipe/icode/hipe_icode_bincomp.erl
index 5ee6fe2c87..f88637e526 100644
--- a/lib/hipe/icode/hipe_icode_bincomp.erl
+++ b/lib/hipe/icode/hipe_icode_bincomp.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_icode_bincomp.erl
diff --git a/lib/hipe/icode/hipe_icode_call_elim.erl b/lib/hipe/icode/hipe_icode_call_elim.erl
index 6a22133962..367ce7cfe5 100644
--- a/lib/hipe/icode/hipe_icode_call_elim.erl
+++ b/lib/hipe/icode/hipe_icode_call_elim.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%----------------------------------------------------------------------
%% File : hipe_icode_call_elim.erl
%% Authors : Daniel S. McCain <[email protected]>,
@@ -46,7 +39,8 @@ cfg(IcodeSSA) ->
-spec elim_insn(icode_instr()) -> icode_instr().
elim_insn(Insn=#icode_call{'fun'={_,_,_}=MFA, args=Args, type=remote,
dstlist=[Dst=#icode_variable{
- annotation={type_anno, RetType, _}}]}) ->
+ annotation={type_anno, RetType, _}}],
+ continuation=[], fail_label=[]}) ->
Opaques = 'universe',
case erl_types:t_is_singleton(RetType, Opaques) of
true ->
diff --git a/lib/hipe/icode/hipe_icode_callgraph.erl b/lib/hipe/icode/hipe_icode_callgraph.erl
index 12c2cd2b44..365c65315e 100644
--- a/lib/hipe/icode/hipe_icode_callgraph.erl
+++ b/lib/hipe/icode/hipe_icode_callgraph.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-----------------------------------------------------------------------
%% File : hipe_icode_callgraph.erl
diff --git a/lib/hipe/icode/hipe_icode_cfg.erl b/lib/hipe/icode/hipe_icode_cfg.erl
index 9a602c0283..c5f5592cc9 100644
--- a/lib/hipe/icode/hipe_icode_cfg.erl
+++ b/lib/hipe/icode/hipe_icode_cfg.erl
@@ -1,10 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
-%%======================================================================
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_icode_cfg).
diff --git a/lib/hipe/icode/hipe_icode_coordinator.erl b/lib/hipe/icode/hipe_icode_coordinator.erl
index b073954ce7..4ef210eca4 100644
--- a/lib/hipe/icode/hipe_icode_coordinator.erl
+++ b/lib/hipe/icode/hipe_icode_coordinator.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%--------------------------------------------------------------------
%% File : hipe_icode_coordinator.erl
diff --git a/lib/hipe/icode/hipe_icode_ebb.erl b/lib/hipe/icode/hipe_icode_ebb.erl
index 2aac9d2f42..2cc4321fb8 100644
--- a/lib/hipe/icode/hipe_icode_ebb.erl
+++ b/lib/hipe/icode/hipe_icode_ebb.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,14 +9,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Icode version of extended basic blocks.
%%
-
+
-module(hipe_icode_ebb).
-define(CFG, hipe_icode_cfg).
diff --git a/lib/hipe/icode/hipe_icode_exceptions.erl b/lib/hipe/icode/hipe_icode_exceptions.erl
index f03ce2faaa..0039eb5091 100644
--- a/lib/hipe/icode/hipe_icode_exceptions.erl
+++ b/lib/hipe/icode/hipe_icode_exceptions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ====================================================================
%% Filename : hipe_icode_exceptions.erl
@@ -71,9 +65,6 @@
%% exit value and jump directly to the catch handler. An
%% alternative solution would be to have a new type of
%% fail instruction that takes a fail-to label...
-%%
-%% CVS:
-%% $Id$
%% ====================================================================
-module(hipe_icode_exceptions).
diff --git a/lib/hipe/icode/hipe_icode_fp.erl b/lib/hipe/icode/hipe_icode_fp.erl
index 4a5877074c..4933ee96b4 100644
--- a/lib/hipe/icode/hipe_icode_fp.erl
+++ b/lib/hipe/icode/hipe_icode_fp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%--------------------------------------------------------------------
%% File : hipe_icode_fp.erl
diff --git a/lib/hipe/icode/hipe_icode_heap_test.erl b/lib/hipe/icode/hipe_icode_heap_test.erl
index ec754d5ee9..1a4f28e1af 100644
--- a/lib/hipe/icode/hipe_icode_heap_test.erl
+++ b/lib/hipe/icode/hipe_icode_heap_test.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2000 by Erik Johansson. All Rights Reserved
@@ -27,9 +21,6 @@
%% Notes :
%% History : * 2000-11-07 Erik Johansson ([email protected]):
%% Created.
-%%
-%% $Id$
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(hipe_icode_heap_test).
diff --git a/lib/hipe/icode/hipe_icode_inline_bifs.erl b/lib/hipe/icode/hipe_icode_inline_bifs.erl
index 79f67c2db6..7a6947f190 100644
--- a/lib/hipe/icode/hipe_icode_inline_bifs.erl
+++ b/lib/hipe/icode/hipe_icode_inline_bifs.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%--------------------------------------------------------------------
%% File : hipe_icode_inline_bifs.erl
@@ -24,7 +18,7 @@
%% Purpose : Inlines BIFs which can be expressed easily in ICode.
%% This allows for optimizations in later ICode passes
%% and makes the code faster.
-%%
+%%
%% Created : 14 May 2007 by Per Gustafsson <[email protected]>
%%--------------------------------------------------------------------
diff --git a/lib/hipe/icode/hipe_icode_instruction_counter.erl b/lib/hipe/icode/hipe_icode_instruction_counter.erl
index afa70e495b..97a19753a1 100644
--- a/lib/hipe/icode/hipe_icode_instruction_counter.erl
+++ b/lib/hipe/icode/hipe_icode_instruction_counter.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-------------------------------------------------------------------
%% File : icode_instruction_counter.erl
diff --git a/lib/hipe/icode/hipe_icode_liveness.erl b/lib/hipe/icode/hipe_icode_liveness.erl
index 317d2e54c2..51e2855108 100644
--- a/lib/hipe/icode/hipe_icode_liveness.erl
+++ b/lib/hipe/icode/hipe_icode_liveness.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/icode/hipe_icode_mulret.erl b/lib/hipe/icode/hipe_icode_mulret.erl
index d927a46222..227cfadfda 100644
--- a/lib/hipe/icode/hipe_icode_mulret.erl
+++ b/lib/hipe/icode/hipe_icode_mulret.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_icode_mulret.erl
diff --git a/lib/hipe/icode/hipe_icode_pp.erl b/lib/hipe/icode/hipe_icode_pp.erl
index a736b54c38..5b017dca32 100644
--- a/lib/hipe/icode/hipe_icode_pp.erl
+++ b/lib/hipe/icode/hipe_icode_pp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2003 by Erik Stenman.
@@ -26,10 +20,6 @@
%% Purpose : Pretty-printer for Icode.
%% Notes :
%% History : * 2003-04-16 ([email protected]): Created.
-%% CVS :
-%% $Author$
-%% $Date$
-%% $Revision$
%% ====================================================================
%%
%% @doc
diff --git a/lib/hipe/icode/hipe_icode_primops.erl b/lib/hipe/icode/hipe_icode_primops.erl
index cee37b6a57..50ece05259 100644
--- a/lib/hipe/icode/hipe_icode_primops.erl
+++ b/lib/hipe/icode/hipe_icode_primops.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
%% ====================================================================
@@ -287,8 +281,8 @@ pp(Dev, Op) ->
io:format(Dev, "bs_start_match<~w>", [Max]);
{{bs_start_match, Type}, Max} ->
io:format(Dev, "bs_start_match<~w,~w>", [Type,Max]);
- {bs_match_string, String, SizeInBytes} ->
- io:format(Dev, "bs_match_string<~w, ~w>", [String, SizeInBytes]);
+ {bs_match_string, String, SizeInBits} ->
+ io:format(Dev, "bs_match_string<~w, ~w>", [String, SizeInBits]);
{bs_get_integer, Size, Flags} ->
io:format(Dev, "bs_get_integer<~w, ~w>", [Size, Flags]);
{bs_get_float, Size, Flags} ->
@@ -596,10 +590,10 @@ type(Primop, Args) ->
erl_types:t_subtract(Type, erl_types:t_matchstate()),
erl_types:t_matchstate_slot(
erl_types:t_inf(Type, erl_types:t_matchstate()), 0));
- {hipe_bs_primop, {bs_match_string,_,Bytes}} ->
+ {hipe_bs_primop, {bs_match_string,_,Bits}} ->
[MatchState] = Args,
BinType = erl_types:t_matchstate_present(MatchState),
- NewBinType = match_bin(erl_types:t_bitstr(0, Bytes*8), BinType),
+ NewBinType = match_bin(erl_types:t_bitstr(0, Bits), BinType),
erl_types:t_matchstate_update_present(NewBinType, MatchState);
{hipe_bs_primop, {bs_test_unit,Unit}} ->
[MatchState] = Args,
diff --git a/lib/hipe/icode/hipe_icode_primops.hrl b/lib/hipe/icode/hipe_icode_primops.hrl
index a0aee165ba..6c6fbd3dad 100644
--- a/lib/hipe/icode/hipe_icode_primops.hrl
+++ b/lib/hipe/icode/hipe_icode_primops.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,16 +11,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%=======================================================================
%% File : hipe_icode_primops.hrl
%% Author : Kostis Sagonas
%% Description : Contains definitions for HiPE's primitive operations.
%%=======================================================================
-%% $Id$
-%%=======================================================================
-record(apply_N, {arity :: arity()}).
diff --git a/lib/hipe/icode/hipe_icode_range.erl b/lib/hipe/icode/hipe_icode_range.erl
index af160769a1..b884132327 100644
--- a/lib/hipe/icode/hipe_icode_range.erl
+++ b/lib/hipe/icode/hipe_icode_range.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%-------------------------------------------------------------------
%%% File : hipe_icode_range.erl
%%% Author : Per Gustafsson <[email protected]>
diff --git a/lib/hipe/icode/hipe_icode_split_arith.erl b/lib/hipe/icode/hipe_icode_split_arith.erl
index e00a13f82e..44c1a9578d 100644
--- a/lib/hipe/icode/hipe_icode_split_arith.erl
+++ b/lib/hipe/icode/hipe_icode_split_arith.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-------------------------------------------------------------------
%% File : hipe_icode_split_arith.erl
diff --git a/lib/hipe/icode/hipe_icode_ssa.erl b/lib/hipe/icode/hipe_icode_ssa.erl
index aca13a2ff0..88317e9629 100644
--- a/lib/hipe/icode/hipe_icode_ssa.erl
+++ b/lib/hipe/icode/hipe_icode_ssa.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_icode_ssa.erl
diff --git a/lib/hipe/icode/hipe_icode_ssa_const_prop.erl b/lib/hipe/icode/hipe_icode_ssa_const_prop.erl
index 4ab4d7e95d..e2cd013b4c 100644
--- a/lib/hipe/icode/hipe_icode_ssa_const_prop.erl
+++ b/lib/hipe/icode/hipe_icode_ssa_const_prop.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -97,11 +91,13 @@ visit_expression(Instruction, Environment) ->
visit_begin_handler (Instruction, EvaluatedArguments, Environment);
#icode_begin_try{} ->
visit_begin_try (Instruction, EvaluatedArguments, Environment);
- #icode_fail{} ->
+ #icode_fail{} ->
visit_fail (Instruction, EvaluatedArguments, Environment);
- _ ->
- %% label, end_try, comment, return,
- {[], [], Environment}
+ #icode_comment{} -> {[], [], Environment};
+ #icode_end_try{} -> {[], [], Environment};
+ #icode_enter{} -> {[], [], Environment};
+ #icode_label{} -> {[], [], Environment};
+ #icode_return{} -> {[], [], Environment}
end.
%%-----------------------------------------------------------------------------
@@ -463,11 +459,15 @@ update_instruction(Instruction, Environment) ->
update_type(Instruction, Environment);
#icode_switch_tuple_arity{} ->
update_switch_tuple_arity(Instruction, Environment);
- _ ->
- %% goto, comment, label, return, begin_handler, end_try,
- %% begin_try, fail
- %% We could but don't handle: catch?, fail?
- [Instruction]
+ %% We could but don't handle: catch?, fail?
+ #icode_begin_handler{} -> [Instruction];
+ #icode_begin_try{} -> [Instruction];
+ #icode_comment{} -> [Instruction];
+ #icode_end_try{} -> [Instruction];
+ #icode_fail{} -> [Instruction];
+ #icode_goto{} -> [Instruction];
+ #icode_label{} -> [Instruction];
+ #icode_return{} -> [Instruction]
end.
%%-----------------------------------------------------------------------------
@@ -502,14 +502,12 @@ update_call(Instruction, Environment) ->
[Instruction, NewInstructions]),
NewInstructions
end;
-%% %% [] -> %% No destination; we don't touch this
-%% [] ->
-%% NewArguments = update_arguments(hipe_icode:call_args(Instruction),
-%% Environment),
-%% [hipe_icode:call_args_update(Instruction, NewArguments)];
+ %% [] -> %% No destination; we don't touch this
%% List-> %% Means register allocation; not implemented at this point
_ ->
- [Instruction]
+ NewArguments = update_arguments(hipe_icode:call_args(Instruction),
+ Environment),
+ [hipe_icode:call_args_update(Instruction, NewArguments)]
end.
%%-----------------------------------------------------------------------------
@@ -574,7 +572,9 @@ update_if(Instruction, Environment) ->
%% Convert the if-test to a type test if possible.
Op = hipe_icode:if_op(Instruction),
case Op =:= '=:=' orelse Op =:= '=/=' of
- false -> [Instruction];
+ false ->
+ [hipe_icode:if_args_update(
+ Instruction, update_arguments(Args, Environment))];
true ->
[Arg1, Arg2] = Args,
case EvaluatedArguments of
@@ -604,8 +604,9 @@ conv_if_to_type(I, Const, Arg) when is_atom(Const);
NewI = hipe_icode:mk_type([Arg], Test, T, F),
?CONST_PROP_MSG("if: ~w ---> type ~w\n", [I, NewI]),
[NewI];
-conv_if_to_type(I, _, _) ->
- [I].
+conv_if_to_type(I, Const, Arg) ->
+ %% Note: we are potentially commuting the (equality) comparison here
+ [hipe_icode:if_args_update(I, [Arg, hipe_icode:mk_const(Const)])].
%%-----------------------------------------------------------------------------
diff --git a/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl b/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl
index 5e5bd2a178..b92b7cfa7a 100644
--- a/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl
+++ b/lib/hipe/icode/hipe_icode_ssa_copy_prop.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-------------------------------------------------------------------
%% File : hipe_icode_ssa_copy_prop.erl
diff --git a/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl b/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
index 7613024787..ec4840980d 100644
--- a/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
+++ b/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%=======================================================================
%% File : hipe_icode_ssa_struct_reuse.erl
diff --git a/lib/hipe/icode/hipe_icode_type.erl b/lib/hipe/icode/hipe_icode_type.erl
index 3f0e2998f1..815d1e57a8 100644
--- a/lib/hipe/icode/hipe_icode_type.erl
+++ b/lib/hipe/icode/hipe_icode_type.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%--------------------------------------------------------------------
%%% File : hipe_icode_type.erl
%%% Author : Tobias Lindahl <[email protected]>
diff --git a/lib/hipe/icode/hipe_icode_type.hrl b/lib/hipe/icode/hipe_icode_type.hrl
index 466e157646..b7c200eef1 100644
--- a/lib/hipe/icode/hipe_icode_type.hrl
+++ b/lib/hipe/icode/hipe_icode_type.hrl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_icode_type.hrl
diff --git a/lib/hipe/llvm/hipe_llvm_main.erl b/lib/hipe/llvm/hipe_llvm_main.erl
index c8fc9cc856..0957dd4df2 100644
--- a/lib/hipe/llvm/hipe_llvm_main.erl
+++ b/lib/hipe/llvm/hipe_llvm_main.erl
@@ -84,7 +84,7 @@ compile_with_llvm(FunName, Arity, LLVMCode, Options, UseBuffer) ->
__ = file:close(File_llvm),
%% Invoke LLVM compiler tools to produce an object file
llvm_opt(Dir, Filename, Options),
- llvm_llc(Dir, Filename, Options),
+ llvm_llc(Dir, Filename, Ver, Options),
compile(Dir, Filename, "gcc"), %%FIXME: use llc -filetype=obj and skip this!
{ok, Dir, Dir ++ Filename ++ ".o"}.
@@ -103,12 +103,14 @@ llvm_opt(Dir, Filename, Options) ->
%% @doc Invoke llc tool to compile the bitcode to object file
%% (_name.bc -> _name.o).
-llvm_llc(Dir, Filename, Options) ->
+llvm_llc(Dir, Filename, Ver, Options) ->
Source = Dir ++ Filename ++ ".bc",
OptLevel = trans_optlev_flag(llc, Options),
+ VerFlags = llc_ver_flags(Ver),
Align = find_stack_alignment(),
LlcFlags = [OptLevel, "-code-model=medium", "-stack-alignment=" ++ Align
- , "-tailcallopt", "-filetype=asm"], %%FIXME
+ , "-tailcallopt", "-filetype=asm" %FIXME
+ | VerFlags],
Command = "llc " ++ fix_opts(LlcFlags) ++ " " ++ Source,
%% io:format("LLC: ~s~n", [Command]),
case os:cmd(Command) of
@@ -153,6 +155,12 @@ trans_optlev_flag(Tool, Options) ->
undefined -> "-O2"
end.
+llc_ver_flags(Ver = {_, _}) when Ver >= {3,9} ->
+ %% Works around a bug in the x86-call-frame-opt pass (as of LLVM 3.9) that
+ %% break the garbage collection stack descriptors.
+ ["-no-x86-call-frame-opt"];
+llc_ver_flags({_, _}) -> [].
+
%%------------------------------------------------------------------------------
%% Functions to manage Relocations
%%------------------------------------------------------------------------------
diff --git a/lib/hipe/llvm/hipe_rtl_to_llvm.erl b/lib/hipe/llvm/hipe_rtl_to_llvm.erl
index 53aa8c57b2..f8911c1909 100644
--- a/lib/hipe/llvm/hipe_rtl_to_llvm.erl
+++ b/lib/hipe/llvm/hipe_rtl_to_llvm.erl
@@ -10,7 +10,8 @@
-include("../rtl/hipe_literals.hrl").
-include("hipe_llvm_arch.hrl").
--define(WORD_WIDTH, (?bytes_to_bits(hipe_rtl_arch:word_size()))).
+-define(BITS_IN_WORD, (?bytes_to_bits(hipe_rtl_arch:word_size()))).
+-define(BITS_IN_BYTE, (?bytes_to_bits(1))).
-define(BRANCH_META_TAKEN, "0").
-define(BRANCH_META_NOT_TAKEN, "1").
-define(FIRST_FREE_META_NO, 2).
@@ -95,9 +96,9 @@ do_alloca_stack([], _, _, Acc) ->
Acc;
do_alloca_stack([D|Ds], Params, Roots, Acc) ->
{Name, _I} = trans_dst(D),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
- ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(8)),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
case hipe_rtl:is_var(D) of
true ->
Num = hipe_rtl:var_index(D),
@@ -155,9 +156,6 @@ translate_instr(I, Relocs, Data) ->
#alub{} ->
{I2, Relocs2} = trans_alub(I, Relocs),
{I2, Relocs2, Data};
- #branch{} ->
- {I2, Relocs2} = trans_branch(I, Relocs),
- {I2, Relocs2, Data};
#call{} ->
{I2, Relocs2} =
case hipe_rtl:call_fun(I) of
@@ -233,7 +231,7 @@ trans_alu(I, Relocs) ->
{Src1, I1} = trans_src(hipe_rtl:alu_src1(I)),
{Src2, I2} = trans_src(hipe_rtl:alu_src2(I)),
Op = trans_op(hipe_rtl:alu_op(I)),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
I3 = hipe_llvm:mk_operation(TmpDst, Op, WordTy, Src1, Src2, []),
I4 = store_stack_dst(TmpDst, RtlDst),
{[I4, I3, I2, I1], Relocs}.
@@ -254,18 +252,20 @@ trans_alub(I, Relocs) ->
trans_alub_overflow(I, Sign, Relocs) ->
{Src1, I1} = trans_src(hipe_rtl:alub_src1(I)),
{Src2, I2} = trans_src(hipe_rtl:alub_src2(I)),
- RtlDst = hipe_rtl:alub_dst(I),
TmpDst = mk_temp(),
Name = trans_alub_op(I, Sign),
NewRelocs = relocs_store(Name, {call, remote, {llvm, Name, 2}}, Relocs),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
ReturnType = hipe_llvm:mk_struct([WordTy, hipe_llvm:mk_int(1)]),
T1 = mk_temp(),
I3 = hipe_llvm:mk_call(T1, false, [], [], ReturnType, "@" ++ Name,
[{WordTy, Src1}, {WordTy, Src2}], []),
%% T1{0}: result of the operation
I4 = hipe_llvm:mk_extractvalue(TmpDst, ReturnType, T1 , "0", []),
- I5 = store_stack_dst(TmpDst, RtlDst),
+ I5 = case hipe_rtl:alub_has_dst(I) of
+ false -> [];
+ true -> store_stack_dst(TmpDst, hipe_rtl:alub_dst(I))
+ end,
T2 = mk_temp(),
%% T1{1}: Boolean variable indicating overflow
I6 = hipe_llvm:mk_extractvalue(T2, ReturnType, T1, "1", []),
@@ -310,42 +310,35 @@ trans_alub_op(I, Sign) ->
Name ++ Type.
trans_alub_no_overflow(I, Relocs) ->
+ {Src1, I1} = trans_src(hipe_rtl:alub_src1(I)),
+ {Src2, I2} = trans_src(hipe_rtl:alub_src2(I)),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
%% alu
- T = hipe_rtl:mk_alu(hipe_rtl:alub_dst(I), hipe_rtl:alub_src1(I),
- hipe_rtl:alub_op(I), hipe_rtl:alub_src2(I)),
- %% A trans_alu instruction cannot change relocations
- {I1, _} = trans_alu(T, Relocs),
+ {CmpLhs, CmpRhs, I5, Cond} =
+ case {hipe_rtl:alub_has_dst(I), hipe_rtl:alub_op(I)} of
+ {false, 'sub'} ->
+ Cond0 = trans_branch_rel_op(hipe_rtl:alub_cond(I)),
+ {Src1, Src2, [], Cond0};
+ {HasDst, AlubOp} ->
+ TmpDst = mk_temp(),
+ Op = trans_op(AlubOp),
+ I3 = hipe_llvm:mk_operation(TmpDst, Op, WordTy, Src1, Src2, []),
+ I4 = case HasDst of
+ false -> [];
+ true -> store_stack_dst(TmpDst, hipe_rtl:alub_dst(I))
+ end,
+ Cond0 = trans_alub_rel_op(hipe_rtl:alub_cond(I)),
+ {TmpDst, "0", [I4, I3], Cond0}
+ end,
%% icmp
- %% Translate destination as src, to match with the semantics of instruction
- {Dst, I2} = trans_src(hipe_rtl:alub_dst(I)),
- Cond = trans_rel_op(hipe_rtl:alub_cond(I)),
T3 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- I5 = hipe_llvm:mk_icmp(T3, Cond, WordTy, Dst, "0"),
+ I6 = hipe_llvm:mk_icmp(T3, Cond, WordTy, CmpLhs, CmpRhs),
%% br
Metadata = branch_metadata(hipe_rtl:alub_pred(I)),
True_label = mk_jump_label(hipe_rtl:alub_true_label(I)),
False_label = mk_jump_label(hipe_rtl:alub_false_label(I)),
- I6 = hipe_llvm:mk_br_cond(T3, True_label, False_label, Metadata),
- {[I6, I5, I2, I1], Relocs}.
-
-%%
-%% branch
-%%
-trans_branch(I, Relocs) ->
- {Src1, I1} = trans_src(hipe_rtl:branch_src1(I)),
- {Src2, I2} = trans_src(hipe_rtl:branch_src2(I)),
- Cond = trans_rel_op(hipe_rtl:branch_cond(I)),
- %% icmp
- T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- I3 = hipe_llvm:mk_icmp(T1, Cond, WordTy, Src1, Src2),
- %% br
- True_label = mk_jump_label(hipe_rtl:branch_true_label(I)),
- False_label = mk_jump_label(hipe_rtl:branch_false_label(I)),
- Metadata = branch_metadata(hipe_rtl:branch_pred(I)),
- I4 = hipe_llvm:mk_br_cond(T1, True_label, False_label, Metadata),
- {[I4, I3, I2, I1], Relocs}.
+ I7 = hipe_llvm:mk_br_cond(T3, True_label, False_label, Metadata),
+ {[I7, I6, I5, I2, I1], Relocs}.
branch_metadata(X) when X =:= 0.5 -> [];
branch_metadata(X) when X > 0.5 -> ?BRANCH_META_TAKEN;
@@ -366,7 +359,7 @@ trans_call(I, Relocs) ->
{Name, I3, Relocs2} =
trans_call_name(RtlCallName, hipe_rtl:call_type(I), Relocs1, CallArgs, FinalArgs),
T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
I4 =
case hipe_rtl:call_fail(I) of
@@ -450,7 +443,7 @@ trans_call_name(RtlCallName, RtlCallType, Relocs, CallArgs, FinalArgs) ->
%% order to make the call
TT1 = mk_temp(),
{RegName, II1} = trans_src(Reg),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
II2 =
hipe_llvm:mk_conversion(TT1, inttoptr, WordTy, RegName, WordTyPtr),
@@ -503,7 +496,7 @@ trans_enter(I, Relocs) ->
{Name, I2, NewRelocs} =
trans_call_name(hipe_rtl:enter_fun(I), hipe_rtl:enter_type(I), Relocs, CallArgs, FinalArgs),
T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
I3 = hipe_llvm:mk_call(T1, true, "cc 11", [], FunRetTy, Name, FinalArgs, []),
I4 = hipe_llvm:mk_ret([{FunRetTy, T1}]),
@@ -518,7 +511,7 @@ trans_fconv(I, Relocs) ->
TmpDst = mk_temp(),
{Src, I1} = trans_float_src(hipe_rtl:fconv_src(I)),
FloatTy = hipe_llvm:mk_double(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
I2 = hipe_llvm:mk_conversion(TmpDst, sitofp, WordTy, Src, FloatTy),
I3 = store_float_stack(TmpDst, RtlDst),
{[I3, I2, I1], Relocs}.
@@ -538,7 +531,7 @@ trans_fload(I, Relocs) ->
{Src, I1} = trans_float_src(RtlSrc),
{Offset, I2} = trans_float_src(_Offset),
T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FloatTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_double()),
I3 = hipe_llvm:mk_operation(T1, add, WordTy, Src, Offset, []),
T2 = mk_temp(),
@@ -619,7 +612,7 @@ trans_fstore(I, Relocs) ->
trans_fstore_reg(I, Relocs) ->
{Base, I0} = trans_reg(hipe_rtl:fstore_base(I), dst),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
FloatTy = hipe_llvm:mk_double(),
FloatTyPtr = hipe_llvm:mk_pointer(FloatTy),
@@ -659,7 +652,7 @@ trans_load(I, Relocs) ->
{Src, I1} = trans_src(hipe_rtl:load_src(I)),
{Offset, I2} = trans_src(hipe_rtl:load_offset(I)),
T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
I3 = hipe_llvm:mk_operation(T1, add, WordTy, Src, Offset, []),
%%----------------------------------------------------------------
@@ -737,7 +730,7 @@ trans_move(I, Relocs) ->
%% return
%%
trans_return(I, Relocs) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
{VarRet, I1} =
case hipe_rtl:return_varlist(I) of
[] ->
@@ -777,7 +770,7 @@ trans_store(I, Relocs) ->
{Offset, I2} = trans_src(hipe_rtl:store_offset(I)),
{Value, I3} = trans_src(hipe_rtl:store_src(I)),
T1 = mk_temp(),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
I4 = hipe_llvm:mk_operation(T1, add, WordTy, Base, Offset, []),
I5 =
@@ -811,14 +804,14 @@ trans_switch(I, Relocs, Data) ->
JumpLabels = [mk_jump_label(L) || L <- Labels],
SortOrder = hipe_rtl:switch_sort_order(I),
NrLabels = length(Labels),
- ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(8)),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
TableType = hipe_llvm:mk_array(NrLabels, ByteTyPtr),
TableTypeP = hipe_llvm:mk_pointer(TableType),
TypedJumpLabels = [{hipe_llvm:mk_label_type(), X} || X <- JumpLabels],
T1 = mk_temp(),
{Src2, []} = trans_dst(RtlSrc),
TableName = "table_" ++ tl(Src2),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
I2 = hipe_llvm:mk_getelementptr(T1, TableTypeP, "@"++TableName,
[{WordTy, "0"}, {WordTy, Src}], false),
T2 = mk_temp(),
@@ -933,7 +926,7 @@ create_fail_blocks(Label, FailLabels, Acc) ->
false ->
Acc;
{value, {Label, FailLabel, SpAdj}, RestFailLabels} ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
I1 = hipe_llvm:mk_label(FailLabel),
LP = hipe_llvm:mk_landingpad(),
I2 =
@@ -962,7 +955,7 @@ create_fail_blocks(Label, FailLabels, Acc) ->
%% @doc Convert RTL argument list to LLVM argument list.
trans_args(ArgList) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
MakeArg =
fun(A) ->
{Name, I1} = trans_src(A),
@@ -972,13 +965,13 @@ trans_args(ArgList) ->
%% @doc Convert a list of Precoloured registers to LLVM argument list.
fix_reg_args(ArgList) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
[{WordTy, A} || A <- ArgList].
%% @doc Load Precoloured registers.
load_fixed_regs(RegList) ->
Names = [mk_temp_reg(R) || R <- RegList],
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
Fun1 =
fun (X, Y) ->
@@ -991,7 +984,7 @@ load_fixed_regs(RegList) ->
store_fixed_regs(RegList, Name) ->
Names = [mk_temp_reg(R) || R <- RegList],
Indexes = lists:seq(0, erlang:length(RegList) - 1),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
Fun1 =
@@ -1064,7 +1057,7 @@ mk_temp_reg(Name) ->
store_stack_dst(TempDst, Dst) ->
{Dst2, II1} = trans_dst(Dst),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
II2 = hipe_llvm:mk_store(WordTy, TempDst, WordTyPtr, Dst2, [], [], false),
[II2, II1].
@@ -1082,7 +1075,7 @@ trans_float_src(Src) ->
Name = "@DL" ++ integer_to_list(hipe_rtl:const_label_label(Src)),
T1 = mk_temp(),
%% XXX: Hardcoded offset
- ByteTy = hipe_llvm:mk_int(8),
+ ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
ByteTyPtr = hipe_llvm:mk_pointer(ByteTy),
I1 = hipe_llvm:mk_getelementptr(T1, ByteTyPtr, Name,
[{ByteTy, integer_to_list(?FLOAT_OFFSET)}], true),
@@ -1098,7 +1091,7 @@ trans_float_src(Src) ->
end.
trans_src(A) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
case hipe_rtl:is_imm(A) of
true ->
@@ -1161,7 +1154,7 @@ trans_dst(A) ->
true ->
"%DL" ++ integer_to_list(hipe_rtl:const_label_label(A)) ++ "_var";
false ->
- exit({?MODULE, trans_dst, {"Bad RTL argument",A}})
+ error(badarg, [A])
end
end
end,
@@ -1201,7 +1194,7 @@ map_precoloured_reg(Index) ->
fix_reg_dst(Register) ->
case Register of
{Name, Offset} -> %% Case of %fcalls, %hplim
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
pointer_from_reg(Name, WordTy, Offset);
Name -> %% Case of %p and %hp
{Name, []}
@@ -1209,7 +1202,7 @@ fix_reg_dst(Register) ->
%% @doc Load precoloured src register.
fix_reg_src(Register) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
case Register of
{Name, Offset} -> %% Case of %fcalls, %hplim
@@ -1259,14 +1252,19 @@ trans_op(Op) ->
Other -> exit({?MODULE, trans_op, {"Unknown RTL operator", Other}})
end.
-trans_rel_op(Op) ->
+trans_branch_rel_op(Op) ->
case Op of
- eq -> eq;
- ne -> ne;
gtu -> ugt;
geu -> uge;
ltu -> ult;
leu -> ule;
+ _ -> trans_alub_rel_op(Op)
+ end.
+
+trans_alub_rel_op(Op) ->
+ case Op of
+ eq -> eq;
+ ne -> ne;
gt -> sgt;
ge -> sge;
lt -> slt;
@@ -1299,7 +1297,10 @@ insn_dst(I) ->
#alu{} ->
[hipe_rtl:alu_dst(I)];
#alub{} ->
- [hipe_rtl:alub_dst(I)];
+ case hipe_rtl:alub_has_dst(I) of
+ true -> [hipe_rtl:alub_dst(I)];
+ false -> []
+ end;
#call{} ->
case hipe_rtl:call_dstlist(I) of
[] -> [];
@@ -1331,10 +1332,10 @@ insn_dst(I) ->
llvm_type_from_size(Size) ->
case Size of
- byte -> hipe_llvm:mk_int(8);
+ byte -> hipe_llvm:mk_int(?BITS_IN_BYTE);
int16 -> hipe_llvm:mk_int(16);
int32 -> hipe_llvm:mk_int(32);
- word -> hipe_llvm:mk_int(64)
+ word -> hipe_llvm:mk_int(?BITS_IN_WORD)
end.
%% @doc Create definition for the compiled function. The parameters that are
@@ -1364,13 +1365,13 @@ create_function_definition(Fun, Params, Code, LocalVars) ->
lists:flatten([EntryLabel, ExceptionSync, I2, LocalVars, StoredParams, I3]),
Final_Code = EntryBlock ++ Code,
FunctionOptions = [nounwind, noredzone, list_to_atom("gc \"erlang\"")],
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
hipe_llvm:mk_fun_def([], [], "cc 11", [], FunRetTy, FunctionName, Args,
FunctionOptions, [], Final_Code).
header_params(Params) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
[{WordTy, "%v" ++ integer_to_list(hipe_rtl:var_index(P))} || P <- Params].
store_params(Params) ->
@@ -1379,7 +1380,7 @@ store_params(Params) ->
Index = hipe_rtl:var_index(X),
{Name, _} = trans_dst(X),
ParamName = "%v" ++ integer_to_list(Index),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
hipe_llvm:mk_store(WordTy, ParamName, WordTyPtr, Name, [], [], false)
end,
@@ -1396,11 +1397,11 @@ fixed_registers() ->
end.
header_regs(Registers) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
[{WordTy, "%" ++ X ++ "_in"} || X <- Registers].
load_regs(Registers) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
WordTyPtr = hipe_llvm:mk_pointer(WordTy),
Fun1 =
fun(X) ->
@@ -1501,28 +1502,30 @@ seperate_relocs([R|Rs], CallAcc, AtomAcc, ClosureAcc, LabelAcc, JmpTableAcc) ->
%% @doc External declaration of an atom.
declare_atom({AtomName, _}) ->
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- hipe_llvm:mk_const_decl("@" ++ AtomName, "external constant", WordTy, "").
+ %% The type has to be byte, or a backend might assume the constant is aligned
+ %% and incorrectly optimise away type tests
+ ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
+ hipe_llvm:mk_const_decl("@" ++ AtomName, "external constant", ByteTy, "").
%% @doc Creation of local variable for an atom.
load_atom({AtomName, _}) ->
Dst = "%" ++ AtomName ++ "_var",
Name = "@" ++ AtomName,
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- WordTyPtr = hipe_llvm:mk_pointer(WordTy),
- hipe_llvm:mk_conversion(Dst, ptrtoint, WordTyPtr, Name, WordTy).
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
+ hipe_llvm:mk_conversion(Dst, ptrtoint, ByteTyPtr, Name, WordTy).
%% @doc External declaration of a closure.
declare_closure({ClosureName, _})->
- ByteTy = hipe_llvm:mk_int(8),
+ ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
hipe_llvm:mk_const_decl("@" ++ ClosureName, "external constant", ByteTy, "").
%% @doc Creation of local variable for a closure.
load_closure({ClosureName, _})->
Dst = "%" ++ ClosureName ++ "_var",
Name = "@" ++ ClosureName,
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(8)),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
hipe_llvm:mk_conversion(Dst, ptrtoint, ByteTyPtr, Name, WordTy).
%% @doc Declaration of a local variable for a switch jump table.
@@ -1553,7 +1556,7 @@ declare_closure_labels(ClosureLabels, Relocs, Fun) ->
List3 = string:join(List2, ",\n"),
List4 = "[\n" ++ List3 ++ "\n]\n",
NrLabels = length(LabelList),
- ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(8)),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
TableType = hipe_llvm:mk_array(NrLabels, ByteTyPtr),
ConstDecl =
hipe_llvm:mk_const_decl("@table_closures", "constant", TableType, List4),
@@ -1568,7 +1571,7 @@ is_external_call(_, _) -> true.
call_to_decl({Name, {call, _, MFA}}) ->
{M, _F, A} = MFA,
CConv = "cc 11",
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
{Type, Args} =
case M of
@@ -1583,14 +1586,14 @@ call_to_decl({Name, {call, _, MFA}}) ->
%% @doc These functions are always declared, even if not used.
fixed_fun_decl() ->
- ByteTy = hipe_llvm:mk_int(8),
+ ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
ByteTyPtr = hipe_llvm:mk_pointer(ByteTy),
LandPad = hipe_llvm:mk_fun_decl([], [], [], [], hipe_llvm:mk_int(32),
"@__gcc_personality_v0", [hipe_llvm:mk_int(32), hipe_llvm:mk_int(64),
ByteTyPtr, ByteTyPtr], []),
GCROOTDecl = hipe_llvm:mk_fun_decl([], [], [], [], hipe_llvm:mk_void(),
"@llvm.gcroot", [hipe_llvm:mk_pointer(ByteTyPtr), ByteTyPtr], []),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
FunRetTy = hipe_llvm:mk_struct(lists:duplicate(?NR_PINNED_REGS + 1, WordTy)),
FixPinnedRegs = hipe_llvm:mk_fun_decl([], [], [], [], FunRetTy,
"@hipe_bifs.llvm_fix_pinned_regs.0", [], []),
@@ -1604,7 +1607,7 @@ fixed_fun_decl() ->
%% values, add the offset and convert them again to pointers.
declare_constant(Label) ->
Name = "@DL" ++ integer_to_list(Label),
- ByteTy = hipe_llvm:mk_int(8),
+ ByteTy = hipe_llvm:mk_int(?BITS_IN_BYTE),
hipe_llvm:mk_const_decl(Name, "external constant", ByteTy, "").
%% @doc Load a constant is achieved by converting a pointer to an integer of
@@ -1612,8 +1615,8 @@ declare_constant(Label) ->
load_constant(Label) ->
Dst = "%DL" ++ integer_to_list(Label) ++ "_var",
Name = "@DL" ++ integer_to_list(Label),
- WordTy = hipe_llvm:mk_int(?WORD_WIDTH),
- ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(8)),
+ WordTy = hipe_llvm:mk_int(?BITS_IN_WORD),
+ ByteTyPtr = hipe_llvm:mk_pointer(hipe_llvm:mk_int(?BITS_IN_BYTE)),
hipe_llvm:mk_conversion(Dst, ptrtoint, ByteTyPtr, Name, WordTy).
%% @doc Store external constants and calls to dictionary.
diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl
index bee5da2195..90ef84ca51 100644
--- a/lib/hipe/main/hipe.erl
+++ b/lib/hipe/main/hipe.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%% ====================================================================
%% Copyright (c) 1998 by Erik Johansson. All Rights Reserved
%% ====================================================================
@@ -635,44 +629,51 @@ run_compiler(Name, DisasmFun, IcodeFun, Opts0) ->
Opts = expand_basic_options(Opts0 ++ ?COMPILE_DEFAULTS),
?when_option(verbose, Opts, ?debug_msg("Compiling: ~p\n",[Name])),
?option_start_time("Compile", Opts),
- Res = run_compiler_1(DisasmFun, IcodeFun, Opts),
+ Res = run_compiler_1(Name, DisasmFun, IcodeFun, Opts),
?option_stop_time("Compile", Opts),
Res.
-run_compiler_1(DisasmFun, IcodeFun, Options) ->
+run_compiler_1(Name, DisasmFun, IcodeFun, Options) ->
Parent = self(),
{trap_exit,TrapExit} = process_info(Parent, trap_exit),
%% Spawn a compilation process CompProc. In case this process gets
%% killed, the trap_exit flag is restored to that of the Parent process.
process_flag(trap_exit, true),
- CompProc = spawn_link(fun () ->
- %% Compiler process
- set_architecture(Options),
- pre_init(Options),
- %% The full option expansion is not done
- %% until the DisasmFun returns.
- {Code, CompOpts} = DisasmFun(Options),
- Opts0 = expand_options(Options ++ CompOpts,
- get(hipe_target_arch)),
- Opts =
- case proplists:get_bool(to_llvm, Opts0) andalso
- not llvm_support_available() of
- true ->
- ?error_msg("No LLVM version 3.4 or greater "
- "found in $PATH; aborting "
- "native code compilation.\n", []),
- ?EXIT(cant_find_required_llvm_version);
- false ->
- Opts0
- end,
- check_options(Opts),
- ?when_option(verbose, Options,
- ?debug_msg("Options: ~p.\n",[Opts])),
- init(Opts),
- {Icode, WholeModule} = IcodeFun(Code, Opts),
- CompRes = compile_finish(Icode, WholeModule, Opts),
- compiler_return(CompRes, Parent)
- end),
+ CompProc =
+ spawn_link(
+ fun () ->
+ try
+ %% Compiler process
+ set_architecture(Options),
+ pre_init(Options),
+ %% The full option expansion is not done
+ %% until the DisasmFun returns.
+ {Code, CompOpts} = DisasmFun(Options),
+ Opts0 = expand_options(Options ++ CompOpts,
+ get(hipe_target_arch)),
+ Opts =
+ case proplists:get_bool(to_llvm, Opts0) andalso
+ not llvm_support_available() of
+ true ->
+ ?error_msg("No LLVM version 3.4 or greater "
+ "found in $PATH; aborting "
+ "native code compilation.\n", []),
+ ?EXIT(cant_find_required_llvm_version);
+ false ->
+ Opts0
+ end,
+ check_options(Opts),
+ ?when_option(verbose, Options,
+ ?debug_msg("Options: ~p.\n",[Opts])),
+ init(Opts),
+ {Icode, WholeModule} = IcodeFun(Code, Opts),
+ CompRes = compile_finish(Icode, WholeModule, Opts),
+ compiler_return(CompRes, Parent)
+ catch error:Error ->
+ print_crash_message(Name, Error),
+ exit(Error)
+ end
+ end),
Timeout = case proplists:get_value(timeout, Options) of
N when is_integer(N), N >= 0 -> N;
undefined -> ?DEFAULT_TIMEOUT;
@@ -691,7 +692,7 @@ run_compiler_1(DisasmFun, IcodeFun, Options) ->
exit(CompProc, kill),
receive {'EXIT', CompProc, _} -> ok end,
flush(),
- ?error_msg("ERROR: Compilation timed out.\n",[]),
+ ?error_msg("ERROR: Compilation of ~w timed out.\n",[Name]),
exit(timed_out)
end,
Result = receive {CompProc, Res} -> Res end,
@@ -844,11 +845,25 @@ finalize_fun_sequential({MFA, Icode}, Opts, Servers) ->
catch
error:Error ->
?when_option(verbose, Opts, ?debug_untagged_msg("\n", [])),
- ErrorInfo = {Error, erlang:get_stacktrace()},
- ?error_msg("ERROR: ~p~n", [ErrorInfo]),
- ?EXIT(ErrorInfo)
+ print_crash_message(MFA, Error),
+ exit(Error)
end.
+print_crash_message(What, Error) ->
+ StackFun = fun(_,_,_) -> false end,
+ FormatFun = fun (Term, _) -> io_lib:format("~p", [Term]) end,
+ StackTrace = lib:format_stacktrace(1, erlang:get_stacktrace(),
+ StackFun, FormatFun),
+ WhatS = case What of
+ {M,F,A} -> io_lib:format("~w:~w/~w", [M,F,A]);
+ Mod -> io_lib:format("~w", [Mod])
+ end,
+ ?error_msg("INTERNAL ERROR~n"
+ "while compiling ~s~n"
+ "crash reason: ~p~n"
+ "~s~n",
+ [WhatS, Error, StackTrace]).
+
pp_server_start(Opts) ->
set_architecture(Opts),
garbage_collect(),
diff --git a/lib/hipe/main/hipe.hrl.src b/lib/hipe/main/hipe.hrl.src
index 53b59f88f0..b9accf0054 100644
--- a/lib/hipe/main/hipe.hrl.src
+++ b/lib/hipe/main/hipe.hrl.src
@@ -1,9 +1,5 @@
-%% -*- erlang-indent-level: 2 -*-
+%% -*- mode: erlang; erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Filename : hipe.hrl (automatically generated by hipe.hrl.src)
@@ -70,20 +64,24 @@
code_server:info_msg(?MSGTAG ++ Msg, Args)).
-define(untagged_msg(Msg, Args),
code_server:info_msg(Msg, Args)).
+-define(untagged_error_msg(Msg, Args),
+ code_server:error_msg(Msg, Args)).
-else.
-define(msg(Msg, Args),
io:format(?MSGTAG ++ Msg, Args)).
-define(untagged_msg(Msg, Args),
io:format(Msg, Args)).
+-define(untagged_error_msg(Msg, Args),
+ io:format(Msg, Args)).
-endif.
%%
%% Define error and warning messages.
%%
-define(error_msg(Msg, Args),
- code_server:error_msg(?MSGTAG ++
+ ?untagged_error_msg(?MSGTAG ++
"Error: [~s:~w]: " ++ Msg,
- [?MODULE,?LINE|Args])).
+ [?MODULE,?LINE|Args])).
-define(WARNING_MSG(Msg, Args),
?msg("Warning: [~s:~w]: " ++ Msg, [?MODULE,?LINE|Args])).
diff --git a/lib/hipe/main/hipe_main.erl b/lib/hipe/main/hipe_main.erl
index 4b89feb48a..dca6fddec3 100644
--- a/lib/hipe/main/hipe_main.erl
+++ b/lib/hipe/main/hipe_main.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%% @doc This is the HiPE compiler's main "loop".
%%
%% <h3>Purpose</h3>
diff --git a/lib/hipe/misc/hipe_consttab.erl b/lib/hipe/misc/hipe_consttab.erl
index 226b20fa46..64e3d3ccaa 100644
--- a/lib/hipe/misc/hipe_consttab.erl
+++ b/lib/hipe/misc/hipe_consttab.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% @doc
diff --git a/lib/hipe/misc/hipe_consttab.hrl b/lib/hipe/misc/hipe_consttab.hrl
index 550da0455c..4d2d357a0b 100644
--- a/lib/hipe/misc/hipe_consttab.hrl
+++ b/lib/hipe/misc/hipe_consttab.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-----------------------------------------------------------------------------
diff --git a/lib/hipe/misc/hipe_data_pp.erl b/lib/hipe/misc/hipe_data_pp.erl
index 6cdc6c5ad2..2c737b6d78 100644
--- a/lib/hipe/misc/hipe_data_pp.erl
+++ b/lib/hipe/misc/hipe_data_pp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
-%% Time-stamp: <2008-04-20 14:57:08 richard>
%% ====================================================================
%% Module : hipe_data_pp
%% Purpose :
diff --git a/lib/hipe/misc/hipe_gensym.erl b/lib/hipe/misc/hipe_gensym.erl
index da7c4f9a5d..548071fd8f 100644
--- a/lib/hipe/misc/hipe_gensym.erl
+++ b/lib/hipe/misc/hipe_gensym.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,16 +11,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%=======================================================================
%% File : hipe_gensym.erl
%% Author : Eric Johansson and Kostis Sagonas
%% Description : Generates unique symbols and fresh integer counts.
%%=======================================================================
-%% $Id$
-%%=======================================================================
%% Notes: Written while we were in Montreal, Canada for PPDP-2000 as an
%% exercise in Principles and Practice of Declarative Programming!
%%=======================================================================
diff --git a/lib/hipe/misc/hipe_pack_constants.erl b/lib/hipe/misc/hipe_pack_constants.erl
index b54830dd57..9dd18bce0f 100644
--- a/lib/hipe/misc/hipe_pack_constants.erl
+++ b/lib/hipe/misc/hipe_pack_constants.erl
@@ -1,10 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
-%%=============================================================================
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_pack_constants).
-export([pack_constants/2, slim_refs/1, slim_constmap/1,
diff --git a/lib/hipe/misc/hipe_sdi.erl b/lib/hipe/misc/hipe_sdi.erl
index 5ca64bc669..9a60382686 100644
--- a/lib/hipe/misc/hipe_sdi.erl
+++ b/lib/hipe/misc/hipe_sdi.erl
@@ -1,10 +1,6 @@
%%% -*- erlang-indent-level: 2 -*-
%%%======================================================================
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% An implementation of the algorithm described in:
%%% "Assembling Code for Machines with Span-Dependent Instructions",
diff --git a/lib/hipe/misc/hipe_sdi.hrl b/lib/hipe/misc/hipe_sdi.hrl
index a1e12f9df2..def697549c 100644
--- a/lib/hipe/misc/hipe_sdi.hrl
+++ b/lib/hipe/misc/hipe_sdi.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,10 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-record(sdi_info,
{lb :: integer(), % span lower bound for short form
diff --git a/lib/hipe/misc/hipe_segment_trees.erl b/lib/hipe/misc/hipe_segment_trees.erl
index 22146396c3..3d6a7487ec 100644
--- a/lib/hipe/misc/hipe_segment_trees.erl
+++ b/lib/hipe/misc/hipe_segment_trees.erl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +10,6 @@
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
%%%
-%%% %CopyrightEnd%
-%%%
%%% Segment trees, with a delete operation.
%%%
%%% Keys are the (0-based) indices into the list passed to build/1.
diff --git a/lib/hipe/opt/hipe_schedule.erl b/lib/hipe/opt/hipe_schedule.erl
index 00ad487620..531690f885 100644
--- a/lib/hipe/opt/hipe_schedule.erl
+++ b/lib/hipe/opt/hipe_schedule.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/opt/hipe_schedule_prio.erl b/lib/hipe/opt/hipe_schedule_prio.erl
index 3dcc0845e0..339bb82aab 100644
--- a/lib/hipe/opt/hipe_schedule_prio.erl
+++ b/lib/hipe/opt/hipe_schedule_prio.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/opt/hipe_spillmin.erl b/lib/hipe/opt/hipe_spillmin.erl
index a2efd35d26..b28a6bfd13 100644
--- a/lib/hipe/opt/hipe_spillmin.erl
+++ b/lib/hipe/opt/hipe_spillmin.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ==========================================================================
%% Module : hipe_spillmin
@@ -24,8 +18,6 @@
%% by a function. This is done using an algorithm for register
%% allocation. The implementation is target-independent and
%% requires a target-specific interface module as argument.
-%%
-%% $Id$
%% ==========================================================================
%% Exported functions (short description):
%%
diff --git a/lib/hipe/opt/hipe_spillmin_color.erl b/lib/hipe/opt/hipe_spillmin_color.erl
index a0d6b03503..50e073a467 100644
--- a/lib/hipe/opt/hipe_spillmin_color.erl
+++ b/lib/hipe/opt/hipe_spillmin_color.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ===========================================================================
%%@doc
diff --git a/lib/hipe/opt/hipe_spillmin_scan.erl b/lib/hipe/opt/hipe_spillmin_scan.erl
index 097a787152..484b05b790 100644
--- a/lib/hipe/opt/hipe_spillmin_scan.erl
+++ b/lib/hipe/opt/hipe_spillmin_scan.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ===========================================================================
%% Copyright (c) 2002 by Niklas Andersson, Andreas Lundin, and Erik Johansson.
diff --git a/lib/hipe/opt/hipe_target_machine.erl b/lib/hipe/opt/hipe_target_machine.erl
index f64bb8b518..75993cb95e 100644
--- a/lib/hipe/opt/hipe_target_machine.erl
+++ b/lib/hipe/opt/hipe_target_machine.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/opt/hipe_ultra_mod2.erl b/lib/hipe/opt/hipe_ultra_mod2.erl
index f28c4e6939..cec9c56a1e 100644
--- a/lib/hipe/opt/hipe_ultra_mod2.erl
+++ b/lib/hipe/opt/hipe_ultra_mod2.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/opt/hipe_ultra_prio.erl b/lib/hipe/opt/hipe_ultra_prio.erl
index 423dc0d6bf..6dd240a33a 100644
--- a/lib/hipe/opt/hipe_ultra_prio.erl
+++ b/lib/hipe/opt/hipe_ultra_prio.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/ppc/hipe_ppc.erl b/lib/hipe/ppc/hipe_ppc.erl
index 380e791bc1..df9f193fa3 100644
--- a/lib/hipe/ppc/hipe_ppc.erl
+++ b/lib/hipe/ppc/hipe_ppc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,10 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-module(hipe_ppc).
-export([
diff --git a/lib/hipe/ppc/hipe_ppc.hrl b/lib/hipe/ppc/hipe_ppc.hrl
index aa8ff4a3f7..a96692c52e 100644
--- a/lib/hipe/ppc/hipe_ppc.hrl
+++ b/lib/hipe/ppc/hipe_ppc.hrl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,10 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
-%%%
-
%%%--------------------------------------------------------------------
%%% Basic Values:
diff --git a/lib/hipe/ppc/hipe_ppc_assemble.erl b/lib/hipe/ppc/hipe_ppc_assemble.erl
index d89ff6235c..66817837df 100644
--- a/lib/hipe/ppc/hipe_ppc_assemble.erl
+++ b/lib/hipe/ppc/hipe_ppc_assemble.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,10 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-module(hipe_ppc_assemble).
-export([assemble/4]).
diff --git a/lib/hipe/ppc/hipe_ppc_cfg.erl b/lib/hipe/ppc/hipe_ppc_cfg.erl
index ee9b4432e0..f17c0ac503 100644
--- a/lib/hipe/ppc/hipe_ppc_cfg.erl
+++ b/lib/hipe/ppc/hipe_ppc_cfg.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_cfg).
diff --git a/lib/hipe/ppc/hipe_ppc_defuse.erl b/lib/hipe/ppc/hipe_ppc_defuse.erl
index 305e88488d..9a99611493 100644
--- a/lib/hipe/ppc/hipe_ppc_defuse.erl
+++ b/lib/hipe/ppc/hipe_ppc_defuse.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_defuse).
-export([insn_def_all/1, insn_use_all/1]).
diff --git a/lib/hipe/ppc/hipe_ppc_encode.erl b/lib/hipe/ppc/hipe_ppc_encode.erl
index 793f6ccc02..1d0ce4f510 100644
--- a/lib/hipe/ppc/hipe_ppc_encode.erl
+++ b/lib/hipe/ppc/hipe_ppc_encode.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 4 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Encode symbolic PowerPC instructions to binary form.
%%% Copyright (C) 2003-2005, 2009 Mikael Pettersson
diff --git a/lib/hipe/ppc/hipe_ppc_finalise.erl b/lib/hipe/ppc/hipe_ppc_finalise.erl
index 8bb9520f89..8db2bf48a5 100644
--- a/lib/hipe/ppc/hipe_ppc_finalise.erl
+++ b/lib/hipe/ppc/hipe_ppc_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_finalise).
-export([finalise/1]).
diff --git a/lib/hipe/ppc/hipe_ppc_frame.erl b/lib/hipe/ppc/hipe_ppc_frame.erl
index 8d37159ad8..a91cb18cc2 100644
--- a/lib/hipe/ppc/hipe_ppc_frame.erl
+++ b/lib/hipe/ppc/hipe_ppc_frame.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_frame).
-export([frame/1]).
@@ -98,7 +91,10 @@ do_pseudo_move(I, Context, FPoff) ->
Offset = pseudo_offset(Src, FPoff, Context),
mk_load(hipe_ppc:ldop_word(), Dst, Offset, mk_sp(), []);
_ ->
- [hipe_ppc:mk_alu('or', Dst, Src, Src)]
+ case hipe_ppc:temp_reg(Dst) =:= hipe_ppc:temp_reg(Src) of
+ true -> [];
+ false -> [hipe_ppc:mk_alu('or', Dst, Src, Src)]
+ end
end
end.
diff --git a/lib/hipe/ppc/hipe_ppc_liveness_all.erl b/lib/hipe/ppc/hipe_ppc_liveness_all.erl
index cab7605967..42138eea08 100644
--- a/lib/hipe/ppc/hipe_ppc_liveness_all.erl
+++ b/lib/hipe/ppc/hipe_ppc_liveness_all.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_liveness_all).
-export([analyse/1]).
diff --git a/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl b/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl
index 1437e27508..eeca0e523e 100644
--- a/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl
+++ b/lib/hipe/ppc/hipe_ppc_liveness_fpr.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_liveness_fpr).
-export([analyse/1]).
diff --git a/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl b/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl
index 074fada918..ab9d28266c 100644
--- a/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl
+++ b/lib/hipe/ppc/hipe_ppc_liveness_gpr.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_liveness_gpr).
-export([analyse/1]).
diff --git a/lib/hipe/ppc/hipe_ppc_main.erl b/lib/hipe/ppc/hipe_ppc_main.erl
index 5d1b0d0305..a094aa65f7 100644
--- a/lib/hipe/ppc/hipe_ppc_main.erl
+++ b/lib/hipe/ppc/hipe_ppc_main.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_main).
-export([rtl_to_ppc/3]).
diff --git a/lib/hipe/ppc/hipe_ppc_pp.erl b/lib/hipe/ppc/hipe_ppc_pp.erl
index e69e6b64a2..4ee91f771e 100644
--- a/lib/hipe/ppc/hipe_ppc_pp.erl
+++ b/lib/hipe/ppc/hipe_ppc_pp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_pp).
-export([pp/1, pp/2, pp_insn/1]).
@@ -170,6 +163,12 @@ pp_insn(Dev, I, Pre) ->
io:format(Dev, ", ", []),
pp_temp(Dev, Base2),
io:format(Dev, "\n", []);
+ #unary{unop={UnOp,I1,I2,I3}, dst=Dst, src=Src} ->
+ io:format(Dev, "\t~s ", [UnOp]),
+ pp_temp(Dev, Dst),
+ io:format(Dev, ", ", []),
+ pp_temp(Dev, Src),
+ io:format(Dev, ", ~s, ~s, ~s\n", [to_hex(I1),to_hex(I2),to_hex(I3)]);
#unary{unop=UnOp, dst=Dst, src=Src} ->
io:format(Dev, "\t~w ", [unop_name(UnOp)]),
pp_temp(Dev, Dst),
diff --git a/lib/hipe/ppc/hipe_ppc_ra.erl b/lib/hipe/ppc/hipe_ppc_ra.erl
index f8614db4ef..b8daf72cef 100644
--- a/lib/hipe/ppc/hipe_ppc_ra.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_ra).
-export([ra/2]).
diff --git a/lib/hipe/ppc/hipe_ppc_ra_finalise.erl b/lib/hipe/ppc/hipe_ppc_ra_finalise.erl
index 78f123116e..74ef7475eb 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_finalise.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_ra_finalise).
-export([finalise/3]).
diff --git a/lib/hipe/ppc/hipe_ppc_ra_ls.erl b/lib/hipe/ppc/hipe_ppc_ra_ls.erl
index 5f331542e8..d8b2087919 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_ls.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_ls.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Linear Scan register allocator for PowerPC
diff --git a/lib/hipe/ppc/hipe_ppc_ra_naive.erl b/lib/hipe/ppc/hipe_ppc_ra_naive.erl
index 322fb1a171..dee89f66f9 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_naive.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_naive.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_ra_naive).
-export([ra/4]).
diff --git a/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl b/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl
index f084a30e63..95aa294fe5 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_postconditions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_ra_postconditions).
diff --git a/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl b/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl
index 81064079aa..5ec5f29577 100644
--- a/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl
+++ b/lib/hipe/ppc/hipe_ppc_ra_postconditions_fp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_ra_postconditions_fp).
-export([check_and_rewrite/2]).
diff --git a/lib/hipe/ppc/hipe_ppc_registers.erl b/lib/hipe/ppc/hipe_ppc_registers.erl
index 8f6d9779fc..86bea784f1 100644
--- a/lib/hipe/ppc/hipe_ppc_registers.erl
+++ b/lib/hipe/ppc/hipe_ppc_registers.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_registers).
diff --git a/lib/hipe/ppc/hipe_ppc_subst.erl b/lib/hipe/ppc/hipe_ppc_subst.erl
index 5e43fd6471..1cd18b5c01 100644
--- a/lib/hipe/ppc/hipe_ppc_subst.erl
+++ b/lib/hipe/ppc/hipe_ppc_subst.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_subst).
-export([insn_temps/2]).
diff --git a/lib/hipe/ppc/hipe_rtl_to_ppc.erl b/lib/hipe/ppc/hipe_rtl_to_ppc.erl
index a01e67a789..c0010a8690 100644
--- a/lib/hipe/ppc/hipe_rtl_to_ppc.erl
+++ b/lib/hipe/ppc/hipe_rtl_to_ppc.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
%%%
-%%% %CopyrightEnd%
-%%%
%%% The PowerPC instruction set is quite irregular.
%%% The following quirks must be handled by the translation:
%%%
@@ -80,7 +74,6 @@ conv_insn(I, Map, Data) ->
case I of
#alu{} -> conv_alu(I, Map, Data);
#alub{} -> conv_alub(I, Map, Data);
- #branch{} -> conv_branch(I, Map, Data);
#call{} -> conv_call(I, Map, Data);
#comment{} -> conv_comment(I, Map, Data);
#enter{} -> conv_enter(I, Map, Data);
@@ -441,36 +434,53 @@ mk_alu_rr(Dst, Src1, RtlAluOp, Src2) ->
conv_alub(I, Map, Data) ->
%% dst = src1 aluop src2; if COND goto label
- {Dst, Map0} = conv_dst(hipe_rtl:alub_dst(I), Map),
- {Src1, Map1} = conv_src(hipe_rtl:alub_src1(I), Map0),
- {Src2, Map2} = conv_src(hipe_rtl:alub_src2(I), Map1),
- {AluOp, BCond} =
- case {hipe_rtl:alub_op(I), hipe_rtl:alub_cond(I)} of
- {'add', 'ltu'} ->
- {'addc', 'eq'};
- {RtlAlubOp, RtlAlubCond} ->
- {conv_alub_op(RtlAlubOp), conv_alub_cond(RtlAlubCond)}
- end,
- BC = mk_pseudo_bc(BCond,
- hipe_rtl:alub_true_label(I),
- hipe_rtl:alub_false_label(I),
- hipe_rtl:alub_pred(I)),
- I2 =
- case {AluOp, BCond} of
- {'addc', 'eq'} -> % copy XER[CA] to CR0[EQ] before the BC
- TmpR = new_untagged_temp(),
- [hipe_ppc:mk_mfspr(TmpR, 'xer'),
- hipe_ppc:mk_mtcr(TmpR) |
- BC];
- _ -> BC
- end,
- {NewSrc1, NewSrc2} =
- case AluOp of
- 'subf' -> {Src2, Src1};
- _ -> {Src1, Src2}
- end,
- I1 = mk_alub(Dst, NewSrc1, AluOp, NewSrc2, BCond),
- {I1 ++ I2, Map2, Data}.
+ HasDst = hipe_rtl:alub_has_dst(I),
+ {Src1, Map0} = conv_src(hipe_rtl:alub_src1(I), Map),
+ {Src2, Map1} = conv_src(hipe_rtl:alub_src2(I), Map0),
+ RtlAlubOp = hipe_rtl:alub_op(I),
+ RtlAlubCond = hipe_rtl:alub_cond(I),
+ case {HasDst, RtlAlubOp} of
+ {false, sub} ->
+ {BCond,Sign} = conv_branch_cond(RtlAlubCond),
+ I2 = mk_branch(Src1, BCond, Sign, Src2,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I)),
+ {I2, Map1, Data};
+ _ ->
+ {Dst, Map2} =
+ case HasDst of
+ false -> {new_untagged_temp(), Map1};
+ true -> conv_dst(hipe_rtl:alub_dst(I), Map1)
+ end,
+ {AluOp, BCond} =
+ case {RtlAlubOp, RtlAlubCond} of
+ {'add', 'ltu'} ->
+ {'addc', 'eq'};
+ {_, _} ->
+ {conv_alub_op(RtlAlubOp), conv_alub_cond(RtlAlubCond)}
+ end,
+ BC = mk_pseudo_bc(BCond,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I)),
+ I2 =
+ case {AluOp, BCond} of
+ {'addc', 'eq'} -> % copy XER[CA] to CR0[EQ] before the BC
+ TmpR = new_untagged_temp(),
+ [hipe_ppc:mk_mfspr(TmpR, 'xer'),
+ hipe_ppc:mk_mtcr(TmpR) |
+ BC];
+ _ -> BC
+ end,
+ {NewSrc1, NewSrc2} =
+ case AluOp of
+ 'subf' -> {Src2, Src1};
+ _ -> {Src1, Src2}
+ end,
+ I1 = mk_alub(Dst, NewSrc1, AluOp, NewSrc2, BCond),
+ {I1 ++ I2, Map2, Data}
+ end.
conv_alub_op(RtlAluOp) ->
case {get(hipe_target_arch), RtlAluOp} of
@@ -689,17 +699,6 @@ mk_alub_rr_Rc(Dst, Src1, AluOp, Src2) ->
end,
[hipe_ppc:mk_alu(AluOpDot, Dst, Src1, Src2)].
-conv_branch(I, Map, Data) ->
- %% <unused> = src1 - src2; if COND goto label
- {Src1, Map0} = conv_src(hipe_rtl:branch_src1(I), Map),
- {Src2, Map1} = conv_src(hipe_rtl:branch_src2(I), Map0),
- {BCond,Sign} = conv_branch_cond(hipe_rtl:branch_cond(I)),
- I2 = mk_branch(Src1, BCond, Sign, Src2,
- hipe_rtl:branch_true_label(I),
- hipe_rtl:branch_false_label(I),
- hipe_rtl:branch_pred(I)),
- {I2, Map1, Data}.
-
conv_branch_cond(Cond) -> % may be unsigned
case Cond of
gtu -> {'gt', 'unsigned'};
diff --git a/lib/hipe/regalloc/hipe_adj_list.erl b/lib/hipe/regalloc/hipe_adj_list.erl
index de59da2410..5066106074 100644
--- a/lib/hipe/regalloc/hipe_adj_list.erl
+++ b/lib/hipe/regalloc/hipe_adj_list.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_adj_list.erl
diff --git a/lib/hipe/regalloc/hipe_amd64_specific.erl b/lib/hipe/regalloc/hipe_amd64_specific.erl
index 6937e71ac7..72900563e6 100644
--- a/lib/hipe/regalloc/hipe_amd64_specific.erl
+++ b/lib/hipe/regalloc/hipe_amd64_specific.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
+
-define(HIPE_AMD64, true).
-include("hipe_x86_specific.erl").
diff --git a/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl b/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
index 890df1b81a..9c94539bc6 100644
--- a/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
+++ b/lib/hipe/regalloc/hipe_amd64_specific_sse2.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_amd64_specific_sse2).
diff --git a/lib/hipe/regalloc/hipe_amd64_specific_x87.erl b/lib/hipe/regalloc/hipe_amd64_specific_x87.erl
index 2160e93d24..918f72f5f2 100644
--- a/lib/hipe/regalloc/hipe_amd64_specific_x87.erl
+++ b/lib/hipe/regalloc/hipe_amd64_specific_x87.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
+
-define(HIPE_AMD64, true).
-include("hipe_x86_specific_x87.erl").
diff --git a/lib/hipe/regalloc/hipe_arm_specific.erl b/lib/hipe/regalloc/hipe_arm_specific.erl
index 06ab17b0e9..cef22e5af9 100644
--- a/lib/hipe/regalloc/hipe_arm_specific.erl
+++ b/lib/hipe/regalloc/hipe_arm_specific.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_arm_specific).
diff --git a/lib/hipe/regalloc/hipe_coalescing_regalloc.erl b/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
index 00bfbaa1b6..e8ccbec9f1 100644
--- a/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_coalescing_regalloc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-----------------------------------------------------------------------
%% File : hipe_coalescing_regalloc.erl
diff --git a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
index e91734d8be..07aa812f4a 100644
--- a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%@doc
diff --git a/lib/hipe/regalloc/hipe_ig.erl b/lib/hipe/regalloc/hipe_ig.erl
index 81eee2e03c..14a1ae77f2 100644
--- a/lib/hipe/regalloc/hipe_ig.erl
+++ b/lib/hipe/regalloc/hipe_ig.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_ig.erl
diff --git a/lib/hipe/regalloc/hipe_ig_moves.erl b/lib/hipe/regalloc/hipe_ig_moves.erl
index 2a70606dab..e193a682bf 100644
--- a/lib/hipe/regalloc/hipe_ig_moves.erl
+++ b/lib/hipe/regalloc/hipe_ig_moves.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%=============================================================================
diff --git a/lib/hipe/regalloc/hipe_ls_regalloc.erl b/lib/hipe/regalloc/hipe_ls_regalloc.erl
index 0db18f5c62..785aa2b080 100644
--- a/lib/hipe/regalloc/hipe_ls_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_ls_regalloc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% =====================================================================
%% @doc
diff --git a/lib/hipe/regalloc/hipe_moves.erl b/lib/hipe/regalloc/hipe_moves.erl
index 39ccfb4a2f..409217bb03 100644
--- a/lib/hipe/regalloc/hipe_moves.erl
+++ b/lib/hipe/regalloc/hipe_moves.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_moves).
-export([new/1,
diff --git a/lib/hipe/regalloc/hipe_node_sets.erl b/lib/hipe/regalloc/hipe_node_sets.erl
index 01922a34d4..3cdfb62090 100644
--- a/lib/hipe/regalloc/hipe_node_sets.erl
+++ b/lib/hipe/regalloc/hipe_node_sets.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_node_sets).
diff --git a/lib/hipe/regalloc/hipe_optimistic_regalloc.erl b/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
index 031c799a2c..b96920cbcf 100644
--- a/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_optimistic_regalloc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-----------------------------------------------------------------------
%% File : hipe_optimistic_regalloc.erl
diff --git a/lib/hipe/regalloc/hipe_ppc_specific.erl b/lib/hipe/regalloc/hipe_ppc_specific.erl
index ed7a26de8c..a6450b4d96 100644
--- a/lib/hipe/regalloc/hipe_ppc_specific.erl
+++ b/lib/hipe/regalloc/hipe_ppc_specific.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_specific).
diff --git a/lib/hipe/regalloc/hipe_ppc_specific_fp.erl b/lib/hipe/regalloc/hipe_ppc_specific_fp.erl
index 6daa624720..23cb6c0318 100644
--- a/lib/hipe/regalloc/hipe_ppc_specific_fp.erl
+++ b/lib/hipe/regalloc/hipe_ppc_specific_fp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_ppc_specific_fp).
diff --git a/lib/hipe/regalloc/hipe_reg_worklists.erl b/lib/hipe/regalloc/hipe_reg_worklists.erl
index 00679cf19c..415f1d6122 100644
--- a/lib/hipe/regalloc/hipe_reg_worklists.erl
+++ b/lib/hipe/regalloc/hipe_reg_worklists.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%----------------------------------------------------------------------
%%% File : hipe_reg_worklists.erl
diff --git a/lib/hipe/regalloc/hipe_regalloc_loop.erl b/lib/hipe/regalloc/hipe_regalloc_loop.erl
index 3777f90534..5bbb0ba7c1 100644
--- a/lib/hipe/regalloc/hipe_regalloc_loop.erl
+++ b/lib/hipe/regalloc/hipe_regalloc_loop.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Common wrapper for graph_coloring and coalescing regallocs.
diff --git a/lib/hipe/regalloc/hipe_regalloc_prepass.erl b/lib/hipe/regalloc/hipe_regalloc_prepass.erl
index 2f1597ffd1..e212420ad2 100644
--- a/lib/hipe/regalloc/hipe_regalloc_prepass.erl
+++ b/lib/hipe/regalloc/hipe_regalloc_prepass.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%@doc
%% PREPASS FOR ITERATED REGISTER ALLOCATORS
diff --git a/lib/hipe/regalloc/hipe_sparc_specific.erl b/lib/hipe/regalloc/hipe_sparc_specific.erl
index 4c575c1c83..31fca81316 100644
--- a/lib/hipe/regalloc/hipe_sparc_specific.erl
+++ b/lib/hipe/regalloc/hipe_sparc_specific.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_specific).
diff --git a/lib/hipe/regalloc/hipe_sparc_specific_fp.erl b/lib/hipe/regalloc/hipe_sparc_specific_fp.erl
index 0334142b95..050d65e1a9 100644
--- a/lib/hipe/regalloc/hipe_sparc_specific_fp.erl
+++ b/lib/hipe/regalloc/hipe_sparc_specific_fp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_specific_fp).
diff --git a/lib/hipe/regalloc/hipe_spillcost.erl b/lib/hipe/regalloc/hipe_spillcost.erl
index b241e637d9..906cdac1aa 100644
--- a/lib/hipe/regalloc/hipe_spillcost.erl
+++ b/lib/hipe/regalloc/hipe_spillcost.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_spillcost).
diff --git a/lib/hipe/regalloc/hipe_spillcost.hrl b/lib/hipe/regalloc/hipe_spillcost.hrl
index 3cadcbe432..b1e84cee16 100644
--- a/lib/hipe/regalloc/hipe_spillcost.hrl
+++ b/lib/hipe/regalloc/hipe_spillcost.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-type hipe_array() :: integer().
@@ -25,4 +18,3 @@
{uses :: hipe_array(), % number of uses of each temp
bb_uses :: hipe_array() % number of basic blocks each temp occurs in
}).
-
diff --git a/lib/hipe/regalloc/hipe_temp_map.erl b/lib/hipe/regalloc/hipe_temp_map.erl
index b683d08054..58145efb3e 100644
--- a/lib/hipe/regalloc/hipe_temp_map.erl
+++ b/lib/hipe/regalloc/hipe_temp_map.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ===========================================================================
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
-%% Time-stamp: <2008-04-20 14:54:00 richard>
%% ===========================================================================
%% Module : hipe_temp_map
%% Purpose :
diff --git a/lib/hipe/regalloc/hipe_x86_specific.erl b/lib/hipe/regalloc/hipe_x86_specific.erl
index 67c45cdca5..c1c8dbbcd6 100644
--- a/lib/hipe/regalloc/hipe_x86_specific.erl
+++ b/lib/hipe/regalloc/hipe_x86_specific.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_SPECIFIC, hipe_amd64_specific).
diff --git a/lib/hipe/regalloc/hipe_x86_specific_x87.erl b/lib/hipe/regalloc/hipe_x86_specific_x87.erl
index 85923f8f44..4b4c83f76d 100644
--- a/lib/hipe/regalloc/hipe_x86_specific_x87.erl
+++ b/lib/hipe/regalloc/hipe_x86_specific_x87.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_SPECIFIC_X87, hipe_amd64_specific_x87).
diff --git a/lib/hipe/rtl/hipe_icode2rtl.erl b/lib/hipe/rtl/hipe_icode2rtl.erl
index 22feca47cc..82970f04ab 100644
--- a/lib/hipe/rtl/hipe_icode2rtl.erl
+++ b/lib/hipe/rtl/hipe_icode2rtl.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,17 +11,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%=======================================================================
%% File : hipe_icode2rtl.erl
%% Author(s) : Erik Johansson
%% Description : Translates Icode to RTL
%%=======================================================================
-%%
-%% $Id$
-%%
%% TODO: Better handling of switches...
-module(hipe_icode2rtl).
diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl
index 0726827299..04c9728d5c 100644
--- a/lib/hipe/rtl/hipe_rtl.erl
+++ b/lib/hipe/rtl/hipe_rtl.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% @doc
@@ -187,18 +181,14 @@
mk_branch/5,
mk_branch/6,
- branch_src1/1,
- branch_src2/1,
- branch_cond/1,
- branch_true_label/1,
- branch_false_label/1,
- branch_pred/1,
+ mk_branch/7,
%% is_branch/1,
%% branch_true_label_update/2,
%% branch_false_label_update/2,
mk_alub/7,
mk_alub/8,
+ alub_has_dst/1,
alub_dst/1,
alub_src1/1,
alub_op/1,
@@ -338,6 +328,7 @@
defines/1,
redirect_jmp/3,
is_safe/1,
+ reduce_unused/1,
%% highest_var/1,
pp/1,
pp/2,
@@ -588,37 +579,25 @@ is_label(#label{}) -> true;
is_label(_) -> false.
%%
-%% branch
-%%
-
-mk_branch(Src1, Op, Src2, True, False) ->
- mk_branch(Src1, Op, Src2, True, False, 0.5).
-mk_branch(Src1, Op, Src2, True, False, P) ->
- #branch{src1=Src1, 'cond'=Op, src2=Src2, true_label=True,
- false_label=False, p=P}.
-branch_src1(#branch{src1=Src1}) -> Src1.
-branch_src1_update(Br, NewSrc) -> Br#branch{src1=NewSrc}.
-branch_src2(#branch{src2=Src2}) -> Src2.
-branch_src2_update(Br, NewSrc) -> Br#branch{src2=NewSrc}.
-branch_cond(#branch{'cond'=Cond}) -> Cond.
-branch_true_label(#branch{true_label=TrueLbl}) -> TrueLbl.
-branch_true_label_update(Br, NewTrue) -> Br#branch{true_label=NewTrue}.
-branch_false_label(#branch{false_label=FalseLbl}) -> FalseLbl.
-branch_false_label_update(Br, NewFalse) -> Br#branch{false_label=NewFalse}.
-branch_pred(#branch{p=P}) -> P.
-
-%%
%% alub
%%
-type alub_cond() :: 'eq' | 'ne' | 'ge' | 'geu' | 'gt' | 'gtu' | 'le'
| 'leu' | 'lt' | 'ltu' | 'overflow' | 'not_overflow'.
+mk_branch(Src1, Cond, Src2, True, False) ->
+ mk_branch(Src1, Cond, Src2, True, False, 0.5).
+mk_branch(Src1, Cond, Src2, True, False, P) ->
+ mk_branch(Src1, 'sub', Src2, Cond, True, False, P).
+mk_branch(Src1, Op, Src2, Cond, True, False, P) ->
+ mk_alub([], Src1, Op, Src2, Cond, True, False, P).
+
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) ->
#alub{dst=Dst, src1=Src1, op=Op, src2=Src2, 'cond'=Cond,
true_label=True, false_label=False, p=P}.
+alub_has_dst(#alub{dst=Dst}) -> Dst =/= [].
alub_dst(#alub{dst=Dst}) -> Dst.
alub_dst_update(A, NewDst) -> A#alub{dst=NewDst}.
alub_src1(#alub{src1=Src1}) -> Src1.
@@ -943,8 +922,7 @@ args(I) ->
case I of
#alu{} -> [alu_src1(I), alu_src2(I)];
#alub{} -> [alub_src1(I), alub_src2(I)];
- #branch{} -> [branch_src1(I), branch_src2(I)];
- #call{} ->
+ #call{} ->
Args = call_arglist(I) ++ hipe_rtl_arch:call_used(),
case call_is_known(I) of
false -> [call_fun(I) | Args];
@@ -987,8 +965,8 @@ args(I) ->
defines(Instr) ->
Defs = case Instr of
#alu{} -> [alu_dst(Instr)];
+ #alub{dst=[]} -> [];
#alub{} -> [alub_dst(Instr)];
- #branch{} -> [];
#call{} -> call_dstlist(Instr) ++ hipe_rtl_arch:call_defined();
#comment{} -> [];
#enter{} -> [];
@@ -1042,9 +1020,6 @@ subst_uses(Subst, I) ->
#alub{} ->
I0 = alub_src1_update(I, subst1(Subst, alub_src1(I))),
alub_src2_update(I0, subst1(Subst, alub_src2(I)));
- #branch{} ->
- I0 = branch_src1_update(I, subst1(Subst, branch_src1(I))),
- branch_src2_update(I0, subst1(Subst, branch_src2(I)));
#call{} ->
case call_is_known(I) of
false ->
@@ -1126,11 +1101,6 @@ subst_uses_llvm(Subst, I) ->
{NewSrc1, _ } = subst1_llvm(Subst1, alub_src1(I)),
I0 = alub_src1_update(I, NewSrc1),
alub_src2_update(I0, NewSrc2);
- #branch{} ->
- {NewSrc2, Subst1} = subst1_llvm(Subst, branch_src2(I)),
- {NewSrc1, _ } = subst1_llvm(Subst1, branch_src1(I)),
- I0 = branch_src1_update(I, NewSrc1),
- branch_src2_update(I0, NewSrc2);
#call{} ->
case call_is_known(I) of
false ->
@@ -1243,10 +1213,10 @@ subst_defines(Subst, I)->
case I of
#alu{} ->
alu_dst_update(I, subst1(Subst, alu_dst(I)));
+ #alub{dst=[]} ->
+ I;
#alub{} ->
alub_dst_update(I, subst1(Subst, alub_dst(I)));
- #branch{} ->
- I;
#call{} ->
call_dstlist_update(I, subst_list(Subst, call_dstlist(I)));
#comment{} ->
@@ -1313,7 +1283,6 @@ is_safe(Instr) ->
case Instr of
#alu{} -> true;
#alub{} -> false;
- #branch{} -> false;
#call{} -> false;
#comment{} -> false;
#enter{} -> false;
@@ -1340,6 +1309,24 @@ is_safe(Instr) ->
#switch{} -> false %% Maybe this is safe...
end.
+%% @spec reduce_unused(rtl_instruction())
+%% -> false | [rtl_instruction()].
+%%
+%% @doc Produces a simplified instruction sequence that is equivalent to [Instr]
+%% under the assumption that all results of Instr are unused, or 'false' if
+%% there is no such sequence (other than [Instr] itself).
+
+reduce_unused(Instr) ->
+ case Instr of
+ #alub{dst=Dst} when Dst =/= [] ->
+ [Instr#alub{dst=[]}];
+ _ ->
+ case is_safe(Instr) of
+ true -> [];
+ false -> false
+ end
+ end.
+
%%
%% True if argument is an alu-operator
%%
@@ -1386,17 +1373,6 @@ redirect_jmp(Jmp, ToOld, ToNew) ->
%% OBS: In a jmp instruction more than one labels may be identical
%% and thus need redirection!
case Jmp of
- #branch{} ->
- TmpJmp = case branch_true_label(Jmp) of
- ToOld -> branch_true_label_update(Jmp, ToNew);
- _ -> Jmp
- end,
- case branch_false_label(TmpJmp) of
- ToOld ->
- branch_false_label_update(TmpJmp, ToNew);
- _ ->
- TmpJmp
- end;
#switch{} ->
NewLbls = [case Lbl =:= ToOld of
true -> ToNew;
@@ -1591,13 +1567,6 @@ pp_instr(Dev, I) ->
io:format(Dev, "~n", []);
#label{} ->
io:format(Dev, "L~w:~n", [label_name(I)]);
- #branch{} ->
- io:format(Dev, " if (", []),
- pp_arg(Dev, branch_src1(I)),
- io:format(Dev, " ~w ", [branch_cond(I)]),
- pp_arg(Dev, branch_src2(I)),
- io:format(Dev, ") then L~w (~.2f) else L~w~n",
- [branch_true_label(I), branch_pred(I), branch_false_label(I)]);
#switch{} ->
io:format(Dev, " switch (", []),
pp_arg(Dev, switch_src(I)),
@@ -1606,7 +1575,10 @@ pp_instr(Dev, I) ->
io:format(Dev, ">\n", []);
#alub{} ->
io:format(Dev, " ", []),
- pp_arg(Dev, alub_dst(I)),
+ case alub_has_dst(I) of
+ true -> pp_arg(Dev, alub_dst(I));
+ false -> io:format(Dev, "_", [])
+ end,
io:format(Dev, " <- ", []),
pp_arg(Dev, alub_src1(I)),
io:format(Dev, " ~w ", [alub_op(I)]),
diff --git a/lib/hipe/rtl/hipe_rtl.hrl b/lib/hipe/rtl/hipe_rtl.hrl
index cc76e7e5c4..50059693aa 100644
--- a/lib/hipe/rtl/hipe_rtl.hrl
+++ b/lib/hipe/rtl/hipe_rtl.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -28,7 +22,6 @@
-record(alu, {dst, src1, op, src2}).
-record(alub, {dst, src1, op, src2, 'cond', true_label, false_label, p}).
--record(branch, {src1, src2, 'cond', true_label, false_label, p}).
-record(call, {dstlist, 'fun', arglist, type, continuation,
failcontinuation, normalcontinuation = []}).
-record(comment, {text}).
diff --git a/lib/hipe/rtl/hipe_rtl_arch.erl b/lib/hipe/rtl/hipe_rtl_arch.erl
index 397b96120e..65149ea7db 100644
--- a/lib/hipe/rtl/hipe_rtl_arch.erl
+++ b/lib/hipe/rtl/hipe_rtl_arch.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson.
%%=====================================================================
diff --git a/lib/hipe/rtl/hipe_rtl_arith.inc b/lib/hipe/rtl/hipe_rtl_arith.inc
index 0c396c8e76..c05b7aa160 100644
--- a/lib/hipe/rtl/hipe_rtl_arith.inc
+++ b/lib/hipe/rtl/hipe_rtl_arith.inc
@@ -1,10 +1,6 @@
%% -*- Erlang -*-
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_rtl_arith.inc
diff --git a/lib/hipe/rtl/hipe_rtl_arith_32.erl b/lib/hipe/rtl/hipe_rtl_arith_32.erl
index 12075ed609..1f911642d5 100644
--- a/lib/hipe/rtl/hipe_rtl_arith_32.erl
+++ b/lib/hipe/rtl/hipe_rtl_arith_32.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2002 by Erik Johansson.
diff --git a/lib/hipe/rtl/hipe_rtl_arith_64.erl b/lib/hipe/rtl/hipe_rtl_arith_64.erl
index 6dac8fb145..5fa067b98e 100644
--- a/lib/hipe/rtl/hipe_rtl_arith_64.erl
+++ b/lib/hipe/rtl/hipe_rtl_arith_64.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_rtl_arith_64.erl
diff --git a/lib/hipe/rtl/hipe_rtl_binary.erl b/lib/hipe/rtl/hipe_rtl_binary.erl
index ad23df80d2..c11f61d567 100644
--- a/lib/hipe/rtl/hipe_rtl_binary.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary.erl
@@ -1,9 +1,5 @@
-%% -*- erlang-indent-level: 2 -*-
+%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,11 +11,9 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
-%%% File : hipe_rtl_binary_2.erl
+%%% File : hipe_rtl_binary.erl
%%% Author : Per Gustafsson <[email protected]>
%%% Description :
%%%
diff --git a/lib/hipe/rtl/hipe_rtl_binary_construct.erl b/lib/hipe/rtl/hipe_rtl_binary_construct.erl
index 367d76b24d..fd0d1f1223 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_construct.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_construct.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% ====================================================================
%% Module : hipe_rtl_binary_construct
@@ -429,8 +423,8 @@ realloc_binary(SizeReg, ProcBin, Base) ->
hipe_tagscheme:set_field_from_term(ProcBinFlagsTag, ProcBin, Flags),
hipe_tagscheme:get_field_from_term(ProcBinValTag, ProcBin, BinPointer),
hipe_tagscheme:get_field_from_pointer(BinOrigSizeTag, BinPointer, OrigSize),
- hipe_rtl:mk_branch(OrigSize, 'ltu', ResultingSize,
- ReallocLblName, NoReallocLblName),
+ hipe_rtl:mk_branch(OrigSize, 'geu', ResultingSize, NoReallocLblName,
+ ReallocLblName),
NoReallocLbl,
hipe_tagscheme:get_field_from_term(ProcBinBytesTag, ProcBin, Base),
hipe_rtl:mk_goto(ContLblName),
@@ -757,9 +751,9 @@ test_alignment(SrcOffset, NumBits, Offset, AlignedCode, CCode) ->
[AlignedLbl, CLbl] = create_lbls(2),
[hipe_rtl:mk_alu(Tmp, SrcOffset, 'or', NumBits),
hipe_rtl:mk_alu(Tmp, Tmp, 'or', Offset),
- hipe_rtl:mk_alub(Tmp, Tmp, 'and', ?LOW_BITS, 'eq',
- hipe_rtl:label_name(AlignedLbl),
- hipe_rtl:label_name(CLbl)),
+ hipe_rtl:mk_branch(Tmp, 'and', ?LOW_BITS, 'eq',
+ hipe_rtl:label_name(AlignedLbl),
+ hipe_rtl:label_name(CLbl), 0.5),
AlignedLbl,
AlignedCode,
CLbl,
@@ -1284,8 +1278,7 @@ is_divisible(Dividend, Divisor, SuccLbl, FailLbl) ->
true -> %% Divisor is a power of 2
%% Test that the Log2-1 lowest bits are clear
Mask = hipe_rtl:mk_imm(Divisor - 1),
- [Tmp] = create_regs(1),
- [hipe_rtl:mk_alub(Tmp, Dividend, 'and', Mask, eq, SuccLbl, FailLbl, 0.99)];
+ [hipe_rtl:mk_branch(Dividend, 'and', Mask, eq, SuccLbl, FailLbl, 0.99)];
false ->
%% We need division, fall back to a primop
[hipe_rtl:mk_call([], is_divisible, [Dividend, hipe_rtl:mk_imm(Divisor)],
diff --git a/lib/hipe/rtl/hipe_rtl_binary_match.erl b/lib/hipe/rtl/hipe_rtl_binary_match.erl
index 528672b893..362a52f8fe 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_match.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_match.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_rtl_binary_match.erl
@@ -270,24 +264,23 @@ gen_rtl({bs_save, Slot}, [NewMs], [Ms], TrueLblName, _FalseLblName) ->
set_field_from_term({matchstate, {saveoffset, Slot}}, Ms, Offset),
hipe_rtl:mk_goto(TrueLblName)];
%% ----- bs_match_string -----
-gen_rtl({bs_match_string, String, ByteSize}, Dst, [Ms],
+gen_rtl({bs_match_string, String, BitSize}, Dst, [Ms],
TrueLblName, FalseLblName) ->
{[Offset, BinSize, Base], Instrs} =
extract_matchstate_vars([offset, binsize, base], Ms),
[SuccessLbl, ALbl, ULbl] = create_lbls(3),
[NewOffset, BitOffset] = create_gcsafe_regs(2),
- Unit = hipe_rtl_arch:word_size() - 1,
- Loops = ByteSize div Unit,
- Init =
+ Unit = (hipe_rtl_arch:word_size() - 1) * ?BYTE_SIZE,
+ Init =
[Instrs,
opt_update_ms(Dst, Ms),
- check_size(Offset, hipe_rtl:mk_imm(ByteSize*?BYTE_SIZE), BinSize,
+ check_size(Offset, hipe_rtl:mk_imm(BitSize), BinSize,
NewOffset, hipe_rtl:label_name(SuccessLbl), FalseLblName),
SuccessLbl],
SplitCode =
[hipe_rtl:mk_alub(BitOffset, Offset, 'and', hipe_rtl:mk_imm(?LOW_BITS), eq,
hipe_rtl:label_name(ALbl), hipe_rtl:label_name(ULbl))],
- Loops = ByteSize div Unit,
+ Loops = BitSize div Unit,
SkipSize = Loops * Unit,
{ACode1, UCode1} =
case Loops of
@@ -297,9 +290,9 @@ gen_rtl({bs_match_string, String, ByteSize}, Dst, [Ms],
create_loops(Loops, Unit, String, Base,
Offset, BitOffset, FalseLblName)
end,
- <<_:SkipSize/binary, RestString/binary>> = String,
+ <<_:SkipSize/bits, RestString/bits>> = String,
{ACode2, UCode2} =
- case ByteSize rem Unit of
+ case BitSize rem Unit of
0 ->
{[], []};
Rem ->
@@ -393,12 +386,12 @@ validate_unicode_retract_c_code(Src, Ms, TrueLblName, FalseLblName) ->
create_loops(Loops, Unit, String, Base, Offset, BitOffset, FalseLblName) ->
[Reg] = create_gcsafe_regs(1),
AlignedFun = fun(Value) ->
- [get_int_to_reg(Reg, Unit*?BYTE_SIZE, Base, Offset, 'srl',
+ [get_int_to_reg(Reg, Unit, Base, Offset, 'srl',
{unsigned, big}),
update_and_test(Reg, Unit, Offset, Value, FalseLblName)]
end,
UnAlignedFun = fun(Value) ->
- [get_unaligned_int_to_reg(Reg, Unit*?BYTE_SIZE,
+ [get_unaligned_int_to_reg(Reg, Unit,
Base, Offset, BitOffset,
'srl', {unsigned, big})|
update_and_test(Reg, Unit, Offset, Value, FalseLblName)]
@@ -406,31 +399,31 @@ create_loops(Loops, Unit, String, Base, Offset, BitOffset, FalseLblName) ->
{create_loops(Loops, Unit, String, AlignedFun),
create_loops(Loops, Unit, String, UnAlignedFun)}.
-create_rests(Rem, String, Base, Offset, BitOffset, FalseLblName) ->
+create_rests(RemBits, String, Base, Offset, BitOffset, FalseLblName) ->
[Reg] = create_gcsafe_regs(1),
AlignedFun = fun(Value) ->
- [get_int_to_reg(Reg, Rem*?BYTE_SIZE, Base, Offset, 'srl',
+ [get_int_to_reg(Reg, RemBits, Base, Offset, 'srl',
{unsigned, big})|
just_test(Reg, Value, FalseLblName)]
end,
UnAlignedFun = fun(Value) ->
- [get_unaligned_int_to_reg(Reg, Rem*?BYTE_SIZE,
+ [get_unaligned_int_to_reg(Reg, RemBits,
Base, Offset, BitOffset,
'srl', {unsigned, big})|
just_test(Reg, Value, FalseLblName)]
end,
- {create_loops(1, Rem, String, AlignedFun),
- create_loops(1, Rem, String, UnAlignedFun)}.
+ {create_loops(1, RemBits, String, AlignedFun),
+ create_loops(1, RemBits, String, UnAlignedFun)}.
create_loops(0, _Unit, _String, _IntFun) ->
[];
create_loops(N, Unit, String, IntFun) ->
- {Value, RestString} = get_value(Unit,String),
+ {Value, RestString} = get_value(Unit, String),
[IntFun(Value),
create_loops(N-1, Unit, RestString, IntFun)].
update_and_test(Reg, Unit, Offset, Value, FalseLblName) ->
- [add_to_offset(Offset, Offset, hipe_rtl:mk_imm(Unit*?BYTE_SIZE), FalseLblName),
+ [add_to_offset(Offset, Offset, hipe_rtl:mk_imm(Unit), FalseLblName),
just_test(Reg, Value, FalseLblName)].
just_test(Reg, Value, FalseLblName) ->
@@ -439,8 +432,8 @@ just_test(Reg, Value, FalseLblName) ->
hipe_rtl:label_name(ContLbl), FalseLblName),
ContLbl].
-get_value(N,String) ->
- <<I:N/integer-unit:8, Rest/binary>> = String,
+get_value(N, String) ->
+ <<I:N, Rest/bits>> = String,
{I, Rest}.
make_int_gc_code(I) when is_integer(I) ->
@@ -660,9 +653,8 @@ test_alignment_code(Size, Unit, SLblName, FalseLblName) ->
end.
get_fast_test_code(Size, AndTest, SLblName, FalseLblName) ->
- [Tmp] = create_gcsafe_regs(1),
- [hipe_rtl:mk_alub(Tmp, Size, 'and', hipe_rtl:mk_imm(AndTest),
- 'eq', SLblName, FalseLblName)].
+ [hipe_rtl:mk_branch(Size, 'and', hipe_rtl:mk_imm(AndTest), 'eq',
+ SLblName, FalseLblName, 0.5)].
%% This is really slow
get_slow_test_code(Size, Unit, SLblName, FalseLblName) ->
diff --git a/lib/hipe/rtl/hipe_rtl_cfg.erl b/lib/hipe/rtl/hipe_rtl_cfg.erl
index f49e8f815f..ce399498d6 100644
--- a/lib/hipe/rtl/hipe_rtl_cfg.erl
+++ b/lib/hipe/rtl/hipe_rtl_cfg.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_rtl_cfg).
@@ -83,9 +76,7 @@ mk_goto(Name) ->
branch_successors(Instr) ->
case Instr of
- #branch{} -> [hipe_rtl:branch_true_label(Instr),
- hipe_rtl:branch_false_label(Instr)];
- #alub{} -> [hipe_rtl:alub_true_label(Instr),
+ #alub{} -> [hipe_rtl:alub_true_label(Instr),
hipe_rtl:alub_false_label(Instr)];
#switch{} -> hipe_rtl:switch_labels(Instr);
#call{} ->
@@ -106,7 +97,6 @@ fails_to(Instr) ->
is_branch(Instr) ->
case Instr of
- #branch{} -> true;
#alub{} -> true;
#switch{} -> true;
#goto{} -> true;
@@ -127,7 +117,7 @@ is_branch(Instr) ->
is_pure_branch(Instr) ->
case Instr of
- #branch{} -> true;
+ #alub{} -> not hipe_rtl:alub_has_dst(Instr);
#switch{} -> true;
#goto{} -> true;
_ -> false
diff --git a/lib/hipe/rtl/hipe_rtl_cleanup_const.erl b/lib/hipe/rtl/hipe_rtl_cleanup_const.erl
index 0a1cdbacb8..bfa6b9682e 100644
--- a/lib/hipe/rtl/hipe_rtl_cleanup_const.erl
+++ b/lib/hipe/rtl/hipe_rtl_cleanup_const.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_rtl_cleanup_const.erl
diff --git a/lib/hipe/rtl/hipe_rtl_exceptions.erl b/lib/hipe/rtl/hipe_rtl_exceptions.erl
index 331719f344..03dc959bcf 100644
--- a/lib/hipe/rtl/hipe_rtl_exceptions.erl
+++ b/lib/hipe/rtl/hipe_rtl_exceptions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
@@ -27,8 +21,6 @@
%% Notes :
%% History : * 2001-04-10 Erik Johansson ([email protected]):
%% Created.
-%% CVS :
-%% $Id$
%% ====================================================================
%% Exports :
%%
diff --git a/lib/hipe/rtl/hipe_rtl_lcm.erl b/lib/hipe/rtl/hipe_rtl_lcm.erl
index 71bd06c0df..9dcdd05fb1 100644
--- a/lib/hipe/rtl/hipe_rtl_lcm.erl
+++ b/lib/hipe/rtl/hipe_rtl_lcm.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% File : hipe_rtl_lcm.erl
@@ -378,7 +372,6 @@ is_expr(I) ->
%% end;
#alub{} -> false; %% TODO: Split instruction to consider alu expression?
- #branch{} -> false;
#call{} -> false; %% We cannot prove that a call has no side-effects
#comment{} -> false;
#enter{} -> false;
diff --git a/lib/hipe/rtl/hipe_rtl_liveness.erl b/lib/hipe/rtl/hipe_rtl_liveness.erl
index 674043ec3c..98376439f3 100644
--- a/lib/hipe/rtl/hipe_rtl_liveness.erl
+++ b/lib/hipe/rtl/hipe_rtl_liveness.erl
@@ -1,9 +1,3 @@
-%% $Id$
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/rtl/hipe_rtl_mk_switch.erl b/lib/hipe/rtl/hipe_rtl_mk_switch.erl
index 5f9dffa8cf..d5cc6bd5df 100644
--- a/lib/hipe/rtl/hipe_rtl_mk_switch.erl
+++ b/lib/hipe/rtl/hipe_rtl_mk_switch.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
diff --git a/lib/hipe/rtl/hipe_rtl_primops.erl b/lib/hipe/rtl/hipe_rtl_primops.erl
index 154c2a8c57..850a75f71b 100644
--- a/lib/hipe/rtl/hipe_rtl_primops.erl
+++ b/lib/hipe/rtl/hipe_rtl_primops.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
@@ -26,9 +20,6 @@
%% Notes :
%% History : * 2001-03-15 Erik Johansson ([email protected]):
%% Created.
-%%
-%% $Id$
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(hipe_rtl_primops).
diff --git a/lib/hipe/rtl/hipe_rtl_ssa.erl b/lib/hipe/rtl/hipe_rtl_ssa.erl
index 1e3b21d6be..70f9eeedc9 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_rtl_ssa.erl
@@ -37,7 +31,7 @@
-include("hipe_rtl.hrl").
-include("../ssa/hipe_ssa.inc").
-
+
%%----------------------------------------------------------------------
%% Auxiliary operations which seriously differ between Icode and RTL.
%%----------------------------------------------------------------------
diff --git a/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl b/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl
index f08ff22ed9..3fbbf6287f 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa_avail_expr.erl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_rtl_ssa_avail_expr.erl
diff --git a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
index 7158383010..cad43e2df5 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -110,8 +104,6 @@ visit_expression(Instruction, Environment) ->
visit_alu(Instruction, Environment);
#alub{} ->
visit_alub(Instruction, Environment);
- #branch{} ->
- visit_branch(Instruction, Environment);
#call{} ->
visit_call(Instruction, Environment);
%% #comment{} ->
@@ -184,42 +176,6 @@ set_to(Dst, Val, Env) ->
{[], SSAWork, Env1}.
%%-----------------------------------------------------------------------------
-%% Procedure : visit_branch/2
-%% Purpose : do symbolic exection of branch instructions.
-%% Arguments : Inst - The instruction
-%% Env - The environment
-%% Returns : { FlowWorkList, SSAWorkList, NewEnvironment}
-%%-----------------------------------------------------------------------------
-
-visit_branch(Inst, Env) -> %% Titta också på exekverbarflagga
- Val1 = lookup_lattice_value(hipe_rtl:branch_src1(Inst), Env),
- Val2 = lookup_lattice_value(hipe_rtl:branch_src2(Inst), Env),
- CFGWL = case evaluate_relop(Val1, hipe_rtl:branch_cond(Inst), Val2) of
- true -> [hipe_rtl:branch_true_label(Inst)];
- false -> [hipe_rtl:branch_false_label(Inst)];
- bottom -> [hipe_rtl:branch_true_label(Inst),
- hipe_rtl:branch_false_label(Inst)];
- top -> []
- end,
- {CFGWL, [], Env}.
-
-%%-----------------------------------------------------------------------------
-%% Procedure : evaluate_relop/3
-%% Purpose : evaluate the given relop. While taking care to handle top &
-%% bottom in some sane way.
-%% Arguments : Val1, Val2 - The operands Integers or top or bottom
-%% RelOp - some relop atom from rtl.
-%% Returns : bottom, top, true or false
-%%-----------------------------------------------------------------------------
-
-evaluate_relop(Val1, RelOp, Val2) ->
- if
- (Val1==bottom) or (Val2==bottom) -> bottom ;
- (Val1==top) or (Val2==top) -> top;
- true -> hipe_rtl_arch:eval_cond(RelOp, Val1, Val2)
- end.
-
-%%-----------------------------------------------------------------------------
%% Procedure : evaluate_fixnumop/2
%% Purpose : try to evaluate a fixnumop.
%% Arguments : Val1 - operand (an integer, 'top' or 'bottom')
@@ -408,6 +364,7 @@ partial_eval_branch(Cond, N0, Z0, V0, C0) ->
Cond =:= 'ne' -> {true, Z0, true, true};
Cond =:= 'gt';
Cond =:= 'le' -> {N0, Z0, V0, true};
+ Cond =:= 'leu';
Cond =:= 'gtu' -> {true, Z0, true, C0 };
Cond =:= 'lt';
Cond =:= 'ge' -> {N0, true, V0, true};
@@ -450,7 +407,11 @@ visit_alub(Inst, Env) ->
false -> [hipe_rtl:alub_false_label(Inst)]
end
end,
- {[], NewSSA, NewEnv} = set_to(hipe_rtl:alub_dst(Inst), NewVal, Env),
+ {[], NewSSA, NewEnv} =
+ case hipe_rtl:alub_has_dst(Inst) of
+ false -> {[], [], Env};
+ true -> set_to(hipe_rtl:alub_dst(Inst), NewVal, Env)
+ end,
{Labels, NewSSA, NewEnv}.
%%-----------------------------------------------------------------------------
@@ -688,8 +649,6 @@ update_instruction(Inst, Env) ->
update_alu(Inst, Env);
#alub{} ->
update_alub(Inst, Env);
- #branch{} ->
- update_branch(Inst, Env);
#call{} ->
subst_all_uses(Inst, Env);
%% #comment{} ->
@@ -902,33 +861,6 @@ update_alu(Inst, Env) ->
{Val,_,_,_,_} = evaluate_alu(Val1, hipe_rtl:alu_op(Inst), Val2),
[hipe_rtl:mk_move(hipe_rtl:alu_dst(Inst), hipe_rtl:mk_imm(Val))]
end.
-
-%%-----------------------------------------------------------------------------
-%% Procedure : update_branch/2
-%% Purpose : update an branch-instruction
-%% Arguments : Inst - the instruction.
-%% Env - in which everything happens.
-%% Returns : list of new instruction
-%%-----------------------------------------------------------------------------
-
-update_branch(Inst, Env) ->
- Src1 = hipe_rtl:branch_src1(Inst),
- Src2 = hipe_rtl:branch_src2(Inst),
- Val1 = lookup_lattice_value(Src1, Env),
- Val2 = lookup_lattice_value(Src2, Env),
- if
- (Val1 =:= bottom) and (Val2 =:= bottom) ->
- [Inst];
- Val1 =:= bottom ->
- [hipe_rtl:subst_uses([{Src2, hipe_rtl:mk_imm(Val2)}], Inst)];
- Val2 =:= bottom ->
- [hipe_rtl:subst_uses([{Src1, hipe_rtl:mk_imm(Val1)}], Inst)];
- true ->
- case hipe_rtl_arch:eval_cond(hipe_rtl:branch_cond(Inst), Val1, Val2) of
- true -> [hipe_rtl:mk_goto(hipe_rtl:branch_true_label(Inst))];
- false -> [hipe_rtl:mk_goto(hipe_rtl:branch_false_label(Inst))]
- end
- end.
%%-----------------------------------------------------------------------------
%% Procedure : update_alub/2
@@ -943,8 +875,12 @@ 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)].
+ Goto = [hipe_rtl:mk_goto(Lab)],
+ case hipe_rtl:alub_has_dst(Inst) of
+ false -> Goto;
+ true ->
+ [hipe_rtl:mk_move(hipe_rtl:alub_dst(Inst), Res) | Goto]
+ end.
make_alub_subst_list(bottom, _, Tail) -> Tail;
make_alub_subst_list(top, Src, _) ->
diff --git a/lib/hipe/rtl/hipe_rtl_ssapre.erl b/lib/hipe/rtl/hipe_rtl_ssapre.erl
index df1a4b9376..eacaa28196 100644
--- a/lib/hipe/rtl/hipe_rtl_ssapre.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssapre.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% File : hipe_rtl_ssapre.erl
diff --git a/lib/hipe/rtl/hipe_rtl_symbolic.erl b/lib/hipe/rtl/hipe_rtl_symbolic.erl
index 1d7e0ec55e..8ca307952b 100644
--- a/lib/hipe/rtl/hipe_rtl_symbolic.erl
+++ b/lib/hipe/rtl/hipe_rtl_symbolic.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-------------------------------------------------------------------
%% File : hipe_rtl_symbolic.erl
diff --git a/lib/hipe/rtl/hipe_rtl_varmap.erl b/lib/hipe/rtl/hipe_rtl_varmap.erl
index 31165d91a4..375a8f85c0 100644
--- a/lib/hipe/rtl/hipe_rtl_varmap.erl
+++ b/lib/hipe/rtl/hipe_rtl_varmap.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
-%% Time-stamp: <2008-04-20 14:55:35 richard>
%% ====================================================================
%% Module : hipe_rtl_varmap
%% Purpose :
diff --git a/lib/hipe/rtl/hipe_tagscheme.erl b/lib/hipe/rtl/hipe_tagscheme.erl
index 8cf45772b5..35d1e7c8a4 100644
--- a/lib/hipe/rtl/hipe_tagscheme.erl
+++ b/lib/hipe/rtl/hipe_tagscheme.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%========================================================================
%%
@@ -25,9 +19,6 @@
%%
%% Modifications:
%% 020904: Happi - added support for external pids and ports.
-%%
-%%========================================================================
-%% $Id$
%%========================================================================
-module(hipe_tagscheme).
@@ -171,22 +162,21 @@ test_nil(X, TrueLab, FalseLab, Pred) ->
hipe_rtl:mk_branch(X, eq, hipe_rtl:mk_imm(?NIL), TrueLab, FalseLab, Pred).
test_cons(X, TrueLab, FalseLab, Pred) ->
- Tmp = hipe_rtl:mk_new_reg_gcsafe(),
Mask = hipe_rtl:mk_imm(?TAG_PRIMARY_MASK - ?TAG_PRIMARY_LIST),
- hipe_rtl:mk_alub(Tmp, X, 'and', Mask, 'eq', TrueLab, FalseLab, Pred).
+ hipe_rtl:mk_branch(X, 'and', Mask, 'eq', TrueLab, FalseLab, Pred).
test_is_boxed(X, TrueLab, FalseLab, Pred) ->
- Tmp = hipe_rtl:mk_new_reg_gcsafe(),
Mask = hipe_rtl:mk_imm(?TAG_PRIMARY_MASK - ?TAG_PRIMARY_BOXED),
- hipe_rtl:mk_alub(Tmp, X, 'and', Mask, 'eq', TrueLab, FalseLab, Pred).
+ hipe_rtl:mk_branch(X, 'and', Mask, 'eq', TrueLab, FalseLab, Pred).
get_header(Res, X) ->
hipe_rtl:mk_load(Res, X, hipe_rtl:mk_imm(-(?TAG_PRIMARY_BOXED))).
mask_and_compare(X, Mask, Value, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
- [hipe_rtl:mk_alu(Tmp, X, 'and', hipe_rtl:mk_imm(Mask)),
- hipe_rtl:mk_branch(Tmp, 'eq', hipe_rtl:mk_imm(Value), TrueLab, FalseLab, Pred)].
+ [hipe_rtl:mk_alu(Tmp, X, 'sub', hipe_rtl:mk_imm(Value)),
+ hipe_rtl:mk_branch(Tmp, 'and', hipe_rtl:mk_imm(Mask),
+ eq, TrueLab, FalseLab, Pred)].
test_immed1(X, Value, TrueLab, FalseLab, Pred) ->
mask_and_compare(X, ?TAG_IMMED1_MASK, Value, TrueLab, FalseLab, Pred).
@@ -238,13 +228,12 @@ test_atom(X, TrueLab, FalseLab, Pred) ->
test_tuple(X, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
- Tmp2 = hipe_rtl:mk_new_reg_gcsafe(),
HalfTrueLab = hipe_rtl:mk_new_label(),
[test_is_boxed(X, hipe_rtl:label_name(HalfTrueLab), FalseLab, Pred),
HalfTrueLab,
get_header(Tmp, X),
- hipe_rtl:mk_alub(Tmp2, Tmp, 'and', hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
- TrueLab, FalseLab, Pred)].
+ hipe_rtl:mk_branch(Tmp, 'and', hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
+ TrueLab, FalseLab, Pred)].
test_tuple_N(X, N, TrueLab, FalseLab, Pred) ->
Tmp = hipe_rtl:mk_new_reg_gcsafe(),
@@ -466,12 +455,17 @@ test_fixnums_1([Arg1, Arg2|Args], Acc) ->
test_two_fixnums(Arg1, Arg2, FalseLab) ->
TrueLab = hipe_rtl:mk_new_label(),
- case hipe_rtl:is_imm(Arg2) of
+ case hipe_rtl:is_imm(Arg1) orelse hipe_rtl:is_imm(Arg2) of
true ->
- Value = hipe_rtl:imm_value(Arg2),
+ {Imm, Var} =
+ case hipe_rtl:is_imm(Arg1) of
+ true -> {Arg1, Arg2};
+ false -> {Arg2, Arg1}
+ end,
+ Value = hipe_rtl:imm_value(Imm),
case Value band ?TAG_IMMED1_MASK of
?TAG_IMMED1_SMALL ->
- [test_fixnum(Arg1, hipe_rtl:label_name(TrueLab), FalseLab, 0.99),
+ [test_fixnum(Var, hipe_rtl:label_name(TrueLab), FalseLab, 0.99),
TrueLab];
_ ->
[hipe_rtl:mk_goto(FalseLab)]
@@ -512,28 +506,48 @@ unsafe_fixnum_sub(Arg1, Arg2, Res) ->
%%% (16X+tag)+((16Y+tag)-tag) = 16X+tag+16Y = 16(X+Y)+tag
%%% (16X+tag)-((16Y+tag)-tag) = 16X+tag-16Y = 16(X-Y)+tag
-fixnum_addsub(AluOp, Arg1, Arg2, Res, OtherLab) ->
- Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+fixnum_addsub(AluOp, Arg1, Arg2, FinalRes, OtherLab) ->
+ NoOverflowLab = hipe_rtl:mk_new_label(),
%% XXX: Consider moving this test to the users of fixnum_addsub.
- case Arg1 =/= Res andalso Arg2 =/= Res of
- true ->
- %% Args differ from res.
- NoOverflowLab = hipe_rtl:mk_new_label(),
- [hipe_rtl:mk_alu(Tmp, Arg2, sub, hipe_rtl:mk_imm(?TAG_IMMED1_SMALL)),
- hipe_rtl:mk_alub(Res, Arg1, AluOp, Tmp, not_overflow,
- hipe_rtl:label_name(NoOverflowLab),
- hipe_rtl:label_name(OtherLab), 0.99),
- NoOverflowLab];
+ {Res, Tail} =
+ case Arg1 =/= FinalRes andalso Arg2 =/= FinalRes of
+ true ->
+ %% Args differ from res.
+ {FinalRes, [NoOverflowLab]};
+ false ->
+ %% At least one of the arguments is the same as Res.
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ {Tmp, [NoOverflowLab, hipe_rtl:mk_move(FinalRes, Tmp)]}
+ end,
+ case (hipe_rtl:is_imm(Arg1) andalso AluOp =:= 'add')
+ orelse hipe_rtl:is_imm(Arg2)
+ of
+ true ->
+ %% Pre-compute the untagged immediate. The optimisers won't do this for us
+ %% since they don't know that the untag never underflows.
+ {Var, Imm0} =
+ case hipe_rtl:is_imm(Arg2) of
+ true -> {Arg1, Arg2};
+ false -> {Arg2, Arg1}
+ end,
+ Imm = hipe_rtl:mk_imm(hipe_rtl:imm_value(Imm0) - ?TAG_IMMED1_SMALL),
+ [hipe_rtl:mk_alub(Res, Var, AluOp, Imm, not_overflow,
+ hipe_rtl:label_name(NoOverflowLab),
+ hipe_rtl:label_name(OtherLab), 0.99)
+ |Tail];
false ->
- %% At least one of the arguments is the same as Res.
- Tmp2 = hipe_rtl:mk_new_var(), % XXX: shouldn't this var be a reg?
- NoOverflowLab = hipe_rtl:mk_new_label(),
- [hipe_rtl:mk_alu(Tmp, Arg2, sub, hipe_rtl:mk_imm(?TAG_IMMED1_SMALL)),
- hipe_rtl:mk_alub(Tmp2, Arg1, AluOp, Tmp, not_overflow,
+ %% Commute add to save a move on x86
+ {UntagFirst, Lhs, Rhs} =
+ case AluOp of
+ 'add' -> {Arg1, Res, Arg2};
+ 'sub' -> {Arg2, Arg1, Res}
+ end,
+ [hipe_rtl:mk_alu(Res, UntagFirst, sub,
+ hipe_rtl:mk_imm(?TAG_IMMED1_SMALL)),
+ hipe_rtl:mk_alub(Res, Lhs, AluOp, Rhs, not_overflow,
hipe_rtl:label_name(NoOverflowLab),
- hipe_rtl:label_name(OtherLab), 0.99),
- NoOverflowLab,
- hipe_rtl:mk_move(Res, Tmp2)]
+ hipe_rtl:label_name(OtherLab), 0.99)
+ |Tail]
end.
%%% ((16X+tag) div 16) * ((16Y+tag)-tag) + tag = X*16Y+tag = 16(XY)+tag
@@ -687,7 +701,6 @@ element(Dst, Index, Tuple, FailLabName, unknown, IndexInfo) ->
IndexOkLab = hipe_rtl:mk_new_label(),
Ptr = hipe_rtl:mk_new_reg(), % offset from Tuple
Header = hipe_rtl:mk_new_reg_gcsafe(),
- Tmp = hipe_rtl:mk_new_reg_gcsafe(),
UIndex = hipe_rtl:mk_new_reg_gcsafe(),
Arity = hipe_rtl:mk_new_reg_gcsafe(),
InvIndex = hipe_rtl:mk_new_reg_gcsafe(),
@@ -700,9 +713,9 @@ element(Dst, Index, Tuple, FailLabName, unknown, IndexInfo) ->
BoxedOkLab,
hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)),
hipe_rtl:mk_load(Header, Ptr, hipe_rtl:mk_imm(0)),
- hipe_rtl:mk_alub(Tmp, Header, 'and',
- hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
- hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
+ hipe_rtl:mk_branch(Header, 'and',
+ hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
+ hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
TupleOkLab,
untag_fixnum(UIndex, Index),
hipe_rtl:mk_alu(Arity, Header, 'srl',
@@ -716,9 +729,9 @@ element(Dst, Index, Tuple, FailLabName, unknown, IndexInfo) ->
BoxedOkLab,
hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)),
hipe_rtl:mk_load(Header, Ptr, hipe_rtl:mk_imm(0)),
- hipe_rtl:mk_alub(Tmp, Header, 'and',
- hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
- hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
+ hipe_rtl:mk_branch(Header, 'and',
+ hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
+ hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
TupleOkLab,
hipe_rtl:mk_alu(Arity, Header, 'srl',
hipe_rtl:mk_imm(?HEADER_ARITY_OFFS))|
@@ -734,9 +747,9 @@ element(Dst, Index, Tuple, FailLabName, unknown, IndexInfo) ->
BoxedOkLab,
hipe_rtl:mk_alu(Ptr, Tuple, 'sub', hipe_rtl:mk_imm(?TAG_PRIMARY_BOXED)),
hipe_rtl:mk_load(Header, Ptr, hipe_rtl:mk_imm(0)),
- hipe_rtl:mk_alub(Tmp, Header, 'and',
- hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
- hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
+ hipe_rtl:mk_branch(Header, 'and',
+ hipe_rtl:mk_imm(?TAG_HEADER_MASK), 'eq',
+ hipe_rtl:label_name(TupleOkLab), FailLabName, 0.99),
TupleOkLab,
untag_fixnum(UIndex, Index),
hipe_rtl:mk_alu(Arity, Header, 'srl',
@@ -870,12 +883,10 @@ heap_arch_spec(HP) ->
hipe_rtl_arch:pcb_store(?P_OFF_HEAP_FIRST, HP)].
test_heap_binary(Binary, TrueLblName, FalseLblName) ->
- Tmp1 = hipe_rtl:mk_new_reg_gcsafe(),
- Tmp2 = hipe_rtl:mk_new_reg_gcsafe(),
- [get_header(Tmp1, Binary),
- hipe_rtl:mk_alu(Tmp2, Tmp1, 'and', hipe_rtl:mk_imm(?TAG_HEADER_MASK)),
- hipe_rtl:mk_branch(Tmp2, eq, hipe_rtl:mk_imm(?TAG_HEADER_HEAP_BIN),
- TrueLblName, FalseLblName)].
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ [get_header(Tmp, Binary),
+ mask_and_compare(Tmp, ?TAG_HEADER_MASK, ?TAG_HEADER_HEAP_BIN,
+ TrueLblName, FalseLblName, 0.5)].
mk_sub_binary(Dst, ByteSize, ByteOffs, BitSize, BitOffs, Orig) ->
mk_sub_binary(Dst, ByteSize, ByteOffs, BitSize, BitOffs,
@@ -903,11 +914,10 @@ build_sub_binary(Dst, ByteSize, ByteOffs, BitSize, BitOffs,
set_field_from_term({sub_binary, orig}, Dst, Orig)].
test_subbinary(Binary, TrueLblName, FalseLblName) ->
- Tmp1 = hipe_rtl:mk_new_reg_gcsafe(),
- Tmp2 = hipe_rtl:mk_new_reg_gcsafe(),
- [get_header(Tmp1, Binary),
- hipe_rtl:mk_alu(Tmp2, Tmp1, 'and', hipe_rtl:mk_imm(?TAG_HEADER_MASK)),
- hipe_rtl:mk_branch(Tmp2, eq, hipe_rtl:mk_imm(?TAG_HEADER_SUB_BIN), TrueLblName, FalseLblName)].
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ [get_header(Tmp, Binary),
+ mask_and_compare(Tmp, ?TAG_HEADER_MASK, ?TAG_HEADER_SUB_BIN,
+ TrueLblName, FalseLblName, 0.5)].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/sparc/hipe_rtl_to_sparc.erl b/lib/hipe/sparc/hipe_rtl_to_sparc.erl
index e170fec3d6..d1a6b15508 100644
--- a/lib/hipe/sparc/hipe_rtl_to_sparc.erl
+++ b/lib/hipe/sparc/hipe_rtl_to_sparc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_rtl_to_sparc).
@@ -63,7 +56,6 @@ conv_insn(I, Map, Data) ->
case I of
#alu{} -> conv_alu(I, Map, Data);
#alub{} -> conv_alub(I, Map, Data);
- #branch{} -> conv_branch(I, Map, Data);
#call{} -> conv_call(I, Map, Data);
#comment{} -> conv_comment(I, Map, Data);
#enter{} -> conv_enter(I, Map, Data);
@@ -281,7 +273,12 @@ mk_alu_rs(XAluOp, Src1, Src2, Dst) ->
conv_alub(I, Map, Data) ->
%% dst = src1 aluop src2; if COND goto label
- {Dst, Map0} = conv_dst(hipe_rtl:alub_dst(I), Map),
+ HasDst = hipe_rtl:alub_has_dst(I),
+ {Dst, Map0} =
+ case HasDst of
+ false -> {hipe_sparc:mk_g0(), Map};
+ true -> conv_dst(hipe_rtl:alub_dst(I), Map)
+ end,
{Src1, Map1} = conv_src(hipe_rtl:alub_src1(I), Map0),
{Src2, Map2} = conv_src(hipe_rtl:alub_src2(I), Map1),
Cond = conv_cond(hipe_rtl:alub_cond(I)),
@@ -307,67 +304,33 @@ conv_alub(I, Map, Data) ->
I1 ++
[hipe_sparc:mk_rdy(TmpHi),
hipe_sparc:mk_alu('sra', Dst, hipe_sparc:mk_uimm5(31), TmpSign) |
- conv_alub2(G0, TmpSign, 'sub', NewCond, TmpHi, I)];
+ conv_alub2(G0, TmpSign, 'cmpcc', NewCond, TmpHi, I)];
_ ->
- conv_alub2(Dst, Src1, RtlAlubOp, Cond, Src2, I)
+ XAluOp =
+ case (not HasDst) andalso RtlAlubOp =:= 'sub' of
+ true -> 'cmpcc'; % == a subcc that commutes
+ false -> conv_alubop_cc(RtlAlubOp)
+ end,
+ conv_alub2(Dst, Src1, XAluOp, Cond, Src2, I)
end,
{I2, Map2, Data}.
--ifdef(notdef). % XXX: only for sparc64, alas
-conv_alub2(Dst, Src1, RtlAlubOp, Cond, Src2, I) ->
- case conv_cond_rcond(Cond) of
- [] ->
- conv_alub_bp(Dst, Src1, RtlAlubOp, Cond, Src2, I);
- RCond ->
- conv_alub_br(Dst, Src1, RtlAlubOp, RCond, Src2, I)
- end.
-
-conv_alub_br(Dst, Src1, RtlAlubOp, RCond, Src2, I) ->
- TrueLab = hipe_rtl:alub_true_label(I),
- FalseLab = hipe_rtl:alub_false_label(I),
- Pred = hipe_rtl:alub_pred(I),
- %% "Dst = Src1 AluOp Src2; if COND" becomes
- %% "Dst = Src1 AluOp Src2; if-COND(Dst)"
- {I2, _DidCommute} = mk_alu(conv_alubop_nocc(RtlAlubOp), Src1, Src2, Dst),
- I2 ++ mk_pseudo_br(RCond, Dst, TrueLab, FalseLab, Pred).
-
-conv_cond_rcond(Cond) ->
- case Cond of
- 'e' -> 'z';
- 'ne' -> 'nz';
- 'g' -> 'gz';
- 'ge' -> 'gez';
- 'l' -> 'lz';
- 'le' -> 'lez';
- _ -> [] % vs, vc, gu, geu, lu, leu
- end.
-
-conv_alubop_nocc(RtlAlubOp) ->
- case RtlAlubOp of
- 'add' -> 'add';
- 'sub' -> 'sub';
- %% mul: handled elsewhere
- 'or' -> 'or';
- 'and' -> 'and';
- 'xor' -> 'xor'
- %% no shift ops
- end.
-
-mk_pseudo_br(RCond, Dst, TrueLab, FalseLab, Pred) ->
- [hipe_sparc:mk_pseudo_br(RCond, Dst, TrueLab, FalseLab, Pred)].
--else.
-conv_alub2(Dst, Src1, RtlAlubOp, Cond, Src2, I) ->
- conv_alub_bp(Dst, Src1, RtlAlubOp, Cond, Src2, I).
--endif.
+conv_alub2(Dst, Src1, XAluOp, Cond, Src2, I) ->
+ conv_alub_bp(Dst, Src1, XAluOp, Cond, Src2, I).
-conv_alub_bp(Dst, Src1, RtlAlubOp, Cond, Src2, I) ->
+conv_alub_bp(Dst, Src1, XAluOp, Cond, Src2, I) ->
TrueLab = hipe_rtl:alub_true_label(I),
FalseLab = hipe_rtl:alub_false_label(I),
Pred = hipe_rtl:alub_pred(I),
%% "Dst = Src1 AluOp Src2; if COND" becomes
%% "Dst = Src1 AluOpCC Src22; if-COND(CC)"
- {I2, _DidCommute} = mk_alu(conv_alubop_cc(RtlAlubOp), Src1, Src2, Dst),
- I2 ++ mk_pseudo_bp(Cond, TrueLab, FalseLab, Pred).
+ {I2, DidCommute} = mk_alu(XAluOp, Src1, Src2, Dst),
+ NewCond =
+ case DidCommute andalso XAluOp =:= 'cmpcc' of
+ true -> commute_cond(Cond); % subcc does not commute; its conditions do
+ false -> Cond
+ end,
+ I2 ++ mk_pseudo_bp(NewCond, TrueLab, FalseLab, Pred).
conv_alubop_cc(RtlAlubOp) ->
case RtlAlubOp of
@@ -380,69 +343,6 @@ conv_alubop_cc(RtlAlubOp) ->
%% no shift ops
end.
-conv_branch(I, Map, Data) ->
- %% <unused> = src1 - src2; if COND goto label
- {Src1, Map0} = conv_src(hipe_rtl:branch_src1(I), Map),
- {Src2, Map1} = conv_src(hipe_rtl:branch_src2(I), Map0),
- Cond = conv_cond(hipe_rtl:branch_cond(I)),
- I2 = conv_branch2(Src1, Cond, Src2, I),
- {I2, Map1, Data}.
-
--ifdef(notdef). % XXX: only for sparc64, alas
-conv_branch2(Src1, Cond, Src2, I) ->
- case conv_cond_rcond(Cond) of
- [] ->
- conv_branch_bp(Src1, Cond, Src2, I);
- RCond ->
- conv_branch_br(Src1, RCond, Src2, I)
- end.
-
-conv_branch_br(Src1, RCond, Src2, I) ->
- TrueLab = hipe_rtl:branch_true_label(I),
- FalseLab = hipe_rtl:branch_false_label(I),
- Pred = hipe_rtl:branch_pred(I),
- %% "if src1-COND-src2" becomes
- %% "sub src1,src2,tmp; if-COND(tmp)"
- Dst = hipe_sparc:mk_new_temp('untagged'),
- XAluOp = 'cmp', % == a sub that commutes
- {I1, DidCommute} = mk_alu(XAluOp, Src1, Src2, Dst),
- NewRCond =
- case DidCommute of
- true -> commute_rcond(RCond);
- false -> RCond
- end,
- I1 ++ mk_pseudo_br(NewRCond, Dst, TrueLab, FalseLab, Pred).
-
-commute_rcond(RCond) -> % if x RCond y, then y commute_rcond(RCond) x
- case RCond of
- 'z' -> 'z'; % ==, ==
- 'nz' -> 'nz'; % !=, !=
- 'gz' -> 'lz'; % >, <
- 'gez' -> 'lez'; % >=, <=
- 'lz' -> 'gz'; % <, >
- 'lez' -> 'gez' % <=, >=
- end.
--else.
-conv_branch2(Src1, Cond, Src2, I) ->
- conv_branch_bp(Src1, Cond, Src2, I).
--endif.
-
-conv_branch_bp(Src1, Cond, Src2, I) ->
- TrueLab = hipe_rtl:branch_true_label(I),
- FalseLab = hipe_rtl:branch_false_label(I),
- Pred = hipe_rtl:branch_pred(I),
- %% "if src1-COND-src2" becomes
- %% "subcc src1,src2,%g0; if-COND(CC)"
- Dst = hipe_sparc:mk_g0(),
- XAluOp = 'cmpcc', % == a subcc that commutes
- {I1, DidCommute} = mk_alu(XAluOp, Src1, Src2, Dst),
- NewCond =
- case DidCommute of
- true -> commute_cond(Cond);
- false -> Cond
- end,
- I1 ++ mk_pseudo_bp(NewCond, TrueLab, FalseLab, Pred).
-
conv_call(I, Map, Data) ->
{Args, Map0} = conv_src_list(hipe_rtl:call_arglist(I), Map),
{Dsts, Map1} = conv_dst_list(hipe_rtl:call_dstlist(I), Map0),
diff --git a/lib/hipe/sparc/hipe_sparc.erl b/lib/hipe/sparc/hipe_sparc.erl
index 5ecb6aa8b9..916857b224 100644
--- a/lib/hipe/sparc/hipe_sparc.erl
+++ b/lib/hipe/sparc/hipe_sparc.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc).
-export([
diff --git a/lib/hipe/sparc/hipe_sparc.hrl b/lib/hipe/sparc/hipe_sparc.hrl
index 01c8d07f22..4eae6777a9 100644
--- a/lib/hipe/sparc/hipe_sparc.hrl
+++ b/lib/hipe/sparc/hipe_sparc.hrl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%%--------------------------------------------------------------------
%%% Basic Values:
diff --git a/lib/hipe/sparc/hipe_sparc_assemble.erl b/lib/hipe/sparc/hipe_sparc_assemble.erl
index e92f024968..08bd47c4d2 100644
--- a/lib/hipe/sparc/hipe_sparc_assemble.erl
+++ b/lib/hipe/sparc/hipe_sparc_assemble.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_assemble).
-export([assemble/4]).
diff --git a/lib/hipe/sparc/hipe_sparc_cfg.erl b/lib/hipe/sparc/hipe_sparc_cfg.erl
index 957c8a0d24..27374d187b 100644
--- a/lib/hipe/sparc/hipe_sparc_cfg.erl
+++ b/lib/hipe/sparc/hipe_sparc_cfg.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_cfg).
diff --git a/lib/hipe/sparc/hipe_sparc_defuse.erl b/lib/hipe/sparc/hipe_sparc_defuse.erl
index 4b5a19a19d..cb75f82e2b 100644
--- a/lib/hipe/sparc/hipe_sparc_defuse.erl
+++ b/lib/hipe/sparc/hipe_sparc_defuse.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_defuse).
-export([insn_def_all/1, insn_use_all/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_encode.erl b/lib/hipe/sparc/hipe_sparc_encode.erl
index 6a7d502fd3..f0ee2d1647 100644
--- a/lib/hipe/sparc/hipe_sparc_encode.erl
+++ b/lib/hipe/sparc/hipe_sparc_encode.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Encode symbolic SPARC instructions to binary form.
%%% Copyright (C) 2007-2008 Mikael Pettersson
diff --git a/lib/hipe/sparc/hipe_sparc_finalise.erl b/lib/hipe/sparc/hipe_sparc_finalise.erl
index 2b7125fb73..3634a4d14c 100644
--- a/lib/hipe/sparc/hipe_sparc_finalise.erl
+++ b/lib/hipe/sparc/hipe_sparc_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_finalise).
-export([finalise/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_frame.erl b/lib/hipe/sparc/hipe_sparc_frame.erl
index 37f29e660a..6f29c3c905 100644
--- a/lib/hipe/sparc/hipe_sparc_frame.erl
+++ b/lib/hipe/sparc/hipe_sparc_frame.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_frame).
-export([frame/1]).
@@ -110,7 +103,10 @@ do_pseudo_move(I, Context, FPoff) ->
Offset = pseudo_offset(Src, FPoff, Context),
mk_load(hipe_sparc:mk_sp(), Offset, Dst, []);
_ ->
- [hipe_sparc:mk_mov(Src, Dst)]
+ case hipe_sparc:temp_reg(Dst) =:= hipe_sparc:temp_reg(Src) of
+ true -> [];
+ false -> [hipe_sparc:mk_mov(Src, Dst)]
+ end
end
end.
diff --git a/lib/hipe/sparc/hipe_sparc_liveness_all.erl b/lib/hipe/sparc/hipe_sparc_liveness_all.erl
index b7c3e1962a..f67b6c0fca 100644
--- a/lib/hipe/sparc/hipe_sparc_liveness_all.erl
+++ b/lib/hipe/sparc/hipe_sparc_liveness_all.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_liveness_all).
-export([analyse/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl b/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl
index 497c554c3e..bd2c0c75ee 100644
--- a/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl
+++ b/lib/hipe/sparc/hipe_sparc_liveness_fpr.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_liveness_fpr).
-export([analyse/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl b/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl
index 55d639e3a2..848148e301 100644
--- a/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl
+++ b/lib/hipe/sparc/hipe_sparc_liveness_gpr.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_liveness_gpr).
-export([analyse/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_main.erl b/lib/hipe/sparc/hipe_sparc_main.erl
index 8e9c560bb2..ea05721f60 100644
--- a/lib/hipe/sparc/hipe_sparc_main.erl
+++ b/lib/hipe/sparc/hipe_sparc_main.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_main).
-export([rtl_to_sparc/3]).
diff --git a/lib/hipe/sparc/hipe_sparc_pp.erl b/lib/hipe/sparc/hipe_sparc_pp.erl
index 8fa0a9c788..d893094eb7 100644
--- a/lib/hipe/sparc/hipe_sparc_pp.erl
+++ b/lib/hipe/sparc/hipe_sparc_pp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_pp).
-export([pp/1, pp/2, pp_insn/1]).
diff --git a/lib/hipe/sparc/hipe_sparc_ra.erl b/lib/hipe/sparc/hipe_sparc_ra.erl
index c4b909528d..ba1a9aa3d8 100644
--- a/lib/hipe/sparc/hipe_sparc_ra.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_ra).
-export([ra/2]).
diff --git a/lib/hipe/sparc/hipe_sparc_ra_finalise.erl b/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
index 5d6056071c..5fdb73e197 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_finalise.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_ra_finalise).
-export([finalise/3]).
diff --git a/lib/hipe/sparc/hipe_sparc_ra_ls.erl b/lib/hipe/sparc/hipe_sparc_ra_ls.erl
index 7019937737..1b8659ab70 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_ls.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_ls.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% Linear Scan register allocator for SPARC
diff --git a/lib/hipe/sparc/hipe_sparc_ra_naive.erl b/lib/hipe/sparc/hipe_sparc_ra_naive.erl
index 745e44f2f9..5ea9ead6bc 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_naive.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_naive.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_ra_naive).
-export([ra/4]).
diff --git a/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl b/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
index e8e231e35c..984c97fbd4 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_postconditions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_ra_postconditions).
diff --git a/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl b/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
index 544b8b05a8..751e91425c 100644
--- a/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
+++ b/lib/hipe/sparc/hipe_sparc_ra_postconditions_fp.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_ra_postconditions_fp).
diff --git a/lib/hipe/sparc/hipe_sparc_registers.erl b/lib/hipe/sparc/hipe_sparc_registers.erl
index 20138836dd..47876e21d2 100644
--- a/lib/hipe/sparc/hipe_sparc_registers.erl
+++ b/lib/hipe/sparc/hipe_sparc_registers.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_registers).
diff --git a/lib/hipe/sparc/hipe_sparc_subst.erl b/lib/hipe/sparc/hipe_sparc_subst.erl
index e5cd244985..1d0671464e 100644
--- a/lib/hipe/sparc/hipe_sparc_subst.erl
+++ b/lib/hipe/sparc/hipe_sparc_subst.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_sparc_subst).
-export([insn_temps/2]).
diff --git a/lib/hipe/ssa/hipe_ssa.inc b/lib/hipe/ssa/hipe_ssa.inc
index 83ab320306..c7c1a8e1d7 100644
--- a/lib/hipe/ssa/hipe_ssa.inc
+++ b/lib/hipe/ssa/hipe_ssa.inc
@@ -1,9 +1,5 @@
-%% -*- erlang-indent-level: 2 -*-
+%% -*- mode: erlang; erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% File : hipe_ssa.inc
@@ -943,9 +937,9 @@ do_code([Instr|Instrs], LiveOut, Changed, Acc) ->
false ->
do_code(Instrs, LiveIn, Changed, [Instr|Acc]);
true ->
- case ?CODE:is_safe(Instr) of
+ case ?CODE:is_call(Instr) of
true ->
- case ?CODE:is_call(Instr) of
+ case ?CODE:is_safe(Instr) of
true ->
case ?CODE:call_continuation(Instr) of
[] ->
@@ -955,11 +949,6 @@ do_code([Instr|Instrs], LiveOut, Changed, Acc) ->
do_code(Instrs, LiveOut, true, [NewInstr|Acc])
end;
false ->
- do_code(Instrs, LiveOut, true, Acc)
- end;
- false -> %% not a safe instruction - cannot be removed
- case ?CODE:is_call(Instr) of
- true ->
case ?CODE:call_dstlist(Instr) of
[] -> %% result was not used anyway; no change
do_code(Instrs, LiveIn, Changed, [Instr|Acc]);
@@ -968,9 +957,14 @@ do_code([Instr|Instrs], LiveOut, Changed, Acc) ->
do_code(Instrs, LiveIn, true, [NewInstr|Acc]);
[_|_] -> %% calls with multiple dests are left untouched
do_code(Instrs, LiveIn, Changed, [Instr|Acc])
- end;
- false ->
- do_code(Instrs, LiveIn, Changed, [Instr|Acc])
+ end
+ end;
+ false ->
+ case ?CODE:reduce_unused(Instr) of
+ false -> % not a safe instruction - cannot be removed
+ do_code(Instrs, LiveIn, Changed, [Instr|Acc]);
+ Replacement ->
+ do_code(lists:reverse(Replacement, Instrs), LiveOut, true, Acc)
end
end
end;
diff --git a/lib/hipe/ssa/hipe_ssa_const_prop.inc b/lib/hipe/ssa/hipe_ssa_const_prop.inc
index 648490f9a3..9c157e0833 100644
--- a/lib/hipe/ssa/hipe_ssa_const_prop.inc
+++ b/lib/hipe/ssa/hipe_ssa_const_prop.inc
@@ -1,10 +1,6 @@
%% -*- Erlang -*-
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%-----------------------------------------------------------------------------
%% File : hipe_ssa_const_prop.inc
diff --git a/lib/hipe/ssa/hipe_ssa_copy_prop.inc b/lib/hipe/ssa/hipe_ssa_copy_prop.inc
index fd80d97b02..8677263213 100644
--- a/lib/hipe/ssa/hipe_ssa_copy_prop.inc
+++ b/lib/hipe/ssa/hipe_ssa_copy_prop.inc
@@ -1,10 +1,6 @@
%%% -*- Erlang -*-
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_ssa_copy_prop.inc
diff --git a/lib/hipe/ssa/hipe_ssa_liveness.inc b/lib/hipe/ssa/hipe_ssa_liveness.inc
index 46df8b66ad..a1b49d5d35 100644
--- a/lib/hipe/ssa/hipe_ssa_liveness.inc
+++ b/lib/hipe/ssa/hipe_ssa_liveness.inc
@@ -1,10 +1,6 @@
%% -*- Erlang -*-
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl b/lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl
index b280705a47..d9f3278b45 100644
--- a/lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl
+++ b/lib/hipe/test/bs_SUITE_data/bs_pmatch_bugs.erl
@@ -9,6 +9,7 @@ test() ->
<<49,50,51>> = lex_digits1(Bin, 1, []),
<<49,50,51>> = lex_digits2(Bin, 1, []),
ok = var_bind_bug(<<1, 2, 3, 4, 5, 6, 7, 8>>),
+ ok = bs_match_string_bug(),
ok.
%%--------------------------------------------------------------------
@@ -65,3 +66,50 @@ var_bind_bug(<<A:1/binary, B:8/integer, _C:B/binary, _Rest/binary>>) ->
B -> wrong;
_ -> ok
end.
+
+%%--------------------------------------------------------------------
+%% From: Andreas Schultz
+%% Date: 2/11/2016
+%%
+%% Either HiPE is messing up binary matches in some cases or I'm not
+%% seeing the problem. ... <SNIP PROGRAM - CLEANED UP VERSION BELOW>
+%% With Erlang 19.1.3 the HiPE compiled version behaves differently
+%% than the non-HiPE version: ... <SNIP TEST RUNS>
+%% So, do I do something wrong here or is this a legitimate HiPE bug?
+%%
+%% Yes, this was a legitimate HiPE bug: The BEAM to ICode tranaslation
+%% of the bs_match_string instruction, written long ago for binaries
+%% (i.e., with byte-sized strings), tried to do a `clever' translation
+%% of even bit-sized strings using a HiPE primop that took a `Size'
+%% argument expressed in *bytes*. ICode is not really the place to do
+%% such a thing, and moreover there is really no reason for the HiPE
+%% primop not to take a Size argument expressed in *bits* instead.
+%% The bug was fixed by changing the `Size' argument to be in bits,
+%% postponing the translation of the bs_match_string primop until RTL
+%% and doing a proper translation using bit-sized quantities there.
+%%--------------------------------------------------------------------
+
+bs_match_string_bug() ->
+ ok = test0(<<50>>),
+ Bin = data(),
+ ok = test1(Bin),
+ ok = test2(Bin),
+ ok.
+
+%% Minimal test case showing the problem matching with strings
+test0(<<6:5, 0:1, 0:2>>) -> weird;
+test0(<<6:5, _:1, _:2>>) -> ok;
+test0(_) -> default.
+
+data() -> <<50,16,0>>.
+
+%% This was the problematic test case in HiPE: 'default' was returned
+test1(<<1:3, 1:1, _:1, 0:1, 0:1, 0:1, _/binary>>) -> weird;
+test1(<<1:3, 1:1, _:1, _:1, _:1, _:1, _/binary>>) -> ok;
+test1(_) -> default.
+
+%% This variation of test1/1 above worked OK, even in HiPE
+test2(<<1:3, 1:1, _:1, A:1, B:1, C:1, _/binary>>)
+ when A =:= 1; B =:= 1; C =:= 1 -> ok;
+test2(<<1:3, 1:1, _:1, 0:1, 0:1, 0:1, _/binary>>) -> weird;
+test2(_) -> default.
diff --git a/lib/hipe/test/maps_SUITE_data/maps_redundant_branch_is_key.erl b/lib/hipe/test/maps_SUITE_data/maps_redundant_branch_is_key.erl
new file mode 100644
index 0000000000..17c3acd6af
--- /dev/null
+++ b/lib/hipe/test/maps_SUITE_data/maps_redundant_branch_is_key.erl
@@ -0,0 +1,14 @@
+-module(maps_redundant_branch_is_key).
+-export([test/0]).
+
+test() ->
+ ok = thingy(#{a => 1}),
+ ok = thingy(#{a => 2}),
+ ok.
+
+thingy(Map) ->
+ try
+ #{a := _} = Map,
+ ok
+ catch _ -> error
+ end.
diff --git a/lib/hipe/tools/hipe_jit.erl b/lib/hipe/tools/hipe_jit.erl
index ffe0e440e9..5b937a9789 100644
--- a/lib/hipe/tools/hipe_jit.erl
+++ b/lib/hipe/tools/hipe_jit.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2002 by Erik Johansson.
diff --git a/lib/hipe/tools/hipe_profile.erl b/lib/hipe/tools/hipe_profile.erl
index 9b9c0d6aad..f790dc6ebb 100644
--- a/lib/hipe/tools/hipe_profile.erl
+++ b/lib/hipe/tools/hipe_profile.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
-%% Time-stamp: <2008-04-20 14:53:42 richard>
%% ====================================================================
%% Module : hipe_profile
%% Purpose :
diff --git a/lib/hipe/tools/hipe_timer.erl b/lib/hipe/tools/hipe_timer.erl
index 90bd0bb81f..13dbeb6f87 100644
--- a/lib/hipe/tools/hipe_timer.erl
+++ b/lib/hipe/tools/hipe_timer.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,12 +11,9 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
-%% Time-stamp: <2008-04-20 14:53:36 richard>
%% ====================================================================
%% Module : hipe_timer
%% Purpose :
diff --git a/lib/hipe/util/hipe_digraph.erl b/lib/hipe/util/hipe_digraph.erl
index 7446836926..0976395262 100644
--- a/lib/hipe/util/hipe_digraph.erl
+++ b/lib/hipe/util/hipe_digraph.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%-----------------------------------------------------------------------
%% File : hipe_digraph.erl
%% Author : Tobias Lindahl <[email protected]>
diff --git a/lib/hipe/util/hipe_dot.erl b/lib/hipe/util/hipe_dot.erl
index 53e474db42..22d9c02ba0 100644
--- a/lib/hipe/util/hipe_dot.erl
+++ b/lib/hipe/util/hipe_dot.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%-------------------------------------------------------------------
%%% File : hipe_dot.erl
diff --git a/lib/hipe/util/hipe_timing.erl b/lib/hipe/util/hipe_timing.erl
index bf8a08dee5..3ebde7b1b5 100644
--- a/lib/hipe/util/hipe_timing.erl
+++ b/lib/hipe/util/hipe_timing.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%====================================================================
%% Note: Uses the process keys:
diff --git a/lib/hipe/util/hipe_vectors.erl b/lib/hipe/util/hipe_vectors.erl
index 90d736d02c..fc4e4edb24 100644
--- a/lib/hipe/util/hipe_vectors.erl
+++ b/lib/hipe/util/hipe_vectors.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
diff --git a/lib/hipe/x86/NOTES.OPTIM b/lib/hipe/x86/NOTES.OPTIM
index 4c241cacb4..c518ea3481 100644
--- a/lib/hipe/x86/NOTES.OPTIM
+++ b/lib/hipe/x86/NOTES.OPTIM
@@ -1,5 +1,3 @@
-$Id$
-
Partial x86 code optimisation guide
===================================
Priority should be given to P6 and P4, then K7,
diff --git a/lib/hipe/x86/NOTES.RA b/lib/hipe/x86/NOTES.RA
index ce80411642..173eaf229e 100644
--- a/lib/hipe/x86/NOTES.RA
+++ b/lib/hipe/x86/NOTES.RA
@@ -1,5 +1,3 @@
-$Id$
-
Register Allocation
===================
diff --git a/lib/hipe/x86/hipe_rtl_to_x86.erl b/lib/hipe/x86/hipe_rtl_to_x86.erl
index 4c8c98551c..29cad6ca51 100644
--- a/lib/hipe/x86/hipe_rtl_to_x86.erl
+++ b/lib/hipe/x86/hipe_rtl_to_x86.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
-%%%
%%%
%%% Translate 3-address RTL code to 2-address pseudo-x86 code.
@@ -91,26 +84,31 @@ conv_insn(I, Map, Data) ->
#alub{} ->
%% dst = src1 op src2; if COND goto label
BinOp = conv_binop(hipe_rtl:alub_op(I)),
- {Dst, Map0} = conv_dst(hipe_rtl:alub_dst(I), Map),
- {FixSrc1, Src1, Map1} = conv_src(hipe_rtl:alub_src1(I), Map0),
- {FixSrc2, Src2, Map2} = conv_src(hipe_rtl:alub_src2(I), Map1),
+ {FixSrc1, Src1, Map0} = conv_src(hipe_rtl:alub_src1(I), Map),
+ {FixSrc2, Src2, Map1} = conv_src(hipe_rtl:alub_src2(I), Map0),
Cc = conv_cond(hipe_rtl:alub_cond(I)),
- I1 = [hipe_x86:mk_pseudo_jcc(Cc,
- hipe_rtl:alub_true_label(I),
- hipe_rtl:alub_false_label(I),
- hipe_rtl:alub_pred(I))],
- I2 = conv_alu(Dst, Src1, BinOp, Src2, I1),
- {FixSrc1++FixSrc2++I2, Map2, Data};
- #branch{} ->
- %% <unused> = src1 - src2; if COND goto label
- {FixSrc1, Src1, Map0} = conv_src(hipe_rtl:branch_src1(I), Map),
- {FixSrc2, Src2, Map1} = conv_src(hipe_rtl:branch_src2(I), Map0),
- Cc = conv_cond(hipe_rtl:branch_cond(I)),
- I2 = conv_branch(Src1, Cc, Src2,
- hipe_rtl:branch_true_label(I),
- hipe_rtl:branch_false_label(I),
- hipe_rtl:branch_pred(I)),
- {FixSrc1++FixSrc2++I2, Map1, Data};
+ BranchOp = conv_branchop(BinOp),
+ HasDst = hipe_rtl:alub_has_dst(I),
+ {I2, Map3} =
+ case (not HasDst) andalso BranchOp =/= none of
+ true ->
+ {conv_branch(Src1, BranchOp, Src2, Cc,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I)), Map1};
+ false ->
+ {Dst, Map2} =
+ case HasDst of
+ false -> {new_untagged_temp(), Map1};
+ true -> conv_dst(hipe_rtl:alub_dst(I), Map1)
+ end,
+ I1 = [hipe_x86:mk_pseudo_jcc(Cc,
+ hipe_rtl:alub_true_label(I),
+ hipe_rtl:alub_false_label(I),
+ hipe_rtl:alub_pred(I))],
+ {conv_alu(Dst, Src1, BinOp, Src2, I1), Map2}
+ end,
+ {FixSrc1++FixSrc2++I2, Map3, Data};
#call{} ->
%% push <arg1>
%% ...
@@ -252,7 +250,9 @@ conv_insn(I, Map, Data) ->
conv_alu_nocc(Dst, Src1, 'add', Src2, Tail) ->
case (not same_opnd(Dst, Src1)) andalso (not same_opnd(Dst, Src2))
- andalso (hipe_x86:is_temp(Src1) orelse hipe_x86:is_temp(Src2))
+ %% We could use orelse instead of xor here to generate lea T1(T2), T3, but
+ %% they seem to move coalesce so well that move+add is better for them.
+ andalso (hipe_x86:is_temp(Src1) xor hipe_x86:is_temp(Src2))
of
false -> conv_alu(Dst, Src1, 'add', Src2, Tail);
true -> % Use LEA
@@ -263,6 +263,16 @@ conv_alu_nocc(Dst, Src1, 'add', Src2, Tail) ->
end,
[hipe_x86:mk_lea(Mem, Dst) | Tail]
end;
+conv_alu_nocc(Dst, Src1, 'sub', Src2, Tail) ->
+ case (not same_opnd(Dst, Src1)) andalso hipe_x86:is_temp(Src1)
+ andalso (not hipe_x86:is_temp(Src2))
+ of
+ false -> conv_alu(Dst, Src1, 'sub', Src2, Tail);
+ true -> % Use LEA
+ Imm = hipe_x86:mk_imm(-hipe_x86:imm_value(Src2)),
+ Mem = hipe_x86:mk_mem(Src1, Imm, typeof_dst(Dst)),
+ [hipe_x86:mk_lea(Mem, Dst) | Tail]
+ end;
conv_alu_nocc(Dst, Src1, BinOp, Src2, Tail) ->
conv_alu(Dst, Src1, BinOp, Src2, Tail).
@@ -360,28 +370,41 @@ conv_shift(Dst, Src1, BinOp, Src2) ->
%%% Finalise the conversion of a conditional branch operation, taking
%%% care to not introduce more temps and moves than necessary.
-conv_branch(Src1, Cc, Src2, TrueLab, FalseLab, Pred) ->
+conv_branchop('sub') -> 'cmp';
+conv_branchop('and') -> 'test';
+conv_branchop(_) -> none.
+
+branchop_commutes('cmp') -> false;
+branchop_commutes('test') -> true.
+
+conv_branch(Src1, Op, Src2, Cc, TrueLab, FalseLab, Pred) ->
case hipe_x86:is_imm(Src1) of
false ->
- mk_branch(Src1, Cc, Src2, TrueLab, FalseLab, Pred);
+ mk_branch(Src1, Op, Src2, Cc, TrueLab, FalseLab, Pred);
true ->
case hipe_x86:is_imm(Src2) of
false ->
- NewCc = commute_cc(Cc),
- mk_branch(Src2, NewCc, Src1, TrueLab, FalseLab, Pred);
+ NewCc = case branchop_commutes(Op) of
+ true -> Cc;
+ false -> commute_cc(Cc)
+ end,
+ mk_branch(Src2, Op, Src1, NewCc, TrueLab, FalseLab, Pred);
true ->
%% two immediates, let the optimiser clean it up
Tmp = new_untagged_temp(),
[hipe_x86:mk_move(Src1, Tmp) |
- mk_branch(Tmp, Cc, Src2, TrueLab, FalseLab, Pred)]
+ mk_branch(Tmp, Op, Src2, Cc, TrueLab, FalseLab, Pred)]
end
end.
-mk_branch(Src1, Cc, Src2, TrueLab, FalseLab, Pred) ->
+mk_branch(Src1, Op, Src2, Cc, TrueLab, FalseLab, Pred) ->
%% PRE: not(is_imm(Src1))
- [hipe_x86:mk_cmp(Src2, Src1),
+ [mk_branchtest(Src1, Op, Src2),
hipe_x86:mk_pseudo_jcc(Cc, TrueLab, FalseLab, Pred)].
+mk_branchtest(Src1, cmp, Src2) -> hipe_x86:mk_cmp(Src2, Src1);
+mk_branchtest(Src1, test, Src2) -> hipe_x86:mk_test(Src2, Src1).
+
%%% Convert an RTL ALU or ALUB binary operator.
conv_binop(BinOp) ->
diff --git a/lib/hipe/x86/hipe_x86.erl b/lib/hipe/x86/hipe_x86.erl
index 33d7f77cf1..cc1c75b04d 100644
--- a/lib/hipe/x86/hipe_x86.erl
+++ b/lib/hipe/x86/hipe_x86.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% representation of 2-address pseudo-amd64 code
@@ -37,7 +30,7 @@
mk_imm_from_addr/2,
mk_imm_from_atom/1,
is_imm/1,
- %% imm_value/1,
+ imm_value/1,
mk_mem/3,
%% is_mem/1,
@@ -201,7 +194,7 @@
shift_src/1,
shift_dst/1,
- %% mk_test/2,
+ mk_test/2,
test_src/1,
test_dst/1,
@@ -218,6 +211,10 @@
%% highest_temp/1
]).
+%% Other utilities
+-export([neg_cc/1
+ ]).
+
%%%
%%% Low-level accessors.
%%%
@@ -241,7 +238,7 @@ mk_imm_from_addr(Addr, Type) ->
mk_imm_from_atom(Atom) ->
mk_imm(Atom).
is_imm(X) -> case X of #x86_imm{} -> true; _ -> false end.
-%% imm_value(#x86_imm{value=Value}) -> Value.
+imm_value(#x86_imm{value=Value}) -> Value.
mk_mem(Base, Off, Type) -> #x86_mem{base=Base, off=Off, type=Type}.
%% is_mem(X) -> case X of #x86_mem{} -> true; _ -> false end.
@@ -305,7 +302,7 @@ mk_cmp(Src, Dst) -> #cmp{src=Src, dst=Dst}.
cmp_src(#cmp{src=Src}) -> Src.
cmp_dst(#cmp{dst=Dst}) -> Dst.
-%% mk_test(Src, Dst) -> #test{src=Src, dst=Dst}.
+mk_test(Src, Dst) -> #test{src=Src, dst=Dst}.
test_src(#test{src=Src}) -> Src.
test_dst(#test{dst=Dst}) -> Dst.
diff --git a/lib/hipe/x86/hipe_x86.hrl b/lib/hipe/x86/hipe_x86.hrl
index ef99bf90d9..567848bae5 100644
--- a/lib/hipe/x86/hipe_x86.hrl
+++ b/lib/hipe/x86/hipe_x86.hrl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% concrete representation of 2-address pseudo-x86 code
diff --git a/lib/hipe/x86/hipe_x86_assemble.erl b/lib/hipe/x86/hipe_x86_assemble.erl
index e21223a5b1..ef9c32ef41 100644
--- a/lib/hipe/x86/hipe_x86_assemble.erl
+++ b/lib/hipe/x86/hipe_x86_assemble.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% HiPE/x86 assembler
%%%
@@ -599,10 +593,20 @@ temp_to_xmm(#x86_temp{reg=Reg}) ->
{xmm, Reg}.
-ifdef(HIPE_AMD64).
+temp_to_rm8(#x86_temp{reg=Reg}) ->
+ {rm8, ?HIPE_X86_ENCODE:rm_reg(Reg)}.
temp_to_rm64(#x86_temp{reg=Reg}) ->
{rm64, hipe_amd64_encode:rm_reg(Reg)}.
+-else.
+temp_to_rm8(#x86_temp{reg=Reg}) ->
+ true = ?HIPE_X86_ENCODE:reg_has_8bit(Reg),
+ {rm8, ?HIPE_X86_ENCODE:rm_reg(Reg)}.
+temp_to_rm16(#x86_temp{reg=Reg}) ->
+ {rm16, ?HIPE_X86_ENCODE:rm_reg(Reg)}.
-endif.
+temp_to_rm32(#x86_temp{reg=Reg}) ->
+ {rm32, ?HIPE_X86_ENCODE:rm_reg(Reg)}.
temp_to_rmArch(#x86_temp{reg=Reg}) ->
{?RMArch, ?HIPE_X86_ENCODE:rm_reg(Reg)}.
temp_to_rm64fp(#x86_temp{reg=Reg}) ->
@@ -878,15 +882,29 @@ resolve_alu_args(Src, Dst, Context) ->
%%% test
resolve_test_args(Src, Dst, Context) ->
case Src of
- #x86_imm{} -> % imm8 not allowed
- {_ImmSize,ImmValue} = translate_imm(Src, Context, false),
- NewDst =
- case Dst of
- #x86_temp{reg=0} -> ?EAX;
- #x86_temp{} -> temp_to_rmArch(Dst);
- #x86_mem{} -> mem_to_rmArch(Dst)
- end,
- {NewDst, {imm32,ImmValue}};
+ %% Since we're using an 8-bit instruction, the immediate is not sign
+ %% extended. Thus, we can use immediates up to 255.
+ #x86_imm{value=ImmVal}
+ when is_integer(ImmVal), ImmVal >= 0, ImmVal =< 255 ->
+ Imm = {imm8, ImmVal},
+ case Dst of
+ #x86_temp{reg=0} -> {al, Imm};
+ #x86_temp{} -> resolve_test_imm8_reg(Imm, Dst);
+ #x86_mem{} -> {mem_to_rm8(Dst), Imm}
+ end;
+ #x86_imm{value=ImmVal} when is_integer(ImmVal), ImmVal >= 0 ->
+ {case Dst of
+ #x86_temp{reg=0} -> eax;
+ #x86_temp{} -> temp_to_rm32(Dst);
+ #x86_mem{} -> mem_to_rm32(Dst)
+ end, {imm32, ImmVal}};
+ #x86_imm{} -> % Negative ImmVal; use word-sized instr, imm32
+ {_, ImmVal} = translate_imm(Src, Context, false),
+ {case Dst of
+ #x86_temp{reg=0} -> ?EAX;
+ #x86_temp{} -> temp_to_rmArch(Dst);
+ #x86_mem{} -> mem_to_rmArch(Dst)
+ end, {imm32, ImmVal}};
#x86_temp{} ->
NewDst =
case Dst of
@@ -896,6 +914,18 @@ resolve_test_args(Src, Dst, Context) ->
{NewDst, temp_to_regArch(Src)}
end.
+-ifdef(HIPE_AMD64).
+resolve_test_imm8_reg(Imm, Dst) -> {temp_to_rm8(Dst), Imm}.
+-else.
+resolve_test_imm8_reg(Imm = {imm8, ImmVal}, Dst = #x86_temp{reg=Reg}) ->
+ case ?HIPE_X86_ENCODE:reg_has_8bit(Reg) of
+ true -> {temp_to_rm8(Dst), Imm};
+ false ->
+ %% Register does not exist in 8-bit version; use 16-bit instead
+ {temp_to_rm16(Dst), {imm16, ImmVal}}
+ end.
+-endif.
+
%%% shifts
resolve_shift_args(Src, Dst, Context) ->
RM32 =
diff --git a/lib/hipe/x86/hipe_x86_cfg.erl b/lib/hipe/x86/hipe_x86_cfg.erl
index b9f9c711f3..a4544e1086 100644
--- a/lib/hipe/x86/hipe_x86_cfg.erl
+++ b/lib/hipe/x86/hipe_x86_cfg.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-module(hipe_x86_cfg).
diff --git a/lib/hipe/x86/hipe_x86_defuse.erl b/lib/hipe/x86/hipe_x86_defuse.erl
index 4455def74e..5d7fadf8e5 100644
--- a/lib/hipe/x86/hipe_x86_defuse.erl
+++ b/lib/hipe/x86/hipe_x86_defuse.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% compute def/use sets for x86 insns
%%%
@@ -60,7 +54,7 @@ insn_def(I) ->
#pseudo_tailcall_prepare{} -> tailcall_clobbered();
#shift{dst=Dst} -> dst_def(Dst);
%% call, cmp, comment, jcc, jmp_fun, jmp_label, jmp_switch, label
- %% pseudo_jcc, pseudo_tailcall, push, ret
+ %% pseudo_jcc, pseudo_tailcall, push, ret, test
_ -> []
end.
@@ -120,6 +114,7 @@ insn_use(I) ->
#push{src=Src} -> addtemp(Src, []);
#ret{} -> [hipe_x86:mk_temp(?HIPE_X86_REGISTERS:?RV(), 'tagged')];
#shift{src=Src,dst=Dst} -> addtemp(Src, addtemp(Dst, []));
+ #test{src=Src, dst=Dst} -> addtemp(Src, addtemp(Dst, []));
%% comment, jcc, jmp_label, label, pseudo_jcc, pseudo_tailcall_prepare
_ -> []
end.
diff --git a/lib/hipe/x86/hipe_x86_encode.erl b/lib/hipe/x86/hipe_x86_encode.erl
index 3b7be86608..2662f76d0b 100644
--- a/lib/hipe/x86/hipe_x86_encode.erl
+++ b/lib/hipe/x86/hipe_x86_encode.erl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Copyright (C) 2000-2005 Mikael Pettersson
%%%
@@ -65,6 +58,7 @@
cc/1,
% 8-bit registers
%% al/0, cl/0, dl/0, bl/0, ah/0, ch/0, dh/0, bh/0,
+ reg_has_8bit/1,
% 32-bit registers
%% eax/0, ecx/0, edx/0, ebx/0, esp/0, ebp/0, esi/0, edi/0,
% operands
@@ -143,6 +137,8 @@ cc(g) -> ?CC_G.
%% dh() -> ?DH.
%% bh() -> ?BH.
+reg_has_8bit(Reg) -> Reg =< ?BL.
+
%%% 32-bit registers
-define(EAX, 2#000).
@@ -700,8 +696,16 @@ shd_op_sizeof(Opnds) ->
test_encode(Opnds) ->
case Opnds of
+ {al, {imm8,Imm8}} ->
+ [16#A8, Imm8];
+ {ax, {imm16,Imm16}} ->
+ [?PFX_OPND, 16#A9 | le16(Imm16, [])];
{eax, {imm32,Imm32}} ->
[16#A9 | le32(Imm32, [])];
+ {{rm8,RM8}, {imm8,Imm8}} ->
+ [16#F6 | encode_rm(RM8, 2#000, [Imm8])];
+ {{rm16,RM16}, {imm16,Imm16}} ->
+ [?PFX_OPND, 16#F7 | encode_rm(RM16, 2#000, le16(Imm16, []))];
{{rm32,RM32}, {imm32,Imm32}} ->
[16#F7 | encode_rm(RM32, 2#000, le32(Imm32, []))];
{{rm32,RM32}, {reg32,Reg32}} ->
@@ -710,8 +714,16 @@ test_encode(Opnds) ->
test_sizeof(Opnds) ->
case Opnds of
+ {al, {imm8,_}} ->
+ 1 + 1;
+ {ax, {imm16,_}} ->
+ 2 + 2;
{eax, {imm32,_}} ->
1 + 4;
+ {{rm8,RM8}, {imm8,_}} ->
+ 1 + sizeof_rm(RM8) + 1;
+ {{rm16,RM16}, {imm16,_}} ->
+ 2 + sizeof_rm(RM16) + 2;
{{rm32,RM32}, {imm32,_}} ->
1 + sizeof_rm(RM32) + 4;
{{rm32,RM32}, {reg32,_}} ->
@@ -1283,7 +1295,11 @@ dotest1(OS) ->
t(OS,'sub',{RM32,Imm8}),
t(OS,'sub',{RM32,Reg32}),
t(OS,'sub',{Reg32,RM32}),
+ t(OS,'test',{al,Imm8}),
+ t(OS,'test',{ax,Imm16}),
t(OS,'test',{eax,Imm32}),
+ t(OS,'test',{RM8,Imm8}),
+ t(OS,'test',{RM16,Imm16}),
t(OS,'test',{RM32,Imm32}),
t(OS,'test',{RM32,Reg32}),
t(OS,'xor',{eax,Imm32}),
diff --git a/lib/hipe/x86/hipe_x86_encode.txt b/lib/hipe/x86/hipe_x86_encode.txt
index 13746e2a47..eab732fb2d 100644
--- a/lib/hipe/x86/hipe_x86_encode.txt
+++ b/lib/hipe/x86/hipe_x86_encode.txt
@@ -1,5 +1,3 @@
-$Id$
-
hipe_x86_encode USAGE GUIDE
Revision 0.4, 2001-10-09
diff --git a/lib/hipe/x86/hipe_x86_frame.erl b/lib/hipe/x86/hipe_x86_frame.erl
index fc782571bf..3c2b67967a 100644
--- a/lib/hipe/x86/hipe_x86_frame.erl
+++ b/lib/hipe/x86/hipe_x86_frame.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% x86 stack frame handling
%%%
@@ -116,6 +110,8 @@ do_insn(I, LiveOut, Context, FPoff) ->
{do_ret(I, Context, FPoff), context_framesize(Context)};
#shift{} ->
{[do_shift(I, Context, FPoff)], FPoff};
+ #test{} ->
+ {[do_test(I, Context, FPoff)], FPoff};
_ -> % comment, jmp, label, pseudo_jcc, pseudo_tailcall_prepare
{[I], FPoff}
end.
@@ -188,6 +184,12 @@ do_shift(I, Context, FPoff) ->
Dst = conv_opnd(Dst0, FPoff, Context),
I#shift{src=Src,dst=Dst}.
+do_test(I, Context, FPoff) ->
+ #test{src=Src0,dst=Dst0} = I,
+ Src = conv_opnd(Src0, FPoff, Context),
+ Dst = conv_opnd(Dst0, FPoff, Context),
+ I#test{src=Src,dst=Dst}.
+
conv_opnd(Opnd, FPoff, Context) ->
case opnd_is_pseudo(Opnd) of
false ->
diff --git a/lib/hipe/x86/hipe_x86_liveness.erl b/lib/hipe/x86/hipe_x86_liveness.erl
index ce46ec920e..470501b46d 100644
--- a/lib/hipe/x86/hipe_x86_liveness.erl
+++ b/lib/hipe/x86/hipe_x86_liveness.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% x86_liveness -- compute register liveness for x86 CFGs
diff --git a/lib/hipe/x86/hipe_x86_main.erl b/lib/hipe/x86/hipe_x86_main.erl
index 341269b698..7e9fd10e62 100644
--- a/lib/hipe/x86/hipe_x86_main.erl
+++ b/lib/hipe/x86/hipe_x86_main.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_MAIN, hipe_amd64_main).
diff --git a/lib/hipe/x86/hipe_x86_postpass.erl b/lib/hipe/x86/hipe_x86_postpass.erl
index 4515822a34..b84e9bed91 100644
--- a/lib/hipe/x86/hipe_x86_postpass.erl
+++ b/lib/hipe/x86/hipe_x86_postpass.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%%----------------------------------------------------------------------
%%% File : hipe_x86_postpass.erl
@@ -120,19 +114,15 @@ peep([#move{src=Src1, dst=Dst},
%% ElimCmp0
%% --------
-peep([C=#cmp{src=Src, dst=Dst},J=#jcc{cc=Cond, label=Lab}|Insns],Res,Lst) ->
- case (((Src =:= #x86_imm{value=0}) or (Dst =:= #x86_imm{value=0})) and
- ((Cond =:= 'eq') or (Cond =:= 'neq'))) of
- true ->
- Src2 = case Src of #x86_imm{value=0} -> Src; _ -> Dst end,
- Cond2 = case Cond of 'eq' -> 'z'; 'neq' -> 'nz' end,
- Test = #test{src=Src2, dst=#x86_imm{value=0}},
- Jump = #jcc{cc=Cond2, label=Lab},
- peep(Insns, [Jump, Test|Res], [elimCmp0|Lst]);
- _ ->
- peep(Insns, [J,C|Res], Lst)
- end;
-
+peep([#cmp{src=#x86_imm{value=0}, dst=Dst=#x86_temp{}}|Insns],Res,Lst) ->
+ %% TEST leaves the adjust flag undefined, whereas CMP sets it properly (in
+ %% this case to 0). However, since HiPE does not use any instructions that
+ %% read the adjust flag, we can do this transform safely.
+ peep(Insns, [#test{src=Dst, dst=Dst} | Res], [elimCmp0_1|Lst]);
+peep([#cmp{src=Src=#x86_temp{}, dst=#x86_imm{value=0}},
+ J=#jcc{cc=Cond}|Insns],Res,Lst)
+ when Cond =:= 'e'; Cond =:= 'ne' -> % We're commuting the comparison
+ peep(Insns, [J, #test{src=Src, dst=Src} | Res], [elimCmp0_2|Lst]);
%% ElimCmpTest
%% -----------
@@ -187,6 +177,18 @@ peep([B = #alu{aluop=Op,src=#x86_imm{value=Val},dst=Dst}|Insns], Res, Lst) ->
peep(Insns, [B|Res], Lst)
end;
+%% LeaToAdd
+%% This rule transforms lea into add when the destination is the same as one of
+%% the operands. Sound because lea is never used where the condition codes are
+%% live (and would be clobbered by add).
+%% ----------
+peep([#lea{mem=#x86_mem{base=#x86_temp{reg=DstR},off=Src},
+ temp=Dst=#x86_temp{reg=DstR}}|Insns], Res, Lst) ->
+ peep(Insns, [#alu{aluop='add',src=Src,dst=Dst}|Res], [leaToAdd|Lst]);
+peep([#lea{mem=#x86_mem{base=Src,off=#x86_temp{reg=DstR}},
+ temp=Dst=#x86_temp{reg=DstR}}|Insns], Res, Lst) ->
+ peep(Insns, [#alu{aluop='add',src=Src,dst=Dst}|Res], [leaToAdd|Lst]);
+
%% SubToDec
%% This rule turns "subl $1,Dst; jl Lab" into "decl Dst; jl Lab", which
%% changes reduction counter tests to use decl instead of subl.
@@ -209,6 +211,11 @@ trivial_goto_elimination(Insns) -> goto_elim(Insns, []).
goto_elim([#jmp_label{label=Label}, I = #label{label=Label}|Insns], Res) ->
goto_elim([I|Insns], Res);
+goto_elim([#jcc{cc=CC, label=Label} = IJCC,
+ #jmp_label{label=BranchTgt},
+ #label{label=Label} = ILBL|Insns], Res) ->
+ goto_elim([IJCC#jcc{cc=hipe_x86:neg_cc(CC), label=BranchTgt},
+ ILBL|Insns], Res);
goto_elim([I | Insns], Res) ->
goto_elim(Insns, [I|Res]);
goto_elim([], Res) ->
diff --git a/lib/hipe/x86/hipe_x86_pp.erl b/lib/hipe/x86/hipe_x86_pp.erl
index ff26a31877..72d2fa80bf 100644
--- a/lib/hipe/x86/hipe_x86_pp.erl
+++ b/lib/hipe/x86/hipe_x86_pp.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% x86 pretty-printer
@@ -188,6 +182,12 @@ pp_insn(Dev, I, Pre) ->
io:format(Dev, ", ", []),
pp_dst(Dev, Dst),
io:format(Dev, "\n", []);
+ #test{src=Src, dst=Dst} ->
+ io:format(Dev, "\ttest ", []),
+ pp_src(Dev, Src),
+ io:format(Dev, ", ", []),
+ pp_dst(Dev, Dst),
+ io:format(Dev, "\n", []);
#fp_binop{src=Src, dst=Dst, op=Op} ->
io:format(Dev, "\t~s ", [Op]),
pp_dst(Dev, Dst),
diff --git a/lib/hipe/x86/hipe_x86_ra.erl b/lib/hipe/x86/hipe_x86_ra.erl
index b64c22a76c..f358306d49 100644
--- a/lib/hipe/x86/hipe_x86_ra.erl
+++ b/lib/hipe/x86/hipe_x86_ra.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_RA, hipe_amd64_ra).
diff --git a/lib/hipe/x86/hipe_x86_ra_finalise.erl b/lib/hipe/x86/hipe_x86_ra_finalise.erl
index edfd7b332c..4273e3cee8 100644
--- a/lib/hipe/x86/hipe_x86_ra_finalise.erl
+++ b/lib/hipe/x86/hipe_x86_ra_finalise.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
-%%%
%%%
%%% - apply temp -> reg/spill map from RA
@@ -162,6 +155,10 @@ ra_insn(I, Map, FpMap) ->
Src = ra_opnd(Src0, Map),
Dst = ra_opnd(Dst0, Map),
I#shift{src=Src,dst=Dst};
+ #test{src=Src0,dst=Dst0} ->
+ Src = ra_opnd(Src0, Map),
+ Dst = ra_opnd(Dst0, Map),
+ I#test{src=Src,dst=Dst};
_ ->
exit({?MODULE,ra_insn,I})
end.
diff --git a/lib/hipe/x86/hipe_x86_ra_ls.erl b/lib/hipe/x86/hipe_x86_ra_ls.erl
index 34ce50d494..581abd299d 100644
--- a/lib/hipe/x86/hipe_x86_ra_ls.erl
+++ b/lib/hipe/x86/hipe_x86_ra_ls.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% Linear Scan register allocator for x86
diff --git a/lib/hipe/x86/hipe_x86_ra_naive.erl b/lib/hipe/x86/hipe_x86_ra_naive.erl
index 35de692e07..f96c662d18 100644
--- a/lib/hipe/x86/hipe_x86_ra_naive.erl
+++ b/lib/hipe/x86/hipe_x86_ra_naive.erl
@@ -1,9 +1,5 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
%%%
%%% simple local x86 regalloc
@@ -100,6 +94,8 @@ do_insn(I) -> % Insn -> Insn list
do_fp_binop(I);
#shift{} ->
do_shift(I);
+ #test{} ->
+ do_test(I);
#label{} ->
[I];
#pseudo_jcc{} ->
@@ -310,6 +306,11 @@ do_shift(I) ->
FixDst ++ [I#shift{dst=Dst}]
end.
+do_test(I) ->
+ #test{src=Src0,dst=Dst0} = I,
+ {FixSrc, Src, FixDst, Dst} = do_binary(Src0, Dst0),
+ FixSrc ++ FixDst ++ [I#test{src=Src,dst=Dst}].
+
%%% Fix the operands of a binary op.
%%% 1. remove pseudos from any explicit memory operands
%%% 2. if both operands are (implicit or explicit) memory operands,
diff --git a/lib/hipe/x86/hipe_x86_ra_postconditions.erl b/lib/hipe/x86/hipe_x86_ra_postconditions.erl
index f496b71828..28ec9c4277 100644
--- a/lib/hipe/x86/hipe_x86_ra_postconditions.erl
+++ b/lib/hipe/x86/hipe_x86_ra_postconditions.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_RA_POSTCONDITIONS, hipe_amd64_ra_postconditions).
@@ -83,6 +76,8 @@ do_insn(I, TempMap, Strategy) -> % Insn -> {Insn list, DidSpill}
do_fmove(I, TempMap, Strategy);
#shift{} ->
do_shift(I, TempMap, Strategy);
+ #test{} ->
+ do_test(I, TempMap, Strategy);
_ ->
%% comment, jmp*, label, pseudo_call, pseudo_jcc, pseudo_tailcall,
%% pseudo_tailcall_prepare, push, ret
@@ -308,6 +303,14 @@ do_shift(I, TempMap, Strategy) ->
{FixDst ++ [I#shift{dst=Dst}], DidSpill}
end.
+%%% Fix a test op.
+
+do_test(I, TempMap, Strategy) ->
+ #test{src=Src0,dst=Dst0} = I,
+ {FixSrc, Src, FixDst, Dst, DidSpill} =
+ do_binary(Src0, Dst0, TempMap, Strategy),
+ {FixSrc ++ FixDst ++ [I#test{src=Src,dst=Dst}], DidSpill}.
+
%%% Fix the operands of a binary op.
%%% 1. remove pseudos from any explicit memory operands
%%% 2. if both operands are (implicit or explicit) memory operands,
diff --git a/lib/hipe/x86/hipe_x86_registers.erl b/lib/hipe/x86/hipe_x86_registers.erl
index f00bbfb280..dbff68ad28 100644
--- a/lib/hipe/x86/hipe_x86_registers.erl
+++ b/lib/hipe/x86/hipe_x86_registers.erl
@@ -1,8 +1,3 @@
-%%%
-%%% %CopyrightBegin%
-%%%
-%%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
@@ -14,9 +9,6 @@
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
-%%%
-%%% %CopyrightEnd%
-%%%
%%%
%%% TODO:
%%% - Do we need a pseudo reg for the condition codes?
diff --git a/lib/hipe/x86/hipe_x86_spill_restore.erl b/lib/hipe/x86/hipe_x86_spill_restore.erl
index 32b1eb7b40..90edef31f3 100644
--- a/lib/hipe/x86/hipe_x86_spill_restore.erl
+++ b/lib/hipe/x86/hipe_x86_spill_restore.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%% ====================================================================
%% Authors : Dogan Yazar and Erdem Aksu (KT2 project of 2008)
%% ====================================================================
diff --git a/lib/hipe/x86/hipe_x86_subst.erl b/lib/hipe/x86/hipe_x86_subst.erl
index 5e642d1d06..7b5fb1352b 100644
--- a/lib/hipe/x86/hipe_x86_subst.erl
+++ b/lib/hipe/x86/hipe_x86_subst.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-ifdef(HIPE_AMD64).
-define(HIPE_X86_SUBST, hipe_amd64_subst).
diff --git a/lib/hipe/x86/hipe_x86_x87.erl b/lib/hipe/x86/hipe_x86_x87.erl
index 10bb6aa75c..85268ab85a 100644
--- a/lib/hipe/x86/hipe_x86_x87.erl
+++ b/lib/hipe/x86/hipe_x86_x87.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% Floating point handling.
diff --git a/lib/inets/doc/src/http_uri.xml b/lib/inets/doc/src/http_uri.xml
index 8e0301c520..2ef36d23ee 100644
--- a/lib/inets/doc/src/http_uri.xml
+++ b/lib/inets/doc/src/http_uri.xml
@@ -118,7 +118,7 @@
<v>Option = {ipv6_host_with_brackets, boolean()} |
{scheme_defaults, scheme_defaults()} |
{fragment, boolean()} |
- {schema_validation_fun, fun()}]</v>
+ {scheme_validation_fun, fun()}]</v>
<v>Result = {Scheme, UserInfo, Host, Port, Path, Query} |
{Scheme, UserInfo, Host, Port, Path, Query, Fragment}</v>
<v>UserInfo = user_info()</v>
diff --git a/lib/inets/src/http_client/httpc_request.erl b/lib/inets/src/http_client/httpc_request.erl
index e8d020c165..89872a3831 100644
--- a/lib/inets/src/http_client/httpc_request.erl
+++ b/lib/inets/src/http_client/httpc_request.erl
@@ -88,9 +88,11 @@ send(SendAddr, Socket, SocketType,
case Address of
SendAddr ->
{TmpHdrs2, Path ++ Query};
- _Proxy ->
+ _Proxy when SocketType == ip_comm ->
TmpHdrs3 = handle_proxy(HttpOptions, TmpHdrs2),
- {TmpHdrs3, AbsUri}
+ {TmpHdrs3, AbsUri};
+ _ ->
+ {TmpHdrs2, Path ++ Query}
end,
FinalHeaders =
diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml
index 3143cdc825..f881fd76fd 100644
--- a/lib/kernel/doc/src/code.xml
+++ b/lib/kernel/doc/src/code.xml
@@ -899,6 +899,48 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
</desc>
</func>
<func>
+ <name name="module_status" arity="1"/>
+ <fsummary>Return the status of the module in relation to object file on disk.</fsummary>
+ <desc>
+ <p>Returns:</p>
+ <taglist>
+ <tag><c>not_loaded</c></tag>
+ <item><p>If <c><anno>Module</anno></c> is not currently loaded.</p></item>
+ <tag><c>loaded</c></tag>
+ <item><p>If <c><anno>Module</anno></c> is loaded and the object file
+ exists and contains the same code.</p></item>
+ <tag><c>removed</c></tag>
+ <item><p>If <c><anno>Module</anno></c> is loaded but no
+ corresponding object file can be found in the code path.</p></item>
+ <tag><c>modified</c></tag>
+ <item><p>If <c><anno>Module</anno></c> is loaded but the object file
+ contains code with a different MD5 checksum.</p></item>
+ </taglist>
+ <p>Preloaded modules are always reported as <c>loaded</c>, without
+ inspecting the contents on disk. Cover compiled modules will always
+ be reported as <c>modified</c> if an object file exists, or as
+ <c>removed</c> otherwise. Modules whose load path is an empty string
+ (which is the convention for auto-generated code) will only be
+ reported as <c>loaded</c> or <c>not_loaded</c>.</p>
+ <p>For modules that have native code loaded (see
+ <seealso marker="#is_module_native/1"><c>is_module_native/1</c></seealso>),
+ the MD5 sum of the native code in the object file is used for the
+ comparison, if it exists; the Beam code in the file is ignored.
+ Reversely, for modules that do not currently have native code
+ loaded, any native code in the file will be ignored.</p>
+ <p>See also <seealso marker="#modified_modules/0"><c>modified_modules/0</c></seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="modified_modules" arity="0"/>
+ <fsummary>Return a list of all modules modified on disk.</fsummary>
+ <desc>
+ <p>Returns the list of all currently loaded modules for which
+ <seealso marker="#module_status/1"><c>module_status/1</c></seealso>
+ returns <c>modified</c>. See also <seealso marker="#all_loaded/0"><c>all_loaded/0</c></seealso>.</p>
+ </desc>
+ </func>
+ <func>
<name name="is_module_native" arity="1"/>
<fsummary>Test if a module has native code.</fsummary>
<desc>
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 09497482cf..b674b3ca93 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -1477,8 +1477,8 @@ f.txt: {person, "kalle", 25}.
<tag><c>16#400</c></tag>
<item><p>set group id on execution</p></item>
</taglist>
- <p>On Unix platforms, the following bits
- can also be set:</p>
+ <p>On Unix platforms, other bits than those listed above
+ may be set.</p>
</item>
<tag><c>links = integer() >= 0</c></tag>
<item>
@@ -2042,8 +2042,8 @@ f.txt: {person, "kalle", 25}.
<tag><c>16#400</c></tag>
<item><p>Set group id on execution</p></item>
</taglist>
- <p>On Unix platforms, the following bits
- can also be set.</p>
+ <p>On Unix platforms, other bits than those listed above
+ may be set.</p>
</item>
<tag><c>uid = integer() >= 0</c></tag>
<item>
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index 08454b9832..e97db20062 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -231,7 +231,11 @@ do_recv(Sock, Bs) ->
<c><anno>Socket</anno></c>. The controlling process is the process
that receives messages from the socket. If called by any other
process than the current controlling process,
- <c>{error, not_owner}</c> is returned.</p>
+ <c>{error, not_owner}</c> is returned. If the process identified
+ by <c><anno>Pid</anno></c> is not an existing local pid,
+ <c>{error, badarg}</c> is returned. <c>{error, badarg}</c> may also
+ be returned in some cases when <c><anno>Socket</anno></c> is closed
+ during the execution of this function.</p>
<p>If the socket is set in active mode, this function
will transfer any messages in the mailbox of the caller
to the new controlling process.
diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml
index 3f88a0272d..f79566ef71 100644
--- a/lib/kernel/doc/src/gen_udp.xml
+++ b/lib/kernel/doc/src/gen_udp.xml
@@ -68,7 +68,11 @@
<c><anno>Socket</anno></c>. The controlling process is the process
that receives messages from the socket. If called by any other
process than the current controlling process,
- <c>{error, not_owner}</c> is returned.</p>
+ <c>{error, not_owner}</c> is returned. If the process identified
+ by <c><anno>Pid</anno></c> is not an existing local pid,
+ <c>{error, badarg}</c> is returned. <c>{error, badarg}</c> may also
+ be returned in some cases when <c><anno>Socket</anno></c> is closed
+ during the execution of this function.</p>
</desc>
</func>
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index d907cef7d3..4c4a5c39cb 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -987,11 +987,6 @@ setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp</code>
<p>Sets the line delimiting character for line-oriented protocols
(<c>line</c>). Defaults to <c>$\n</c>.</p>
</item>
- <tag><c>{priority, Priority}</c></tag>
- <item>
- <p>Sets the protocol-defined priority for all packets to be sent
- on this socket.</p>
- </item>
<tag><c>{raw, Protocol, OptionNum, ValueBin}</c></tag>
<item>
<p>See below.</p>
diff --git a/lib/kernel/doc/src/rpc.xml b/lib/kernel/doc/src/rpc.xml
index 5944e9321a..adec2d9520 100644
--- a/lib/kernel/doc/src/rpc.xml
+++ b/lib/kernel/doc/src/rpc.xml
@@ -88,6 +88,12 @@
to retrieve the value of evaluating <c>apply(<anno>Module</anno>,
<anno>Function</anno>, <anno>Args</anno>)</c> on node
<c><anno>Node</anno></c>.</p>
+ <note>
+ <p><seealso marker="#yield/1"><c>yield/1</c></seealso> and
+ <seealso marker="#nb_yield/1"><c>nb_yield/1,2</c></seealso>
+ must be called by the same process from which this function
+ was made otherwise they will never yield correctly.</p>
+ </note>
</desc>
</func>
@@ -299,6 +305,11 @@
the tuple <c>{value, <anno>Val</anno>}</c> when the computation is
finished, or <c>timeout</c> when <c><anno>Timeout</anno></c>
milliseconds has elapsed.</p>
+ <note>
+ <p>This function must be called by the same process from which
+ <seealso marker="#async_call/4"><c>async_call/4</c></seealso>
+ was made otherwise it will only return <c>timeout</c>.</p>
+ </note>
</desc>
</func>
@@ -407,6 +418,11 @@
If the answer is available, it is
returned immediately. Otherwise, the calling process is
suspended until the answer arrives from <c>Node</c>.</p>
+ <note>
+ <p>This function must be called by the same process from which
+ <seealso marker="#async_call/4"><c>async_call/4</c></seealso>
+ was made otherwise it will never return.</p>
+ </note>
</desc>
</func>
</funcs>
diff --git a/lib/kernel/include/dist_util.hrl b/lib/kernel/include/dist_util.hrl
index 320e916c04..e3d2fe0eb6 100644
--- a/lib/kernel/include/dist_util.hrl
+++ b/lib/kernel/include/dist_util.hrl
@@ -29,7 +29,7 @@
-endif.
-ifdef(dist_trace).
--define(trace(Fmt,Args), io:format("~p ~p:~s",[erlang:now(),node(),lists:flatten(io_lib:format(Fmt, Args))])).
+-define(trace(Fmt,Args), io:format("~p ~p:~s",[erlang:timestamp(),node(),lists:flatten(io_lib:format(Fmt, Args))])).
% Use the one below for config-file (early boot) connection tracing
%-define(trace(Fmt,Args), erlang:display([erlang:now(),node(),lists:flatten(io_lib:format(Fmt, Args))])).
-define(trace_factor,8).
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index 622b27080c..5a7ca493cc 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -70,7 +70,9 @@
where_is_file/2,
set_primary_archive/4,
clash/0,
- get_mode/0]).
+ module_status/1,
+ modified_modules/0,
+ get_mode/0]).
-deprecated({rehash,0,next_major_release}).
@@ -719,38 +721,14 @@ start_get_mode() ->
which(Module) when is_atom(Module) ->
case is_loaded(Module) of
false ->
- which2(Module);
+ which(Module, get_path());
{file, File} ->
File
end.
-which2(Module) ->
- Base = atom_to_list(Module),
- File = filename:basename(Base) ++ objfile_extension(),
- Path = get_path(),
- which(File, filename:dirname(Base), Path).
-
--spec which(file:filename(), file:filename(), [file:filename()]) ->
- 'non_existing' | file:filename().
-
-which(_, _, []) ->
- non_existing;
-which(File, Base, [Directory|Tail]) ->
- Path = if
- Base =:= "." -> Directory;
- true -> filename:join(Directory, Base)
- end,
- case erl_prim_loader:list_dir(Path) of
- {ok,Files} ->
- case lists:member(File,Files) of
- true ->
- filename:append(Path, File);
- false ->
- which(File, Base, Tail)
- end;
- _Error ->
- which(File, Base, Tail)
- end.
+which(Module, Path) when is_atom(Module) ->
+ File = atom_to_list(Module) ++ objfile_extension(),
+ where_is_file(Path, File).
%% Search the code path for a specific file. Try to locate
%% it in the code path cache if possible.
@@ -760,13 +738,33 @@ which(File, Base, [Directory|Tail]) ->
Absname :: file:filename().
where_is_file(File) when is_list(File) ->
Path = get_path(),
- which(File, ".", Path).
+ where_is_file(Path, File).
+
+%% To avoid unnecessary work when looking at many modules, this also
+%% accepts pairs of directories and pre-fetched contents in the path
+-spec where_is_file(Path :: [Dir|{Dir,Files}], Filename :: file:filename()) ->
+ 'non_existing' | file:filename() when
+ Dir :: file:filename(), Files :: [file:filename()].
--spec where_is_file(Path :: file:filename(), Filename :: file:filename()) ->
- file:filename() | 'non_existing'.
+where_is_file([], _) ->
+ non_existing;
+where_is_file([{Path, Files}|Tail], File) ->
+ where_is_file(Tail, File, Path, Files);
+where_is_file([Path|Tail], File) ->
+ case erl_prim_loader:list_dir(Path) of
+ {ok,Files} ->
+ where_is_file(Tail, File, Path, Files);
+ _Error ->
+ where_is_file(Tail, File)
+ end.
-where_is_file(Path, File) when is_list(Path), is_list(File) ->
- which(File, ".", Path).
+where_is_file(Tail, File, Path, Files) ->
+ case lists:member(File, Files) of
+ true ->
+ filename:append(Path, File);
+ false ->
+ where_is_file(Tail, File)
+ end.
-spec set_primary_archive(ArchiveFile :: file:filename(),
ArchiveBin :: binary(),
@@ -899,3 +897,97 @@ load_all_native_1([{Mod,BeamFilename}|T], ChunkTag) ->
load_all_native_1(T, ChunkTag);
load_all_native_1([], _) ->
ok.
+
+%% Returns the status of the module in relation to object file on disk.
+-spec module_status(Module :: module()) -> not_loaded | loaded | modified | removed.
+module_status(Module) ->
+ module_status(Module, code:get_path()).
+
+%% Note that we don't want to go via which/1, since it doesn't look at the
+%% disk contents at all if the module is already loaded.
+module_status(Module, PathFiles) ->
+ case code:is_loaded(Module) of
+ false -> not_loaded;
+ {file, preloaded} -> loaded;
+ {file, cover_compiled} ->
+ %% cover compilation loads directly to memory and does not
+ %% create a beam file, so report 'modified' if a file exists
+ case which(Module, PathFiles) of
+ non_existing -> removed;
+ _File -> modified
+ end;
+ {file, []} -> loaded; % no beam file - generated code
+ {file, OldFile} when is_list(OldFile) ->
+ %% we don't care whether or not the file is in the same location
+ %% as when last loaded, as long as it can be found in the path
+ case which(Module, PathFiles) of
+ non_existing -> removed;
+ Path ->
+ case module_changed_on_disk(Module, Path) of
+ true -> modified;
+ false -> loaded
+ end
+ end
+ end.
+
+%% Detects actual code changes only, e.g. to decide whether a module should
+%% be reloaded; does not care about file timestamps or compilation time
+module_changed_on_disk(Module, Path) ->
+ MD5 = erlang:get_module_info(Module, md5),
+ case erlang:system_info(hipe_architecture) of
+ undefined ->
+ %% straightforward, since native is not supported
+ MD5 =/= beam_file_md5(Path);
+ Architecture ->
+ case code:is_module_native(Module) of
+ true ->
+ %% MD5 is for native code, so we check only the native
+ %% code on disk, ignoring the beam code
+ MD5 =/= beam_file_native_md5(Path, Architecture);
+ _ ->
+ %% MD5 is for beam code, so check only the beam code on
+ %% disk, even if the file contains native code as well
+ MD5 =/= beam_file_md5(Path)
+ end
+ end.
+
+beam_file_md5(Path) ->
+ case beam_lib:md5(Path) of
+ {ok,{_Mod,MD5}} -> MD5;
+ _ -> undefined
+ end.
+
+beam_file_native_md5(Path, Architecture) ->
+ try
+ get_beam_chunk(Path, hipe_unified_loader:chunk_name(Architecture))
+ of
+ NativeCode when is_binary(NativeCode) ->
+ erlang:md5(NativeCode)
+ catch
+ _:_ -> undefined
+ end.
+
+get_beam_chunk(Path, Chunk) ->
+ {ok, {_, [{_, Bin}]}} = beam_lib:chunks(Path, [Chunk]),
+ Bin.
+
+%% Returns a list of all modules modified on disk.
+-spec modified_modules() -> [module()].
+modified_modules() ->
+ PathFiles = path_files(),
+ [M || {M, _} <- code:all_loaded(),
+ module_status(M, PathFiles) =:= modified].
+
+%% prefetch the directory contents of code path directories
+path_files() ->
+ path_files(code:get_path()).
+
+path_files([]) ->
+ [];
+path_files([Path|Tail]) ->
+ case erl_prim_loader:list_dir(Path) of
+ {ok, Files} ->
+ [{Path,Files} | path_files(Tail)];
+ _Error ->
+ path_files(Tail)
+ end.
diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl
index b133e6fed4..a6aa0edd15 100644
--- a/lib/kernel/src/gen_sctp.erl
+++ b/lib/kernel/src/gen_sctp.erl
@@ -439,7 +439,7 @@ error_string(X) ->
-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when
Socket :: sctp_socket(),
Pid :: pid(),
- Reason :: closed | not_owner | inet:posix().
+ Reason :: closed | not_owner | badarg | inet:posix().
controlling_process(S, Pid) when is_port(S), is_pid(Pid) ->
inet:udp_controlling_process(S, Pid);
diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl
index 1a21541b7c..ac61dbc792 100644
--- a/lib/kernel/src/gen_tcp.erl
+++ b/lib/kernel/src/gen_tcp.erl
@@ -320,7 +320,7 @@ unrecv(S, Data) when is_port(S) ->
-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when
Socket :: socket(),
Pid :: pid(),
- Reason :: closed | not_owner | inet:posix().
+ Reason :: closed | not_owner | badarg | inet:posix().
controlling_process(S, NewOwner) ->
case inet_db:lookup_socket(S) of
diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl
index 98d2f0bcfb..3121544719 100644
--- a/lib/kernel/src/gen_udp.erl
+++ b/lib/kernel/src/gen_udp.erl
@@ -195,7 +195,7 @@ connect(S, Address, Port) when is_port(S) ->
-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when
Socket :: socket(),
Pid :: pid(),
- Reason :: closed | not_owner | inet:posix().
+ Reason :: closed | not_owner | badarg | inet:posix().
controlling_process(S, NewOwner) ->
inet:udp_controlling_process(S, NewOwner).
diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl
index 0c73ead7c5..5e8bc2ba5d 100644
--- a/lib/kernel/src/global.erl
+++ b/lib/kernel/src/global.erl
@@ -58,14 +58,18 @@
%%% In certain places in the server, calling io:format hangs everything,
%%% so we'd better use erlang:display/1.
%%% my_tracer is used in testsuites
--define(trace(_), ok).
+%% uncomment this if tracing is wanted
+%%-define(DEBUG, true).
+-ifdef(DEBUG).
+-define(trace(T), erlang:display({format, node(), cs(), T})).
+ cs() ->
+ {_Big, Small, Tiny} = erlang:timestamp(),
+ (Small rem 100) * 100 + (Tiny div 10000).
%-define(trace(T), (catch my_tracer ! {node(), {line,?LINE}, T})).
-
-%-define(trace(T), erlang:display({format, node(), cs(), T})).
-%cs() ->
-% {_Big, Small, Tiny} = now(),
-% (Small rem 100) * 100 + (Tiny div 10000).
+-else.
+-define(trace(_), ok).
+-endif.
%% These are the protocol versions:
%% Vsn 1 is the original protocol.
diff --git a/lib/kernel/src/hipe_ext_format.hrl b/lib/kernel/src/hipe_ext_format.hrl
index 102cb49a2b..05c678fdec 100644
--- a/lib/kernel/src/hipe_ext_format.hrl
+++ b/lib/kernel/src/hipe_ext_format.hrl
@@ -1,3 +1,15 @@
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
%% hipe_x86_ext_format.hrl
%% Definitions for unified external object format
%% Currently: sparc, x86, amd64
diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl
index 04ec1479cb..f4c7c277ed 100644
--- a/lib/kernel/src/hipe_unified_loader.erl
+++ b/lib/kernel/src/hipe_unified_loader.erl
@@ -1,4 +1,15 @@
%% -*- erlang-indent-level: 2 -*-
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%% =======================================================================
%% Filename : hipe_unified_loader.erl
%% Module : hipe_unified_loader
diff --git a/lib/kernel/src/kernel.appup.src b/lib/kernel/src/kernel.appup.src
index 82cf73cbda..b505524471 100644
--- a/lib/kernel/src/kernel.appup.src
+++ b/lib/kernel/src/kernel.appup.src
@@ -18,9 +18,7 @@
%% %CopyrightEnd%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"5\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.*
+ [{<<"5\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-19.*
%% Down to - max one major revision back
- [{<<"5\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"4\\.[0-2](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.*
+ [{<<"5\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-19.*
}.
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index 0c679e7349..0a9f9316b0 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -26,15 +26,13 @@
%%-define(dist_debug, true).
-%-define(DBG,erlang:display([?MODULE,?LINE])).
-
-ifdef(dist_debug).
-define(debug(Term), erlang:display(Term)).
-else.
-define(debug(Term), ok).
-endif.
--ifdef(DEBUG).
+-ifdef(dist_debug).
-define(connect_failure(Node,Term),
io:format("Net Kernel 2: Failed connection to node ~p, reason ~p~n",
[Node,Term])).
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 29b3f7caaf..4914ce9e4c 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -38,6 +38,7 @@
on_load_purge/1, on_load_self_call/1, on_load_pending/1,
on_load_deleted/1,
big_boot_embedded/1,
+ module_status/1,
native_early_modules/1, get_mode/1,
normalized_paths/1]).
@@ -68,6 +69,7 @@ all() ->
on_load_binary, on_load_embedded, on_load_errors, on_load_update,
on_load_purge, on_load_self_call, on_load_pending,
on_load_deleted,
+ module_status,
big_boot_embedded, native_early_modules, get_mode, normalized_paths].
groups() ->
@@ -93,6 +95,11 @@ init_per_suite(Config) ->
end_per_suite(Config) ->
Config.
+-define(TESTMOD, test_dummy).
+-define(TESTMODSTR, "test_dummy").
+-define(TESTMODSRC, ?TESTMODSTR ".erl").
+-define(TESTMODOBJ, ?TESTMODSTR ".beam").
+
init_per_testcase(big_boot_embedded, Config) ->
case catch crypto:start() of
ok ->
@@ -104,6 +111,13 @@ init_per_testcase(_Func, Config) ->
P = code:get_path(),
[{code_path, P}|Config].
+end_per_testcase(module_status, Config) ->
+ code:purge(?TESTMOD),
+ code:delete(?TESTMOD),
+ code:purge(?TESTMOD),
+ file:delete(?TESTMODOBJ),
+ file:delete(?TESTMODSRC),
+ end_per_testcase(Config);
end_per_testcase(TC, Config) when TC == mult_lib_roots;
TC == big_boot_embedded ->
{ok, HostName} = inet:gethostname(),
@@ -1757,6 +1771,172 @@ do_normalized_paths([M|Ms]) ->
do_normalized_paths([]) ->
ok.
+%% Test that module_status/1 behaves as expected
+module_status(_Config) ->
+ %% basics
+ not_loaded = code:module_status(fubar), % nonexisting
+ {file, preloaded} = code:is_loaded(erlang),
+ loaded = code:module_status(erlang), % preloaded
+ loaded = code:module_status(?MODULE), % normal known loaded
+
+ non_existing = code:which(?TESTMOD), % verify dummy name not in path
+ code:purge(?TESTMOD), % ensure no previous version in memory
+ code:delete(?TESTMOD),
+ code:purge(?TESTMOD),
+
+ %% generated code is detected as such
+ {ok,?TESTMOD,Bin} = compile:forms(dummy_ast(), []),
+ {module,?TESTMOD} = code:load_binary(?TESTMOD,"",Bin), % no source file
+ ok = ?TESTMOD:f(),
+ "" = code:which(?TESTMOD), % verify empty string for source file
+ loaded = code:module_status(?TESTMOD),
+
+ %% deleting generated code
+ true = code:delete(?TESTMOD),
+ non_existing = code:which(?TESTMOD), % verify still not in path
+ not_loaded = code:module_status(?TESTMOD),
+
+ %% beam file exists but not loaded
+ make_source_file(<<"0">>),
+ compile_beam(0),
+ true = (non_existing =/= code:which(?TESTMOD)), % verify in path
+ not_loaded = code:module_status(?TESTMOD),
+
+ %% loading code from disk makes it loaded
+ load_code(),
+ loaded = code:module_status(?TESTMOD), % loaded
+
+ %% cover compiling a module
+ {ok,?TESTMOD} = cover:compile(?TESTMOD),
+ {file, cover_compiled} = code:is_loaded(?TESTMOD), % verify cover compiled
+ modified = code:module_status(?TESTMOD), % loaded cover code but file exists
+ remove_code(),
+ removed = code:module_status(?TESTMOD), % removed
+ compile_beam(0),
+ modified = code:module_status(?TESTMOD), % recreated
+ load_code(),
+ loaded = code:module_status(?TESTMOD), % loading removes cover status
+ code:purge(?TESTMOD),
+ true = code:delete(?TESTMOD),
+ not_loaded = code:module_status(?TESTMOD), % deleted
+
+ %% recompilation ignores timestamps, only md5 matters
+ load_code(),
+ compile_beam(1100),
+ loaded = code:module_status(?TESTMOD),
+
+ %% modifying module detects different md5
+ make_source_file(<<"1">>),
+ compile_beam(0),
+ modified = code:module_status(?TESTMOD),
+
+ %% loading the modified code from disk makes it loaded
+ load_code(),
+ loaded = code:module_status(?TESTMOD),
+
+ %% removing and recreating a module with same md5
+ remove_code(),
+ removed = code:module_status(?TESTMOD),
+ compile_beam(0),
+ loaded = code:module_status(?TESTMOD),
+
+ case erlang:system_info(hipe_architecture) of
+ undefined ->
+ %% no native support
+ ok;
+ _ ->
+ %% native chunk is ignored if beam code is already loaded
+ load_code(),
+ loaded = code:module_status(?TESTMOD),
+ false = has_native(?TESTMOD),
+ compile_native(0),
+ BeamMD5 = erlang:get_module_info(?TESTMOD, md5),
+ {ok,{?TESTMOD,BeamMD5}} = beam_lib:md5(?TESTMODOBJ), % beam md5 unchanged
+ loaded = code:module_status(?TESTMOD),
+
+ %% native code reported as loaded, though different md5 from beam
+ load_code(),
+ true = has_native(?TESTMOD),
+ NativeMD5 = erlang:get_module_info(?TESTMOD, md5),
+ true = (BeamMD5 =/= NativeMD5),
+ loaded = code:module_status(?TESTMOD),
+
+ %% recompilation ignores timestamps, only md5 matters
+ compile_native(1100), % later timestamp
+ loaded = code:module_status(?TESTMOD),
+
+ %% modifying native module detects different md5
+ make_source_file(<<"2">>),
+ compile_native(0),
+ modified = code:module_status(?TESTMOD),
+
+ %% loading the modified native code from disk makes it loaded
+ load_code(),
+ true = has_native(?TESTMOD),
+ NativeMD5_2 = erlang:get_module_info(?TESTMOD, md5),
+ true = (NativeMD5 =/= NativeMD5_2), % verify native md5 changed
+ {ok,{?TESTMOD,BeamMD5_2}} = beam_lib:md5(?TESTMODOBJ),
+ true = (BeamMD5_2 =/= NativeMD5_2), % verify md5 differs from beam
+ loaded = code:module_status(?TESTMOD),
+
+ %% removing and recreating a native module with same md5
+ remove_code(),
+ removed = code:module_status(?TESTMOD),
+ compile_native(0),
+ loaded = code:module_status(?TESTMOD),
+
+ %% purging/deleting native module
+ code:purge(?TESTMOD),
+ true = code:delete(?TESTMOD),
+ not_loaded = code:module_status(?TESTMOD)
+ end,
+ ok.
+
+compile_beam(Sleep) ->
+ compile(Sleep, []).
+
+compile_native(Sleep) ->
+ compile(Sleep, [native]).
+
+compile(Sleep, Opts) ->
+ timer:sleep(Sleep), % increment compilation timestamp
+ {ok,?TESTMOD} = compile:file(?TESTMODSRC, Opts).
+
+load_code() ->
+ code:purge(?TESTMOD),
+ {module,?TESTMOD} = code:load_file(?TESTMOD).
+
+remove_code() ->
+ ok = file:delete(?TESTMODOBJ).
+
+has_native(Module) ->
+ case erlang:get_module_info(Module, native_addresses) of
+ [] -> false;
+ [_|_] -> true
+ end.
+
+make_source_file(Body) ->
+ ok = file:write_file(?TESTMODSRC, dummy_source(Body)).
+
+dummy_source(Body) ->
+ [<<"-module(" ?TESTMODSTR ").\n"
+ "-export([f/0]).\n"
+ "f() -> ">>, Body, <<".\n">>].
+
+dummy_ast() ->
+ dummy_ast(?TESTMODSTR).
+
+dummy_ast(Mod) when is_atom(Mod) ->
+ dummy_ast(atom_to_list(Mod));
+dummy_ast(ModStr) ->
+ [scan_form("-module(" ++ ModStr ++ ")."),
+ scan_form("-export([f/0])."),
+ scan_form("f() -> ok.")].
+
+scan_form(String) ->
+ {ok,Ts,_} = erl_scan:string(String),
+ {ok,F} = erl_parse:parse_form(Ts),
+ F.
%%-----------------------------------------------------------------
%% error_logger handler.
diff --git a/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc
index 8f1a4366ee..ffda739dfa 100644
--- a/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap3.xmlsrc
@@ -348,7 +348,7 @@ skeppet %<input>erl -sname b -mnesia dir '"/ldisc/scratch/Mnesia.company"'</inpu
<p>If the startup procedure fails, the function
<seealso marker="mnesia#start/0">mnesia:start()</seealso>
returns the cryptic tuple
- <c>{error,{shutdown, {mnesia_sup,start,[normal,[]]}}}</c>.
+ <c>{error,{shutdown, {mnesia_sup,start_link,[normal,[]]}}}</c>.
To get more information about the start failure, use
command-line arguments <c>-boot start_sasl</c> as argument to
the <c>erl</c> script.</p>
diff --git a/lib/mnesia/src/Makefile b/lib/mnesia/src/Makefile
index 08a00e6aba..5206e469a5 100644
--- a/lib/mnesia/src/Makefile
+++ b/lib/mnesia/src/Makefile
@@ -43,6 +43,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/mnesia-$(VSN)
# ----------------------------------------------------
MODULES= \
mnesia \
+ mnesia_app \
mnesia_backend_type \
mnesia_backup \
mnesia_bup \
diff --git a/lib/mnesia/src/mnesia.app.src b/lib/mnesia/src/mnesia.app.src
index 006ad4bac1..af14826c90 100644
--- a/lib/mnesia/src/mnesia.app.src
+++ b/lib/mnesia/src/mnesia.app.src
@@ -3,6 +3,7 @@
{vsn, "%VSN%"},
{modules, [
mnesia,
+ mnesia_app,
mnesia_backend_type,
mnesia_backup,
mnesia_bup,
@@ -49,7 +50,5 @@
mnesia_tm
]},
{applications, [kernel, stdlib]},
- {mod, {mnesia_sup, []}},
+ {mod, {mnesia_app, []}},
{runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-7.0"]}]}.
-
-
diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl
index 5bf2fc2dc3..7b0e4976a0 100644
--- a/lib/mnesia/src/mnesia.erl
+++ b/lib/mnesia/src/mnesia.erl
@@ -138,6 +138,36 @@
-include("mnesia.hrl").
-import(mnesia_lib, [verbose/2]).
+-type create_option() ::
+ {'access_mode', 'read_write' | 'read_only'} |
+ {'attributes', [atom()]} |
+ {'disc_copies', [node()]} |
+ {'disc_only_copies', [node]} |
+ {'index', [index_attr()]} |
+ {'load_order', non_neg_integer()} |
+ {'majority', boolean()} |
+ {'ram_copies', [node()]} |
+ {'record_name', atom()} |
+ {'snmp', SnmpStruct::term()} |
+ {'storage_properties', [{Backend::module(), [BackendProp::_]}]} |
+ {'type', 'set' | 'ordered_set' | 'bag'} |
+ {'local_content', boolean()}.
+
+-type t_result(Res) :: {'atomic', Res} | {'aborted', Reason::term()}.
+-type activity() :: 'ets' | 'async_dirty' | 'sync_dirty' | 'transaction' | 'sync_transaction' |
+ {'transaction', Retries::non_neg_integer()} |
+ {'sync_transaction', Retries::non_neg_integer()}.
+-type table() :: atom().
+-type storage_type() :: 'ram_copies' | 'disc_copies' | 'disc_only_copies'.
+-type index_attr() :: atom() | non_neg_integer().
+-type write_locks() :: 'write' | 'sticky_write'.
+-type read_locks() :: 'read'.
+-type lock_kind() :: write_locks() | read_locks().
+-type select_continuation() :: term().
+-type snmp_struct() :: [{atom(), snmp_type() | tuple_of(snmp_type())}].
+-type snmp_type() :: 'fix_string' | 'string' | 'integer'.
+-type tuple_of(_) :: tuple().
+
-define(DEFAULT_ACCESS, ?MODULE).
%% Select
@@ -196,7 +226,7 @@ e_has_var(X, Pos) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Start and stop
-
+-spec start() -> 'ok' | {'error', term()}.
start() ->
start([]).
@@ -216,6 +246,7 @@ start_() ->
{error, R}
end.
+-spec start([{Option::atom(), Value::_}]) -> 'ok' | {'error', term()}.
start(ExtraEnv) when is_list(ExtraEnv) ->
case mnesia_lib:ensure_loaded(?APPLICATION) of
ok ->
@@ -238,6 +269,7 @@ patched_start([Head | _]) ->
patched_start([]) ->
start_().
+-spec stop() -> 'stopped' | {'error', term()}.
stop() ->
case application:stop(?APPLICATION) of
ok -> stopped;
@@ -245,6 +277,7 @@ stop() ->
Other -> Other
end.
+-spec change_config(Config::atom(), Value::_) -> ok | {error, term()}.
change_config(extra_db_nodes, Ns) when is_list(Ns) ->
mnesia_controller:connect_nodes(Ns);
change_config(dc_dump_limit, N) when is_number(N), N > 0 ->
@@ -273,6 +306,7 @@ kill() ->
ms() ->
[
mnesia,
+ mnesia_app,
mnesia_backup,
mnesia_bup,
mnesia_checkpoint,
@@ -311,12 +345,12 @@ ms() ->
%% Activity mgt
-spec abort(_) -> no_return().
-
abort(Reason = {aborted, _}) ->
exit(Reason);
abort(Reason) ->
exit({aborted, Reason}).
+-spec is_transaction() -> boolean().
is_transaction() ->
case get(mnesia_activity_state) of
{_, Tid, _Ts} when element(1,Tid) == tid ->
@@ -325,29 +359,52 @@ is_transaction() ->
false
end.
+-spec transaction(Fun) -> t_result(Res) when
+ Fun :: fun(() -> Res).
transaction(Fun) ->
transaction(get(mnesia_activity_state), Fun, [], infinity, ?DEFAULT_ACCESS, async).
+
+-spec transaction(Fun, Retries) -> t_result(Res) when
+ Fun :: fun(() -> Res),
+ Retries :: non_neg_integer() | 'infinity';
+ (Fun, [Arg::_]) -> t_result(Res) when
+ Fun :: fun((...) -> Res).
transaction(Fun, Retries) when is_integer(Retries), Retries >= 0 ->
transaction(get(mnesia_activity_state), Fun, [], Retries, ?DEFAULT_ACCESS, async);
transaction(Fun, Retries) when Retries == infinity ->
transaction(get(mnesia_activity_state), Fun, [], Retries, ?DEFAULT_ACCESS, async);
transaction(Fun, Args) ->
transaction(get(mnesia_activity_state), Fun, Args, infinity, ?DEFAULT_ACCESS, async).
+
+-spec transaction(Fun, [Arg::_], Retries) -> t_result(Res) when
+ Fun :: fun((...) -> Res),
+ Retries :: non_neg_integer() | 'infinity'.
transaction(Fun, Args, Retries) ->
transaction(get(mnesia_activity_state), Fun, Args, Retries, ?DEFAULT_ACCESS, async).
+-spec sync_transaction(Fun) -> t_result(Res) when
+ Fun :: fun(() -> Res).
sync_transaction(Fun) ->
transaction(get(mnesia_activity_state), Fun, [], infinity, ?DEFAULT_ACCESS, sync).
+
+-spec sync_transaction(Fun, Retries) -> t_result(Res) when
+ Fun :: fun(() -> Res),
+ Retries :: non_neg_integer() | 'infinity';
+ (Fun, [Arg::_]) -> t_result(Res) when
+ Fun :: fun((...) -> Res).
sync_transaction(Fun, Retries) when is_integer(Retries), Retries >= 0 ->
transaction(get(mnesia_activity_state), Fun, [], Retries, ?DEFAULT_ACCESS, sync);
sync_transaction(Fun, Retries) when Retries == infinity ->
transaction(get(mnesia_activity_state), Fun, [], Retries, ?DEFAULT_ACCESS, sync);
sync_transaction(Fun, Args) ->
transaction(get(mnesia_activity_state), Fun, Args, infinity, ?DEFAULT_ACCESS, sync).
+
+-spec sync_transaction(Fun, [Arg::_], Retries) -> t_result(Res) when
+ Fun :: fun((...) -> Res),
+ Retries :: non_neg_integer() | 'infinity'.
sync_transaction(Fun, Args, Retries) ->
transaction(get(mnesia_activity_state), Fun, Args, Retries, ?DEFAULT_ACCESS, sync).
-
transaction(State, Fun, Args, Retries, Mod, Kind)
when is_function(Fun), is_list(Args), Retries == infinity, is_atom(Mod) ->
mnesia_tm:transaction(State, Fun, Args, Retries, Mod, Kind);
@@ -363,28 +420,60 @@ non_transaction(State, Fun, Args, ActivityKind, Mod)
non_transaction(_State, Fun, Args, _ActivityKind, _Mod) ->
{aborted, {badarg, Fun, Args}}.
+-spec async_dirty(Fun) -> Res | no_return() when
+ Fun :: fun(() -> Res).
async_dirty(Fun) ->
async_dirty(Fun, []).
+
+-spec async_dirty(Fun, [Arg::_]) -> Res | no_return() when
+ Fun :: fun((...) -> Res).
async_dirty(Fun, Args) ->
non_transaction(get(mnesia_activity_state), Fun, Args, async_dirty, ?DEFAULT_ACCESS).
+-spec sync_dirty(Fun) -> Res | no_return() when
+ Fun :: fun(() -> Res).
sync_dirty(Fun) ->
sync_dirty(Fun, []).
+
+-spec sync_dirty(Fun, [Arg::_]) -> Res | no_return() when
+ Fun :: fun((...) -> Res).
sync_dirty(Fun, Args) ->
non_transaction(get(mnesia_activity_state), Fun, Args, sync_dirty, ?DEFAULT_ACCESS).
+-spec ets(Fun) -> Res | no_return() when
+ Fun :: fun(() -> Res).
ets(Fun) ->
ets(Fun, []).
+
+-spec ets(Fun, [Arg::_]) -> Res | no_return() when
+ Fun :: fun((...) -> Res).
ets(Fun, Args) ->
non_transaction(get(mnesia_activity_state), Fun, Args, ets, ?DEFAULT_ACCESS).
+-spec activity(Kind, Fun) -> t_result(Res) | Res when
+ Kind :: activity(),
+ Fun :: fun(() -> Res).
activity(Kind, Fun) ->
activity(Kind, Fun, []).
+
+-spec activity(Kind, Fun, [Arg::_]) -> t_result(Res) | Res when
+ Kind :: activity(),
+ Fun :: fun((...) -> Res);
+ (Kind, Fun, Mod) -> t_result(Res) | Res when
+ Kind :: activity(),
+ Fun :: fun(() -> Res),
+ Mod :: atom().
+
activity(Kind, Fun, Args) when is_list(Args) ->
activity(Kind, Fun, Args, mnesia_monitor:get_env(access_module));
activity(Kind, Fun, Mod) ->
activity(Kind, Fun, [], Mod).
+-spec activity(Kind, Fun, [Arg::_], Mod) -> t_result(Res) | Res when
+ Kind :: activity(),
+ Fun :: fun((...) -> Res),
+ Mod :: atom().
+
activity(Kind, Fun, Args, Mod) ->
State = get(mnesia_activity_state),
case Kind of
@@ -414,7 +503,11 @@ wrap_trans(State, Fun, Args, Retries, Mod, Kind) ->
%% Nodes may either be a list of nodes or one node as an atom
%% Mnesia on all Nodes must be connected to each other, but
%% it is not neccessary that they are up and running.
-
+-spec lock(LockItem, LockKind) -> list() | tuple() | no_return() when
+ LockItem :: {'record', table(), Key::term()} |
+ {'table', table()} |
+ {'global', Key::term(), MnesiaNodes::[node()]},
+ LockKind :: lock_kind() | 'load'.
lock(LockItem, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -425,6 +518,9 @@ lock(LockItem, LockKind) ->
abort(no_transaction)
end.
+-spec lock_table(Tab::table(), LockKind) -> [MnesiaNode] | no_return() when
+ MnesiaNode :: node(),
+ LockKind :: lock_kind() | load.
lock_table(Tab, LockKind) ->
lock({table, Tab}, LockKind).
@@ -446,11 +542,13 @@ lock(Tid, Ts, LockItem, LockKind) ->
end.
%% Grab a read lock on a whole table
+-spec read_lock_table(Tab::table()) -> ok.
read_lock_table(Tab) ->
lock({table, Tab}, read),
ok.
%% Grab a write lock on a whole table
+-spec write_lock_table(Tab::table()) -> ok.
write_lock_table(Tab) ->
lock({table, Tab}, write),
ok.
@@ -515,17 +613,19 @@ good_global_nodes(Nodes) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Access within an activity - updates
-
+-spec write(Record::tuple()) -> 'ok'.
write(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
write(Tab, Val, write);
write(Val) ->
abort({bad_type, Val}).
+-spec s_write(Record::tuple()) -> 'ok'.
s_write(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
write(Tab, Val, sticky_write).
+-spec write(Tab::table(), Record::tuple(), LockKind::write_locks()) -> 'ok'.
write(Tab, Val, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -572,16 +672,19 @@ write_to_store(Tab, Store, Oid, Val) ->
end,
ok.
+-spec delete({Tab::table(), Key::_}) -> 'ok'.
delete({Tab, Key}) ->
delete(Tab, Key, write);
delete(Oid) ->
abort({bad_type, Oid}).
+-spec s_delete({Tab::table(), Key::_}) -> 'ok'.
s_delete({Tab, Key}) ->
delete(Tab, Key, sticky_write);
s_delete(Oid) ->
abort({bad_type, Oid}).
+-spec delete(Tab::table(), Key::_, LockKind::write_locks()) -> 'ok'.
delete(Tab, Key, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -618,18 +721,21 @@ delete(Tid, Ts, Tab, Key, LockKind)
delete(_Tid, _Ts, Tab, _Key, _LockKind) ->
abort({bad_type, Tab}).
+-spec delete_object(Rec::tuple()) -> 'ok'.
delete_object(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
delete_object(Tab, Val, write);
delete_object(Val) ->
abort({bad_type, Val}).
+-spec s_delete_object(Rec::tuple()) -> 'ok'.
s_delete_object(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
delete_object(Tab, Val, sticky_write);
s_delete_object(Val) ->
abort({bad_type, Val}).
+-spec delete_object(Tab::table(), Rec::tuple(), LockKind::write_locks()) -> 'ok'.
delete_object(Tab, Val, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -689,19 +795,23 @@ do_delete_object(Tid, Ts, Tab, Val, LockKind) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Access within an activity - read
+-spec read(Tab::table(), Key::_) -> [tuple()].
read(Tab, Key) ->
read(Tab, Key, read).
+-spec read({Tab::table(), Key::_}) -> [tuple()].
read({Tab, Key}) ->
read(Tab, Key, read);
read(Oid) ->
abort({bad_type, Oid}).
+-spec wread({Tab::table(), Key::_}) -> [tuple()].
wread({Tab, Key}) ->
read(Tab, Key, write);
wread(Oid) ->
abort({bad_type, Oid}).
+-spec read(Tab::table(), Key::_, LockKind::lock_kind()) -> [tuple()].
read(Tab, Key, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -738,6 +848,7 @@ read(Tid, Ts, Tab, Key, LockKind)
read(_Tid, _Ts, Tab, _Key, _LockKind) ->
abort({bad_type, Tab}).
+-spec first(Tab::table()) -> Key::term().
first(Tab) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -765,6 +876,7 @@ first(Tid, Ts, Tab)
first(_Tid, _Ts,Tab) ->
abort({bad_type, Tab}).
+-spec last(Tab::table()) -> Key::term().
last(Tab) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -792,6 +904,7 @@ last(Tid, Ts, Tab)
last(_Tid, _Ts,Tab) ->
abort({bad_type, Tab}).
+-spec next(Tab::table(), Key::term()) -> NextKey::term().
next(Tab,Key) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS,Tid,Ts} ->
@@ -818,6 +931,7 @@ next(Tid,Ts,Tab,Key)
next(_Tid, _Ts,Tab,_) ->
abort({bad_type, Tab}).
+-spec prev(Tab::table(), Key::term()) -> PrevKey::term().
prev(Tab,Key) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS,Tid,Ts} ->
@@ -952,6 +1066,8 @@ ts_keys_1([], Acc) ->
%%%%%%%%%%%%%%%%%%%%%
%% Iterators
+-spec foldl(Fun, Acc0, Tab::table()) -> Acc when
+ Fun::fun((Record::tuple(), Acc0) -> Acc).
foldl(Fun, Acc, Tab) ->
foldl(Fun, Acc, Tab, read).
@@ -992,6 +1108,8 @@ do_foldl(A, O, Tab, Key, Fun, Acc, Type, Stored) -> %% Type is set or bag
{_, Tid, Ts} = get(mnesia_activity_state),
do_foldl(Tid, Ts, Tab, dirty_next(Tab, Key), Fun, NewAcc, Type, NewStored).
+-spec foldr(Fun, Acc0, Tab::table()) -> Acc when
+ Fun::fun((Record::tuple(), Acc0) -> Acc).
foldr(Fun, Acc, Tab) ->
foldr(Fun, Acc, Tab, read).
foldr(Fun, Acc, Tab, LockKind) when is_function(Fun) ->
@@ -1105,12 +1223,15 @@ add_written_to_bag([{_, _ , delete} | Tail], _Objs, _Ack) ->
add_written_to_bag([{_, Val, delete_object} | Tail], Objs, Ack) ->
add_written_to_bag(Tail, lists:delete(Val, Objs), lists:delete(Val, Ack)).
+-spec match_object(Pattern::tuple()) -> [Record::tuple()].
match_object(Pat) when is_tuple(Pat), tuple_size(Pat) > 2 ->
Tab = element(1, Pat),
match_object(Tab, Pat, read);
match_object(Pat) ->
abort({bad_type, Pat}).
+-spec match_object(Tab,Pattern,LockKind) -> [Record] when
+ Tab::table(),Pattern::tuple(),LockKind::lock_kind(),Record::tuple().
match_object(Tab, Pat, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -1270,9 +1391,13 @@ deloid(Oid, [H | T]) ->
%%%%%%%%%%%%%%%%%%
% select
-
+-spec select(Tab, Spec) -> [Match] when
+ Tab::table(), Spec::ets:match_spec(), Match::term().
select(Tab, Pat) ->
select(Tab, Pat, read).
+-spec select(Tab, Spec, LockKind) -> [Match] when
+ Tab::table(), Spec::ets:match_spec(),
+ Match::term(),LockKind::lock_kind().
select(Tab, Pat, LockKind)
when is_atom(Tab), Tab /= schema, is_list(Pat) ->
case get(mnesia_activity_state) of
@@ -1331,6 +1456,11 @@ select_lock(Tid,Ts,LockKind,Spec,Tab) ->
end.
%% Breakable Select
+-spec select(Tab, Spec, N, LockKind) -> {[Match], Cont} | '$end_of_table' when
+ Tab::table(), Spec::ets:match_spec(),
+ Match::term(), N::non_neg_integer(),
+ LockKind::lock_kind(),
+ Cont::select_continuation().
select(Tab, Pat, NObjects, LockKind)
when is_atom(Tab), Tab /= schema, is_list(Pat), is_integer(NObjects) ->
case get(mnesia_activity_state) of
@@ -1387,6 +1517,9 @@ fun_select(Tid, Ts, Tab, Spec, LockKind, TabPat, Init, NObjects, Node, Storage)
select_state(Init(Spec),Def)
end.
+-spec select(Cont) -> {[Match], Cont} | '$end_of_table' when
+ Match::term(),
+ Cont::select_continuation().
select(Cont) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -1436,6 +1569,7 @@ get_record_pattern([]) -> [];
get_record_pattern([{M,C,_B}|R]) ->
[{M,C,['$_']} | get_record_pattern(R)].
+-spec all_keys(Tab::table()) -> [Key::term()].
all_keys(Tab) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -1460,12 +1594,20 @@ all_keys(Tid, Ts, Tab, LockKind)
all_keys(_Tid, _Ts, Tab, _LockKind) ->
abort({bad_type, Tab}).
+-spec index_match_object(Pattern, Attr) -> [Record] when
+ Pattern::tuple(), Attr::index_attr(), Record::tuple().
index_match_object(Pat, Attr) when is_tuple(Pat), tuple_size(Pat) > 2 ->
Tab = element(1, Pat),
index_match_object(Tab, Pat, Attr, read);
index_match_object(Pat, _Attr) ->
abort({bad_type, Pat}).
+-spec index_match_object(Tab, Pattern, Attr, LockKind) -> [Record] when
+ Tab::table(),
+ Pattern::tuple(),
+ Attr::index_attr(),
+ LockKind::lock_kind(),
+ Record::tuple().
index_match_object(Tab, Pat, Attr, LockKind) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -1502,6 +1644,11 @@ index_match_object(Tid, Ts, Tab, Pat, Attr, LockKind)
index_match_object(_Tid, _Ts, Tab, Pat, _Attr, _LockKind) ->
abort({bad_type, Tab, Pat}).
+-spec index_read(Tab, Key, Attr) -> [Record] when
+ Tab::table(),
+ Key::term(),
+ Attr::index_attr(),
+ Record::tuple().
index_read(Tab, Key, Attr) ->
case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
@@ -1541,13 +1688,14 @@ index_read(_Tid, _Ts, Tab, _Key, _Attr, _LockKind) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Dirty access regardless of activities - updates
-
+-spec dirty_write(Record::tuple()) -> 'ok'.
dirty_write(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
dirty_write(Tab, Val);
dirty_write(Val) ->
abort({bad_type, Val}).
+-spec dirty_write(Tab::table(), Record::tuple()) -> 'ok'.
dirty_write(Tab, Val) ->
do_dirty_write(async_dirty, Tab, Val).
@@ -1559,11 +1707,13 @@ do_dirty_write(SyncMode, Tab, Val)
do_dirty_write(_SyncMode, Tab, Val) ->
abort({bad_type, Tab, Val}).
+-spec dirty_delete({Tab::table(), Key::_}) -> 'ok'.
dirty_delete({Tab, Key}) ->
dirty_delete(Tab, Key);
dirty_delete(Oid) ->
abort({bad_type, Oid}).
+-spec dirty_delete(Tab::table(), Key::_) -> 'ok'.
dirty_delete(Tab, Key) ->
do_dirty_delete(async_dirty, Tab, Key).
@@ -1573,12 +1723,14 @@ do_dirty_delete(SyncMode, Tab, Key) when is_atom(Tab), Tab /= schema ->
do_dirty_delete(_SyncMode, Tab, _Key) ->
abort({bad_type, Tab}).
+-spec dirty_delete_object(Record::tuple()) -> 'ok'.
dirty_delete_object(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
Tab = element(1, Val),
dirty_delete_object(Tab, Val);
dirty_delete_object(Val) ->
abort({bad_type, Val}).
+-spec dirty_delete_object(Tab::table(), Record::tuple()) -> 'ok'.
dirty_delete_object(Tab, Val) ->
do_dirty_delete_object(async_dirty, Tab, Val).
@@ -1596,12 +1748,15 @@ do_dirty_delete_object(_SyncMode, Tab, Val) ->
abort({bad_type, Tab, Val}).
%% A Counter is an Oid being {CounterTab, CounterName}
-
+-spec dirty_update_counter({Tab::table(), Key::_}, Incr::integer()) ->
+ NewVal::integer().
dirty_update_counter({Tab, Key}, Incr) ->
dirty_update_counter(Tab, Key, Incr);
dirty_update_counter(Counter, _Incr) ->
abort({bad_type, Counter}).
+-spec dirty_update_counter(Tab::table(), Key::_, Incr::integer()) ->
+ NewVal::integer().
dirty_update_counter(Tab, Key, Incr) ->
do_dirty_update_counter(async_dirty, Tab, Key, Incr).
@@ -1620,23 +1775,28 @@ do_dirty_update_counter(_SyncMode, Tab, _Key, Incr) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Dirty access regardless of activities - read
+-spec dirty_read({Tab::table(), Key::_}) -> [tuple()].
dirty_read({Tab, Key}) ->
dirty_read(Tab, Key);
dirty_read(Oid) ->
abort({bad_type, Oid}).
+-spec dirty_read(Tab::table(), Key::_) -> [tuple()].
dirty_read(Tab, Key)
when is_atom(Tab), Tab /= schema ->
dirty_rpc(Tab, mnesia_lib, db_get, [Tab, Key]);
dirty_read(Tab, _Key) ->
abort({bad_type, Tab}).
+-spec dirty_match_object(Pattern::tuple()) -> [Record::tuple()].
dirty_match_object(Pat) when is_tuple(Pat), tuple_size(Pat) > 2 ->
Tab = element(1, Pat),
dirty_match_object(Tab, Pat);
dirty_match_object(Pat) ->
abort({bad_type, Pat}).
+-spec dirty_match_object(Tab,Pattern) -> [Record] when
+ Tab::table(), Pattern::tuple(), Record::tuple().
dirty_match_object(Tab, Pat)
when is_atom(Tab), Tab /= schema, is_tuple(Pat), tuple_size(Pat) > 2 ->
dirty_rpc(Tab, ?MODULE, remote_dirty_match_object, [Tab, Pat]);
@@ -1666,6 +1826,8 @@ remote_dirty_match_object(Tab, Pat, []) ->
remote_dirty_match_object(Tab, Pat, _PosList) ->
abort({bad_type, Tab, Pat}).
+-spec dirty_select(Tab, Spec) -> [Match] when
+ Tab::table(), Spec::ets:match_spec(), Match::term().
dirty_select(Tab, Spec) when is_atom(Tab), Tab /= schema, is_list(Spec) ->
dirty_rpc(Tab, ?MODULE, remote_dirty_select, [Tab, Spec]);
dirty_select(Tab, Spec) ->
@@ -1714,6 +1876,7 @@ dirty_sel_cont(#mnesia_select{cont='$end_of_table'}) -> '$end_of_table';
dirty_sel_cont(#mnesia_select{node=Node,tab=Tab,storage=Type,cont=Cont,orig=Ms}) ->
do_dirty_rpc(Tab,Node,mnesia_lib,db_select_cont,[Type,Cont,Ms]).
+-spec dirty_all_keys(Tab::table()) -> [Key::term()].
dirty_all_keys(Tab) when is_atom(Tab), Tab /= schema ->
case ?catch_val({Tab, wild_pattern}) of
{'EXIT', _} ->
@@ -1729,12 +1892,19 @@ dirty_all_keys(Tab) when is_atom(Tab), Tab /= schema ->
dirty_all_keys(Tab) ->
abort({bad_type, Tab}).
+-spec dirty_index_match_object(Pattern, Attr) -> [Record] when
+ Pattern::tuple(), Attr::index_attr(), Record::tuple().
dirty_index_match_object(Pat, Attr) when is_tuple(Pat), tuple_size(Pat) > 2 ->
Tab = element(1, Pat),
dirty_index_match_object(Tab, Pat, Attr);
dirty_index_match_object(Pat, _Attr) ->
abort({bad_type, Pat}).
+-spec dirty_index_match_object(Tab, Pattern, Attr) -> [Record] when
+ Tab::table(),
+ Pattern::tuple(),
+ Attr::index_attr(),
+ Record::tuple().
dirty_index_match_object(Tab, Pat, Attr)
when is_atom(Tab), Tab /= schema, is_tuple(Pat), tuple_size(Pat) > 2 ->
case mnesia_schema:attr_tab_to_pos(Tab, Attr) of
@@ -1758,6 +1928,11 @@ dirty_index_match_object(Tab, Pat, Attr)
dirty_index_match_object(Tab, Pat, _Attr) ->
abort({bad_type, Tab, Pat}).
+-spec dirty_index_read(Tab, Key, Attr) -> [Record] when
+ Tab::table(),
+ Key::term(),
+ Attr::index_attr(),
+ Record::tuple().
dirty_index_read(Tab, Key, Attr) when is_atom(Tab), Tab /= schema ->
Pos = mnesia_schema:attr_tab_to_pos(Tab, Attr),
case has_var(Key) of
@@ -1769,26 +1944,31 @@ dirty_index_read(Tab, Key, Attr) when is_atom(Tab), Tab /= schema ->
dirty_index_read(Tab, _Key, _Attr) ->
abort({bad_type, Tab}).
+%% do not use only for backwards compatibility
dirty_slot(Tab, Slot) when is_atom(Tab), Tab /= schema, is_integer(Slot) ->
dirty_rpc(Tab, mnesia_lib, db_slot, [Tab, Slot]);
dirty_slot(Tab, Slot) ->
abort({bad_type, Tab, Slot}).
+-spec dirty_first(Tab::table()) -> Key::term().
dirty_first(Tab) when is_atom(Tab), Tab /= schema ->
dirty_rpc(Tab, mnesia_lib, db_first, [Tab]);
dirty_first(Tab) ->
abort({bad_type, Tab}).
+-spec dirty_last(Tab::table()) -> Key::term().
dirty_last(Tab) when is_atom(Tab), Tab /= schema ->
dirty_rpc(Tab, mnesia_lib, db_last, [Tab]);
dirty_last(Tab) ->
abort({bad_type, Tab}).
+-spec dirty_next(Tab::table(), Key::_) -> NextKey::term().
dirty_next(Tab, Key) when is_atom(Tab), Tab /= schema ->
dirty_rpc(Tab, mnesia_lib, db_next_key, [Tab, Key]);
dirty_next(Tab, _Key) ->
abort({bad_type, Tab}).
+-spec dirty_prev(Tab::table(), Key::_) -> PrevKey::term().
dirty_prev(Tab, Key) when is_atom(Tab), Tab /= schema ->
dirty_rpc(Tab, mnesia_lib, db_prev_key, [Tab, Key]);
dirty_prev(Tab, _Key) ->
@@ -1839,7 +2019,7 @@ do_dirty_rpc(Tab, Node, M, F, Args) ->
%% Info
%% Info about one table
--spec table_info(atom(), any()) -> any().
+-spec table_info(Tab::table(), Item::term()) -> Info::term().
table_info(Tab, Item) ->
case get(mnesia_activity_state) of
undefined ->
@@ -1927,16 +2107,20 @@ bad_info_reply(_Tab, memory) -> 0;
bad_info_reply(Tab, Item) -> abort({no_exists, Tab, Item}).
%% Raw info about all tables
+-spec schema() -> ok.
schema() ->
mnesia_schema:info().
%% Raw info about one tables
+-spec schema(Tab::table()) -> ok.
schema(Tab) ->
mnesia_schema:info(Tab).
+-spec error_description(Error::term()) -> string().
error_description(Err) ->
mnesia_lib:error_desc(Err).
+-spec info() -> ok.
info() ->
case mnesia_lib:is_running() of
yes ->
@@ -2062,6 +2246,7 @@ display_tab_info() ->
Rdisp = fun({Rpat, Rtabs}) -> io:format("~p = ~p~n", [Rpat, Rtabs]) end,
lists:foreach(Rdisp, lists:sort(Repl)).
+-spec get_backend_types() -> [BackendType::term()].
get_backend_types() ->
case ?catch_val({schema, user_property, mnesia_backend_types}) of
{'EXIT', _} ->
@@ -2070,6 +2255,7 @@ get_backend_types() ->
lists:sort(Ts)
end.
+-spec get_index_plugins() -> [IndexPlugins::term()].
get_index_plugins() ->
case ?catch_val({schema, user_property, mnesia_index_plugins}) of
{'EXIT', _} ->
@@ -2118,6 +2304,7 @@ storage_count(T, {U, R, D, DO, Ext}) ->
{ext, A, _} -> {U, R, D, DO, orddict:append(A, T, Ext)}
end.
+-spec system_info(Iterm::term()) -> Info::term().
system_info(Item) ->
try system_info2(Item)
catch _:Error -> abort(Error)
@@ -2367,83 +2554,134 @@ load_mnesia_or_abort() ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Database mgt
+-spec create_schema(Ns::[node()]) -> 'ok' | {'error', Reason::term()}.
create_schema(Ns) ->
create_schema(Ns, []).
+-spec create_schema(Ns::[node()], [Prop]) -> 'ok' | {'error', Reason::term()} when
+ Prop :: BackendType | IndexPlugin,
+ BackendType :: {backend_types, [{Name::atom(), Module::module()}]},
+ IndexPlugin :: {index_plugins, [{{Name::atom()}, Module::module(), Function::atom()}]}.
create_schema(Ns, Properties) ->
mnesia_bup:create_schema(Ns, Properties).
+-spec delete_schema(Ns::[node()]) -> 'ok' | {'error', Reason::term()}.
delete_schema(Ns) ->
mnesia_schema:delete_schema(Ns).
+-spec add_backend_type(Name::atom(), Module::module()) -> t_result('ok').
add_backend_type(Alias, Module) ->
mnesia_schema:add_backend_type(Alias, Module).
+-spec backup(Dest::term()) -> 'ok' | {'error', Reason::term()}.
backup(Opaque) ->
mnesia_log:backup(Opaque).
+-spec backup(Dest::term(), Mod::module()) ->
+ 'ok' | {'error', Reason::term()}.
backup(Opaque, Mod) ->
mnesia_log:backup(Opaque, Mod).
+-spec traverse_backup(Src::term(), Dest::term(), Fun, Acc) ->
+ {'ok', Acc} | {'error', Reason::term()} when
+ Fun :: fun((Items, Acc) -> {Items,Acc}).
traverse_backup(S, T, Fun, Acc) ->
mnesia_bup:traverse_backup(S, T, Fun, Acc).
+-spec traverse_backup(Src::term(), SrcMod::module(),
+ Dest::term(), DestMod::module(),
+ Fun, Acc) ->
+ {'ok', Acc} | {'error', Reason::term()} when
+ Fun :: fun((Items, Acc) -> {Items,Acc}).
traverse_backup(S, SM, T, TM, F, A) ->
mnesia_bup:traverse_backup(S, SM, T, TM, F, A).
+-spec install_fallback(Src::term()) -> 'ok' | {'error', Reason::term()}.
install_fallback(Opaque) ->
mnesia_bup:install_fallback(Opaque).
+-spec install_fallback(Src::term(), Mod::module()|[Opt]) ->
+ 'ok' | {'error', Reason::term()} when
+ Opt :: Module | Scope | Dir,
+ Module :: {'module', Mod::module()},
+ Scope :: {'scope', 'global' | 'local'},
+ Dir :: {'mnesia_dir', Dir::string()}.
install_fallback(Opaque, Mod) ->
mnesia_bup:install_fallback(Opaque, Mod).
+-spec uninstall_fallback() -> 'ok' | {'error', Reason::term()}.
uninstall_fallback() ->
mnesia_bup:uninstall_fallback().
+-spec uninstall_fallback(Args) -> 'ok' | {'error', Reason::term()} when
+ Args :: [{'mnesia_dir', Dir::string()}].
uninstall_fallback(Args) ->
mnesia_bup:uninstall_fallback(Args).
+-spec activate_checkpoint([Arg]) -> {'ok', Name, [node()]} | {'error', Reason::term()} when
+ Arg :: {'name', Name} | {'max', [table()]} | {'min', [table()]} |
+ {'allow_remote', boolean()} | {'ram_overrides_dump', boolean()}.
activate_checkpoint(Args) ->
mnesia_checkpoint:activate(Args).
+-spec deactivate_checkpoint(Name::_) -> 'ok' | {'error', Reason::term()}.
deactivate_checkpoint(Name) ->
mnesia_checkpoint:deactivate(Name).
+-spec backup_checkpoint(Name::_, Dest::_) -> 'ok' | {'error', Reason::term()}.
backup_checkpoint(Name, Opaque) ->
mnesia_log:backup_checkpoint(Name, Opaque).
+-spec backup_checkpoint(Name::_, Dest::_, Mod::module()) ->
+ 'ok' | {'error', Reason::term()}.
backup_checkpoint(Name, Opaque, Mod) ->
mnesia_log:backup_checkpoint(Name, Opaque, Mod).
+-spec restore(Src::_, [Arg]) -> t_result([table()]) when
+ Op :: 'skip_tables' | 'clear_tables' | 'keep_tables' | 'restore_tables',
+ Arg :: {'module', module()} | {Op, [table()]} | {'default_op', Op}.
restore(Opaque, Args) ->
mnesia_schema:restore(Opaque, Args).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Table mgt
-
+-spec create_table([Arg]) -> t_result('ok') when
+ Arg :: {'name', table()} | create_option().
create_table(Arg) ->
mnesia_schema:create_table(Arg).
+
+-spec create_table(Name::table(), [create_option()]) -> t_result('ok').
create_table(Name, Arg) when is_list(Arg) ->
mnesia_schema:create_table([{name, Name}| Arg]);
create_table(Name, Arg) ->
{aborted, badarg, Name, Arg}.
+-spec delete_table(Tab::table()) -> t_result('ok').
delete_table(Tab) ->
mnesia_schema:delete_table(Tab).
+-spec add_table_copy(Tab::table(), N::node(), ST::storage_type()) -> t_result(ok).
add_table_copy(Tab, N, S) ->
mnesia_schema:add_table_copy(Tab, N, S).
+
+-spec del_table_copy(Tab::table(), N::node()) -> t_result(ok).
del_table_copy(Tab, N) ->
mnesia_schema:del_table_copy(Tab, N).
+-spec move_table_copy(Tab::table(), From::node(), To::node()) -> t_result(ok).
move_table_copy(Tab, From, To) ->
mnesia_schema:move_table(Tab, From, To).
+-spec add_table_index(Tab::table(), I::index_attr()) -> t_result(ok).
add_table_index(Tab, Ix) ->
mnesia_schema:add_table_index(Tab, Ix).
+-spec del_table_index(Tab::table(), I::index_attr()) -> t_result(ok).
del_table_index(Tab, Ix) ->
mnesia_schema:del_table_index(Tab, Ix).
+-spec transform_table(Tab::table(), Fun, [Attr]) -> t_result(ok) when
+ Attr :: atom(),
+ Fun:: fun((Record::tuple()) -> Transformed::tuple()).
transform_table(Tab, Fun, NewA) ->
try val({Tab, record_name}) of
OldRN -> mnesia_schema:transform_table(Tab, Fun, NewA, OldRN)
@@ -2451,12 +2689,18 @@ transform_table(Tab, Fun, NewA) ->
mnesia:abort(Reason)
end.
+-spec transform_table(Tab::table(), Fun, [Attr], RecName) -> t_result(ok) when
+ RecName :: atom(),
+ Attr :: atom(),
+ Fun:: fun((Record::tuple()) -> Transformed::tuple()).
transform_table(Tab, Fun, NewA, NewRN) ->
mnesia_schema:transform_table(Tab, Fun, NewA, NewRN).
+-spec change_table_copy_type(Tab::table(), Node::node(), To::storage_type()) -> t_result(ok).
change_table_copy_type(T, N, S) ->
mnesia_schema:change_table_copy_type(T, N, S).
+-spec clear_table(Tab::table()) -> t_result(ok).
clear_table(Tab) ->
case get(mnesia_activity_state) of
State = {Mod, Tid, _Ts} when element(1, Tid) =/= tid ->
@@ -2486,19 +2730,22 @@ clear_table(Tid, Ts, Tab, Obj) when element(1, Tid) =:= tid ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Table mgt - user properties
-
+-spec read_table_property(Tab::table(), PropKey::term()) -> Res::tuple().
read_table_property(Tab, PropKey) ->
val({Tab, user_property, PropKey}).
+-spec write_table_property(Tab::table(), Prop::tuple()) -> t_result(ok).
write_table_property(Tab, Prop) ->
mnesia_schema:write_table_property(Tab, Prop).
+-spec delete_table_property(Tab::table(), PropKey::term()) -> t_result(ok).
delete_table_property(Tab, PropKey) ->
mnesia_schema:delete_table_property(Tab, PropKey).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Table mgt - user properties
+-spec change_table_frag(Tab::table(), FP::term()) -> t_result(ok).
change_table_frag(Tab, FragProp) ->
mnesia_schema:change_table_frag(Tab, FragProp).
@@ -2506,28 +2753,38 @@ change_table_frag(Tab, FragProp) ->
%% Table mgt - table load
%% Dump a ram table to disc
+-spec dump_tables([Tab::table()]) -> t_result(ok).
dump_tables(Tabs) ->
mnesia_schema:dump_tables(Tabs).
%% allow the user to wait for some tables to be loaded
+-spec wait_for_tables([Tab::table()], TMO::timeout()) ->
+ 'ok' | {'timeout', [table()]} | {'error', Reason::term()}.
wait_for_tables(Tabs, Timeout) ->
mnesia_controller:wait_for_tables(Tabs, Timeout).
+-spec force_load_table(Tab::table()) -> 'yes' | {'error', Reason::term()}.
force_load_table(Tab) ->
case mnesia_controller:force_load_table(Tab) of
ok -> yes; % Backwards compatibility
Other -> Other
end.
+-spec change_table_access_mode(Tab::table(), Mode) -> t_result(ok) when
+ Mode :: 'read_only'|'read_write'.
change_table_access_mode(T, Access) ->
mnesia_schema:change_table_access_mode(T, Access).
+-spec change_table_load_order(Tab::table(), Order) -> t_result(ok) when
+ Order :: non_neg_integer().
change_table_load_order(T, O) ->
mnesia_schema:change_table_load_order(T, O).
+-spec change_table_majority(Tab::table(), M::boolean()) -> t_result(ok).
change_table_majority(T, M) ->
mnesia_schema:change_table_majority(T, M).
+-spec set_master_nodes(Ns::[node()]) -> 'ok' | {'error', Reason::term()}.
set_master_nodes(Nodes) when is_list(Nodes) ->
UseDir = system_info(use_dir),
IsRunning = system_info(is_running),
@@ -2566,6 +2823,8 @@ log_valid_master_nodes(Cstructs, Nodes, UseDir, IsRunning) ->
Args = lists:map(Fun, Cstructs),
mnesia_recover:log_master_nodes(Args, UseDir, IsRunning).
+-spec set_master_nodes(Tab::table(), Ns::[node()]) ->
+ 'ok' | {'error', Reason::term()}.
set_master_nodes(Tab, Nodes) when is_list(Nodes) ->
UseDir = system_info(use_dir),
IsRunning = system_info(is_running),
@@ -2616,31 +2875,39 @@ set_master_nodes(Tab, Nodes) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Misc admin
-
+-spec dump_log() -> 'dumped'.
dump_log() ->
mnesia_controller:sync_dump_log(user).
+-spec sync_log() -> 'ok' | {'error', Reason::term()}.
sync_log() ->
mnesia_monitor:sync_log(latest_log).
+-spec subscribe(What) -> {'ok', node()} | {'error', Reason::term()} when
+ What :: 'system' | 'activity' | {'table', table(), 'simple' | 'detailed'}.
subscribe(What) ->
mnesia_subscr:subscribe(self(), What).
+-spec unsubscribe(What) -> {'ok', node()} | {'error', Reason::term()} when
+ What :: 'system' | 'activity' | {'table', table(), 'simple' | 'detailed'}.
unsubscribe(What) ->
mnesia_subscr:unsubscribe(self(), What).
+-spec report_event(Event::_) -> 'ok'.
report_event(Event) ->
mnesia_lib:report_system_event({mnesia_user, Event}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Snmp
-
+-spec snmp_open_table(Tab::table(), Snmp::snmp_struct()) -> ok.
snmp_open_table(Tab, Us) ->
mnesia_schema:add_snmp(Tab, Us).
+-spec snmp_close_table(Tab::table()) -> ok.
snmp_close_table(Tab) ->
mnesia_schema:del_snmp(Tab).
+-spec snmp_get_row(Tab::table(), [integer()]) -> {'ok', Row::tuple()} | 'undefined'.
snmp_get_row(Tab, RowIndex) when is_atom(Tab), Tab /= schema, is_list(RowIndex) ->
case get(mnesia_activity_state) of
{Mod, Tid, Ts=#tidstore{store=Store}} when element(1, Tid) =:= tid ->
@@ -2676,7 +2943,7 @@ snmp_get_row(Tab, _RowIndex) ->
abort({bad_type, Tab}).
%%%%%%%%%%%%%
-
+-spec snmp_get_next_index(Tab::table(), [integer()]) -> {'ok', [integer()]} | 'endOfTable'.
snmp_get_next_index(Tab, RowIndex) when is_atom(Tab), Tab /= schema, is_list(RowIndex) ->
{Next,OrigKey} = dirty_rpc(Tab, mnesia_snmp_hook, get_next_index, [Tab, RowIndex]),
case get(mnesia_activity_state) of
@@ -2718,7 +2985,7 @@ get_ordered_snmp_key(_, []) ->
endOfTable.
%%%%%%%%%%
-
+-spec snmp_get_mnesia_key(Tab::table(), [integer()]) -> {'ok', Key::term()} | 'undefined'.
snmp_get_mnesia_key(Tab, RowIndex) when is_atom(Tab), Tab /= schema, is_list(RowIndex) ->
case get(mnesia_activity_state) of
{_Mod, Tid, Ts} when element(1, Tid) =:= tid ->
@@ -2782,17 +3049,27 @@ snmp_filter_key(undefined, RowIndex, Tab, Store) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Textfile access
-
+-spec load_textfile(File::file:filename()) -> t_result(ok) | {'error', term()}.
load_textfile(F) ->
mnesia_text:load_textfile(F).
+
+-spec dump_to_textfile(File :: file:filename()) -> 'ok' | 'error' | {'error', term()}.
dump_to_textfile(F) ->
mnesia_text:dump_to_textfile(F).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% QLC Handles
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec table(Tab::table()) -> qlc:query_handle().
table(Tab) ->
table(Tab, []).
+
+-spec table(Tab::table(), Options) -> qlc:query_handle() when
+ Options :: Option | [Option],
+ Option :: MnesiaOpt | QlcOption,
+ MnesiaOpt :: {'traverse', SelectOp} | {lock, lock_kind()} | {n_objects, non_neg_integer()},
+ SelectOp :: 'select' | {'select', ets:match_spec()},
+ QlcOption :: {'key_equality', '==' | '=:='}.
table(Tab,Opts) ->
{[Trav,Lock,NObjects],QlcOptions0} =
qlc_opts(Opts,[{traverse,select},{lock,read},{n_objects,100}]),
diff --git a/lib/mnesia/src/mnesia_app.erl b/lib/mnesia/src/mnesia_app.erl
new file mode 100644
index 0000000000..4d89011db2
--- /dev/null
+++ b/lib/mnesia/src/mnesia_app.erl
@@ -0,0 +1,41 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(mnesia_app).
+
+-behaviour(application).
+
+-export([start/2, stop/1]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% application callback functions
+
+start(normal, Args) ->
+ case mnesia_sup:start_link(Args) of
+ {ok, Pid} ->
+ {ok, Pid, {normal, Args}};
+ Error ->
+ Error
+ end;
+start(_, _) ->
+ {error, badarg}.
+
+stop(_StartArgs) ->
+ ok.
diff --git a/lib/mnesia/src/mnesia_lib.erl b/lib/mnesia/src/mnesia_lib.erl
index 10e232c800..1fdc656600 100644
--- a/lib/mnesia/src/mnesia_lib.erl
+++ b/lib/mnesia/src/mnesia_lib.erl
@@ -1192,25 +1192,15 @@ db_select(Storage, Tab, Pat) ->
end.
db_select_init({ext, Alias, Mod}, Tab, Pat, Limit) ->
- case Mod:select(Alias, Tab, Pat, Limit) of
- {Matches, Continuation} when is_list(Matches) ->
- {Matches, {Alias, Continuation}};
- R ->
- R
- end;
+ Mod:select(Alias, Tab, Pat, Limit);
db_select_init(disc_only_copies, Tab, Pat, Limit) ->
dets:select(Tab, Pat, Limit);
db_select_init(_, Tab, Pat, Limit) ->
ets:select(Tab, Pat, Limit).
-db_select_cont({ext, Alias, Mod}, Cont0, Ms) ->
+db_select_cont({ext, _Alias, Mod}, Cont0, Ms) ->
Cont = Mod:repair_continuation(Cont0, Ms),
- case Mod:select(Cont) of
- {Matches, Continuation} when is_list(Matches) ->
- {Matches, {Alias, Continuation}};
- R ->
- R
- end;
+ Mod:select(Cont);
db_select_cont(disc_only_copies, Cont0, Ms) ->
Cont = dets:repair_continuation(Cont0, Ms),
dets:select(Cont);
diff --git a/lib/mnesia/src/mnesia_sup.erl b/lib/mnesia/src/mnesia_sup.erl
index 4aece81308..3e5792900b 100644
--- a/lib/mnesia/src/mnesia_sup.erl
+++ b/lib/mnesia/src/mnesia_sup.erl
@@ -23,39 +23,21 @@
-module(mnesia_sup).
--behaviour(application).
-behaviour(supervisor).
--export([start/0, start/2, init/1, stop/1, start_event/0, kill/0]).
+-export([start_link/1, init/1, start_event/0, kill/0]).
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% application and suprvisor callback functions
-
-start(normal, Args) ->
- SupName = {local,?MODULE},
- case supervisor:start_link(SupName, ?MODULE, [Args]) of
- {ok, Pid} ->
- {ok, Pid, {normal, Args}};
- Error ->
- Error
- end;
-start(_, _) ->
- {error, badarg}.
-
-start() ->
- SupName = {local,?MODULE},
- supervisor:start_link(SupName, ?MODULE, []).
+start_link(Args) ->
+ supervisor:start_link({local,?MODULE}, ?MODULE, [Args]).
-stop(_StartArgs) ->
- ok.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% supervisor callback functions
-init([]) -> % Supervisor
- init();
-init([[]]) -> % Application
+init([[]]) ->
init();
init(BadArg) ->
{error, {badarg, BadArg}}.
-
+
init() ->
Flags = {one_for_all, 0, 3600}, % Should be rest_for_one policy
@@ -124,4 +106,3 @@ ensure_dead(Name) ->
timer:sleep(10),
ensure_dead(Name)
end.
-
diff --git a/lib/mnesia/test/ext_test.erl b/lib/mnesia/test/ext_test.erl
index 45ddb148bc..b7904c95ac 100644
--- a/lib/mnesia/test/ext_test.erl
+++ b/lib/mnesia/test/ext_test.erl
@@ -233,5 +233,5 @@ select_1({Acc, C}) ->
select(ext_ets, Tab, Ms, Limit) when is_integer(Limit); Limit =:= infinity ->
ets:select(mnesia_lib:val({?MODULE,Tab}), Ms, Limit).
-repair_continuation({Alias, Cont}, Ms) ->
- {Alias, ets:repair_continuation(Cont, Ms)}.
+repair_continuation(Cont, Ms) ->
+ ets:repair_continuation(Cont, Ms).
diff --git a/lib/mnesia/test/mnesia_test_lib.erl b/lib/mnesia/test/mnesia_test_lib.erl
index 6e84a27ec9..0fabdc7929 100644
--- a/lib/mnesia/test/mnesia_test_lib.erl
+++ b/lib/mnesia/test/mnesia_test_lib.erl
@@ -263,6 +263,7 @@ slave_start_link(Host, Name, Retries) ->
Path = code:get_path(),
ok = rpc:call(NewNode, file, set_cwd, [Cwd]),
true = rpc:call(NewNode, code, set_path, [Path]),
+ ok = rpc:call(NewNode, error_logger, tty, [false]),
spawn_link(NewNode, ?MODULE, slave_sup, []),
rpc:multicall([node() | nodes()], global, sync, []),
{ok, NewNode};
diff --git a/lib/observer/priv/bin/cdv b/lib/observer/priv/bin/cdv
index 1c44785ac2..d14fd47e41 100755
--- a/lib/observer/priv/bin/cdv
+++ b/lib/observer/priv/bin/cdv
@@ -1,4 +1,4 @@
#!/bin/sh
-erl -sname cdv -noinput -s crashdump_viewer script_start $@
+erl -noinput -s crashdump_viewer script_start $@
diff --git a/lib/observer/priv/bin/cdv.bat b/lib/observer/priv/bin/cdv.bat
index efa8bf8687..18136a30d6 100644
--- a/lib/observer/priv/bin/cdv.bat
+++ b/lib/observer/priv/bin/cdv.bat
@@ -1,2 +1,2 @@
@ECHO OFF
-CALL werl -sname cdv -s crashdump_viewer script_start %*
+CALL werl -s crashdump_viewer script_start %*
diff --git a/lib/observer/priv/crashdump_viewer.tool b/lib/observer/priv/crashdump_viewer.tool
deleted file mode 100644
index b6bd6bbdef..0000000000
--- a/lib/observer/priv/crashdump_viewer.tool
+++ /dev/null
@@ -1,2 +0,0 @@
-{version,"1.2"}.
-[{config_func,{crashdump_viewer,configData,[]}}].
diff --git a/lib/observer/priv/crashdump_viewer/collapsd.gif b/lib/observer/priv/crashdump_viewer/collapsd.gif
deleted file mode 100644
index 0b90c08a9a..0000000000
--- a/lib/observer/priv/crashdump_viewer/collapsd.gif
+++ /dev/null
Binary files differ
diff --git a/lib/observer/priv/crashdump_viewer/exploded.gif b/lib/observer/priv/crashdump_viewer/exploded.gif
deleted file mode 100644
index e3ab5ca2e9..0000000000
--- a/lib/observer/priv/crashdump_viewer/exploded.gif
+++ /dev/null
Binary files differ
diff --git a/lib/observer/src/Makefile b/lib/observer/src/Makefile
index dd7831fa2b..ff2bcbdb99 100644
--- a/lib/observer/src/Makefile
+++ b/lib/observer/src/Makefile
@@ -92,7 +92,7 @@ EXAMPLE_FILES= multitrace.erl
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
PRIVDIR= ../priv
-WEBTOOLFILES= $(PRIVDIR)/crashdump_viewer.tool $(PRIVDIR)/erlang_observer.png
+PNGFILES= $(PRIVDIR)/erlang_observer.png
BINDIR= $(PRIVDIR)/bin
ifeq ($(findstring win32,$(TARGET)),win32)
WIN32_EXECUTABLES= $(BINDIR)/etop.bat $(BINDIR)/cdv.bat
@@ -103,10 +103,6 @@ EXECUTABLES= \
$(BINDIR)/etop \
$(BINDIR)/cdv \
$(WIN32_EXECUTABLES)
-CDVDIR= $(PRIVDIR)/crashdump_viewer
-GIF_FILES= \
- $(CDVDIR)/collapsd.gif \
- $(CDVDIR)/exploded.gif
APP_FILE= observer.app
@@ -163,9 +159,7 @@ release_spec: opt
$(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin"
$(INSTALL_DIR) "$(RELSYSDIR)/priv/bin"
$(INSTALL_SCRIPT) $(EXECUTABLES) "$(RELSYSDIR)/priv/bin"
- $(INSTALL_DIR) "$(RELSYSDIR)/priv/crashdump_viewer"
- $(INSTALL_DATA) $(WEBTOOLFILES) "$(RELSYSDIR)/priv"
- $(INSTALL_DATA) $(GIF_FILES) "$(RELSYSDIR)/priv/crashdump_viewer"
+ $(INSTALL_DATA) $(PNGFILES) "$(RELSYSDIR)/priv"
release_docs_spec:
diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in
index d26daa5eda..2dec6e5abf 100644
--- a/lib/odbc/configure.in
+++ b/lib/odbc/configure.in
@@ -65,7 +65,7 @@ dnl ---------------------------------------------------------------------
dnl Special windows stuff regarding CFLAGS and details in the environment...
dnl ---------------------------------------------------------------------
LM_WINDOWS_ENVIRONMENT
-
+
AC_PROG_MAKE_SET
AC_CHECK_PROGS(LD, ld.sh)
@@ -136,8 +136,8 @@ AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_addr], [], [],
dnl Checks for library functions.
AC_CHECK_FUNCS([memset socket])
-
-# ODBC
+
+# ODBC
$RM -f "$ERL_TOP/lib/odbc/SKIP"
LM_CHECK_THR_LIB
@@ -146,24 +146,24 @@ AC_SUBST(THR_LIBS)
odbc_lib_link_success=no
AC_SUBST(TARGET_FLAGS)
- case $host_os in
- darwin1[[0-5]].*|darwin[[0-9]].*)
+ case $host_os in
+ darwin1[[0-9]].*)
TARGET_FLAGS="-DUNIX"
if test ! -d "$with_odbc" || test "$with_odbc" = "yes"; then
- ODBC_LIB= -L"/usr/lib"
- ODBC_INCLUDE="-I/usr/lib/include"
+ ODBC_LIB= -L"/usr/local/lib"
+ ODBC_INCLUDE="-I/usr/local/include"
else
ODBC_LIB=-L"$with_odbc/lib"
ODBC_INCLUDE="-I$with_odbc/include"
fi
-
- AC_CHECK_LIB(iodbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -liodbc"; odbc_lib_link_success=yes])
+
+ AC_CHECK_LIB(iodbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc"; odbc_lib_link_success=yes])
;;
win32|cygwin)
TARGET_FLAGS="-DWIN32"
AC_CHECK_LIB(ws2_32, main)
if test ! -d "$with_odbc" || test "$with_odbc" = "yes"; then
- ODBC_LIB=""
+ ODBC_LIB=""
ODBC_INCLUDE=""
else
ODBC_LIB=-L"$with_odbc/lib"
@@ -196,7 +196,7 @@ AC_SUBST(TARGET_FLAGS)
elif test -d "${libdir}/64/."; then
libdir="${libdir}/64"
fi
- fi
+ fi
ODBC_LIB="-L$libdir"
ODBC_INCLUDE="-I$erl_xcomp_isysroot$rdir/include"
break
@@ -207,7 +207,7 @@ AC_SUBST(TARGET_FLAGS)
echo "No odbc library found" > "$ERL_TOP/lib/odbc/SKIP"
else
AC_MSG_RESULT($ODBC_LIB)
- AC_CHECK_LIB(odbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc"; odbc_lib_link_success=yes])
+ AC_CHECK_LIB(odbc, SQLAllocHandle,[ODBC_LIB="$ODBC_LIB -lodbc"; odbc_lib_link_success=yes])
fi
;;
diff --git a/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl b/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl
index 545be62852..8f7da2425b 100644
--- a/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl
+++ b/lib/orber/COSS/CosNaming/CosNaming_NamingContextExt_impl.erl
@@ -624,12 +624,7 @@ destroy(OE_THIS, OE_State) ->
orber:dbg("[~p] ~p:destroy(~p);~n"
"DB access returned ~p",
[?LINE, ?MODULE, SubobjKey, Other], ?DEBUG_LEVEL),
- {'EXCEPTION', #'CosNaming_NamingContext_NotEmpty'{}};
- Other ->
- orber:dbg("[~p] ~p:destroy(~p);~n"
- "DB access returned ~p",
- [?LINE, ?MODULE, SubobjKey, Other], ?DEBUG_LEVEL),
- {'EXCEPTION', #'INTERNAL'{completion_status=?COMPLETED_NO}}
+ {'EXCEPTION', #'CosNaming_NamingContext_NotEmpty'{}}
end
end,
case mnesia:transaction(_DF) of
diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml
index 89f258e5e9..5a82270b28 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -33,6 +33,20 @@
<file>notes.xml</file>
</header>
+ <section><title>Orber 3.8.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Fix some dialyzer warnings</p>
+ <p>
+ Own Id: OTP-14006</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
<section><title>Orber 3.8.2</title>
diff --git a/lib/orber/src/corba.erl b/lib/orber/src/corba.erl
index faebbc4059..1be84f5a83 100644
--- a/lib/orber/src/corba.erl
+++ b/lib/orber/src/corba.erl
@@ -2115,7 +2115,7 @@ call_RQprotected(Module, Obj, Func, Args, GroupID, RQCtx) ->
sticky_write),
Reply;
% retransmitted request
- #ft_reply_retention{reply = Reply} ->
+ [#ft_reply_retention{reply = Reply}] ->
Reply
end.
diff --git a/lib/orber/src/orber_ifr_contained.erl b/lib/orber/src/orber_ifr_contained.erl
index d5f41fbe72..2a67fa98fd 100644
--- a/lib/orber/src/orber_ifr_contained.erl
+++ b/lib/orber/src/orber_ifr_contained.erl
@@ -232,7 +232,7 @@ move(true, Contained_objref, New_container, New_name, New_version) ->
lists:filter(fun(X) -> X /= Contained_objref
end, select(Old_container_obj,
contents))),
- New_container_obj = mnesia:read(New_container),
+ [New_container_obj] = mnesia:read(New_container),
Contents = orber_ifr_container:contents(New_container, dk_All,
true),
New_new_container_obj =
diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk
index dcb2c985a3..595e686cb7 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -1 +1 @@
-ORBER_VSN = 3.8.2
+ORBER_VSN = 3.8.3
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index 385604677c..edebfe0f84 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -822,6 +822,36 @@ fun(#'DistributionPoint'{}, #'CertificateList'{},
</func>
<func>
+ <name>ssh_hostkey_fingerprint(HostKey) -> string()</name>
+ <name>ssh_hostkey_fingerprint(DigestType, HostKey) -> string()</name>
+ <fsummary>Calculates a ssh fingerprint for a hostkey.</fsummary>
+ <type>
+ <v>Key = public_key()</v>
+ <v>DigestType = digest_type()</v>
+ </type>
+ <desc>
+ <p>Calculates a ssh fingerprint from a public host key as openssh does.</p>
+ <p>The algorithm in <c>ssh_hostkey_fingerprint/1</c> is md5 to be compatible with older
+ ssh-keygen commands. The string from the second variant is prepended by the algorithm name
+ in uppercase as in newer ssh-keygen commands.</p>
+ <p>Examples:</p>
+ <code>
+ 2> public_key:ssh_hostkey_fingerprint(Key).
+ "f5:64:a6:c1:5a:cb:9f:0a:10:46:a2:5c:3e:2f:57:84"
+
+ 3> public_key:ssh_hostkey_fingerprint(md5,Key).
+ "MD5:f5:64:a6:c1:5a:cb:9f:0a:10:46:a2:5c:3e:2f:57:84"
+
+ 4> public_key:ssh_hostkey_fingerprint(sha,Key).
+ "SHA1:bSLY/C4QXLDL/Iwmhyg0PGW9UbY"
+
+ 5> public_key:ssh_hostkey_fingerprint(sha256,Key).
+ "SHA256:aZGXhabfbf4oxglxltItWeHU7ub3Dc31NcNw2cMJePQ"
+ </code>
+ </desc>
+ </func>
+
+ <func>
<name>verify(Msg, DigestType, Signature, Key) -> boolean()</name>
<fsummary>Verifies a digital signature.</fsummary>
<type>
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index d23abfe256..fed3b09f36 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -49,6 +49,7 @@
pkix_normalize_name/1,
pkix_path_validation/3,
ssh_decode/2, ssh_encode/2,
+ ssh_hostkey_fingerprint/1, ssh_hostkey_fingerprint/2,
ssh_curvename2oid/1, oid2ssh_curvename/1,
pkix_crls_validate/3,
pkix_dist_point/1,
@@ -91,7 +92,8 @@
-type public_crypt_options() :: [{rsa_pad, rsa_padding()}].
-type rsa_digest_type() :: 'md5' | 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'.
-type dss_digest_type() :: 'none' | 'sha'. %% None is for backwards compatibility
--type ecdsa_digest_type() :: 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'.
+-type ecdsa_digest_type() :: 'sha'| 'sha224' | 'sha256' | 'sha384' | 'sha512'.
+-type digest_type() :: rsa_digest_type() | dss_digest_type() | ecdsa_digest_type().
-type crl_reason() :: unspecified | keyCompromise | cACompromise | affiliationChanged | superseded
| cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise.
-type oid() :: tuple().
@@ -819,6 +821,41 @@ oid2ssh_curvename(?'secp384r1') -> <<"nistp384">>;
oid2ssh_curvename(?'secp521r1') -> <<"nistp521">>.
%%--------------------------------------------------------------------
+-spec ssh_hostkey_fingerprint(public_key()) -> string().
+-spec ssh_hostkey_fingerprint(digest_type(), public_key()) -> string().
+
+ssh_hostkey_fingerprint(Key) ->
+ sshfp_string(md5, Key).
+
+ssh_hostkey_fingerprint(HashAlg, Key) ->
+ lists:concat([sshfp_alg_name(HashAlg),
+ [$: | sshfp_string(HashAlg, Key)]
+ ]).
+
+sshfp_string(HashAlg, Key) ->
+ %% Other HashAlgs than md5 will be printed with
+ %% other formats than hextstr by
+ %% ssh-keygen -E <alg> -lf <file>
+ fp_fmt(sshfp_fmt(HashAlg), crypto:hash(HashAlg, public_key:ssh_encode(Key,ssh2_pubkey))).
+
+sshfp_alg_name(sha) -> "SHA1";
+sshfp_alg_name(Alg) -> string:to_upper(atom_to_list(Alg)).
+
+sshfp_fmt(md5) -> hexstr;
+sshfp_fmt(_) -> b64.
+
+fp_fmt(hexstr, Bin) ->
+ lists:flatten(string:join([io_lib:format("~2.16.0b",[C1]) || <<C1>> <= Bin], ":"));
+fp_fmt(b64, Bin) ->
+ %% This function clause *seems* to be
+ %% [C || C<-base64:encode_to_string(Bin), C =/= $=]
+ %% but I am not sure. Must be checked.
+ B64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
+ BitsInLast = 8*size(Bin) rem 6,
+ Padding = (6-BitsInLast) rem 6, % Want BitsInLast = [1:5] to map to padding [5:1] and 0 -> 0
+ [lists:nth(C+1,B64Chars) || <<C:6>> <= <<Bin/binary,0:Padding>> ].
+
+%%--------------------------------------------------------------------
-spec short_name_hash({rdnSequence, [#'AttributeTypeAndValue'{}]}) ->
string().
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index b22b69a0f2..cd24819899 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -45,7 +45,14 @@ all() ->
{group, sign_verify},
pkix, pkix_countryname, pkix_emailaddress, pkix_path_validation,
pkix_iso_rsa_oid, pkix_iso_dsa_oid, pkix_crl, general_name,
- short_cert_issuer_hash, short_crl_issuer_hash].
+ short_cert_issuer_hash, short_crl_issuer_hash,
+ ssh_hostkey_fingerprint_md5_implicit,
+ ssh_hostkey_fingerprint_md5,
+ ssh_hostkey_fingerprint_sha,
+ ssh_hostkey_fingerprint_sha256,
+ ssh_hostkey_fingerprint_sha384,
+ ssh_hostkey_fingerprint_sha512
+ ].
groups() ->
[{pem_decode_encode, [], [dsa_pem, rsa_pem, ec_pem, encrypted_pem,
@@ -81,7 +88,25 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
%%-------------------------------------------------------------------
-init_per_testcase(_TestCase, Config0) ->
+init_per_testcase(TestCase, Config) ->
+ case TestCase of
+ ssh_hostkey_fingerprint_md5_implicit -> init_fingerprint_testcase(md5, Config);
+ ssh_hostkey_fingerprint_md5 -> init_fingerprint_testcase(md5, Config);
+ ssh_hostkey_fingerprint_sha -> init_fingerprint_testcase(sha, Config);
+ ssh_hostkey_fingerprint_sha256 -> init_fingerprint_testcase(sha256, Config);
+ ssh_hostkey_fingerprint_sha384 -> init_fingerprint_testcase(sha384, Config);
+ ssh_hostkey_fingerprint_sha512 -> init_fingerprint_testcase(sha512, Config);
+ _ -> init_common_per_testcase(Config)
+ end.
+
+init_fingerprint_testcase(Alg, Config) ->
+ CryptoSupports = lists:member(Alg, proplists:get_value(hashs, crypto:supports())),
+ case CryptoSupports of
+ false -> {skip,{Alg,not_supported}};
+ true -> init_common_per_testcase(Config)
+ end.
+
+init_common_per_testcase(Config0) ->
Config = lists:keydelete(watchdog, 1, Config0),
Dog = ct:timetrap(?TIMEOUT),
[{watchdog, Dog} | Config].
@@ -89,6 +114,7 @@ init_per_testcase(_TestCase, Config0) ->
end_per_testcase(_TestCase, _Config) ->
ok.
+
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
@@ -529,6 +555,48 @@ ssh_openssh_public_key_long_header(Config) when is_list(Config) ->
Decoded = public_key:ssh_decode(Encoded, rfc4716_public_key).
%%--------------------------------------------------------------------
+%% Check of different host keys left to later
+ssh_hostkey_fingerprint_md5_implicit(_Config) ->
+ Expected = "4b:0b:63:de:0f:a7:3a:ab:2c:cc:2d:d1:21:37:1d:3a",
+ Expected = public_key:ssh_hostkey_fingerprint(ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Check of different host keys left to later
+ssh_hostkey_fingerprint_md5(_Config) ->
+ Expected = "MD5:4b:0b:63:de:0f:a7:3a:ab:2c:cc:2d:d1:21:37:1d:3a",
+ Expected = public_key:ssh_hostkey_fingerprint(md5, ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Since this kind of fingerprint is not available yet on standard
+%% distros, we do like this instead. The Expected is generated with:
+%% $ openssh-7.3p1/ssh-keygen -E sha1 -lf <file>
+%% 2048 SHA1:Soammnaqg06jrm2jivMSnzQGlmk [email protected] (RSA)
+ssh_hostkey_fingerprint_sha(_Config) ->
+ Expected = "SHA1:Soammnaqg06jrm2jivMSnzQGlmk",
+ Expected = public_key:ssh_hostkey_fingerprint(sha, ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Since this kind of fingerprint is not available yet on standard
+%% distros, we do like this instead.
+ssh_hostkey_fingerprint_sha256(_Config) ->
+ Expected = "SHA256:T7F1BahkJWR7iJO8+rpzWOPbp7LZP4MlNrDExdNYOvY",
+ Expected = public_key:ssh_hostkey_fingerprint(sha256, ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Since this kind of fingerprint is not available yet on standard
+%% distros, we do like this instead.
+ssh_hostkey_fingerprint_sha384(_Config) ->
+ Expected = "SHA384:QhkLoGNI4KXdPvC//HxxSCP3uTQVADqxdajbgm+Gkx9zqz8N94HyP1JmH8C4/aEl",
+ Expected = public_key:ssh_hostkey_fingerprint(sha384, ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
+%% Since this kind of fingerprint is not available yet on standard
+%% distros, we do like this instead.
+ssh_hostkey_fingerprint_sha512(_Config) ->
+ Expected = "SHA512:ezUismvm3ADQQb6Nm0c1DwQ6ydInlJNfsnSQejFkXNmABg1Aenk9oi45CXeBOoTnlfTsGG8nFDm0smP10PBEeA",
+ Expected = public_key:ssh_hostkey_fingerprint(sha512, ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
encrypt_decrypt() ->
[{doc, "Test public_key:encrypt_private and public_key:decrypt_public"}].
encrypt_decrypt(Config) when is_list(Config) ->
@@ -929,3 +997,13 @@ incorrect_countryname_pkix_cert() ->
incorrect_emailaddress_pkix_cert() ->
<<48,130,3,74,48,130,2,50,2,9,0,133,49,203,25,198,156,252,230,48,13,6,9,42,134, 72,134,247,13,1,1,5,5,0,48,103,49,11,48,9,6,3,85,4,6,19,2,65,85,49,19,48,17, 6,3,85,4,8,12,10,83,111,109,101,45,83,116,97,116,101,49,33,48,31,6,3,85,4,10, 12,24,73,110,116,101,114,110,101,116,32,87,105,100,103,105,116,115,32,80,116, 121,32,76,116,100,49,32,48,30,6,9,42,134,72,134,247,13,1,9,1,12,17,105,110, 118,97,108,105,100,64,101,109,97,105,108,46,99,111,109,48,30,23,13,49,51,49, 49,48,55,50,48,53,54,49,56,90,23,13,49,52,49,49,48,55,50,48,53,54,49,56,90, 48,103,49,11,48,9,6,3,85,4,6,19,2,65,85,49,19,48,17,6,3,85,4,8,12,10,83,111, 109,101,45,83,116,97,116,101,49,33,48,31,6,3,85,4,10,12,24,73,110,116,101, 114,110,101,116,32,87,105,100,103,105,116,115,32,80,116,121,32,76,116,100,49, 32,48,30,6,9,42,134,72,134,247,13,1,9,1,12,17,105,110,118,97,108,105,100,64, 101,109,97,105,108,46,99,111,109,48,130,1,34,48,13,6,9,42,134,72,134,247,13, 1,1,1,5,0,3,130,1,15,0,48,130,1,10,2,130,1,1,0,190,243,49,213,219,60,232,105, 1,127,126,9,130,15,60,190,78,100,148,235,246,223,21,91,238,200,251,84,55,212, 78,32,120,61,85,172,0,144,248,5,165,29,143,79,64,178,51,153,203,76,115,238, 192,49,173,37,121,203,89,62,157,13,181,166,30,112,154,40,202,140,104,211,157, 73,244,9,78,236,70,153,195,158,233,141,42,238,2,143,160,225,249,27,30,140, 151,176,43,211,87,114,164,108,69,47,39,195,123,185,179,219,28,218,122,53,83, 77,48,81,184,14,91,243,12,62,146,86,210,248,228,171,146,225,87,51,146,155, 116,112,238,212,36,111,58,41,67,27,6,61,61,3,84,150,126,214,121,57,38,12,87, 121,67,244,37,45,145,234,131,115,134,58,194,5,36,166,52,59,229,32,47,152,80, 237,190,58,182,248,98,7,165,198,211,5,31,231,152,116,31,108,71,218,64,188, 178,143,27,167,79,15,112,196,103,116,212,65,197,94,37,4,132,103,91,217,73, 223,207,185,7,153,221,240,232,31,44,102,108,82,83,56,242,210,214,74,71,246, 177,217,148,227,220,230,4,176,226,74,194,37,2,3,1,0,1,48,13,6,9,42,134,72, 134,247,13,1,1,5,5,0,3,130,1,1,0,89,247,141,154,173,123,123,203,143,85,28,79, 73,37,164,6,17,89,171,224,149,22,134,17,198,146,158,192,241,41,253,58,230, 133,71,189,43,66,123,88,15,242,119,227,249,99,137,61,200,54,161,0,177,167, 169,114,80,148,90,22,97,78,162,181,75,93,209,116,245,46,81,232,64,157,93,136, 52,57,229,113,197,218,113,93,42,161,213,104,205,137,30,144,183,58,10,98,47, 227,177,96,40,233,98,150,209,217,68,22,221,133,27,161,152,237,46,36,179,59, 172,97,134,194,205,101,137,71,192,57,153,20,114,27,173,233,166,45,56,0,61, 205,45,202,139,7,132,103,248,193,157,184,123,43,62,172,236,110,49,62,209,78, 249,83,219,133,1,213,143,73,174,16,113,143,189,41,84,60,128,222,30,177,104, 134,220,52,239,171,76,59,176,36,113,176,214,118,16,44,235,21,167,199,216,200, 76,219,142,248,13,70,145,205,216,230,226,148,97,223,216,179,68,209,222,63, 140,137,24,164,192,149,194,79,119,247,75,159,49,116,70,241,70,116,11,40,119, 176,157,36,160,102,140,255,34,248,25,231,136,59>>.
+
+
+
+ssh_hostkey(rsa) ->
+ [{PKdecoded,_}] =
+ public_key:ssh_decode(
+ <<"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDYXcYmsyJBstl4EfFYzfQJmSiUE162zvSGSoMYybShYOI6rnnyvvihfw8Aml+2gZ716F2tqG48FQ/yPZEGWNPMrCejPpJctaPWhpNdNMJ8KFXSEgr5bY2mEpa19DHmuDeXKzeJJ+X7s3fVdYc4FMk5731KIW6Huf019ZnTxbx0VKG6b1KAJBg3vpNsDxEMwQ4LFMB0JHVklOTzbxmpaeULuIxvl65A+eGeFVeo2Q+YI9UnwY1vSgmc9Azwy8Ie9Z0HpQBN5I7Uc5xnknT8V6xDhgNfXEfzsgsRdDfZLECt1WO/1gP9wkosvAGZWt5oG8pbNQWiQdFq536ck8WQD9WD [email protected]">>,
+ public_key),
+ PKdecoded.
+
diff --git a/lib/reltool/doc/src/reltool_examples.xml b/lib/reltool/doc/src/reltool_examples.xml
index f735d914ea..83eee6017a 100644
--- a/lib/reltool/doc/src/reltool_examples.xml
+++ b/lib/reltool/doc/src/reltool_examples.xml
@@ -277,7 +277,7 @@ Eshell V5.7.3 (abort with ^G)
disk_log_sup,dist_ac,dist_util,erl_boot_server|...]},
{path,["$ROOT/lib/stdlib-1.16/ebin"]},
{primLoad,[array,base64,beam_lib,c,calendar,dets,
- dets_server,dets_sup,dets_utils,dets_v8,dets_v9,dict|...]},
+ dets_server,dets_sup,dets_utils,dets_v9,dict|...]},
{path,["$ROOT/lib/sasl-2.1.6/ebin"]},
{primLoad,[alarm_handler,erlsrv,format_lib_supp,misc_supp,
overload,rb,rb_format_supp,release_handler,
diff --git a/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat b/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat
index bdc510e838..a0e3806981 100644
--- a/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat
+++ b/lib/runtime_tools/test/system_information_SUITE_data/information_test_report.dat
@@ -447,11 +447,6 @@
{native,false},
{compiler,"4.9.1"},
{md5,"a64e0220f855e6e97d53a9bc4f0a111b"}]},
- {dets_v8,
- [{loaded,false},
- {native,false},
- {compiler,"4.9.1"},
- {md5,"ebf2c94f62d180c3159b663ba2094189"}]},
{dets_v9,
[{loaded,false},
{native,false},
diff --git a/lib/sasl/src/sasl.appup.src b/lib/sasl/src/sasl.appup.src
index ecd320c1ea..7f866507a0 100644
--- a/lib/sasl/src/sasl.appup.src
+++ b/lib/sasl/src/sasl.appup.src
@@ -18,9 +18,7 @@
%% %CopyrightEnd%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.*
+ [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-19.*
%% Down to - max one major revision back
- [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.*
+ [{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-19.*
}.
diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl
index efe6cc9eb4..6a16c8689e 100644
--- a/lib/sasl/src/systools_make.erl
+++ b/lib/sasl/src/systools_make.erl
@@ -643,6 +643,8 @@ get_items([], _Dict) ->
check_item({_,{mod,{M,A}}},_) when is_atom(M) ->
{M,A};
+check_item({_,{mod,[]}},_) -> % default mod is [], so accept as entry
+ [];
check_item({_,{vsn,Vsn}},I) ->
case string_p(Vsn) of
true -> Vsn;
@@ -678,6 +680,8 @@ check_item({_,{modules,Mods}},I) ->
true -> Mods;
_ -> throw({bad_param, I})
end;
+check_item({_,{start_phases,undefined}},_) -> % default start_phase is undefined,
+ undefined; % so accept as entry
check_item({_,{start_phases,Phase}},I) ->
case t_list_p(Phase) of
true -> Phase;
diff --git a/lib/sasl/test/systools_SUITE.erl b/lib/sasl/test/systools_SUITE.erl
index bf95ceb70c..dd5f277a77 100644
--- a/lib/sasl/test/systools_SUITE.erl
+++ b/lib/sasl/test/systools_SUITE.erl
@@ -59,7 +59,7 @@
no_appup_relup/1, bad_appup_relup/1, app_start_type_relup/1,
regexp_relup/1]).
-export([normal_hybrid/1,hybrid_no_old_sasl/1,hybrid_no_new_sasl/1]).
--export([otp_6226_outdir/1]).
+-export([otp_6226_outdir/1, app_file_defaults/1]).
-export([init_per_suite/1, end_per_suite/1,
init_per_testcase/2, end_per_testcase/2]).
-export([delete_tree/1]).
@@ -97,7 +97,7 @@ groups() ->
no_appup_relup, bad_appup_relup, app_start_type_relup, regexp_relup
]},
{hybrid, [], [normal_hybrid,hybrid_no_old_sasl,hybrid_no_new_sasl]},
- {options, [], [otp_6226_outdir]}].
+ {options, [], [otp_6226_outdir,app_file_defaults]}].
init_per_group(_GroupName, Config) ->
Config.
@@ -2014,6 +2014,37 @@ otp_6226_outdir(Config) when is_list(Config) ->
ok.
+%% Test that all default values can be used as values in the .app file
+app_file_defaults(Config) ->
+ PrivDir = ?config(priv_dir,Config),
+ Name = app1,
+ NameStr = atom_to_list(Name),
+ Vsn = "1.0",
+ AppSpec = app_spec(Name,#{vsn=>"1.0"}),
+ ok = file:write_file(filename:join(PrivDir,NameStr ++ ".app"),
+ io_lib:format("~p.~n",[AppSpec])),
+ {ok,_} = systools_make:read_application(NameStr,Vsn,[PrivDir],[]),
+ ok.
+
+app_spec(Name,New) ->
+ {application,Name,app_spec(New)}.
+
+app_spec(New) ->
+ Default = #{description => "",
+ id => "",
+ vsn => "",
+ modules => [],
+ maxP => infinity,
+ maxT => infinity,
+ registered => [],
+ included_applications => [],
+ applications => [],
+ env => [],
+ mod => [],
+ start_phases => undefined,
+ runtime_dependencies => []},
+ maps:to_list(maps:merge(Default,New)).
+
%%%%%%
%%%%%% Utilities
%%%%%%
diff --git a/lib/sasl/test/test_lib.hrl b/lib/sasl/test/test_lib.hrl
index 2d897e9903..9a54937f96 100644
--- a/lib/sasl/test/test_lib.hrl
+++ b/lib/sasl/test/test_lib.hrl
@@ -1,3 +1,3 @@
-define(ertsvsn,"4.4").
--define(kernelvsn,"4.0").
--define(stdlibvsn,"2.5").
+-define(kernelvsn,"5.0").
+-define(stdlibvsn,"3.0").
diff --git a/lib/ssh/doc/src/introduction.xml b/lib/ssh/doc/src/introduction.xml
index ca84528f3d..b7a73e2597 100644
--- a/lib/ssh/doc/src/introduction.xml
+++ b/lib/ssh/doc/src/introduction.xml
@@ -195,8 +195,6 @@
Transport Layer Protocol</item>
<item><url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url> -
Connection Protocol</item>
- <item><url href="http://www.ietf.org/rfc/rfc4255.txt">RFC 4255</url> -
- Key Fingerprints</item>
<item><url href="http://www.ietf.org/rfc/rfc4344.txt">RFC 4344</url> -
Transport Layer Encryption Modes</item>
<item><url href="http://www.ietf.org/rfc/rfc4716.txt">RFC 4716</url> -
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index ef9f7cbd9b..6b49f89449 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -175,11 +175,21 @@
supplied with this option.
</p>
</item>
- <tag><c><![CDATA[{silently_accept_hosts, boolean()}]]></c></tag>
+ <tag><c><![CDATA[{silently_accept_hosts, boolean() | accept_fun() | {crypto:digest_type(), accept_fun()} }]]></c>
+ <br/>
+ <c><![CDATA[accept_fun() :: fun(PeerName::string(), FingerPrint::string()) -> boolean()]]></c>
+ </tag>
<item>
<p>When <c>true</c>, hosts are added to the
file <c><![CDATA[known_hosts]]></c> without asking the user.
- Defaults to <c>false</c>.
+ Defaults to <c>false</c> which will give a user question on stdio of whether to accept or reject a previously
+ unseen host.</p>
+ <p>If the option value is has an <c>accept_fun()</c>, that fun will called with the arguments
+ <c>(PeerName, PeerHostKeyFingerPrint)</c>. The fingerprint is calculated on the Peer's Host Key with
+ <seealso marker="public_key:public_key#ssh_hostkey_fingerprint-1">public_key:ssh_hostkey_fingerprint/1</seealso>.
+ </p>
+ <p>If the <c>crypto:digest_type()</c> is present, the fingerprint is calculated with that digest type by the function
+ <seealso marker="public_key:public_key#ssh_hostkey_fingerprint-2">public_key:ssh_hostkey_fingerprint/2</seealso>.
</p>
</item>
<tag><c><![CDATA[{user_interaction, boolean()}]]></c></tag>
diff --git a/lib/ssh/doc/src/ssh_protocol.xml b/lib/ssh/doc/src/ssh_protocol.xml
index 7288266cf7..013823b4df 100644
--- a/lib/ssh/doc/src/ssh_protocol.xml
+++ b/lib/ssh/doc/src/ssh_protocol.xml
@@ -138,8 +138,6 @@
Transport Layer Protocol.</item>
<item><url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url> -
Connection Protocol.</item>
- <item><url href="http://www.ietf.org/rfc/rfc4255.txt">RFC 4255</url> -
- Key Fingerprints.</item>
<item><url href="http://www.ietf.org/rfc/rfc4344.txt">RFC 4344</url> -
Transport Layer Encryption Modes.</item>
<item><url href="http://www.ietf.org/rfc/rfc4716.txt">RFC 4716</url> -
diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile
index 69d5a47f83..7ab6f22424 100644
--- a/lib/ssh/src/Makefile
+++ b/lib/ssh/src/Makefile
@@ -96,7 +96,7 @@ APP_TARGET= $(EBIN)/$(APP_FILE)
APPUP_SRC= $(APPUP_FILE).src
APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
-INTERNAL_HRL_FILES = ssh_auth.hrl ssh_connect.hrl ssh_transport.hrl ssh.hrl ssh_userauth.hrl ssh_xfer.hrl
+INTERNAL_HRL_FILES = ssh_auth.hrl ssh_connect.hrl ssh_transport.hrl ssh.hrl ssh_userauth.hrl ssh_xfer.hrl ssh_dbg.hrl
# ----------------------------------------------------
# FLAGS
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 1d7be3547b..31e343e81b 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -617,6 +617,15 @@ handle_ssh_option({user_dir_fun, Value} = Opt) when is_function(Value) ->
Opt;
handle_ssh_option({silently_accept_hosts, Value} = Opt) when is_boolean(Value) ->
Opt;
+handle_ssh_option({silently_accept_hosts, Value} = Opt) when is_function(Value,2) ->
+ Opt;
+handle_ssh_option({silently_accept_hosts, {DigestAlg,Value}} = Opt) when is_function(Value,2) ->
+ case lists:member(DigestAlg, [md5, sha, sha224, sha256, sha384, sha512]) of
+ true ->
+ Opt;
+ false ->
+ throw({error, {eoptions, Opt}})
+ end;
handle_ssh_option({user_interaction, Value} = Opt) when is_boolean(Value) ->
Opt;
handle_ssh_option({preferred_algorithms,[_|_]} = Opt) ->
diff --git a/lib/ssh/src/ssh_channel.erl b/lib/ssh/src/ssh_channel.erl
index 426e2f5125..85b31f3669 100644
--- a/lib/ssh/src/ssh_channel.erl
+++ b/lib/ssh/src/ssh_channel.erl
@@ -261,7 +261,7 @@ handle_info({ssh_cm, _, _} = Msg, #state{cm = ConnectionManager,
adjust_window(Msg),
{noreply, State#state{channel_state = ChannelState}, Timeout};
{stop, ChannelId, ChannelState} ->
- ssh_connection:close(ConnectionManager, ChannelId),
+ catch ssh_connection:close(ConnectionManager, ChannelId),
{stop, normal, State#state{close_sent = true,
channel_state = ChannelState}}
end;
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl
index d0f2d54c06..1153095135 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.erl
@@ -287,6 +287,9 @@ handle_msg(#ssh_msg_channel_open_confirmation{recipient_channel = ChannelId,
ssh_channel:cache_update(Cache, Channel#channel{
remote_id = RemoteId,
+ recv_packet_size = max(32768, % rfc4254/5.2
+ min(PacketSz, Channel#channel.recv_packet_size)
+ ),
send_window_size = WindowSz,
send_packet_size = PacketSz}),
{Reply, Connection} = reply_msg(Channel, Connection0, {open, ChannelId}),
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index dd414894d4..7451c9e6d0 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -928,6 +928,7 @@ handle_event(internal, Msg=#ssh_msg_channel_request{}, StateName, D) -
handle_connection_msg(Msg, StateName, D);
handle_event(internal, Msg=#ssh_msg_channel_success{}, StateName, D) ->
+ update_inet_buffers(D#data.socket),
handle_connection_msg(Msg, StateName, D);
handle_event(internal, Msg=#ssh_msg_channel_failure{}, StateName, D) ->
@@ -1007,6 +1008,7 @@ handle_event(cast, {reply_request,success,ChannelId}, {connected,_}, D) ->
case ssh_channel:cache_lookup(cache(D), ChannelId) of
#channel{remote_id = RemoteId} ->
Msg = ssh_connection:channel_success_msg(RemoteId),
+ update_inet_buffers(D#data.socket),
{keep_state, send_msg(Msg,D)};
undefined ->
@@ -1194,12 +1196,12 @@ handle_event(info, {Proto, Sock, NewData}, StateName, D0 = #data{socket = Sock,
ssh_message:decode(set_kex_overload_prefix(DecryptedBytes,D))
of
Msg = #ssh_msg_kexinit{} ->
- {keep_state, D, [{next_event, internal, {Msg,DecryptedBytes}},
- {next_event, internal, prepare_next_packet}
+ {keep_state, D, [{next_event, internal, prepare_next_packet},
+ {next_event, internal, {Msg,DecryptedBytes}}
]};
Msg ->
- {keep_state, D, [{next_event, internal, Msg},
- {next_event, internal, prepare_next_packet}
+ {keep_state, D, [{next_event, internal, prepare_next_packet},
+ {next_event, internal, Msg}
]}
catch
_C:_E ->
@@ -1738,6 +1740,11 @@ send_replies(Repls, State) ->
Repls).
get_repl({connection_reply,Msg}, {CallRepls,S}) ->
+ if is_record(Msg, ssh_msg_channel_success) ->
+ update_inet_buffers(S#data.socket);
+ true ->
+ ok
+ end,
{CallRepls, send_msg(Msg,S)};
get_repl({channel_data,undefined,_Data}, Acc) ->
Acc;
@@ -1926,3 +1933,13 @@ handshake(Pid, Ref, Timeout) ->
{error, timeout}
end.
+update_inet_buffers(Socket) ->
+ {ok, BufSzs0} = inet:getopts(Socket, [sndbuf,recbuf]),
+ MinVal = 655360,
+ case
+ [{Tag,MinVal} || {Tag,Val} <- BufSzs0,
+ Val < MinVal]
+ of
+ [] -> ok;
+ NewOpts -> inet:setopts(Socket, NewOpts)
+ end.
diff --git a/lib/ssh/src/ssh_dbg.erl b/lib/ssh/src/ssh_dbg.erl
index bd6bc0335b..dff2bae9f2 100644
--- a/lib/ssh/src/ssh_dbg.erl
+++ b/lib/ssh/src/ssh_dbg.erl
@@ -28,6 +28,9 @@
stop/0
]).
+-export([shrink_bin/1,
+ wr_record/3]).
+
-include("ssh.hrl").
-include("ssh_transport.hrl").
-include("ssh_connect.hrl").
@@ -113,7 +116,12 @@ setup_tracer(Write, MangleArg) ->
ok.
%%%----------------------------------------------------------------
-shrink_bin(B) when is_binary(B), size(B)>100 -> {'*** SHRINKED BIN',size(B),element(1,split_binary(B,20)),'***'};
+shrink_bin(B) when is_binary(B), size(B)>100 -> {'*** SHRINKED BIN',
+ size(B),
+ element(1,split_binary(B,20)),
+ '...',
+ element(2,split_binary(B,size(B)-20))
+ };
shrink_bin(L) when is_list(L) -> lists:map(fun shrink_bin/1, L);
shrink_bin(T) when is_tuple(T) -> list_to_tuple(shrink_bin(tuple_to_list(T)));
shrink_bin(X) -> X.
diff --git a/lib/ssh/src/ssh_dbg.hrl b/lib/ssh/src/ssh_dbg.hrl
new file mode 100644
index 0000000000..e94664737b
--- /dev/null
+++ b/lib/ssh/src/ssh_dbg.hrl
@@ -0,0 +1,27 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-ifndef(SSH_DBG_HRL).
+-define(SSH_DBG_HRL, 1).
+
+-define(formatrec(RecName,R),
+ ssh_dbg:wr_record(R, record_info(fields,RecName), [])).
+
+-endif. % SSH_DBG_HRL defined
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 15b80de30a..21ba34506a 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -734,12 +734,16 @@ public_algo({#'ECPoint'{},{namedCurve,OID}}) ->
list_to_atom("ecdsa-sha2-" ++ binary_to_list(Curve)).
-accepted_host(Ssh, PeerName, Opts) ->
+accepted_host(Ssh, PeerName, Public, Opts) ->
case proplists:get_value(silently_accept_hosts, Opts, false) of
+ F when is_function(F,2) ->
+ true == (catch F(PeerName, public_key:ssh_hostkey_fingerprint(Public)));
+ {DigestAlg,F} when is_function(F,2) ->
+ true == (catch F(PeerName, public_key:ssh_hostkey_fingerprint(DigestAlg,Public)));
true ->
- yes;
+ true;
false ->
- yes_no(Ssh, "New host " ++ PeerName ++ " accept")
+ yes == yes_no(Ssh, "New host " ++ PeerName ++ " accept")
end.
known_host_key(#ssh{opts = Opts, key_cb = Mod, peer = Peer} = Ssh,
@@ -749,10 +753,10 @@ known_host_key(#ssh{opts = Opts, key_cb = Mod, peer = Peer} = Ssh,
true ->
ok;
false ->
- case accepted_host(Ssh, PeerName, Opts) of
- yes ->
+ case accepted_host(Ssh, PeerName, Public, Opts) of
+ true ->
Mod:add_host_key(PeerName, Public, Opts);
- no ->
+ false ->
{error, rejected}
end
end.
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 51e0d5196b..0a0ab5cdf7 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -315,9 +315,9 @@ init_per_testcase(TC, Config) when TC==shell_no_unicode ;
{user_passwords, [{"foo", "bar"}]}]),
ct:sleep(500),
IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir,
- [{silently_accept_hosts, true},
- {user,"foo"},{password,"bar"}]),
+ Shell = ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir},
+ {silently_accept_hosts, true},
+ {user,"foo"},{password,"bar"}]),
ct:log("IO=~p, Shell=~p, self()=~p",[IO,Shell,self()]),
ct:log("file:native_name_encoding() = ~p,~nio:getopts() = ~p",
[file:native_name_encoding(),io:getopts()]),
@@ -343,14 +343,15 @@ end_per_testcase(TC, Config) when TC==shell_no_unicode ;
TC==shell_unicode_string ->
case proplists:get_value(sftpd, Config) of
{Pid, _, _} ->
- ssh:stop_daemon(Pid),
- ssh:stop();
+ catch ssh:stop_daemon(Pid);
_ ->
- ssh:stop()
- end;
+ ok
+ end,
+ end_per_testcase(Config);
end_per_testcase(_TestCase, Config) ->
end_per_testcase(Config).
-end_per_testcase(_Config) ->
+
+end_per_testcase(_Config) ->
ssh:stop(),
ok.
@@ -524,7 +525,7 @@ shell(Config) when is_list(Config) ->
ct:sleep(500),
IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir),
+ Shell = ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir}]),
receive
{'EXIT', _, _} ->
ct:fail(no_ssh_connection);
@@ -562,10 +563,10 @@ exec_key_differs(Config, UserPKAlgs) ->
ct:sleep(500),
IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir,
- [{preferred_algorithms,[{public_key,['ssh-rsa']}]},
- {pref_public_key_algs,UserPKAlgs}
- ]),
+ Shell = ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir},
+ {preferred_algorithms,[{public_key,['ssh-rsa']}]},
+ {pref_public_key_algs,UserPKAlgs}
+ ]),
receive
@@ -596,9 +597,9 @@ exec_key_differs_fail(Config) when is_list(Config) ->
ct:sleep(500),
IO = ssh_test_lib:start_io_server(),
- ssh_test_lib:start_shell(Port, IO, UserDir,
- [{preferred_algorithms,[{public_key,['ssh-rsa']}]},
- {pref_public_key_algs,['ssh-dss']}]),
+ ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir},
+ {preferred_algorithms,[{public_key,['ssh-rsa']}]},
+ {pref_public_key_algs,['ssh-dss']}]),
receive
{'EXIT', _, _} ->
ok;
diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl
index bcf3b01824..2819a4dbd9 100644
--- a/lib/ssh/test/ssh_connection_SUITE.erl
+++ b/lib/ssh/test/ssh_connection_SUITE.erl
@@ -381,13 +381,13 @@ do_interrupted_send(Config, SendSize, EchoSize) ->
{password, "morot"},
{subsystems, [{"echo_n",EchoSS_spec}]}]),
- ct:log("connect", []),
+ ct:log("~p:~p connect", [?MODULE,?LINE]),
ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
{user, "foo"},
{password, "morot"},
{user_interaction, false},
{user_dir, UserDir}]),
- ct:log("connected", []),
+ ct:log("~p:~p connected", [?MODULE,?LINE]),
%% build big binary
Data = << <<X:32>> || X <- lists:seq(1,SendSize div 4)>>,
@@ -399,58 +399,80 @@ do_interrupted_send(Config, SendSize, EchoSize) ->
Parent = self(),
ResultPid = spawn(
fun() ->
- ct:log("open channel",[]),
+ ct:log("~p:~p open channel",[?MODULE,?LINE]),
{ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
- ct:log("start subsystem", []),
+ ct:log("~p:~p start subsystem", [?MODULE,?LINE]),
case ssh_connection:subsystem(ConnectionRef, ChannelId, "echo_n", infinity) of
success ->
Parent ! {self(), channelId, ChannelId},
Result =
- try collect_data(ConnectionRef, ChannelId)
+ try collect_data(ConnectionRef, ChannelId, EchoSize)
of
ExpectedData ->
+ ct:log("~p:~p got expected data",[?MODULE,?LINE]),
ok;
- _ ->
- {fail,"unexpected result"}
+ Other ->
+ ct:log("~p:~p unexpect: ~p", [?MODULE,?LINE,Other]),
+ {fail,"unexpected result in listener"}
catch
Class:Exception ->
- {fail, io_lib:format("Exception ~p:~p",[Class,Exception])}
+ {fail, io_lib:format("Listener exception ~p:~p",[Class,Exception])}
end,
- Parent ! {self(), Result};
+ Parent ! {self(), result, Result};
Other ->
Parent ! {self(), channelId, error, Other}
end
end),
receive
+ {ResultPid, channelId, error, Other} ->
+ ct:log("~p:~p channelId error ~p", [?MODULE,?LINE,Other]),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid),
+ {fail, "ssh_connection:subsystem"};
+
{ResultPid, channelId, ChannelId} ->
- %% pre-adjust receive window so the other end doesn't block
- ct:log("adjust window", []),
- ssh_connection:adjust_window(ConnectionRef, ChannelId, size(ExpectedData) + 1),
-
- ct:log("going to send ~p bytes", [size(Data)]),
- case ssh_connection:send(ConnectionRef, ChannelId, Data, 30000) of
- {error, closed} ->
- ct:log("{error,closed} - That's what we expect :)", []),
- ok;
- Msg ->
- ct:log("Got ~p - that's bad, very bad indeed",[Msg]),
- ct:fail({expected,{error,closed}, got, Msg})
- end,
- ct:log("going to check the result (if it is available)", []),
+ ct:log("~p:~p ~p going to send ~p bytes", [?MODULE,?LINE,self(),size(Data)]),
+ SenderPid = spawn(fun() ->
+ Parent ! {self(), ssh_connection:send(ConnectionRef, ChannelId, Data, 30000)}
+ end),
receive
- {ResultPid, Result} ->
- ct:log("Got result: ~p", [Result]),
+ {ResultPid, result, {fail, Fail}} ->
+ ct:log("~p:~p Listener failed: ~p", [?MODULE,?LINE,Fail]),
+ {fail, Fail};
+
+ {ResultPid, result, Result} ->
+ ct:log("~p:~p Got result: ~p", [?MODULE,?LINE,Result]),
ssh:close(ConnectionRef),
ssh:stop_daemon(Pid),
- Result
- end;
+ ct:log("~p:~p Check sender", [?MODULE,?LINE]),
+ receive
+ {SenderPid, {error, closed}} ->
+ ct:log("~p:~p {error,closed} - That's what we expect :)",[?MODULE,?LINE]),
+ ok;
+ Msg ->
+ ct:log("~p:~p Not expected send result: ~p",[?MODULE,?LINE,Msg]),
+ {fail, "Not expected msg"}
+ end;
+
+ {SenderPid, {error, closed}} ->
+ ct:log("~p:~p {error,closed} - That's what we expect, but client channel handler has not reported yet",[?MODULE,?LINE]),
+ receive
+ {ResultPid, result, Result} ->
+ ct:log("~p:~p Now got the result: ~p", [?MODULE,?LINE,Result]),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid),
+ ok;
+ Msg ->
+ ct:log("~p:~p Got an unexpected msg ~p",[?MODULE,?LINE,Msg]),
+ {fail, "Un-expected msg"}
+ end;
- {ResultPid, channelId, error, Other} ->
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid),
- {fail, io_lib:format("ssh_connection:subsystem: ~p",[Other])}
+ Msg ->
+ ct:log("~p:~p Got unexpected ~p",[?MODULE,?LINE,Msg]),
+ {fail, "Unexpected msg"}
+ end
end.
%%--------------------------------------------------------------------
@@ -909,36 +931,46 @@ big_cat_rx(ConnectionRef, ChannelId, Acc) ->
timeout
end.
-collect_data(ConnectionRef, ChannelId) ->
- ct:log("Listener ~p running! ConnectionRef=~p, ChannelId=~p",[self(),ConnectionRef,ChannelId]),
- collect_data(ConnectionRef, ChannelId, [], 0).
+collect_data(ConnectionRef, ChannelId, EchoSize) ->
+ ct:log("~p:~p Listener ~p running! ConnectionRef=~p, ChannelId=~p",[?MODULE,?LINE,self(),ConnectionRef,ChannelId]),
+ collect_data(ConnectionRef, ChannelId, EchoSize, [], 0).
-collect_data(ConnectionRef, ChannelId, Acc, Sum) ->
+collect_data(ConnectionRef, ChannelId, EchoSize, Acc, Sum) ->
TO = 5000,
receive
{ssh_cm, ConnectionRef, {data, ChannelId, 0, Data}} when is_binary(Data) ->
- ct:log("collect_data: received ~p bytes. total ~p bytes",[size(Data),Sum+size(Data)]),
- collect_data(ConnectionRef, ChannelId, [Data | Acc], Sum+size(Data));
- {ssh_cm, ConnectionRef, {eof, ChannelId}} ->
- try
- iolist_to_binary(lists:reverse(Acc))
- of
- Bin ->
- ct:log("collect_data: received eof.~nGot in total ~p bytes",[size(Bin)]),
- Bin
- catch
- C:E ->
- ct:log("collect_data: received eof.~nAcc is strange...~nException=~p:~p~nAcc=~p",
- [C,E,Acc]),
- {error,{C,E}}
- end;
+ ct:log("~p:~p collect_data: received ~p bytes. total ~p bytes, want ~p more",
+ [?MODULE,?LINE,size(Data),Sum+size(Data),EchoSize-Sum]),
+ ssh_connection:adjust_window(ConnectionRef, ChannelId, size(Data)),
+ collect_data(ConnectionRef, ChannelId, EchoSize, [Data | Acc], Sum+size(Data));
+ {ssh_cm, ConnectionRef, Msg={eof, ChannelId}} ->
+ collect_data_report_end(Acc, Msg, EchoSize);
+
+ {ssh_cm, ConnectionRef, Msg={closed,ChannelId}} ->
+ collect_data_report_end(Acc, Msg, EchoSize);
+
Msg ->
- ct:log("collect_data: ***** unexpected message *****~n~p",[Msg]),
- collect_data(ConnectionRef, ChannelId, Acc, Sum)
+ ct:log("~p:~p collect_data: ***** unexpected message *****~n~p",[?MODULE,?LINE,Msg]),
+ collect_data(ConnectionRef, ChannelId, EchoSize, Acc, Sum)
after TO ->
- ct:log("collect_data: ----- Nothing received for ~p seconds -----~n",[]),
- collect_data(ConnectionRef, ChannelId, Acc, Sum)
+ ct:log("~p:~p collect_data: ----- Nothing received for ~p seconds -----~n",[?MODULE,?LINE,TO]),
+ collect_data(ConnectionRef, ChannelId, EchoSize, Acc, Sum)
+ end.
+
+collect_data_report_end(Acc, Msg, EchoSize) ->
+ try
+ iolist_to_binary(lists:reverse(Acc))
+ of
+ Bin ->
+ ct:log("~p:~p collect_data: received ~p.~nGot in total ~p bytes, want ~p more",
+ [?MODULE,?LINE,Msg,size(Bin),EchoSize,size(Bin)]),
+ Bin
+ catch
+ C:E ->
+ ct:log("~p:~p collect_data: received ~p.~nAcc is strange...~nException=~p:~p~nAcc=~p",
+ [?MODULE,?LINE,Msg,C,E,Acc]),
+ {error,{C,E}}
end.
%%%-------------------------------------------------------------------
diff --git a/lib/ssh/test/ssh_options_SUITE.erl b/lib/ssh/test/ssh_options_SUITE.erl
index 61883c0647..8f060bebd8 100644
--- a/lib/ssh/test/ssh_options_SUITE.erl
+++ b/lib/ssh/test/ssh_options_SUITE.erl
@@ -61,7 +61,13 @@
unexpectedfun_option_client/1,
unexpectedfun_option_server/1,
user_dir_option/1,
- connectfun_disconnectfun_server/1
+ connectfun_disconnectfun_server/1,
+ hostkey_fingerprint_check/1,
+ hostkey_fingerprint_check_md5/1,
+ hostkey_fingerprint_check_sha/1,
+ hostkey_fingerprint_check_sha256/1,
+ hostkey_fingerprint_check_sha384/1,
+ hostkey_fingerprint_check_sha512/1
]).
%%% Common test callbacks
@@ -100,6 +106,12 @@ all() ->
disconnectfun_option_client,
unexpectedfun_option_server,
unexpectedfun_option_client,
+ hostkey_fingerprint_check,
+ hostkey_fingerprint_check_md5,
+ hostkey_fingerprint_check_sha,
+ hostkey_fingerprint_check_sha256,
+ hostkey_fingerprint_check_sha384,
+ hostkey_fingerprint_check_sha512,
id_string_no_opt_client,
id_string_own_string_client,
id_string_random_client,
@@ -540,10 +552,18 @@ connectfun_disconnectfun_server(Config) ->
{disconnect,Ref,R} ->
ct:log("Disconnect result: ~p",[R]),
ssh:stop_daemon(Pid)
- after 2000 ->
+ after 5000 ->
+ receive
+ X -> ct:log("received ~p",[X])
+ after 0 -> ok
+ end,
{fail, "No disconnectfun action"}
end
- after 2000 ->
+ after 5000 ->
+ receive
+ X -> ct:log("received ~p",[X])
+ after 0 -> ok
+ end,
{fail, "No connectfun action"}
end.
@@ -649,7 +669,7 @@ disconnectfun_option_server(Config) ->
ct:log("Server detected disconnect: ~p",[Reason]),
ssh:stop_daemon(Pid),
ok
- after 3000 ->
+ after 5000 ->
receive
X -> ct:log("received ~p",[X])
after 0 -> ok
@@ -774,6 +794,93 @@ unexpectedfun_option_client(Config) ->
end.
%%--------------------------------------------------------------------
+hostkey_fingerprint_check(Config) ->
+ do_hostkey_fingerprint_check(Config, old).
+
+hostkey_fingerprint_check_md5(Config) ->
+ do_hostkey_fingerprint_check(Config, md5).
+
+hostkey_fingerprint_check_sha(Config) ->
+ do_hostkey_fingerprint_check(Config, sha).
+
+hostkey_fingerprint_check_sha256(Config) ->
+ do_hostkey_fingerprint_check(Config, sha256).
+
+hostkey_fingerprint_check_sha384(Config) ->
+ do_hostkey_fingerprint_check(Config, sha384).
+
+hostkey_fingerprint_check_sha512(Config) ->
+ do_hostkey_fingerprint_check(Config, sha512).
+
+
+%%%----
+do_hostkey_fingerprint_check(Config, HashAlg) ->
+ case supported_hash(HashAlg) of
+ true ->
+ really_do_hostkey_fingerprint_check(Config, HashAlg);
+ false ->
+ {skip,{unsupported_hash,HashAlg}}
+ end.
+
+supported_hash(old) -> true;
+supported_hash(HashAlg) ->
+ proplists:get_value(HashAlg,
+ proplists:get_value(hashs, crypto:supports(), []),
+ false).
+
+
+really_do_hostkey_fingerprint_check(Config, HashAlg) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = proplists:get_value(data_dir, Config),
+
+ %% All host key fingerprints. Trust that public_key has checked the ssh_hostkey_fingerprint
+ %% function since that function is used by the ssh client...
+ FPs = [case HashAlg of
+ old -> public_key:ssh_hostkey_fingerprint(Key);
+ _ -> public_key:ssh_hostkey_fingerprint(HashAlg, Key)
+ end
+ || FileCandidate <- begin
+ {ok,KeyFileCands} = file:list_dir(SysDir),
+ KeyFileCands
+ end,
+ nomatch =/= re:run(FileCandidate, ".*\\.pub", []),
+ {Key,_Cmnts} <- begin
+ {ok,Bin} = file:read_file(filename:join(SysDir, FileCandidate)),
+ try public_key:ssh_decode(Bin, public_key)
+ catch
+ _:_ -> []
+ end
+ end],
+ ct:log("Fingerprints(~p) = ~p",[HashAlg,FPs]),
+
+ %% Start daemon with the public keys that we got fingerprints from
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"}]),
+
+ FP_check_fun = fun(PeerName, FP) ->
+ ct:pal("PeerName = ~p, FP = ~p",[PeerName,FP]),
+ HostCheck = (Host == PeerName),
+ FPCheck = lists:member(FP, FPs),
+ ct:log("check ~p == ~p (~p) and ~n~p in ~p (~p)~n",
+ [PeerName,Host,HostCheck,FP,FPs,FPCheck]),
+ HostCheck and FPCheck
+ end,
+
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts,
+ case HashAlg of
+ old -> FP_check_fun;
+ _ -> {HashAlg, FP_check_fun}
+ end},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
%%% Test connect_timeout option in ssh:connect/4
ssh_connect_timeout(_Config) ->
ConnTimeout = 2000,
@@ -974,7 +1081,14 @@ ssh_connect_negtimeout(Config, Parallel) ->
ct:sleep(round(Factor * NegTimeOut)),
case inet:sockname(Socket) of
- {ok,_} -> ct:fail("Socket not closed");
+ {ok,_} ->
+ %% Give it another chance...
+ ct:log("Sleep more...",[]),
+ ct:sleep(round(Factor * NegTimeOut)),
+ case inet:sockname(Socket) of
+ {ok,_} -> ct:fail("Socket not closed");
+ {error,_} -> ok
+ end;
{error,_} -> ok
end.
@@ -1003,7 +1117,7 @@ ssh_connect_nonegtimeout_connected(Config, Parallel) ->
ct:sleep(500),
IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir),
+ Shell = ssh_test_lib:start_shell(Port, IO, [{user_dir,UserDir}]),
receive
Error = {'EXIT', _, _} ->
ct:log("~p",[Error]),
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE.erl b/lib/ssh/test/ssh_renegotiate_SUITE.erl
index b10ec3707f..74bbc291b2 100644
--- a/lib/ssh/test/ssh_renegotiate_SUITE.erl
+++ b/lib/ssh/test/ssh_renegotiate_SUITE.erl
@@ -92,11 +92,11 @@ rekey(Config) ->
ConnectionRef =
ssh_test_lib:std_connect(Config, Host, Port,
[{rekey_limit, 0}]),
- Kex1 = get_kex_init(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
receive
after ?REKEY_DATA_TMO ->
%%By this time rekeying would have been done
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
false = (Kex2 == Kex1),
ssh:close(ConnectionRef),
ssh:stop_daemon(Pid)
@@ -120,31 +120,31 @@ rekey_limit(Config) ->
{max_random_length_padding,0}]),
{ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
- Kex1 = get_kex_init(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
timer:sleep(?REKEY_DATA_TMO),
- Kex1 = get_kex_init(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
Data = lists:duplicate(159000,1),
ok = ssh_sftp:write_file(SftpPid, DataFile, Data),
timer:sleep(?REKEY_DATA_TMO),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
false = (Kex2 == Kex1),
timer:sleep(?REKEY_DATA_TMO),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
ok = ssh_sftp:write_file(SftpPid, DataFile, "hi\n"),
timer:sleep(?REKEY_DATA_TMO),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
false = (Kex2 == Kex1),
timer:sleep(?REKEY_DATA_TMO),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
ssh_sftp:stop_channel(SftpPid),
ssh:close(ConnectionRef),
@@ -169,7 +169,7 @@ renegotiate1(Config) ->
ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
{ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
- Kex1 = get_kex_init(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
{ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
@@ -181,7 +181,7 @@ renegotiate1(Config) ->
timer:sleep(2000),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
false = (Kex2 == Kex1),
@@ -208,7 +208,7 @@ renegotiate2(Config) ->
ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
{ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
- Kex1 = get_kex_init(ConnectionRef),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
{ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
@@ -223,7 +223,7 @@ renegotiate2(Config) ->
timer:sleep(2000),
- Kex2 = get_kex_init(ConnectionRef),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
false = (Kex2 == Kex1),
@@ -235,19 +235,3 @@ renegotiate2(Config) ->
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
-%% get_kex_init - helper function to get key_exchange_init_msg
-get_kex_init(Conn) ->
- %% First, validate the key exchange is complete (StateName == connected)
- {{connected,_},S} = sys:get_state(Conn),
- %% Next, walk through the elements of the #state record looking
- %% for the #ssh_msg_kexinit record. This method is robust against
- %% changes to either record. The KEXINIT message contains a cookie
- %% unique to each invocation of the key exchange procedure (RFC4253)
- SL = tuple_to_list(S),
- case lists:keyfind(ssh_msg_kexinit, 1, SL) of
- false ->
- throw(not_found);
- KexInit ->
- KexInit
- end.
-
diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl
index 19ad81e7da..70662f5d93 100644
--- a/lib/ssh/test/ssh_sftp_SUITE.erl
+++ b/lib/ssh/test/ssh_sftp_SUITE.erl
@@ -60,12 +60,16 @@ end_per_suite(_onfig) ->
groups() ->
[{not_unicode, [], [{group,erlang_server},
{group,openssh_server},
+ {group,big_recvpkt_size},
sftp_nonexistent_subsystem]},
{unicode, [], [{group,erlang_server},
{group,openssh_server},
sftp_nonexistent_subsystem]},
+ {big_recvpkt_size, [], [{group,erlang_server},
+ {group,openssh_server}]},
+
{erlang_server, [], [{group,write_read_tests},
version_option,
{group,remote_tar}]},
@@ -149,6 +153,9 @@ init_per_group(unicode, Config) ->
{skip, "Not unicode file encoding"}
end;
+init_per_group(big_recvpkt_size, Config) ->
+ [{pkt_sz,123456} | Config];
+
init_per_group(erlang_server, Config) ->
ct:comment("Begin ~p",[grps(Config)]),
PrivDir = proplists:get_value(priv_dir, Config),
@@ -257,7 +264,10 @@ init_per_testcase(Case, Config00) ->
Dog = ct:timetrap(2 * ?default_timeout),
User = proplists:get_value(user, Config0),
Passwd = proplists:get_value(passwd, Config0),
-
+ PktSzOpt = case proplists:get_value(pkt_sz, Config0) of
+ undefined -> [];
+ Sz -> [{packet_size,Sz}]
+ end,
Config =
case proplists:get_value(group,Config2) of
erlang_server ->
@@ -267,7 +277,9 @@ init_per_testcase(Case, Config00) ->
[{user, User},
{password, Passwd},
{user_interaction, false},
- {silently_accept_hosts, true}]
+ {silently_accept_hosts, true}
+ | PktSzOpt
+ ]
),
Sftp = {ChannelPid, Connection},
[{sftp, Sftp}, {watchdog, Dog} | Config2];
@@ -278,7 +290,9 @@ init_per_testcase(Case, Config00) ->
{ok, ChannelPid, Connection} =
ssh_sftp:start_channel(Host,
[{user_interaction, false},
- {silently_accept_hosts, true}]),
+ {silently_accept_hosts, true}
+ | PktSzOpt
+ ]),
Sftp = {ChannelPid, Connection},
[{sftp, Sftp}, {watchdog, Dog} | Config2]
end,
diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl
index 6fd401d182..f93237f3e7 100644
--- a/lib/ssh/test/ssh_test_lib.erl
+++ b/lib/ssh/test/ssh_test_lib.erl
@@ -127,24 +127,19 @@ std_simple_exec(Host, Port, Config, Opts) ->
ssh:close(ConnectionRef).
-start_shell(Port, IOServer, UserDir) ->
- start_shell(Port, IOServer, UserDir, []).
-
-start_shell(Port, IOServer, UserDir, Options) ->
- spawn_link(?MODULE, init_shell, [Port, IOServer, [{user_dir, UserDir}|Options]]).
-
start_shell(Port, IOServer) ->
- spawn_link(?MODULE, init_shell, [Port, IOServer, []]).
+ start_shell(Port, IOServer, []).
-init_shell(Port, IOServer, UserDir) ->
- Host = hostname(),
- Options = [{user_interaction, false}, {silently_accept_hosts,
- true}] ++ UserDir,
- group_leader(IOServer, self()),
- loop_shell(Host, Port, Options).
+start_shell(Port, IOServer, ExtraOptions) ->
+ spawn_link(
+ fun() ->
+ Host = hostname(),
+ Options = [{user_interaction, false},
+ {silently_accept_hosts,true} | ExtraOptions],
+ group_leader(IOServer, self()),
+ ssh:shell(Host, Port, Options)
+ end).
-loop_shell(Host, Port, Options) ->
- ssh:shell(Host, Port, Options).
start_io_server() ->
spawn_link(?MODULE, init_io_server, [self()]).
@@ -802,3 +797,40 @@ busy_wait(Nus, T0) ->
end.
%%%----------------------------------------------------------------
+%% get_kex_init - helper function to get key_exchange_init_msg
+
+get_kex_init(Conn) ->
+ Ref = make_ref(),
+ {ok,TRef} = timer:send_after(15000, {reneg_timeout,Ref}),
+ get_kex_init(Conn, Ref, TRef).
+
+get_kex_init(Conn, Ref, TRef) ->
+ %% First, validate the key exchange is complete (StateName == connected)
+ case sys:get_state(Conn) of
+ {{connected,_}, S} ->
+ timer:cancel(TRef),
+ %% Next, walk through the elements of the #state record looking
+ %% for the #ssh_msg_kexinit record. This method is robust against
+ %% changes to either record. The KEXINIT message contains a cookie
+ %% unique to each invocation of the key exchange procedure (RFC4253)
+ SL = tuple_to_list(S),
+ case lists:keyfind(ssh_msg_kexinit, 1, SL) of
+ false ->
+ throw(not_found);
+ KexInit ->
+ KexInit
+ end;
+
+ {OtherState, S} ->
+ ct:log("Not in 'connected' state: ~p",[OtherState]),
+ receive
+ {reneg_timeout,Ref} ->
+ ct:log("S = ~p", [S]),
+ ct:fail(reneg_timeout)
+ after 0 ->
+ timer:sleep(100), % If renegotiation is complete we do not
+ % want to exit on the reneg_timeout
+ get_kex_init(Conn, Ref, TRef)
+ end
+ end.
+
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl
index f481e9c1ce..86c3d5de26 100644
--- a/lib/ssh/test/ssh_to_openssh_SUITE.erl
+++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl
@@ -29,6 +29,7 @@
-define(TIMEOUT, 50000).
-define(SSH_DEFAULT_PORT, 22).
+-define(REKEY_DATA_TMO, 65000).
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
@@ -55,7 +56,8 @@ groups() ->
erlang_client_openssh_server_publickey_rsa,
erlang_client_openssh_server_password,
erlang_client_openssh_server_kexs,
- erlang_client_openssh_server_nonexistent_subsystem
+ erlang_client_openssh_server_nonexistent_subsystem,
+ erlang_client_openssh_server_renegotiate
]},
{erlang_server, [], [erlang_server_openssh_client_public_key_dsa,
erlang_server_openssh_client_public_key_rsa,
@@ -105,6 +107,11 @@ init_per_testcase(erlang_server_openssh_client_public_key_rsa, Config) ->
chk_key(sshc, 'ssh-rsa', ".ssh/id_rsa", Config);
init_per_testcase(erlang_client_openssh_server_publickey_dsa, Config) ->
chk_key(sshd, 'ssh-dss', ".ssh/id_dsa", Config);
+init_per_testcase(erlang_server_openssh_client_renegotiate, Config) ->
+ case os:type() of
+ {unix,_} -> ssh:start(), Config;
+ Type -> {skip, io_lib:format("Unsupported test on ~p",[Type])}
+ end;
init_per_testcase(_TestCase, Config) ->
ssh:start(),
Config.
@@ -146,7 +153,7 @@ erlang_shell_client_openssh_server(Config) when is_list(Config) ->
IO = ssh_test_lib:start_io_server(),
Shell = ssh_test_lib:start_shell(?SSH_DEFAULT_PORT, IO),
IO ! {input, self(), "echo Hej\n"},
- receive_hej(),
+ receive_data("Hej"),
IO ! {input, self(), "exit\n"},
receive_logout(),
receive_normal_exit(Shell).
@@ -393,33 +400,103 @@ erlang_server_openssh_client_renegotiate(Config) ->
SystemDir = proplists:get_value(data_dir, Config),
PrivDir = proplists:get_value(priv_dir, Config),
KnownHosts = filename:join(PrivDir, "known_hosts"),
+
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
{public_key_alg, PubKeyAlg},
{failfun, fun ssh_test_lib:failfun/2}]),
-
ct:sleep(500),
+ RenegLimitK = 3,
DataFile = filename:join(PrivDir, "renegotiate_openssh_client.data"),
- Data = lists:duplicate(32000, $a),
+ Data = lists:duplicate(trunc(1.1*RenegLimitK*1024), $a),
ok = file:write_file(DataFile, Data),
Cmd = "ssh -p " ++ integer_to_list(Port) ++
" -o UserKnownHostsFile=" ++ KnownHosts ++
- " -o RekeyLimit=20K" ++
+ " -o RekeyLimit=" ++ integer_to_list(RenegLimitK) ++"K" ++
" " ++ Host ++ " < " ++ DataFile,
OpenSsh = ssh_test_lib:open_port({spawn, Cmd}),
Expect = fun({data,R}) ->
- try lists:prefix(binary_to_list(R), Data)
+ try
+ NonAlphaChars = [C || C<-lists:seq(1,255),
+ not lists:member(C,lists:seq($a,$z)),
+ not lists:member(C,lists:seq($A,$Z))
+ ],
+ Lines = string:tokens(binary_to_list(R), NonAlphaChars),
+ lists:any(fun(L) -> length(L)>1 andalso lists:prefix(L, Data) end,
+ Lines)
catch
_:_ -> false
end;
+
+ ({exit_status,E}) when E=/=0 ->
+ ct:log("exit_status ~p",[E]),
+ throw({skip,"exit status"});
+
(_) ->
false
end,
+
+ try
+ ssh_test_lib:rcv_expected(Expect, OpenSsh, ?TIMEOUT)
+ of
+ _ ->
+ %% Unfortunatly we can't check that there has been a renegotiation, just trust OpenSSH.
+ ssh:stop_daemon(Pid)
+ catch
+ throw:{skip,R} -> {skip,R}
+ end.
- ssh_test_lib:rcv_expected(Expect, OpenSsh, ?TIMEOUT),
- ssh:stop_daemon(Pid).
+%%--------------------------------------------------------------------
+erlang_client_openssh_server_renegotiate(_Config) ->
+ process_flag(trap_exit, true),
+
+ IO = ssh_test_lib:start_io_server(),
+ Ref = make_ref(),
+ Parent = self(),
+
+ Shell =
+ spawn_link(
+ fun() ->
+ Host = ssh_test_lib:hostname(),
+ Options = [{user_interaction, false},
+ {silently_accept_hosts,true}],
+ group_leader(IO, self()),
+ {ok, ConnRef} = ssh:connect(Host, ?SSH_DEFAULT_PORT, Options),
+ case ssh_connection:session_channel(ConnRef, infinity) of
+ {ok,ChannelId} ->
+ success = ssh_connection:ptty_alloc(ConnRef, ChannelId, []),
+ Args = [{channel_cb, ssh_shell},
+ {init_args,[ConnRef, ChannelId]},
+ {cm, ConnRef}, {channel_id, ChannelId}],
+ {ok, State} = ssh_channel:init([Args]),
+ Parent ! {ok, Ref, ConnRef},
+ ssh_channel:enter_loop(State);
+ Error ->
+ Parent ! {error, Ref, Error}
+ end,
+ receive
+ nothing -> ok
+ end
+ end),
+
+ receive
+ {error, Ref, Error} ->
+ ct:fail("Error=~p",[Error]);
+ {ok, Ref, ConnectionRef} ->
+ IO ! {input, self(), "echo Hej1\n"},
+ receive_data("Hej1"),
+ Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
+ ssh_connection_handler:renegotiate(ConnectionRef),
+ IO ! {input, self(), "echo Hej2\n"},
+ receive_data("Hej2"),
+ Kex2 = ssh_test_lib:get_kex_init(ConnectionRef),
+ IO ! {input, self(), "exit\n"},
+ receive_logout(),
+ receive_normal_exit(Shell),
+ true = (Kex1 =/= Kex2)
+ end.
%%--------------------------------------------------------------------
erlang_client_openssh_server_password() ->
@@ -476,27 +553,24 @@ erlang_client_openssh_server_nonexistent_subsystem(Config) when is_list(Config)
%%--------------------------------------------------------------------
%%% Internal functions -----------------------------------------------
%%--------------------------------------------------------------------
-receive_hej() ->
+receive_data(Data) ->
receive
- <<"Hej", _binary>> = Hej ->
- ct:log("Expected result: ~p~n", [Hej]);
- <<"Hej\n", _binary>> = Hej ->
- ct:log("Expected result: ~p~n", [Hej]);
- <<"Hej\r\n", _/binary>> = Hej ->
- ct:log("Expected result: ~p~n", [Hej]);
- Info ->
- Lines = binary:split(Info, [<<"\r\n">>], [global]),
- case lists:member(<<"Hej">>, Lines) of
+ Info when is_binary(Info) ->
+ Lines = string:tokens(binary_to_list(Info), "\r\n "),
+ case lists:member(Data, Lines) of
true ->
ct:log("Expected result found in lines: ~p~n", [Lines]),
ok;
false ->
ct:log("Extra info: ~p~n", [Info]),
- receive_hej()
- end
+ receive_data(Data)
+ end;
+ Other ->
+ ct:log("Unexpected: ~p",[Other]),
+ receive_data(Data)
after
30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
- end.
+ end.
receive_logout() ->
receive
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 68f2f97b6e..edc7e0d8b2 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -170,6 +170,14 @@
<tag><c>SNIfun::fun()</c></tag>
<item><p><c>= fun(ServerName :: string()) -> [ssl_option()]</c></p></item>
+ <tag><c>named_curve() =</c></tag>
+ <item><p><c>sect571r1 | sect571k1 | secp521r1 | brainpoolP512r1
+ | sect409k1 | sect409r1 | brainpoolP384r1 | secp384r1
+ | sect283k1 | sect283r1 | brainpoolP256r1 | secp256k1 | secp256r1
+ | sect239k1 | sect233k1 | sect233r1 | secp224k1 | secp224r1
+ | sect193r1 | sect193r2 | secp192k1 | secp192r1 | sect163k1
+ | sect163r1 | sect163r2 | secp160k1 | secp160r1 | secp160r2</c></p></item>
+
</taglist>
</section>
@@ -217,6 +225,11 @@
Anonymous cipher suites are supported for testing purposes
only and are not be used when security matters.</p></item>
+ <tag><c>{eccs, [named_curve()]}</c></tag>
+ <item><p> Allows to specify the order of preference for named curves
+ and to restrict their usage when using a cipher suite supporting them.
+ </p></item>
+
<tag><c>{secure_renegotiate, boolean()}</c></tag>
<item><p>Specifies if to reject renegotiation attempt that does
not live up to
@@ -751,6 +764,11 @@ fun(srp, Username :: string(), UserState :: term()) ->
(the default), use the client's preference.
</item>
+ <tag><c>{honor_ecc_order, boolean()}</c></tag>
+ <item>If true, use the server's preference for ECC curve selection. If false
+ (the default), use the client's preference.
+ </item>
+
<tag><c>{signature_algs, [{hash(), ecdsa | rsa | dsa}]}</c></tag>
<item><p> The algorithms specified by
this option will be the ones accepted by the server in a signature algorithm
@@ -804,6 +822,17 @@ fun(srp, Username :: string(), UserState :: term()) ->
</func>
<func>
+ <name>eccs() -></name>
+ <name>eccs(protocol()) -> [named_curve()]</name>
+ <fsummary>Returns a list of supported ECCs.</fsummary>
+
+ <desc><p>Returns a list of supported ECCs. <c>eccs()</c>
+ is equivalent to calling <c>eccs(Protocol)</c> with all
+ supported protocols and then deduplicating the output.</p>
+ </desc>
+ </func>
+
+ <func>
<name>clear_pem_cache() -> ok </name>
<fsummary> Clears the pem cache</fsummary>
@@ -898,7 +927,7 @@ fun(srp, Username :: string(), UserState :: term()) ->
<fsummary>Returns all the connection information.
</fsummary>
<type>
- <v>Item = protocol | cipher_suite | sni_hostname | atom()</v>
+ <v>Item = protocol | cipher_suite | sni_hostname | ecc | atom()</v>
<d>Meaningful atoms, not specified above, are the ssl option names.</d>
<v>Result = [{Item::atom(), Value::term()}]</v>
<v>Reason = term()</v>
diff --git a/lib/ssl/doc/src/ssl_distribution.xml b/lib/ssl/doc/src/ssl_distribution.xml
index 1150043e76..61f88e3860 100644
--- a/lib/ssl/doc/src/ssl_distribution.xml
+++ b/lib/ssl/doc/src/ssl_distribution.xml
@@ -43,7 +43,7 @@
Erlang node distributed, <c>net_kernel</c> uses this module to
set up listen ports and connections.</p>
- <p>In the SSL application, an exra distribution
+ <p>In the SSL application, an extra distribution
module, <c>inet_tls_dist</c>, can be used as an
alternative. All distribution connections will use SSL and
all participating Erlang nodes in a distributed system must use
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 27b753af2e..aa62ab8865 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -38,7 +38,7 @@
getopts/2, setopts/2, getstat/1, getstat/2
]).
%% SSL/TLS protocol handling
--export([cipher_suites/0, cipher_suites/1,
+-export([cipher_suites/0, cipher_suites/1, eccs/0, eccs/1,
connection_info/1, versions/0, session_info/1, format_error/1,
renegotiate/1, prf/5, negotiated_protocol/1, negotiated_next_protocol/1,
connection_information/1, connection_information/2]).
@@ -420,6 +420,33 @@ cipher_suites(all) ->
[ssl_cipher:erl_suite_definition(Suite) || Suite <- available_suites(all)].
%%--------------------------------------------------------------------
+-spec eccs() -> tls_v1:curves().
+%% Description: returns all supported curves across all versions
+%%--------------------------------------------------------------------
+eccs() ->
+ Curves = tls_v1:ecc_curves(all), % only tls_v1 has named curves right now
+ eccs_filter_supported(Curves).
+
+%%--------------------------------------------------------------------
+-spec eccs(tls_record:tls_version() | tls_record:tls_atom_version()) ->
+ tls_v1:curves().
+%% Description: returns the curves supported for a given version of
+%% ssl/tls.
+%%--------------------------------------------------------------------
+eccs({3,0}) ->
+ [];
+eccs({3,_}) ->
+ Curves = tls_v1:ecc_curves(all),
+ eccs_filter_supported(Curves);
+eccs(AtomVersion) when is_atom(AtomVersion) ->
+ eccs(tls_record:protocol_version(AtomVersion)).
+
+eccs_filter_supported(Curves) ->
+ CryptoCurves = crypto:ec_curves(),
+ lists:filter(fun(Curve) -> proplists:get_bool(Curve, CryptoCurves) end,
+ Curves).
+
+%%--------------------------------------------------------------------
-spec getopts(#sslsocket{}, [gen_tcp:option_name()]) ->
{ok, [gen_tcp:option()]} | {error, reason()}.
%%
@@ -647,6 +674,8 @@ do_connect(Address, Port,
end.
%% Handle extra ssl options given to ssl_accept
+-spec handle_options([any()], #ssl_options{}) -> #ssl_options{}
+ ; ([any()], client | server) -> {ok, #config{}}.
handle_options(Opts0, #ssl_options{protocol = Protocol, cacerts = CaCerts0,
cacertfile = CaCertFile0} = InheritedSslOpts) ->
RecordCB = record_cb(Protocol),
@@ -725,6 +754,8 @@ handle_options(Opts0, Role) ->
srp_identity = handle_option(srp_identity, Opts, undefined),
ciphers = handle_cipher_option(proplists:get_value(ciphers, Opts, []),
RecordCb:highest_protocol_version(Versions)),
+ eccs = handle_eccs_option(proplists:get_value(eccs, Opts, eccs()),
+ RecordCb:highest_protocol_version(Versions)),
signature_algs = handle_hashsigns_option(proplists:get_value(signature_algs, Opts,
default_option_role(server,
tls_v1:default_signature_algs(Versions), Role)),
@@ -755,6 +786,9 @@ handle_options(Opts0, Role) ->
honor_cipher_order = handle_option(honor_cipher_order, Opts,
default_option_role(server, false, Role),
server, Role),
+ honor_ecc_order = handle_option(honor_ecc_order, Opts,
+ default_option_role(server, false, Role),
+ server, Role),
protocol = proplists:get_value(protocol, Opts, tls),
padding_check = proplists:get_value(padding_check, Opts, true),
beast_mitigation = handle_option(beast_mitigation, Opts, one_n_minus_one),
@@ -780,7 +814,7 @@ handle_options(Opts0, Role) ->
alpn_preferred_protocols, next_protocols_advertised,
client_preferred_next_protocols, log_alert,
server_name_indication, honor_cipher_order, padding_check, crl_check, crl_cache,
- fallback, signature_algs, beast_mitigation, v2_hello_compatible],
+ fallback, signature_algs, eccs, honor_ecc_order, beast_mitigation, v2_hello_compatible],
SockOpts = lists:foldl(fun(Key, PropList) ->
proplists:delete(Key, PropList)
@@ -1010,6 +1044,8 @@ validate_option(sni_fun, Fun) when is_function(Fun) ->
Fun;
validate_option(honor_cipher_order, Value) when is_boolean(Value) ->
Value;
+validate_option(honor_ecc_order, Value) when is_boolean(Value) ->
+ Value;
validate_option(padding_check, Value) when is_boolean(Value) ->
Value;
validate_option(fallback, Value) when is_boolean(Value) ->
@@ -1164,6 +1200,14 @@ binary_cipher_suites(Version, Ciphers0) ->
Ciphers = [ssl_cipher:openssl_suite(C) || C <- string:tokens(Ciphers0, ":")],
binary_cipher_suites(Version, Ciphers).
+handle_eccs_option(Value, {_Major, Minor}) when is_list(Value) ->
+ try tls_v1:ecc_curves(Minor, Value) of
+ Curves -> #elliptic_curves{elliptic_curve_list = Curves}
+ catch
+ exit:_ -> throw({error, {options, {eccs, Value}}});
+ error:_ -> throw({error, {options, {eccs, Value}}})
+ end.
+
unexpected_format(Error) ->
lists:flatten(io_lib:format("Unexpected error: ~p", [Error])).
@@ -1334,6 +1378,14 @@ new_ssl_options([{server_name_indication, Value} | Rest], #ssl_options{} = Opts,
new_ssl_options(Rest, Opts#ssl_options{server_name_indication = validate_option(server_name_indication, Value)}, RecordCB);
new_ssl_options([{honor_cipher_order, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
new_ssl_options(Rest, Opts#ssl_options{honor_cipher_order = validate_option(honor_cipher_order, Value)}, RecordCB);
+new_ssl_options([{honor_ecc_order, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
+ new_ssl_options(Rest, Opts#ssl_options{honor_ecc_order = validate_option(honor_ecc_order, Value)}, RecordCB);
+new_ssl_options([{eccs, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
+ new_ssl_options(Rest,
+ Opts#ssl_options{eccs =
+ handle_eccs_option(Value, RecordCB:highest_protocol_version())
+ },
+ RecordCB);
new_ssl_options([{signature_algs, Value} | Rest], #ssl_options{} = Opts, RecordCB) ->
new_ssl_options(Rest,
Opts#ssl_options{signature_algs =
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 08fca76123..b6e4d5b433 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -1172,14 +1172,23 @@ handle_alert(#alert{level = ?WARNING} = Alert, StateName,
%%% Internal functions
%%--------------------------------------------------------------------
connection_info(#state{sni_hostname = SNIHostname,
- session = #session{cipher_suite = CipherSuite},
+ session = #session{cipher_suite = CipherSuite, ecc = ECCCurve},
protocol_cb = Connection,
negotiated_version = {_,_} = Version,
ssl_options = Opts}) ->
RecordCB = record_cb(Connection),
+ CipherSuiteDef = ssl_cipher:erl_suite_definition(CipherSuite),
+ IsNamedCurveSuite = lists:member(element(1,CipherSuiteDef),
+ [ecdh_ecdsa, ecdhe_ecdsa, ecdh_anon]),
+ CurveInfo = case ECCCurve of
+ {namedCurve, Curve} when IsNamedCurveSuite ->
+ [{ecc, {named_curve, pubkey_cert_records:namedCurves(Curve)}}];
+ _ ->
+ []
+ end,
[{protocol, RecordCB:protocol_version(Version)},
- {cipher_suite, ssl_cipher:erl_suite_definition(CipherSuite)},
- {sni_hostname, SNIHostname}] ++ ssl_options_list(Opts).
+ {cipher_suite, CipherSuiteDef},
+ {sni_hostname, SNIHostname} | CurveInfo] ++ ssl_options_list(Opts).
do_server_hello(Type, #hello_extensions{next_protocol_negotiation = NextProtocols} =
ServerHelloExt,
@@ -1741,12 +1750,13 @@ calculate_secret(#server_dh_params{dh_p = Prime, dh_g = Base,
Connection, certify, certify);
calculate_secret(#server_ecdh_params{curve = ECCurve, public = ECServerPubKey},
- State, Connection) ->
+ State=#state{session=Session}, Connection) ->
ECDHKeys = public_key:generate_key(ECCurve),
PremasterSecret =
ssl_handshake:premaster_secret(#'ECPoint'{point = ECServerPubKey}, ECDHKeys),
calculate_master_secret(PremasterSecret,
- State#state{diffie_hellman_keys = ECDHKeys},
+ State#state{diffie_hellman_keys = ECDHKeys,
+ session = Session#session{ecc = ECCurve}},
Connection, certify, certify);
calculate_secret(#server_psk_params{
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 5b51ac0916..4acc745c5f 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -70,7 +70,7 @@
%% Extensions handling
-export([client_hello_extensions/6,
handle_client_hello_extensions/9, %% Returns server hello extensions
- handle_server_hello_extensions/9, select_curve/2
+ handle_server_hello_extensions/9, select_curve/2, select_curve/3
]).
%% MISC
@@ -120,11 +120,13 @@ server_hello_done() ->
#server_hello_done{}.
client_hello_extensions(Host, Version, CipherSuites,
- #ssl_options{signature_algs = SupportedHashSigns, versions = AllVersions} = SslOpts, ConnectionStates, Renegotiation) ->
+ #ssl_options{signature_algs = SupportedHashSigns,
+ eccs = SupportedECCs,
+ versions = AllVersions} = SslOpts, ConnectionStates, Renegotiation) ->
{EcPointFormats, EllipticCurves} =
case advertises_ec_ciphers(lists:map(fun ssl_cipher:suite_definition/1, CipherSuites)) of
true ->
- client_ecc_extensions(tls_v1, Version);
+ client_ecc_extensions(SupportedECCs);
false ->
{undefined, undefined}
end,
@@ -1169,8 +1171,9 @@ select_session(SuggestedSessionId, CipherSuites, HashSigns, Compressions, Port,
{resumed, Resumed}
end.
-supported_ecc({Major, Minor} = Version) when ((Major == 3) and (Minor >= 1)) orelse (Major > 3) ->
- Curves = tls_v1:ecc_curves(Version),
+%% Deprecated?
+supported_ecc({Major, Minor}) when ((Major == 3) and (Minor >= 1)) orelse (Major > 3) ->
+ Curves = tls_v1:ecc_curves(Minor),
#elliptic_curves{elliptic_curve_list = Curves};
supported_ecc(_) ->
#elliptic_curves{elliptic_curve_list = []}.
@@ -1454,12 +1457,12 @@ srp_user(#ssl_options{srp_identity = {UserName, _}}) ->
srp_user(_) ->
undefined.
-client_ecc_extensions(Module, Version) ->
+client_ecc_extensions(SupportedECCs) ->
CryptoSupport = proplists:get_value(public_keys, crypto:supports()),
case proplists:get_bool(ecdh, CryptoSupport) of
true ->
EcPointFormats = #ec_point_formats{ec_point_format_list = [?ECPOINT_UNCOMPRESSED]},
- EllipticCurves = #elliptic_curves{elliptic_curve_list = Module:ecc_curves(Version)},
+ EllipticCurves = SupportedECCs,
{EcPointFormats, EllipticCurves};
_ ->
{undefined, undefined}
@@ -1493,22 +1496,34 @@ advertises_ec_ciphers([{ecdh_anon, _,_,_} | _]) ->
true;
advertises_ec_ciphers([_| Rest]) ->
advertises_ec_ciphers(Rest).
-select_curve(#elliptic_curves{elliptic_curve_list = ClientCurves},
- #elliptic_curves{elliptic_curve_list = ServerCurves}) ->
- select_curve(ClientCurves, ServerCurves);
-select_curve(undefined, _) ->
+
+select_curve(Client, Server) ->
+ select_curve(Client, Server, false).
+
+select_curve(#elliptic_curves{elliptic_curve_list = ClientCurves},
+ #elliptic_curves{elliptic_curve_list = ServerCurves},
+ ServerOrder) ->
+ case ServerOrder of
+ false ->
+ select_shared_curve(ClientCurves, ServerCurves);
+ true ->
+ select_shared_curve(ServerCurves, ClientCurves)
+ end;
+select_curve(undefined, _, _) ->
%% Client did not send ECC extension use default curve if
%% ECC cipher is negotiated
- {namedCurve, ?secp256r1};
-select_curve(_, []) ->
+ {namedCurve, ?secp256r1}.
+
+select_shared_curve([], _) ->
no_curve;
-select_curve(Curves, [Curve| Rest]) ->
+select_shared_curve([Curve | Rest], Curves) ->
case lists:member(Curve, Curves) of
true ->
{namedCurve, Curve};
false ->
- select_curve(Curves, Rest)
+ select_shared_curve(Rest, Curves)
end.
+
%% RFC 6066, Section 3: Currently, the only server names supported are
%% DNS hostnames
sni(_, disable) ->
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index c19c1787ff..487d1fa096 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -140,6 +140,8 @@
crl_check :: boolean() | peer | best_effort,
crl_cache,
signature_algs,
+ eccs,
+ honor_ecc_order :: boolean(),
v2_hello_compatible :: boolean()
}).
diff --git a/lib/ssl/src/tls_handshake.erl b/lib/ssl/src/tls_handshake.erl
index a2486bf752..2bd103c18a 100644
--- a/lib/ssl/src/tls_handshake.erl
+++ b/lib/ssl/src/tls_handshake.erl
@@ -160,13 +160,15 @@ handle_client_hello(Version, #client_hello{session_id = SugesstedId,
extensions = #hello_extensions{elliptic_curves = Curves,
signature_algs = ClientHashSigns} = HelloExt},
#ssl_options{versions = Versions,
- signature_algs = SupportedHashSigns} = SslOpts,
+ signature_algs = SupportedHashSigns,
+ eccs = SupportedECCs,
+ honor_ecc_order = ECCOrder} = SslOpts,
{Port, Session0, Cache, CacheCb, ConnectionStates0, Cert, _}, Renegotiation) ->
case tls_record:is_acceptable_version(Version, Versions) of
true ->
AvailableHashSigns = ssl_handshake:available_signature_algs(
ClientHashSigns, SupportedHashSigns, Cert, Version),
- ECCCurve = ssl_handshake:select_curve(Curves, ssl_handshake:supported_ecc(Version)),
+ ECCCurve = ssl_handshake:select_curve(Curves, SupportedECCs, ECCOrder),
{Type, #session{cipher_suite = CipherSuite} = Session1}
= ssl_handshake:select_session(SugesstedId, CipherSuites, AvailableHashSigns, Compressions,
Port, Session0#session{ecc = ECCCurve}, Version,
diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl
index 711db77708..7f24ce5192 100644
--- a/lib/ssl/src/tls_v1.erl
+++ b/lib/ssl/src/tls_v1.erl
@@ -31,9 +31,18 @@
-export([master_secret/4, finished/5, certificate_verify/3, mac_hash/7,
setup_keys/8, suites/1, prf/5,
- ecc_curves/1, oid_to_enum/1, enum_to_oid/1,
+ ecc_curves/1, ecc_curves/2, oid_to_enum/1, enum_to_oid/1,
default_signature_algs/1, signature_algs/2]).
+-type named_curve() :: sect571r1 | sect571k1 | secp521r1 | brainpoolP512r1 |
+ sect409k1 | sect409r1 | brainpoolP384r1 | secp384r1 |
+ sect283k1 | sect283r1 | brainpoolP256r1 | secp256k1 | secp256r1 |
+ sect239k1 | sect233k1 | sect233r1 | secp224k1 | secp224r1 |
+ sect193r1 | sect193r2 | secp192k1 | secp192r1 | sect163k1 |
+ sect163r1 | sect163r2 | secp160k1 | secp160r1 | secp160r2.
+-type curves() :: [named_curve()].
+-export_type([curves/0, named_curve/0]).
+
%%====================================================================
%% Internal application API
%%====================================================================
@@ -399,13 +408,20 @@ is_pair(Hash, rsa, Hashs) ->
lists:member(Hash, AtLeastMd5).
%% list ECC curves in prefered order
-ecc_curves(_Minor) ->
- TLSCurves = [sect571r1,sect571k1,secp521r1,brainpoolP512r1,
- sect409k1,sect409r1,brainpoolP384r1,secp384r1,
- sect283k1,sect283r1,brainpoolP256r1,secp256k1,secp256r1,
- sect239k1,sect233k1,sect233r1,secp224k1,secp224r1,
- sect193r1,sect193r2,secp192k1,secp192r1,sect163k1,
- sect163r1,sect163r2,secp160k1,secp160r1,secp160r2],
+-spec ecc_curves(1..3 | all) -> [named_curve()].
+ecc_curves(all) ->
+ [sect571r1,sect571k1,secp521r1,brainpoolP512r1,
+ sect409k1,sect409r1,brainpoolP384r1,secp384r1,
+ sect283k1,sect283r1,brainpoolP256r1,secp256k1,secp256r1,
+ sect239k1,sect233k1,sect233r1,secp224k1,secp224r1,
+ sect193r1,sect193r2,secp192k1,secp192r1,sect163k1,
+ sect163r1,sect163r2,secp160k1,secp160r1,secp160r2];
+ecc_curves(Minor) ->
+ TLSCurves = ecc_curves(all),
+ ecc_curves(Minor, TLSCurves).
+
+-spec ecc_curves(1..3, [named_curve()]) -> [named_curve()].
+ecc_curves(_Minor, TLSCurves) ->
CryptoCurves = crypto:ec_curves(),
lists:foldr(fun(Curve, Curves) ->
case proplists:get_bool(Curve, CryptoCurves) of
@@ -414,6 +430,7 @@ ecc_curves(_Minor) ->
end
end, [], TLSCurves).
+
%% ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005)
oid_to_enum(?sect163k1) -> 1;
oid_to_enum(?sect163r1) -> 2;
diff --git a/lib/ssl/test/ssl_ECC_SUITE.erl b/lib/ssl/test/ssl_ECC_SUITE.erl
index 258922d128..76999185b6 100644
--- a/lib/ssl/test/ssl_ECC_SUITE.erl
+++ b/lib/ssl/test/ssl_ECC_SUITE.erl
@@ -46,7 +46,7 @@ groups() ->
{'tlsv1', [], all_versions_groups()},
{'erlang_server', [], key_cert_combinations()},
{'erlang_client', [], key_cert_combinations()},
- {'erlang', [], key_cert_combinations() ++ misc()}
+ {'erlang', [], key_cert_combinations() ++ misc() ++ ecc_negotiation()}
].
all_versions_groups ()->
@@ -68,6 +68,23 @@ key_cert_combinations() ->
misc()->
[client_ecdsa_server_ecdsa_with_raw_key].
+ecc_negotiation() ->
+ [ecc_default_order,
+ ecc_default_order_custom_curves,
+ ecc_client_order,
+ ecc_client_order_custom_curves,
+ ecc_unknown_curve,
+ client_ecdh_server_ecdh_ecc_server_custom,
+ client_rsa_server_ecdh_ecc_server_custom,
+ client_ecdh_server_rsa_ecc_server_custom,
+ client_rsa_server_rsa_ecc_server_custom,
+ client_ecdsa_server_ecdsa_ecc_server_custom,
+ client_ecdsa_server_rsa_ecc_server_custom,
+ client_rsa_server_ecdsa_ecc_server_custom,
+ client_ecdsa_server_ecdsa_ecc_client_custom,
+ client_rsa_server_ecdsa_ecc_client_custom
+ ].
+
%%--------------------------------------------------------------------
init_per_suite(Config0) ->
end_per_suite(Config0),
@@ -218,6 +235,132 @@ client_ecdsa_server_ecdsa_with_raw_key(Config) when is_list(Config) ->
check_result(Server, SType, Client, CType),
close(Server, Client).
+ecc_default_order(Config) ->
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ ECCOpts = [],
+ case supported_eccs([{eccs, [sect571r1]}]) of
+ true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+ecc_default_order_custom_curves(Config) ->
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ ECCOpts = [{eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+ecc_client_order(Config) ->
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ ECCOpts = [{honor_ecc_order, false}],
+ case supported_eccs([{eccs, [sect571r1]}]) of
+ true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+ecc_client_order_custom_curves(Config) ->
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ ECCOpts = [{honor_ecc_order, false}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+ecc_unknown_curve(Config) ->
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ ECCOpts = [{eccs, ['123_fake_curve']}],
+ ecc_test_error(COpts, SOpts, [], ECCOpts, Config).
+
+%% We can only expect to see a named curve on a conn with
+%% a server supporting ecdsa. Otherwise the curve is selected
+%% but not used and communicated to the client?
+client_ecdh_server_ecdh_ecc_server_custom(Config) ->
+ COpts = proplists:get_value(client_ecdh_rsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdh_rsa_opts, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdh_server_rsa_ecc_server_custom(Config) ->
+ COpts = proplists:get_value(client_ecdh_rsa_opts, Config),
+ SOpts = proplists:get_value(server_opts, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_rsa_server_ecdh_ecc_server_custom(Config) ->
+ COpts = proplists:get_value(client_opts, Config),
+ SOpts = proplists:get_value(server_ecdh_rsa_opts, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_rsa_server_rsa_ecc_server_custom(Config) ->
+ COpts = proplists:get_value(client_opts, Config),
+ SOpts = proplists:get_value(server_opts, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdsa_server_ecdsa_ecc_server_custom(Config) ->
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdsa_server_rsa_ecc_server_custom(Config) ->
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_opts, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_rsa_server_ecdsa_ecc_server_custom(Config) ->
+ COpts = proplists:get_value(client_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_ecdsa_server_ecdsa_ecc_client_custom(Config) ->
+ COpts = proplists:get_value(client_ecdsa_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ ECCOpts = [{eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(secp256r1, COpts, SOpts, ECCOpts, [], Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
+client_rsa_server_ecdsa_ecc_client_custom(Config) ->
+ COpts = proplists:get_value(client_opts, Config),
+ SOpts = proplists:get_value(server_ecdsa_opts, Config),
+ ECCOpts = [{eccs, [secp256r1, sect571r1]}],
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(secp256r1, COpts, SOpts, ECCOpts, [], Config);
+ false -> {skip, "unsupported named curves"}
+ end.
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
@@ -244,6 +387,30 @@ basic_test(ClientCert, ClientKey, ClientCA, ServerCert, ServerKey, ServerCA, Con
check_result(Server, SType, Client, CType),
close(Server, Client).
+ecc_test(Expect, COpts, SOpts, CECCOpts, SECCOpts, Config) ->
+ CCA = proplists:get_value(cacertfile, COpts),
+ CCert = proplists:get_value(certfile, COpts),
+ CKey = proplists:get_value(keyfile, COpts),
+ SCA = proplists:get_value(cacertfile, SOpts),
+ SCert = proplists:get_value(certfile, SOpts),
+ SKey = proplists:get_value(keyfile, SOpts),
+ {Server, Port} = start_server_ecc(erlang, CCA, SCA, SCert, SKey, Expect, SECCOpts, Config),
+ Client = start_client_ecc(erlang, Port, SCA, CCA, CCert, CKey, Expect, CECCOpts, Config),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ close(Server, Client).
+
+ecc_test_error(COpts, SOpts, CECCOpts, SECCOpts, Config) ->
+ CCA = proplists:get_value(cacertfile, COpts),
+ CCert = proplists:get_value(certfile, COpts),
+ CKey = proplists:get_value(keyfile, COpts),
+ SCA = proplists:get_value(cacertfile, SOpts),
+ SCert = proplists:get_value(certfile, SOpts),
+ SKey = proplists:get_value(keyfile, SOpts),
+ {Server, Port} = start_server_ecc_error(erlang, CCA, SCA, SCert, SKey, SECCOpts, Config),
+ Client = start_client_ecc_error(erlang, Port, SCA, CCA, CCert, CKey, CECCOpts, Config),
+ Error = {error, {tls_alert, "insufficient security"}},
+ ssl_test_lib:check_result(Server, Error, Client, Error).
+
start_client(openssl, Port, PeerCA, OwnCa, Cert, Key, _Config) ->
CA = new_openssl_ca("openssl_client_ca", PeerCA, OwnCa),
Version = tls_record:protocol_version(tls_record:highest_protocol_version([])),
@@ -267,6 +434,31 @@ start_client(erlang, Port, PeerCA, OwnCa, Cert, Key, Config) ->
{cacertfile, CA},
{certfile, Cert}, {keyfile, Key}]}]).
+start_client_ecc(erlang, Port, PeerCA, OwnCa, Cert, Key, Expect, ECCOpts, Config) ->
+ CA = new_ca("erlang_client_ca", PeerCA, OwnCa),
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, check_ecc, [client, Expect]}},
+ {options,
+ ECCOpts ++
+ [{verify, verify_peer},
+ {cacertfile, CA},
+ {certfile, Cert}, {keyfile, Key}]}]).
+
+start_client_ecc_error(erlang, Port, PeerCA, OwnCa, Cert, Key, ECCOpts, Config) ->
+ CA = new_ca("erlang_client_ca", PeerCA, OwnCa),
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options,
+ ECCOpts ++
+ [{verify, verify_peer},
+ {cacertfile, CA},
+ {certfile, Cert}, {keyfile, Key}]}]).
+
start_server(openssl, PeerCA, OwnCa, Cert, Key, _Config) ->
CA = new_openssl_ca("openssl_server_ca", PeerCA, OwnCa),
Port = ssl_test_lib:inet_port(node()),
@@ -290,6 +482,7 @@ start_server(erlang, PeerCA, OwnCa, Cert, Key, Config) ->
[{verify, verify_peer}, {cacertfile, CA},
{certfile, Cert}, {keyfile, Key}]}]),
{Server, ssl_test_lib:inet_port(Server)}.
+
start_server_with_raw_key(erlang, PeerCA, OwnCa, Cert, Key, Config) ->
CA = new_ca("erlang_server_ca", PeerCA, OwnCa),
{_, ServerNode, _} = ssl_test_lib:run_where(Config),
@@ -303,6 +496,29 @@ start_server_with_raw_key(erlang, PeerCA, OwnCa, Cert, Key, Config) ->
{certfile, Cert}, {key, Key}]}]),
{Server, ssl_test_lib:inet_port(Server)}.
+start_server_ecc(erlang, PeerCA, OwnCa, Cert, Key, Expect, ECCOpts, Config) ->
+ CA = new_ca("erlang_server_ca", PeerCA, OwnCa),
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, check_ecc, [server, Expect]}},
+ {options,
+ ECCOpts ++
+ [{verify, verify_peer}, {cacertfile, CA},
+ {certfile, Cert}, {keyfile, Key}]}]),
+ {Server, ssl_test_lib:inet_port(Server)}.
+
+start_server_ecc_error(erlang, PeerCA, OwnCa, Cert, Key, ECCOpts, Config) ->
+ CA = new_ca("erlang_server_ca", PeerCA, OwnCa),
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options,
+ ECCOpts ++
+ [{verify, verify_peer}, {cacertfile, CA},
+ {certfile, Cert}, {keyfile, Key}]}]),
+ {Server, ssl_test_lib:inet_port(Server)}.
+
check_result(Server, erlang, Client, erlang) ->
ssl_test_lib:check_result(Server, ok, Client, ok);
check_result(Server, erlang, _, _) ->
@@ -350,15 +566,20 @@ new_openssl_ca(FileName, CA, OwnCa) ->
E1 = public_key:pem_decode(P1),
{ok, P2} = file:read_file(OwnCa),
E2 = public_key:pem_decode(P2),
- case os:cmd("openssl version") of
- "OpenSSL 1.0.1p-freebsd" ++ _ ->
- Pem = public_key:pem_encode(E1 ++E2),
- file:write_file(FileName, Pem);
- "LibreSSL" ++ _ ->
- Pem = public_key:pem_encode(E1 ++E2),
- file:write_file(FileName, Pem);
- _ ->
- Pem = public_key:pem_encode(E2 ++E1),
- file:write_file(FileName, Pem)
- end,
+ Pem = public_key:pem_encode(E2 ++E1),
+ file:write_file(FileName, Pem),
FileName.
+
+supported_eccs(Opts) ->
+ ToCheck = proplists:get_value(eccs, Opts, []),
+ Supported = ssl:eccs(),
+ lists:all(fun(Curve) -> lists:member(Curve, Supported) end, ToCheck).
+
+check_ecc(SSL, Role, Expect) ->
+ {ok, Data} = ssl:connection_information(SSL),
+ case lists:keyfind(ecc, 1, Data) of
+ {ecc, {named_curve, Expect}} -> ok;
+ false when Expect =:= undefined -> ok;
+ Other -> {error, Role, Expect, Other}
+ end.
+
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 1be43c56c4..392da738ec 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -150,6 +150,7 @@ api_tests() ->
peercert_with_client_cert,
sockname,
versions,
+ eccs,
controlling_process,
getstat,
close_with_timeout,
@@ -456,6 +457,15 @@ init_per_testcase(accept_pool, Config) ->
init_per_testcase(controller_dies, Config) ->
ct:timetrap({seconds, 10}),
Config;
+init_per_testcase(eccs, Config) ->
+ case ssl:eccs() of
+ [] ->
+ {skip, "named curves not supported"};
+ [_|_] ->
+ ssl_test_lib:ct_log_supported_protocol_versions(Config),
+ ct:timetrap({seconds, 5}),
+ Config
+ end;
init_per_testcase(_TestCase, Config) ->
ssl_test_lib:ct_log_supported_protocol_versions(Config),
ct:timetrap({seconds, 5}),
@@ -1504,6 +1514,25 @@ versions(Config) when is_list(Config) ->
[_|_] = Versions = ssl:versions(),
ct:log("~p~n", [Versions]).
+
+%%--------------------------------------------------------------------
+eccs() ->
+ [{doc, "Test API functions eccs/0 and eccs/1"}].
+
+eccs(Config) when is_list(Config) ->
+ [_|_] = All = ssl:eccs(),
+ [] = SSL3 = ssl:eccs({3,0}),
+ [_|_] = Tls = ssl:eccs({3,1}),
+ [_|_] = Tls1 = ssl:eccs({3,2}),
+ [_|_] = Tls2 = ssl:eccs({3,3}),
+ [] = SSL3 = ssl:eccs(sslv3),
+ [_|_] = Tls = ssl:eccs(tlsv1),
+ [_|_] = Tls1 = ssl:eccs('tlsv1.1'),
+ [_|_] = Tls2 = ssl:eccs('tlsv1.2'),
+ %% ordering is currently unverified by the test
+ true = lists:sort(All) =:= lists:usort(SSL3 ++ Tls ++ Tls1 ++ Tls2),
+ ok.
+
%%--------------------------------------------------------------------
send_recv() ->
[{doc,""}].
@@ -2164,7 +2193,7 @@ ciphers_dsa_signed_certs() ->
ciphers_dsa_signed_certs(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:dsa_suites(),
+ Ciphers = ssl_test_lib:dsa_suites(tls_record:protocol_version(Version)),
ct:log("~p erlang cipher suites ~p~n", [Version, Ciphers]),
run_suites(Ciphers, Version, Config, dsa).
%%-------------------------------------------------------------------
@@ -2305,7 +2334,7 @@ ciphers_ecdsa_signed_certs() ->
ciphers_ecdsa_signed_certs(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:ecdsa_suites(),
+ Ciphers = ssl_test_lib:ecdsa_suites(tls_record:protocol_version(Version)),
ct:log("~p erlang cipher suites ~p~n", [Version, Ciphers]),
run_suites(Ciphers, Version, Config, ecdsa).
%%--------------------------------------------------------------------
@@ -2323,7 +2352,7 @@ ciphers_ecdh_rsa_signed_certs() ->
ciphers_ecdh_rsa_signed_certs(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:ecdh_rsa_suites(),
+ Ciphers = ssl_test_lib:ecdh_rsa_suites(tls_record:protocol_version(Version)),
ct:log("~p erlang cipher suites ~p~n", [Version, Ciphers]),
run_suites(Ciphers, Version, Config, ecdh_rsa).
%%--------------------------------------------------------------------
@@ -3634,9 +3663,10 @@ no_rizzo_rc4() ->
[{doc,"Test that there is no 1/n-1-split for RC4 as it is not vunrable to Rizzo/Dungon attack"}].
no_rizzo_rc4(Config) when is_list(Config) ->
- Ciphers = [X || X ={_,Y,_} <- ssl:cipher_suites(),Y == rc4_128],
Prop = proplists:get_value(tc_group_properties, Config),
Version = proplists:get_value(name, Prop),
+ Ciphers = [ssl_cipher:erl_suite_definition(Suite) ||
+ Suite <- ssl_test_lib:rc4_suites(tls_record:protocol_version(Version))],
run_send_recv_rizzo(Ciphers, Config, Version,
{?MODULE, send_recv_result_active_no_rizzo, []}).
@@ -3644,9 +3674,10 @@ rizzo_one_n_minus_one() ->
[{doc,"Test that the 1/n-1-split mitigation of Rizzo/Dungon attack can be explicitly selected"}].
rizzo_one_n_minus_one(Config) when is_list(Config) ->
- Ciphers = [X || X ={_,Y,_} <- ssl:cipher_suites(), Y =/= rc4_128],
Prop = proplists:get_value(tc_group_properties, Config),
Version = proplists:get_value(name, Prop),
+ AllSuites = ssl_test_lib:available_suites(tls_record:protocol_version(Version)),
+ Ciphers = [X || X ={_,Y,_} <- AllSuites, Y =/= rc4_128],
run_send_recv_rizzo(Ciphers, Config, Version,
{?MODULE, send_recv_result_active_rizzo, []}).
@@ -3654,9 +3685,10 @@ rizzo_zero_n() ->
[{doc,"Test that the 0/n-split mitigation of Rizzo/Dungon attack can be explicitly selected"}].
rizzo_zero_n(Config) when is_list(Config) ->
- Ciphers = [X || X ={_,Y,_} <- ssl:cipher_suites(), Y =/= rc4_128],
Prop = proplists:get_value(tc_group_properties, Config),
Version = proplists:get_value(name, Prop),
+ AllSuites = ssl_test_lib:available_suites(tls_record:protocol_version(Version)),
+ Ciphers = [X || X ={_,Y,_} <- AllSuites, Y =/= rc4_128],
run_send_recv_rizzo(Ciphers, Config, Version,
{?MODULE, send_recv_result_active_no_rizzo, []}).
@@ -4407,7 +4439,7 @@ rizzo_test(Cipher, Config, Version, Mfa) ->
{host, Hostname},
{from, self()},
{mfa, Mfa},
- {options, [{active, true} | ClientOpts]}]),
+ {options, [{active, true}, {ciphers, [Cipher]}| ClientOpts]}]),
Result = ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
@@ -4698,3 +4730,4 @@ first_rsa_suite([_ | Rest]) ->
wait_for_send(Socket) ->
%% Make sure TLS process processed send message event
_ = ssl:connection_information(Socket).
+
diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
index 4c6f1d7c01..5265c87e29 100644
--- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl
+++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
@@ -1097,7 +1097,8 @@ client_with_cert_cipher_suites_handshake(Config) when is_list(Config) ->
{mfa, {ssl_test_lib,
send_recv_result_active, []}},
{options, [{active, true},
- {ciphers, ssl_test_lib:rsa_non_signed_suites()}
+ {ciphers,
+ ssl_test_lib:rsa_non_signed_suites(tls_record:highest_protocol_version([]))}
| ServerOpts]}]),
Port = ssl_test_lib:inet_port(Server),
Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
index 942e68967a..3446a566c4 100644
--- a/lib/ssl/test/ssl_packet_SUITE.erl
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -41,9 +41,9 @@
-define(MANY, 1000).
-define(SOME, 50).
--define(BASE_TIMEOUT_SECONDS, 30).
--define(SOME_SCALE, 20).
--define(MANY_SCALE, 20).
+-define(BASE_TIMEOUT_SECONDS, 5).
+-define(SOME_SCALE, 2).
+-define(MANY_SCALE, 3).
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index cab22a60a8..9632103696 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -462,9 +462,10 @@ cert_options(Config) ->
make_dsa_cert(Config) ->
-
- {ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_cert_files("server", Config, dsa, dsa, ""),
- {ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_cert_files("client", Config, dsa, dsa, ""),
+ {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}]},
@@ -490,8 +491,10 @@ make_ecdsa_cert(Config) ->
CryptoSupport = crypto:supports(),
case proplists:get_bool(ecdsa, proplists:get_value(public_keys, CryptoSupport)) of
true ->
- {ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_cert_files("server", Config, ec, ec, ""),
- {ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_cert_files("client", Config, ec, ec, ""),
+ {ServerCaCertFile, ServerCertFile, ServerKeyFile} =
+ make_cert_files("server", Config, ec, ec, "", [{digest, appropriate_sha(CryptoSupport)}]),
+ {ClientCaCertFile, ClientCertFile, ClientKeyFile} =
+ make_cert_files("client", Config, ec, ec, "", [{digest, appropriate_sha(CryptoSupport)}]),
[{server_ecdsa_opts, [{ssl_imp, new},{reuseaddr, true},
{cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
@@ -507,6 +510,14 @@ make_ecdsa_cert(Config) ->
Config
end.
+appropriate_sha(CryptoSupport) ->
+ case proplists:get_bool(sha256, CryptoSupport) of
+ true ->
+ sha256;
+ false ->
+ sha1
+ end.
+
%% RFC 4492, Sect. 2.3. ECDH_RSA
%%
%% This key exchange algorithm is the same as ECDH_ECDSA except that the
@@ -515,8 +526,10 @@ make_ecdh_rsa_cert(Config) ->
CryptoSupport = crypto:supports(),
case proplists:get_bool(ecdh, proplists:get_value(public_keys, CryptoSupport)) of
true ->
- {ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_cert_files("server", Config, rsa, ec, "rsa_"),
- {ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_cert_files("client", Config, rsa, ec, "rsa_"),
+ {ServerCaCertFile, ServerCertFile, ServerKeyFile} =
+ make_cert_files("server", Config, rsa, ec, "rsa_", []),
+ {ClientCaCertFile, ClientCertFile, ClientKeyFile} =
+ make_cert_files("client", Config, rsa, ec, "rsa_",[]),
[{server_ecdh_rsa_opts, [{ssl_imp, new},{reuseaddr, true},
{cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
@@ -534,9 +547,9 @@ make_ecdh_rsa_cert(Config) ->
make_mix_cert(Config) ->
{ServerCaCertFile, ServerCertFile, ServerKeyFile} = make_cert_files("server", Config, dsa,
- rsa, "mix"),
+ rsa, "mix", []),
{ClientCaCertFile, ClientCertFile, ClientKeyFile} = make_cert_files("client", Config, dsa,
- rsa, "mix"),
+ rsa, "mix", []),
[{server_mix_opts, [{ssl_imp, new},{reuseaddr, true},
{cacertfile, ServerCaCertFile},
{certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
@@ -549,11 +562,11 @@ make_mix_cert(Config) ->
{certfile, ClientCertFile}, {keyfile, ClientKeyFile}]}
| Config].
-make_cert_files(RoleStr, Config, Alg1, Alg2, Prefix) ->
+make_cert_files(RoleStr, Config, Alg1, Alg2, Prefix, Opts) ->
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}]),
+ CaInfo = {CaCert, _} = erl_make_certs:make_cert([{key, Alg1}| Opts]),
+ {Cert, CertKey} = erl_make_certs:make_cert([{key, Alg2}, {issuer, CaInfo} | Opts]),
CaCertFile = filename:join([proplists:get_value(priv_dir, Config),
RoleStr, Prefix ++ Alg1Str ++ "_cacerts.pem"]),
CertFile = filename:join([proplists:get_value(priv_dir, Config),
@@ -840,37 +853,42 @@ common_ciphers(openssl) ->
lists:member(ssl_cipher:openssl_suite_name(S), OpenSslSuites)
].
-rsa_non_signed_suites() ->
+available_suites(Version) ->
+ [ssl_cipher:erl_suite_definition(Suite) ||
+ Suite <- ssl_cipher:filter_suites(ssl_cipher:suites(Version))].
+
+
+rsa_non_signed_suites(Version) ->
lists:filter(fun({rsa, _, _}) ->
true;
(_) ->
false
end,
- ssl:cipher_suites()).
+ available_suites(Version)).
-dsa_suites() ->
+dsa_suites(Version) ->
lists:filter(fun({dhe_dss, _, _}) ->
true;
(_) ->
false
end,
- ssl:cipher_suites()).
+ available_suites(Version)).
-ecdsa_suites() ->
+ecdsa_suites(Version) ->
lists:filter(fun({ecdhe_ecdsa, _, _}) ->
true;
(_) ->
false
end,
- ssl:cipher_suites()).
+ available_suites(Version)).
-ecdh_rsa_suites() ->
+ecdh_rsa_suites(Version) ->
lists:filter(fun({ecdh_rsa, _, _}) ->
true;
(_) ->
false
end,
- ssl:cipher_suites()).
+ available_suites(Version)).
openssl_rsa_suites(CounterPart) ->
Ciphers = ssl:cipher_suites(openssl),
@@ -1174,14 +1192,15 @@ is_fips(_) ->
false.
cipher_restriction(Config0) ->
+ Version = tls_record:protocol_version(protocol_version(Config0)),
case is_sane_ecc(openssl) of
false ->
Opts = proplists:get_value(server_opts, Config0),
Config1 = proplists:delete(server_opts, Config0),
VerOpts = proplists:get_value(server_verification_opts, Config1),
Config = proplists:delete(server_verification_opts, Config1),
- Restricted0 = ssl:cipher_suites() -- ecdsa_suites(),
- Restricted = Restricted0 -- ecdh_rsa_suites(),
+ Restricted0 = ssl:cipher_suites() -- ecdsa_suites(Version),
+ Restricted = Restricted0 -- ecdh_rsa_suites(Version),
[{server_opts, [{ciphers, Restricted} | Opts]}, {server_verification_opts, [{ciphers, Restricted} | VerOpts] } | Config];
true ->
Config0
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
index 9ecfe5b0ea..e99340822d 100644
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -834,7 +834,7 @@ ciphers_dsa_signed_certs() ->
[{doc,"Test cipher suites that uses dsa certs"}].
ciphers_dsa_signed_certs(Config) when is_list(Config) ->
Version = ssl_test_lib:protocol_version(Config),
- Ciphers = ssl_test_lib:dsa_suites(),
+ Ciphers = ssl_test_lib:dsa_suites(tls_record:protocol_version(Version)),
run_suites(Ciphers, Version, Config, dsa).
%%--------------------------------------------------------------------
diff --git a/lib/stdlib/doc/src/assert_hrl.xml b/lib/stdlib/doc/src/assert_hrl.xml
index e2dfc2ab9b..a29f6d6ad7 100644
--- a/lib/stdlib/doc/src/assert_hrl.xml
+++ b/lib/stdlib/doc/src/assert_hrl.xml
@@ -28,7 +28,7 @@
<date></date>
<rev></rev>
</header>
- <file>assert.hrl.xml</file>
+ <file>assert.hrl</file>
<filesummary>Assert macros.</filesummary>
<description>
<p>The include file <c>assert.hrl</c> provides macros for inserting
@@ -49,25 +49,33 @@
entries in the <c>Info</c> list are optional; do not rely programatically
on any of them being present.</p>
+ <p>Each assert macro has a corresponding version with an extra argument,
+ for adding comments to assertions. These can for example be printed as
+ part of error reports, to clarify the meaning of the check that
+ failed. For example, <c>?assertEqual(0, fib(0), "Fibonacci is defined
+ for zero")</c>. The comment text can be any character data (string,
+ UTF8-binary, or deep list of such data), and will be included in the
+ error term as <c>{comment, Text}</c>.</p>
+
<p>If the macro <c>NOASSERT</c> is defined when <c>assert.hrl</c> is read
by the compiler, the macros are defined as equivalent to the atom
- <c>ok</c>. The test is not performed and there is no cost at runtime.</p>
+ <c>ok</c>. The test will not be performed and there is no cost at runtime.</p>
<p>For example, using <c>erlc</c> to compile your modules, the following
- disable all assertions:</p>
+ disables all assertions:</p>
<code type="none">
erlc -DNOASSERT=true *.erl</code>
- <p>The value of <c>NOASSERT</c> does not matter, only the fact that it is
- defined.</p>
+ <p>(The value of <c>NOASSERT</c> does not matter, only the fact that it is
+ defined.)</p>
<p>A few other macros also have effect on the enabling or disabling of
assertions:</p>
<list type="bulleted">
- <item><p>If <c>NODEBUG</c> is defined, it implies <c>NOASSERT</c>, unless
- <c>DEBUG</c> is also defined, which is assumed to take precedence.</p>
+ <item><p>If <c>NODEBUG</c> is defined, it implies <c>NOASSERT</c> (unless
+ <c>DEBUG</c> is also defined, which overrides <c>NODEBUG</c>).</p>
</item>
<item><p>If <c>ASSERT</c> is defined, it overrides <c>NOASSERT</c>, that
is, the assertions remain enabled.</p></item>
@@ -84,16 +92,19 @@ erlc -DNOASSERT=true *.erl</code>
<title>Macros</title>
<taglist>
<tag><c>assert(BoolExpr)</c></tag>
+ <tag><c>assert(BoolExpr, Comment)</c></tag>
<item>
<p>Tests that <c>BoolExpr</c> completes normally returning
<c>true</c>.</p>
</item>
<tag><c>assertNot(BoolExpr)</c></tag>
+ <tag><c>assertNot(BoolExpr, Comment)</c></tag>
<item>
<p>Tests that <c>BoolExpr</c> completes normally returning
<c>false</c>.</p>
</item>
<tag><c>assertMatch(GuardedPattern, Expr)</c></tag>
+ <tag><c>assertMatch(GuardedPattern, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> completes normally yielding a value that
matches <c>GuardedPattern</c>, for example:</p>
@@ -104,6 +115,7 @@ erlc -DNOASSERT=true *.erl</code>
?assertMatch({bork, X} when X > 0, f())</code>
</item>
<tag><c>assertNotMatch(GuardedPattern, Expr)</c></tag>
+ <tag><c>assertNotMatch(GuardedPattern, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> completes normally yielding a value that does
not match <c>GuardedPattern</c>.</p>
@@ -111,16 +123,19 @@ erlc -DNOASSERT=true *.erl</code>
<c>when</c> part.</p>
</item>
<tag><c>assertEqual(ExpectedValue, Expr)</c></tag>
+ <tag><c>assertEqual(ExpectedValue, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> completes normally yielding a value that is
exactly equal to <c>ExpectedValue</c>.</p>
</item>
<tag><c>assertNotEqual(ExpectedValue, Expr)</c></tag>
+ <tag><c>assertNotEqual(ExpectedValue, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> completes normally yielding a value that is
not exactly equal to <c>ExpectedValue</c>.</p>
</item>
<tag><c>assertException(Class, Term, Expr)</c></tag>
+ <tag><c>assertException(Class, Term, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> completes abnormally with an exception of type
<c>Class</c> and with the associated <c>Term</c>. The assertion fails
@@ -130,6 +145,7 @@ erlc -DNOASSERT=true *.erl</code>
patterns, as in <c>assertMatch</c>.</p>
</item>
<tag><c>assertNotException(Class, Term, Expr)</c></tag>
+ <tag><c>assertNotException(Class, Term, Expr, Comment)</c></tag>
<item>
<p>Tests that <c>Expr</c> does not evaluate abnormally with an
exception of type <c>Class</c> and with the associated <c>Term</c>.
@@ -139,14 +155,17 @@ erlc -DNOASSERT=true *.erl</code>
be guarded patterns.</p>
</item>
<tag><c>assertError(Term, Expr)</c></tag>
+ <tag><c>assertError(Term, Expr, Comment)</c></tag>
<item>
<p>Equivalent to <c>assertException(error, Term, Expr)</c></p>
</item>
<tag><c>assertExit(Term, Expr)</c></tag>
+ <tag><c>assertExit(Term, Expr, Comment)</c></tag>
<item>
<p>Equivalent to <c>assertException(exit, Term, Expr)</c></p>
</item>
<tag><c>assertThrow(Term, Expr)</c></tag>
+ <tag><c>assertThrow(Term, Expr, Comment)</c></tag>
<item>
<p>Equivalent to <c>assertException(throw, Term, Expr)</c></p>
</item>
diff --git a/lib/stdlib/doc/src/c.xml b/lib/stdlib/doc/src/c.xml
index 92ab59c6b0..55a77d1bc5 100644
--- a/lib/stdlib/doc/src/c.xml
+++ b/lib/stdlib/doc/src/c.xml
@@ -148,6 +148,15 @@ compile:file(<anno>File</anno>, <anno>Options</anno> ++ [report_errors, report_w
</func>
<func>
+ <name name="lm" arity="0"/>
+ <fsummary>Loads all modified modules.</fsummary>
+ <desc>
+ <p>Reloads all currently loaded modules that have changed on disk (see <c>mm()</c>).
+ Returns the list of results from calling <c>l(M)</c> for each such <c>M</c>.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="ls" arity="0"/>
<fsummary>List files in the current directory.</fsummary>
<desc>
@@ -182,6 +191,15 @@ compile:file(<anno>File</anno>, <anno>Options</anno> ++ [report_errors, report_w
</func>
<func>
+ <name name="mm" arity="0"/>
+ <fsummary>Lists all modified modules.</fsummary>
+ <desc>
+ <p>Lists all modified modules. Shorthand for
+ <seealso marker="kernel:code#modified_modules/0"><c>code:modified_modules/0</c></seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="memory" arity="0"/>
<fsummary>Memory allocation information.</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/dets.xml b/lib/stdlib/doc/src/dets.xml
index 2e4261d72e..eb6e32aecf 100644
--- a/lib/stdlib/doc/src/dets.xml
+++ b/lib/stdlib/doc/src/dets.xml
@@ -100,18 +100,12 @@
provided by Dets, neither is the limited support for
concurrent updates that makes a sequence of <c>first</c> and
<c>next</c> calls safe to use on fixed ETS tables. Both these
- features will be provided by Dets in a future release of
+ features may be provided by Dets in a future release of
Erlang/OTP. Until then, the Mnesia application (or some
user-implemented method for locking) must be used to implement safe
concurrency. Currently, no Erlang/OTP library has support for
ordered disk-based term storage.</p>
- <p>Two versions of the format used for storing objects on file are
- supported by Dets. The first version, 8, is the format always used
- for tables created by Erlang/OTP R7 and earlier. The second version, 9,
- is the default version of tables created by Erlang/OTP R8 (and later
- releases). Erlang/OTP R8 can create version 8 tables, and convert version
- 8 tables to version 9, and conversely, upon request.</p>
<p>All Dets functions return <c>{error, Reason}</c> if an error
occurs (<seealso marker="#first/1"><c>first/1</c></seealso> and
<seealso marker="#next/2"><c>next/2</c></seealso> are exceptions, they
@@ -190,9 +184,6 @@
<datatype>
<name name="type"/>
</datatype>
- <datatype>
- <name name="version"/>
- </datatype>
</datatypes>
<funcs>
@@ -385,8 +376,7 @@
<p><c>{bchunk_format, binary()}</c> - An opaque binary
describing the format of the objects returned by
<c>bchunk/2</c>. The binary can be used as argument to
- <c>is_compatible_chunk_format/2</c>. Only available for
- version 9 tables.</p>
+ <c>is_compatible_chunk_format/2</c>.</p>
</item>
<item>
<p><c>{hash, Hash}</c> - Describes which BIF is
@@ -394,10 +384,6 @@
Dets table. Possible values of <c>Hash</c>:</p>
<list>
<item>
- <p><c>hash</c> - Implies that the <c>erlang:hash/2</c> BIF
- is used.</p>
- </item>
- <item>
<p><c>phash</c> - Implies that the <c>erlang:phash/2</c> BIF
is used.</p>
</item>
@@ -413,8 +399,7 @@
</item>
<item>
<p><c>{no_keys, integer >= 0()}</c> - The number of different
- keys stored in the table. Only available for version 9
- tables.</p>
+ keys stored in the table.</p>
</item>
<item>
<p><c>{no_objects, integer >= 0()}</c> - The number of objects
@@ -424,8 +409,7 @@
<p><c>{no_slots, {Min, Used, Max}}</c> - The
number of slots of the table. <c>Min</c> is the minimum number of
slots, <c>Used</c> is the number of currently used slots,
- and <c>Max</c> is the maximum number of slots. Only
- available for version 9 tables.</p>
+ and <c>Max</c> is the maximum number of slots.</p>
</item>
<item>
<p><c>{owner, pid()}</c> - The pid of the process that
@@ -466,10 +450,6 @@
time warp safe</seealso>. Time warp safe code must use
<c>safe_fixed_monotonic_time</c> instead.</p>
</item>
- <item>
- <p><c>{version, integer()}</c> - The version of the format of
- the table.</p>
- </item>
</list>
</desc>
</func>
@@ -662,8 +642,8 @@ ok
objects at a time, until at least one object matches or the
end of the table is reached. The default, indicated by
giving <c><anno>N</anno></c> the value <c>default</c>, is to let
- the number of objects vary depending on the sizes of the objects. If
- <c><anno>Name</anno></c> is a version 9 table, all objects with the
+ the number of objects vary depending on the sizes of the objects.
+ All objects with the
same key are always matched at the same time, which implies that
more than <anno>N</anno> objects can sometimes be matched.</p>
<p>The table is always to be protected using
@@ -743,9 +723,9 @@ ok
end of the table is reached. The default, indicated by
giving <c><anno>N</anno></c> the value <c>default</c>,
is to let the number
- of objects vary depending on the sizes of the objects. If
- <c><anno>Name</anno></c> is a version 9 table, all matching objects
- with the same key are always returned in the same reply, which implies
+ of objects vary depending on the sizes of the objects. All
+ matching objects with the same key are always returned
+ in the same reply, which implies
that more than <anno>N</anno> objects can sometimes be returned.</p>
<p>The table is always to be protected using
<seealso marker="#safe_fixtable/2"><c>safe_fixtable/2</c></seealso>
@@ -842,8 +822,7 @@ ok
maximal value. Notice that a higher value can
increase the table fragmentation, and
a smaller value can decrease the fragmentation, at
- the expense of execution time. Only available for version
- 9 tables.</p>
+ the expense of execution time.</p>
</item>
<item>
<p><c>{min_no_slots, </c><seealso marker="#type-no_slots">
@@ -880,12 +859,7 @@ ok
FileName}}</c> is returned if the table must be repaired.</p>
<p>Value <c>force</c> means that a reparation
is made even if the table is properly closed.
- This is how to convert tables created by older versions of
- STDLIB. An example is tables hashed with the deprecated
- <c>erlang:hash/2</c> BIF. Tables created with Dets from
- STDLIB version 1.8.2 or later use function
- <c>erlang:phash/2</c> or function <c>erlang:phash2/1</c>,
- which is preferred.</p>
+ This is a seldom needed option.</p>
<p>Option <c>repair</c> is ignored if the table is already open.</p>
</item>
<item>
@@ -893,15 +867,6 @@ ok
<c>type()</c></seealso><c>}</c> - The table type. Defaults to
<c>set</c>.</p>
</item>
- <item>
- <p><c>{version, </c><seealso marker="#type-version">
- <c>version()</c></seealso><c>}</c> - The version of the format
- used for the table. Defaults to <c>9</c>. Tables on the format
- used before Erlang/OTP R8 can be created by specifying value
- <c>8</c>. A version 8 table can be converted to a version 9
- table by specifying options <c>{version,9}</c>
- and <c>{repair,force}</c>.</p>
- </item>
</list>
</desc>
</func>
@@ -1041,8 +1006,8 @@ ok
a time, until at least one object matches or the end of the
table is reached. The default, indicated by giving
<c><anno>N</anno></c> the value <c>default</c>, is to let the number
- of objects vary depending on the sizes of the objects. If
- <c><anno>Name</anno></c> is a version 9 table, all objects with the
+ of objects vary depending on the sizes of the objects. All
+ objects with the
same key are always handled at the same time, which implies that the
match specification can be applied to more than <anno>N</anno>
objects.</p>
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml
index 64267c2af5..fd498ee82e 100644
--- a/lib/stdlib/doc/src/gen_statem.xml
+++ b/lib/stdlib/doc/src/gen_statem.xml
@@ -533,7 +533,7 @@ handle_event(_, _, State, Data) ->
Type <c>info</c> originates from regular process messages sent
to the <c>gen_statem</c>. Also, the state machine
implementation can generate events of types
- <c>timeout</c>, <c>state_timeout</c>, <c>enter</c>,
+ <c>timeout</c>, <c>state_timeout</c>,
and <c>internal</c> to itself.
</p>
</desc>
@@ -639,6 +639,20 @@ handle_event(_, _, State, Data) ->
</p>
<list type="ordered">
<item>
+ <p>
+ If the state changes or is the initial state, and
+ <seealso marker="#type-state_enter"><em>state enter calls</em></seealso>
+ are used, the <c>gen_statem</c> calls
+ the new state callback with arguments
+ <seealso marker="#type-state_enter">(enter, OldState, Data)</seealso>.
+ Any
+ <seealso marker="#type-enter_action"><c>actions</c></seealso>
+ returned from this call are handled as if they were
+ appended to the actions
+ returned by the state callback that changed states.
+ </p>
+ </item>
+ <item>
<p>
All
<seealso marker="#type-action">actions</seealso>
@@ -668,36 +682,36 @@ handle_event(_, _, State, Data) ->
</p>
</item>
<item>
- <p>
- If the state changes or is the initial state, and
- <seealso marker="#type-state_enter"><em>state enter calls</em></seealso>
- are used, the <c>gen_statem</c> calls
- the new state callback with arguments
- <seealso marker="#type-state_enter">(enter, OldState, Data)</seealso>.
- Any
- <seealso marker="#type-enter_action"><c>actions</c></seealso>
- returned from this call are handled as if they were
- appended to the actions
- returned by the state callback that changed states.
- </p>
- </item>
- <item>
- <p>
- If there are enqueued events the (possibly new)
- <seealso marker="#state callback">state callback</seealso>
- is called with the oldest enqueued event,
- and we start again from the top of this list.
- </p>
- </item>
- <item>
<p>
Timeout timers
<seealso marker="#type-state_timeout"><c>state_timeout()</c></seealso>
and
<seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso>
- are handled. This may lead to a time-out zero event
- being generated to the
+ are handled. Time-outs with zero time are guaranteed to be
+ delivered to the state machine before any external
+ not yet received event so if there is such a timeout requested,
+ the corresponding time-out zero event is enqueued as
+ the newest event.
+ </p>
+ <p>
+ Any event cancels an
+ <seealso marker="#type-event_timeout"><c>event_timeout()</c></seealso>
+ so a zero time event time-out is only generated
+ if the event queue is empty.
+ </p>
+ <p>
+ A state change cancels a
+ <seealso marker="#type-state_timeout"><c>state_timeout()</c></seealso>
+ and any new transition option of this type
+ belongs to the new state.
+ </p>
+ </item>
+ <item>
+ <p>
+ If there are enqueued events the
<seealso marker="#state callback">state callback</seealso>
+ for the possibly new state
+ is called with the oldest enqueued event,
and we start again from the top of this list.
</p>
</item>
@@ -759,8 +773,9 @@ handle_event(_, _, State, Data) ->
after this time (in milliseconds) unless another
event arrives or has arrived
in which case this time-out is cancelled.
- Note that a retried, inserted or state time-out zero
- events counts as arrived.
+ Note that a retried or inserted event counts as arrived.
+ So does a state time-out zero event, if it was generated
+ before this timer is requested.
</p>
<p>
If the value is <c>infinity</c>, no timer is started, as
@@ -802,7 +817,7 @@ handle_event(_, _, State, Data) ->
<p>
Setting this timer while it is running will restart it with
the new time-out value. Therefore it is possible to cancel
- this timeout by setting it to <c>infinity</c>.
+ this time-out by setting it to <c>infinity</c>.
</p>
</desc>
</datatype>
@@ -1130,7 +1145,7 @@ handle_event(_, _, State, Data) ->
<c><anno>Timeout</anno></c> can also be a tuple
<c>{clean_timeout,<anno>T</anno>}</c> or
<c>{dirty_timeout,<anno>T</anno>}</c>, where
- <c><anno>T</anno></c> is the timeout time.
+ <c><anno>T</anno></c> is the time-out time.
<c>{clean_timeout,<anno>T</anno>}</c> works like
just <c>T</c> described in the note above
and uses a proxy process for <c>T &lt; infinity</c>,
@@ -1773,7 +1788,7 @@ handle_event(_, _, State, Data) ->
StateFunctionResult
</name>
<name>Module:handle_event(enter, OldState, State, Data) ->
- StateEnterResult
+ StateEnterResult(State)
</name>
<name>Module:handle_event(EventType, EventContent, State, Data) ->
HandleEventResult
@@ -1802,8 +1817,8 @@ handle_event(_, _, State, Data) ->
<seealso marker="#type-event_handler_result">event_handler_result</seealso>(<seealso marker="#type-state_name">state_name()</seealso>)
</v>
<v>
- StateEnterResult =
- <seealso marker="#type-state_enter_result">state_enter_result</seealso>(<seealso marker="#type-state">state()</seealso>)
+ StateEnterResult(State) =
+ <seealso marker="#type-state_enter_result">state_enter_result(State)</seealso>
</v>
<v>
HandleEventResult =
diff --git a/lib/stdlib/doc/src/maps.xml b/lib/stdlib/doc/src/maps.xml
index e1edbadcd3..8c7270816b 100644
--- a/lib/stdlib/doc/src/maps.xml
+++ b/lib/stdlib/doc/src/maps.xml
@@ -160,7 +160,7 @@ val1
<p><em>Example:</em></p>
<code type="none">
> Map = #{"42" => value}.
-#{"42"> => value}
+#{"42" => value}
> maps:is_key("42",Map).
true
> maps:is_key(value,Map).
diff --git a/lib/stdlib/doc/src/math.xml b/lib/stdlib/doc/src/math.xml
index 70ca6ae78e..b4f096217a 100644
--- a/lib/stdlib/doc/src/math.xml
+++ b/lib/stdlib/doc/src/math.xml
@@ -62,6 +62,7 @@
<name name="cosh" arity="1"/>
<name name="exp" arity="1"/>
<name name="floor" arity="1"/>
+ <name name="fmod" arity="2"/>
<name name="log" arity="1"/>
<name name="log10" arity="1"/>
<name name="log2" arity="1"/>
diff --git a/lib/stdlib/doc/src/orddict.xml b/lib/stdlib/doc/src/orddict.xml
index 076b06fc38..39b43809b6 100644
--- a/lib/stdlib/doc/src/orddict.xml
+++ b/lib/stdlib/doc/src/orddict.xml
@@ -38,7 +38,7 @@
<p>This module provides a <c>Key</c>-<c>Value</c> dictionary.
An <c>orddict</c> is a representation of a dictionary, where a
list of pairs is used to store the keys and values. The list is
- ordered after the keys.</p>
+ ordered after the keys in the <em>Erlang term order</em>.</p>
<p>This module provides the same interface as the
<seealso marker="dict"><c>dict(3)</c></seealso> module
diff --git a/lib/stdlib/doc/src/ordsets.xml b/lib/stdlib/doc/src/ordsets.xml
index 148281fcf7..7b590932e4 100644
--- a/lib/stdlib/doc/src/ordsets.xml
+++ b/lib/stdlib/doc/src/ordsets.xml
@@ -39,7 +39,8 @@
<p>Sets are collections of elements with no duplicate elements.
An <c>ordset</c> is a representation of a set, where an ordered
list is used to store the elements of the set. An ordered list
- is more efficient than an unordered list.</p>
+ is more efficient than an unordered list. Elements are ordered
+ according to the <em>Erlang term order</em>.</p>
<p>This module provides the same interface as the
<seealso marker="sets"><c>sets(3)</c></seealso> module
diff --git a/lib/stdlib/doc/src/proc_lib.xml b/lib/stdlib/doc/src/proc_lib.xml
index da03c39a26..e64b2ce18a 100644
--- a/lib/stdlib/doc/src/proc_lib.xml
+++ b/lib/stdlib/doc/src/proc_lib.xml
@@ -66,6 +66,12 @@
<seealso marker="sasl:error_logging">SASL Error Logging</seealso>
in the SASL User's Guide.</p>
+ <p>Unlike in "plain Erlang", <c>proc_lib</c> processes will not generate
+ <em>error reports</em>, which are written to the terminal by the
+ emulator and do not require SASL to be started. All exceptions are
+ converted to <em>exits</em> which are ignored by the default
+ <c>error_logger</c> handler.</p>
+
<p>The crash report contains the previously stored information, such
as ancestors and initial function, the termination reason, and
information about other processes that terminate as a result
diff --git a/lib/stdlib/doc/src/rand.xml b/lib/stdlib/doc/src/rand.xml
index 1dcc3de000..1364a3277b 100644
--- a/lib/stdlib/doc/src/rand.xml
+++ b/lib/stdlib/doc/src/rand.xml
@@ -41,6 +41,11 @@
Sebastiano Vigna</url>. The normal distribution algorithm uses the
<url href="http://www.jstatsoft.org/v05/i08">Ziggurat Method by Marsaglia
and Tsang</url>.</p>
+ <p>For some algorithms, jump functions are provided for generating
+ non-overlapping sequences for parallel computations.
+ The jump functions perform calculations
+ equivalent to perform a large number of repeated calls
+ for calculating new states. </p>
<p>The following algorithms are provided:</p>
@@ -48,14 +53,17 @@
<tag><c>exsplus</c></tag>
<item>
<p>Xorshift116+, 58 bits precision and period of 2^116-1</p>
+ <p>Jump function: equivalent to 2^64 calls</p>
</item>
<tag><c>exs64</c></tag>
<item>
<p>Xorshift64*, 64 bits precision and a period of 2^64-1</p>
+ <p>Jump function: not available</p>
</item>
<tag><c>exs1024</c></tag>
<item>
<p>Xorshift1024*, 64 bits precision and a period of 2^1024-1</p>
+ <p>Jump function: equivalent to 2^512 calls</p>
</item>
</taglist>
@@ -156,6 +164,33 @@ S0 = rand:seed_s(exsplus),
</func>
<func>
+ <name name="jump" arity="0"/>
+ <fsummary>Return the seed after performing jump calculation
+ to the state in the process dictionary.</fsummary>
+ <desc><marker id="jump-0" />
+ <p>Returns the state
+ after performing jump calculation
+ to the state in the process dictionary.</p>
+ <p>This function generates a <c>not_implemented</c> error exception
+ when the jump function is not implemented for
+ the algorithm specified in the state
+ in the process dictionary.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="jump" arity="1"/>
+ <fsummary>Return the seed after performing jump calculation.</fsummary>
+ <desc><marker id="jump-1" />
+ <p>Returns the state after performing jump calculation
+ to the given state. </p>
+ <p>This function generates a <c>not_implemented</c> error exception
+ when the jump function is not implemented for
+ the algorithm specified in the state.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="normal" arity="0"/>
<fsummary>Return a standard normal distributed random float.</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml
index 294196f746..bb06d3645e 100644
--- a/lib/stdlib/doc/src/supervisor.xml
+++ b/lib/stdlib/doc/src/supervisor.xml
@@ -133,8 +133,10 @@ sup_flags() = #{strategy => strategy(), % optional
map. Assuming the values <c>MaxR</c> for <c>intensity</c>
and <c>MaxT</c> for <c>period</c>, then, if more than <c>MaxR</c>
restarts occur within <c>MaxT</c> seconds, the supervisor
- terminates all child processes and then itself. <c>intensity</c>
- defaults to <c>1</c> and <c>period</c> defaults to <c>5</c>.</p>
+ terminates all child processes and then itself. The termination
+ reason for the supervisor itself in that case will be <c>shutdown</c>.
+ <c>intensity</c> defaults to <c>1</c> and <c>period</c> defaults to
+ <c>5</c>.</p>
<marker id="child_spec"/>
<p>The type definition of a child specification is as follows:</p>
diff --git a/lib/stdlib/include/assert.hrl b/lib/stdlib/include/assert.hrl
index 9e5d4eb598..2fbaeba0b2 100644
--- a/lib/stdlib/include/assert.hrl
+++ b/lib/stdlib/include/assert.hrl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright (C) 2004-2016 Richard Carlsson, Mickaël Rémond
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,8 +10,7 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
+%% Copyright (C) 2004-2016 Richard Carlsson, Mickaël Rémond
-ifndef(ASSERT_HRL).
-define(ASSERT_HRL, true).
@@ -56,7 +50,8 @@
%% It is not possible to nest assert macros.
-ifdef(NOASSERT).
--define(assert(BoolExpr),ok).
+-define(assert(BoolExpr), ok).
+-define(assert(BoolExpr, Comment), ok).
-else.
%% The assert macro is written the way it is so as not to cause warnings
%% for clauses that cannot match, even if the expression is a constant or
@@ -79,11 +74,31 @@
end
end)())
end).
+-define(assert(BoolExpr, Comment),
+ begin
+ ((fun () ->
+ __T = is_process_alive(self()), % cheap source of truth
+ case (BoolExpr) of
+ __T -> ok;
+ __V -> erlang:error({assert,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??BoolExpr)},
+ {expected, true},
+ case not __T of
+ __V -> {value, false};
+ _ -> {not_boolean, __V}
+ end]})
+ end
+ end)())
+ end).
-endif.
%% This is the inverse case of assert, for convenience.
-ifdef(NOASSERT).
-define(assertNot(BoolExpr),ok).
+-define(assertNot(BoolExpr, Comment), ok).
-else.
-define(assertNot(BoolExpr),
begin
@@ -103,12 +118,32 @@
end
end)())
end).
+-define(assertNot(BoolExpr, Comment),
+ begin
+ ((fun () ->
+ __F = not is_process_alive(self()),
+ case (BoolExpr) of
+ __F -> ok;
+ __V -> erlang:error({assert,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??BoolExpr)},
+ {expected, false},
+ case not __F of
+ __V -> {value, true};
+ _ -> {not_boolean, __V}
+ end]})
+ end
+ end)())
+ end).
-endif.
%% This is mostly a convenience which gives more detailed reports.
%% Note: Guard is a guarded pattern, and can not be used for value.
-ifdef(NOASSERT).
-define(assertMatch(Guard, Expr), ok).
+-define(assertMatch(Guard, Expr, Comment), ok).
-else.
-define(assertMatch(Guard, Expr),
begin
@@ -124,11 +159,27 @@
end
end)())
end).
+-define(assertMatch(Guard, Expr, Comment),
+ begin
+ ((fun () ->
+ case (Expr) of
+ Guard -> ok;
+ __V -> erlang:error({assertMatch,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern, (??Guard)},
+ {value, __V}]})
+ end
+ end)())
+ end).
-endif.
%% This is the inverse case of assertMatch, for convenience.
-ifdef(NOASSERT).
-define(assertNotMatch(Guard, Expr), ok).
+-define(assertNotMatch(Guard, Expr, Comment), ok).
-else.
-define(assertNotMatch(Guard, Expr),
begin
@@ -145,12 +196,29 @@
end
end)())
end).
+-define(assertNotMatch(Guard, Expr, Comment),
+ begin
+ ((fun () ->
+ __V = (Expr),
+ case __V of
+ Guard -> erlang:error({assertNotMatch,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern, (??Guard)},
+ {value, __V}]});
+ _ -> ok
+ end
+ end)())
+ end).
-endif.
%% This is a convenience macro which gives more detailed reports when
%% the expected LHS value is not a pattern, but a computed value
-ifdef(NOASSERT).
-define(assertEqual(Expect, Expr), ok).
+-define(assertEqual(Expect, Expr, Comment), ok).
-else.
-define(assertEqual(Expect, Expr),
begin
@@ -167,11 +235,28 @@
end
end)())
end).
+-define(assertEqual(Expect, Expr, Comment),
+ begin
+ ((fun () ->
+ __X = (Expect),
+ case (Expr) of
+ __X -> ok;
+ __V -> erlang:error({assertEqual,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {expected, __X},
+ {value, __V}]})
+ end
+ end)())
+ end).
-endif.
%% This is the inverse case of assertEqual, for convenience.
-ifdef(NOASSERT).
-define(assertNotEqual(Unexpected, Expr), ok).
+-define(assertNotEqual(Unexpected, Expr, Comment), ok).
-else.
-define(assertNotEqual(Unexpected, Expr),
begin
@@ -187,12 +272,28 @@
end
end)())
end).
+-define(assertNotEqual(Unexpected, Expr, Comment),
+ begin
+ ((fun () ->
+ __X = (Unexpected),
+ case (Expr) of
+ __X -> erlang:error({assertNotEqual,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {value, __X}]});
+ _ -> ok
+ end
+ end)())
+ end).
-endif.
%% Note: Class and Term are patterns, and can not be used for value.
%% Term can be a guarded pattern, but Class cannot.
-ifdef(NOASSERT).
-define(assertException(Class, Term, Expr), ok).
+-define(assertException(Class, Term, Expr, Comment), ok).
-else.
-define(assertException(Class, Term, Expr),
begin
@@ -222,17 +323,54 @@
end
end)())
end).
+-define(assertException(Class, Term, Expr, Comment),
+ begin
+ ((fun () ->
+ try (Expr) of
+ __V -> erlang:error({assertException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "++(??Term)
+ ++" , [...] }"},
+ {unexpected_success, __V}]})
+ catch
+ Class:Term -> ok;
+ __C:__T ->
+ erlang:error({assertException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "++(??Term)
+ ++" , [...] }"},
+ {unexpected_exception,
+ {__C, __T,
+ erlang:get_stacktrace()}}]})
+ end
+ end)())
+ end).
-endif.
-define(assertError(Term, Expr), ?assertException(error, Term, Expr)).
+-define(assertError(Term, Expr, Comment),
+ ?assertException(error, Term, Expr, Comment)).
-define(assertExit(Term, Expr), ?assertException(exit, Term, Expr)).
+-define(assertExit(Term, Expr, Comment),
+ ?assertException(exit, Term, Expr, Comment)).
-define(assertThrow(Term, Expr), ?assertException(throw, Term, Expr)).
+-define(assertThrow(Term, Expr, Comment),
+ ?assertException(throw, Term, Expr, Comment)).
%% This is the inverse case of assertException, for convenience.
%% Note: Class and Term are patterns, and can not be used for value.
%% Both Class and Term can be guarded patterns.
-ifdef(NOASSERT).
-define(assertNotException(Class, Term, Expr), ok).
+-define(assertNotException(Class, Term, Expr, Comment), ok).
-else.
-define(assertNotException(Class, Term, Expr),
begin
@@ -263,6 +401,36 @@
end
end)())
end).
+-define(assertNotException(Class, Term, Expr, Comment),
+ begin
+ ((fun () ->
+ try (Expr) of
+ _ -> ok
+ catch
+ __C:__T ->
+ case __C of
+ Class ->
+ case __T of
+ Term ->
+ erlang:error({assertNotException,
+ [{module, ?MODULE},
+ {line, ?LINE},
+ {comment, (Comment)},
+ {expression, (??Expr)},
+ {pattern,
+ "{ "++(??Class)++" , "
+ ++(??Term)++" , [...] }"},
+ {unexpected_exception,
+ {__C, __T,
+ erlang:get_stacktrace()
+ }}]});
+ _ -> ok
+ end;
+ _ -> ok
+ end
+ end
+ end)())
+ end).
-endif.
-endif. % ASSERT_HRL
diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile
index 302834f9d0..d6c0ff8d8d 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -51,7 +51,6 @@ MODULES= \
dets_server \
dets_sup \
dets_utils \
- dets_v8 \
dets_v9 \
dict \
digraph \
@@ -225,7 +224,6 @@ $(EBIN)/beam_lib.beam: ../include/erl_compile.hrl ../../kernel/include/file.hrl
$(EBIN)/dets.beam: dets.hrl ../../kernel/include/file.hrl
$(EBIN)/dets_server.beam: dets.hrl
$(EBIN)/dets_utils.beam: dets.hrl
-$(EBIN)/dets_v8.beam: dets.hrl
$(EBIN)/dets_v9.beam: dets.hrl
$(EBIN)/erl_bits.beam: ../include/erl_bits.hrl
$(EBIN)/erl_compile.beam: ../include/erl_compile.hrl ../../kernel/include/file.hrl
diff --git a/lib/stdlib/src/array.erl b/lib/stdlib/src/array.erl
index d5757dda5b..079b761463 100644
--- a/lib/stdlib/src/array.erl
+++ b/lib/stdlib/src/array.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,13 +9,12 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
-%% @author Richard Carlsson <[email protected]>
+%% Copyright (C) 2006-2016 Richard Carlsson and Ericsson AB
+%%
+%% @author Richard Carlsson <[email protected]>
%% @author Dan Gudmundsson <[email protected]>
-%% @version 1.0
-
+%%
%% @doc Functional, extendible arrays. Arrays can have fixed size, or
%% can grow automatically as needed. A default value is used for entries
%% that have not been explicitly set.
diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl
index ad4915eabe..d36630214c 100644
--- a/lib/stdlib/src/c.erl
+++ b/lib/stdlib/src/c.erl
@@ -26,7 +26,7 @@
-export([help/0,lc/1,c/1,c/2,nc/1,nc/2, nl/1,l/1,i/0,i/1,ni/0,
y/1, y/2,
lc_batch/0, lc_batch/1,
- i/3,pid/3,m/0,m/1,
+ i/3,pid/3,m/0,m/1,mm/0,lm/0,
bt/1, q/0,
erlangrc/0,erlangrc/1,bi/1, flush/0, regs/0, uptime/0,
nregs/0,pwd/0,ls/0,ls/1,cd/1,memory/1,memory/0, xm/1]).
@@ -52,11 +52,13 @@ help() ->
"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"
+ "lm() -- load all modified modules\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"
+ "mm() -- list all modified modules\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"
@@ -459,6 +461,16 @@ m() ->
mformat(A1, A2) ->
format("~-20s ~ts\n", [A1,A2]).
+-spec mm() -> [module()].
+
+mm() ->
+ code:modified_modules().
+
+-spec lm() -> [code:load_ret()].
+
+lm() ->
+ [l(M) || M <- mm()].
+
%% erlangrc(Home)
%% Try to run a ".erlang" file, first in the current directory
%% else in home directory.
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index 8ce29f23d3..5bc9475fc8 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.erl
@@ -105,9 +105,6 @@
%%% the file with the split indicator, size etc is held in ram by the
%%% server at all times.
%%%
-%%% The parts specific for formats up to and including 8(c) are
-%%% implemented in dets_v8.erl, parts specific for format 9 are
-%%% implemented in dets_v9.erl.
%% The method of hashing is the so called linear hashing algorithm
%% with segments.
@@ -140,28 +137,33 @@
%%% written, and a repair is forced next time the file is opened.
-record(dets_cont, {
- what, % object | bindings | select | bchunk
- no_objs, % requested number of objects: default | integer() > 0
- 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
+ what :: 'undefined' | 'bchunk' | 'bindings' | 'object' | 'select',
+ no_objs :: 'default' | pos_integer(), % requested number of objects
+ bin :: 'eof' | binary(), % small chunk not consumed,
+ % or 'eof' at end-of-file
+ alloc :: binary() % the part of the file not yet scanned
+ | {From :: non_neg_integer(),
+ To :: non_neg_integer,
+ binary()},
+ tab :: tab_name(),
+ proc :: 'undefined' | pid(), % the pid of the Dets process
+ match_program :: 'true'
+ | 'undefined'
+ | {'match_spec', ets:comp_match_spec()}
}).
-record(open_args, {
- file,
- type,
- keypos,
- repair,
- min_no_slots,
- max_no_slots,
- ram_file,
- delayed_write,
- auto_save,
- access,
- version,
- debug
+ file :: list(),
+ type :: type(),
+ keypos :: keypos(),
+ repair :: 'force' | boolean(),
+ min_no_slots :: no_slots(),
+ max_no_slots :: no_slots(),
+ ram_file :: boolean(),
+ delayed_write :: cache_parms(),
+ auto_save :: auto_save(),
+ access :: access(),
+ debug :: boolean()
}).
-define(PATTERN_TO_OBJECT_MATCH_SPEC(Pat), [{Pat,[],['$_']}]).
@@ -177,20 +179,13 @@
%%-define(PROFILE(C), C).
-define(PROFILE(C), void).
--type access() :: 'read' | 'read_write'.
--type auto_save() :: 'infinity' | non_neg_integer().
-opaque bindings_cont() :: #dets_cont{}.
-opaque cont() :: #dets_cont{}.
--type keypos() :: pos_integer().
-type match_spec() :: ets:match_spec().
-type object() :: tuple().
--type no_slots() :: non_neg_integer() | 'default'.
-opaque object_cont() :: #dets_cont{}.
-type pattern() :: atom() | tuple().
-opaque select_cont() :: #dets_cont{}.
--type tab_name() :: term().
--type type() :: 'bag' | 'duplicate_bag' | 'set'.
--type version() :: 8 | 9 | 'default'.
%%% Some further debug code was added in R12B-1 (stdlib-1.15.1):
%%% - there is a new open_file() option 'debug';
@@ -273,19 +268,20 @@ delete_all_objects(Tab) ->
delete_object(Tab, O) ->
badarg(treq(Tab, {delete_object, [O]}), [Tab, O]).
+%% Backwards compatibility.
+fsck(Fname, _Version) ->
+ fsck(Fname).
+
%% Given a filename, fsck it. Debug.
fsck(Fname) ->
- fsck(Fname, default).
-
-fsck(Fname, Version) ->
catch begin
{ok, Fd, FH} = read_file_header(Fname, read, false),
?DEBUGF("FileHeader: ~p~n", [FH]),
- case (FH#fileheader.mod):check_file_header(FH, Fd) of
+ case dets_v9:check_file_header(FH, Fd) of
{error, not_closed} ->
- fsck(Fd, make_ref(), Fname, FH, default, default, Version);
- {ok, _Head, _Extra} ->
- fsck(Fd, make_ref(), Fname, FH, default, default, Version);
+ fsck(Fd, make_ref(), Fname, FH, default, default);
+ {ok, _Head} ->
+ fsck(Fd, make_ref(), Fname, FH, default, default);
Error ->
Error
end
@@ -372,7 +368,7 @@ info(Tab) ->
Item :: 'access' | 'auto_save' | 'bchunk_format'
| 'hash' | 'file_size' | 'filename' | 'keypos' | 'memory'
| 'no_keys' | 'no_objects' | 'no_slots' | 'owner' | 'ram_file'
- | 'safe_fixed' | 'safe_fixed_monotonic_time' | 'size' | 'type' | 'version',
+ | 'safe_fixed' | 'safe_fixed_monotonic_time' | 'size' | 'type',
Value :: term().
info(Tab, owner) ->
@@ -640,8 +636,7 @@ open_file(File) ->
| {'keypos', keypos()}
| {'ram_file', boolean()}
| {'repair', boolean() | 'force'}
- | {'type', type()}
- | {'version', version()},
+ | {'type', type()},
Reason :: term().
open_file(Tab, Args) when is_list(Args) ->
@@ -674,13 +669,13 @@ remove_user(Pid, From) ->
Continuation2 :: select_cont(),
MatchSpec :: match_spec().
-repair_continuation(#dets_cont{match_program = B}=Cont, MS)
- when is_binary(B) ->
+repair_continuation(#dets_cont{match_program = {match_spec, B}}=Cont, MS) ->
case ets:is_compiled_ms(B) of
true ->
Cont;
false ->
- Cont#dets_cont{match_program = ets:match_spec_compile(MS)}
+ Cont#dets_cont{match_program = {match_spec,
+ ets:match_spec_compile(MS)}}
end;
repair_continuation(#dets_cont{}=Cont, _MS) ->
Cont;
@@ -999,7 +994,9 @@ init_chunk_match(Tab, Pat, What, N, Safe) when is_integer(N), N >= 0;
case req(Proc, {match, MP, Spec, N, Safe}) of
{done, L} ->
{L, #dets_cont{tab = Tab, proc = Proc,
- what = What, bin = eof}};
+ what = What, bin = eof,
+ no_objs = default,
+ alloc = <<>>}};
{cont, State} ->
chunk_match(State#dets_cont{what = What,
tab = Tab,
@@ -1041,17 +1038,17 @@ chunk_match(#dets_cont{proc = Proc}=State, Safe) ->
do_foldl_bins(Bins, true) ->
foldl_bins(Bins, []);
-do_foldl_bins(Bins, MP) ->
+do_foldl_bins(Bins, {match_spec, MP}) ->
foldl_bins(Bins, MP, []).
foldl_bins([], Terms) ->
- %% Preserve time order (version 9).
+ %% Preserve time order.
Terms;
foldl_bins([Bin | Bins], Terms) ->
foldl_bins(Bins, [binary_to_term(Bin) | Terms]).
foldl_bins([], _MP, Terms) ->
- %% Preserve time order (version 9).
+ %% Preserve time order.
Terms;
foldl_bins([Bin | Bins], MP, Terms) ->
Term = binary_to_term(Bin),
@@ -1068,7 +1065,7 @@ compile_match_spec(select, ?PATTERN_TO_OBJECT_MATCH_SPEC('_') = Spec) ->
compile_match_spec(select, Spec) ->
case catch ets:match_spec_compile(Spec) of
X when is_binary(X) ->
- {Spec, X};
+ {Spec, {match_spec, X}};
_ ->
badarg
end;
@@ -1091,16 +1088,10 @@ defaults(Tab, Args) ->
delayed_write = ?DEFAULT_CACHE,
auto_save = timer:minutes(?DEFAULT_AUTOSAVE),
access = read_write,
- version = default,
debug = false},
Fun = fun repl/2,
Defaults = lists:foldl(Fun, Defaults0, Args),
- case Defaults#open_args.version of
- 8 ->
- Defaults#open_args{max_no_slots = default};
- _ ->
- is_comp_min_max(Defaults)
- end.
+ is_comp_min_max(Defaults).
to_list(T) when is_atom(T) -> atom_to_list(T);
to_list(T) -> T.
@@ -1131,7 +1122,6 @@ repl({file, File}, Defs) when is_atom(File) ->
repl({keypos, P}, Defs) when is_integer(P), P > 0 ->
Defs#open_args{keypos =P};
repl({max_no_slots, I}, Defs) ->
- %% Version 9 only.
MaxSlots = is_max_no_slots(I),
Defs#open_args{max_no_slots = MaxSlots};
repl({min_no_slots, I}, Defs) ->
@@ -1147,8 +1137,9 @@ repl({type, T}, Defs) ->
mem(T, [set, bag, duplicate_bag]),
Defs#open_args{type =T};
repl({version, Version}, Defs) ->
- V = is_version(Version),
- Defs#open_args{version = V};
+ %% Backwards compatibility.
+ is_version(Version),
+ Defs;
repl({debug, Bool}, Defs) ->
%% Not documented.
mem(Bool, [true, false]),
@@ -1164,16 +1155,15 @@ is_max_no_slots(default) -> default;
is_max_no_slots(I) when is_integer(I), I > 0, I < 1 bsl 31 -> I.
is_comp_min_max(Defs) ->
- #open_args{max_no_slots = Max, min_no_slots = Min, version = V} = Defs,
- case V of
- _ when Min =:= default -> Defs;
- _ when Max =:= default -> Defs;
- _ -> true = Min =< Max, Defs
+ #open_args{max_no_slots = Max, min_no_slots = Min} = Defs,
+ if
+ Min =:= default -> Defs;
+ Max =:= default -> Defs;
+ true -> true = Min =< Max, Defs
end.
-is_version(default) -> default;
-is_version(8) -> 8;
-is_version(9) -> 9.
+is_version(default) -> true;
+is_version(9) -> true.
mem(X, L) ->
case lists:member(X, L) of
@@ -1288,17 +1278,23 @@ badarg_exit(Reply, _A) ->
init(Parent, Server) ->
process_flag(trap_exit, true),
- open_file_loop(#head{parent = Parent, server = Server}).
-
-open_file_loop(Head) ->
%% The Dets server pretends the file is open before
%% internal_open() has been called, which means that unless the
%% internal_open message is applied first, other processes can
%% find the pid by calling dets_server:get_pid() and do things
%% before Head has been initialized properly.
receive
- ?DETS_CALL(From, {internal_open, _Ref, _Args}=Op) ->
- do_apply_op(Op, From, Head, 0)
+ ?DETS_CALL(From, {internal_open, Ref, Args}=Op) ->
+ try do_internal_open(Parent, Server, From, Ref, Args) of
+ Head ->
+ open_file_loop(Head, 0)
+ catch
+ exit:normal ->
+ exit(normal);
+ _:Bad ->
+ bug_found(no_name, Op, Bad, From),
+ exit(Bad) % give up
+ end
end.
open_file_loop(Head, N) when element(1, Head#head.update_mode) =:= error ->
@@ -1379,28 +1375,7 @@ do_apply_op(Op, From, Head, N) ->
exit:normal ->
exit(normal);
_:Bad ->
- Name = Head#head.name,
- case dets_utils:debug_mode() of
- true ->
- %% If stream_op/5 found more requests, this is not
- %% the last operation.
- error_logger:format
- ("** dets: Bug was found when accessing table ~w,~n"
- "** dets: operation was ~p and reply was ~w.~n"
- "** dets: Stacktrace: ~w~n",
- [Name, Op, Bad, erlang:get_stacktrace()]);
- false ->
- error_logger:format
- ("** dets: Bug was found when accessing table ~w~n",
- [Name])
- end,
- if
- From =/= self() ->
- From ! {self(), {error, {dets_bug, Name, Op, Bad}}},
- ok;
- true -> % auto_save | may_grow | {delayed_write, _}
- ok
- end,
+ bug_found(Head#head.name, Op, Bad, From),
open_file_loop(Head, N)
end.
@@ -1408,10 +1383,7 @@ apply_op(Op, From, Head, N) ->
case Op of
{add_user, Tab, OpenArgs}->
#open_args{file = Fname, type = Type, keypos = Keypos,
- ram_file = Ram, access = Access,
- version = Version} = OpenArgs,
- VersionOK = (Version =:= default) or
- (Head#head.version =:= Version),
+ ram_file = Ram, access = Access} = OpenArgs,
%% min_no_slots and max_no_slots are not tested
Res = if
Tab =:= Head#head.name,
@@ -1419,7 +1391,6 @@ apply_op(Op, From, Head, N) ->
Head#head.type =:= Type,
Head#head.ram_file =:= Ram,
Head#head.access =:= Access,
- VersionOK,
Fname =:= Head#head.filename ->
ok;
true ->
@@ -1475,21 +1446,14 @@ apply_op(Op, From, Head, N) ->
From ! {self(), Res},
ok;
{internal_open, Ref, Args} ->
- ?PROFILE(ep:do()),
- case do_open_file(Args, Head#head.parent, Head#head.server,Ref) of
- {ok, H2} ->
- From ! {self(), ok},
- H2;
- Error ->
- From ! {self(), Error},
- exit(normal)
- end;
+ do_internal_open(Head#head.parent, Head#head.server, From,
+ Ref, Args);
may_grow when Head#head.update_mode =/= saved ->
if
Head#head.update_mode =:= dirty ->
%% Won't grow more if the table is full.
{H2, _Res} =
- (Head#head.mod):may_grow(Head, 0, many_times),
+ dets_v9:may_grow(Head, 0, many_times),
{N + 1, H2};
true ->
ok
@@ -1519,21 +1483,10 @@ apply_op(Op, From, Head, N) ->
From ! {self(), Res},
erlang:garbage_collect(),
{0, H2};
- {delete_key, Keys} when Head#head.update_mode =:= dirty ->
- if
- Head#head.version =:= 8 ->
- {H2, Res} = fdelete_key(Head, Keys),
- From ! {self(), Res},
- {N + 1, H2};
- true ->
- stream_op(Op, From, [], Head, N)
- end;
+ {delete_key, _Keys} when Head#head.update_mode =:= dirty ->
+ stream_op(Op, From, [], Head, N);
{delete_object, Objs} when Head#head.update_mode =:= dirty ->
case check_objects(Objs, Head#head.keypos) of
- true when Head#head.version =:= 8 ->
- {H2, Res} = fdelete_object(Head, Objs),
- From ! {self(), Res},
- {N + 1, H2};
true ->
stream_op(Op, From, [], Head, N);
false ->
@@ -1551,10 +1504,6 @@ apply_op(Op, From, Head, N) ->
H2;
{insert, Objs} when Head#head.update_mode =:= dirty ->
case check_objects(Objs, Head#head.keypos) of
- true when Head#head.version =:= 8 ->
- {H2, Res} = finsert(Head, Objs),
- From ! {self(), Res},
- {N + 1, H2};
true ->
stream_op(Op, From, [], Head, N);
false ->
@@ -1565,10 +1514,6 @@ apply_op(Op, From, Head, N) ->
{H2, Res} = finsert_new(Head, Objs),
From ! {self(), Res},
{N + 1, H2};
- {lookup_keys, Keys} when Head#head.version =:= 8 ->
- {H2, Res} = flookup_keys(Head, Keys),
- From ! {self(), Res},
- H2;
{lookup_keys, _Keys} ->
stream_op(Op, From, [], Head, N);
{match_init, State, Safe} ->
@@ -1584,10 +1529,6 @@ apply_op(Op, From, Head, N) ->
{H2, Res} = fmatch(Head, MP, Spec, NObjs, Safe, From),
From ! {self(), Res},
H2;
- {member, Key} when Head#head.version =:= 8 ->
- {H2, Res} = fmember(Head, Key),
- From ! {self(), Res},
- H2;
{member, _Key} = Op ->
stream_op(Op, From, [], Head, N);
{next, Key} ->
@@ -1628,7 +1569,7 @@ apply_op(Op, From, Head, N) ->
apply_op(WriteOp, From, H2, 0);
WriteOp when Head#head.access =:= read_write,
Head#head.update_mode =:= saved ->
- case catch (Head#head.mod):mark_dirty(Head) of
+ case catch dets_v9:mark_dirty(Head) of
ok ->
start_auto_save_timer(Head),
H2 = Head#head{update_mode = dirty},
@@ -1643,6 +1584,40 @@ apply_op(Op, From, Head, N) ->
ok
end.
+bug_found(Name, Op, Bad, From) ->
+ case dets_utils:debug_mode() of
+ true ->
+ %% If stream_op/5 found more requests, this is not
+ %% the last operation.
+ error_logger:format
+ ("** dets: Bug was found when accessing table ~w,~n"
+ "** dets: operation was ~p and reply was ~w.~n"
+ "** dets: Stacktrace: ~w~n",
+ [Name, Op, Bad, erlang:get_stacktrace()]);
+ false ->
+ error_logger:format
+ ("** dets: Bug was found when accessing table ~w~n",
+ [Name])
+ end,
+ if
+ From =/= self() ->
+ From ! {self(), {error, {dets_bug, Name, Op, Bad}}},
+ ok;
+ true -> % auto_save | may_grow | {delayed_write, _}
+ ok
+ end.
+
+do_internal_open(Parent, Server, From, Ref, Args) ->
+ ?PROFILE(ep:do()),
+ case do_open_file(Args, Parent, Server, Ref) of
+ {ok, Head} ->
+ From ! {self(), ok},
+ Head;
+ Error ->
+ From ! {self(), Error},
+ exit(normal)
+ end.
+
start_auto_save_timer(Head) when Head#head.auto_save =:= infinity ->
ok;
start_auto_save_timer(Head) ->
@@ -1650,7 +1625,7 @@ start_auto_save_timer(Head) ->
_Ref = erlang:send_after(Millis, self(), ?DETS_CALL(self(), auto_save)),
ok.
-%% Version 9: Peek the message queue and try to evaluate several
+%% Peek the message queue and try to evaluate several
%% lookup requests in parallel. Evalute delete_object, delete and
%% insert as well.
stream_op(Op, Pid, Pids, Head, N) ->
@@ -1760,7 +1735,7 @@ lookup_reply(P, O) ->
%% Callback functions for system messages handling.
%%-----------------------------------------------------------------
system_continue(_Parent, _, Head) ->
- open_file_loop(Head).
+ open_file_loop(Head, 0).
system_terminate(Reason, _Parent, _, Head) ->
_NewHead = do_stop(Head),
@@ -1793,7 +1768,8 @@ read_file_header(FileName, Access, RamFile) ->
dets_utils:pread_close(Fd, FileName, ?FILE_FORMAT_VERSION_POS, 4),
if
Version =< 8 ->
- dets_v8:read_file_header(Fd, FileName);
+ _ = file:close(Fd),
+ throw({error, {format_8_no_longer_supported, FileName}});
Version =:= 9 ->
dets_v9:read_file_header(Fd, FileName);
true ->
@@ -1820,7 +1796,7 @@ perform_save(Head, DoSync) when Head#head.update_mode =:= dirty;
Head#head.update_mode =:= new_dirty ->
case catch begin
{Head1, []} = write_cache(Head),
- {Head2, ok} = (Head1#head.mod):do_perform_save(Head1),
+ {Head2, ok} = dets_v9:do_perform_save(Head1),
ok = ensure_written(Head2, DoSync),
{Head2#head{update_mode = saved}, ok}
end of
@@ -1853,7 +1829,7 @@ ensure_written(Head, false) when not Head#head.ram_file ->
do_bchunk_init(Head, Tab) ->
case catch write_cache(Head) of
{H2, []} ->
- case (H2#head.mod):table_parameters(H2) of
+ case dets_v9:table_parameters(H2) of
undefined ->
{H2, {error, old_version}};
Parms ->
@@ -1862,9 +1838,9 @@ do_bchunk_init(Head, Tab) ->
L =:= <<>> -> eof;
true -> <<>>
end,
- C0 = #dets_cont{no_objs = default, bin = Bin, alloc = L},
BinParms = term_to_binary(Parms),
- {H2, {C0#dets_cont{tab = Tab, proc = self(),what = bchunk},
+ {H2, {#dets_cont{no_objs = default, bin = Bin, alloc = L,
+ tab = Tab, proc = self(),what = bchunk},
[BinParms]}}
end;
{NewHead, _} = HeadError when is_record(NewHead, head) ->
@@ -1904,16 +1880,8 @@ do_delete_all_objects(Head) ->
max_no_slots = MaxSlots, cache = Cache} = Head,
CacheSz = dets_utils:cache_size(Cache),
ok = dets_utils:truncate(Fd, Fname, bof),
- (Head#head.mod):initiate_file(Fd, Tab, Fname, Type, Kp, MinSlots, MaxSlots,
- Ram, CacheSz, Auto, true).
-
-%% -> {NewHead, Reply}, Reply = ok | Error.
-fdelete_key(Head, Keys) ->
- do_delete(Head, Keys, delete_key).
-
-%% -> {NewHead, Reply}, Reply = ok | badarg | Error.
-fdelete_object(Head, Objects) ->
- do_delete(Head, Objects, delete_object).
+ dets_v9:initiate_file(Fd, Tab, Fname, Type, Kp, MinSlots, MaxSlots,
+ Ram, CacheSz, Auto, true).
ffirst(H) ->
Ref = make_ref(),
@@ -1930,7 +1898,7 @@ ffirst1(H) ->
ffirst(NH, 0).
ffirst(H, Slot) ->
- case (H#head.mod):slot_objs(H, Slot) of
+ case dets_v9:slot_objs(H, Slot) of
'$end_of_table' -> {H, '$end_of_table'};
[] -> ffirst(H, Slot+1);
[X|_] -> {H, element(H#head.keypos, X)}
@@ -2067,7 +2035,7 @@ finfo(H, auto_save) -> {H, H#head.auto_save};
finfo(H, bchunk_format) ->
case catch write_cache(H) of
{H2, []} ->
- case (H2#head.mod):table_parameters(H2) of
+ case dets_v9:table_parameters(H2) of
undefined = Undef ->
{H2, Undef};
Parms ->
@@ -2100,7 +2068,7 @@ finfo(H, no_keys) ->
{H2, _} = HeadError when is_record(H2, head) ->
HeadError
end;
-finfo(H, no_slots) -> {H, (H#head.mod):no_slots(H)};
+finfo(H, no_slots) -> {H, dets_v9:no_slots(H)};
finfo(H, pid) -> {H, self()};
finfo(H, ram_file) -> {H, H#head.ram_file};
finfo(H, safe_fixed) ->
@@ -2127,7 +2095,7 @@ finfo(H, size) ->
HeadError
end;
finfo(H, type) -> {H, H#head.type};
-finfo(H, version) -> {H, H#head.version};
+finfo(H, version) -> {H, 9};
finfo(H, _) -> {H, undefined}.
file_size(Fd, FileName) ->
@@ -2136,8 +2104,6 @@ file_size(Fd, FileName) ->
test_bchunk_format(_Head, undefined) ->
false;
-test_bchunk_format(Head, _Term) when Head#head.version =:= 8 ->
- false;
test_bchunk_format(Head, Term) ->
dets_v9:try_bchunk_header(Term, Head) =/= not_ok.
@@ -2206,7 +2172,7 @@ do_finit(Head, Init, Format, NoSlots) ->
#head{fptr = Fd, type = Type, keypos = Kp, auto_save = Auto,
cache = Cache, filename = Fname, ram_file = Ram,
min_no_slots = MinSlots0, max_no_slots = MaxSlots,
- name = Tab, update_mode = UpdateMode, mod = HMod} = Head,
+ name = Tab, update_mode = UpdateMode} = Head,
CacheSz = dets_utils:cache_size(Cache),
{How, Head1} =
case Format of
@@ -2219,9 +2185,10 @@ do_finit(Head, Init, Format, NoSlots) ->
{general_init, Head};
true ->
ok = dets_utils:truncate(Fd, Fname, bof),
- {ok, H} = HMod:initiate_file(Fd, Tab, Fname, Type, Kp,
- MinSlots, MaxSlots, Ram,
- CacheSz, Auto, false),
+ {ok, H} =
+ dets_v9:initiate_file(Fd, Tab, Fname, Type, Kp,
+ MinSlots, MaxSlots, Ram,
+ CacheSz, Auto, false),
{general_init, H}
end;
bchunk ->
@@ -2230,7 +2197,7 @@ do_finit(Head, Init, Format, NoSlots) ->
end,
case How of
bchunk_init ->
- case HMod:bchunk_init(Head1, Init) of
+ case dets_v9:bchunk_init(Head1, Init) of
{ok, NewHead} ->
{ok, NewHead#head{update_mode = dirty}};
Error ->
@@ -2238,10 +2205,10 @@ do_finit(Head, Init, Format, NoSlots) ->
end;
general_init ->
Cntrs = ets:new(dets_init, []),
- Input = HMod:bulk_input(Head1, Init, Cntrs),
+ Input = dets_v9:bulk_input(Head1, Init, Cntrs),
SlotNumbers = {Head1#head.min_no_slots, bulk_init, MaxSlots},
{Reply, SizeData} =
- do_sort(Head1, SlotNumbers, Input, Cntrs, Fname, not_used),
+ do_sort(Head1, SlotNumbers, Input, Cntrs, Fname),
Bulk = true,
case Reply of
{ok, NoDups, H1} ->
@@ -2297,7 +2264,8 @@ fmatch(Head, MP, Spec, N, Safe, From) ->
{NewHead, Reply} = flookup_keys(Head, Keys),
case Reply of
Objs when is_list(Objs) ->
- MatchingObjs = ets:match_spec_run(Objs, MP),
+ {match_spec, MS} = MP,
+ MatchingObjs = ets:match_spec_run(Objs, MS),
{NewHead, {done, MatchingObjs}};
Error ->
{NewHead, Error}
@@ -2377,7 +2345,7 @@ fmatch_delete(Head, C) ->
{[], _} ->
{Head, {done, 0}};
{RTs, NC} ->
- MP = C#dets_cont.match_program,
+ {match_spec, MP} = C#dets_cont.match_program,
case catch filter_binary_terms(RTs, MP, []) of
{'EXIT', _} ->
Bad = dets_utils:bad_object(fmatch_delete, RTs),
@@ -2405,7 +2373,7 @@ do_fmatch_delete_var_keys(Head, MP, _Spec, From) ->
C0 = init_scan(NewHead, default),
{NewHead, {cont, C0#dets_cont{match_program = MP}, 0}}.
-do_fmatch_constant_keys(Head, Keys, MP) ->
+do_fmatch_constant_keys(Head, Keys, {match_spec, MP}) ->
case flookup_keys(Head, Keys) of
{NewHead, ReadTerms} when is_list(ReadTerms) ->
Terms = filter_terms(ReadTerms, MP, []),
@@ -2454,18 +2422,8 @@ do_delete(Head, Things, What) ->
HeadError
end.
-fmember(Head, Key) ->
- case catch begin
- {Head2, [{_NoPid,Objs}]} =
- update_cache(Head, [Key], {lookup, nopid}),
- {Head2, Objs =/= []}
- end of
- {NewHead, _} = Reply when is_record(NewHead, head) ->
- Reply
- end.
-
fnext(Head, Key) ->
- Slot = (Head#head.mod):db_hash(Key, Head),
+ Slot = dets_v9:db_hash(Key, Head),
Ref = make_ref(),
case catch {Ref, fnext(Head, Key, Slot)} of
{Ref, {H, R}} ->
@@ -2476,7 +2434,7 @@ fnext(Head, Key) ->
fnext(H, Key, Slot) ->
{NH, []} = write_cache(H),
- case (H#head.mod):slot_objs(NH, Slot) of
+ case dets_v9:slot_objs(NH, Slot) of
'$end_of_table' -> {NH, '$end_of_table'};
L -> fnext_search(NH, Key, Slot, L)
end.
@@ -2490,7 +2448,7 @@ fnext_search(H, K, Slot, L) ->
%% We've got to continue to search for the next key in the next slot
fnext_slot(H, K, Slot) ->
- case (H#head.mod):slot_objs(H, Slot) of
+ case dets_v9:slot_objs(H, Slot) of
'$end_of_table' -> {H, '$end_of_table'};
[] -> fnext_slot(H, K, Slot+1);
L -> {H, element(H#head.keypos, hd(L))}
@@ -2518,11 +2476,10 @@ fopen2(Fname, Tab) ->
Acc = read_write,
Ram = false,
{ok, Fd, FH} = read_file_header(Fname, Acc, Ram),
- Mod = FH#fileheader.mod,
- Do = case Mod:check_file_header(FH, Fd) of
- {ok, Head1, ExtraInfo} ->
+ Do = case dets_v9:check_file_header(FH, Fd) of
+ {ok, Head1} ->
Head2 = Head1#head{filename = Fname},
- try {ok, Mod:init_freelist(Head2, ExtraInfo)}
+ try {ok, dets_v9:init_freelist(Head2)}
catch
throw:_ ->
{repair, " has bad free lists, repairing ..."}
@@ -2536,8 +2493,7 @@ fopen2(Fname, Tab) ->
case Do of
{repair, Mess} ->
io:format(user, "dets: file ~tp~s~n", [Fname, Mess]),
- Version = default,
- case fsck(Fd, Tab, Fname, FH, default, default, Version) of
+ case fsck(Fd, Tab, Fname, FH, default, default) of
ok ->
fopen2(Fname, Tab);
Error ->
@@ -2570,33 +2526,23 @@ fopen_existing_file(Tab, OpenArgs) ->
#open_args{file = Fname, type = Type, keypos = Kp, repair = Rep,
min_no_slots = MinSlots, max_no_slots = MaxSlots,
ram_file = Ram, delayed_write = CacheSz, auto_save =
- Auto, access = Acc, version = Version, debug = Debug} =
+ Auto, access = Acc, debug = Debug} =
OpenArgs,
{ok, Fd, FH} = read_file_header(Fname, Acc, Ram),
- V9 = (Version =:= 9) or (Version =:= default),
MinF = (MinSlots =:= default) or (MinSlots =:= FH#fileheader.min_no_slots),
MaxF = (MaxSlots =:= default) or (MaxSlots =:= FH#fileheader.max_no_slots),
- Mod = (FH#fileheader.mod),
- Wh = case Mod:check_file_header(FH, Fd) of
- {ok, Head, true} when Rep =:= force, Acc =:= read_write,
- FH#fileheader.version =:= 9,
- FH#fileheader.no_colls =/= undefined,
- MinF, MaxF, V9 ->
- {compact, Head, true};
- {ok, _Head, _Extra} when Rep =:= force, Acc =:= read ->
+ Wh = case dets_v9:check_file_header(FH, Fd) of
+ {ok, Head} when Rep =:= force, Acc =:= read_write,
+ FH#fileheader.no_colls =/= undefined,
+ MinF, MaxF ->
+ {compact, Head};
+ {ok, _Head} when Rep =:= force, Acc =:= read ->
throw({error, {access_mode, Fname}});
- {ok, Head, need_compacting} when Acc =:= read ->
- {final, Head, true}; % Version 8 only.
- {ok, _Head, need_compacting} when Rep =:= true ->
- %% The file needs to be compacted due to a very big
- %% and fragmented free_list. Version 8 only.
- M = " is now compacted ...",
- {repair, M};
- {ok, _Head, _Extra} when Rep =:= force ->
+ {ok, _Head} when Rep =:= force ->
M = ", repair forced.",
{repair, M};
- {ok, Head, ExtraInfo} ->
- {final, Head, ExtraInfo};
+ {ok, Head} ->
+ {final, Head};
{error, not_closed} when Rep =:= force, Acc =:= read_write ->
M = ", repair forced.",
{repair, M};
@@ -2605,17 +2551,13 @@ fopen_existing_file(Tab, OpenArgs) ->
{repair, M};
{error, not_closed} when Rep =:= false ->
throw({error, {needs_repair, Fname}});
- {error, version_bump} when Rep =:= true, Acc =:= read_write ->
- %% Version 8 only
- M = " old version, upgrading ...",
- {repair, M};
{error, Reason} ->
throw({error, {Reason, Fname}})
end,
Do = case Wh of
- {Tag, Hd, Extra} when Tag =:= final; Tag =:= compact ->
+ {Tag, Hd} when Tag =:= final; Tag =:= compact ->
Hd1 = Hd#head{filename = Fname},
- try {Tag, Mod:init_freelist(Hd1, Extra)}
+ try {Tag, dets_v9:init_freelist(Hd1)}
catch
throw:_ ->
{repair, " has bad free lists, repairing ..."}
@@ -2643,23 +2585,20 @@ fopen_existing_file(Tab, OpenArgs) ->
"now repairing ...~n", [Fname]),
{ok, Fd2, _FH} = read_file_header(Fname, Acc, Ram),
do_repair(Fd2, Tab, Fname, FH, MinSlots, MaxSlots,
- Version, OpenArgs)
+ OpenArgs)
end;
{repair, Mess} ->
io:format(user, "dets: file ~tp~s~n", [Fname, Mess]),
do_repair(Fd, Tab, Fname, FH, MinSlots, MaxSlots,
- Version, OpenArgs);
- _ when FH#fileheader.version =/= Version, Version =/= default ->
- throw({error, {version_mismatch, Fname}});
+ OpenArgs);
{final, H} ->
H1 = H#head{auto_save = Auto},
open_final(H1, Fname, Acc, Ram, CacheSz, Tab, Debug)
end.
-do_repair(Fd, Tab, Fname, FH, MinSlots, MaxSlots, Version, OpenArgs) ->
- case fsck(Fd, Tab, Fname, FH, MinSlots, MaxSlots, Version) of
+do_repair(Fd, Tab, Fname, FH, MinSlots, MaxSlots, OpenArgs) ->
+ case fsck(Fd, Tab, Fname, FH, MinSlots, MaxSlots) of
ok ->
- %% No need to update 'version'.
erlang:garbage_collect(),
fopen3(Tab, OpenArgs#open_args{repair = false});
Error ->
@@ -2673,8 +2612,8 @@ open_final(Head, Fname, Acc, Ram, CacheSz, Tab, Debug) ->
filename = Fname,
name = Tab,
cache = dets_utils:new_cache(CacheSz)},
- init_disk_map(Head1#head.version, Tab, Debug),
- (Head1#head.mod):cache_segps(Head1#head.fptr, Fname, Head1#head.next),
+ init_disk_map(Tab, Debug),
+ dets_v9:cache_segps(Head1#head.fptr, Fname, Head1#head.next),
check_growth(Head1),
{ok, Head1}.
@@ -2683,7 +2622,7 @@ fopen_init_file(Tab, OpenArgs) ->
#open_args{file = Fname, type = Type, keypos = Kp,
min_no_slots = MinSlotsArg, max_no_slots = MaxSlotsArg,
ram_file = Ram, delayed_write = CacheSz, auto_save = Auto,
- version = UseVersion, debug = Debug} = OpenArgs,
+ debug = Debug} = OpenArgs,
MinSlots = choose_no_slots(MinSlotsArg, ?DEFAULT_MIN_NO_SLOTS),
MaxSlots = choose_no_slots(MaxSlotsArg, ?DEFAULT_MAX_NO_SLOTS),
FileSpec = if
@@ -2691,20 +2630,11 @@ fopen_init_file(Tab, OpenArgs) ->
true -> Fname
end,
{ok, Fd} = dets_utils:open(FileSpec, open_args(read_write, Ram)),
- Version = if
- UseVersion =:= default ->
- case os:getenv("DETS_USE_FILE_FORMAT") of
- "8" -> 8;
- _ -> 9
- end;
- true ->
- UseVersion
- end,
- Mod = version2module(Version),
%% No need to truncate an empty file.
- init_disk_map(Version, Tab, Debug),
- case catch Mod:initiate_file(Fd, Tab, Fname, Type, Kp, MinSlots, MaxSlots,
- Ram, CacheSz, Auto, true) of
+ init_disk_map(Tab, Debug),
+ case catch dets_v9:initiate_file(Fd, Tab, Fname, Type, Kp,
+ MinSlots, MaxSlots,
+ Ram, CacheSz, Auto, true) of
{error, Reason} when Ram ->
_ = file:close(Fd),
throw({error, Reason});
@@ -2719,15 +2649,13 @@ fopen_init_file(Tab, OpenArgs) ->
end.
%% Debug.
-init_disk_map(9, Name, Debug) ->
+init_disk_map(Name, Debug) ->
case Debug orelse dets_utils:debug_mode() of
true ->
dets_utils:init_disk_map(Name);
false ->
ok
- end;
-init_disk_map(_Version, _Name, _Debug) ->
- ok.
+ end.
open_args(Access, RamFile) ->
A1 = case Access of
@@ -2740,15 +2668,7 @@ open_args(Access, RamFile) ->
end,
A1 ++ A2 ++ [binary, read].
-version2module(V) when V =< 8 -> dets_v8;
-version2module(9) -> dets_v9.
-
-module2version(dets_v8) -> 8;
-module2version(dets_v9) -> 9;
-module2version(not_used) -> 9.
-
%% -> ok | throw(Error)
-%% For version 9 tables only.
compact(SourceHead) ->
#head{name = Tab, filename = Fname, fptr = SFd, type = Type, keypos = Kp,
ram_file = Ram, auto_save = Auto} = SourceHead,
@@ -2759,7 +2679,7 @@ compact(SourceHead) ->
%% It is normally not possible to have two open tables in the same
%% process since the process dictionary is used for caching
%% segment pointers, but here is works anyway--when reading a file
- %% serially the pointers to not need to be used.
+ %% serially the pointers do not need to be used.
Head = case catch dets_v9:prep_table_copy(Fd, Tab, Tmp, Type, Kp, Ram,
CacheSz, Auto, TblParms) of
{ok, H} ->
@@ -2794,7 +2714,7 @@ compact(SourceHead) ->
%% -> ok | Error
%% Closes Fd.
-fsck(Fd, Tab, Fname, FH, MinSlotsArg, MaxSlotsArg, Version) ->
+fsck(Fd, Tab, Fname, FH, MinSlotsArg, MaxSlotsArg) ->
%% MinSlots and MaxSlots are the option values.
#fileheader{min_no_slots = MinSlotsFile,
max_no_slots = MaxSlotsFile} = FH,
@@ -2807,10 +2727,10 @@ fsck(Fd, Tab, Fname, FH, MinSlotsArg, MaxSlotsArg, Version) ->
%% If the number of objects (keys) turns out to be significantly
%% different from NoSlots, we try again with the correct number of
%% objects (keys).
- case fsck_try(Fd, Tab, FH, Fname, SlotNumbers, Version) of
+ case fsck_try(Fd, Tab, FH, Fname, SlotNumbers) of
{try_again, BetterNoSlots} ->
BetterSlotNumbers = {MinSlots, BetterNoSlots, MaxSlots},
- case fsck_try(Fd, Tab, FH, Fname, BetterSlotNumbers, Version) of
+ case fsck_try(Fd, Tab, FH, Fname, BetterSlotNumbers) of
{try_again, _} ->
_ = file:close(Fd),
{error, {cannot_repair, Fname}};
@@ -2829,7 +2749,7 @@ choose_no_slots(NoSlots, _) -> NoSlots.
%% Initiating a table using a fun and repairing (or converting) a
%% file are completely different things, but nevertheless the same
%% method is used in both cases...
-fsck_try(Fd, Tab, FH, Fname, SlotNumbers, Version) ->
+fsck_try(Fd, Tab, FH, Fname, SlotNumbers) ->
Tmp = tempfile(Fname),
#fileheader{type = Type, keypos = KeyPos} = FH,
{_MinSlots, EstNoSlots, MaxSlots} = SlotNumbers,
@@ -2838,7 +2758,7 @@ fsck_try(Fd, Tab, FH, Fname, SlotNumbers, Version) ->
max_no_slots = MaxSlots,
ram_file = false, delayed_write = ?DEFAULT_CACHE,
auto_save = infinity, access = read_write,
- version = Version, debug = false},
+ debug = false},
case catch fopen3(Tab, OpenArgs) of
{ok, Head} ->
case fsck_try_est(Head, Fd, Fname, SlotNumbers, FH) of
@@ -2888,10 +2808,9 @@ assure_no_file(File) ->
%% -> {ok, NewHead} | {try_again, integer()} | Error
fsck_try_est(Head, Fd, Fname, SlotNumbers, FH) ->
%% Mod is the module to use for reading input when repairing.
- Mod = FH#fileheader.mod,
Cntrs = ets:new(dets_repair, []),
- Input = Mod:fsck_input(Head, Fd, Cntrs, FH),
- {Reply, SizeData} = do_sort(Head, SlotNumbers, Input, Cntrs, Fname, Mod),
+ Input = dets_v9:fsck_input(Head, Fd, Cntrs, FH),
+ {Reply, SizeData} = do_sort(Head, SlotNumbers, Input, Cntrs, Fname),
Bulk = false,
case Reply of
{ok, NoDups, H1} ->
@@ -2906,14 +2825,13 @@ fsck_try_est(Head, Fd, Fname, SlotNumbers, FH) ->
Else
end.
-do_sort(Head, SlotNumbers, Input, Cntrs, Fname, Mod) ->
- OldV = module2version(Mod),
+do_sort(Head, SlotNumbers, Input, Cntrs, Fname) ->
%% output_objs/4 replaces {LogSize,NoObjects} in Cntrs by
%% {LogSize,Position,Data,NoObjects | NoCollections}.
%% Data = {FileName,FileDescriptor} | [object()]
- %% For small tables Data may be a list of objects which is more
+ %% For small tables Data can be a list of objects which is more
%% efficient since no temporary files are created.
- Output = (Head#head.mod):output_objs(OldV, Head, SlotNumbers, Cntrs),
+ Output = dets_v9:output_objs(Head, SlotNumbers, Cntrs),
TmpDir = filename:dirname(Fname),
Reply = (catch file_sorter:sort(Input, Output,
[{format, binary},{tmpdir, TmpDir}])),
@@ -2954,13 +2872,6 @@ fsck_copy1([SzData | L], Head, Bulk, NoDups) ->
{ok, Copied} when Copied =:= ExpectedSize;
NoObjects =:= 0 -> % the segments
fsck_copy1(L, Head, Bulk, NoDups);
- {ok, Copied} when Bulk, Head#head.version =:= 8 ->
- NoZeros = ExpectedSize - Copied,
- Dups = NoZeros div Size,
- Addr = Pos+Copied,
- NewHead = free_n_objects(Head, Addr, Size-1, NoDups),
- NewNoDups = NoDups - Dups,
- fsck_copy1(L, NewHead, Bulk, NewNoDups);
{ok, _Copied} -> % should never happen
close_files(Bulk, L, Head),
Reason = if Bulk -> initialization_failed;
@@ -2975,13 +2886,6 @@ fsck_copy1([], Head, _Bulk, NoDups) when NoDups =/= 0 ->
fsck_copy1([], Head, _Bulk, _NoDups) ->
{ok, Head#head{update_mode = dirty}}.
-free_n_objects(Head, _Addr, _Size, 0) ->
- Head;
-free_n_objects(Head, Addr, Size, N) ->
- {NewHead, _} = dets_utils:free(Head, Addr, Size),
- NewAddr = Addr + Size + 1,
- free_n_objects(NewHead, NewAddr, Size, N-1).
-
close_files(false, SizeData, Head) ->
_ = file:close(Head#head.fptr),
close_files(true, SizeData, Head);
@@ -3000,7 +2904,7 @@ close_tmp(Fd) ->
fslot(H, Slot) ->
case catch begin
{NH, []} = write_cache(H),
- Objs = (NH#head.mod):slot_objs(NH, Slot),
+ Objs = dets_v9:slot_objs(NH, Slot),
{NH, Objs}
end of
{NewHead, _Objects} = Reply when is_record(NewHead, head) ->
@@ -3050,7 +2954,7 @@ where_is_object(Head, Object) ->
true ->
case catch write_cache(Head) of
{NewHead, []} ->
- {NewHead, (Head#head.mod):find_object(NewHead, Object)};
+ {NewHead, dets_v9:find_object(NewHead, Object)};
{NewHead, _} = HeadError when is_record(NewHead, head) ->
HeadError
end;
@@ -3063,13 +2967,9 @@ check_objects([T | Ts], Kp) when tuple_size(T) >= Kp ->
check_objects(L, _Kp) ->
L =:= [].
-no_things(Head) when Head#head.no_keys =:= undefined ->
- Head#head.no_objects;
no_things(Head) ->
Head#head.no_keys.
-file_no_things(FH) when FH#fileheader.no_keys =:= undefined ->
- FH#fileheader.no_objects;
file_no_things(FH) ->
FH#fileheader.no_keys.
@@ -3110,7 +3010,7 @@ update_cache(Head, ToAdd) ->
if
Lookup; NewSize >= Cache#cache.tsize ->
%% The cache is considered full, or some lookup.
- {NewHead, LU, PwriteList} = (Head#head.mod):write_cache(Head1),
+ {NewHead, LU, PwriteList} = dets_v9:write_cache(Head1),
{NewHead, Found ++ LU, PwriteList};
NewC =:= [] ->
{Head1, Found, []};
@@ -3195,7 +3095,7 @@ delayed_write(Head, WrTime) ->
%% -> {NewHead, [LookedUpObject]} | throw({NewHead, Error})
write_cache(Head) ->
- {Head1, LU, PwriteList} = (Head#head.mod):write_cache(Head),
+ {Head1, LU, PwriteList} = dets_v9:write_cache(Head),
{NewHead, ok} = dets_utils:pwrite(Head1, PwriteList),
{NewHead, LU}.
@@ -3248,7 +3148,7 @@ scan(Head, C) -> % when is_record(C, dets_cont)
scan(Bin, Head, From, To, L, [], R, {C, Head#head.type}).
scan(Bin, H, From, To, L, Ts, R, {C0, Type} = C) ->
- case (H#head.mod):scan_objs(H, Bin, From, To, L, Ts, R, Type) of
+ case dets_v9:scan_objs(H, Bin, From, To, L, Ts, R, Type) of
{more, NFrom, NTo, NL, NTs, NR, Sz} ->
scan_read(H, NFrom, NTo, Sz, NL, NTs, NR, C);
{stop, <<>>=B, NFrom, NTo, <<>>=NL, NTs} ->
@@ -3317,7 +3217,7 @@ file_info(FileName) ->
case catch read_file_header(FileName, read, false) of
{ok, Fd, FH} ->
_ = file:close(Fd),
- (FH#fileheader.mod):file_info(FH);
+ dets_v9:file_info(FH);
Other ->
Other
end.
@@ -3332,15 +3232,13 @@ get_head_field(Fd, Field) ->
view(FileName) ->
case catch read_file_header(FileName, read, false) of
{ok, Fd, FH} ->
- Mod = FH#fileheader.mod,
- try Mod:check_file_header(FH, Fd) of
- {ok, H0, ExtraInfo} ->
- Mod = FH#fileheader.mod,
- case Mod:check_file_header(FH, Fd) of
- {ok, H0, ExtraInfo} ->
- H = Mod:init_freelist(H0, ExtraInfo),
+ try dets_v9:check_file_header(FH, Fd) of
+ {ok, H0} ->
+ case dets_v9:check_file_header(FH, Fd) of
+ {ok, H0} ->
+ H = dets_v9:init_freelist(H0),
v_free_list(H),
- Mod:v_segments(H),
+ dets_v9:v_segments(H),
ok;
X ->
X
diff --git a/lib/stdlib/src/dets.hrl b/lib/stdlib/src/dets.hrl
index 6ebeb96156..b5e732b08f 100644
--- a/lib/stdlib/src/dets.hrl
+++ b/lib/stdlib/src/dets.hrl
@@ -21,7 +21,7 @@
-define(DEFAULT_MIN_NO_SLOTS, 256).
-define(DEFAULT_MAX_NO_SLOTS, 32*1024*1024).
-define(DEFAULT_AUTOSAVE, 3). % minutes
--define(DEFAULT_CACHE, {3000, 14000}). % {delay,size} in {milliseconds,bytes}
+-define(DEFAULT_CACHE, {3000, 14000}). % cache_parms()
%% Type.
-define(SET, 1).
@@ -46,83 +46,111 @@
-define(DETS_CALL(Pid, Req), {'$dets_call', Pid, Req}).
+-type access() :: 'read' | 'read_write'.
+-type auto_save() :: 'infinity' | non_neg_integer().
+-type hash_bif() :: 'phash' | 'phash2'.
+-type keypos() :: pos_integer().
+-type no_colls() :: [{LogSize :: non_neg_integer(),
+ NoCollections :: non_neg_integer()}].
+-type no_slots() :: 'default' | non_neg_integer().
+-type tab_name() :: term().
+-type type() :: 'bag' | 'duplicate_bag' | 'set'.
+-type update_mode() :: 'dirty'
+ | 'new_dirty'
+ | 'saved'
+ | {'error', Reason :: term()}.
+
%% Record holding the file header and more.
-record(head, {
- m, % size
- m2, % m * 2
- next, % next position for growth (segm mgmt only)
- fptr, % the file descriptor
- no_objects, % number of objects in table,
- no_keys, % number of keys (version 9 only)
- maxobjsize, % 2-log of the size of the biggest object
- % collection (version 9 only)
+ m :: non_neg_integer(), % size
+ m2 :: non_neg_integer(), % m * 2
+ next :: non_neg_integer(), % next position for growth
+ % (segm mgmt only)
+ fptr :: file:fd(), % the file descriptor
+ no_objects :: non_neg_integer() , % number of objects in table,
+ no_keys :: non_neg_integer(), % number of keys
+ maxobjsize :: 'undefined' | non_neg_integer(), % 2-log of
+ % the size of the biggest object collection
n, % split indicator
- type, % set | bag | duplicate_bag
- keypos, % default is 1 as for ets
- freelists, % tuple of free lists of buddies
- % if fixed =/= false, then a pair of freelists
- freelists_p, % cached FreelistsPointer
- no_collections, % [{LogSize,NoCollections}] | undefined; number of
- % object collections per size (version 9(b))
- auto_save, % Integer | infinity
- update_mode, % saved | dirty | new_dirty | {error, Reason}
- fixed = false, % false | {now_time(), [{pid(),Counter}]}
- % time of first fix, and number of fixes per process
- hash_bif, % hash bif used for this file (phash2, phash, hash)
- has_md5, % whether the header has an MD5 sum (version 9(c))
- min_no_slots, % minimum number of slots (default or integer)
- max_no_slots, % maximum number of slots (default or integer)
- cache, % cache(). Write cache.
-
- filename, % name of the file being used
- access = read_write, % read | read_write
- ram_file = false, % true | false
- name, % the name of the table
-
- parent, % The supervisor of Dets processes.
- server, % The creator of Dets processes.
-
- %% Depending on the file format:
- version,
- mod,
- bump,
- base
+ type :: type(),
+ keypos :: keypos(), % default is 1 as for ets
+ freelists :: 'undefined'
+ | tuple(), % tuple of free lists of buddies
+ % if fixed =/= false, then a pair of freelists
+ freelists_p :: 'undefined'
+ | non_neg_integer(), % cached FreelistsPointer
+ no_collections :: 'undefined'
+ | no_colls(), % number of object collections
+ % per size (version 9(b))
+ auto_save :: auto_save(),
+ update_mode :: update_mode(),
+ fixed = false :: 'false'
+ | {{integer(), integer()}, % time of first fix,
+ [{pid(), % and number of fixes per process
+ non_neg_integer()}]},
+ hash_bif :: hash_bif(), % hash bif used for this file
+ has_md5 :: boolean(), % whether the header has
+ % an MD5 sum (version 9(c))
+ min_no_slots :: no_slots(), % minimum number of slots
+ max_no_slots :: no_slots(), % maximum number of slots
+ cache :: 'undefined' | cache(), % Write cache.
+
+ filename :: file:name(), % name of the file being used
+ access = read_write :: access(),
+ ram_file = false :: boolean(),
+ name :: tab_name(), % the name of the table
+
+ parent :: 'undefined' | pid(), % The supervisor of Dets processes.
+ server :: 'undefined' | pid(), % The creator of Dets processes.
+
+ bump :: non_neg_integer(),
+ base :: non_neg_integer()
}).
%% Info extracted from the file header.
-record(fileheader, {
- freelist,
- fl_base,
- cookie,
- closed_properly,
- type,
- version,
- m,
- next,
- keypos,
- no_objects,
- no_keys,
- min_no_slots,
- max_no_slots,
- no_colls,
- hash_method,
- read_md5,
- has_md5,
- md5,
- trailer,
- eof,
- n,
- mod
+ freelist :: non_neg_integer(),
+ fl_base :: non_neg_integer(),
+ cookie :: non_neg_integer(),
+ closed_properly :: non_neg_integer(),
+ type :: 'badtype' | type(),
+ version :: non_neg_integer(),
+ m :: non_neg_integer(),
+ next :: non_neg_integer(),
+ keypos :: keypos(),
+ no_objects :: non_neg_integer(),
+ no_keys :: non_neg_integer(),
+ min_no_slots :: non_neg_integer(),
+ max_no_slots :: non_neg_integer(),
+ no_colls :: 'undefined' | no_colls(),
+ hash_method :: non_neg_integer(),
+ read_md5 :: binary(),
+ has_md5 :: boolean(),
+ md5 :: binary(),
+ trailer :: non_neg_integer(),
+ eof :: non_neg_integer(),
+ n
}).
+-type delay() :: non_neg_integer().
+-type threshold() :: non_neg_integer().
+-type cache_parms() ::
+ {Delay :: delay(), % max time items are kept in RAM only,
+ % in milliseconds
+ Size :: threshold()}. % threshold size of cache, in bytes
+
%% Write Cache.
-record(cache, {
- cache, % [{Key,{Seq,Item}}], write cache, last item first
- csize, % current size of the cached items
- inserts, % upper limit on number of inserted keys
- wrtime, % last write or update time
- tsize, % threshold size of cache, in bytes
- delay % max time items are kept in RAM only, in milliseconds
+ cache :: % write cache, last item first
+ [{Key :: term(),
+ {Seq :: non_neg_integer(), Item :: term()}}],
+ csize :: non_neg_integer(), % current size of the cached items
+ inserts :: % upper limit on number of inserted keys
+ non_neg_integer(),
+ wrtime :: 'undefined' | integer(), % last write or update time
+ tsize :: threshold(), % threshold size of cache
+ delay :: delay() % max time items are kept in RAM only
}).
+-type cache() :: #cache{}.
diff --git a/lib/stdlib/src/dets_utils.erl b/lib/stdlib/src/dets_utils.erl
index 34a8ddddaa..da6ebd18f2 100644
--- a/lib/stdlib/src/dets_utils.erl
+++ b/lib/stdlib/src/dets_utils.erl
@@ -20,13 +20,13 @@
-module(dets_utils).
%% Utility functions common to several dets file formats.
-%% To be used from dets, dets_v8 and dets_v9 only.
+%% To be used from modules dets and dets_v9 only.
-export([cmp/2, msort/1, mkeysort/2, mkeysearch/3, family/1]).
-export([rename/2, pread/2, pread/4, ipread/3, pwrite/2, write/2,
truncate/2, position/2, sync/1, open/2, truncate/3, fwrite/3,
- write_file/2, position/3, position_close/3, pwrite/4,
+ write_file/2, position/3, position_close/3,
pwrite/3, pread_close/4, read_n/2, pread_n/3, read_4/2]).
-export([code_to_type/1, type_to_code/1]).
@@ -44,8 +44,6 @@
all_allocated_as_list/1, find_allocated/4, find_next_allocated/3,
log2/1, make_zeros/1]).
--export([init_slots_from_old_file/2]).
-
-export([list_to_tree/1, tree_to_bin/5]).
-compile({inline, [{sz2pos,1}, {adjust_addr,3}]}).
@@ -308,12 +306,6 @@ position_close(Fd, FileName, Pos) ->
OK -> OK
end.
-pwrite(Fd, FileName, Position, B) ->
- case file:pwrite(Fd, Position, B) of
- ok -> ok;
- Error -> file_error(FileName, {error, Error})
- end.
-
pwrite(Fd, FileName, Bins) ->
case file:pwrite(Fd, Bins) of
ok ->
@@ -478,20 +470,6 @@ new_cache({Delay, Size}) ->
%%% Ullman. I think buddy systems were invented by Knuth, a long
%%% time ago.
-init_slots_from_old_file([{Slot,Addr} | T], Ftab) ->
- init_slot(Slot+1,[{Slot,Addr} | T], Ftab);
-init_slots_from_old_file([], Ftab) ->
- Ftab.
-
-init_slot(_Slot,[], Ftab) ->
- Ftab; % should never happen
-init_slot(_Slot,[{_Addr,0}|T], Ftab) ->
- init_slots_from_old_file(T, Ftab);
-init_slot(Slot,[{_Slot1,Addr}|T], Ftab) ->
- Stree = element(Slot, Ftab),
- %% io:format("init_slot ~p:~p~n",[Slot, Addr]),
- init_slot(Slot,T,setelement(Slot, Ftab, bplus_insert(Stree, Addr))).
-
%%% The free lists are kept in RAM, and written to the end of the file
%%% from time to time. It is possible that a considerable amount of
%%% memory is used for a fragmented file.
diff --git a/lib/stdlib/src/dets_v8.erl b/lib/stdlib/src/dets_v8.erl
deleted file mode 100644
index 1bf53d91b1..0000000000
--- a/lib/stdlib/src/dets_v8.erl
+++ /dev/null
@@ -1,1594 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(dets_v8).
-
-%% Dets files, implementation part. This module handles versions up to
-%% and including 8(c). To be called from dets.erl only.
-
--export([mark_dirty/1, read_file_header/2,
- check_file_header/2, do_perform_save/1, initiate_file/11,
- init_freelist/2, fsck_input/4,
- bulk_input/3, output_objs/4, write_cache/1, may_grow/3,
- find_object/2, re_hash/2, slot_objs/2, scan_objs/8,
- db_hash/2, no_slots/1, table_parameters/1]).
-
--export([file_info/1, v_segments/1]).
-
--export([cache_segps/3]).
-
-%% For backward compatibility.
--export([sz2pos/1]).
-
--dialyzer(no_improper_lists).
-
--compile({inline, [{sz2pos,1},{scan_skip,7}]}).
--compile({inline, [{skip_bytes,5}, {get_segp,1}]}).
--compile({inline, [{wl_lookup,5}]}).
--compile({inline, [{actual_seg_size,0}]}).
-
--include("dets.hrl").
-
-%% The layout of the file is :
-%%
-%% bytes decsription
-%% ---------------------- File header
-%% 4 FreelistsPointer
-%% 4 Cookie
-%% 4 ClosedProperly (pos=8)
-%% 4 Type (pos=12)
-%% 4 Version (pos=16)
-%% 4 M
-%% 4 Next
-%% 4 KeyPos
-%% 4 NoObjects
-%% 4 N
-%% ------------------ end of file header
-%% 4*8192 SegmentArray
-%% ------------------
-%% 4*256 First segment
-%% ----------------------------- This is BASE.
-%% ??? Objects (free and alive)
-%% 4*256 Second segment (2 kB now, due to a bug)
-%% ??? Objects (free and alive)
-%% ... more objects and segments ...
-%% -----------------------------
-%% ??? Free lists
-%% -----------------------------
-%% 4 File size, in bytes.
-
-%% The first slot (0) in the segment array always points to the
-%% pre-allocated first segment.
-%% Before we can find an object we must find the slot where the
-%% object resides. Each slot is a (possibly empty) list (or chain) of
-%% objects that hash to the same slot. If the value stored in the
-%% slot is zero, the slot chain is empty. If the slot value is
-%% non-zero, the value points to a position in the file where the
-%% chain starts. Each object in a chain has the following layout:
-%%
-%% bytes decsription
-%% --------------------
-%% 4 Pointer to the next object of the chain.
-%% 4 Size of the object in bytes (Sz).
-%% 4 Status (FREE or ACTIVE)
-%% Sz Binary representing the object
-%%
-%% The status field is used while repairing a file (but not next or size).
-%%
-%%|---------------|
-%%| head |
-%%| |
-%%| |
-%%|_______________|
-%%| |------|
-%%|___seg ptr1____| |
-%%| | |
-%%|__ seg ptr 2___| |
-%%| | | segment 1
-%%| .... | V _____________
-%% | |
-%% | |
-%% |___slot 0 ____|
-%% | |
-%% |___slot 1 ____|-----|
-%% | | |
-%% | ..... | | 1:st obj in slot 1
-%% V segment 1
-%% |-----------|
-%% | next |
-%% |___________|
-%% | size |
-%% |___________|
-%% | status |
-%% |___________|
-%% | |
-%% | |
-%% | obj |
-%% | |
-
-%%%
-%%% File header
-%%%
-
--define(HEADSZ, 40). % The size of the file header, in bytes.
--define(SEGSZ, 256). % Size of a segment, in words.
--define(SEGSZ_LOG2, 8).
--define(SEGARRSZ, 8192). % Maximal number of segments.
--define(SEGADDR(SegN), (?HEADSZ + (4 * (SegN)))).
--define(BASE, ?SEGADDR((?SEGSZ + ?SEGARRSZ))).
--define(MAXOBJS, (?SEGSZ * ?SEGARRSZ)). % 2 M objects
-
--define(SLOT2SEG(S), ((S) bsr ?SEGSZ_LOG2)).
-
-%% BIG is used for hashing. BIG must be greater than the maximum
-%% number of slots, currently MAXOBJS.
--define(BIG, 16#ffffff).
-
-%% Hard coded positions into the file header:
--define(FREELIST_POS, 0).
--define(CLOSED_PROPERLY_POS, 8).
--define(D_POS, 20).
--define(NO_OBJECTS_POS, (?D_POS + 12)).
-
-%% The version of a dets file is indicated by the ClosedProperly
-%% field. Version 6 was used in the R1A release, and version 7 in the
-%% R1B release up to and including the R3B01 release. Both version 6
-%% and version 7 indicate properly closed files by the value
-%% CLOSED_PROPERLY.
-%%
-%% The current version, 8, has three sub-versions:
-%%
-%% - 8(a), indicated by the value CLOSED_PROPERLY (same as in versions 6
-%% and 7), introduced in R3B02;
-%% - 8(b), indicated by the value CLOSED_PROPERLY2(_NEED_COMPACTING),
-%% introduced in R5A and used up to and including R6A;
-%% - 8(c), indicated by the value CLOSED_PROPERLY_NEW_HASH(_NEED_COMPACTING),
-%% in use since R6B.
-%%
-%% The difference between the 8(a) and the 8(b) versions is the format
-%% used for free lists saved on dets files.
-%% The 8(c) version uses a different hashing algorithm, erlang:phash
-%% (former versions use erlang:hash).
-%% Version 8(b) files are only converted to version 8(c) if repair is
-%% done, so we need compatibility with 8(b) for a _long_ time.
-%%
-%% There are known bugs due to the fact that keys and objects are
-%% sometimes compared (==) and sometimes matched (=:=). The version
-%% used by default (9, see dets_v9.erl) does not have this problem.
-
--define(NOT_PROPERLY_CLOSED,0).
--define(CLOSED_PROPERLY,1).
--define(CLOSED_PROPERLY2,2).
--define(CLOSED_PROPERLY2_NEED_COMPACTING,3).
--define(CLOSED_PROPERLY_NEW_HASH,4).
--define(CLOSED_PROPERLY_NEW_HASH_NEED_COMPACTING,5).
-
--define(FILE_FORMAT_VERSION, 8).
--define(CAN_BUMP_BY_REPAIR, [6, 7]).
--define(CAN_CONVERT_FREELIST, [8]).
-
-%%%
-%%% Object header (next, size, status).
-%%%
-
--define(OHDSZ, 12). % The size of the object header, in bytes.
--define(STATUS_POS, 8). % Position of the status field.
-
-%% The size of each object is a multiple of 16.
-%% BUMP is used when repairing files.
--define(BUMP, 16).
-
--define(ReadAhead, 512).
-
-%%-define(DEBUGF(X,Y), io:format(X, Y)).
--define(DEBUGF(X,Y), void).
-
-%% -> ok | throw({NewHead,Error})
-mark_dirty(Head) ->
- Dirty = [{?CLOSED_PROPERLY_POS, <<?NOT_PROPERLY_CLOSED:32>>}],
- {_NewHead, ok} = dets_utils:pwrite(Head, Dirty),
- ok = dets_utils:sync(Head),
- {ok, _Pos} = dets_utils:position(Head, Head#head.freelists_p),
- ok = dets_utils:truncate(Head, cur).
-
-%% -> {ok, head()} | throw(Error)
-initiate_file(Fd, Tab, Fname, Type, Kp, MinSlots, MaxSlots,
- Ram, CacheSz, Auto, _DoInitSegments) ->
- Freelist = 0,
- Cookie = ?MAGIC,
- ClosedProperly = ?NOT_PROPERLY_CLOSED, % immediately overwritten
- Version = ?FILE_FORMAT_VERSION,
- Factor = est_no_segments(MinSlots),
- N = 0,
- M = Next = ?SEGSZ * Factor,
- NoObjects = 0,
- dets_utils:pwrite(Fd, Fname, 0,
- <<Freelist:32,
- Cookie:32,
- ClosedProperly:32,
- (dets_utils:type_to_code(Type)):32,
- Version:32,
- M:32,
- Next:32,
- Kp:32,
- NoObjects:32,
- N:32,
- 0:(?SEGARRSZ*4)/unit:8, % Initialize SegmentArray
- 0:(?SEGSZ*4)/unit:8>>), % Initialize first segment
- %% We must set the first slot of the segment pointer array to
- %% point to the first segment
- Pos = ?SEGADDR(0),
- SegP = (?HEADSZ + (4 * ?SEGARRSZ)),
- dets_utils:pwrite(Fd, Fname, Pos, <<SegP:32>>),
- segp_cache(Pos, SegP),
-
- Ftab = dets_utils:init_alloc(?BASE),
- H0 = #head{freelists=Ftab, fptr = Fd, base = ?BASE},
- {H1, Ws} = init_more_segments(H0, 1, Factor, undefined, []),
-
- %% This is not optimal but simple: always initiate the segments.
- dets_utils:pwrite(Fd, Fname, Ws),
-
- %% Return a new nice head structure
- Head = #head{
- m = M,
- m2 = M * 2,
- next = Next,
- fptr = Fd,
- no_objects = NoObjects,
- n = N,
- type = Type,
- update_mode = dirty,
- freelists = H1#head.freelists,
- auto_save = Auto,
- hash_bif = phash,
- keypos = Kp,
- min_no_slots = Factor * ?SEGSZ,
- max_no_slots = no_segs(MaxSlots) * ?SEGSZ,
-
- ram_file = Ram,
- filename = Fname,
- name = Tab,
- cache = dets_utils:new_cache(CacheSz),
- version = Version,
- bump = ?BUMP,
- base = ?BASE,
- mod = ?MODULE
- },
- {ok, Head}.
-
-est_no_segments(MinSlots) when 1 + ?SLOT2SEG(MinSlots) > ?SEGARRSZ ->
- ?SEGARRSZ;
-est_no_segments(MinSlots) ->
- 1 + ?SLOT2SEG(MinSlots).
-
-init_more_segments(Head, SegNo, Factor, undefined, Ws) when SegNo < Factor ->
- init_more_segments(Head, SegNo, Factor, seg_zero(), Ws);
-init_more_segments(Head, SegNo, Factor, SegZero, Ws) when SegNo < Factor ->
- {NewHead, W} = allocate_segment(Head, SegZero, SegNo),
- init_more_segments(NewHead, SegNo+1, Factor, SegZero, W++Ws);
-init_more_segments(Head, _SegNo, _Factor, _SegZero, Ws) ->
- {Head, Ws}.
-
-allocate_segment(Head, SegZero, SegNo) ->
- %% may throw error:
- {NewHead, Segment, _} = dets_utils:alloc(Head, 4 * ?SEGSZ),
- InitSegment = {Segment, SegZero},
- Pos = ?SEGADDR(SegNo),
- segp_cache(Pos, Segment),
- SegPointer = {Pos, <<Segment:32>>},
- {NewHead, [InitSegment, SegPointer]}.
-
-%% Read free lists (using a Buddy System) from file.
-init_freelist(Head, {convert_freelist,_Version}) ->
- %% This function converts the saved freelist of the form
- %% [{Slot1,Addr1},{Addr1,Addr2},...,{AddrN,0},{Slot2,Addr},...]
- %% i.e each slot is a linked list which ends with a 0.
- %% This is stored in a bplus_tree per Slot.
- %% Each Slot is a position in a tuple.
-
- Ftab = dets_utils:empty_free_lists(),
- Pos = Head#head.freelists_p,
- case catch prterm(Head, Pos, ?OHDSZ) of
- {0, _Sz, Term} ->
- FreeList1 = lists:reverse(Term),
- FreeList = dets_utils:init_slots_from_old_file(FreeList1, Ftab),
- Head#head{freelists = FreeList, base = ?BASE};
- _ ->
- throw({error, {bad_freelists, Head#head.filename}})
- end;
-init_freelist(Head, _) ->
- %% bplus_tree stored as is
- Pos = Head#head.freelists_p,
- case catch prterm(Head, Pos, ?OHDSZ) of
- {0, _Sz, Term} ->
- Head#head{freelists = Term, base = ?BASE};
- _ ->
- throw({error, {bad_freelists, Head#head.filename}})
- end.
-
-%% -> {ok, Fd, fileheader()} | throw(Error)
-read_file_header(Fd, FileName) ->
- {ok, Bin} = dets_utils:pread_close(Fd, FileName, 0, ?HEADSZ),
- [Freelist, Cookie, CP, Type2, Version, M, Next, Kp, NoObjects, N] =
- bin2ints(Bin),
- {ok, EOF} = dets_utils:position_close(Fd, FileName, eof),
- {ok, <<FileSize:32>>} = dets_utils:pread_close(Fd, FileName, EOF-4, 4),
- FH = #fileheader{freelist = Freelist,
- fl_base = ?BASE,
- cookie = Cookie,
- closed_properly = CP,
- type = dets_utils:code_to_type(Type2),
- version = Version,
- m = M,
- next = Next,
- keypos = Kp,
- no_objects = NoObjects,
- min_no_slots = ?DEFAULT_MIN_NO_SLOTS,
- max_no_slots = ?DEFAULT_MAX_NO_SLOTS,
- trailer = FileSize,
- eof = EOF,
- n = N,
- mod = ?MODULE},
- {ok, Fd, FH}.
-
-%% -> {ok, head(), ExtraInfo} | {error, Reason} (Reason lacking file name)
-%% ExtraInfo = {convert_freelist, Version} | true | need_compacting
-check_file_header(FH, Fd) ->
- Test =
- if
- FH#fileheader.cookie =/= ?MAGIC ->
- {error, not_a_dets_file};
- FH#fileheader.type =:= badtype ->
- {error, invalid_type_code};
- FH#fileheader.version =/= ?FILE_FORMAT_VERSION ->
- case lists:member(FH#fileheader.version,
- ?CAN_BUMP_BY_REPAIR) of
- true ->
- {error, version_bump};
- false ->
- {error, bad_version}
- end;
- FH#fileheader.trailer =/= FH#fileheader.eof ->
- {error, not_closed};
- FH#fileheader.closed_properly =:= ?CLOSED_PROPERLY ->
- case lists:member(FH#fileheader.version,
- ?CAN_CONVERT_FREELIST) of
- true ->
- {ok, {convert_freelist, FH#fileheader.version}, hash};
- false ->
- {error, not_closed} % should not happen
- end;
- FH#fileheader.closed_properly =:= ?CLOSED_PROPERLY2 ->
- {ok, true, hash};
- FH#fileheader.closed_properly =:=
- ?CLOSED_PROPERLY2_NEED_COMPACTING ->
- {ok, need_compacting, hash};
- FH#fileheader.closed_properly =:= ?CLOSED_PROPERLY_NEW_HASH ->
- {ok, true, phash};
- FH#fileheader.closed_properly =:=
- ?CLOSED_PROPERLY_NEW_HASH_NEED_COMPACTING ->
- {ok, need_compacting, phash};
- FH#fileheader.closed_properly =:= ?NOT_PROPERLY_CLOSED ->
- {error, not_closed};
- FH#fileheader.closed_properly >
- ?CLOSED_PROPERLY_NEW_HASH_NEED_COMPACTING ->
- {error, not_closed};
- true ->
- {error, not_a_dets_file}
- end,
- case Test of
- {ok, ExtraInfo, HashAlg} ->
- H = #head{
- m = FH#fileheader.m,
- m2 = FH#fileheader.m * 2,
- next = FH#fileheader.next,
- fptr = Fd,
- no_objects= FH#fileheader.no_objects,
- n = FH#fileheader.n,
- type = FH#fileheader.type,
- update_mode = saved,
- auto_save = infinity, % not saved on file
- fixed = false, % not saved on file
- freelists_p = FH#fileheader.freelist,
- hash_bif = HashAlg,
- keypos = FH#fileheader.keypos,
- min_no_slots = FH#fileheader.min_no_slots,
- max_no_slots = FH#fileheader.max_no_slots,
- version = ?FILE_FORMAT_VERSION,
- mod = ?MODULE,
- bump = ?BUMP,
- base = FH#fileheader.fl_base},
- {ok, H, ExtraInfo};
- Error ->
- Error
- end.
-
-cache_segps(Fd, FileName, M) ->
- NSegs = no_segs(M),
- {ok, Bin} = dets_utils:pread_close(Fd, FileName, ?HEADSZ, 4 * NSegs),
- Fun = fun(S, P) -> segp_cache(P, S), P+4 end,
- lists:foldl(Fun, ?HEADSZ, bin2ints(Bin)).
-
-no_segs(NoSlots) ->
- ?SLOT2SEG(NoSlots - 1) + 1.
-
-bin2ints(<<Int:32, B/binary>>) ->
- [Int | bin2ints(B)];
-bin2ints(<<>>) ->
- [].
-
-%%%
-%%% Repair, conversion and initialization of a dets file.
-%%%
-
-bulk_input(Head, InitFun, Cntrs) ->
- bulk_input(Head, InitFun, Cntrs, make_ref()).
-
-bulk_input(Head, InitFun, Cntrs, Ref) ->
- fun(close) ->
- ok;
- (read) ->
- case catch {Ref, InitFun(read)} of
- {Ref, end_of_input} ->
- end_of_input;
- {Ref, {L0, NewInitFun}} when is_list(L0),
- is_function(NewInitFun) ->
- Kp = Head#head.keypos,
- case catch bulk_objects(L0, Head, Cntrs, Kp, []) of
- {'EXIT', _Error} ->
- _ = (catch NewInitFun(close)),
- {error, invalid_objects_list};
- L ->
- {L, bulk_input(Head, NewInitFun, Cntrs, Ref)}
- end;
- {Ref, Value} ->
- {error, {init_fun, Value}};
- Error ->
- throw({thrown, Error})
- end
- end.
-
-bulk_objects([T | Ts], Head, Cntrs, Kp, L) ->
- BT = term_to_binary(T),
- Sz = byte_size(BT),
- LogSz = sz2pos(Sz+?OHDSZ),
- count_object(Cntrs, LogSz),
- Key = element(Kp, T),
- bulk_objects(Ts, Head, Cntrs, Kp, [make_object(Head, Key, LogSz, BT) | L]);
-bulk_objects([], _Head, _Cntrs, _Kp, L) ->
- L.
-
--define(FSCK_SEGMENT, 10000).
-
--define(DCT(D, CT), [D | CT]).
-
--define(VNEW(N, E), erlang:make_tuple(N, E)).
--define(VSET(I, V, E), setelement(I, V, E)).
--define(VGET(I, V), element(I, V)).
-
-%% OldVersion not used, assuming later versions have been converted already.
-output_objs(OldVersion, Head, SlotNumbers, Cntrs) ->
- fun(close) ->
- {ok, 0, Head};
- ([]) ->
- output_objs(OldVersion, Head, SlotNumbers, Cntrs);
- (L) ->
- %% Descending sizes.
- Count = lists:sort(ets:tab2list(Cntrs)),
- RCount = lists:reverse(Count),
- NoObjects = lists:foldl(fun({_Sz,No}, A) -> A + No end, 0, Count),
- {_, MinSlots, _} = SlotNumbers,
- if
- %% Using number of objects for bags and duplicate bags
- %% is not ideal; number of (unique) keys should be
- %% used instead. The effect is that there will be more
- %% segments than "necessary".
- MinSlots =/= bulk_init,
- abs(?SLOT2SEG(NoObjects) - ?SLOT2SEG(MinSlots)) > 5,
- (NoObjects < ?MAXOBJS) ->
- {try_again, NoObjects};
- true ->
- Head1 = Head#head{no_objects = NoObjects},
- SegSz = actual_seg_size(),
- {_, End, _} = dets_utils:alloc(Head, SegSz-1),
- %% Now {LogSize,NoObjects} in Cntrs is replaced by
- %% {LogSize,Position,{FileName,FileDescriptor},NoObjects}.
- {Head2, CT} = allocate_all_objects(Head1, RCount, Cntrs),
- [E | Es] = bin2term(L, []),
- {NE, Acc, DCT1} =
- output_slots(E, Es, [E], Head2, ?DCT(0, CT)),
- NDCT = write_all_sizes(DCT1, Cntrs),
- Max = ets:info(Cntrs, size),
- output_objs2(NE, Acc, Head2, Cntrs, NDCT, End, Max,Max)
- end
- end.
-
-output_objs2(E, Acc, Head, Cntrs, DCT, End, 0, MaxNoChunks) ->
- NDCT = write_all_sizes(DCT, Cntrs),
- output_objs2(E, Acc, Head, Cntrs, NDCT, End, MaxNoChunks, MaxNoChunks);
-output_objs2(E, Acc, Head, Cntrs, DCT, End, ChunkI, MaxNoChunks) ->
- fun(close) ->
- DCT1 = output_slot(Acc, Head, DCT),
- NDCT = write_all_sizes(DCT1, Cntrs),
- ?DCT(NoDups, CT) = NDCT,
- [SegAddr | []] = ?VGET(tuple_size(CT), CT),
- FinalZ = End - SegAddr,
- [{?FSCK_SEGMENT, _, {FileName, Fd}, _}] =
- ets:lookup(Cntrs, ?FSCK_SEGMENT),
- ok = dets_utils:fwrite(Fd, FileName,
- dets_utils:make_zeros(FinalZ)),
- NewHead = Head#head{no_objects = Head#head.no_objects - NoDups},
- {ok, NoDups, NewHead};
- (L) ->
- Es = bin2term(L, []),
- {NE, NAcc, NDCT} = output_slots(E, Es, Acc, Head, DCT),
- output_objs2(NE, NAcc, Head, Cntrs, NDCT, End,
- ChunkI-1, MaxNoChunks)
- end.
-
-%% By allocating bigger objects before smaller ones, holes in the
-%% buddy system memory map are avoided. Unfortunately, the segments
-%% are always allocated first, so if there are objects bigger than a
-%% segment, there is a hole to handle. (Haven't considered placing the
-%% segments among other objects of the same size.)
-allocate_all_objects(Head, Count, Cntrs) ->
- SegSize = actual_seg_size(),
- {Head1, HSz, HN, HA} = alloc_hole(Count, Head, SegSize),
- {Max, _} = hd(Count),
- CT = ?VNEW(Max+1, not_used),
- {Head2, NCT} = allocate_all(Head1, Count, Cntrs, CT),
- Head3 = free_hole(Head2, HSz, HN, HA),
- {Head3, NCT}.
-
-alloc_hole([{LSize,_} | _], Head, SegSz) when ?POW(LSize-1) > SegSz ->
- {_, SegAddr, _} = dets_utils:alloc(Head, SegSz-1),
- Size = ?POW(LSize-1)-1,
- {_, Addr, _} = dets_utils:alloc(Head, Size),
- N = (Addr - SegAddr) div SegSz,
- Head1 = dets_utils:alloc_many(Head, SegSz, N, SegAddr),
- {Head1, SegSz-1, N, SegAddr};
-alloc_hole(_Count, Head, _SegSz) ->
- {Head, 0, 0, 0}.
-
-free_hole(Head, _Size, 0, _Addr) ->
- Head;
-free_hole(Head, Size, N, Addr) ->
- {Head1, _} = dets_utils:free(Head, Addr, Size),
- free_hole(Head1, Size, N-1, Addr+Size+1).
-
-%% One (temporary) file for each buddy size, write all objects of that
-%% size to the file.
-allocate_all(Head, [{LSize,NoObjects} | Count], Cntrs, CT) ->
- Size = ?POW(LSize-1)-1,
- {_Head, Addr, _} = dets_utils:alloc(Head, Size),
- NewHead = dets_utils:alloc_many(Head, Size+1, NoObjects, Addr),
- {FileName, Fd} = temp_file(Head, LSize),
- true = ets:insert(Cntrs, {LSize, Addr, {FileName, Fd}, NoObjects}),
- NCT = ?VSET(LSize, CT, [Addr | []]),
- allocate_all(NewHead, Count, Cntrs, NCT);
-allocate_all(Head, [], Cntrs, CT) ->
- %% Note that space for the segments has been allocated already.
- %% And one file for the segments...
- {FileName, Fd} = temp_file(Head, ?FSCK_SEGMENT),
- Addr = ?SEGADDR(?SEGARRSZ),
- true = ets:insert(Cntrs, {?FSCK_SEGMENT, Addr, {FileName, Fd}, 0}),
- NCT = ?VSET(tuple_size(CT), CT, [Addr | []]),
- {Head, NCT}.
-
-temp_file(Head, N) ->
- TmpName = lists:concat([Head#head.filename, '.', N]),
- {ok, Fd} = dets_utils:open(TmpName, [raw, binary, write]),
- {TmpName, Fd}.
-
-bin2term([<<Slot:32, LogSize:8, BinTerm/binary>> | BTs], L) ->
- bin2term(BTs, [{Slot, LogSize, BinTerm} | L]);
-bin2term([], L) ->
- lists:reverse(L).
-
-write_all_sizes(?DCT(D, CT), Cntrs) ->
- ?DCT(D, write_sizes(1, tuple_size(CT), CT, Cntrs)).
-
-write_sizes(Sz, Sz, CT, Cntrs) ->
- write_size(Sz, ?FSCK_SEGMENT, CT, Cntrs);
-write_sizes(Sz, MaxSz, CT, Cntrs) ->
- NCT = write_size(Sz, Sz, CT, Cntrs),
- write_sizes(Sz+1, MaxSz, NCT, Cntrs).
-
-write_size(Sz, I, CT, Cntrs) ->
- case ?VGET(Sz, CT) of
- not_used ->
- CT;
- [Addr | L] ->
- {FileName, Fd} = ets:lookup_element(Cntrs, I, 3),
- case file:write(Fd, lists:reverse(L)) of
- ok ->
- ?VSET(Sz, CT, [Addr | []]);
- Error ->
- dets_utils:file_error(FileName, Error)
- end
- end.
-
-output_slots(E, [E1 | Es], Acc, Head, DCT)
- when element(1, E) =:= element(1, E1) ->
- output_slots(E1, Es, [E1 | Acc], Head, DCT);
-output_slots(_E, [E | L], Acc, Head, DCT) ->
- NDCT = output_slot(Acc, Head, DCT),
- output_slots(E, L, [E], Head, NDCT);
-output_slots(E, [], Acc, _Head, DCT) ->
- {E, Acc, DCT}.
-
-output_slot([E], _Head, ?DCT(D, CT)) ->
- ?DCT(D, output_slot([{foo, E}], 0, foo, CT));
-output_slot(Es0, Head, ?DCT(D, CT)) ->
- Kp = Head#head.keypos,
- Fun = fun({_Slot, _LSize, BinTerm} = E) ->
- Key = element(Kp, binary_to_term(BinTerm)),
- {Key, E}
- end,
- Es = lists:map(Fun, Es0),
- NEs = case Head#head.type of
- set ->
- [{Key0,_} = E | L0] = lists:sort(Es),
- choose_one(lists:sort(L0), Key0, [E]);
- bag ->
- lists:usort(Es);
- duplicate_bag ->
- lists:sort(Es)
- end,
- Dups = D + length(Es) - length(NEs),
- ?DCT(Dups, output_slot(NEs, 0, foo, CT)).
-
-choose_one([{Key,_} | Es], Key, L) ->
- choose_one(Es, Key, L);
-choose_one([{Key,_} = E | Es], _Key, L) ->
- choose_one(Es, Key, [E | L]);
-choose_one([], _Key, L) ->
- L.
-
-output_slot([E | Es], Next, _Slot, CT) ->
- {_Key, {Slot, LSize, BinTerm}} = E,
- Size = byte_size(BinTerm),
- Size2 = ?POW(LSize-1),
- Pad = <<0:(Size2-Size-?OHDSZ)/unit:8>>,
- BinObject = [<<Next:32, Size:32, ?ACTIVE:32>>, BinTerm | Pad],
- [Addr | L] = ?VGET(LSize, CT),
- NCT = ?VSET(LSize, CT, [Addr+Size2 | [BinObject | L]]),
- output_slot(Es, Addr, Slot, NCT);
-output_slot([], Next, Slot, CT) ->
- I = tuple_size(CT),
- [Addr | L] = ?VGET(I, CT),
- {Pos, _} = slot_position(Slot),
- NoZeros = Pos - Addr,
- BinObject = if
- NoZeros > 100 ->
- [dets_utils:make_zeros(NoZeros) | <<Next:32>>];
- true ->
- <<0:NoZeros/unit:8,Next:32>>
- end,
- Size = NoZeros+4,
- ?VSET(I, CT, [Addr+Size | [BinObject | L]]).
-
-%% Does not close Fd.
-fsck_input(Head, Fd, Cntrs, _FileHeader) ->
- %% The file is not compressed, so the object size cannot exceed
- %% the filesize, for all objects.
- MaxSz = case file:position(Fd, eof) of
- {ok, Pos} ->
- Pos;
- _ ->
- (1 bsl 32) - 1
- end,
- State0 = fsck_read(?BASE, Fd, []),
- fsck_input1(Head, State0, Fd, MaxSz, Cntrs).
-
-fsck_input1(Head, State, Fd, MaxSz, Cntrs) ->
- fun(close) ->
- ok;
- (read) ->
- case State of
- done ->
- end_of_input;
- {done, L} ->
- R = count_input(Cntrs, L, []),
- {R, fsck_input1(Head, done, Fd, MaxSz, Cntrs)};
- {cont, L, Bin, Pos} ->
- R = count_input(Cntrs, L, []),
- FR = fsck_objs(Bin, Head#head.keypos, Head, []),
- NewState = fsck_read(FR, Pos, Fd, MaxSz, Head),
- {R, fsck_input1(Head, NewState, Fd, MaxSz, Cntrs)}
- end
- end.
-
-%% The ets table Cntrs is used for counting objects per size.
-count_input(Cntrs, [[LogSz | B] | Ts], L) ->
- count_object(Cntrs, LogSz),
- count_input(Cntrs, Ts, [B | L]);
-count_input(_Cntrs, [], L) ->
- L.
-
-count_object(Cntrs, LogSz) ->
- case catch ets:update_counter(Cntrs, LogSz, 1) of
- N when is_integer(N) -> ok;
- _Badarg -> true = ets:insert(Cntrs, {LogSz, 1})
- end.
-
-fsck_read(Pos, F, L) ->
- case file:position(F, Pos) of
- {ok, _} ->
- read_more_bytes(<<>>, 0, Pos, F, L);
- _Error ->
- {done, L}
- end.
-
-fsck_read({more, Bin, Sz, L}, Pos, F, MaxSz, Head) when Sz > MaxSz ->
- FR = skip_bytes(Bin, ?BUMP, Head#head.keypos, Head, L),
- fsck_read(FR, Pos, F, MaxSz, Head);
-fsck_read({more, Bin, Sz, L}, Pos, F, _MaxSz, _Head) ->
- read_more_bytes(Bin, Sz, Pos, F, L);
-fsck_read({new, Skip, L}, Pos, F, _MaxSz, _Head) ->
- NewPos = Pos + Skip,
- fsck_read(NewPos, F, L).
-
-read_more_bytes(B, Min, Pos, F, L) ->
- Max = if
- Min < ?CHUNK_SIZE -> ?CHUNK_SIZE;
- true -> Min
- end,
- case dets_utils:read_n(F, Max) of
- eof ->
- {done, L};
- Bin ->
- NewPos = Pos + byte_size(Bin),
- {cont, L, list_to_binary([B, Bin]), NewPos}
- end.
-
-fsck_objs(Bin = <<_N:32, Sz:32, Status:32, Tail/binary>>, Kp, Head, L) ->
- if
- Status =:= ?ACTIVE ->
- case Tail of
- <<BinTerm:Sz/binary, Tail2/binary>> ->
- case catch element(Kp, binary_to_term(BinTerm)) of
- {'EXIT', _} ->
- skip_bytes(Bin, ?BUMP, Kp, Head, L);
- Key ->
- LogSz = sz2pos(Sz+?OHDSZ),
- Obj = make_object(Head, Key, LogSz, BinTerm),
- NL = [[LogSz | Obj] | L],
- Skip = ?POW(LogSz-1) - Sz - ?OHDSZ,
- skip_bytes(Tail2, Skip, Kp, Head, NL)
- end;
- _ ->
- {more, Bin, Sz, L}
- end;
- true ->
- skip_bytes(Bin, ?BUMP, Kp, Head, L)
- end;
-fsck_objs(Bin, _Kp, _Head, L) ->
- {more, Bin, 0, L}.
-
-%% Version 8 has to know about version 9.
-make_object(Head, Key, _LogSz, BT) when Head#head.version =:= 9 ->
- Slot = dets_v9:db_hash(Key, Head),
- <<Slot:32, BT/binary>>;
-make_object(Head, Key, LogSz, BT) ->
- Slot = db_hash(Key, Head),
- <<Slot:32, LogSz:8, BT/binary>>.
-
-%% Inlined.
-skip_bytes(Bin, Skip, Kp, Head, L) ->
- case Bin of
- <<_:Skip/binary, Tail/binary>> ->
- fsck_objs(Tail, Kp, Head, L);
- _ ->
- {new, Skip - byte_size(Bin), L}
- end.
-
-%% -> {NewHead, ok} | throw({Head, Error})
-do_perform_save(H) ->
- FL = dets_utils:get_freelists(H),
- B = term_to_binary(FL),
- Size = byte_size(B),
- ?DEBUGF("size of freelist = ~p~n", [Size]),
- ?DEBUGF("head.m = ~p~n", [H#head.m]),
- ?DEBUGF("head.no_objects = ~p~n", [H#head.no_objects]),
-
- {ok, Pos} = dets_utils:position(H, eof),
- H1 = H#head{freelists_p = Pos},
- W1 = {?FREELIST_POS, <<Pos:32>>},
- W2 = {Pos, [<<0:32, Size:32, ?FREE:32>>, B]},
-
- W3 = {?D_POS, <<(H1#head.m):32,
- (H1#head.next):32,
- (H1#head.keypos):32,
- (H1#head.no_objects):32,
- (H1#head.n):32>>},
- {ClosedProperly, ClosedProperlyNeedCompacitng} =
- case H1#head.hash_bif of
- hash ->
- {?CLOSED_PROPERLY2, ?CLOSED_PROPERLY2_NEED_COMPACTING};
- phash ->
- {?CLOSED_PROPERLY_NEW_HASH,
- ?CLOSED_PROPERLY_NEW_HASH_NEED_COMPACTING}
- end,
- W4 =
- if
- Size > 1000, Size > H1#head.no_objects ->
- {?CLOSED_PROPERLY_POS,
- <<ClosedProperlyNeedCompacitng:32>>};
- true ->
- {?CLOSED_PROPERLY_POS, <<ClosedProperly:32>>}
- end,
- W5 = {?FILE_FORMAT_VERSION_POS, <<?FILE_FORMAT_VERSION:32>>},
- {H2, ok} = dets_utils:pwrite(H1, [W1,W2,W3,W4,W5]),
- {ok, Pos2} = dets_utils:position(H2, eof),
- ?DEBUGF("Writing file size ~p, eof at ~p~n", [Pos2+4, Pos2]),
- dets_utils:pwrite(H2, [{Pos2, <<(Pos2 + 4):32>>}]).
-
-%% -> [term()] | throw({Head, Error})
-slot_objs(H, Slot) when Slot >= H#head.next ->
- '$end_of_table';
-slot_objs(H, Slot) ->
- {_Pos, Chain} = chain(H, Slot),
- collect_chain(H, Chain).
-
-collect_chain(_H, 0) -> [];
-collect_chain(H, Pos) ->
- {Next, _Sz, Term} = prterm(H, Pos, ?ReadAhead),
- [Term | collect_chain(H, Next)].
-
-db_hash(Key, Head) ->
- H = h(Key, Head#head.hash_bif),
- Hash = H rem Head#head.m,
- if
- Hash < Head#head.n ->
- H rem (Head#head.m2); % H rem (2 * m)
- true ->
- Hash
- end.
-
-h(I, phash) -> erlang:phash(I, ?BIG) - 1;
-h(I, HF) -> erlang:HF(I, ?BIG) - 1. %% stupid BIF has 1 counts.
-
-no_slots(_Head) ->
- undefined.
-
-table_parameters(_Head) ->
- undefined.
-
-%% Re-hashing a segment, starting with SlotStart.
-%%
-%% On the average, half of the objects of the chain are put into a new
-%% chain. If the slot of the old chain is i, then the slot of the new
-%% chain is i+m.
-%% Note that the insertion of objects into the new chain is simplified
-%% by the fact that the chains are not sorted on key, which means that
-%% each moved object can be inserted first in the new chain.
-%% (It is also a fact that the objects with the same key are not sorted.)
-%%
-%% -> {ok, Writes} | throw({Head, Error})
-re_hash(Head, SlotStart) ->
- {SlotPos, _4} = slot_position(SlotStart),
- {ok, Bin} = dets_utils:pread(Head, SlotPos, 4*?SEGSZ, 0),
- {Read, Cs} = split_bin(SlotPos, Bin, [], []),
- re_hash_read(Head, [], Read, Cs).
-
-split_bin(Pos, <<P:32, B/binary>>, R, Cs) ->
- if
- P =:= 0 ->
- split_bin(Pos+4, B, R, Cs);
- true ->
- split_bin(Pos+4, B, [{P,?ReadAhead} | R], [[Pos] | Cs])
- end;
-split_bin(_Pos, <<>>, R, Cs) ->
- {R, Cs}.
-
-re_hash_read(Head, Cs, R, RCs) ->
- {ok, Bins} = dets_utils:pread(R, Head),
- re_hash_read(Head, R, RCs, Bins, Cs, [], []).
-
-re_hash_read(Head, [{Pos, Size} | Ps], [C | Cs],
- [<<Next:32, Sz:32, _Status:32, Bin0/binary>> | Bins],
- DoneCs, R, RCs) ->
- case byte_size(Bin0) of
- BinSz when BinSz >= Sz ->
- case catch binary_to_term(Bin0) of
- {'EXIT', _Error} ->
- throw(dets_utils:corrupt_reason(Head, bad_object));
- Term ->
- Key = element(Head#head.keypos, Term),
- New = h(Key, Head#head.hash_bif) rem Head#head.m2,
- NC = case New >= Head#head.m of
- true -> [{Pos,New} | C];
- false -> [Pos | C]
- end,
- if
- Next =:= 0 ->
- NDoneCs = [NC | DoneCs],
- re_hash_read(Head, Ps, Cs, Bins, NDoneCs, R, RCs);
- true ->
- NR = [{Next,?ReadAhead} | R],
- NRCs = [NC | RCs],
- re_hash_read(Head, Ps, Cs, Bins, DoneCs, NR, NRCs)
- end
- end;
- BinSz when Size =:= BinSz+?OHDSZ ->
- NR = [{Pos, Sz+?OHDSZ} | R],
- re_hash_read(Head, Ps, Cs, Bins, DoneCs, NR, [C | RCs]);
- _BinSz ->
- throw({Head, {error, {premature_eof, Head#head.filename}}})
- end;
-re_hash_read(Head, [], [], [], Cs, [], []) ->
- re_hash_traverse_chains(Cs, Head, [], [], []);
-re_hash_read(Head, [], [], [], Cs, R, RCs) ->
- re_hash_read(Head, Cs, R, RCs).
-
-re_hash_traverse_chains([C | Cs], Head, Rs, Ns, Ws) ->
- case re_hash_find_new(C, Rs, start, start) of
- false ->
- re_hash_traverse_chains(Cs, Head, Rs, Ns, Ws);
- {NRs, FirstNew, LastNew} ->
- LastInNew = case C of
- [{_,_} | _] -> true;
- _ -> false
- end,
- N = {FirstNew, LastNew, LastInNew},
- NWs = re_hash_link(C, start, start, start, Ws),
- re_hash_traverse_chains(Cs, Head, NRs, [N | Ns], NWs)
- end;
-re_hash_traverse_chains([], Head, Rs, Ns, Ws) ->
- {ok, Bins} = dets_utils:pread(Rs, Head),
- {ok, insert_new(Rs, Bins, Ns, Ws)}.
-
-re_hash_find_new([{Pos,NewSlot} | C], R, start, start) ->
- {SPos, _4} = slot_position(NewSlot),
- re_hash_find_new(C, [{SPos,4} | R], Pos, Pos);
-re_hash_find_new([{Pos,_SPos} | C], R, _FirstNew, LastNew) ->
- re_hash_find_new(C, R, Pos, LastNew);
-re_hash_find_new([_Pos | C], R, FirstNew, LastNew) ->
- re_hash_find_new(C, R, FirstNew, LastNew);
-re_hash_find_new([], _R, start, start) ->
- false;
-re_hash_find_new([], R, FirstNew, LastNew) ->
- {R, FirstNew, LastNew}.
-
-re_hash_link([{Pos,_SPos} | C], LastOld, start, _LastInNew, Ws) ->
- re_hash_link(C, LastOld, Pos, true, Ws);
-re_hash_link([{Pos,_SPos} | C], LastOld, LastNew, false, Ws) ->
- re_hash_link(C, LastOld, Pos, true, [{Pos,<<LastNew:32>>} | Ws]);
-re_hash_link([{Pos,_SPos} | C], LastOld, _LastNew, LastInNew, Ws) ->
- re_hash_link(C, LastOld, Pos, LastInNew, Ws);
-re_hash_link([Pos | C], start, LastNew, true, Ws) ->
- re_hash_link(C, Pos, LastNew, false, [{Pos,<<0:32>>} | Ws]);
-re_hash_link([Pos | C], LastOld, LastNew, true, Ws) ->
- re_hash_link(C, Pos, LastNew, false, [{Pos,<<LastOld:32>>} | Ws]);
-re_hash_link([Pos | C], _LastOld, LastNew, LastInNew, Ws) ->
- re_hash_link(C, Pos, LastNew, LastInNew, Ws);
-re_hash_link([], _LastOld, _LastNew, _LastInNew, Ws) ->
- Ws.
-
-insert_new([{NewSlotPos,_4} | Rs], [<<P:32>> = PB | Bins], [N | Ns], Ws) ->
- {FirstNew, LastNew, LastInNew} = N,
- Ws1 = case P of
- 0 when LastInNew ->
- Ws;
- 0 ->
- [{LastNew, <<0:32>>} | Ws];
- _ ->
- [{LastNew, PB} | Ws]
- end,
- NWs = [{NewSlotPos, <<FirstNew:32>>} | Ws1],
- insert_new(Rs, Bins, Ns, NWs);
-insert_new([], [], [], Ws) ->
- Ws.
-
-%% When writing the cache, a 'work list' is first created:
-%% WorkList = [{Key, {Delete,Lookup,[Inserted]}}]
-%% Delete = keep | delete
-%% Lookup = skip | lookup
-%% Inserted = {object(), No}
-%% No = integer()
-%% If No =< 0 then there will be -No instances of object() on the file
-%% when the cache has been written. If No > 0 then No instances of
-%% object() will be added to the file.
-%% If Delete has the value 'delete', then all objects with the key Key
-%% have been deleted. (This could be viewed as a shorthand for {Object,0}
-%% for each object Object on the file not mentioned in some Inserted.)
-%% If Lookup has the value 'lookup', all objects with the key Key will
-%% be returned.
-%%
-
-%% -> {NewHead, [LookedUpObject], pwrite_list()} | throw({NewHead, Error})
-write_cache(Head) ->
- #head{cache = C, type = Type} = Head,
- case dets_utils:is_empty_cache(C) of
- true -> {Head, [], []};
- false ->
- {NewC, _MaxInserts, PerKey} = dets_utils:reset_cache(C),
- %% NoInsertedKeys is an upper limit on the number of new keys.
- {WL, NoInsertedKeys} = make_wl(PerKey, Type),
- Head1 = Head#head{cache = NewC},
- case may_grow(Head1, NoInsertedKeys, once) of
- {Head2, ok} ->
- eval_work_list(Head2, WL);
- HeadError ->
- throw(HeadError)
- end
- end.
-
-make_wl(PerKey, Type) ->
- make_wl(PerKey, Type, [], 0).
-
-make_wl([{Key,L} | PerKey], Type, WL, Ins) ->
- [Cs | I] = wl(L, Type),
- make_wl(PerKey, Type, [{Key,Cs} | WL], Ins+I);
-make_wl([], _Type, WL, Ins) ->
- {WL, Ins}.
-
-wl(L, Type) ->
- wl(L, Type, keep, skip, 0, []).
-
-wl([{_Seq, delete_key} | Cs], Type, _Del, Lookup, _I, _Objs) ->
- wl(Cs, Type, delete, Lookup, 0, []);
-wl([{_Seq, {delete_object, Object}} | Cs], Type, Del, Lookup, I, Objs) ->
- NObjs = lists:keydelete(Object, 1, Objs),
- wl(Cs, Type, Del, Lookup, I, [{Object,0} | NObjs]);
-wl([{_Seq, {insert, Object}} | Cs], Type, _Del, Lookup, _I, _Objs)
- when Type =:= set ->
- wl(Cs, Type, delete, Lookup, 1, [{Object,-1}]);
-wl([{_Seq, {insert, Object}} | Cs], Type, Del, Lookup, _I, Objs) ->
- NObjs =
- case lists:keyfind(Object, 1, Objs) of
- {_, 0} ->
- lists:keyreplace(Object, 1, Objs, {Object,-1});
- {_, _C} when Type =:= bag -> % C =:= 1; C =:= -1
- Objs;
- {_, C} when C < 0 -> % when Type =:= duplicate_bag
- lists:keyreplace(Object, 1, Objs, {Object,C-1});
- {_, C} -> % when C > 0, Type =:= duplicate_bag
- lists:keyreplace(Object, 1, Objs, {Object,C+1});
- false when Del =:= delete ->
- [{Object, -1} | Objs];
- false ->
- [{Object, 1} | Objs]
- end,
- wl(Cs, Type, Del, Lookup, 1, NObjs);
-wl([{_Seq, {lookup,_Pid}=Lookup} | Cs], Type, Del, _Lookup, I, Objs) ->
- wl(Cs, Type, Del, Lookup, I, Objs);
-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) ->
- {Head, ok};
-may_grow(Head, _N, _How) when Head#head.next >= ?MAXOBJS ->
- {Head, ok};
-may_grow(Head, N, How) ->
- Extra = erlang:min(2*?SEGSZ, Head#head.no_objects + N - Head#head.next),
- case catch may_grow1(Head, Extra, How) of
- {error, Reason} -> % alloc may throw error
- {Head, {error, Reason}};
- Reply ->
- Reply
- end.
-
-may_grow1(Head, Extra, many_times) when Extra > ?SEGSZ ->
- Reply = grow(Head, 1, undefined),
- self() ! ?DETS_CALL(self(), may_grow),
- Reply;
-may_grow1(Head, Extra, _How) ->
- grow(Head, Extra, undefined).
-
-%% -> {Head, ok} | throw({Head, Error})
-grow(Head, Extra, _SegZero) when Extra =< 0 ->
- {Head, ok};
-grow(Head, Extra, undefined) ->
- grow(Head, Extra, seg_zero());
-grow(Head, Extra, SegZero) ->
- #head{n = N, next = Next, m = M} = Head,
- SegNum = ?SLOT2SEG(Next),
- {Head0, Ws1} = allocate_segment(Head, SegZero, SegNum),
- {Head1, ok} = dets_utils:pwrite(Head0, Ws1),
- %% If re_hash fails, segp_cache has been called, but it does not matter.
- {ok, Ws2} = re_hash(Head1, N),
- {Head2, ok} = dets_utils:pwrite(Head1, Ws2),
- NewHead =
- if
- N + ?SEGSZ =:= M ->
- Head2#head{n = 0, next = Next + ?SEGSZ, m = 2 * M, m2 = 4 * M};
- true ->
- Head2#head{n = N + ?SEGSZ, next = Next + ?SEGSZ}
- end,
- grow(NewHead, Extra - ?SEGSZ, SegZero).
-
-seg_zero() ->
- <<0:(4*?SEGSZ)/unit:8>>.
-
-find_object(Head, Object) ->
- Key = element(Head#head.keypos, Object),
- Slot = db_hash(Key, Head),
- find_object(Head, Object, Slot).
-
-find_object(H, _Obj, Slot) when Slot >= H#head.next ->
- false;
-find_object(H, Obj, Slot) ->
- {_Pos, Chain} = chain(H, Slot),
- case catch find_obj(H, Obj, Chain) of
- {ok, Pos} ->
- {ok, Pos};
- _Else ->
- false
- end.
-
-find_obj(H, Obj, Pos) when Pos > 0 ->
- {Next, _Sz, Term} = prterm(H, Pos, ?ReadAhead),
- if
- Term == Obj ->
- {ok, Pos};
- true ->
- find_obj(H, Obj, Next)
- end.
-
-%% Given, a slot, return the {Pos, Chain} in the file where the
-%% objects hashed to this slot reside. Pos is the position in the
-%% file where the chain pointer is written and Chain is the position
-%% in the file where the first object resides.
-chain(Head, Slot) ->
- Pos = ?SEGADDR(?SLOT2SEG(Slot)),
- Segment = get_segp(Pos),
- FinalPos = Segment + (4 * ?REM2(Slot, ?SEGSZ)),
- {ok, <<Chain:32>>} = dets_utils:pread(Head, FinalPos, 4, 0),
- {FinalPos, Chain}.
-
-%%%
-%%% Cache routines depending on the dets file format.
-%%%
-
-%% -> {Head, [LookedUpObject], pwrite_list()} | throw({Head, Error})
-eval_work_list(Head, WorkLists) ->
- SWLs = tag_with_slot(WorkLists, Head, []),
- P1 = dets_utils:family(SWLs),
- {PerSlot, SlotPositions} = remove_slot_tag(P1, [], []),
- {ok, Bins} = dets_utils:pread(SlotPositions, Head),
- first_object(PerSlot, SlotPositions, Bins, Head, [], [], [], []).
-
-tag_with_slot([{K,_} = WL | WLs], Head, L) ->
- tag_with_slot(WLs, Head, [{db_hash(K, Head), WL} | L]);
-tag_with_slot([], _Head, L) ->
- L.
-
-remove_slot_tag([{S,SWLs} | SSWLs], Ls, SPs) ->
- remove_slot_tag(SSWLs, [SWLs | Ls], [slot_position(S) | SPs]);
-remove_slot_tag([], Ls, SPs) ->
- {Ls, SPs}.
-
-%% The initial chain pointers and the first object in each chain are
-%% read "in parallel", that is, with one call to file:pread/2 (two
-%% calls altogether). The following chain objects are read one by
-%% one. This is a compromise: if the chains are long and threads are
-%% active, it would be faster to keep a state for each chain and read
-%% the objects of the chains in parallel, but the overhead would be
-%% quite substantial.
-
-first_object([WorkLists | SPs], [{P1,_4} | Ss], [<<P2:32>> | Bs], Head,
- ObjsToRead, ToRead, Ls, LU) when P2 =:= 0 ->
- L0 = [{old,P1}],
- {L, NLU} = eval_slot(Head, ?ReadAhead, P2, WorkLists, L0, LU),
- first_object(SPs, Ss, Bs, Head, ObjsToRead, ToRead, [L | Ls], NLU);
-first_object([WorkLists | SPs], [{P1,_4} | Ss], [<<P2:32>> | Bs], Head,
- ObjsToRead, ToRead, Ls, LU) ->
- E = {P1,P2,WorkLists},
- first_object(SPs, Ss, Bs, Head,
- [E | ObjsToRead], [{P2, ?ReadAhead} | ToRead], Ls, LU);
-first_object([], [], [], Head, ObjsToRead, ToRead, Ls, LU) ->
- {ok, Bins} = dets_utils:pread(ToRead, Head),
- case catch eval_first(Bins, ObjsToRead, Head, Ls, LU) of
- {ok, NLs, NLU} ->
- case create_writes(NLs, Head, [], 0) of
- {Head1, [], 0} ->
- {Head1, NLU, []};
- {Head1, Ws, No} ->
- {NewHead, Ws2} = update_no_objects(Head1, Ws, No),
- {NewHead, NLU, Ws2}
- end;
- _Error ->
- throw(dets_utils:corrupt_reason(Head, bad_object))
- end.
-
-%% Update no_objects on the file too, if the number of segments that
-%% dets:fsck/6 use for estimate has changed.
-update_no_objects(Head, Ws, 0) -> {Head, Ws};
-update_no_objects(Head, Ws, Delta) ->
- No = Head#head.no_objects,
- NewNo = No + Delta,
- NWs =
- if
- NewNo > ?MAXOBJS ->
- Ws;
- ?SLOT2SEG(No) =:= ?SLOT2SEG(NewNo) ->
- Ws;
- true ->
- [{?NO_OBJECTS_POS, <<NewNo:32>>} | Ws]
- end,
- {Head#head{no_objects = NewNo}, NWs}.
-
-eval_first([<<Next:32, Sz:32, _Status:32, Bin/binary>> | Bins],
- [SP | SPs], Head, Ls, LU) ->
- {P1, P2, WLs} = SP,
- L0 = [{old,P1}],
- case byte_size(Bin) of
- BinSz when BinSz >= Sz ->
- Term = binary_to_term(Bin),
- Key = element(Head#head.keypos, Term),
- {L, NLU} = find_key(Head, P2, Next, Sz, Term, Key, WLs, L0, LU),
- eval_first(Bins, SPs, Head, [L | Ls], NLU);
- _BinSz ->
- {L, NLU} = eval_slot(Head, Sz+?OHDSZ, P2, WLs, L0, LU),
- eval_first(Bins, SPs, Head, [L | Ls], NLU)
- end;
-eval_first([], [], _Head, Ls, LU) ->
- {ok, Ls, LU}.
-
-eval_slot(_Head, _TrySize, _Pos=0, [], L, LU) ->
- {L, LU};
-eval_slot(Head, _TrySize, Pos=0, [WL | WLs], L, LU) ->
- {_Key, {_Delete, LookUp, Objects}} = WL,
- {NL, NLU} = end_of_key(Objects, LookUp, L, []),
- eval_slot(Head, ?ReadAhead, Pos, WLs, NL, NLU++LU);
-eval_slot(Head, TrySize, Pos, WLs, L, LU) ->
- {NextPos, Size, Term} = prterm(Head, Pos, TrySize),
- Key = element(Head#head.keypos, Term),
- find_key(Head, Pos, NextPos, Size, Term, Key, WLs, L, LU).
-
-find_key(Head, Pos, NextPos, Size, Term, Key, WLs, L, LU) ->
- case lists:keyfind(Key, 1, WLs) of
- {_, {Delete, LookUp, Objects}} = WL ->
- NWLs = lists:delete(WL, WLs),
- {NewObjects, NL, LUK} = eval_object(Size, Term, Delete, LookUp,
- Objects, Head, Pos, L, []),
- eval_key(Key, Delete, LookUp, NewObjects, Head, NextPos,
- NWLs, NL, LU, LUK);
- false ->
- L0 = [{old,Pos} | L],
- eval_slot(Head, ?ReadAhead, NextPos, WLs, L0, LU)
- end.
-
-eval_key(_Key, _Delete, Lookup, _Objects, Head, Pos, WLs, L, LU, LUK)
- when Head#head.type =:= set ->
- NLU = case Lookup of
- {lookup, Pid} -> [{Pid,LUK} | LU];
- skip -> LU
- end,
- eval_slot(Head, ?ReadAhead, Pos, WLs, L, NLU);
-eval_key(_Key, _Delete, LookUp, Objects, Head, Pos, WLs, L, LU, LUK)
- when Pos =:= 0 ->
- {NL, NLU} = end_of_key(Objects, LookUp, L, LUK),
- eval_slot(Head, ?ReadAhead, Pos, WLs, NL, NLU++LU);
-eval_key(Key, Delete, LookUp, Objects, Head, Pos, WLs, L, LU, LUK) ->
- {NextPos, Size, Term} = prterm(Head, Pos, ?ReadAhead),
- case element(Head#head.keypos, Term) of
- Key ->
- {NewObjects, NL, LUK1} =
- eval_object(Size, Term, Delete, LookUp,Objects,Head,Pos,L,LUK),
- eval_key(Key, Delete, LookUp, NewObjects, Head, NextPos, WLs,
- NL, LU, LUK1);
- Key2 ->
- {L1, NLU} = end_of_key(Objects, LookUp, L, LUK),
- find_key(Head, Pos, NextPos, Size, Term, Key2, WLs, L1, NLU++LU)
- end.
-
-%% All objects in Objects have the key Key.
-eval_object(Size, Term, Delete, LookUp, Objects, Head, Pos, L, LU) ->
- Type = Head#head.type,
- case lists:keyfind(Term, 1, Objects) of
- {_Object, N} when N =:= 0 ->
- L1 = [{delete,Pos,Size} | L],
- {Objects, L1, LU};
- {_Object, N} when N < 0, Type =:= set ->
- L1 = [{old,Pos} | L],
- wl_lookup(LookUp, Objects, Term, L1, LU);
- {Object, _N} when Type =:= bag -> % when N =:= 1; N =:= -1
- L1 = [{old,Pos} | L],
- Objects1 = lists:keydelete(Object, 1, Objects),
- wl_lookup(LookUp, Objects1, Term, L1, LU);
- {Object, N} when N < 0, Type =:= duplicate_bag ->
- L1 = [{old,Pos} | L],
- Objects1 = lists:keyreplace(Object, 1, Objects, {Object,N+1}),
- wl_lookup(LookUp, Objects1, Term, L1, LU);
- {_Object, N} when N > 0, Type =:= duplicate_bag ->
- L1 = [{old,Pos} | L],
- wl_lookup(LookUp, Objects, Term, L1, LU);
- false when Type =:= set, Delete =:= delete ->
- case lists:keyfind(-1, 2, Objects) of
- false -> % no inserted object, perhaps deleted objects
- L1 = [{delete,Pos,Size} | L],
- {[], L1, LU};
- {Term2, -1} ->
- Bin2 = term_to_binary(Term2),
- NSize = byte_size(Bin2),
- Overwrite =
- if
- NSize =:= Size ->
- true;
- true ->
- SizePos = sz2pos(Size+?OHDSZ),
- NSizePos = sz2pos(NSize+?OHDSZ),
- SizePos =:= NSizePos
- end,
- E = if
- Overwrite ->
- {overwrite,Bin2,Pos};
- true ->
- {replace,Bin2,Pos,Size}
- end,
- wl_lookup(LookUp, [], Term2, [E | L], LU)
- end;
- false when Delete =:= delete ->
- L1 = [{delete,Pos,Size} | L],
- {Objects, L1, LU};
- false ->
- L1 = [{old,Pos} | L],
- wl_lookup(LookUp, Objects, Term, L1, LU)
- end.
-
-%% Inlined.
-wl_lookup({lookup,_}, Objects, Term, L, LU) ->
- {Objects, L, [Term | LU]};
-wl_lookup(skip, Objects, _Term, L, LU) ->
- {Objects, L, LU}.
-
-end_of_key([{Object,N0} | Objs], LookUp, L, LU) when N0 =/= 0 ->
- N = abs(N0),
- NL = [{insert,N,term_to_binary(Object)} | L],
- NLU = case LookUp of
- {lookup, _} ->
- lists:duplicate(N, Object) ++ LU;
- skip ->
- LU
- end,
- end_of_key(Objs, LookUp, NL, NLU);
-end_of_key([_ | Objects], LookUp, L, LU) ->
- end_of_key(Objects, LookUp, L, LU);
-end_of_key([], {lookup,Pid}, L, LU) ->
- {L, [{Pid,LU}]};
-end_of_key([], skip, L, LU) ->
- {L, LU}.
-
-create_writes([L | Ls], H, Ws, No) ->
- {NH, NWs, NNo} = create_writes(L, H, Ws, No, 0, true),
- create_writes(Ls, NH, NWs, NNo);
-create_writes([], H, Ws, No) ->
- {H, lists:reverse(Ws), No}.
-
-create_writes([{old,Pos} | L], H, Ws, No, _Next, true) ->
- create_writes(L, H, Ws, No, Pos, true);
-create_writes([{old,Pos} | L], H, Ws, No, Next, false) ->
- W = {Pos, <<Next:32>>},
- create_writes(L, H, [W | Ws], No, Pos, true);
-create_writes([{insert,N,Bin} | L], H, Ws, No, Next, _NextIsOld) ->
- {NH, NWs, Pos} = create_inserts(N, H, Ws, Next, byte_size(Bin), Bin),
- create_writes(L, NH, NWs, No+N, Pos, false);
-create_writes([{overwrite,Bin,Pos} | L], H, Ws, No, Next, _) ->
- Size = byte_size(Bin),
- W = {Pos, [<<Next:32, Size:32, ?ACTIVE:32>>, Bin]},
- create_writes(L, H, [W | Ws], No, Pos, true);
-create_writes([{replace,Bin,Pos,OSize} | L], H, Ws, No, Next, _) ->
- Size = byte_size(Bin),
- {H1, _} = dets_utils:free(H, Pos, OSize+?OHDSZ),
- {NH, NewPos, _} = dets_utils:alloc(H1, ?OHDSZ + Size),
- W1 = {NewPos, [<<Next:32, Size:32, ?ACTIVE:32>>, Bin]},
- NWs = if
- Pos =:= NewPos ->
- [W1 | Ws];
- true ->
- W2 = {Pos+?STATUS_POS, <<?FREE:32>>},
- [W1,W2 | Ws]
- end,
- create_writes(L, NH, NWs, No, NewPos, false);
-create_writes([{delete,Pos,Size} | L], H, Ws, No, Next, _) ->
- {NH, _} = dets_utils:free(H, Pos, Size+?OHDSZ),
- NWs = [{Pos+?STATUS_POS,<<?FREE:32>>} | Ws],
- create_writes(L, NH, NWs, No-1, Next, false);
-create_writes([], H, Ws, No, _Next, _NextIsOld) ->
- {H, Ws, No}.
-
-create_inserts(0, H, Ws, Next, _Size, _Bin) ->
- {H, Ws, Next};
-create_inserts(N, H, Ws, Next, Size, Bin) ->
- {NH, Pos, _} = dets_utils:alloc(H, ?OHDSZ + Size),
- W = {Pos, [<<Next:32, Size:32, ?ACTIVE:32>>, Bin]},
- create_inserts(N-1, NH, [W | Ws], Pos, Size, Bin).
-
-slot_position(S) ->
- Pos = ?SEGADDR(?SLOT2SEG(S)),
- Segment = get_segp(Pos),
- FinalPos = Segment + (4 * ?REM2(S, ?SEGSZ)),
- {FinalPos, 4}.
-
-%% Twice the size of a segment due to the bug in sz2pos/1. Inlined.
-actual_seg_size() ->
- ?POW(sz2pos(?SEGSZ*4)-1).
-
-segp_cache(Pos, Segment) ->
- put(Pos, Segment).
-
-%% Inlined.
-get_segp(Pos) ->
- get(Pos).
-
-%% Bug: If Sz0 is equal to 2**k for some k, then 2**(k+1) bytes are
-%% allocated (wasting 2**k bytes).
-sz2pos(N) ->
- 1 + dets_utils:log2(N+1).
-
-scan_objs(_Head, Bin, From, To, L, Ts, R, _Type) ->
- scan_objs(Bin, From, To, L, Ts, R).
-
-scan_objs(Bin, From, To, L, Ts, -1) ->
- {stop, Bin, From, To, L, Ts};
-scan_objs(B = <<_N:32, Sz:32, St:32, T/binary>>, From, To, L, Ts, R) ->
- if
- St =:= ?ACTIVE;
- St =:= ?FREE -> % deleted after scanning started
- case T of
- <<BinTerm:Sz/binary, T2/binary>> ->
- NTs = [BinTerm | Ts],
- OSz = Sz + ?OHDSZ,
- Skip = ?POW(sz2pos(OSz)-1) - OSz,
- F2 = From + OSz,
- NR = if
- R < 0 ->
- R + 1;
- true ->
- R + OSz + Skip
- end,
- scan_skip(T2, F2, To, Skip, L, NTs, NR);
- _ ->
- {more, From, To, L, Ts, R, Sz+?OHDSZ}
- end;
- true -> % a segment
- scan_skip(B, From, To, actual_seg_size(), L, Ts, R)
- end;
-scan_objs(_B, From, To, L, Ts, R) ->
- {more, From, To, L, Ts, R, 0}.
-
-scan_skip(Bin, From, To, Skip, L, Ts, R) when From + Skip < To ->
- SkipPos = From + Skip,
- case Bin of
- <<_:Skip/binary, Tail/binary>> ->
- scan_objs(Tail, SkipPos, To, L, Ts, R);
- _ ->
- {more, SkipPos, To, L, Ts, R, 0}
- end;
-scan_skip(Bin, From, To, Skip, L, Ts, R) when From + Skip =:= To ->
- scan_next_allocated(Bin, From, To, L, Ts, R);
-scan_skip(_Bin, From, _To, Skip, L, Ts, R) -> % when From + Skip > _To
- From1 = From + Skip,
- {more, From1, From1, L, Ts, R, 0}.
-
-scan_next_allocated(_Bin, _From, To, <<>>=L, Ts, R) ->
- {more, To, To, L, Ts, R, 0};
-scan_next_allocated(Bin, From0, _To, <<From:32, To:32, L/binary>>, Ts, R) ->
- Skip = From - From0,
- scan_skip(Bin, From0, To, Skip, L, Ts, R).
-
-%% Read term from file at position Pos
-prterm(Head, Pos, ReadAhead) ->
- Res = dets_utils:pread(Head, Pos, ?OHDSZ, ReadAhead),
- ?DEBUGF("file:pread(~tp, ~p, ?) -> ~p~n", [Head#head.filename, Pos, Res]),
- {ok, <<Next:32, Sz:32, _Status:32, Bin0/binary>>} = Res,
- ?DEBUGF("{Next, Sz} = ~p~n", [{Next, Sz}]),
- Bin = case byte_size(Bin0) of
- Actual when Actual >= Sz ->
- Bin0;
- _ ->
- {ok, Bin1} = dets_utils:pread(Head, Pos + ?OHDSZ, Sz, 0),
- Bin1
- end,
- Term = binary_to_term(Bin),
- {Next, Sz, Term}.
-
-%%%%%%%%%%%%%%%%% DEBUG functions %%%%%%%%%%%%%%%%
-
-file_info(FH) ->
- #fileheader{closed_properly = CP, keypos = Kp,
- m = M, next = Next, n = N, version = Version,
- type = Type, no_objects = NoObjects}
- = FH,
- if
- CP =:= 0 ->
- {error, not_closed};
- FH#fileheader.cookie =/= ?MAGIC ->
- {error, not_a_dets_file};
- FH#fileheader.version =/= ?FILE_FORMAT_VERSION ->
- {error, bad_version};
- true ->
- {ok, [{closed_properly,CP},{keypos,Kp},{m, M},
- {n,N},{next,Next},{no_objects,NoObjects},
- {type,Type},{version,Version}]}
- end.
-
-v_segments(H) ->
- v_segments(H, 0).
-
-v_segments(_H, ?SEGARRSZ) ->
- done;
-v_segments(H, SegNo) ->
- Seg = dets_utils:read_4(H#head.fptr, ?SEGADDR(SegNo)),
- if
- Seg =:= 0 ->
- done;
- true ->
- io:format("SEGMENT ~w ", [SegNo]),
- io:format("At position ~w~n", [Seg]),
- v_segment(H, SegNo, Seg, 0),
- v_segments(H, SegNo+1)
- end.
-
-v_segment(_H, _, _SegPos, ?SEGSZ) ->
- done;
-v_segment(H, SegNo, SegPos, SegSlot) ->
- Slot = SegSlot + (SegNo * ?SEGSZ),
- Chain = dets_utils:read_4(H#head.fptr, SegPos + (4 * SegSlot)),
- if
- Chain =:= 0 -> %% don't print empty chains
- true;
- true ->
- io:format(" <~p>~p: [",[SegPos + (4 * SegSlot), Slot]),
- print_chain(H, Chain)
- end,
- v_segment(H, SegNo, SegPos, SegSlot+1).
-
-print_chain(_H, 0) ->
- io:format("] \n", []);
-print_chain(H, Pos) ->
- {ok, _} = file:position(H#head.fptr, Pos),
- case rterm(H#head.fptr) of
- {ok, 0, _Sz, Term} ->
- io:format("<~p>~p] \n",[Pos, Term]);
- {ok, Next, _Sz, Term} ->
- io:format("<~p>~p, ", [Pos, Term]),
- print_chain(H, Next);
- Other ->
- io:format("~nERROR ~p~n", [Other])
- end.
-
-%% Can't be used at the bucket level!!!!
-%% Only when we go down a chain
-rterm(F) ->
- case catch rterm2(F) of
- {'EXIT', Reason} -> %% truncated DAT file
- dets_utils:vformat("** dets: Corrupt or truncated dets file~n",
- []),
- {error, Reason};
- Other ->
- Other
- end.
-
-rterm2(F) ->
- {ok, <<Next:32, Sz:32, _:32>>} = file:read(F, ?OHDSZ),
- {ok, Bin} = file:read(F, Sz),
- Term = binary_to_term(Bin),
- {ok, Next, Sz, Term}.
-
-
diff --git a/lib/stdlib/src/dets_v9.erl b/lib/stdlib/src/dets_v9.erl
index 6c406fc03a..3ab8f87ebf 100644
--- a/lib/stdlib/src/dets_v9.erl
+++ b/lib/stdlib/src/dets_v9.erl
@@ -24,8 +24,8 @@
-export([mark_dirty/1, read_file_header/2,
check_file_header/2, do_perform_save/1, initiate_file/11,
- prep_table_copy/9, init_freelist/2, fsck_input/4,
- bulk_input/3, output_objs/4, bchunk_init/2,
+ prep_table_copy/9, init_freelist/1, fsck_input/4,
+ bulk_input/3, output_objs/3, bchunk_init/2,
try_bchunk_header/2, compact_init/3, read_bchunks/2,
write_cache/1, may_grow/3, find_object/2, slot_objs/2,
scan_objs/8, db_hash/2, no_slots/1, table_parameters/1]).
@@ -228,8 +228,8 @@
-define(CLOSED_PROPERLY_POS, 8).
-define(D_POS, 20).
-%%% Dets file versions up to 8 are handled in dets_v8. This module
-%%% handles version 9, introduced in R8.
+%%% This module handles Dets file format version 9, introduced in
+%%% Erlang/OTP R8.
%%%
%%% Version 9(a) tables have 256 reserved bytes in the file header,
%%% all initialized to zero.
@@ -249,32 +249,32 @@
-define(OHDSZ, 8). % The size of the object header, in bytes.
-define(STATUS_POS, 4). % Position of the status field.
--define(OHDSZ_v8, 12). % The size of the version 8 object header.
-
%% The size of each object is a multiple of 16.
%% BUMP is used when repairing files.
-define(BUMP, 16).
-%%% '$hash' is the value of HASH_PARMS in R8, '$hash2' is the value in R9.
+%%% '$hash' is the value of HASH_PARMS in Erlang/OTP R8, '$hash2' is
+%%% the value in Erlang/OTP R9.
%%%
%%% The fields of the ?HASH_PARMS records are the same, but having
-%%% different tags makes bchunk_init on R8 nodes reject data from R9
-%%% nodes, and vice versa. This is overkill, and due to an oversight.
-%%% What should have been done in R8 was to check the hash method, not
-%%% only the type of the table and the key position. R8 nodes cannot
-%%% handle the phash2 method.
+%%% different tags makes bchunk_init on Erlang/OTP R8 nodes reject
+%%% data from Erlang/OTP R9 nodes, and vice versa. This is overkill,
+%%% and due to an oversight. What should have been done in Erlang/OTP
+%%% R8 was to check the hash method, not only the type of the table
+%%% and the key position. Erlang/OTP R8 nodes cannot handle the phash2
+%%% method.
-define(HASH_PARMS, '$hash2').
-define(BCHUNK_FORMAT_VERSION, 1).
-record(?HASH_PARMS, {
- file_format_version,
+ file_format_version,
bchunk_format_version,
file, type, keypos, hash_method,
n,m,next,
min,max,
no_objects,no_keys,
- no_colls % [{LogSz,NoColls}], NoColls >= 0
+ no_colls :: no_colls()
}).
-define(ACTUAL_SEG_SIZE, (?SEGSZ*4)).
@@ -364,10 +364,8 @@ init_file(Fd, Tab, Fname, Type, Kp, MinSlots, MaxSlots, Ram, CacheSz,
filename = Fname,
name = Tab,
cache = dets_utils:new_cache(CacheSz),
- version = ?FILE_FORMAT_VERSION,
bump = ?BUMP,
- base = ?BASE, % to be overwritten
- mod = ?MODULE
+ base = ?BASE % to be overwritten
},
FreeListsPointer = 0,
@@ -457,7 +455,7 @@ alloc_seg(Head, SegZero, SegNo, Part) ->
{NewHead, InitSegment, [SegPointer]}.
%% Read free lists (using a Buddy System) from file.
-init_freelist(Head, true) ->
+init_freelist(Head) ->
Pos = Head#head.freelists_p,
free_lists_from_file(Head, Pos).
@@ -510,12 +508,10 @@ read_file_header(Fd, FileName) ->
md5 = erlang:md5(MD5DigestedPart),
trailer = FileSize + FlBase,
eof = EOF,
- n = N,
- mod = ?MODULE},
+ n = N},
{ok, Fd, FH}.
-%% -> {ok, head(), ExtraInfo} | {error, Reason} (Reason lacking file name)
-%% ExtraInfo = true
+%% -> {ok, head()} | {error, Reason} (Reason lacking file name)
check_file_header(FH, Fd) ->
HashBif = code_to_hash_method(FH#fileheader.hash_method),
Test =
@@ -534,14 +530,14 @@ check_file_header(FH, Fd) ->
HashBif =:= undefined ->
{error, bad_hash_bif};
FH#fileheader.closed_properly =:= ?CLOSED_PROPERLY ->
- {ok, true};
+ ok;
FH#fileheader.closed_properly =:= ?NOT_PROPERLY_CLOSED ->
{error, not_closed};
true ->
{error, not_a_dets_file}
end,
case Test of
- {ok, ExtraInfo} ->
+ ok ->
MaxObjSize = max_objsize(FH#fileheader.no_colls),
H = #head{
m = FH#fileheader.m,
@@ -563,11 +559,9 @@ check_file_header(FH, Fd) ->
min_no_slots = FH#fileheader.min_no_slots,
max_no_slots = FH#fileheader.max_no_slots,
no_collections = FH#fileheader.no_colls,
- version = ?FILE_FORMAT_VERSION,
- mod = ?MODULE,
bump = ?BUMP,
base = FH#fileheader.fl_base},
- {ok, H, ExtraInfo};
+ {ok, H};
Error ->
Error
end.
@@ -621,7 +615,7 @@ no_segs(NoSlots) ->
%%%
%%% bulk_input/3. Initialization, the general case (any stream of objects).
-%%% output_objs/4. Initialization (general case) and repair.
+%%% output_objs/3. Initialization (general case) and repair.
%%% bchunk_init/2. Initialization using bchunk.
bulk_input(Head, InitFun, _Cntrs) ->
@@ -678,7 +672,7 @@ bulk_objects([], _Head, Kp, Seq, L) when is_integer(Kp), is_integer(Seq) ->
-define(OBJ_COUNTER, 2).
-define(KEY_COUNTER, 3).
-output_objs(OldV, Head, SlotNums, Cntrs) when OldV =< 9 ->
+output_objs(Head, SlotNums, Cntrs) ->
fun(close) ->
%% Make sure that the segments are initialized in case
%% init_table has been called.
@@ -686,31 +680,31 @@ output_objs(OldV, Head, SlotNums, Cntrs) when OldV =< 9 ->
Acc = [], % This is the only way Acc can be empty.
true = ets:insert(Cntrs, {?FSCK_SEGMENT,0,[],0}),
true = ets:insert(Cntrs, {?COUNTERS, 0, 0}),
- Fun = output_objs2(foo, Acc, OldV, Head, Cache, Cntrs,
+ Fun = output_objs2(foo, Acc, Head, Cache, Cntrs,
SlotNums, bar),
Fun(close);
([]) ->
- output_objs(OldV, Head, SlotNums, Cntrs);
+ output_objs(Head, SlotNums, Cntrs);
(L) ->
%% Information about number of objects per size is not
%% relevant for version 9. It is the number of collections
%% that matters.
true = ets:delete_all_objects(Cntrs),
true = ets:insert(Cntrs, {?COUNTERS, 0, 0}),
- Es = bin2term(L, OldV, Head#head.keypos),
+ Es = bin2term(L, Head#head.keypos),
%% The cache is a tuple indexed by the (log) size. An element
%% is [BinaryObject].
Cache = ?VEMPTY,
{NE, NAcc, NCache} = output_slots(Es, Head, Cache, Cntrs, 0, 0),
- output_objs2(NE, NAcc, OldV, Head, NCache, Cntrs, SlotNums, 1)
+ output_objs2(NE, NAcc, Head, NCache, Cntrs, SlotNums, 1)
end.
-output_objs2(E, Acc, OldV, Head, Cache, SizeT, SlotNums, 0) ->
+output_objs2(E, Acc, Head, Cache, SizeT, SlotNums, 0) ->
NCache = write_all_sizes(Cache, SizeT, Head, more),
%% Number of handled file_sorter chunks before writing:
Max = erlang:max(1, erlang:min(tuple_size(NCache), 10)),
- output_objs2(E, Acc, OldV, Head, NCache, SizeT, SlotNums, Max);
-output_objs2(E, Acc, OldV, Head, Cache, SizeT, SlotNums, ChunkI) ->
+ output_objs2(E, Acc, Head, NCache, SizeT, SlotNums, Max);
+output_objs2(E, Acc, Head, Cache, SizeT, SlotNums, ChunkI) ->
fun(close) ->
{_, [], Cache1} =
if
@@ -747,11 +741,10 @@ output_objs2(E, Acc, OldV, Head, Cache, SizeT, SlotNums, ChunkI) ->
end
end;
(L) ->
- Es = bin2term(L, OldV, Head#head.keypos),
+ Es = bin2term(L, Head#head.keypos),
{NE, NAcc, NCache} =
output_slots(E, Es, Acc, Head, Cache, SizeT, 0, 0),
- output_objs2(NE, NAcc, OldV, Head, NCache, SizeT, SlotNums,
- ChunkI-1)
+ output_objs2(NE, NAcc, Head, NCache, SizeT, SlotNums, ChunkI-1)
end.
%%% Compaction.
@@ -1245,10 +1238,8 @@ allocate_all(Head, [{LSize,_,Data,NoCollections} | DTL], L) ->
E = {LSize,Addr,Data,NoCollections},
allocate_all(NewHead, DTL, [E | L]).
-bin2term(Bin, 9, Kp) ->
- bin2term1(Bin, Kp, []);
-bin2term(Bin, 8, Kp) ->
- bin2term_v8(Bin, Kp, []).
+bin2term(Bin, Kp) ->
+ bin2term1(Bin, Kp, []).
bin2term1([<<Slot:32, Seq:32, BinTerm/binary>> | BTs], Kp, L) ->
Term = binary_to_term(BinTerm),
@@ -1257,13 +1248,6 @@ bin2term1([<<Slot:32, Seq:32, BinTerm/binary>> | BTs], Kp, L) ->
bin2term1([], _Kp, L) ->
lists:reverse(L).
-bin2term_v8([<<Slot:32, BinTerm/binary>> | BTs], Kp, L) ->
- Term = binary_to_term(BinTerm),
- Key = element(Kp, Term),
- bin2term_v8(BTs, Kp, [{Slot, Key, foo, Term, BinTerm} | L]);
-bin2term_v8([], _Kp, L) ->
- lists:reverse(L).
-
write_all_sizes({}=Cache, _SizeT, _Head, _More) ->
Cache;
write_all_sizes(Cache, SizeT, Head, More) ->
@@ -1461,7 +1445,7 @@ temp_file(Head, SizeT, N) ->
%% Does not close Fd.
fsck_input(Head, Fd, Cntrs, FileHeader) ->
MaxSz0 = case FileHeader#fileheader.has_md5 of
- true when is_integer(FileHeader#fileheader.no_colls) ->
+ true when is_list(FileHeader#fileheader.no_colls) ->
?POW(max_objsize(FileHeader#fileheader.no_colls));
_ ->
%% The file is not compressed, so the bucket size
@@ -1485,10 +1469,10 @@ fsck_input(Head, State, Fd, MaxSz, Cntrs) ->
done ->
end_of_input;
{done, L, _Seq} ->
- R = count_input(Head, Cntrs, L),
+ R = count_input(L),
{R, fsck_input(Head, done, Fd, MaxSz, Cntrs)};
{cont, L, Bin, Pos, Seq} ->
- R = count_input(Head, Cntrs, L),
+ R = count_input(L),
FR = fsck_objs(Bin, Head#head.keypos, Head, [], Seq),
NewState = fsck_read(FR, Pos, Fd, MaxSz, Head),
{R, fsck_input(Head, NewState, Fd, MaxSz, Cntrs)}
@@ -1496,20 +1480,9 @@ fsck_input(Head, State, Fd, MaxSz, Cntrs) ->
end.
%% The ets table Cntrs is used for counting objects per size.
-count_input(Head, Cntrs, L) when Head#head.version =:= 8 ->
- count_input1(Cntrs, L, []);
-count_input(_Head, _Cntrs, L) ->
+count_input(L) ->
lists:reverse(L).
-count_input1(Cntrs, [[LogSz | B] | Ts], L) ->
- case catch ets:update_counter(Cntrs, LogSz, 1) of
- N when is_integer(N) -> ok;
- _Badarg -> true = ets:insert(Cntrs, {LogSz, 1})
- end,
- count_input1(Cntrs, Ts, [B | L]);
-count_input1(_Cntrs, [], L) ->
- L.
-
fsck_read(Pos, F, L, Seq) ->
case file:position(F, Pos) of
{ok, _} ->
@@ -1564,11 +1537,6 @@ fsck_objs(Bin = <<Sz:32, Status:32, Tail/binary>>, Kp, Head, L, Seq) ->
fsck_objs(Bin, _Kp, _Head, L, Seq) ->
{more, Bin, 0, L, Seq}.
-make_objects([{K,BT}|Os], Seq, Kp, Head, L) when Head#head.version =:= 8 ->
- LogSz = dets_v8:sz2pos(byte_size(BT)+?OHDSZ_v8),
- Slot = dets_v8:db_hash(K, Head),
- Obj = [LogSz | <<Slot:32, LogSz:8, BT/binary>>],
- make_objects(Os, Seq, Kp, Head, [Obj | L]);
make_objects([{K,BT} | Os], Seq, Kp, Head, L) ->
Obj = make_object(Head, K, Seq, BT),
make_objects(Os, Seq+1, Kp, Head, [Obj | L]);
@@ -1607,7 +1575,7 @@ do_perform_save(H) ->
FileHeader = file_header(H1, FreeListsPointer, ?CLOSED_PROPERLY),
case dets_utils:debug_mode() of
true ->
- TmpHead0 = init_freelist(H1#head{fixed = false}, true),
+ TmpHead0 = init_freelist(H1#head{fixed = false}),
TmpHead = TmpHead0#head{base = H1#head.base},
case
catch dets_utils:all_allocated_as_list(TmpHead)
@@ -1794,7 +1762,7 @@ table_parameters(Head) ->
(E, A) -> [E | A]
end, [], CL),
NoColls = lists:reverse(NoColls0),
- #?HASH_PARMS{file_format_version = Head#head.version,
+ #?HASH_PARMS{file_format_version = ?FILE_FORMAT_VERSION,
bchunk_format_version = ?BCHUNK_FORMAT_VERSION,
file = filename:basename(Head#head.filename),
type = Head#head.type,
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index 549179da68..9cd95705af 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -516,6 +516,22 @@ comp_op -> '>' : '$1'.
comp_op -> '=:=' : '$1'.
comp_op -> '=/=' : '$1'.
+Header
+"%% This file was automatically generated from the file \"erl_parse.yrl\"."
+"%%"
+"%% Copyright Ericsson AB 1996-2015. All Rights Reserved."
+"%%"
+"%% Licensed under the Apache License, Version 2.0 (the \"License\"); you may"
+"%% not use this file except in compliance with the License. You may obtain"
+"%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>"
+"%%"
+"%% Unless required by applicable law or agreed to in writing, software"
+"%% distributed under the License is distributed on an \"AS IS\" BASIS,"
+"%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."
+"%% See the License for the specific language governing permissions and"
+"%% limitations under the License."
+"".
+
Erlang code.
-export([parse_form/1,parse_exprs/1,parse_term/1]).
@@ -612,11 +628,11 @@ Erlang code.
| af_bin(abstract_expr())
| af_binary_op(abstract_expr())
| af_unary_op(abstract_expr())
- | af_record_access(abstract_expr())
+ | af_record_creation(abstract_expr())
| af_record_update(abstract_expr())
| af_record_index()
| af_record_field_access(abstract_expr())
- | af_map_access(abstract_expr())
+ | af_map_creation(abstract_expr())
| af_map_update(abstract_expr())
| af_catch()
| af_local_call()
@@ -720,26 +736,25 @@ Erlang code.
| af_bin(af_guard_test())
| af_binary_op(af_guard_test())
| af_unary_op(af_guard_test())
- | af_record_access(af_guard_test())
+ | af_record_creation(af_guard_test())
| af_record_index()
| af_record_field_access(af_guard_test())
- | af_map_access(abstract_expr()) % FIXME
- | af_map_update(abstract_expr()) % FIXME
+ | af_map_creation(abstract_expr())
+ | af_map_update(abstract_expr())
| af_guard_call()
| af_remote_guard_call().
-type af_record_field_access(T) ::
{'record_field', anno(), T, record_name(), af_field_name()}.
--type af_map_access(T) :: {'map', anno(), [af_map_field(T)]}.
-
--type af_map_update(T) :: {'map', anno(), T, [af_map_field(T)]}.
+-type af_map_creation(T) :: {'map', anno(), [af_assoc(T)]}.
--type af_map_field(T) :: af_map_field_assoc(T) | af_map_field_exact(T).
+-type af_map_update(T) :: {'map', anno(), T, [af_assoc(T)]}.
--type af_map_field_assoc(T) :: {'map_field_assoc', anno(), T, T}.
+-type af_assoc(T) :: {'map_field_assoc', anno(), T, T}
+ | af_assoc_exact(T).
--type af_map_field_exact(T) :: {'map_field_exact', anno(), T, T}.
+-type af_assoc_exact(T) :: {'map_field_exact', anno(), T, T}.
-type af_guard_call() :: {'call', anno(), function_name(), [af_guard_test()]}.
@@ -757,20 +772,20 @@ Erlang code.
| af_bin(af_pattern())
| af_binary_op(af_pattern())
| af_unary_op(af_pattern())
- | af_record_access(af_pattern())
+ | af_record_creation(af_pattern())
| af_record_index()
| af_map_pattern().
-type af_record_index() ::
{'record_index', anno(), record_name(), af_field_name()}.
--type af_record_access(T) ::
+-type af_record_creation(T) ::
{'record', anno(), record_name(), [af_record_field(T)]}.
-type af_record_field(T) :: {'record_field', anno(), af_field_name(), T}.
-type af_map_pattern() ::
- {'map', anno(), [af_map_field_exact(abstract_expr)]}. % FIXME?
+ {'map', anno(), [af_assoc_exact(abstract_expr)]}.
-type abstract_type() :: af_annotated_type()
| af_atom()
@@ -807,9 +822,9 @@ Erlang code.
{'type', anno(), 'range', [af_singleton_integer_type()]}.
-type af_map_type() :: {'type', anno(), 'map', 'any'}
- | {'type', anno(), 'map', [af_map_pair_type()]}.
+ | {'type', anno(), 'map', [af_assoc_type()]}.
--type af_map_pair_type() ::
+-type af_assoc_type() ::
{'type', anno(), 'map_field_assoc', [abstract_type()]}
| {'type', anno(), 'map_field_exact', [abstract_type()]}.
diff --git a/lib/stdlib/src/error_logger_file_h.erl b/lib/stdlib/src/error_logger_file_h.erl
index 665685d3ee..0b262de3ab 100644
--- a/lib/stdlib/src/error_logger_file_h.erl
+++ b/lib/stdlib/src/error_logger_file_h.erl
@@ -116,8 +116,8 @@ write_event(#st{fd=Fd}=State, Event) ->
ignore ->
ok;
{Head,Pid,FormatList} ->
- Time = maybe_utc(erlang:universaltime()),
- Header = write_time(Time, Head),
+ Time = erlang:universaltime(),
+ Header = header(Time, Head),
Body = format_body(State, FormatList),
AtNode = if
node(Pid) =/= node() ->
@@ -125,7 +125,7 @@ write_event(#st{fd=Fd}=State, Event) ->
true ->
[]
end,
- io:put_chars(Fd, [Header,Body,AtNode])
+ io:put_chars(Fd, [Header,AtNode,Body])
end.
format_body(State, [{Format,Args}|T]) ->
@@ -172,21 +172,6 @@ parse_event({warning_report, _GL, {Pid, std_warning, Args}}) ->
{"WARNING REPORT",Pid,format_term(Args)};
parse_event(_) -> ignore.
-maybe_utc(Time) ->
- UTC = case application:get_env(sasl, utc_log) of
- {ok, Val} -> Val;
- undefined ->
- %% Backwards compatible:
- case application:get_env(stdlib, utc_log) of
- {ok, Val} -> Val;
- undefined -> false
- end
- end,
- maybe_utc(Time, UTC).
-
-maybe_utc(Time, true) -> {utc, Time};
-maybe_utc(Time, _) -> {local, calendar:universal_time_to_local_time(Time)}.
-
format_term(Term) when is_list(Term) ->
case string_p(Term) of
true ->
@@ -227,17 +212,33 @@ string_p1([H|T]) when is_list(H) ->
string_p1([]) -> true;
string_p1(_) -> false.
-write_time({utc,{{Y,Mo,D},{H,Mi,S}}}, Type) ->
- io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s UTC ===~n",
- [Type,D,month(Mo),Y,t(H),t(Mi),t(S)]);
-write_time({local, {{Y,Mo,D},{H,Mi,S}}}, Type) ->
- io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s ===~n",
- [Type,D,month(Mo),Y,t(H),t(Mi),t(S)]).
+get_utc_config() ->
+ %% SASL utc_log configuration overrides stdlib config
+ %% in order to have uniform timestamps in log messages
+ case application:get_env(sasl, utc_log) of
+ {ok, Val} -> Val;
+ undefined ->
+ case application:get_env(stdlib, utc_log) of
+ {ok, Val} -> Val;
+ undefined -> false
+ end
+ end.
+
+header(Time, Title) ->
+ case get_utc_config() of
+ true ->
+ header(Time, Title, "UTC ");
+ _ ->
+ header(calendar:universal_time_to_local_time(Time), Title, "")
+ end.
+
+header({{Y,Mo,D},{H,Mi,S}}, Title, UTC) ->
+ io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s ~s===~n",
+ [Title,D,month(Mo),Y,t(H),t(Mi),t(S),UTC]).
t(X) when is_integer(X) ->
- t1(integer_to_list(X));
-t(_) ->
- "".
+ t1(integer_to_list(X)).
+
t1([X]) -> [$0,X];
t1(X) -> X.
@@ -253,5 +254,3 @@ month(9) -> "Sep";
month(10) -> "Oct";
month(11) -> "Nov";
month(12) -> "Dec".
-
-
diff --git a/lib/stdlib/src/error_logger_tty_h.erl b/lib/stdlib/src/error_logger_tty_h.erl
index cb22a8c0b6..2f2fd65252 100644
--- a/lib/stdlib/src/error_logger_tty_h.erl
+++ b/lib/stdlib/src/error_logger_tty_h.erl
@@ -128,13 +128,12 @@ write_events(State, [Ev|Es]) ->
write_events(_State, []) ->
ok.
-do_write_event(State, {Time0, Event}) ->
+do_write_event(State, {Time, Event}) ->
case parse_event(Event) of
ignore ->
ok;
- {Head,Pid,FormatList} ->
- Time = maybe_utc(Time0),
- Header = write_time(Time, Head),
+ {Title,Pid,FormatList} ->
+ Header = header(Time, Title),
Body = format_body(State, FormatList),
AtNode = if
node(Pid) =/= node() ->
@@ -142,7 +141,7 @@ do_write_event(State, {Time0, Event}) ->
true ->
[]
end,
- Str = [Header,Body,AtNode],
+ Str = [Header,AtNode,Body],
case State#st.io_mod of
io_lib ->
Str;
@@ -197,21 +196,6 @@ parse_event({warning_report, _GL, {Pid, std_warning, Args}}) ->
{"WARNING REPORT",Pid,format_term(Args)};
parse_event(_) -> ignore.
-maybe_utc(Time) ->
- UTC = case application:get_env(sasl, utc_log) of
- {ok, Val} -> Val;
- undefined ->
- %% Backwards compatible:
- case application:get_env(stdlib, utc_log) of
- {ok, Val} -> Val;
- undefined -> false
- end
- end,
- maybe_utc(Time, UTC).
-
-maybe_utc(Time, true) -> {utc, Time};
-maybe_utc(Time, _) -> {local, calendar:universal_time_to_local_time(Time)}.
-
format_term(Term) when is_list(Term) ->
case string_p(Term) of
true ->
@@ -255,12 +239,29 @@ string_p1([H|T]) when is_list(H) ->
string_p1([]) -> true;
string_p1(_) -> false.
-write_time({utc,{{Y,Mo,D},{H,Mi,S}}},Type) ->
- io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s UTC ===~n",
- [Type,D,month(Mo),Y,t(H),t(Mi),t(S)]);
-write_time({local, {{Y,Mo,D},{H,Mi,S}}},Type) ->
- io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s ===~n",
- [Type,D,month(Mo),Y,t(H),t(Mi),t(S)]).
+get_utc_config() ->
+ %% SASL utc_log configuration overrides stdlib config
+ %% in order to have uniform timestamps in log messages
+ case application:get_env(sasl, utc_log) of
+ {ok, Val} -> Val;
+ undefined ->
+ case application:get_env(stdlib, utc_log) of
+ {ok, Val} -> Val;
+ undefined -> false
+ end
+ end.
+
+header(Time, Title) ->
+ case get_utc_config() of
+ true ->
+ header(Time, Title, "UTC ");
+ _ ->
+ header(calendar:universal_time_to_local_time(Time), Title, "")
+ end.
+
+header({{Y,Mo,D},{H,Mi,S}}, Title, UTC) ->
+ io_lib:format("~n=~s==== ~p-~s-~p::~s:~s:~s ~s===~n",
+ [Title,D,month(Mo),Y,t(H),t(Mi),t(S),UTC]).
t(X) when is_integer(X) ->
t1(integer_to_list(X));
@@ -281,8 +282,3 @@ month(9) -> "Sep";
month(10) -> "Oct";
month(11) -> "Nov";
month(12) -> "Dec".
-
-
-
-
-
diff --git a/lib/stdlib/src/gb_sets.erl b/lib/stdlib/src/gb_sets.erl
index 47a8fa6db0..6d6f7d40ac 100644
--- a/lib/stdlib/src/gb_sets.erl
+++ b/lib/stdlib/src/gb_sets.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% =====================================================================
%% Ordered Sets implemented as General Balanced Trees
diff --git a/lib/stdlib/src/gb_trees.erl b/lib/stdlib/src/gb_trees.erl
index c4a20d92a7..457287fa52 100644
--- a/lib/stdlib/src/gb_trees.erl
+++ b/lib/stdlib/src/gb_trees.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2015. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -14,8 +9,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
%%
%% =====================================================================
%% General Balanced Trees - highly efficient dictionaries.
diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl
index 17d1ebecec..018aca90e6 100644
--- a/lib/stdlib/src/gen_statem.erl
+++ b/lib/stdlib/src/gen_statem.erl
@@ -85,7 +85,8 @@
-type state_enter() :: 'state_enter'.
-type transition_option() ::
- postpone() | hibernate() | event_timeout().
+ postpone() | hibernate() |
+ event_timeout() | state_timeout().
-type postpone() ::
%% If 'true' postpone the current event
%% and retry it when the state changes (=/=)
@@ -108,7 +109,7 @@
%% * All action()s are executed in order of apperance.
%% * Postponing the current event is performed
%% iff 'postpone' is 'true'.
- %% * A state timer is started iff 'timeout' is set.
+ %% * A state timeout is started iff 'timeout' is set.
%% * Pending events are handled or if there are
%% no pending events the server goes into receive
%% or hibernate (iff 'hibernate' is 'true')
@@ -154,12 +155,12 @@
-type handle_event_result() ::
event_handler_result(state()).
%%
--type state_enter_result(StateType) ::
+-type state_enter_result(State) ::
{'next_state', % {next_state,NextState,NewData,[]}
- State :: StateType,
+ State,
NewData :: data()} |
{'next_state', % State transition, maybe to the same state
- State :: StateType,
+ State,
NewData :: data(),
Actions :: [enter_action()] | enter_action()} |
state_callback_result(enter_action()).
@@ -231,9 +232,9 @@
-callback handle_event(
'enter',
OldState :: state(),
- State :: state(), % Current state
+ State, % Current state
Data :: data()) ->
- state_enter_result(state());
+ state_enter_result(State);
(event_type(),
EventContent :: term(),
State :: state(), % Current state
@@ -596,8 +597,8 @@ enter(Module, Opts, State, Data, Server, Actions, Parent) ->
data => Data,
postponed => P,
%% The rest of the fields are set from to the arguments to
- %% loop_event_actions/9 when it finally loops back to loop/3
- %% in loop_events_done/9
+ %% loop_event_actions/10 when it finally loops back to loop/3
+ %% in loop_events/10
%%
%% Marker for initial state, cleared immediately when used
init_state => true
@@ -605,9 +606,10 @@ enter(Module, Opts, State, Data, Server, Actions, Parent) ->
NewDebug = sys_debug(Debug, S, State, {enter,Event,State}),
case call_callback_mode(S) of
{ok,NewS} ->
- StateTimer = undefined,
+ TimerRefs = #{},
+ TimerTypes = #{},
loop_event_actions(
- Parent, NewDebug, NewS, StateTimer,
+ Parent, NewDebug, NewS, TimerRefs, TimerTypes,
Events, Event, State, Data, NewActions);
{Class,Reason,Stacktrace} ->
terminate(
@@ -747,6 +749,10 @@ print_event(Dev, {out,Reply,{To,_Tag}}, {Name,State}) ->
io:format(
Dev, "*DBG* ~p send ~p to ~p from state ~p~n",
[Name,Reply,To,State]);
+print_event(Dev, {terminate,Reason}, {Name,State}) ->
+ io:format(
+ Dev, "*DBG* ~p terminate ~p in state ~p~n",
+ [Name,Reason,State]);
print_event(Dev, {Tag,Event,NextState}, {Name,State}) ->
StateString =
case NextState of
@@ -806,7 +812,7 @@ loop(Parent, Debug, #{hibernate := Hibernate} = S) ->
%% Entry point for wakeup_from_hibernate/3
loop_receive(
- Parent, Debug, #{timer := Timer, state_timer := StateTimer} = S) ->
+ Parent, Debug, #{timer_refs := TimerRefs, timer_types := TimerTypes} = S) ->
receive
Msg ->
case Msg of
@@ -822,18 +828,23 @@ loop_receive(
%% but this will stand out in the crash report...
terminate(
exit, Reason, ?STACKTRACE(), Debug, S, [EXIT]);
- {timeout,Timer,Content}
- when Timer =/= undefined ->
- loop_receive_result(
- Parent, Debug, S, StateTimer,
- {timeout,Content});
- {timeout,StateTimer,Content}
- when StateTimer =/= undefined ->
- loop_receive_result(
- Parent, Debug, S, undefined,
- {state_timeout,Content});
+ {timeout,TimerRef,TimerMsg} ->
+ case TimerRefs of
+ #{TimerRef := TimerType} ->
+ Event = {TimerType,TimerMsg},
+ %% Unregister the triggered timeout
+ loop_receive_result(
+ Parent, Debug, S,
+ maps:remove(TimerRef, TimerRefs),
+ maps:remove(TimerType, TimerTypes),
+ Event);
+ _ ->
+ Event = {info,Msg},
+ loop_receive_result(
+ Parent, Debug, S,
+ TimerRefs, TimerTypes, Event)
+ end;
_ ->
- cancel_timer(Timer),
Event =
case Msg of
{'$gen_call',From,Request} ->
@@ -844,12 +855,15 @@ loop_receive(
{info,Msg}
end,
loop_receive_result(
- Parent, Debug, S, StateTimer, Event)
+ Parent, Debug, S,
+ TimerRefs, TimerTypes, Event)
end
end.
-loop_receive_result(Parent, Debug, #{state := State} = S, StateTimer, Event) ->
- %% The fields 'timer', 'state_timer' and 'hibernate'
+loop_receive_result(
+ Parent, Debug, #{state := State} = S,
+ TimerRefs, TimerTypes, Event) ->
+ %% The fields 'timer_refs', 'timer_types' and 'hibernate'
%% are now invalid in state map S - they will be recalculated
%% and restored when we return to loop/3
%%
@@ -857,82 +871,196 @@ loop_receive_result(Parent, Debug, #{state := State} = S, StateTimer, Event) ->
%% Here the queue of not yet handled events is created
Events = [],
Hibernate = false,
- loop_event(Parent, NewDebug, S, StateTimer, Events, Event, Hibernate).
+ loop_event(
+ Parent, NewDebug, S, TimerRefs, TimerTypes, Events, Event, Hibernate).
-%% Process the event queue, or if it is empty
-%% loop back to loop/3 to receive a new event
-loop_events(
- Parent, Debug, S, StateTimeout,
- [Event|Events], _Timeout, State, Data, P, Hibernate) ->
+%% Entry point for handling an event, received or enqueued
+loop_event(
+ Parent, Debug, #{state := State, data := Data} = S, TimerRefs, TimerTypes,
+ Events, {Type,Content} = Event, Hibernate) ->
%%
- %% If there was an event timer requested we just ignore that
- %% since we have events to handle which cancels the timer
- loop_event(
- Parent, Debug, S, StateTimeout,
- Events, Event, State, Data, P, Hibernate);
-loop_events(
- Parent, Debug, S, {state_timeout,Time,EventContent},
- [] = Events, Timeout, State, Data, P, Hibernate) ->
- if
- Time =:= 0 ->
- %% Simulate an immediate timeout
- %% so we do not get the timeout message
- %% after any received event
- %%
- %% This faked event will cancel
- %& any not yet started event timer
- Event = {state_timeout,EventContent},
- StateTimer = undefined,
- loop_event(
- Parent, Debug, S, StateTimer,
- Events, Event, State, Data, P, Hibernate);
- true ->
- StateTimer = erlang:start_timer(Time, self(), EventContent),
- loop_events(
- Parent, Debug, S, StateTimer,
- Events, Timeout, State, Data, P, Hibernate)
- end;
-loop_events(
- Parent, Debug, S, StateTimer,
- [] = Events, Timeout, State, Data, P, Hibernate) ->
- case Timeout of
- {timeout,0,EventContent} ->
- %% Simulate an immediate timeout
- %% so we do not get the timeout message
- %% after any received event
- %%
- Event = {timeout,EventContent},
- loop_event(
- Parent, Debug, S, StateTimer,
- Events, Event, State, Data, P, Hibernate);
- {timeout,Time,EventContent} ->
- Timer = erlang:start_timer(Time, self(), EventContent),
- loop_events_done(
- Parent, Debug, S, StateTimer,
- State, Data, P, Hibernate, Timer);
- undefined ->
- %% No event timeout has been requested
- Timer = undefined,
- loop_events_done(
- Parent, Debug, S, StateTimer,
- State, Data, P, Hibernate, Timer)
+ %% If Hibernate is true here it can only be
+ %% because it was set from an event action
+ %% and we did not go into hibernation since there
+ %% were events in queue, so we do what the user
+ %% might rely on i.e collect garbage which
+ %% would have happened if we actually hibernated
+ %% and immediately was awakened
+ Hibernate andalso garbage_collect(),
+ case call_state_function(S, Type, Content, State, Data) of
+ {ok,Result,NewS} ->
+ %% Cancel event timeout
+ {NewTimerRefs,NewTimerTypes} =
+ cancel_timer_by_type(
+ timeout, TimerRefs, TimerTypes),
+ {NewData,NextState,Actions} =
+ parse_event_result(
+ true, Debug, NewS, Result,
+ Events, Event, State, Data),
+ loop_event_actions(
+ Parent, Debug, S, NewTimerRefs, NewTimerTypes,
+ Events, Event, NextState, NewData, Actions);
+ {Class,Reason,Stacktrace} ->
+ terminate(
+ Class, Reason, Stacktrace, Debug, S, [Event|Events])
end.
-%% Back to the top
-loop_events_done(
- Parent, Debug, S, StateTimer,
- State, Data, P, Hibernate, Timer) ->
+loop_event_actions(
+ Parent, Debug,
+ #{state := State, state_enter := StateEnter} = S, TimerRefs, TimerTypes,
+ Events, Event, NextState, NewData, Actions) ->
+ case parse_actions(Debug, S, State, Actions) of
+ {ok,NewDebug,Hibernate,TimeoutsR,Postpone,NextEventsR} ->
+ if
+ StateEnter, NextState =/= State ->
+ loop_event_enter(
+ Parent, NewDebug, S, TimerRefs, TimerTypes,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR);
+ StateEnter ->
+ case maps:is_key(init_state, S) of
+ true ->
+ %% Avoid infinite loop in initial state
+ %% with state entry events
+ NewS = maps:remove(init_state, S),
+ loop_event_enter(
+ Parent, NewDebug, NewS, TimerRefs, TimerTypes,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR);
+ false ->
+ loop_event_result(
+ Parent, NewDebug, S, TimerRefs, TimerTypes,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR)
+ end;
+ true ->
+ loop_event_result(
+ Parent, NewDebug, S, TimerRefs, TimerTypes,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR)
+ end;
+ {Class,Reason,Stacktrace} ->
+ terminate(
+ Class, Reason, Stacktrace,
+ Debug, S#{data := NewData}, [Event|Events])
+ end.
+
+loop_event_enter(
+ Parent, Debug, #{state := State} = S, TimerRefs, TimerTypes,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR) ->
+ case call_state_function(S, enter, State, NextState, NewData) of
+ {ok,Result,NewS} ->
+ {NewerData,_,Actions} =
+ parse_event_result(
+ false, Debug, NewS, Result,
+ Events, Event, NextState, NewData),
+ loop_event_enter_actions(
+ Parent, Debug, NewS, TimerRefs, TimerTypes,
+ Events, Event, NextState, NewerData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR, Actions);
+ {Class,Reason,Stacktrace} ->
+ terminate(
+ Class, Reason, Stacktrace,
+ Debug, S#{state := NextState, data := NewData},
+ [Event|Events])
+ end.
+
+loop_event_enter_actions(
+ Parent, Debug, S, TimerRefs, TimerTypes,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR, Actions) ->
+ case
+ parse_enter_actions(
+ Debug, S, NextState, Actions,
+ Hibernate, TimeoutsR)
+ of
+ {ok,NewDebug,NewHibernate,NewTimeoutsR,_,_} ->
+ loop_event_result(
+ Parent, NewDebug, S, TimerRefs, TimerTypes,
+ Events, Event, NextState, NewData,
+ NewHibernate, NewTimeoutsR, Postpone, NextEventsR);
+ {Class,Reason,Stacktrace} ->
+ terminate(
+ Class, Reason, Stacktrace,
+ Debug, S#{state := NextState, data := NewData},
+ [Event|Events])
+ end.
+
+loop_event_result(
+ Parent, Debug,
+ #{state := State, postponed := P_0} = S, TimerRefs_0, TimerTypes_0,
+ Events, Event, NextState, NewData,
+ Hibernate, TimeoutsR, Postpone, NextEventsR) ->
+ %%
+ %% All options have been collected and next_events are buffered.
+ %% Do the actual state transition.
+ %%
+ {NewDebug,P_1} = % Move current event to postponed if Postpone
+ case Postpone of
+ true ->
+ {sys_debug(Debug, S, State, {postpone,Event,State}),
+ [Event|P_0]};
+ false ->
+ {sys_debug(Debug, S, State, {consume,Event,State}),
+ P_0}
+ end,
+ {Events_1,NewP,{TimerRefs_1,TimerTypes_1}} =
+ %% Move all postponed events to queue and cancel the
+ %% state timeout if the state changes
+ if
+ NextState =:= State ->
+ {Events,P_1,{TimerRefs_0,TimerTypes_0}};
+ true ->
+ {lists:reverse(P_1, Events),[],
+ cancel_timer_by_type(
+ state_timeout, TimerRefs_0, TimerTypes_0)}
+ end,
+ {TimerRefs_2,TimerTypes_2,TimeoutEvents} =
+ %% Stop and start timers non-event timers
+ parse_timers(TimerRefs_1, TimerTypes_1, TimeoutsR),
+ %% Place next events last in reversed queue
+ Events_2R = lists:reverse(Events_1, NextEventsR),
+ %% Enqueue immediate timeout events and start event timer
+ {NewTimerRefs,NewTimerTypes,Events_3R} =
+ process_timeout_events(
+ TimerRefs_2, TimerTypes_2, TimeoutEvents, Events_2R),
+ NewEvents = lists:reverse(Events_3R),
+ loop_events(
+ Parent, NewDebug, S, NewTimerRefs, NewTimerTypes,
+ NewEvents, Hibernate, NextState, NewData, NewP).
+
+%% Loop until out of enqueued events
+%%
+loop_events(
+ Parent, Debug, S, TimerRefs, TimerTypes,
+ [] = _Events, Hibernate, State, Data, P) ->
+ %% Update S and loop back to loop/3 to receive a new event
NewS =
S#{
state := State,
data := Data,
postponed := P,
hibernate => Hibernate,
- timer => Timer,
- state_timer => StateTimer},
- loop(Parent, Debug, NewS).
+ timer_refs => TimerRefs,
+ timer_types => TimerTypes},
+ loop(Parent, Debug, NewS);
+loop_events(
+ Parent, Debug, S, TimerRefs, TimerTypes,
+ [Event|Events], Hibernate, State, Data, P) ->
+ %% Update S and continue with enqueued events
+ NewS =
+ S#{
+ state := State,
+ data := Data,
+ postponed := P},
+ loop_event(
+ Parent, Debug, NewS, TimerRefs, TimerTypes, Events, Event, Hibernate).
+
+%%---------------------------------------------------------------------------
+%% Server loop helpers
call_callback_mode(#{module := Module} = S) ->
try Module:callback_mode() of
@@ -996,6 +1124,7 @@ parse_callback_mode([H|T], CBMode, StateEnter) ->
parse_callback_mode(_, _CBMode, StateEnter) ->
{undefined,StateEnter}.
+
call_state_function(
#{callback_mode := undefined} = S,
Type, Content, State, Data) ->
@@ -1061,42 +1190,6 @@ call_state_function(
{Class,Reason,erlang:get_stacktrace()}
end.
-%% Update S and continue
-loop_event(
- Parent, Debug, S, StateTimer,
- Events, Event, State, Data, P, Hibernate) ->
- NewS =
- S#{
- state := State,
- data := Data,
- postponed := P},
- loop_event(Parent, Debug, NewS, StateTimer, Events, Event, Hibernate).
-
-loop_event(
- Parent, Debug, #{state := State, data := Data} = S, StateTimer,
- Events, {Type,Content} = Event, Hibernate) ->
- %%
- %% If Hibernate is true here it can only be
- %% because it was set from an event action
- %% and we did not go into hibernation since there
- %% were events in queue, so we do what the user
- %% might rely on i.e collect garbage which
- %% would have happened if we actually hibernated
- %% and immediately was awakened
- Hibernate andalso garbage_collect(),
- case call_state_function(S, Type, Content, State, Data) of
- {ok,Result,NewS} ->
- {NewData,NextState,Actions} =
- parse_event_result(
- true, Debug, NewS, Result,
- Events, Event, State, Data),
- loop_event_actions(
- Parent, Debug, S, StateTimer,
- Events, Event, NextState, NewData, Actions);
- {Class,Reason,Stacktrace} ->
- terminate(
- Class, Reason, Stacktrace, Debug, S, [Event|Events])
- end.
%% Interpret all callback return variants
parse_event_result(
@@ -1146,32 +1239,32 @@ parse_event_result(
Debug, S, [Event|Events])
end.
+
parse_enter_actions(
Debug, S, State, Actions,
- Hibernate, Timeout, StateTimeout) ->
+ Hibernate, TimeoutsR) ->
Postpone = forbidden,
- NextEvents = forbidden,
+ NextEventsR = forbidden,
parse_actions(
Debug, S, State, listify(Actions),
- Hibernate, Timeout, StateTimeout, Postpone, NextEvents).
+ Hibernate, TimeoutsR, Postpone, NextEventsR).
parse_actions(Debug, S, State, Actions) ->
Hibernate = false,
- Timeout = undefined,
- StateTimeout = undefined,
+ TimeoutsR = [],
Postpone = false,
- NextEvents = [],
+ NextEventsR = [],
parse_actions(
Debug, S, State, listify(Actions),
- Hibernate, Timeout, StateTimeout, Postpone, NextEvents).
+ Hibernate, TimeoutsR, Postpone, NextEventsR).
%%
parse_actions(
Debug, _S, _State, [],
- Hibernate, Timeout, StateTimeout, Postpone, NextEvents) ->
- {ok,Debug,Hibernate,Timeout,StateTimeout,Postpone,NextEvents};
+ Hibernate, TimeoutsR, Postpone, NextEventsR) ->
+ {ok,Debug,Hibernate,TimeoutsR,Postpone,NextEventsR};
parse_actions(
Debug, S, State, [Action|Actions],
- Hibernate, Timeout, StateTimeout, Postpone, NextEvents) ->
+ Hibernate, TimeoutsR, Postpone, NextEventsR) ->
case Action of
%% Actual actions
{reply,From,Reply} ->
@@ -1180,8 +1273,7 @@ parse_actions(
NewDebug = do_reply(Debug, S, State, From, Reply),
parse_actions(
NewDebug, S, State, Actions,
- Hibernate, Timeout, StateTimeout,
- Postpone, NextEvents);
+ Hibernate, TimeoutsR, Postpone, NextEventsR);
false ->
{error,
{bad_action_from_state_function,Action},
@@ -1191,7 +1283,7 @@ parse_actions(
{hibernate,NewHibernate} when is_boolean(NewHibernate) ->
parse_actions(
Debug, S, State, Actions,
- NewHibernate, Timeout, StateTimeout, Postpone, NextEvents);
+ NewHibernate, TimeoutsR, Postpone, NextEventsR);
{hibernate,_} ->
{error,
{bad_action_from_state_function,Action},
@@ -1199,43 +1291,44 @@ parse_actions(
hibernate ->
parse_actions(
Debug, S, State, Actions,
- true, Timeout, StateTimeout, Postpone, NextEvents);
- {state_timeout,Time,_} = NewStateTimeout
+ true, TimeoutsR, Postpone, NextEventsR);
+ {state_timeout,Time,_} = StateTimeout
when is_integer(Time), Time >= 0;
Time =:= infinity ->
parse_actions(
Debug, S, State, Actions,
- Hibernate, Timeout, NewStateTimeout, Postpone, NextEvents);
+ Hibernate, [StateTimeout|TimeoutsR], Postpone, NextEventsR);
{state_timeout,_,_} ->
{error,
{bad_action_from_state_function,Action},
?STACKTRACE()};
- {timeout,infinity,_} -> % Clear timer - it will never trigger
+ {timeout,infinity,_} ->
+ %% Ignore - timeout will never happen and already cancelled
parse_actions(
Debug, S, State, Actions,
- Hibernate, undefined, StateTimeout, Postpone, NextEvents);
- {timeout,Time,_} = NewTimeout when is_integer(Time), Time >= 0 ->
+ Hibernate, TimeoutsR, Postpone, NextEventsR);
+ {timeout,Time,_} = Timeout when is_integer(Time), Time >= 0 ->
parse_actions(
Debug, S, State, Actions,
- Hibernate, NewTimeout, StateTimeout, Postpone, NextEvents);
+ Hibernate, [Timeout|TimeoutsR], Postpone, NextEventsR);
{timeout,_,_} ->
{error,
{bad_action_from_state_function,Action},
?STACKTRACE()};
- infinity -> % Clear timer - it will never trigger
+ infinity -> % Ignore - timeout will never happen
parse_actions(
Debug, S, State, Actions,
- Hibernate, undefined, StateTimeout, Postpone, NextEvents);
+ Hibernate, TimeoutsR, Postpone, NextEventsR);
Time when is_integer(Time), Time >= 0 ->
- NewTimeout = {timeout,Time,Time},
+ Timeout = {timeout,Time,Time},
parse_actions(
Debug, S, State, Actions,
- Hibernate, NewTimeout, StateTimeout, Postpone, NextEvents);
+ Hibernate, [Timeout|TimeoutsR], Postpone, NextEventsR);
{postpone,NewPostpone}
when is_boolean(NewPostpone), Postpone =/= forbidden ->
parse_actions(
Debug, S, State, Actions,
- Hibernate, Timeout, StateTimeout, NewPostpone, NextEvents);
+ Hibernate, TimeoutsR, NewPostpone, NextEventsR);
{postpone,_} ->
{error,
{bad_action_from_state_function,Action},
@@ -1243,16 +1336,16 @@ parse_actions(
postpone when Postpone =/= forbidden ->
parse_actions(
Debug, S, State, Actions,
- Hibernate, Timeout, StateTimeout, true, NextEvents);
+ Hibernate, TimeoutsR, true, NextEventsR);
{next_event,Type,Content} ->
case event_type(Type) of
- true when NextEvents =/= forbidden ->
+ true when NextEventsR =/= forbidden ->
NewDebug =
sys_debug(Debug, S, State, {in,{Type,Content}}),
parse_actions(
NewDebug, S, State, Actions,
- Hibernate, Timeout, StateTimeout,
- Postpone, [{Type,Content}|NextEvents]);
+ Hibernate, TimeoutsR, Postpone,
+ [{Type,Content}|NextEventsR]);
_ ->
{error,
{bad_action_from_state_function,Action},
@@ -1264,158 +1357,92 @@ parse_actions(
?STACKTRACE()}
end.
-loop_event_actions(
- Parent, Debug,
- #{state := State, state_enter := StateEnter} = S, StateTimer,
- Events, Event, NextState, NewData, Actions) ->
- case parse_actions(Debug, S, State, Actions) of
- {ok,NewDebug,Hibernate,Timeout,StateTimeout,Postpone,NextEvents} ->
+
+%% Stop and start timers as well as create timeout zero events
+%% and pending event timer
+%%
+%% Stop and start timers non-event timers
+parse_timers(TimerRefs, TimerTypes, TimeoutsR) ->
+ parse_timers(TimerRefs, TimerTypes, TimeoutsR, #{}, []).
+%%
+parse_timers(TimerRefs, TimerTypes, [], _Seen, TimeoutEvents) ->
+ {TimerRefs,TimerTypes,TimeoutEvents};
+parse_timers(
+ TimerRefs, TimerTypes, [Timeout|TimeoutsR], Seen, TimeoutEvents) ->
+ {TimerType,Time,TimerMsg} = Timeout,
+ case Seen of
+ #{TimerType := _} ->
+ %% Type seen before - ignore
+ parse_timers(
+ TimerRefs, TimerTypes, TimeoutsR, Seen, TimeoutEvents);
+ #{} ->
+ %% Unseen type - handle
+ NewSeen = Seen#{TimerType => true},
+ %% Cancel any running timer
+ {NewTimerRefs,NewTimerTypes} =
+ cancel_timer_by_type(TimerType, TimerRefs, TimerTypes),
if
- StateEnter, NextState =/= State ->
- loop_event_enter(
- Parent, NewDebug, S, StateTimer,
- Events, Event, NextState, NewData,
- Hibernate, Timeout, StateTimeout, Postpone, NextEvents);
- StateEnter ->
- case maps:is_key(init_state, S) of
- true ->
- %% Avoid infinite loop in initial state
- %% with state entry events
- NewS = maps:remove(init_state, S),
- loop_event_enter(
- Parent, NewDebug, NewS, StateTimer,
- Events, Event, NextState, NewData,
- Hibernate, Timeout, StateTimeout,
- Postpone, NextEvents);
- false ->
- loop_event_result(
- Parent, NewDebug, S, StateTimer,
- Events, Event, NextState, NewData,
- Hibernate, Timeout, StateTimeout,
- Postpone, NextEvents)
- end;
+ Time =:= infinity ->
+ %% Ignore - timer will never fire
+ parse_timers(
+ NewTimerRefs, NewTimerTypes, TimeoutsR,
+ NewSeen, TimeoutEvents);
+ TimerType =:= timeout ->
+ %% Handle event timer later
+ parse_timers(
+ NewTimerRefs, NewTimerTypes, TimeoutsR,
+ NewSeen, [Timeout|TimeoutEvents]);
+ Time =:= 0 ->
+ %% Handle zero time timeouts later
+ TimeoutEvent = {TimerType,TimerMsg},
+ parse_timers(
+ NewTimerRefs, NewTimerTypes, TimeoutsR,
+ NewSeen, [TimeoutEvent|TimeoutEvents]);
true ->
- loop_event_result(
- Parent, NewDebug, S, StateTimer,
- Events, Event, NextState, NewData,
- Hibernate, Timeout, StateTimeout, Postpone, NextEvents)
- end;
- {Class,Reason,Stacktrace} ->
- terminate(
- Class, Reason, Stacktrace,
- Debug, S#{data := NewData}, [Event|Events])
+ %% Start a new timer
+ TimerRef = erlang:start_timer(Time, self(), TimerMsg),
+ parse_timers(
+ NewTimerRefs#{TimerRef => TimerType},
+ NewTimerTypes#{TimerType => TimerRef},
+ TimeoutsR, NewSeen, TimeoutEvents)
+ end
end.
-loop_event_enter(
- Parent, Debug, #{state := State} = S, StateTimer,
- Events, Event, NextState, NewData,
- Hibernate, Timeout, StateTimeout, Postpone, NextEvents) ->
- case call_state_function(S, enter, State, NextState, NewData) of
- {ok,Result,NewS} ->
- {NewerData,_,Actions} =
- parse_event_result(
- false, Debug, NewS, Result,
- Events, Event, NextState, NewData),
- loop_event_enter_actions(
- Parent, Debug, NewS, StateTimer,
- Events, Event, NextState, NewerData,
- Hibernate, Timeout, StateTimeout, Postpone, NextEvents, Actions);
- {Class,Reason,Stacktrace} ->
- terminate(
- Class, Reason, Stacktrace,
- Debug, S#{state := NextState, data := NewData},
- [Event|Events])
- end.
+%% Enqueue immediate timeout events and start event timer
+process_timeout_events(TimerRefs, TimerTypes, [], EventsR) ->
+ {TimerRefs, TimerTypes, EventsR};
+process_timeout_events(
+ TimerRefs, TimerTypes,
+ [{timeout,0,TimerMsg}|TimeoutEvents], []) ->
+ %% No enqueued events - insert a timeout zero event
+ TimeoutEvent = {timeout,TimerMsg},
+ process_timeout_events(
+ TimerRefs, TimerTypes,
+ TimeoutEvents, [TimeoutEvent]);
+process_timeout_events(
+ TimerRefs, TimerTypes,
+ [{timeout,Time,TimerMsg}], []) ->
+ %% No enqueued events - start event timer
+ TimerRef = erlang:start_timer(Time, self(), TimerMsg),
+ process_timeout_events(
+ TimerRefs#{TimerRef => timeout}, TimerTypes#{timeout => TimerRef},
+ [], []);
+process_timeout_events(
+ TimerRefs, TimerTypes,
+ [{timeout,_Time,_TimerMsg}|TimeoutEvents], EventsR) ->
+ %% There will be some other event so optimize by not starting
+ %% an event timer to just have to cancel it again
+ process_timeout_events(
+ TimerRefs, TimerTypes,
+ TimeoutEvents, EventsR);
+process_timeout_events(
+ TimerRefs, TimerTypes,
+ [{_TimeoutType,_TimeoutMsg} = TimeoutEvent|TimeoutEvents], EventsR) ->
+ process_timeout_events(
+ TimerRefs, TimerTypes,
+ TimeoutEvents, [TimeoutEvent|EventsR]).
-loop_event_enter_actions(
- Parent, Debug, S, StateTimer,
- Events, Event, NextState, NewData,
- Hibernate, Timeout, StateTimeout, Postpone, NextEvents, Actions) ->
- case
- parse_enter_actions(
- Debug, S, NextState, Actions,
- Hibernate, Timeout, StateTimeout)
- of
- {ok,NewDebug,NewHibernate,NewTimeout,NewStateTimeout,_,_} ->
- loop_event_result(
- Parent, NewDebug, S, StateTimer,
- Events, Event, NextState, NewData,
- NewHibernate, NewTimeout, NewStateTimeout, Postpone, NextEvents);
- {Class,Reason,Stacktrace} ->
- terminate(
- Class, Reason, Stacktrace,
- Debug, S#{state := NextState, data := NewData},
- [Event|Events])
- end.
-loop_event_result(
- Parent, Debug,
- #{state := State, postponed := P_0} = S, StateTimer,
- Events, Event, NextState, NewData,
- Hibernate, Timeout, StateTimeout, Postpone, NextEvents) ->
- %%
- %% All options have been collected and next_events are buffered.
- %% Do the actual state transition.
- %%
- NewStateTimeout =
- case StateTimeout of
- {state_timeout,Time,_} ->
- %% New timeout -> cancel timer
- case StateTimer of
- {state_timeout,_,_} ->
- ok;
- _ ->
- cancel_timer(StateTimer)
- end,
- case Time of
- infinity ->
- undefined;
- _ ->
- StateTimeout
- end;
- undefined when NextState =/= State ->
- %% State change -> cancel timer
- case StateTimer of
- {state_timeout,_,_} ->
- ok;
- _ ->
- cancel_timer(StateTimer)
- end,
- undefined;
- undefined ->
- StateTimer
- end,
- %%
- P_1 = % Move current event to postponed if Postpone
- case Postpone of
- true ->
- [Event|P_0];
- false ->
- P_0
- end,
- {Events_1,NewP} = % Move all postponed events to queue if state change
- if
- NextState =:= State ->
- {Events,P_1};
- true ->
- {lists:reverse(P_1, Events),[]}
- end,
- %% Place next events first in queue
- NewEvents = lists:reverse(NextEvents, Events_1),
- %%
- NewDebug =
- sys_debug(
- Debug, S, State,
- case Postpone of
- true ->
- {postpone,Event,State};
- false ->
- {consume,Event,State}
- end),
- %%
- loop_events(
- Parent, NewDebug, S, NewStateTimeout,
- NewEvents, Timeout, NextState, NewData, NewP, Hibernate).
%%---------------------------------------------------------------------------
%% Server helpers
@@ -1474,16 +1501,20 @@ terminate(
sys:print_log(Debug),
erlang:raise(C, R, ST)
end,
- case Reason of
- normal -> ok;
- shutdown -> ok;
- {shutdown,_} -> ok;
- _ ->
- error_info(
- Class, Reason, Stacktrace, S, Q, P,
- format_status(terminate, get(), S)),
- sys:print_log(Debug)
- end,
+ _ =
+ case Reason of
+ normal ->
+ sys_debug(Debug, S, State, {terminate,Reason});
+ shutdown ->
+ sys_debug(Debug, S, State, {terminate,Reason});
+ {shutdown,_} ->
+ sys_debug(Debug, S, State, {terminate,Reason});
+ _ ->
+ error_info(
+ Class, Reason, Stacktrace, S, Q, P,
+ format_status(terminate, get(), S)),
+ sys:print_log(Debug)
+ end,
case Stacktrace of
[] ->
erlang:Class(Reason);
@@ -1605,8 +1636,19 @@ listify(Item) when is_list(Item) ->
listify(Item) ->
[Item].
-cancel_timer(undefined) ->
- ok;
+%% Cancel timer if running, otherwise no op
+cancel_timer_by_type(TimerType, TimerRefs, TimerTypes) ->
+ case TimerTypes of
+ #{TimerType := TimerRef} ->
+ cancel_timer(TimerRef),
+ {maps:remove(TimerRef, TimerRefs),
+ maps:remove(TimerType, TimerTypes)};
+ #{} ->
+ {TimerRefs,TimerTypes}
+ end.
+
+%%cancel_timer(undefined) ->
+%% ok;
cancel_timer(TRef) ->
case erlang:cancel_timer(TRef) of
false ->
diff --git a/lib/stdlib/src/math.erl b/lib/stdlib/src/math.erl
index 1db48cd0a2..3a3b384d8f 100644
--- a/lib/stdlib/src/math.erl
+++ b/lib/stdlib/src/math.erl
@@ -26,7 +26,8 @@
-export([sin/1, cos/1, tan/1, asin/1, acos/1, atan/1, atan2/2, sinh/1,
cosh/1, tanh/1, asinh/1, acosh/1, atanh/1, exp/1, log/1,
log2/1, log10/1, pow/2, sqrt/1, erf/1, erfc/1,
- ceil/1, floor/1]).
+ ceil/1, floor/1,
+ fmod/2]).
-spec acos(X) -> float() when
X :: number().
@@ -99,6 +100,11 @@ exp(_) ->
floor(_) ->
erlang:nif_error(undef).
+-spec fmod(X, Y) -> float() when
+ X :: number(), Y :: number().
+fmod(_, _) ->
+ erlang:nif_error(undef).
+
-spec log(X) -> float() when
X :: number().
log(_) ->
diff --git a/lib/stdlib/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl
index 3dc1848550..363705b0f4 100644
--- a/lib/stdlib/src/proc_lib.erl
+++ b/lib/stdlib/src/proc_lib.erl
@@ -232,7 +232,7 @@ init_p(Parent, Ancestors, Fun) when is_function(Fun) ->
Fun()
catch
Class:Reason ->
- exit_p(Class, Reason)
+ exit_p(Class, Reason, erlang:get_stacktrace())
end.
-spec init_p(pid(), [pid()], atom(), atom(), [term()]) -> term().
@@ -247,7 +247,7 @@ init_p_do_apply(M, F, A) ->
apply(M, F, A)
catch
Class:Reason ->
- exit_p(Class, Reason)
+ exit_p(Class, Reason, erlang:get_stacktrace())
end.
-spec wake_up(atom(), atom(), [term()]) -> term().
@@ -257,22 +257,29 @@ wake_up(M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
apply(M, F, A)
catch
Class:Reason ->
- exit_p(Class, Reason)
+ exit_p(Class, Reason, erlang:get_stacktrace())
end.
-exit_p(Class, Reason) ->
+exit_p(Class, Reason, Stacktrace) ->
case get('$initial_call') of
{M,F,A} when is_atom(M), is_atom(F), is_integer(A) ->
MFA = {M,F,make_dummy_args(A, [])},
crash_report(Class, Reason, MFA),
- exit(Reason);
+ erlang:raise(exit, exit_reason(Class, Reason, Stacktrace), Stacktrace);
_ ->
%% The process dictionary has been cleared or
%% possibly modified.
crash_report(Class, Reason, []),
- exit(Reason)
+ erlang:raise(exit, exit_reason(Class, Reason, Stacktrace), Stacktrace)
end.
+exit_reason(error, Reason, Stacktrace) ->
+ {Reason, Stacktrace};
+exit_reason(exit, Reason, _Stacktrace) ->
+ Reason;
+exit_reason(throw, Reason, Stacktrace) ->
+ {{nocatch, Reason}, Stacktrace}.
+
-spec start(Module, Function, Args) -> Ret when
Module :: module(),
Function :: atom(),
diff --git a/lib/stdlib/src/proplists.erl b/lib/stdlib/src/proplists.erl
index 5356467b19..21de8c45c1 100644
--- a/lib/stdlib/src/proplists.erl
+++ b/lib/stdlib/src/proplists.erl
@@ -1,8 +1,3 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -15,14 +10,8 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
-%% =====================================================================
-%% Support functions for property lists
-%%
-%% Copyright (C) 2000-2003 Richard Carlsson
-%% ---------------------------------------------------------------------
-%%
+%% @copyright 2000-2003 Richard Carlsson
+%% @author Richard Carlsson <[email protected]>
%% @doc Support functions for property lists.
%%
%% <p>Property lists are ordinary lists containing entries in the form
diff --git a/lib/stdlib/src/rand.erl b/lib/stdlib/src/rand.erl
index 93409d95df..1f457b9e0e 100644
--- a/lib/stdlib/src/rand.erl
+++ b/lib/stdlib/src/rand.erl
@@ -19,7 +19,7 @@
%%
%% =====================================================================
%% Multiple PRNG module for Erlang/OTP
-%% Copyright (c) 2015 Kenji Rikitake
+%% Copyright (c) 2015-2016 Kenji Rikitake
%% =====================================================================
-module(rand).
@@ -27,11 +27,14 @@
-export([seed_s/1, seed_s/2, seed/1, seed/2,
export_seed/0, export_seed_s/1,
uniform/0, uniform/1, uniform_s/1, uniform_s/2,
+ jump/0, jump/1,
normal/0, normal_s/1
]).
-compile({inline, [exs64_next/1, exsplus_next/1,
+ exsplus_jump/1,
exs1024_next/1, exs1024_calc/2,
+ exs1024_jump/1,
get_52/1, normal_kiwi/1]}).
-define(DEFAULT_ALG_HANDLER, exsplus).
@@ -48,7 +51,8 @@
max := integer(),
next := fun(),
uniform := fun(),
- uniform_n := fun()}.
+ uniform_n := fun(),
+ jump := fun()}.
%% Internal state
-opaque state() :: {alg_handler(), alg_seed()}.
@@ -79,9 +83,7 @@ export_seed_s({#{type:=Alg}, Seed}) -> {Alg, Seed}.
-spec seed(AlgOrExpState::alg() | export_state()) -> state().
seed(Alg) ->
- R = seed_s(Alg),
- _ = seed_put(R),
- R.
+ seed_put(seed_s(Alg)).
-spec seed_s(AlgOrExpState::alg() | export_state()) -> state().
seed_s(Alg) when is_atom(Alg) ->
@@ -97,9 +99,7 @@ seed_s({Alg0, Seed}) ->
-spec seed(Alg :: alg(), {integer(), integer(), integer()}) -> state().
seed(Alg0, S0) ->
- State = seed_s(Alg0, S0),
- _ = seed_put(State),
- State.
+ seed_put(seed_s(Alg0, S0)).
-spec seed_s(Alg :: alg(), {integer(), integer(), integer()}) -> state().
seed_s(Alg0, S0 = {_, _, _}) ->
@@ -150,6 +150,25 @@ uniform_s(N, State0 = {#{uniform:=Uniform}, _})
{F, State} = Uniform(State0),
{trunc(F * N) + 1, State}.
+%% jump/1: given a state, jump/1
+%% returns a new state which is equivalent to that
+%% after a large number of call defined for each algorithm.
+%% The large number is algorithm dependent.
+
+-spec jump(state()) -> NewS :: state().
+jump(State = {#{jump:=Jump}, _}) ->
+ Jump(State).
+
+%% jump/0: read the internal state and
+%% apply the jump function for the state as in jump/1
+%% and write back the new value to the internal state,
+%% then returns the new value.
+
+-spec jump() -> NewS :: state().
+
+jump() ->
+ seed_put(jump(seed_get())).
+
%% normal/0: returns a random float with standard normal distribution
%% updating the state in the process dictionary.
@@ -192,9 +211,10 @@ normal_s(State0) ->
-type uint64() :: 0..16#ffffffffffffffff.
-type uint58() :: 0..16#03ffffffffffffff.
--spec seed_put(state()) -> undefined | state().
+-spec seed_put(state()) -> state().
seed_put(Seed) ->
- put(?SEED_DICT, Seed).
+ put(?SEED_DICT, Seed),
+ Seed.
seed_get() ->
case get(?SEED_DICT) of
@@ -205,15 +225,18 @@ seed_get() ->
%% Setup alg record
mk_alg(exs64) ->
{#{type=>exs64, max=>?UINT64MASK, next=>fun exs64_next/1,
- uniform=>fun exs64_uniform/1, uniform_n=>fun exs64_uniform/2},
+ uniform=>fun exs64_uniform/1, uniform_n=>fun exs64_uniform/2,
+ jump=>fun exs64_jump/1},
fun exs64_seed/1};
mk_alg(exsplus) ->
{#{type=>exsplus, max=>?UINT58MASK, next=>fun exsplus_next/1,
- uniform=>fun exsplus_uniform/1, uniform_n=>fun exsplus_uniform/2},
+ uniform=>fun exsplus_uniform/1, uniform_n=>fun exsplus_uniform/2,
+ jump=>fun exsplus_jump/1},
fun exsplus_seed/1};
mk_alg(exs1024) ->
{#{type=>exs1024, max=>?UINT64MASK, next=>fun exs1024_next/1,
- uniform=>fun exs1024_uniform/1, uniform_n=>fun exs1024_uniform/2},
+ uniform=>fun exs1024_uniform/1, uniform_n=>fun exs1024_uniform/2,
+ jump=>fun exs1024_jump/1},
fun exs1024_seed/1}.
%% =====================================================================
@@ -246,6 +269,9 @@ exs64_uniform(Max, {Alg, R}) ->
{V, R1} = exs64_next(R),
{(V rem Max) + 1, {Alg, R1}}.
+exs64_jump(_) ->
+ erlang:error(not_implemented).
+
%% =====================================================================
%% exsplus PRNG: Xorshift116+
%% Algorithm by Sebastiano Vigna
@@ -283,6 +309,40 @@ exsplus_uniform(Max, {Alg, R}) ->
{V, R1} = exsplus_next(R),
{(V rem Max) + 1, {Alg, R1}}.
+%% This is the jump function for the exsplus generator, equivalent
+%% to 2^64 calls to next/1; it can be used to generate 2^52
+%% non-overlapping subsequences for parallel computations.
+%% Note: the jump function takes 116 times of the execution time of
+%% next/1.
+
+%% -define(JUMPCONST, 16#000d174a83e17de2302f8ea6bc32c797).
+%% split into 58-bit chunks
+%% and two iterative executions
+
+-define(JUMPCONST1, 16#02f8ea6bc32c797).
+-define(JUMPCONST2, 16#345d2a0f85f788c).
+-define(JUMPELEMLEN, 58).
+
+-dialyzer({no_improper_lists, exsplus_jump/1}).
+-spec exsplus_jump(state()) -> state().
+exsplus_jump({Alg, S}) ->
+ {S1, AS1} = exsplus_jump(S, [0|0], ?JUMPCONST1, ?JUMPELEMLEN),
+ {_, AS2} = exsplus_jump(S1, AS1, ?JUMPCONST2, ?JUMPELEMLEN),
+ {Alg, AS2}.
+
+-dialyzer({no_improper_lists, exsplus_jump/4}).
+exsplus_jump(S, AS, _, 0) ->
+ {S, AS};
+exsplus_jump(S, [AS0|AS1], J, N) ->
+ {_, NS} = exsplus_next(S),
+ case (J band 1) of
+ 1 ->
+ [S0|S1] = S,
+ exsplus_jump(NS, [(AS0 bxor S0)|(AS1 bxor S1)], J bsr 1, N-1);
+ 0 ->
+ exsplus_jump(NS, [AS0|AS1], J bsr 1, N-1)
+ end.
+
%% =====================================================================
%% exs1024 PRNG: Xorshift1024*
%% Algorithm by Sebastiano Vigna
@@ -340,6 +400,60 @@ exs1024_uniform(Max, {Alg, R}) ->
{V, R1} = exs1024_next(R),
{(V rem Max) + 1, {Alg, R1}}.
+%% This is the jump function for the exs1024 generator, equivalent
+%% to 2^512 calls to next(); it can be used to generate 2^512
+%% non-overlapping subsequences for parallel computations.
+%% Note: the jump function takes ~2000 times of the execution time of
+%% next/1.
+
+%% Jump constant here split into 58 bits for speed
+-define(JUMPCONSTHEAD, 16#00242f96eca9c41d).
+-define(JUMPCONSTTAIL,
+ [16#0196e1ddbe5a1561,
+ 16#0239f070b5837a3c,
+ 16#03f393cc68796cd2,
+ 16#0248316f404489af,
+ 16#039a30088bffbac2,
+ 16#02fea70dc2d9891f,
+ 16#032ae0d9644caec4,
+ 16#0313aac17d8efa43,
+ 16#02f132e055642626,
+ 16#01ee975283d71c93,
+ 16#00552321b06f5501,
+ 16#00c41d10a1e6a569,
+ 16#019158ecf8aa1e44,
+ 16#004e9fc949d0b5fc,
+ 16#0363da172811fdda,
+ 16#030e38c3b99181f2,
+ 16#0000000a118038fc]).
+-define(JUMPTOTALLEN, 1024).
+-define(RINGLEN, 16).
+
+-spec exs1024_jump(state()) -> state().
+
+exs1024_jump({Alg, {L, RL}}) ->
+ P = length(RL),
+ AS = exs1024_jump({L, RL},
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ ?JUMPCONSTTAIL, ?JUMPCONSTHEAD, ?JUMPELEMLEN, ?JUMPTOTALLEN),
+ {ASL, ASR} = lists:split(?RINGLEN - P, AS),
+ {Alg, {ASL, lists:reverse(ASR)}}.
+
+exs1024_jump(_, AS, _, _, _, 0) ->
+ AS;
+exs1024_jump(S, AS, [H|T], _, 0, TN) ->
+ exs1024_jump(S, AS, T, H, ?JUMPELEMLEN, TN);
+exs1024_jump({L, RL}, AS, JL, J, N, TN) ->
+ {_, NS} = exs1024_next({L, RL}),
+ case (J band 1) of
+ 1 ->
+ AS2 = lists:zipwith(fun(X, Y) -> X bxor Y end,
+ AS, L ++ lists:reverse(RL)),
+ exs1024_jump(NS, AS2, JL, J bsr 1, N-1, TN-1);
+ 0 ->
+ exs1024_jump(NS, AS, JL, J bsr 1, N-1, TN-1)
+ end.
+
%% =====================================================================
%% Ziggurat cont
%% =====================================================================
diff --git a/lib/stdlib/src/sets.erl b/lib/stdlib/src/sets.erl
index 3e70450320..c65a13b22e 100644
--- a/lib/stdlib/src/sets.erl
+++ b/lib/stdlib/src/sets.erl
@@ -128,14 +128,14 @@ is_element(E, S) ->
Set2 :: set(Element).
add_element(E, S0) ->
Slot = get_slot(S0, E),
- {S1,Ic} = on_bucket(fun (B0) -> add_bkt_el(E, B0, B0) end, S0, Slot),
- maybe_expand(S1, Ic).
-
--spec add_bkt_el(T, [T], [T]) -> {[T], 0 | 1}.
-add_bkt_el(E, [E|_], Bkt) -> {Bkt,0};
-add_bkt_el(E, [_|B], Bkt) ->
- add_bkt_el(E, B, Bkt);
-add_bkt_el(E, [], Bkt) -> {[E|Bkt],1}.
+ Bkt = get_bucket(S0, Slot),
+ case lists:member(E, Bkt) of
+ true ->
+ S0;
+ false ->
+ S1 = update_bucket(S0, Slot, [E | Bkt]),
+ maybe_expand(S1)
+ end.
%% del_element(Element, Set) -> Set.
%% Return Set but with Element removed.
@@ -144,15 +144,28 @@ add_bkt_el(E, [], Bkt) -> {[E|Bkt],1}.
Set2 :: set(Element).
del_element(E, S0) ->
Slot = get_slot(S0, E),
- {S1,Dc} = on_bucket(fun (B0) -> del_bkt_el(E, B0) end, S0, Slot),
- maybe_contract(S1, Dc).
+ Bkt = get_bucket(S0, Slot),
+ case lists:member(E, Bkt) of
+ false ->
+ S0;
+ true ->
+ S1 = update_bucket(S0, Slot, lists:delete(E, Bkt)),
+ maybe_contract(S1, 1)
+ end.
--spec del_bkt_el(T, [T]) -> {[T], 0 | 1}.
-del_bkt_el(E, [E|Bkt]) -> {Bkt,1};
-del_bkt_el(E, [Other|Bkt0]) ->
- {Bkt1,Dc} = del_bkt_el(E, Bkt0),
- {[Other|Bkt1],Dc};
-del_bkt_el(_, []) -> {[],0}.
+%% update_bucket(Set, Slot, NewBucket) -> UpdatedSet.
+%% Replace bucket in Slot by NewBucket
+-spec update_bucket(Set1, Slot, Bkt) -> Set2 when
+ Set1 :: set(Element),
+ Set2 :: set(Element),
+ Slot :: non_neg_integer(),
+ Bkt :: [Element].
+update_bucket(Set, Slot, NewBucket) ->
+ SegI = ((Slot-1) div ?seg_size) + 1,
+ BktI = ((Slot-1) rem ?seg_size) + 1,
+ Segs = Set#set.segs,
+ Seg = element(SegI, Segs),
+ Set#set{segs = setelement(SegI, Segs, setelement(BktI, Seg, NewBucket))}.
%% union(Set1, Set2) -> Set
%% Return the union of Set1 and Set2.
@@ -272,19 +285,6 @@ get_slot(T, Key) ->
-spec get_bucket(set(), non_neg_integer()) -> term().
get_bucket(T, Slot) -> get_bucket_s(T#set.segs, Slot).
-%% on_bucket(Fun, Hashdb, Slot) -> {NewHashDb,Result}.
-%% Apply Fun to the bucket in Slot and replace the returned bucket.
--spec on_bucket(fun((_) -> {[_], 0 | 1}), set(E), non_neg_integer()) ->
- {set(E), 0 | 1}.
-on_bucket(F, T, Slot) ->
- SegI = ((Slot-1) div ?seg_size) + 1,
- BktI = ((Slot-1) rem ?seg_size) + 1,
- Segs = T#set.segs,
- Seg = element(SegI, Segs),
- B0 = element(BktI, Seg),
- {B1, Res} = F(B0), %Op on the bucket.
- {T#set{segs = setelement(SegI, Segs, setelement(BktI, Seg, B1))},Res}.
-
%% fold_set(Fun, Acc, Dictionary) -> Dictionary.
%% filter_set(Fun, Dictionary) -> Dictionary.
@@ -349,8 +349,8 @@ put_bucket_s(Segs, Slot, Bkt) ->
Seg = setelement(BktI, element(SegI, Segs), Bkt),
setelement(SegI, Segs, Seg).
--spec maybe_expand(set(E), 0 | 1) -> set(E).
-maybe_expand(T0, Ic) when T0#set.size + Ic > T0#set.exp_size ->
+-spec maybe_expand(set(E)) -> set(E).
+maybe_expand(T0) when T0#set.size + 1 > T0#set.exp_size ->
T = maybe_expand_segs(T0), %Do we need more segments.
N = T#set.n + 1, %Next slot to expand into
Segs0 = T#set.segs,
@@ -360,12 +360,12 @@ maybe_expand(T0, Ic) when T0#set.size + Ic > T0#set.exp_size ->
{B1,B2} = rehash(B, Slot1, Slot2, T#set.maxn),
Segs1 = put_bucket_s(Segs0, Slot1, B1),
Segs2 = put_bucket_s(Segs1, Slot2, B2),
- T#set{size = T#set.size + Ic,
+ T#set{size = T#set.size + 1,
n = N,
exp_size = N * ?expand_load,
con_size = N * ?contract_load,
segs = Segs2};
-maybe_expand(T, Ic) -> T#set{size = T#set.size + Ic}.
+maybe_expand(T) -> T#set{size = T#set.size + 1}.
-spec maybe_expand_segs(set(E)) -> set(E).
maybe_expand_segs(T) when T#set.n =:= T#set.maxn ->
diff --git a/lib/stdlib/src/shell_default.erl b/lib/stdlib/src/shell_default.erl
index 6947cf181b..cd63ab28b5 100644
--- a/lib/stdlib/src/shell_default.erl
+++ b/lib/stdlib/src/shell_default.erl
@@ -23,7 +23,7 @@
-module(shell_default).
--export([help/0,lc/1,c/1,c/2,nc/1,nl/1,l/1,i/0,pid/3,i/3,m/0,m/1,
+-export([help/0,lc/1,c/1,c/2,nc/1,nl/1,l/1,i/0,pid/3,i/3,m/0,m/1,lm/0,mm/0,
memory/0,memory/1,uptime/0,
erlangrc/1,bi/1, regs/0, flush/0,pwd/0,ls/0,ls/1,cd/1,
y/1, y/2,
@@ -83,6 +83,8 @@ ls() -> c:ls().
ls(S) -> c:ls(S).
m() -> c:m().
m(Mod) -> c:m(Mod).
+lm() -> c:lm().
+mm() -> c:mm().
memory() -> c:memory().
memory(Type) -> c:memory(Type).
nc(X) -> c:nc(X).
diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src
index 8cf46482dd..82ab484ea6 100644
--- a/lib/stdlib/src/stdlib.app.src
+++ b/lib/stdlib/src/stdlib.app.src
@@ -31,7 +31,6 @@
dets_server,
dets_sup,
dets_utils,
- dets_v8,
dets_v9,
dict,
digraph,
diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src
index e917b7ea1f..979161fef7 100644
--- a/lib/stdlib/src/stdlib.appup.src
+++ b/lib/stdlib/src/stdlib.appup.src
@@ -18,9 +18,7 @@
%% %CopyrightEnd%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"3\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-18.*
+ [{<<"3\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}], % OTP-19.*
%% Down to - max one major revision back
- [{<<"3\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-19.*
- {<<"2\\.[5-8](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-18.*
+ [{<<"3\\.[0-1](\\.[0-9]+)*">>,[restart_new_emulator]}] % OTP-19.*
}.
diff --git a/lib/stdlib/test/base64_SUITE.erl b/lib/stdlib/test/base64_SUITE.erl
index 9176a3664a..d0abe5c961 100644
--- a/lib/stdlib/test/base64_SUITE.erl
+++ b/lib/stdlib/test/base64_SUITE.erl
@@ -23,9 +23,7 @@
-include_lib("common_test/include/ct.hrl").
%% Test server specific exports
--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([all/0, suite/0, groups/0, group/1]).
%% Test cases must be exported.
-export([base64_encode/1, base64_decode/1, base64_otp_5635/1,
@@ -33,41 +31,26 @@
mime_decode_to_string/1,
roundtrip_1/1, roundtrip_2/1, roundtrip_3/1, roundtrip_4/1]).
-init_per_testcase(_, Config) ->
- Config.
-
-end_per_testcase(_, _Config) ->
- ok.
-
%%-------------------------------------------------------------------------
%% Test cases starts here.
%%-------------------------------------------------------------------------
+
suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap,{minutes,4}}].
-all() ->
+all() ->
[base64_encode, base64_decode, base64_otp_5635,
base64_otp_6279, big, illegal, mime_decode, mime_decode_to_string,
{group, roundtrip}].
-groups() ->
+groups() ->
[{roundtrip, [parallel],
[roundtrip_1, roundtrip_2, roundtrip_3, roundtrip_4]}].
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
+group(roundtrip) ->
+ %% valgrind needs a lot of time
+ [{timetrap,{minutes,10}}].
%%-------------------------------------------------------------------------
%% Test base64:encode/1.
@@ -78,9 +61,9 @@ base64_encode(Config) when is_list(Config) ->
%% One pad
<<"SGVsbG8gV29ybGQ=">> = base64:encode(<<"Hello World">>),
%% No pad
- "QWxhZGRpbjpvcGVuIHNlc2Ft" =
+ "QWxhZGRpbjpvcGVuIHNlc2Ft" =
base64:encode_to_string("Aladdin:open sesam"),
-
+
"MDEyMzQ1Njc4OSFAIzBeJiooKTs6PD4sLiBbXXt9" =
base64:encode_to_string(<<"0123456789!@#0^&*();:<>,. []{}">>),
ok.
@@ -93,7 +76,7 @@ base64_decode(Config) when is_list(Config) ->
%% One pad
<<"Hello World">> = base64:decode(<<"SGVsbG8gV29ybGQ=">>),
%% No pad
- <<"Aladdin:open sesam">> =
+ <<"Aladdin:open sesam">> =
base64:decode("QWxhZGRpbjpvcGVuIHNlc2Ft"),
Alphabet = list_to_binary(lists:seq(0, 255)),
@@ -208,7 +191,7 @@ mime_decode_to_string(Config) when is_list(Config) ->
%% One pad to ignore, followed by more text
"Hello World!!" = base64:mime_decode_to_string(<<"SGVsb)(G8gV29ybGQ=h IQ= =">>),
%% No pad
- "Aladdin:open sesam" =
+ "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.
@@ -314,7 +297,7 @@ interleaved_ws_roundtrip_1([], Base64List, Bin, List) ->
random_byte_list(0, Acc) ->
Acc;
-random_byte_list(N, Acc) ->
+random_byte_list(N, Acc) ->
random_byte_list(N-1, [rand:uniform(255)|Acc]).
make_big_binary(N) ->
diff --git a/lib/stdlib/test/dets_SUITE.erl b/lib/stdlib/test/dets_SUITE.erl
index 8948f496c4..aa31fdde5a 100644
--- a/lib/stdlib/test/dets_SUITE.erl
+++ b/lib/stdlib/test/dets_SUITE.erl
@@ -35,26 +35,18 @@
-endif.
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2,
- 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,
- bag_next_v8/1, bag_next_v9/1, oldbugs_v8/1, oldbugs_v9/1,
- unsafe_assumptions/1, truncated_segment_array_v8/1,
- truncated_segment_array_v9/1, open_file_v8/1, open_file_v9/1,
- init_table_v8/1, init_table_v9/1, repair_v8/1, repair_v9/1,
- hash_v8b_v8c/1, phash/1, fold_v8/1, fold_v9/1, fixtable_v8/1,
- fixtable_v9/1, match_v8/1, match_v9/1, select_v8/1,
- select_v9/1, update_counter/1, badarg/1, cache_sets_v8/1,
- cache_sets_v9/1, cache_bags_v8/1, cache_bags_v9/1,
- cache_duplicate_bags_v8/1, cache_duplicate_bags_v9/1,
+ init_per_group/2,end_per_group/2, newly_started/1, basic/1,
+ open/1, sets/1, bags/1, duplicate_bags/1, access/1, dirty_mark/1,
+ dirty_mark2/1, bag_next/1, oldbugs/1,
+ truncated_segment_array/1, open_file/1, init_table/1, repair/1,
+ phash/1, fold/1, fixtable/1, match/1, select/1, update_counter/1,
+ badarg/1, cache_sets/1, cache_bags/1, cache_duplicate_bags/1,
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_8856/1, otp_8898/1, otp_8899/1, otp_8903/1,
otp_8923/1, otp_9282/1, otp_11245/1, otp_11709/1, otp_13229/1,
- otp_13260/1]).
+ otp_13260/1, otp_13830/1]).
-export([dets_dirty_loop/0]).
@@ -73,8 +65,7 @@
-define(DETS_SERVER, dets).
-%% HEADSZ taken from dets_v8.erl and dets_v9.erl.
--define(HEADSZ_v8, 40).
+%% HEADSZ taken from dets_v9.erl.
-define(HEADSZ_v9, (56+28*4+16)).
-define(NO_KEYS_POS_v9, 36).
-define(CLOSED_PROPERLY_POS, 8).
@@ -94,24 +85,16 @@ suite() ->
all() ->
[
- 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,
+ basic, open, sets, bags, duplicate_bags, newly_started, open_file,
+ init_table, repair, access, oldbugs,
+ truncated_segment_array, dirty_mark, dirty_mark2, bag_next,
+ phash, fold, fixtable, match, select, update_counter, badarg,
+ cache_sets, cache_bags, cache_duplicate_bags, 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, otp_9282, otp_11245, otp_11709,
- otp_13229, otp_13260
+ otp_13229, otp_13260, otp_13830
].
groups() ->
@@ -137,20 +120,12 @@ newly_started(Config) when is_list(Config) ->
test_server:stop_node(Node),
ok.
-%% Basic test case.
-basic_v8(Config) when is_list(Config) ->
- basic(Config, 8).
-
-%% Basic test case.
-basic_v9(Config) when is_list(Config) ->
- basic(Config, 9).
-
-basic(Config, Version) ->
+basic(Config) when is_list(Config) ->
Tab = dets_basic_test,
FName = filename(Tab, Config),
P0 = pps(),
- {ok, _} = dets:open_file(Tab,[{file, FName},{version,Version}]),
+ {ok, _} = dets:open_file(Tab,[{file, FName}]),
ok = dets:insert(Tab,{mazda,japan}),
ok = dets:insert(Tab,{toyota,japan}),
ok = dets:insert(Tab,{suzuki,japan}),
@@ -174,13 +149,7 @@ basic(Config, Version) ->
ok.
-open_v8(Config) when is_list(Config) ->
- open(Config, 8).
-
-open_v9(Config) when is_list(Config) ->
- open(Config, 9).
-
-open(Config, Version) ->
+open(Config) when is_list(Config) ->
%% Running this test twice means that the Dets server is restarted
%% twice. dets_sup specifies a maximum of 4 restarts in an hour.
%% If this becomes a problem, one should consider running this
@@ -194,14 +163,14 @@ open(Config, Version) ->
Data = make_data(1),
P0 = pps(),
- Tabs = open_files(1, All, Version),
+ Tabs = open_files(1, All),
initialize(Tabs, Data),
check(Tabs, Data),
foreach(fun(Tab) -> ok = dets:close(Tab) end, Tabs),
%% Now reopen the files
?format("Reopening closed files \n", []),
- Tabs = open_files(1, All, Version),
+ Tabs = open_files(1, All),
?format("Checking contents of reopened files \n", []),
check(Tabs, Data),
%% crash the dets server
@@ -216,7 +185,7 @@ open(Config, Version) ->
%% Now reopen the files again
?format("Reopening crashed files \n", []),
- open_files(1, All, Version),
+ open_files(1, All),
?format("Checking contents of repaired files \n", []),
check(Tabs, Data),
@@ -266,20 +235,13 @@ bad(_Tab, _Item) ->
exit(badtab).
%% Perform traversal and match testing on set type dets tables.
-sets_v8(Config) when is_list(Config) ->
- sets(Config, 8).
-
-%% Perform traversal and match testing on set type dets tables.
-sets_v9(Config) when is_list(Config) ->
- sets(Config, 9).
-
-sets(Config, Version) ->
+sets(Config) when is_list(Config) ->
{Sets, _, _} = args(Config),
Data = make_data(1),
delete_files(Sets),
P0 = pps(),
- Tabs = open_files(1, Sets, Version),
+ Tabs = open_files(1, Sets),
Bigger = [{17,q,w,w}, {48,q,w,w,w,w,w,w}], % 48 requires a bigger buddy
initialize(Tabs, Data++Bigger++Data), % overwrite
Len = length(Data),
@@ -302,19 +264,12 @@ sets(Config, Version) ->
ok.
%% Perform traversal and match testing on bag type dets tables.
-bags_v8(Config) when is_list(Config) ->
- bags(Config, 8).
-
-%% Perform traversal and match testing on bag type dets tables.
-bags_v9(Config) when is_list(Config) ->
- bags(Config, 9).
-
-bags(Config, Version) ->
+bags(Config) when is_list(Config) ->
{_, Bags, _} = args(Config),
Data = make_data(1, bag), %% gives twice as many objects
delete_files(Bags),
P0 = pps(),
- Tabs = open_files(1, Bags, Version),
+ Tabs = open_files(1, Bags),
initialize(Tabs, Data++Data),
Len = length(Data),
foreach(fun(Tab) -> trav_test(Data, Len, Tab) end, Tabs),
@@ -336,19 +291,12 @@ bags(Config, Version) ->
%% Perform traversal and match testing on duplicate_bag type dets tables.
-duplicate_bags_v8(Config) when is_list(Config) ->
- duplicate_bags(Config, 8).
-
-%% Perform traversal and match testing on duplicate_bag type dets tables.
-duplicate_bags_v9(Config) when is_list(Config) ->
- duplicate_bags(Config, 9).
-
-duplicate_bags(Config, Version) when is_list(Config) ->
+duplicate_bags(Config) when is_list(Config) ->
{_, _, Dups} = args(Config),
Data = make_data(1, duplicate_bag), %% gives twice as many objects
delete_files(Dups),
P0 = pps(),
- Tabs = open_files(1, Dups, Version),
+ Tabs = open_files(1, Dups),
initialize(Tabs, Data),
Len = length(Data),
foreach(fun(Tab) -> trav_test(Data, Len, Tab) end, Tabs),
@@ -369,13 +317,7 @@ duplicate_bags(Config, Version) when is_list(Config) ->
ok.
-access_v8(Config) when is_list(Config) ->
- access(Config, 8).
-
-access_v9(Config) when is_list(Config) ->
- access(Config, 9).
-
-access(Config, Version) ->
+access(Config) when is_list(Config) ->
Args_acc = [[{ram_file, true}, {access, read}],
[{access, read}]],
Args = [[{ram_file, true}],
@@ -388,9 +330,9 @@ access(Config, Version) ->
P0 = pps(),
{error, {file_error,_,enoent}} = dets:open_file('1', hd(Args_acc_1)),
- Tabs = open_files(1, Args_1, Version),
+ Tabs = open_files(1, Args_1),
close_all(Tabs),
- Tabs = open_files(1, Args_acc_1, Version),
+ Tabs = open_files(1, Args_acc_1),
foreach(fun(Tab) ->
{error, {access_mode,_}} = dets:insert(Tab, {1,2}),
@@ -522,16 +464,12 @@ dets_dirty_loop() ->
%% Check that bags and next work as expected.
-bag_next_v8(Config) when is_list(Config) ->
- bag_next(Config, 8).
-
-%% Check that bags and next work as expected.
-bag_next_v9(Config) when is_list(Config) ->
+bag_next(Config) when is_list(Config) ->
Tab = dets_bag_next_test,
FName = filename(Tab, Config),
%% first and next crash upon error
- dets:open_file(Tab,[{file, FName}, {type, bag},{version,9}]),
+ dets:open_file(Tab,[{file, FName}, {type, bag}]),
ok = dets:insert(Tab, [{1,1},{2,2},{3,3},{4,4}]),
FirstKey = dets:first(Tab),
NextKey = dets:next(Tab, FirstKey),
@@ -548,13 +486,8 @@ bag_next_v9(Config) when is_list(Config) ->
dets:close(Tab),
file:delete(FName),
- bag_next(Config, 9).
-
-bag_next(Config, Version) ->
- Tab = dets_bag_next_test,
- FName = filename(Tab, Config),
P0 = pps(),
- dets:open_file(Tab,[{file, FName}, {type, bag},{version,Version}]),
+ dets:open_file(Tab,[{file, FName}, {type, bag}]),
dets:insert(Tab,{698,hopp}),
dets:insert(Tab,{186,hopp}),
dets:insert(Tab,{hej,hopp}),
@@ -578,17 +511,10 @@ bag_next(Config, Version) ->
check_pps(P0),
ok.
-oldbugs_v8(Config) when is_list(Config) ->
- oldbugs(Config, 8).
-
-oldbugs_v9(Config) when is_list(Config) ->
- oldbugs(Config, 9).
-
-oldbugs(Config, Version) ->
+oldbugs(Config) when is_list(Config) ->
FName = filename(dets_suite_oldbugs_test, Config),
P0 = pps(),
- {ok, ob} = dets:open_file(ob, [{version, Version},
- {type, bag}, {file, FName}]),
+ {ok, ob} = dets:open_file(ob, [{type, bag}, {file, FName}]),
ok = dets:insert(ob, {1, 2}),
ok = dets:insert(ob, {1,3}),
ok = dets:insert(ob, {1, 2}),
@@ -598,56 +524,19 @@ oldbugs(Config, Version) ->
check_pps(P0),
ok.
-%% Test that shrinking an object and then expanding it works.
-unsafe_assumptions(Config) when is_list(Config) ->
- FName = filename(dets_suite_unsafe_assumptions_test, Config),
- file:delete(FName),
- P0 = pps(),
- {ok, a} = dets:open_file(a, [{version,8},{file, FName}]),
- O0 = {2,false},
- O1 = {1, false},
- O2 = {1, true},
- O3 = {1, duplicate(20,false)},
- O4 = {1, duplicate(25,false)}, % same 2-log as O3
- ok = dets:insert(a, O1),
- ok = dets:insert(a, O0),
- true = [O1,O0] =:= sort(get_all_objects(a)),
- true = [O1,O0] =:= sort(get_all_objects_fast(a)),
- ok = dets:insert(a, O2),
- true = [O2,O0] =:= sort(get_all_objects(a)),
- true = [O2,O0] =:= sort(get_all_objects_fast(a)),
- ok = dets:insert(a, O3),
- true = [O3,O0] =:= sort(get_all_objects(a)),
- true = [O3,O0] =:= sort(get_all_objects_fast(a)),
- ok = dets:insert(a, O4),
- true = [O4,O0] =:= sort(get_all_objects(a)),
- true = [O4,O0] =:= sort(get_all_objects_fast(a)),
- ok = dets:close(a),
- file:delete(FName),
- check_pps(P0),
- ok.
-
-%% Test that a file where the segment array has been truncated
-%% is possible to repair.
-truncated_segment_array_v8(Config) when is_list(Config) ->
- trunc_seg_array(Config, 8).
-
%% Test that a file where the segment array has been truncated
%% is possible to repair.
-truncated_segment_array_v9(Config) when is_list(Config) ->
- trunc_seg_array(Config, 9).
-
-trunc_seg_array(Config, V) ->
+truncated_segment_array(Config) when is_list(Config) ->
TabRef = dets_suite_truncated_segment_array_test,
Fname = filename(TabRef, Config),
%% Create file that needs to be repaired
file:delete(Fname),
P0 = pps(),
- {ok, TabRef} = dets:open_file(TabRef, [{file, Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file, Fname}]),
ok = dets:close(TabRef),
%% Truncate the file
- HeadSize = headsz(V),
+ HeadSize = headsz(),
truncate(Fname, HeadSize + 10),
%% Open the truncated file
@@ -660,19 +549,13 @@ trunc_seg_array(Config, V) ->
ok.
%% Test open_file/1.
-open_file_v8(Config) when is_list(Config) ->
- open_1(Config, 8).
-
-%% Test open_file/1.
-open_file_v9(Config) when is_list(Config) ->
+open_file(Config) when is_list(Config) ->
T = open_v9,
Fname = filename(T, Config),
- {ok, _} = dets:open_file(T, [{file,Fname},{version,9}]),
- 9 = dets:info(T, version),
+ {ok, _} = dets:open_file(T, [{file,Fname}]),
+ 9 = dets:info(T, version), % Backwards compatibility.
true = [self()] =:= dets:info(T, users),
- {ok, _} = dets:open_file(T, [{file,Fname},{version,9}]),
- {error,incompatible_arguments} =
- dets:open_file(T, [{file,Fname},{version,8}]),
+ {ok, _} = dets:open_file(T, [{file,Fname}]),
true = [self(),self()] =:= dets:info(T, users),
ok = dets:close(T),
true = [self()] =:= dets:info(T, users),
@@ -680,9 +563,9 @@ open_file_v9(Config) when is_list(Config) ->
undefined = ets:info(T, users),
file:delete(Fname),
- open_1(Config, 9).
+ open_1(Config).
-open_1(Config, V) ->
+open_1(Config) ->
TabRef = open_file_1_test,
Fname = filename(TabRef, Config),
file:delete(Fname),
@@ -694,8 +577,8 @@ open_1(Config, V) ->
{error,{not_a_dets_file,Fname}} = dets:open_file(Fname),
file:delete(Fname),
- HeadSize = headsz(V),
- {ok, TabRef} = dets:open_file(TabRef, [{file, Fname},{version,V}]),
+ HeadSize = headsz(),
+ {ok, TabRef} = dets:open_file(TabRef, [{file, Fname}]),
ok = dets:close(TabRef),
truncate(Fname, HeadSize + 10),
true = dets:is_dets_file(Fname),
@@ -705,7 +588,7 @@ open_1(Config, V) ->
file:delete(Fname),
%% truncated file header, invalid type
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = ins(TabRef, 3000),
ok = dets:close(TabRef),
TypePos = 12,
@@ -714,7 +597,7 @@ open_1(Config, V) ->
truncate(Fname, HeadSize - 10),
{error,{not_a_dets_file,Fname}} = dets:open_file(Fname),
{error,{not_a_dets_file,Fname}} =
- dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ dets:open_file(TabRef, [{file,Fname}]),
file:delete(Fname),
{error,{file_error,{foo,bar},_}} = dets:is_dets_file({foo,bar}),
@@ -722,35 +605,30 @@ open_1(Config, V) ->
ok.
%% Test initialize_table/2 and from_ets/2.
-init_table_v8(Config) when is_list(Config) ->
- init_table(Config, 8).
-
-%% Test initialize_table/2 and from_ets/2.
-init_table_v9(Config) when is_list(Config) ->
+init_table(Config) when is_list(Config) ->
%% Objects are returned in "time order".
T = init_table_v9,
Fname = filename(T, Config),
file:delete(Fname),
L = [{1,a},{2,b},{1,c},{2,c},{1,c},{2,a},{1,b}],
Input = init([L]),
- {ok, _} = dets:open_file(T, [{file,Fname},{version,9},
- {type,duplicate_bag}]),
+ {ok, _} = dets:open_file(T, [{file,Fname},{type,duplicate_bag}]),
ok = dets:init_table(T, Input),
[{1,a},{1,c},{1,c},{1,b}] = dets:lookup(T, 1),
[{2,b},{2,c},{2,a}] = dets:lookup(T, 2),
ok = dets:close(T),
file:delete(Fname),
- init_table(Config, 9),
+ init_table_1(Config),
fast_init_table(Config).
-init_table(Config, V) ->
+init_table_1(Config) ->
TabRef = init_table_test,
Fname = filename(TabRef, Config),
file:delete(Fname),
P0 = pps(),
- Args = [{file,Fname},{version,V},{auto_save,120000}],
+ Args = [{file,Fname},{auto_save,120000}],
{ok, _} = dets:open_file(TabRef, Args),
{'EXIT', _} =
(catch dets:init_table(TabRef, fun(foo) -> bar end)),
@@ -800,13 +678,13 @@ init_table(Config, V) ->
file:delete(Fname),
L1 = [[{1,a},{2,b}],[],[{3,c}],[{4,d}],[]],
- bulk_init(L1, set, 4, Config, V),
+ bulk_init(L1, set, 4, Config),
L2 = [[{1,a},{2,b}],[],[{2,q},{3,c}],[{4,d}],[{4,e},{2,q}]],
- bulk_init(L2, set, 4, Config, V),
- bulk_init(L2, bag, 6, Config, V),
- bulk_init(L2, duplicate_bag, 7, Config, V),
- bulk_init(L1, set, 4, 512, Config, V),
- bulk_init([], set, 0, 10000, Config, V),
+ bulk_init(L2, set, 4, Config),
+ bulk_init(L2, bag, 6, Config),
+ bulk_init(L2, duplicate_bag, 7, Config),
+ bulk_init(L1, set, 4, 512, Config),
+ bulk_init([], set, 0, 10000, Config),
file:delete(Fname),
%% Initiate a file that contains a lot of objects.
@@ -834,16 +712,16 @@ init_table(Config, V) ->
check_pps(P0),
ok.
-bulk_init(Ls, Type, N, Config, V) ->
- bulk_init(Ls, Type, N, 256, Config, V).
+bulk_init(Ls, Type, N, Config) ->
+ bulk_init(Ls, Type, N, 256, Config).
-bulk_init(Ls, Type, N, Est, Config, V) ->
+bulk_init(Ls, Type, N, Est, Config) ->
T = init_table_test,
Fname = filename(T, Config),
file:delete(Fname),
Input = init(Ls),
Args = [{ram_file,false}, {type,Type},{keypos,1},{file,Fname},
- {estimated_no_objects, Est},{version,V}],
+ {estimated_no_objects, Est}],
{ok, T} = dets:open_file(T, Args),
ok = dets:init_table(T, Input),
All = sort(get_all_objects(T)),
@@ -882,18 +760,17 @@ init_fun(I, N) ->
end.
fast_init_table(Config) ->
- V = 9,
TabRef = init_table_test,
Fname = filename(TabRef, Config),
file:delete(Fname),
P0 = pps(),
- Args = [{file,Fname},{version,V},{auto_save,120000}],
+ Args = [{file,Fname},{auto_save,120000}],
Source = init_table_test_source,
SourceFname = filename(Source, Config),
file:delete(SourceFname),
- SourceArgs = [{file,SourceFname},{version,V},{auto_save,120000}],
+ SourceArgs = [{file,SourceFname},{auto_save,120000}],
{ok, Source} = dets:open_file(Source, SourceArgs),
@@ -1015,13 +892,13 @@ fast_init_table(Config) ->
file:delete(SourceFname),
L1 = [{1,a},{2,b},{3,c},{4,d}],
- fast_bulk_init(L1, set, 4, 4, Config, V),
+ fast_bulk_init(L1, set, 4, 4, Config),
L2 = [{1,a},{2,b},{2,q},{3,c},{4,d},{4,e},{2,q}],
- fast_bulk_init(L2, set, 4, 4, Config, V),
- fast_bulk_init(L2, bag, 6, 4, Config, V),
- fast_bulk_init(L2, duplicate_bag, 7, 4, Config, V),
- fast_bulk_init(L1, set, 4, 4, 512, Config, V),
- fast_bulk_init([], set, 0, 0, 10000, Config, V),
+ fast_bulk_init(L2, set, 4, 4, Config),
+ fast_bulk_init(L2, bag, 6, 4, Config),
+ fast_bulk_init(L2, duplicate_bag, 7, 4, Config),
+ fast_bulk_init(L1, set, 4, 4, 512, Config),
+ fast_bulk_init([], set, 0, 0, 10000, Config),
file:delete(Fname),
%% Initiate a file that contains a lot of objects.
@@ -1112,16 +989,16 @@ fast_init_table(Config) ->
check_pps(P0),
ok.
-fast_bulk_init(L, Type, N, NoKeys, Config, V) ->
- fast_bulk_init(L, Type, N, NoKeys, 256, Config, V).
+fast_bulk_init(L, Type, N, NoKeys, Config) ->
+ fast_bulk_init(L, Type, N, NoKeys, 256, Config).
-fast_bulk_init(L, Type, N, NoKeys, Est, Config, V) ->
+fast_bulk_init(L, Type, N, NoKeys, Est, Config) ->
T = init_table_test,
Fname = filename(T, Config),
file:delete(Fname),
Args0 = [{ram_file,false}, {type,Type},{keypos,1},
- {estimated_no_objects, Est},{version,V}],
+ {estimated_no_objects, Est}],
Args = [{file,Fname} | Args0],
S = init_table_test_source,
SFname = filename(S, Config),
@@ -1189,35 +1066,7 @@ items(I, N, C, L) ->
items(I+1, N, C-1, [{I, item(I)} | L]).
%% Test open_file and repair.
-repair_v8(Config) when is_list(Config) ->
- repair(Config, 8).
-
-%% Test open_file and repair.
-repair_v9(Config) when is_list(Config) ->
- %% Convert from format 9 to format 8.
- T = convert_98,
- Fname = filename(T, Config),
- file:delete(Fname),
- {ok, _} = dets:open_file(T, [{file,Fname},{version,9},
- {type,duplicate_bag}]),
- 9 = dets:info(T, version),
- true = is_binary(dets:info(T, bchunk_format)),
- ok = dets:insert(T, [{1,a},{2,b},{1,c},{2,c},{1,c},{2,a},{1,b}]),
- dets:close(T),
- {error, {version_mismatch, _}} =
- dets:open_file(T, [{file,Fname},{version,8},{type,duplicate_bag}]),
- {ok, _} = dets:open_file(T, [{file,Fname},{version,8},
- {type,duplicate_bag},{repair,force}]),
- 8 = dets:info(T, version),
- true = undefined =:= dets:info(T, bchunk_format),
- [{1,a},{1,b},{1,c},{1,c}] = sort(dets:lookup(T, 1)),
- [{2,a},{2,b},{2,c}] = sort(dets:lookup(T, 2)),
- 7 = dets:info(T, no_objects),
- no_keys_test(T),
- _ = histogram(T, silent),
- ok = dets:close(T),
- file:delete(Fname),
-
+repair(Config) when is_list(Config) ->
%% The short lived format 9(a).
%% Not very throughly tested here.
A9 = a9,
@@ -1238,13 +1087,13 @@ repair_v9(Config) when is_list(Config) ->
ok = dets:close(A9),
file:delete(Version9aT),
- repair(Config, 9).
+ repair_1(Config).
-repair(Config, V) ->
+repair_1(Config) ->
TabRef = repair_test,
Fname = filename(TabRef, Config),
file:delete(Fname),
- HeadSize = headsz(V),
+ HeadSize = headsz(),
P0 = pps(),
{'EXIT', {badarg, _}} =
@@ -1255,7 +1104,7 @@ repair(Config, V) ->
dets:open_file(TabRef, [{file, Fname}, {access, read}]),
%% compacting, and some kind of test that free lists are saved OK on file
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
0 = dets:info(TabRef, size),
ok = ins(TabRef, 30000),
ok = del(TabRef, 30000, 3),
@@ -1268,38 +1117,20 @@ repair(Config, V) ->
20000 = count_objects_quite_fast(Ref3), % actually a test of match
no_keys_test(Ref3),
ok = dets:close(Ref3),
- if
- V =:= 8 ->
- {ok, TabRef} = dets:open_file(TabRef,
- [{file, Fname},{version,V},{access,read}]),
- ok = dets:close(TabRef),
- io:format("Expect compacting repair:~n"),
- {ok, TabRef} = dets:open_file(TabRef,
- [{file, Fname},{version,V}]),
- 20000 = dets:info(TabRef, size),
- _ = histogram(TabRef, silent),
- ok = dets:close(TabRef);
- true ->
- ok
- end,
{error,{keypos_mismatch,Fname}} =
dets:open_file(TabRef, [{file, Fname},{keypos,17}]),
{error,{type_mismatch,Fname}} =
dets:open_file(TabRef, [{file, Fname},{type,duplicate_bag}]),
%% make one of the temporary files unwritable
- TmpFile = if
- V =:= 8 ->
- Fname ++ ".TMP.10000";
- true -> Fname ++ ".TMP.1"
- end,
+ TmpFile = Fname ++ ".TMP.1",
file:delete(TmpFile),
{ok, TmpFd} = file:open(TmpFile, [read,write]),
ok = file:close(TmpFd),
unwritable(TmpFile),
- {error,{file_error,TmpFile,eacces}} = dets:fsck(Fname, V),
+ {error,{file_error,TmpFile,eacces}} = dets:fsck(Fname),
{ok, _} = dets:open_file(TabRef,
- [{repair,false},{file, Fname},{version,V}]),
+ [{repair,false},{file, Fname}]),
20000 = length(get_all_objects(TabRef)),
_ = histogram(TabRef, silent),
20000 = length(get_all_objects_fast(TabRef)),
@@ -1318,68 +1149,15 @@ repair(Config, V) ->
file:delete(Fname),
%% truncated file header
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = ins(TabRef, 100),
ok = dets:close(TabRef),
file:delete(Fname),
- %% version bump (v8)
- Version7S = filename:join(?datadir(Config), "version_r2d.dets"),
- Version7T = filename('v2.dets', Config),
- {ok, _} = file:copy(Version7S, Version7T),
- {error,{version_bump, Version7T}} = dets:open_file(Version7T),
- {error,{version_bump, Version7T}} =
- dets:open_file(Version7T, [{file,Version7T},{repair,false}]),
- {error,{version_bump, Version7T}} =
- dets:open_file(Version7T, [{file, Version7T}, {access, read}]),
- io:format("Expect upgrade:~n"),
- {ok, _} = dets:open_file(Version7T,
- [{file, Version7T},{version, V}]),
- [{1,a},{2,b}] = sort(get_all_objects(Version7T)),
- [{1,a},{2,b}] = sort(get_all_objects_fast(Version7T)),
- Phash = if
- V =:= 8 -> phash;
- true -> phash2
- end,
- Phash = dets:info(Version7T, hash),
- _ = histogram(Version7T, silent),
- ok = dets:close(Version7T),
- {ok, _} = dets:open_file(Version7T, [{file, Version7T}]),
- Phash = dets:info(Version7T, hash),
- ok = dets:close(Version7T),
- file:delete(Version7T),
-
- %% converting free lists
- Version8aS = filename:join(?datadir(Config), "version_r3b02.dets"),
- Version8aT = filename('v3.dets', Config),
- {ok, _} = file:copy(Version8aS, Version8aT),
- %% min_no_slots and max_no_slots are ignored - no repair is taking place
- {ok, _} = dets:open_file(version_8a,
- [{file, Version8aT},{min_no_slots,1000},
- {max_no_slots,100000}]),
- [{1,b},{2,a},{a,1},{b,2}] = sort(get_all_objects(version_8a)),
- [{1,b},{2,a},{a,1},{b,2}] = sort(get_all_objects_fast(version_8a)),
- ok = ins(version_8a, 1000),
- 1002 = dets:info(version_8a, size),
- no_keys_test(version_8a),
- All8a = sort(get_all_objects(version_8a)),
- 1002 = length(All8a),
- FAll8a = sort(get_all_objects_fast(version_8a)),
- true = sort(All8a) =:= sort(FAll8a),
- ok = del(version_8a, 300, 3),
- 902 = dets:info(version_8a, size),
- no_keys_test(version_8a),
- All8a2 = sort(get_all_objects(version_8a)),
- 902 = length(All8a2),
- FAll8a2 = sort(get_all_objects_fast(version_8a)),
- true = sort(All8a2) =:= sort(FAll8a2),
- _ = histogram(version_8a, silent),
- ok = dets:close(version_8a),
- file:delete(Version8aT),
-
+ %% FIXME.
%% will fail unless the slots are properly sorted when repairing (v8)
BArgs = [{file, Fname},{type,duplicate_bag},
- {delayed_write,{3000,10000}},{version,V}],
+ {delayed_write,{3000,10000}}],
{ok, TabRef} = dets:open_file(TabRef, BArgs),
Seq = seq(1, 500),
Small = map(fun(X) -> {X,X} end, Seq),
@@ -1393,18 +1171,14 @@ repair(Config, V) ->
io:format("Expect forced repair:~n"),
{ok, _} =
dets:open_file(TabRef, [{repair,force},{min_no_slots,2000} | BArgs]),
- if
- V =:= 9 ->
- {MinNoSlots,_,MaxNoSlots} = dets:info(TabRef, no_slots),
- ok = dets:close(TabRef),
- io:format("Expect compaction:~n"),
- {ok, _} =
- dets:open_file(TabRef, [{repair,force},
- {min_no_slots,MinNoSlots},
- {max_no_slots,MaxNoSlots} | BArgs]);
- true ->
- ok
- end,
+
+ {MinNoSlots,_,MaxNoSlots} = dets:info(TabRef, no_slots),
+ ok = dets:close(TabRef),
+ io:format("Expect compaction:~n"),
+ {ok, _} =
+ dets:open_file(TabRef, [{repair,force},
+ {min_no_slots,MinNoSlots},
+ {max_no_slots,MaxNoSlots} | BArgs]),
All2 = get_all_objects(TabRef),
true = All =:= sort(All2),
FAll2 = get_all_objects_fast(TabRef),
@@ -1418,35 +1192,15 @@ repair(Config, V) ->
file:delete(Fname),
%% object bigger than segments, the "hole" is taken care of
- {ok, TabRef} = dets:open_file(TabRef, [{file, Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file, Fname}]),
Tuple = erlang:make_tuple(1000, foobar), % > 2 kB
ok = dets:insert(TabRef, Tuple),
%% at least one full segment (objects smaller than 2 kB):
ins(TabRef, 2000),
ok = dets:close(TabRef),
- if
- V =:= 8 ->
- %% first estimated number of objects is wrong, repair once more
- {ok, Fd} = file:open(Fname, [read,write]),
- NoPos = HeadSize - 8, % no_objects
- file:pwrite(Fd, NoPos, <<0:32>>), % NoItems
- ok = file:close(Fd),
- dets:fsck(Fname, V),
- {ok, _} =
- dets:open_file(TabRef,
- [{repair,false},{file, Fname},{version,V}]),
- 2001 = length(get_all_objects(TabRef)),
- _ = histogram(TabRef, silent),
- 2001 = length(get_all_objects_fast(TabRef)),
- ok = dets:close(TabRef);
- true ->
- ok
- end,
-
{ok, _} =
- dets:open_file(TabRef,
- [{repair,false},{file, Fname},{version,V}]),
+ dets:open_file(TabRef, [{repair,false},{file, Fname}]),
{ok, ObjPos} = dets:where(TabRef, {66,{item,number,66}}),
ok = dets:close(TabRef),
%% Damaged object.
@@ -1454,25 +1208,24 @@ repair(Config, V) ->
crash(Fname, ObjPos+Pos),
io:format(
"Expect forced repair (possibly after attempted compaction):~n"),
- {ok, _} =
- dets:open_file(TabRef, [{repair,force},{file, Fname},{version,V}]),
+ {ok, _} = dets:open_file(TabRef, [{repair,force},{file, Fname}]),
true = dets:info(TabRef, size) < 2001,
ok = dets:close(TabRef),
file:delete(Fname),
%% The file is smaller than the padded object.
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = dets:insert(TabRef, Tuple),
ok = dets:close(TabRef),
io:format("Expect forced repair or compaction:~n"),
{ok, _} =
- dets:open_file(TabRef, [{repair,force},{file, Fname},{version,V}]),
+ dets:open_file(TabRef, [{repair,force},{file, Fname}]),
true = 1 =:= dets:info(TabRef, size),
ok = dets:close(TabRef),
file:delete(Fname),
%% Damaged free lists.
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = ins(TabRef, 300),
ok = dets:sync(TabRef),
ok = del(TabRef, 300, 3),
@@ -1481,48 +1234,42 @@ repair(Config, V) ->
ok = dets:close(TabRef),
crash(Fname, FileSize+20),
%% Used to return bad_freelists, but that changed in OTP-9622
- {ok, TabRef} =
- dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = dets:close(TabRef),
file:delete(Fname),
%% File not closed, opening with read and read_write access tried.
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = ins(TabRef, 300),
ok = dets:close(TabRef),
crash(Fname, ?CLOSED_PROPERLY_POS+3, ?NOT_PROPERLY_CLOSED),
{error, {not_closed, Fname}} =
- dets:open_file(foo, [{file,Fname},{version,V},{repair,force},
+ dets:open_file(foo, [{file,Fname},{repair,force},
{access,read}]),
{error, {not_closed, Fname}} =
- dets:open_file(foo, [{file,Fname},{version,V},{repair,true},
+ dets:open_file(foo, [{file,Fname},{repair,true},
{access,read}]),
io:format("Expect repair:~n"),
{ok, TabRef} =
- dets:open_file(TabRef, [{file,Fname},{version,V},{repair,true},
+ dets:open_file(TabRef, [{file,Fname},{repair,true},
{access,read_write}]),
ok = dets:close(TabRef),
crash(Fname, ?CLOSED_PROPERLY_POS+3, ?NOT_PROPERLY_CLOSED),
io:format("Expect forced repair:~n"),
{ok, TabRef} =
- dets:open_file(TabRef, [{file,Fname},{version,V},{repair,force},
+ dets:open_file(TabRef, [{file,Fname},{repair,force},
{access,read_write}]),
ok = dets:close(TabRef),
file:delete(Fname),
%% The size of an object is huge.
- {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname}]),
ok = dets:insert(TabRef, [{1,2,3},{2,3,4}]),
{ok, ObjPos2} = dets:where(TabRef, {1,2,3}),
ok = dets:close(TabRef),
- ObjPos3 = if
- V =:= 8 -> ObjPos2 + 4;
- V =:= 9 -> ObjPos2
- end,
- crash(Fname, ObjPos3, 255),
+ crash(Fname, ObjPos2, 255),
io:format("Expect forced repair:~n"),
- {ok, TabRef} =
- dets:open_file(TabRef, [{file,Fname},{version,V},{repair,force}]),
+ {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{repair,force}]),
ok = dets:close(TabRef),
file:delete(Fname),
@@ -1530,82 +1277,6 @@ repair(Config, V) ->
ok.
-%% Test the use of different hashing algorithms in v8b and v8c of the
-%% Dets file format.
-hash_v8b_v8c(Config) when is_list(Config) ->
- Source =
- filename:join(?datadir(Config), "dets_test_v8b.dets"),
- %% Little endian version of old file (there is an endianess bug in
- %% the old hash). This is all about version 8 of the dets file format.
-
- P0 = pps(),
- SourceLE =
- filename:join(?datadir(Config),
- "dets_test_v8b_little_endian.dets"),
- Target1 = filename('oldhash1.dets', Config),
- Target1LE = filename('oldhash1le.dets', Config),
- Target2 = filename('oldhash2.dets', Config),
- {ok, Bin} = file:read_file(Source),
- {ok, BinLE} = file:read_file(SourceLE),
- ok = file:write_file(Target1,Bin),
- ok = file:write_file(Target1LE,BinLE),
- ok = file:write_file(Target2,Bin),
- {ok, d1} = dets:open_file(d1,[{file,Target1}]),
- {ok, d1le} = dets:open_file(d1le,[{file,Target1LE}]),
- {ok, d2} = dets:open_file(d2,[{file,Target2},{repair,force},
- {version,8}]),
- FF = fun(N,_F,_T) when N > 16#FFFFFFFFFFFFFFFF ->
- ok;
- (N,F,T) ->
- V = integer_to_list(N),
- case dets:lookup(T,N) of
- [{N,V}] ->
- F(N*2,F,T);
- _Error ->
- exit({failed,{lookup,T,N}})
- end
- end,
- Mess = case (catch FF(1,FF,d1)) of
- {'EXIT', {failed, {lookup,_,_}}} ->
- ok = dets:close(d1),
- FF(1,FF,d1le),
- hash = dets:info(d1le,hash),
- dets:insert(d1le,{33333333333,hejsan}),
- [{33333333333,hejsan}] =
- dets:lookup(d1le,33333333333),
- ok = dets:close(d1le),
- {ok, d1le} = dets:open_file(d1le,
- [{file,Target1LE}]),
- [{33333333333,hejsan}] =
- dets:lookup(d1le,33333333333),
- FF(1,FF,d1le),
- ok = dets:close(d1le),
- "Seems to be a little endian machine";
- {'EXIT', Fault} ->
- exit(Fault);
- _ ->
- ok = dets:close(d1le),
- hash = dets:info(d1,hash),
- dets:insert(d1,{33333333333,hejsan}),
- [{33333333333,hejsan}] =
- dets:lookup(d1,33333333333),
- ok = dets:close(d1),
- {ok, d1} = dets:open_file(d1,[{file,Target1}]),
- [{33333333333,hejsan}] =
- dets:lookup(d1,33333333333),
- FF(1,FF,d1),
- ok = dets:close(d1),
- "Seems to be a big endian machine"
- end,
- FF(1,FF,d2),
- phash = dets:info(d2,hash),
- ok = dets:close(d2),
- file:delete(Target1),
- file:delete(Target1LE),
- file:delete(Target2),
- check_pps(P0),
- {comment, Mess}.
-
%% Test version 9(b) with erlang:phash/2 as hash function.
phash(Config) when is_list(Config) ->
T = phash,
@@ -1643,9 +1314,10 @@ phash(Config) when is_list(Config) ->
ok = dets:close(T),
%% One cannot use the bchunk format when copying between a phash
- %% table and a phash2 table. (There is no test for the case an R9
- %% (or later) node (using phash2) copies a table to an R8 node
- %% (using phash).) See also the comment on HASH_PARMS in dets_v9.erl.
+ %% table and a phash2 table. (There is no test for the case an
+ %% Erlang/OTP R9 (or later) node (using phash2) copies a table to
+ %% an Erlang/OTP R8 node (using phash).) See also the comment on
+ %% HASH_PARMS in dets_v9.erl.
{ok, _} = file:copy(Phash_v9bS, Fname),
{ok, T} = dets:open_file(T, [{file, Fname}]),
Type = dets:info(T, type),
@@ -1653,7 +1325,7 @@ phash(Config) when is_list(Config) ->
Input = init_bchunk(T),
T2 = phash_table,
Fname2 = filename(T2, Config),
- Args = [{type,Type},{keypos,KeyPos},{version,9},{file,Fname2}],
+ Args = [{type,Type},{keypos,KeyPos},{file,Fname2}],
{ok, T2} = dets:open_file(T2, Args),
{error, {init_fun, _}} =
dets:init_table(T2, Input, {format,bchunk}),
@@ -1665,21 +1337,14 @@ phash(Config) when is_list(Config) ->
ok.
%% Test foldl, foldr, to_ets.
-fold_v8(Config) when is_list(Config) ->
- fold(Config, 8).
-
-%% Test foldl, foldr, to_ets.
-fold_v9(Config) when is_list(Config) ->
- fold(Config, 9).
-
-fold(Config, Version) ->
+fold(Config) when is_list(Config) ->
T = test_table,
N = 100,
Fname = filename(T, Config),
file:delete(Fname),
P0 = pps(),
- Args = [{version, Version}, {file,Fname}, {estimated_no_objects, N}],
+ Args = [{file,Fname}, {estimated_no_objects, N}],
{ok, _} = dets:open_file(T, Args),
ok = ins(T, N),
@@ -1721,10 +1386,7 @@ fold(Config, Version) ->
ok = dets:close(T),
%% Damaged object.
- Pos = if
- Version =:= 8 -> 12;
- Version =:= 9 -> 8
- end,
+ Pos = 8,
crash(Fname, ObjPos+Pos),
{ok, _} = dets:open_file(T, Args),
io:format("Expect corrupt table:~n"),
@@ -1738,18 +1400,11 @@ fold(Config, Version) ->
ok.
%% Add objects to a fixed table.
-fixtable_v8(Config) when is_list(Config) ->
- fixtable(Config, 8).
-
-%% Add objects to a fixed table.
-fixtable_v9(Config) when is_list(Config) ->
- fixtable(Config, 9).
-
-fixtable(Config, Version) when is_list(Config) ->
+fixtable(Config) when is_list(Config) ->
T = fixtable,
Fname = filename(fixtable, Config),
file:delete(Fname),
- Args = [{version,Version},{file,Fname}],
+ Args = [{file,Fname}],
P0 = pps(),
{ok, _} = dets:open_file(T, Args),
@@ -1832,21 +1487,13 @@ fixtable(Config, Version) when is_list(Config) ->
ok.
%% Matching objects of a fixed table.
-match_v8(Config) when is_list(Config) ->
- match(Config, 8).
-
-%% Matching objects of a fixed table.
-match_v9(Config) when is_list(Config) ->
- match(Config, 9).
-
-match(Config, Version) ->
+match(Config) when is_list(Config) ->
T = match,
Fname = filename(match, Config),
file:delete(Fname),
P0 = pps(),
- Args = [{version, Version}, {file,Fname}, {type, duplicate_bag},
- {estimated_no_objects,550}],
+ Args = [{file,Fname}, {type, duplicate_bag}, {estimated_no_objects,550}],
{ok, _} = dets:open_file(T, Args),
ok = dets:insert(T, {1, a, b}),
ok = dets:insert(T, {1, b, a}),
@@ -1901,7 +1548,7 @@ match(Config, Version) ->
{_, TmpCont} = dets:match_object(T, '_', 200),
{_, TmpCont1} = dets:match_object(TmpCont),
{TTL, _} = dets:match_object(TmpCont1),
- DI = if Version =:= 8 -> last(TTL); Version =:= 9 -> hd(TTL) end,
+ DI = hd(TTL),
dets:safe_fixtable(T, true),
{L1, C20} = dets:match_object(T, '_', 200),
true = 200 =< length(L1),
@@ -1957,8 +1604,7 @@ match(Config, Version) ->
ok = dets:close(T),
%% Damaged size of object.
- %% In v8, there is a next pointer before the size.
- CrashPos = if Version =:= 8 -> 5; Version =:= 9 -> 1 end,
+ CrashPos = 1,
crash(Fname, ObjPos2+CrashPos),
{ok, _} = dets:open_file(T, Args),
case dets:insert_new(T, Obj) of % OTP-12024
@@ -1986,7 +1632,7 @@ match(Config, Version) ->
ok = dets:close(T),
%% match_delete finds an error
- CrashPos3 = if Version =:= 8 -> 12; Version =:= 9 -> 16 end,
+ CrashPos3 = 16,
crash(Fname, ObjPos3+CrashPos3),
{ok, _} = dets:open_file(T, Args),
bad_object(dets:match_delete(T, Spec), Fname),
@@ -2008,21 +1654,13 @@ match(Config, Version) ->
ok.
%% Selecting objects of a fixed table.
-select_v8(Config) when is_list(Config) ->
- select(Config, 8).
-
-%% Selecting objects of a fixed table.
-select_v9(Config) when is_list(Config) ->
- select(Config, 9).
-
-select(Config, Version) ->
+select(Config) when is_list(Config) ->
T = select,
Fname = filename(select, Config),
file:delete(Fname),
P0 = pps(),
- Args = [{version,Version}, {file,Fname}, {type, duplicate_bag},
- {estimated_no_objects,550}],
+ Args = [{file,Fname}, {type, duplicate_bag},{estimated_no_objects,550}],
{ok, _} = dets:open_file(T, Args),
ok = dets:insert(T, {1, a, b}),
ok = dets:insert(T, {1, b, a}),
@@ -2074,7 +1712,7 @@ select(Config, Version) ->
{_, TmpCont} = dets:match_object(T, '_', 200),
{_, TmpCont1} = dets:match_object(TmpCont),
{TTL, _} = dets:match_object(TmpCont1),
- DI = if Version =:= 8 -> last(TTL); Version =:= 9 -> hd(TTL) end,
+ DI = hd(TTL),
dets:safe_fixtable(T, true),
{L1, C20} = dets:select(T, AllSpec, 200),
true = 200 =< length(L1),
@@ -2281,28 +1919,21 @@ badarg(Config) when is_list(Config) ->
ok.
%% Test the write cache for sets.
-cache_sets_v8(Config) when is_list(Config) ->
- cache_sets(Config, 8).
-
-%% Test the write cache for sets.
-cache_sets_v9(Config) when is_list(Config) ->
- cache_sets(Config, 9).
-
-cache_sets(Config, Version) ->
+cache_sets(Config) when is_list(Config) ->
Small = 2,
- cache_sets(Config, {0,0}, false, Small, Version),
- cache_sets(Config, {0,0}, true, Small, Version),
- cache_sets(Config, {5000,5000}, false, Small, Version),
- cache_sets(Config, {5000,5000}, true, Small, Version),
+ cache_sets(Config, {0,0}, false, Small),
+ cache_sets(Config, {0,0}, true, Small),
+ cache_sets(Config, {5000,5000}, false, Small),
+ cache_sets(Config, {5000,5000}, true, Small),
%% Objects of size greater than 2 kB.
Big = 1200,
- cache_sets(Config, {0,0}, false, Big, Version),
- cache_sets(Config, {0,0}, true, Big, Version),
- cache_sets(Config, {5000,5000}, false, Big, Version),
- cache_sets(Config, {5000,5000}, true, Big, Version),
+ cache_sets(Config, {0,0}, false, Big),
+ cache_sets(Config, {0,0}, true, Big),
+ cache_sets(Config, {5000,5000}, false, Big),
+ cache_sets(Config, {5000,5000}, true, Big),
ok.
-cache_sets(Config, DelayedWrite, Extra, Sz, Version) ->
+cache_sets(Config, DelayedWrite, Extra, Sz) ->
%% Extra = bool(). Insert tuples until the tested key is not alone.
%% Sz = integer(). Size of the inserted tuples.
@@ -2311,9 +1942,8 @@ cache_sets(Config, DelayedWrite, Extra, Sz, Version) ->
file:delete(Fname),
P0 = pps(),
- {ok, _} =
- dets:open_file(T,[{version, Version}, {file,Fname}, {type,set},
- {delayed_write, DelayedWrite}]),
+ {ok, _} = dets:open_file(T,[{file,Fname}, {type,set},
+ {delayed_write, DelayedWrite}]),
Dups = 1,
{Key, OtherKeys} =
@@ -2430,28 +2060,21 @@ cache_sets(Config, DelayedWrite, Extra, Sz, Version) ->
ok.
%% Test the write cache for bags.
-cache_bags_v8(Config) when is_list(Config) ->
- cache_bags(Config, 8).
-
-%% Test the write cache for bags.
-cache_bags_v9(Config) when is_list(Config) ->
- cache_bags(Config, 9).
-
-cache_bags(Config, Version) ->
+cache_bags(Config) when is_list(Config) ->
Small = 2,
- cache_bags(Config, {0,0}, false, Small, Version),
- cache_bags(Config, {0,0}, true, Small, Version),
- cache_bags(Config, {5000,5000}, false, Small, Version),
- cache_bags(Config, {5000,5000}, true, Small, Version),
+ cache_bags(Config, {0,0}, false, Small),
+ cache_bags(Config, {0,0}, true, Small),
+ cache_bags(Config, {5000,5000}, false, Small),
+ cache_bags(Config, {5000,5000}, true, Small),
%% Objects of size greater than 2 kB.
Big = 1200,
- cache_bags(Config, {0,0}, false, Big, Version),
- cache_bags(Config, {0,0}, true, Big, Version),
- cache_bags(Config, {5000,5000}, false, Big, Version),
- cache_bags(Config, {5000,5000}, true, Big, Version),
+ cache_bags(Config, {0,0}, false, Big),
+ cache_bags(Config, {0,0}, true, Big),
+ cache_bags(Config, {5000,5000}, false, Big),
+ cache_bags(Config, {5000,5000}, true, Big),
ok.
-cache_bags(Config, DelayedWrite, Extra, Sz, Version) ->
+cache_bags(Config, DelayedWrite, Extra, Sz) ->
%% Extra = bool(). Insert tuples until the tested key is not alone.
%% Sz = integer(). Size of the inserted tuples.
@@ -2460,9 +2083,8 @@ cache_bags(Config, DelayedWrite, Extra, Sz, Version) ->
file:delete(Fname),
P0 = pps(),
- {ok, _} =
- dets:open_file(T,[{version, Version}, {file,Fname}, {type,bag},
- {delayed_write, DelayedWrite}]),
+ {ok, _} = dets:open_file(T,[{file,Fname}, {type,bag},
+ {delayed_write, DelayedWrite}]),
Dups = 1,
{Key, OtherKeys} =
@@ -2588,8 +2210,7 @@ cache_bags(Config, DelayedWrite, Extra, Sz, Version) ->
R1 = {index_test,1,2,3,4},
R2 = {index_test,2,2,13,14},
R3 = {index_test,1,12,13,14},
- {ok, _} = dets:open_file(T,[{version,Version},{type,bag},
- {keypos,2},{file,Fname}]),
+ {ok, _} = dets:open_file(T,[{type,bag}, {keypos,2},{file,Fname}]),
ok = dets:insert(T,R1),
ok = dets:sync(T),
ok = dets:insert(T,R2),
@@ -2606,27 +2227,20 @@ cache_bags(Config, DelayedWrite, Extra, Sz, Version) ->
ok.
%% Test the write cache for duplicate bags.
-cache_duplicate_bags_v8(Config) when is_list(Config) ->
- cache_duplicate_bags(Config, 8).
-
-%% Test the write cache for duplicate bags.
-cache_duplicate_bags_v9(Config) when is_list(Config) ->
- cache_duplicate_bags(Config, 9).
-
-cache_duplicate_bags(Config, Version) ->
+cache_duplicate_bags(Config) when is_list(Config) ->
Small = 2,
- cache_dup_bags(Config, {0,0}, false, Small, Version),
- cache_dup_bags(Config, {0,0}, true, Small, Version),
- cache_dup_bags(Config, {5000,5000}, false, Small, Version),
- cache_dup_bags(Config, {5000,5000}, true, Small, Version),
+ cache_dup_bags(Config, {0,0}, false, Small),
+ cache_dup_bags(Config, {0,0}, true, Small),
+ cache_dup_bags(Config, {5000,5000}, false, Small),
+ cache_dup_bags(Config, {5000,5000}, true, Small),
%% Objects of size greater than 2 kB.
Big = 1200,
- cache_dup_bags(Config, {0,0}, false, Big, Version),
- cache_dup_bags(Config, {0,0}, true, Big, Version),
- cache_dup_bags(Config, {5000,5000}, false, Big, Version),
- cache_dup_bags(Config, {5000,5000}, true, Big, Version).
+ cache_dup_bags(Config, {0,0}, false, Big),
+ cache_dup_bags(Config, {0,0}, true, Big),
+ cache_dup_bags(Config, {5000,5000}, false, Big),
+ cache_dup_bags(Config, {5000,5000}, true, Big).
-cache_dup_bags(Config, DelayedWrite, Extra, Sz, Version) ->
+cache_dup_bags(Config, DelayedWrite, Extra, Sz) ->
%% Extra = bool(). Insert tuples until the tested key is not alone.
%% Sz = integer(). Size of the inserted tuples.
@@ -2635,10 +2249,8 @@ cache_dup_bags(Config, DelayedWrite, Extra, Sz, Version) ->
file:delete(Fname),
P0 = pps(),
- {ok, _} =
- dets:open_file(T,[{version, Version}, {file,Fname},
- {type,duplicate_bag},
- {delayed_write, DelayedWrite}]),
+ {ok, _} = dets:open_file(T,[{file,Fname}, {type,duplicate_bag},
+ {delayed_write, DelayedWrite}]),
Dups = 2,
{Key, OtherKeys} =
@@ -2869,7 +2481,7 @@ otp_8899(Config) when is_list(Config) ->
Server = self(),
file:delete(FName),
- {ok, _} = dets:open_file(Tab,[{file, FName},{version,9}]),
+ {ok, _} = dets:open_file(Tab,[{file, FName}]),
[P1,P2,P3,P4] = new_clients(4, Tab),
MC = [Tab],
@@ -2895,7 +2507,7 @@ many_clients(Config) when is_list(Config) ->
file:delete(FName),
P0 = pps(),
- {ok, _} = dets:open_file(Tab,[{file, FName},{version,9}]),
+ {ok, _} = dets:open_file(Tab,[{file, FName}]),
[P1,P2,P3,P4] = new_clients(4, Tab),
%% dets:init_table/2 is used for making sure that all processes
@@ -2954,14 +2566,14 @@ many_clients(Config) when is_list(Config) ->
file:delete(FName),
%% Check that errors are handled correctly by the streaming operators.
- {ok, _} = dets:open_file(Tab,[{file, FName},{version,9}]),
+ {ok, _} = dets:open_file(Tab,[{file, FName}]),
ok = ins(Tab, 100),
Obj = {66,{item,number,66}},
{ok, ObjPos} = dets:where(Tab, Obj),
ok = dets:close(Tab),
%% Damaged object.
crash(FName, ObjPos+12),
- {ok, _} = dets:open_file(Tab,[{file, FName},{version,9}]),
+ {ok, _} = dets:open_file(Tab,[{file, FName}]),
BadObject1 = dets:lookup_keys(Tab, [65,66,67,68,69]),
bad_object(BadObject1, FName),
_Error = dets:close(Tab),
@@ -3415,18 +3027,13 @@ repair_continuation(Config) ->
%% OTP-5487. Growth of read-only table (again).
otp_5487(Config) ->
- otp_5487(Config, 9),
- otp_5487(Config, 8),
- ok.
-
-otp_5487(Config, Version) ->
Tab = otp_5487,
Fname = filename(otp_5487, Config),
file:delete(Fname),
Ets = ets:new(otp_5487, [public, set]),
lists:foreach(fun(I) -> ets:insert(Ets, {I,I+1}) end,
lists:seq(0,1000)),
- {ok, _} = dets:open_file(Tab, [{file,Fname},{version,Version}]),
+ {ok, _} = dets:open_file(Tab, [{file,Fname}]),
ok = dets:from_ets(Tab, Ets),
ok = dets:sync(Tab),
ok = dets:close(Tab),
@@ -3470,14 +3077,12 @@ otp_6359(Config) ->
%% OTP-4738. ==/2 and =:=/2.
otp_4738(Config) ->
- %% Version 8 has not been corrected.
- %% (The constant -12857447 is for version 9 only.)
- otp_4738_set(9, Config),
- otp_4738_bag(9, Config),
- otp_4738_dupbag(9, Config),
+ otp_4738_set(Config),
+ otp_4738_bag(Config),
+ otp_4738_dupbag(Config),
ok.
-otp_4738_dupbag(Version, Config) ->
+otp_4738_dupbag(Config) ->
Tab = otp_4738,
File = filename(Tab, Config),
file:delete(File),
@@ -3485,7 +3090,7 @@ otp_4738_dupbag(Version, Config) ->
F = float(I),
One = 1,
FOne = float(One),
- Args = [{file,File},{type,duplicate_bag},{version,Version}],
+ Args = [{file,File},{type,duplicate_bag}],
{ok, Tab} = dets:open_file(Tab, Args),
ok = dets:insert(Tab, [{I,One},{F,One},{I,FOne},{F,FOne}]),
ok = dets:sync(Tab),
@@ -3530,7 +3135,7 @@ otp_4738_dupbag(Version, Config) ->
file:delete(File),
ok.
-otp_4738_bag(Version, Config) ->
+otp_4738_bag(Config) ->
Tab = otp_4738,
File = filename(Tab, Config),
file:delete(File),
@@ -3538,7 +3143,7 @@ otp_4738_bag(Version, Config) ->
F = float(I),
One = 1,
FOne = float(One),
- Args = [{file,File},{type,bag},{version,Version}],
+ Args = [{file,File},{type,bag}],
{ok, Tab} = dets:open_file(Tab, Args),
ok = dets:insert(Tab, [{I,One},{F,One},{I,FOne},{F,FOne}]),
ok = dets:sync(Tab),
@@ -3561,11 +3166,11 @@ otp_4738_bag(Version, Config) ->
ok = dets:close(Tab),
file:delete(File).
-otp_4738_set(Version, Config) ->
+otp_4738_set(Config) ->
Tab = otp_4738,
File = filename(Tab, Config),
file:delete(File),
- Args = [{file,File},{type,set},{version,Version}],
+ Args = [{file,File},{type,set}],
%% I and F share the same slot.
I = -12857447,
@@ -3864,6 +3469,19 @@ wait_for_close(Tab) ->
wait_for_close(Tab)
end.
+%% OTP-13830. Format 8 is no longer supported.
+otp_13830(Config) ->
+ Tab = otp_13830,
+ File8 = filename:join(?datadir(Config), "version_8.dets"),
+ {error,{format_8_no_longer_supported,_}} =
+ dets:open_file(Tab, [{file, File8}]),
+ File = filename(Tab, Config),
+ %% Check the 'version' option, for backwards compatibility:
+ {ok, Tab} = dets:open_file(Tab, [{file, File}, {version, 9}]),
+ ok = dets:close(Tab),
+ {ok, Tab} = dets:open_file(Tab, [{file, File}, {version, default}]),
+ ok = dets:close(Tab).
+
%%
%% Parts common to several test cases
%%
@@ -4000,9 +3618,7 @@ match_test(Data, Tab) ->
%% Utilities
%%
-headsz(8) ->
- ?HEADSZ_v8;
-headsz(_) ->
+headsz() ->
?HEADSZ_v9.
unwritable(Fname) ->
@@ -4030,13 +3646,13 @@ filename(Name, Config) when is_atom(Name) ->
filename(Name, _Config) ->
filename:join(?privdir(_Config), Name).
-open_files(_Name, [], _Version) ->
+open_files(_Name, []) ->
[];
-open_files(Name0, [Args | Tail], Version) ->
+open_files(Name0, [Args | Tail]) ->
?format("init ~p~n", [Args]),
Name = list_to_atom(integer_to_list(Name0)),
- {ok, Name} = dets:open_file(Name, [{version,Version} | Args]),
- [Name | open_files(Name0+1, Tail, Version)].
+ {ok, Name} = dets:open_file(Name, Args),
+ [Name | open_files(Name0+1, Tail)].
close_all(Tabs) -> foreach(fun(Tab) -> ok = dets:close(Tab) end, Tabs).
@@ -4137,20 +3753,15 @@ no_keys_test([T | Ts]) ->
no_keys_test([]) ->
ok;
no_keys_test(T) ->
- case dets:info(T, version) of
- 8 ->
- ok;
- 9 ->
- Kp = dets:info(T, keypos),
- All = dets:match_object(T, '_'),
- L = lists:map(fun(X) -> element(Kp, X) end, All),
- NoKeys = length(lists:usort(L)),
- case {dets:info(T, no_keys), NoKeys} of
- {N, N} ->
- ok;
- {N1, N2} ->
- exit({no_keys_test, N1, N2})
- end
+ Kp = dets:info(T, keypos),
+ All = dets:match_object(T, '_'),
+ L = lists:map(fun(X) -> element(Kp, X) end, All),
+ NoKeys = length(lists:usort(L)),
+ case {dets:info(T, no_keys), NoKeys} of
+ {N, N} ->
+ ok;
+ {N1, N2} ->
+ exit({no_keys_test, N1, N2})
end.
safe_get_all_objects(Tab) ->
@@ -4182,7 +3793,6 @@ count_objs_1({Ts,C}, N) when is_list(Ts) ->
get_all_objects_fast(Tab) ->
dets:match_object(Tab, '_').
-%% Relevant for version 8.
histogram(Tab) ->
OnePercent = case dets:info(Tab, no_slots) of
undefined -> undefined;
@@ -4244,10 +3854,6 @@ ave_histogram([{S,N1} | H], N) ->
ave_histogram([], N) ->
N.
-bad_object({error,{bad_object,FileName}}, FileName) ->
- ok; % Version 8, no debug.
-bad_object({error,{{bad_object,_,_},FileName}}, FileName) ->
- ok; % Version 8, debug...
bad_object({error,{{bad_object,_}, FileName}}, FileName) ->
ok; % No debug.
bad_object({error,{{{bad_object,_,_},_,_,_}, FileName}}, FileName) ->
diff --git a/lib/stdlib/test/dets_SUITE_data/dets_test_v8b.dets b/lib/stdlib/test/dets_SUITE_data/dets_test_v8b.dets
deleted file mode 100644
index d0aa20fe06..0000000000
--- a/lib/stdlib/test/dets_SUITE_data/dets_test_v8b.dets
+++ /dev/null
Binary files differ
diff --git a/lib/stdlib/test/dets_SUITE_data/dets_test_v8b_little_endian.dets b/lib/stdlib/test/dets_SUITE_data/dets_test_v8b_little_endian.dets
deleted file mode 100644
index bf490afa1a..0000000000
--- a/lib/stdlib/test/dets_SUITE_data/dets_test_v8b_little_endian.dets
+++ /dev/null
Binary files differ
diff --git a/lib/stdlib/test/dets_SUITE_data/version_r2d.dets b/lib/stdlib/test/dets_SUITE_data/version_8.dets
index 327072f99e..278187e85c 100644
--- a/lib/stdlib/test/dets_SUITE_data/version_r2d.dets
+++ b/lib/stdlib/test/dets_SUITE_data/version_8.dets
Binary files differ
diff --git a/lib/stdlib/test/dets_SUITE_data/version_r3b02.dets b/lib/stdlib/test/dets_SUITE_data/version_r3b02.dets
deleted file mode 100644
index 058cd15b31..0000000000
--- a/lib/stdlib/test/dets_SUITE_data/version_r3b02.dets
+++ /dev/null
Binary files differ
diff --git a/lib/stdlib/test/error_logger_h_SUITE.erl b/lib/stdlib/test/error_logger_h_SUITE.erl
index 2a34c7764f..30f96e0522 100644
--- a/lib/stdlib/test/error_logger_h_SUITE.erl
+++ b/lib/stdlib/test/error_logger_h_SUITE.erl
@@ -297,13 +297,13 @@ match_format(Tag, [Format,Args], [Head|Lines], AtNode, Depth) ->
iolist_to_binary(S)
end,
Expected0 = binary:split(Bin, <<"\n">>, [global,trim]),
- Expected = Expected0 ++ AtNode,
+ Expected = AtNode ++ Expected0,
match_term_lines(Expected, Lines).
match_term(Tag, [Arg], [Head|Lines], AtNode, Depth) ->
match_head(Tag, Head),
Expected0 = match_term_get_expected(Arg, Depth),
- Expected = Expected0 ++ AtNode,
+ Expected = AtNode ++ Expected0,
match_term_lines(Expected, Lines).
match_term_get_expected(List, Depth) when is_list(List) ->
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 9a14c7014c..f68d5eca3f 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -19,7 +19,7 @@
%%
-module(ets_SUITE).
--export([all/0, suite/0,groups/0,init_per_suite/1, 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]).
-export([default/1,setbag/1,badnew/1,verybadnew/1,named/1,keypos2/1,
privacy/1,privacy_owner/2]).
@@ -31,15 +31,14 @@
-export([match_delete3/1]).
-export([firstnext/1,firstnext_concurrent/1]).
-export([slot/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, badfile/1]).
--export([ heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]).
--export([ lookup_element_mult/1]).
--export([]).
+-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, badfile/1]).
+-export([heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]).
+-export([lookup_element_mult/1]).
-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,
+-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,
t_select_delete/1,t_ets_dets/1]).
@@ -61,8 +60,7 @@
-export([otp_7665/1]).
-export([meta_wb/1]).
-export([grow_shrink/1, grow_pseudo_deleted/1, shrink_pseudo_deleted/1]).
--export([
- meta_lookup_unnamed_read/1, meta_lookup_unnamed_write/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]).
-export([smp_insert/1, smp_fixed_delete/1, smp_unfix_fix/1, smp_select_delete/1,
@@ -95,7 +93,7 @@
rename_do/1, rename_unnamed_do/1, interface_equality_do/1, ordered_match_do/1,
ordered_do/1, privacy_do/1, empty_do/1, badinsert_do/1, time_lookup_do/1,
lookup_order_do/1, lookup_element_mult_do/1, delete_tab_do/1, delete_elem_do/1,
- match_delete_do/1, match_delete3_do/1, firstnext_do/1,
+ match_delete_do/1, match_delete3_do/1, firstnext_do/1,
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,
@@ -129,7 +127,7 @@ suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap,{minutes,5}}].
-all() ->
+all() ->
[{group, new}, {group, insert}, {group, lookup},
{group, delete}, firstnext, firstnext_concurrent, slot,
{group, match}, t_match_spec_run,
@@ -161,7 +159,7 @@ all() ->
memory_check_summary]. % MUST BE LAST
-groups() ->
+groups() ->
[{new, [],
[default, setbag, badnew, verybadnew, named, keypos2,
privacy]},
@@ -249,6 +247,7 @@ t_bucket_disappears_do(Opts) ->
%% Check ets:match_spec_run/2.
t_match_spec_run(Config) when is_list(Config) ->
+ ct:timetrap({minutes,30}), %% valgrind needs a lot
init_externals(),
EtsMem = etsmem(),
@@ -703,7 +702,7 @@ adjust_xmem([_T1,_T2,_T3,_T4], {A0,B0,C0,D0} = _Mem0, EstCnt) ->
{A0+TabSz, B0+HTabSz, C0+HTabSz, D0+HTabSz}.
%% Misc. whitebox tests
-t_whitebox(Config) when is_list(Config) ->
+t_whitebox(Config) when is_list(Config) ->
EtsMem = etsmem(),
repeat_for_opts(whitebox_1),
repeat_for_opts(whitebox_1),
@@ -1044,6 +1043,7 @@ do_reverse_chunked({L,C},Acc) ->
%% Test the ets:select_delete/2 and ets:select_count/2 BIFs.
t_select_delete(Config) when is_list(Config) ->
+ ct:timetrap({minutes,30}), %% valgrind needs a lot
EtsMem = etsmem(),
Tables = fill_sets_int(10000) ++ fill_sets_int(10000,[{write_concurrency,true}]),
lists:foreach
@@ -1489,15 +1489,15 @@ update_element(Config) when is_list(Config) ->
verify_etsmem(EtsMem).
update_element_opts(Opts) ->
- TupleCases = [{{key,val}, 1 ,2},
- {{val,key}, 2, 1},
- {{key,val}, 1 ,[2]},
+ TupleCases = [{{key,val}, 1 ,2},
+ {{val,key}, 2, 1},
+ {{key,val}, 1 ,[2]},
{{key,val,val}, 1, [2,3]},
{{val,key,val,val}, 2, [3,4,1]},
{{val,val,key,val}, 3, [1,4,1,2]}, % update pos1 twice
{{val,val,val,key}, 4, [2,1,2,3]}],% update pos2 twice
- lists:foreach(fun({Tuple,KeyPos,UpdPos}) -> update_element_opts(Tuple,KeyPos,UpdPos,Opts) end,
+ lists:foreach(fun({Tuple,KeyPos,UpdPos}) -> update_element_opts(Tuple,KeyPos,UpdPos,Opts) end,
TupleCases),
update_element_neg(Opts).
@@ -1513,9 +1513,9 @@ update_element_opts(Tuple,KeyPos,UpdPos,Opts) ->
true = ets:delete(OrdSet),
ok.
-update_element(T,Tuple,KeyPos,UpdPos) ->
+update_element(T,Tuple,KeyPos,UpdPos) ->
KeyList = [17,"seventeen",<<"seventeen">>,{17},list_to_binary(lists:seq(1,100)),make_ref(), self()],
- lists:foreach(fun(Key) ->
+ lists:foreach(fun(Key) ->
TupleWithKey = setelement(KeyPos,Tuple,Key),
update_element_do(T,TupleWithKey,Key,UpdPos)
end,
@@ -1550,29 +1550,29 @@ update_element_do(Tab,Tuple,Key,UpdPos) ->
{Pos, element(ToIx+1,Values)} % single {pos,value} arg
end,
- UpdateF = fun(ToIx,Rand) ->
- PosValArg = PosValArgF(ToIx,[],UpdPos,Rand,PosValArgF),
- %%io:format("update_element(~p)~n",[PosValArg]),
- ArgHash = erlang:phash2({Tab,Key,PosValArg}),
- true = ets:update_element(Tab, Key, PosValArg),
- ArgHash = erlang:phash2({Tab,Key,PosValArg}),
- NewTuple = update_tuple(PosValArg,Tuple),
- [NewTuple] = ets:lookup(Tab,Key)
+ UpdateF = fun(ToIx,Rand) ->
+ PosValArg = PosValArgF(ToIx,[],UpdPos,Rand,PosValArgF),
+ %%io:format("update_element(~p)~n",[PosValArg]),
+ ArgHash = erlang:phash2({Tab,Key,PosValArg}),
+ true = ets:update_element(Tab, Key, PosValArg),
+ ArgHash = erlang:phash2({Tab,Key,PosValArg}),
+ NewTuple = update_tuple(PosValArg,Tuple),
+ [NewTuple] = ets:lookup(Tab,Key)
end,
- LoopF = fun(_FromIx, Incr, _Times, Checksum, _MeF) when Incr >= Length ->
+ LoopF = fun(_FromIx, Incr, _Times, Checksum, _MeF) when Incr >= Length ->
Checksum; % done
- (FromIx, Incr, 0, Checksum, MeF) ->
+ (FromIx, Incr, 0, Checksum, MeF) ->
MeF(FromIx, Incr+1, Length, Checksum, MeF);
- (FromIx, Incr, Times, Checksum, MeF) ->
+ (FromIx, Incr, Times, Checksum, MeF) ->
ToIx = (FromIx + Incr) rem Length,
UpdateF(ToIx,Checksum),
- if
+ if
Incr =:= 0 -> UpdateF(ToIx,Checksum); % extra update to same value
true -> true
- end,
+ end,
MeF(ToIx, Incr, Times-1, Checksum+ToIx+1, MeF)
end,
@@ -1616,7 +1616,7 @@ update_element_neg_do(T) ->
Object = {key, 0, "Hej"},
true = ets:insert(T,Object),
- UpdateF = fun(Arg3) ->
+ UpdateF = fun(Arg3) ->
ArgHash = erlang:phash2({T,key,Arg3}),
{'EXIT',{badarg,_}} = (catch ets:update_element(T,key,Arg3)),
ArgHash = erlang:phash2({T,key,Arg3}),
@@ -1691,7 +1691,7 @@ update_counter_for(T) ->
true = ets:lookup(T, b) =:= [setelement(1, NewObj, b)],
ets:delete(T, b),
Myself(NewObj,Times-1,Arg3,Myself)
- end,
+ end,
LoopF = fun(Obj, Times, Arg3) ->
%%io:format("Loop start:\nObj = ~p\nArg3=~p\n",[Obj,Arg3]),
@@ -1800,7 +1800,7 @@ uc_mimic(Obj, [Pits|Tail], Acc) ->
uc_adder(Init, {_Pos, Add}) ->
Init + Add;
-uc_adder(Init, {_Pos, Add, Thres, Warp}) ->
+uc_adder(Init, {_Pos, Add, Thres, Warp}) ->
case Init + Add of
X when X > Thres, Add > 0 ->
Warp;
@@ -1832,7 +1832,7 @@ update_counter_neg_for(T) ->
Object = {key,0,false,1},
true = ets:insert(T,Object),
- UpdateF = fun(Arg3) ->
+ UpdateF = fun(Arg3) ->
ArgHash = erlang:phash2({T,key,Arg3}),
{'EXIT',{badarg,_}} = (catch ets:update_counter(T,key,Arg3)),
ArgHash = erlang:phash2({T,key,Arg3}),
@@ -1972,15 +1972,16 @@ fixtable_next_do(Opts) ->
verify_etsmem(EtsMem).
do_fixtable_next(Tab) ->
- F = fun(X,T,FF) -> case X of
- 0 -> true;
- _ ->
- ets:insert(T, {X,
- integer_to_list(X),
- X rem 10}),
- FF(X-1,T,FF)
- end
- end,
+ F = fun(X,T,FF) ->
+ case X of
+ 0 -> true;
+ _ ->
+ ets:insert(T, {X,
+ integer_to_list(X),
+ X rem 10}),
+ FF(X-1,T,FF)
+ end
+ end,
F(100,Tab,F),
ets:safe_fixtable(Tab,true),
First = ets:first(Tab),
@@ -1995,7 +1996,7 @@ do_fixtable_next(Tab) ->
%% Check inserts of deleted keys in fixed bags.
fixtable_insert(Config) when is_list(Config) ->
- Combos = [[Type,{write_concurrency,WC}] || Type<- [bag,duplicate_bag],
+ Combos = [[Type,{write_concurrency,WC}] || Type<- [bag,duplicate_bag],
WC <- [false,true]],
lists:foreach(fun(Opts) -> fixtable_insert_do(Opts) end,
Combos),
@@ -2111,7 +2112,7 @@ heir_do(Opts) ->
%% Different types of heir data and link/monitor relations
TestFun = fun(Arg) -> {EtsMem,Arg} end,
- Combos = [{Data,Mode} || Data<-[foo_data, <<"binary">>,
+ Combos = [{Data,Mode} || Data<-[foo_data, <<"binary">>,
lists:seq(1,10), {17,TestFun,self()},
"The busy heir"],
Mode<-[none,link,monitor]],
@@ -2151,7 +2152,7 @@ heir_do(Opts) ->
Founder4 ! {go, Heir4},
{'DOWN', MrefH4, process, Heir4, normal} = receive_any(),
erts_debug:set_internal_state(next_pid, NextPidIx),
- DoppelGanger = spawn_monitor_with_pid(Heir4,
+ DoppelGanger = spawn_monitor_with_pid(Heir4,
fun()-> die_please = receive_any() end),
Founder4 ! die_please,
{'DOWN', MrefF4, process, Founder4, normal} = receive_any(),
@@ -2164,12 +2165,12 @@ heir_do(Opts) ->
failed ->
io:format("Failed to spawn process with pid ~p\n", [Heir4]),
true % try again
- end
+ end
end),
verify_etsmem(EtsMem).
-heir_founder(Master, HeirData, Opts) ->
+heir_founder(Master, HeirData, Opts) ->
{go,Heir} = receive_any(),
HeirTpl = case Heir of
none -> {heir,none};
@@ -2242,7 +2243,7 @@ heir_1(HeirData,Mode,Opts) ->
{'DOWN', Mref, process, Heir, normal} = receive_any().
%% Test ets:give_way/3.
-give_away(Config) when is_list(Config) ->
+give_away(Config) when is_list(Config) ->
repeat_for_opts(give_away_do).
give_away_do(Opts) ->
@@ -2381,7 +2382,7 @@ bad_table(Config) when is_list(Config) ->
ok.
bad_table_do(Opts, DummyFile) ->
- Parent = self(),
+ Parent = self(),
{Pid,Mref} = my_spawn_opt(fun()-> ets_new(priv,[private,named_table | Opts]),
Priv = ets_new(priv,[private | Opts]),
ets_new(prot,[protected,named_table | Opts]),
@@ -2436,7 +2437,7 @@ bad_table_do(Opts, DummyFile) ->
],
Info = {Opts, Priv, Prot},
lists:foreach(fun(Op) -> bad_table_op(Info, Op) end,
- OpList),
+ OpList),
Pid ! die_please,
{'DOWN', Mref, process, Pid, normal} = receive_any(),
ok.
@@ -2571,14 +2572,14 @@ interface_equality_do(Opts) ->
Set = ets_new(set,[set | Opts]),
OrderedSet = ets_new(ordered_set,[ordered_set | Opts]),
F = fun(X,T,FF) -> case X of
- 0 -> true;
- _ ->
- ets:insert(T, {X,
- integer_to_list(X),
- X rem 10}),
- FF(X-1,T,FF)
- end
- end,
+ 0 -> true;
+ _ ->
+ ets:insert(T, {X,
+ integer_to_list(X),
+ X rem 10}),
+ FF(X-1,T,FF)
+ end
+ end,
F(100,Set,F),
F(100,OrderedSet,F),
equal_results(ets, insert, Set, OrderedSet, [{a,"a"}]),
@@ -2647,20 +2648,20 @@ ordered_match_do(Opts) ->
F(3000,T1,F),
[[3,3],[3,3],[3,3]] = ets:match(T1, {'_','_','$1','$2',3}),
F2 = fun(X,Rem,Res,FF) -> case X of
- 0 -> [];
- _ ->
+ 0 -> [];
+ _ ->
case X rem Rem of
Res ->
FF(X-1,Rem,Res,FF) ++
[{X,
- integer_to_list(X),
+ integer_to_list(X),
X rem 10,
X rem 100,
X rem 1000}];
_ ->
FF(X-1,Rem,Res,FF)
end
- end
+ end
end,
OL1 = F2(3000,100,2,F2),
OL1 = ets:match_object(T1, {'_','_','_',2,'_'}),
@@ -2738,7 +2739,7 @@ pick_all_backwards(T) ->
%% Small test case for both set and bag type ets tables.
-setbag(Config) when is_list(Config) ->
+setbag(Config) when is_list(Config) ->
EtsMem = etsmem(),
Set = ets_new(set,[set]),
Bag = ets_new(bag,[bag]),
@@ -2815,7 +2816,7 @@ privacy_do(Opts) ->
privacy_check(pub,prot,priv),
- Owner ! {shift,1,{pub,prot,priv}},
+ Owner ! {shift,1,{pub,prot,priv}},
receive
{Pub1,Prot1,Priv1} ->
ok = privacy_check(Pub1,Prot1,Priv1),
@@ -2954,7 +2955,7 @@ badlookup(Config) when is_list(Config) ->
verify_etsmem(EtsMem).
%% Test that lookup returns objects in order of insertion for bag and dbag.
-lookup_order(Config) when is_list(Config) ->
+lookup_order(Config) when is_list(Config) ->
EtsMem = etsmem(),
repeat_for_opts(lookup_order_do, [write_concurrency,[bag,duplicate_bag]]),
verify_etsmem(EtsMem),
@@ -2976,7 +2977,7 @@ lookup_order_2(Opts, Fixed) ->
case Fixed of
true -> ets:safe_fixtable(T,true);
false -> ok
- end,
+ end,
S10 = {T,[],key},
S20 = check_insert(S10,A),
S30 = check_insert(S20,B),
@@ -2988,7 +2989,7 @@ lookup_order_2(Opts, Fixed) ->
S80 = check_delete(S70,D2b),
S90 = check_insert(S80,D2a),
SA0 = check_delete(S90,D3a),
- SB0 = check_delete(SA0,D3b),
+ SB0 = check_delete(SA0,D3b),
check_insert_new(SB0,D3b),
true = ets:delete(T)
@@ -3001,7 +3002,7 @@ check_insert({T,List0,Key},Val) ->
ets:insert(T,{Key,Val}),
List1 = case (ets:info(T,type) =:= bag andalso
lists:member({Key,Val},List0)) of
- true -> List0;
+ true -> List0;
false -> [{Key,Val} | List0]
end,
check_check({T,List1,Key}).
@@ -3034,8 +3035,6 @@ check_check(S={T,List,Key}) ->
Items = length(List),
S.
-
-
fill_tab(Tab,Val) ->
ets:insert(Tab,{key,Val}),
ets:insert(Tab,{{a,144},Val}),
@@ -3063,13 +3062,11 @@ lookup_element_mult_do(Opts) ->
verify_etsmem(EtsMem).
lem_data() ->
- [
- {service,'eddie2@boromir',{150,236,14,103},httpd88,self()},
+ [{service,'eddie2@boromir',{150,236,14,103},httpd88,self()},
{service,'eddie2@boromir',{150,236,14,103},httpd80,self()},
{service,'eddie3@boromir',{150,236,14,107},httpd88,self()},
{service,'eddie3@boromir',{150,236,14,107},httpd80,self()},
- {service,'eddie4@boromir',{150,236,14,108},httpd88,self()}
- ].
+ {service,'eddie4@boromir',{150,236,14,108},httpd88,self()}].
lem_crash(T) ->
L = ets:lookup_element(T, 'eddie2@boromir', 3),
@@ -3120,6 +3117,7 @@ delete_tab_do(Opts) ->
%% Check that ets:delete/1 works and that other processes can run.
delete_large_tab(Config) when is_list(Config) ->
+ ct:timetrap({minutes,30}), %% valgrind needs a lot
Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 200000)],
EtsMem = etsmem(),
repeat_for_opts(fun(Opts) -> delete_large_tab_do(Opts,Data) end),
@@ -3142,7 +3140,7 @@ delete_large_tab_1(Name, Flags, Data, Fix) ->
lists:foreach(fun({K,_}) -> ets:delete(Tab, K) end, Data)
end,
- {priority, Prio} = process_info(self(), priority),
+ {priority, Prio} = process_info(self(), priority),
Deleter = self(),
[SchedTracer]
= start_loopers(1,
@@ -3189,7 +3187,7 @@ delete_large_tab_1(Name, Flags, Data, Fix) ->
%% Delete a large name table and try to create a new table with
%% the same name in another process.
-delete_large_named_table(Config) when is_list(Config) ->
+delete_large_named_table(Config) when is_list(Config) ->
Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 200000)],
EtsMem = etsmem(),
repeat_for_opts(fun(Opts) -> delete_large_named_table_do(Opts,Data) end),
@@ -3562,7 +3560,7 @@ dyn_lookup(T) -> dyn_lookup(T, ets:first(T)).
dyn_lookup(_T, '$end_of_table') -> [];
dyn_lookup(T, K) ->
- NextKey=ets:next(T,K),
+ NextKey = ets:next(T,K),
case ets:next(T,K) of
NextKey ->
dyn_lookup(T, NextKey);
@@ -4081,9 +4079,9 @@ tabfile_ext2_do(Opts,Config) ->
Name = make_ref(),
[ets:insert(T,{X,integer_to_list(X)}) || X <- L],
ok = ets:tab2file(T,FName,[{extended_info,[md5sum]}]),
- true = lists:sort(ets:tab2list(T)) =:=
+ true = lists:sort(ets:tab2list(T)) =:=
lists:sort(ets:tab2list(element(2,ets:file2tab(FName)))),
- true = lists:sort(ets:tab2list(T)) =:=
+ true = lists:sort(ets:tab2list(T)) =:=
lists:sort(ets:tab2list(
element(2,ets:file2tab(FName,[{verify,true}])))),
{ok, Name} = disk_log:open([{name,Name},{file,FName}]),
@@ -4098,9 +4096,9 @@ tabfile_ext2_do(Opts,Config) ->
ets:tab2list(
element(2,ets:file2tab(FName2)))),
{error,checksum_error} = ets:file2tab(FName2,[{verify,true}]),
- {value,{extended_info,[md5sum]}} =
+ {value,{extended_info,[md5sum]}} =
lists:keysearch(extended_info,1,element(2,ets:tabfile_info(FName2))),
- {value,{extended_info,[md5sum]}} =
+ {value,{extended_info,[md5sum]}} =
lists:keysearch(extended_info,1,element(2,ets:tabfile_info(FName))),
file:delete(FName),
file:delete(FName2),
@@ -4145,15 +4143,14 @@ tabfile_ext4(Config) when is_list(Config) ->
Name2 = make_ref(),
[ets:insert(TL,{X,integer_to_list(X)}) || X <- LL],
ok = ets:tab2file(TL,FName,[{extended_info,[md5sum]}]),
- {ok, Name2} = disk_log:open([{name, Name2}, {file, FName},
+ {ok, Name2} = disk_log:open([{name, Name2}, {file, FName},
{mode, read_only}]),
{C,[_|_]} = disk_log:chunk(Name2,start),
{_,[_|_]} = disk_log:chunk(Name2,C),
disk_log:close(Name2),
- true = lists:sort(ets:tab2list(TL)) =:=
+ true = lists:sort(ets:tab2list(TL)) =:=
lists:sort(ets:tab2list(element(2,ets:file2tab(FName)))),
- Res = [
- begin
+ Res = [begin
{ok,FD} = file:open(FName,[binary,read,write]),
{ok, Bin} = file:pread(FD,0,1000),
<<B1:N/binary,Ch:8,B2/binary>> = Bin,
@@ -4163,7 +4160,7 @@ tabfile_ext4(Config) when is_list(Config) ->
ok = file:close(FD),
X = case ets:file2tab(FName) of
{ok,TL2} ->
- true = lists:sort(ets:tab2list(TL)) =/=
+ true = lists:sort(ets:tab2list(TL)) =/=
lists:sort(ets:tab2list(TL2));
_ ->
totally_broken
@@ -4171,7 +4168,7 @@ tabfile_ext4(Config) when is_list(Config) ->
{error,Y} = ets:file2tab(FName,[{verify,true}]),
ets:tab2file(TL,FName,[{extended_info,[md5sum]}]),
{X,Y}
- end || N <- lists:seq(500,600) ],
+ end || N <- lists:seq(500,600)],
io:format("~p~n",[Res]),
file:delete(FName),
ok.
@@ -4402,16 +4399,14 @@ member_do(Opts) ->
build_table(L1,L2,Num) ->
- T = ets_new(xxx, [ordered_set]
- ),
+ T = ets_new(xxx, [ordered_set]),
lists:foreach(
fun(X1) ->
lists:foreach(
fun(X2) ->
F = fun(FF,N) ->
- ets:insert(T,{{X1,X2,N},
- X1, X2, N}),
- case N of
+ ets:insert(T,{{X1,X2,N}, X1, X2, N}),
+ case N of
0 ->
ok;
_ ->
@@ -4424,16 +4419,14 @@ 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) ->
lists:foreach(
fun(X2) ->
F = fun(FF,N) ->
- ets:insert(T,{{N,X1,X2},
- N, X1, X2}),
- case N of
+ ets:insert(T,{{N,X1,X2}, N, X1, X2}),
+ case N of
0 ->
ok;
_ ->
@@ -4724,7 +4717,7 @@ del_one_by_one_dbag_3(T,From,To) ->
N = (ets:info(T,size) + 1),
Obj2 = {From, integer_to_list(From)},
ets:delete_object(T,Obj2),
- N = (ets:info(T,size) + 2)
+ N = (ets:info(T,size) + 2)
end,
Next = if
From < To ->
@@ -4771,14 +4764,14 @@ gen_dets_filename(Config,N) ->
filename:join(proplists:get_value(priv_dir,Config),
"testdets_" ++ integer_to_list(N) ++ ".dets").
-otp_6842_select_1000(Config) when is_list(Config) ->
+otp_6842_select_1000(Config) when is_list(Config) ->
Tab = ets_new(xxx,[ordered_set]),
[ets:insert(Tab,{X,X}) || X <- lists:seq(1,10000)],
AllTrue = lists:duplicate(10,true),
AllTrue =
[ length(
element(1,
- ets:select(Tab,[{'_',[],['$_']}],X*1000))) =:=
+ ets:select(Tab,[{'_',[],['$_']}],X*1000))) =:=
X*1000 || X <- lists:seq(1,10) ],
Sequences = [[1000,1000,1000,1000,1000,1000,1000,1000,1000,1000],
[2000,2000,2000,2000,2000],
@@ -4804,7 +4797,13 @@ check_seq(A,B,C) ->
false.
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>>),
+ 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]),
lists:foreach(fun(X) -> ets:insert(T,X) end,L),
[[4839,recv]] = ets:match(T,{[{sbm,ppb2_bs12@blade_0_8},'$1'],'$2'}),
@@ -4823,7 +4822,7 @@ otp_5340_do(Opts) ->
ets:delete(T).
w(_,0, _) -> ok;
-w(T,N, Id) ->
+w(T,N, Id) ->
ets:insert(T, {N, Id}),
w(T,N-1,Id).
@@ -4913,7 +4912,7 @@ meta_wb_new(Name, _, Tabs, Opts) ->
case (catch ets_new(Name,[named_table|Opts])) of
Name ->
false = lists:member(Name, Tabs),
- [Name | Tabs];
+ [Name | Tabs];
{'EXIT',{badarg,_}} ->
true = lists:member(Name, Tabs),
Tabs
@@ -5088,7 +5087,7 @@ meta_lookup_unnamed_read(Config) when is_list(Config) ->
Tab
end,
ExecF = fun(Tab) -> [{key,data}] = ets:lookup(Tab,key),
- Tab
+ Tab
end,
FiniF = fun(Tab) -> true = ets:delete(Tab)
end,
@@ -5112,7 +5111,7 @@ meta_lookup_named_read(Config) when is_list(Config) ->
Tab
end,
ExecF = fun(Tab) -> [{key,data}] = ets:lookup(Tab,key),
- Tab
+ Tab
end,
FiniF = fun(Tab) -> true = ets:delete(Tab)
end,
@@ -5171,9 +5170,9 @@ smp_fixed_delete_do() ->
ets:safe_fixtable(T,true),
Buckets = num_of_buckets(T),
InitF = fun([ProcN,NumOfProcs|_]) -> {ProcN,NumOfProcs} end,
- ExecF = fun({Key,_}) when Key > NumOfObjs ->
+ ExecF = fun({Key,_}) when Key > NumOfObjs ->
[end_of_work];
- ({Key,Increment}) ->
+ ({Key,Increment}) ->
true = ets:delete(T,Key),
{Key+Increment,Increment}
end,
@@ -5202,7 +5201,7 @@ smp_unfix_fix_do() ->
T = ets_new(foo,[public,{write_concurrency,true}]),
%%Mem = ets:info(T,memory),
NumOfObjs = 100000,
- Deleted = 50000,
+ Deleted = 50000,
filltabint(T,NumOfObjs),
ets:safe_fixtable(T,true),
Buckets = num_of_buckets(T),
@@ -5215,7 +5214,7 @@ smp_unfix_fix_do() ->
true = ets:info(T,fixed),
Deleted = get_kept_objects(T),
- {Child, Mref} =
+ {Child, Mref} =
my_spawn_opt(
fun()->
true = ets:info(T,fixed),
@@ -5274,22 +5273,19 @@ otp_8166_do(WC) ->
NumOfObjs = 3000, %% Need more than 1000 live objects for match_object to trap one time
Deleted = NumOfObjs div 2,
filltabint(T,NumOfObjs),
- {ReaderPid, ReaderMref} =
- my_spawn_opt(fun()-> otp_8166_reader(T,NumOfObjs) end,
- [link, monitor, {scheduler,2}]),
- {ZombieCrPid, ZombieCrMref} =
- my_spawn_opt(fun()-> otp_8166_zombie_creator(T,Deleted) end,
- [link, monitor, {scheduler,3}]),
+ {ReaderPid, ReaderMref} = my_spawn_opt(fun()-> otp_8166_reader(T,NumOfObjs) end,
+ [link, monitor, {scheduler,2}]),
+ {ZombieCrPid, ZombieCrMref} = my_spawn_opt(fun()-> otp_8166_zombie_creator(T,Deleted) end,
+ [link, monitor, {scheduler,3}]),
repeat(fun() -> ZombieCrPid ! {loop, self()},
zombies_created = receive_any(),
otp_8166_trapper(T, 10, ZombieCrPid)
- end,
- 100),
+ end, 100),
ReaderPid ! quit,
{'DOWN', ReaderMref, process, ReaderPid, normal} = receive_any(),
- ZombieCrPid ! quit,
+ ZombieCrPid ! quit,
{'DOWN', ZombieCrMref, process, ZombieCrPid, normal} = receive_any(),
false = ets:info(T,fixed),
0 = get_kept_objects(T),
@@ -5299,7 +5295,7 @@ otp_8166_do(WC) ->
%% Keep reading the table
otp_8166_reader(T, NumOfObjs) ->
- repeat_while(fun(0) ->
+ repeat_while(fun(0) ->
receive quit -> {false,done}
after 0 -> {true,NumOfObjs}
end;
@@ -5313,14 +5309,14 @@ otp_8166_reader(T, NumOfObjs) ->
otp_8166_trapper(T, Try, ZombieCrPid) ->
[] = ets:match_object(T,{'_',"Pink Unicorn"}),
case {ets:info(T,fixed),Try} of
- {true,1} ->
+ {true,1} ->
io:format("failed to provoke unsafe unfix, give up...\n",[]),
ZombieCrPid ! unfix;
- {true,_} ->
+ {true,_} ->
io:format("trapper too fast, trying again...\n",[]),
otp_8166_trapper(T, Try-1, ZombieCrPid);
{false,_} -> done
- end.
+ end.
%% Fixate table and create some pseudo-deleted objects (zombies)
@@ -5340,7 +5336,7 @@ otp_8166_zombie_creator(T,Deleted) ->
repeat_while(fun() -> case ets:info(T,safe_fixed_monotonic_time) of
{_,[_P1,_P2]} ->
false;
- _ ->
+ _ ->
receive unfix -> false
after 0 -> true
end
@@ -5397,7 +5393,7 @@ smp_select_delete(Config) when is_list(Config) ->
Mod = 17,
Zeros = erlang:make_tuple(Mod,0),
InitF = fun(_) -> Zeros end,
- ExecF = fun(Diffs0) ->
+ ExecF = fun(Diffs0) ->
case rand:uniform(20) of
1 ->
Mod = 17,
@@ -5419,7 +5415,7 @@ smp_select_delete(Config) when is_list(Config) ->
Diffs1;
false -> Diffs0
end
- end
+ end
end,
FiniF = fun(Result) -> Result end,
Results = run_workers_do(InitF,ExecF,FiniF,20000),
@@ -5430,7 +5426,7 @@ smp_select_delete(Config) when is_list(Config) ->
0, TotCnts),
io:format("LeftInTab = ~p\n",[LeftInTab]),
LeftInTab = ets:info(T,size),
- lists:foldl(fun(Cnt,Eq) ->
+ lists:foldl(fun(Cnt,Eq) ->
WasCnt = ets:select_count(T,
[{{'_', '$1'},
[{'=:=', {'rem', '$1', Mod}, Eq}],
@@ -5438,7 +5434,7 @@ smp_select_delete(Config) when is_list(Config) ->
io:format("~p: ~p =?= ~p\n",[Eq,Cnt,WasCnt]),
Cnt = WasCnt,
Eq+1
- end,
+ end,
0, TotCnts),
%% May fail as select_delete does not shrink table (enough)
%%verify_table_load(T),
@@ -5477,8 +5473,8 @@ types_do(Opts) ->
%% OTP-9932: Memory overwrite when inserting large integers in compressed bag.
%% Will crash with segv on 64-bit opt if not fixed.
otp_9932(Config) when is_list(Config) ->
- T = ets:new(xxx, [bag, compressed]),
- Fun = fun(N) ->
+ T = ets:new(xxx, [bag, compressed]),
+ Fun = fun(N) ->
Key = {1316110174588445 bsl N,1316110174588583 bsl N},
S = {Key, Key},
true = ets:insert(T, S),
@@ -5494,9 +5490,9 @@ otp_9932(Config) when is_list(Config) ->
%% write_concurrency table.
otp_9423(Config) when is_list(Config) ->
InitF = fun(_) -> {0,0} end,
- ExecF = fun({S,F}) ->
- receive
- stop ->
+ ExecF = fun({S,F}) ->
+ receive
+ stop ->
io:format("~p got stop\n", [self()]),
[end_of_work | {"Succeded=",S,"Failed=",F}]
after 0 ->
@@ -5592,12 +5588,12 @@ take(Config) when is_list(Config) ->
%% Utility functions:
%%
-add_lists(L1,L2) ->
+add_lists(L1,L2) ->
add_lists(L1,L2,[]).
add_lists([],[],Acc) ->
lists:reverse(Acc);
add_lists([E1|T1], [E2|T2], Acc) ->
- add_lists(T1, T2, [E1+E2 | Acc]).
+ add_lists(T1, T2, [E1+E2 | Acc]).
run_workers(InitF,ExecF,FiniF,Laps) ->
run_workers(InitF,ExecF,FiniF,Laps, 0).
@@ -5643,9 +5639,9 @@ worker_loop(infinite, ExecF, State) ->
worker_loop(N, ExecF, State) ->
worker_loop(N-1,ExecF,ExecF(State)).
-wait_pids(Pids) ->
+wait_pids(Pids) ->
wait_pids(Pids,[]).
-wait_pids([],Acc) ->
+wait_pids([],Acc) ->
Acc;
wait_pids(Pids, Acc) ->
receive
@@ -5682,7 +5678,7 @@ etsmem() ->
wait_for_memory_deallocations(),
AllTabs = lists:map(fun(T) -> {T,ets:info(T,name),ets:info(T,size),
- ets:info(T,memory),ets:info(T,type)}
+ ets:info(T,memory),ets:info(T,type)}
end, ets:all()),
EtsAllocInfo = erlang:system_info({allocator,ets_alloc}),
@@ -5912,7 +5908,7 @@ receive_any() ->
receive_any_spinning() ->
receive_any_spinning(1000000).
receive_any_spinning(Loops) ->
- receive_any_spinning(Loops,Loops,1).
+ receive_any_spinning(Loops,Loops,1).
receive_any_spinning(Loops,0,Tries) ->
receive M ->
io:format("Spinning process ~p got msg ~p after ~p tries\n", [self(),M,Tries]),
diff --git a/lib/stdlib/test/gen_statem_SUITE.erl b/lib/stdlib/test/gen_statem_SUITE.erl
index 28f9ab81fe..8f2ba0cab2 100644
--- a/lib/stdlib/test/gen_statem_SUITE.erl
+++ b/lib/stdlib/test/gen_statem_SUITE.erl
@@ -505,10 +505,10 @@ abnormal2(Config) ->
{ok,Pid} = gen_statem:start_link(?MODULE, start_arg(Config, []), []),
%% bad return value in the gen_statem loop
- {{bad_return_from_state_function,badreturn},_} =
+ {{{bad_return_from_state_function,badreturn},_},_} =
?EXPECT_FAILURE(gen_statem:call(Pid, badreturn), Reason),
receive
- {'EXIT',Pid,{bad_return_from_state_function,badreturn}} -> ok
+ {'EXIT',Pid,{{bad_return_from_state_function,badreturn},_}} -> ok
after 5000 ->
ct:fail(gen_statem_did_not_die)
end,
@@ -742,26 +742,40 @@ state_timeout(_Config) ->
%% Verify that {state_timeout,0,_}
%% comes after next_event and that
%% {timeout,0,_} is cancelled by
- %% {state_timeout,0,_}
+ %% pending {state_timeout,0,_}
{keep_state, {ok,2,Data},
[{timeout,0,3}]};
- (state_timeout, 2, {ok,2,{Time,From}}) ->
- {next_state, state3, 3,
+ (state_timeout, 2, {ok,2,Data}) ->
+ %% Verify that timeout 0's are processed
+ %% in order
+ {keep_state, {ok,3,Data},
+ [{timeout,0,4},{state_timeout,0,5}]};
+ (timeout, 4, {ok,3,Data}) ->
+ %% Verify that timeout 0 is cancelled by
+ %% enqueued state_timeout 0 and that
+ %% multiple state_timeout 0 can be enqueued
+ {keep_state, {ok,4,Data},
+ [{state_timeout,0,6},{timeout,0,7}]};
+ (state_timeout, 5, {ok,4,Data}) ->
+ {keep_state, {ok,5,Data}};
+ (state_timeout, 6, {ok,5,{Time,From}}) ->
+ {next_state, state3, 6,
[{reply,From,ok},
- {state_timeout,Time,3}]}
+ {state_timeout,Time,8}]}
end,
state3 =>
fun
- (info, message_to_self, 3) ->
- {keep_state, '3'};
- ({call,From}, check, '3') ->
+ (info, message_to_self, 6) ->
+ {keep_state, 7};
+ ({call,From}, check, 7) ->
{keep_state, From};
- (state_timeout, 3, From) ->
+ (state_timeout, 8, From) ->
{stop_and_reply, normal,
{reply,From,ok}}
end},
{ok,STM} = gen_statem:start_link(?MODULE, {map_statem,Machine,[]}, []),
+ sys:trace(STM, true),
TRef = erlang:start_timer(1000, self(), kull),
ok = gen_statem:call(STM, {go,500}),
ok = gen_statem:call(STM, check),
@@ -887,7 +901,7 @@ error_format_status(Config) ->
gen_statem:start(
?MODULE, start_arg(Config, {data,Data}), []),
%% bad return value in the gen_statem loop
- {{bad_return_from_state_function,badreturn},_} =
+ {{{bad_return_from_state_function,badreturn},_},_} =
?EXPECT_FAILURE(gen_statem:call(Pid, badreturn), Reason),
receive
{error,_,
diff --git a/lib/stdlib/test/proc_lib_SUITE.erl b/lib/stdlib/test/proc_lib_SUITE.erl
index 416650e27e..a53e99afc9 100644
--- a/lib/stdlib/test/proc_lib_SUITE.erl
+++ b/lib/stdlib/test/proc_lib_SUITE.erl
@@ -26,7 +26,7 @@
-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,
+ crash/1, stacktrace/1, sync_start_nolink/1, sync_start_link/1,
spawn_opt/1, sp1/0, sp2/0, sp3/1, sp4/2, sp5/1,
hibernate/1, stop/1, t_format/1]).
-export([ otp_6345/1, init_dont_hang/1]).
@@ -50,7 +50,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [crash, {group, sync_start}, spawn_opt, hibernate,
+ [crash, stacktrace, {group, sync_start}, spawn_opt, hibernate,
{group, tickets}, stop, t_format].
groups() ->
@@ -198,6 +198,31 @@ match_info(Tuple1, Tuple2) when tuple_size(Tuple1) =:= tuple_size(Tuple2) ->
match_info(_, _) ->
throw(no_match).
+stacktrace(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ %% Errors.
+ Pid1 = proc_lib:spawn_link(fun() -> 1 = 2 end),
+ receive
+ {'EXIT',Pid1,{{badmatch,2},_Stack1}} -> ok
+ after 500 ->
+ ct:fail(error)
+ end,
+ %% Exits.
+ Pid2 = proc_lib:spawn_link(fun() -> exit(bye) end),
+ receive
+ {'EXIT',Pid2,bye} -> ok
+ after 500 ->
+ ct:fail(exit)
+ end,
+ %% Throws.
+ Pid3 = proc_lib:spawn_link(fun() -> throw(ball) end),
+ receive
+ {'EXIT',Pid3,{{nocatch,ball},_Stack3}} -> ok
+ after 500 ->
+ ct:fail(throw)
+ end,
+ ok.
+
sync_start_nolink(Config) when is_list(Config) ->
_Pid = spawn_link(?MODULE, sp5, [self()]),
receive
@@ -457,7 +482,7 @@ stop(_Config) ->
%% System message is handled, but process dies with other reason
%% than the given (in system_terminate/4 below)
Pid5 = proc_lib:spawn(SysMsgProc),
- {'EXIT',{badmatch,2}} = (catch proc_lib:stop(Pid5,crash,infinity)),
+ {'EXIT',{{badmatch,2},_Stacktrace}} = (catch proc_lib:stop(Pid5,crash,infinity)),
false = erlang:is_process_alive(Pid5),
%% Local registered name
diff --git a/lib/stdlib/test/rand_SUITE.erl b/lib/stdlib/test/rand_SUITE.erl
index cb778c96d4..8e7ac223a7 100644
--- a/lib/stdlib/test/rand_SUITE.erl
+++ b/lib/stdlib/test/rand_SUITE.erl
@@ -18,13 +18,18 @@
%% %CopyrightEnd%
-module(rand_SUITE).
--export([all/0, suite/0,groups/0]).
+-compile({nowarn_deprecated_function,[{random,seed,1},
+ {random,uniform_s,1},
+ {random,uniform_s,2}]}).
+
+-export([all/0, suite/0, groups/0, group/1]).
-export([interval_int/1, interval_float/1, seed/1,
api_eq/1, reference/1,
basic_stats_uniform_1/1, basic_stats_uniform_2/1,
basic_stats_normal/1,
- plugin/1, measure/1]).
+ plugin/1, measure/1,
+ reference_jump_state/1, reference_jump_procdict/1]).
-export([test/0, gen/1]).
@@ -41,24 +46,35 @@ all() ->
api_eq,
reference,
{group, basic_stats},
- plugin, measure].
+ plugin, measure,
+ {group, reference_jump}
+ ].
groups() ->
[{basic_stats, [parallel],
- [basic_stats_uniform_1, basic_stats_uniform_2, basic_stats_normal]}].
+ [basic_stats_uniform_1, basic_stats_uniform_2, basic_stats_normal]},
+ {reference_jump, [parallel],
+ [reference_jump_state, reference_jump_procdict]}].
+
+group(basic_stats) ->
+ %% valgrind needs a lot of time
+ [{timetrap,{minutes,10}}];
+group(reference_jump) ->
+ %% valgrind needs a lot of time
+ [{timetrap,{minutes,10}}].
%% A simple helper to test without test_server during dev
test() ->
Tests = all(),
lists:foreach(fun(Test) ->
- try
- ok = ?MODULE:Test([]),
- io:format("~p: ok~n", [Test])
- catch _:Reason ->
- io:format("Failed: ~p: ~p ~p~n",
- [Test, Reason, erlang:get_stacktrace()])
- end
- end, Tests).
+ try
+ ok = ?MODULE:Test([]),
+ io:format("~p: ok~n", [Test])
+ catch _:Reason ->
+ io:format("Failed: ~p: ~p ~p~n",
+ [Test, Reason, erlang:get_stacktrace()])
+ end
+ end, Tests).
algs() ->
[exs64, exsplus, exs1024].
@@ -220,7 +236,7 @@ interval_float_1(N) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Check if exs64 algorithm generates the proper sequence.
+%% Check if each algorithm generates the proper sequence.
reference(Config) when is_list(Config) ->
[reference_1(Alg) || Alg <- algs()],
ok.
@@ -234,7 +250,7 @@ reference_1(Alg) ->
io:format("Failed: ~p~n",[Alg]),
io:format("Length ~p ~p~n",[length(Refval), length(Testval)]),
io:format("Head ~p ~p~n",[hd(Refval), hd(Testval)]),
- ok
+ exit(wrong_value)
end.
gen(Algo) ->
@@ -426,6 +442,112 @@ measure_2(N, State0, Fun) when N > 0 ->
measure_2(0, _, _) -> ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% The jump sequence tests has two parts
+%% for those with the functional API (jump/1)
+%% and for those with the internal state
+%% in process dictionary (jump/0).
+
+-define(LOOP_JUMP, (?LOOP div 1000)).
+
+%% Check if each algorithm generates the proper jump sequence
+%% with the functional API.
+reference_jump_state(Config) when is_list(Config) ->
+ [reference_jump_1(Alg) || Alg <- algs()],
+ ok.
+
+reference_jump_1(Alg) ->
+ Refval = reference_jump_val(Alg),
+ Testval = gen_jump_1(Alg),
+ case Refval =:= Testval of
+ true -> ok;
+ false ->
+ io:format("Failed: ~p~n",[Alg]),
+ io:format("Length ~p ~p~n",[length(Refval), length(Testval)]),
+ io:format("Head ~p ~p~n",[hd(Refval), hd(Testval)]),
+ exit(wrong_value)
+ end.
+
+gen_jump_1(Algo) ->
+ Seed = case Algo of
+ exsplus -> %% Printed with orig 'C' code and this seed
+ rand:seed_s({exsplus, [12345678|12345678]});
+ exs1024 -> %% Printed with orig 'C' code and this seed
+ rand:seed_s({exs1024, {lists:duplicate(16, 12345678), []}});
+ exs64 -> %% Test exception of not_implemented notice
+ try rand:jump(rand:seed_s(exs64))
+ catch
+ error:not_implemented -> not_implemented
+ end;
+ _ -> % unimplemented
+ not_implemented
+ end,
+ case Seed of
+ not_implemented -> [not_implemented];
+ S -> gen_jump_1(?LOOP_JUMP, S, [])
+ end.
+
+gen_jump_1(N, State0 = {#{max:=Max}, _}, Acc) when N > 0 ->
+ {_, State1} = rand:uniform_s(Max, State0),
+ {Random, State2} = rand:uniform_s(Max, rand:jump(State1)),
+ case N rem (?LOOP_JUMP div 100) of
+ 0 -> gen_jump_1(N-1, State2, [Random|Acc]);
+ _ -> gen_jump_1(N-1, State2, Acc)
+ end;
+gen_jump_1(_, _, Acc) -> lists:reverse(Acc).
+
+%% Check if each algorithm generates the proper jump sequence
+%% with the internal state in the process dictionary.
+reference_jump_procdict(Config) when is_list(Config) ->
+ [reference_jump_0(Alg) || Alg <- algs()],
+ ok.
+
+reference_jump_0(Alg) ->
+ Refval = reference_jump_val(Alg),
+ Testval = gen_jump_0(Alg),
+ case Refval =:= Testval of
+ true -> ok;
+ false ->
+ io:format("Failed: ~p~n",[Alg]),
+ io:format("Length ~p ~p~n",[length(Refval), length(Testval)]),
+ io:format("Head ~p ~p~n",[hd(Refval), hd(Testval)]),
+ exit(wrong_value)
+ end.
+
+gen_jump_0(Algo) ->
+ Seed = case Algo of
+ exsplus -> %% Printed with orig 'C' code and this seed
+ rand:seed({exsplus, [12345678|12345678]});
+ exs1024 -> %% Printed with orig 'C' code and this seed
+ rand:seed({exs1024, {lists:duplicate(16, 12345678), []}});
+ exs64 -> %% Test exception of not_implemented notice
+ try
+ _ = rand:seed(exs64),
+ rand:jump()
+ catch
+ error:not_implemented -> not_implemented
+ end;
+ _ -> % unimplemented
+ not_implemented
+ end,
+ case Seed of
+ not_implemented -> [not_implemented];
+ S ->
+ {Seedmap=#{}, _} = S,
+ Max = maps:get(max, Seedmap),
+ gen_jump_0(?LOOP_JUMP, Max, [])
+ end.
+
+gen_jump_0(N, Max, Acc) when N > 0 ->
+ _ = rand:uniform(Max),
+ _ = rand:jump(),
+ Random = rand:uniform(Max),
+ case N rem (?LOOP_JUMP div 100) of
+ 0 -> gen_jump_0(N-1, Max, [Random|Acc]);
+ _ -> gen_jump_0(N-1, Max, Acc)
+ end;
+gen_jump_0(_, _, Acc) -> lists:reverse(Acc).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Data
reference_val(exs64) ->
[16#3737ad0c703ff6c3,16#3868a78fe71adbbd,16#1f01b62b4338b605,16#50876a917437965f,
@@ -507,3 +629,61 @@ reference_val(exsplus) ->
16#36f715a249f4ec2,16#1c27629826c50d3,16#914d9a6648726a,16#27f5bf5ce2301e8,
16#3dd493b8012970f,16#be13bed1e00e5c,16#ceef033b74ae10,16#3da38c6a50abe03,
16#15cbd1a421c7a8c,16#22794e3ec6ef3b1,16#26154d26e7ea99f,16#3a66681359a6ab6].
+
+%%%
+
+reference_jump_val(exsplus) ->
+ [82445318862816932, 145810727464480743, 16514517716894509, 247642377064868650,
+ 162385642339156908, 251810707075252101, 82288275771998924, 234412731596926322,
+ 49960883129071044, 200690077681656596, 213743196668671647, 131182800982967108,
+ 144200072021941728, 263557425008503277, 194858522616874272, 185869394820993172,
+ 80384502675241453, 262654144824057588, 90033295011291362, 4494510449302659,
+ 226005372746479588, 116780561309220553, 47048528594475843, 39168929349768743,
+ 139615163424415552, 55330632656603925, 237575574720486569, 102381140288455025,
+ 18452933910354323, 150248612130579752, 269358096791922740, 61313433522002187,
+ 160327361842676597, 185187983548528938, 57378981505594193, 167510799293984067,
+ 105117045862954303, 176126685946302943, 123590876906828803, 69185336947273487,
+ 9098689247665808, 49906154674145057, 131575138412788650, 161843880211677185,
+ 30743946051071186, 187578920583823612, 45008401528636978, 122454158686456658,
+ 111195992644229524, 17962783958752862, 13579507636941108, 130137843317798663,
+ 144202635170576832, 132539563255093922, 159785575703967124, 187241848364816640,
+ 183044737781926478, 12921559769912263, 83553932242922001, 96698298841984688,
+ 281664320227537824, 224233030818578263, 77812932110318774, 169729351013291728,
+ 164475402723178734, 242780633011249051, 51095111179609125, 19249189591963554,
+ 221412426221439180, 265700202856282653, 265342254311932308, 241218503498385511,
+ 255400887248486575, 212083616929812076, 227947034485840579, 268261881651571692,
+ 104846262373404908, 49690734329496661, 213259196633566308, 186966479726202436,
+ 282157378232384574, 11272948584603747, 166540426999573480, 50628164001018755,
+ 65235580992800860, 230664399047956956, 64575592354687978, 40519393736078511,
+ 108341851194332747, 115426411532008961, 120656817002338193, 234537867870809797,
+ 12504080415362731, 45083100453836317, 270968267812126657, 93505647407734103,
+ 252852934678537969, 258758309277167202, 74250882143432077, 141629095984552833];
+
+reference_jump_val(exs1024) ->
+ [2655961906500790629, 17003395417078685063, 10466831598958356428, 7603399148503548021,
+ 1650550950190587188, 12294992315080723704, 15743995773860389219, 5492181000145247327,
+ 14118165228742583601, 1024386975263610703, 10124872895886669513, 6445624517813169301,
+ 6238575554686562601, 14108646153524288915, 11804141635807832816, 8421575378006186238,
+ 6354993374304550369, 838493020029548163, 14759355804308819469, 12212491527912522022,
+ 16943204735100571602, 198964074252287588, 7325922870779721649, 15853102065526570574,
+ 16294058349151823341, 6153379962047409781, 15874031679495957261, 17299265255608442340,
+ 984658421210027171, 17408042033939375278, 3326465916992232353, 5222817718770538733,
+ 13262385796795170510, 15648751121811336061, 6718721549566546451, 7353765235619801875,
+ 16110995049882478788, 14559143407227563441, 4189805181268804683, 10938587948346538224,
+ 1635025506014383478, 12619562911869525411, 17469465615861488695, 125252234176411528,
+ 2004192558503448853, 13175467866790974840, 17712272336167363518, 1710549840100880318,
+ 17486892343528340916, 5337910082227550967, 8333082060923612691, 6284787745504163856,
+ 8072221024586708290, 6077032673910717705, 11495200863352251610, 11722792537523099594,
+ 14642059504258647996, 8595733246938141113, 17223366528010341891, 17447739753327015776,
+ 6149800490736735996, 11155866914574313276, 7123864553063709909, 15982886296520662323,
+ 5775920250955521517, 8624640108274906072, 8652974210855988961, 8715770416136907275,
+ 11841689528820039868, 10991309078149220415, 11758038663970841716, 7308750055935299261,
+ 15939068400245256963, 6920341533033919644, 8017706063646646166, 15814376391419160498,
+ 13529376573221932937, 16749061963269842448, 14639730709921425830, 3265850480169354066,
+ 4569394597532719321, 16594515239012200038, 13372824240764466517, 16892840440503406128,
+ 11260004846380394643, 2441660009097834955, 10566922722880085440, 11463315545387550692,
+ 5252492021914937692, 10404636333478845345, 11109538423683960387, 5525267334484537655,
+ 17936751184378118743, 4224632875737239207, 15888641556987476199, 9586888813112229805,
+ 9476861567287505094, 14909536929239540332, 17996844556292992842, 2699310519182298856];
+
+reference_jump_val(exs64) -> [not_implemented].
diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl
index 64dd41e75a..6f3979bb77 100644
--- a/lib/stdlib/test/tar_SUITE.erl
+++ b/lib/stdlib/test/tar_SUITE.erl
@@ -720,20 +720,25 @@ memory(Config) when is_list(Config) ->
%% Test filenames with characters outside the US ASCII range.
unicode(Config) when is_list(Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- do_unicode(PrivDir),
+ run_unicode_node(Config, "+fnu"),
case has_transparent_naming() of
true ->
- Pa = filename:dirname(code:which(?MODULE)),
- Node = start_node(unicode, "+fnl -pa "++Pa),
- ok = rpc:call(Node, erlang, apply,
- [fun() -> do_unicode(PrivDir) end,[]]),
- true = test_server:stop_node(Node),
- ok;
+ run_unicode_node(Config, "+fnl");
false ->
ok
end.
+run_unicode_node(Config, Option) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Pa = filename:dirname(code:which(?MODULE)),
+ Args = Option ++ " -pa "++Pa,
+ io:format("~s\n", [Args]),
+ Node = start_node(unicode, Args),
+ ok = rpc:call(Node, erlang, apply,
+ [fun() -> do_unicode(PrivDir) end,[]]),
+ true = test_server:stop_node(Node),
+ ok.
+
has_transparent_naming() ->
case os:type() of
{unix,darwin} -> false;
@@ -745,10 +750,11 @@ do_unicode(PrivDir) ->
ok = file:set_cwd(PrivDir),
ok = file:make_dir("unicöde"),
- Names = unicode_create_files(),
+ Names = lists:sort(unicode_create_files()),
Tar = "unicöde.tar",
ok = erl_tar:create(Tar, ["unicöde"], []),
- {ok,Names} = erl_tar:table(Tar, []),
+ {ok,Names0} = erl_tar:table(Tar, []),
+ Names = lists:sort(Names0),
_ = [ok = file:delete(Name) || Name <- Names],
ok = erl_tar:extract(Tar),
_ = [{ok,_} = file:read_file(Name) || Name <- Names],
diff --git a/lib/syntax_tools/AUTHORS b/lib/syntax_tools/AUTHORS
deleted file mode 100644
index 0212787b30..0000000000
--- a/lib/syntax_tools/AUTHORS
+++ /dev/null
@@ -1,2 +0,0 @@
-Original Authors and Contributors:
-
diff --git a/lib/syntax_tools/COPYING b/lib/syntax_tools/COPYING
deleted file mode 100644
index 223ede7de3..0000000000
--- a/lib/syntax_tools/COPYING
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/lib/syntax_tools/src/epp_dodger.erl b/lib/syntax_tools/src/epp_dodger.erl
index 39c522fd11..cf1ba0abfa 100644
--- a/lib/syntax_tools/src/epp_dodger.erl
+++ b/lib/syntax_tools/src/epp_dodger.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2001-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/syntax_tools/src/erl_comment_scan.erl b/lib/syntax_tools/src/erl_comment_scan.erl
index b5ac564146..a7a2c10b79 100644
--- a/lib/syntax_tools/src/erl_comment_scan.erl
+++ b/lib/syntax_tools/src/erl_comment_scan.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% =====================================================================
%% @copyright 1997-2006 Richard Carlsson
diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl
index df0d78031c..378d69095d 100644
--- a/lib/syntax_tools/src/erl_prettypr.erl
+++ b/lib/syntax_tools/src/erl_prettypr.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1997-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/syntax_tools/src/erl_recomment.erl b/lib/syntax_tools/src/erl_recomment.erl
index 1d23034991..4d9aaf4eed 100644
--- a/lib/syntax_tools/src/erl_recomment.erl
+++ b/lib/syntax_tools/src/erl_recomment.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1997-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index ee42e56172..4347cc46c1 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1997-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/syntax_tools/src/erl_syntax_lib.erl b/lib/syntax_tools/src/erl_syntax_lib.erl
index 5aecf5d774..c7f477c4d2 100644
--- a/lib/syntax_tools/src/erl_syntax_lib.erl
+++ b/lib/syntax_tools/src/erl_syntax_lib.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1997-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/syntax_tools/src/erl_tidy.erl b/lib/syntax_tools/src/erl_tidy.erl
index 9e273dfb84..1ca60ea73b 100644
--- a/lib/syntax_tools/src/erl_tidy.erl
+++ b/lib/syntax_tools/src/erl_tidy.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or
-%% modify it under the terms of the GNU Lesser General Public License
-%% as published by the Free Software Foundation; either version 2 of
-%% the License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1999-2014 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/syntax_tools/src/igor.erl b/lib/syntax_tools/src/igor.erl
index 943250e5cd..72170ec5da 100644
--- a/lib/syntax_tools/src/igor.erl
+++ b/lib/syntax_tools/src/igor.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
-%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
-%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 1998-2014 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/syntax_tools/src/merl.erl b/lib/syntax_tools/src/merl.erl
index 163ce48bbc..d6cf208998 100644
--- a/lib/syntax_tools/src/merl.erl
+++ b/lib/syntax_tools/src/merl.erl
@@ -9,6 +9,16 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
+%%
%% Note: EDoc uses @@ and @} as escape sequences, so in the doc text below,
%% `@@' must be written `@@@@' and `@}' must be written `@@}'.
%%
diff --git a/lib/syntax_tools/src/merl_tests.erl b/lib/syntax_tools/src/merl_tests.erl
index 27db594050..61efc6935e 100644
--- a/lib/syntax_tools/src/merl_tests.erl
+++ b/lib/syntax_tools/src/merl_tests.erl
@@ -9,6 +9,16 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
+%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2012-2015 Richard Carlsson
%% @doc Unit tests for merl.
diff --git a/lib/syntax_tools/src/merl_transform.erl b/lib/syntax_tools/src/merl_transform.erl
index 497baddd0a..b298bc407f 100644
--- a/lib/syntax_tools/src/merl_transform.erl
+++ b/lib/syntax_tools/src/merl_transform.erl
@@ -9,6 +9,16 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
+%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2012-2015 Richard Carlsson
%% @doc Parse transform for merl. Enables the use of automatic metavariables
diff --git a/lib/syntax_tools/src/prettypr.erl b/lib/syntax_tools/src/prettypr.erl
index 1b5ba6b05a..61a8993b84 100644
--- a/lib/syntax_tools/src/prettypr.erl
+++ b/lib/syntax_tools/src/prettypr.erl
@@ -1,18 +1,23 @@
%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
%%
%% @copyright 2000-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/syntax_tools/syntax_tools.pub b/lib/syntax_tools/syntax_tools.pub
deleted file mode 100644
index 6d69b31818..0000000000
--- a/lib/syntax_tools/syntax_tools.pub
+++ /dev/null
@@ -1,13 +0,0 @@
-{name, "syntax_tools"}.
-{vsn, {1,3}}.
-{summary, "A set of modules for working with Erlang source code."}.
-{author, "Richard Carlsson", "[email protected]", "031124"}.
-{keywords, ["source code", "syntax", "syntax trees", "erl_parse",
- "pretty printing", "comments", "tidying"]}.
-{needs, []}.
-{abstract, "This package defines an abstract datatype that is\n"
- "compatible with the `erl_parse' data structures, and\n"
- "provides modules for analysis and manipulation,\n"
- "flexible pretty printing, and preservation of source-code\n"
- "comments. Also includes `erl_tidy': automatic code tidying\n"
- "and checking."}.
diff --git a/lib/syntax_tools/test/syntax_tools_SUITE.erl b/lib/syntax_tools/test/syntax_tools_SUITE.erl
index 43c17e9f1f..868f43b8ee 100644
--- a/lib/syntax_tools/test/syntax_tools_SUITE.erl
+++ b/lib/syntax_tools/test/syntax_tools_SUITE.erl
@@ -9,13 +9,11 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
+%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
%% AB. All Rights Reserved.''
-%%
-%% $Id$
-%%
+
-module(syntax_tools_SUITE).
-include_lib("common_test/include/ct.hrl").
diff --git a/lib/tools/emacs/Makefile b/lib/tools/emacs/Makefile
index e1b195ef97..35c93ba4ed 100644
--- a/lib/tools/emacs/Makefile
+++ b/lib/tools/emacs/Makefile
@@ -38,6 +38,7 @@ MAN_FILES= \
tags.3
EMACS_FILES= \
+ erldoc \
erlang-skels \
erlang-skels-old \
erlang_appwiz \
diff --git a/lib/tools/emacs/erlang-edoc.el b/lib/tools/emacs/erlang-edoc.el
index 034036ad04..2801aa8ae7 100644
--- a/lib/tools/emacs/erlang-edoc.el
+++ b/lib/tools/emacs/erlang-edoc.el
@@ -78,7 +78,7 @@
'(("^%+\\s-*\\(@\\w+\\)\\_>" 1 'erlang-edoc-tag prepend)
("^%+\\s-*" ("{\\(@\\w+\\)\\_>" nil nil (1 'erlang-edoc-macro prepend)))
("^%+\\s-*" ("\\(?:@@\\)*\\(@[@{}]\\)" nil nil (1 'escape-glyph prepend)))
- ("^%+\\s-*@\\(deprecated\\)\\_>" 1 font-lock-warning-face prepend)
+ ("^%+\\s-*\\(@deprecated\\)\\_>" 1 font-lock-warning-face prepend)
;; http://www.erlang.org/doc/apps/edoc/chapter.html#Wiki_notation
("^%+\\s-*" ("[^`]`\\([^`]?\\|[^`].*?[^']\\)'"
(forward-char -1) nil (1 'erlang-edoc-verbatim prepend)))
diff --git a/lib/tools/emacs/erlang-start.el b/lib/tools/emacs/erlang-start.el
index f9a6d24b2c..160057e179 100644
--- a/lib/tools/emacs/erlang-start.el
+++ b/lib/tools/emacs/erlang-start.el
@@ -78,9 +78,23 @@
(autoload 'erlang-find-tag-other-window "erlang"
"Like `find-tag-other-window'. Capable of retreiving Erlang modules.")
+;;
+;; Declare functions in "erlang-edoc.el".
+;;
+
(autoload 'erlang-edoc-mode "erlang-edoc" "Toggle Erlang-Edoc mode on or off." t)
;;
+;; Declare functions in "erldoc.el".
+;;
+
+(autoload 'erldoc-browse "erldoc" "\n\n(fn MFA)" t nil)
+(autoload 'erldoc-browse-topic "erldoc" "\n\n(fn TOPIC)" t nil)
+(autoload 'erldoc-apropos "erldoc" "\n\n(fn PATTERN)" t nil)
+(autoload 'erldoc-eldoc-function "erldoc" "\
+A function suitable for `eldoc-documentation-function'.\n\n(fn)" nil nil)
+
+;;
;; Associate files extensions ".erl" and ".hrl" with Erlang mode.
;;
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index 2bde21dbed..51f7e8e26c 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -479,6 +479,11 @@ To activate the workaround, place the following in your `~/.emacs' file:
"*Indentation of Erlang calls/clauses within blocks.")
(put 'erlang-indent-level 'safe-local-variable 'integerp)
+(defvar erlang-icr-indent nil
+ "*Indentation of Erlang if/case/receive/ patterns. `nil' means
+ keeping default behavior. When non-nil, indent to th column of
+ if/case/receive.")
+
(defvar erlang-indent-guard 2
"*Indentation of Erlang guards.")
(put 'erlang-indent-guard 'safe-local-variable 'integerp)
@@ -1442,6 +1447,11 @@ Other commands:
(erlang-skel-init)
(when (fboundp 'tempo-use-tag-list)
(tempo-use-tag-list 'erlang-tempo-tags))
+ (when (and (fboundp 'add-function) (fboundp 'erldoc-eldoc-function))
+ (or eldoc-documentation-function
+ (setq-local eldoc-documentation-function #'ignore))
+ (add-function :before-until (local 'eldoc-documentation-function)
+ #'erldoc-eldoc-function))
(run-hooks 'erlang-mode-hook)
(if (zerop (buffer-size))
(run-hooks 'erlang-new-file-hook)))
@@ -2916,14 +2926,16 @@ Return nil if inside string, t if in a comment."
(t
(save-excursion
(goto-char (nth 1 stack-top))
- (if (looking-at "case[^_a-zA-Z0-9]")
- (+ (nth 2 stack-top) erlang-indent-level)
- (skip-chars-forward "a-z")
- (skip-chars-forward " \t")
- (if (memq (following-char) '(?% ?\n))
+ (if (and erlang-icr-indent
+ (looking-at "\\(if\\|case\\|receive\\)[^_a-zA-Z0-9]"))
+ (+ (nth 2 stack-top) erlang-icr-indent)
+ (if (looking-at "\\(case\\|receive\\)[^_a-zA-Z0-9]")
(+ (nth 2 stack-top) erlang-indent-level)
- (current-column))))))
- )
+ (skip-chars-forward "a-z")
+ (skip-chars-forward " \t")
+ (if (memq (following-char) '(?% ?\n))
+ (+ (nth 2 stack-top) erlang-indent-level)
+ (current-column))))))))
((and (eq (car stack-top) '||) (looking-at "\\(]\\|>>\\)[^_a-zA-Z0-9]"))
(nth 2 (car (cdr stack))))
;; Real indentation, where operators create extra indentation etc.
@@ -2945,7 +2957,9 @@ Return nil if inside string, t if in a comment."
;; If in fun definition use standard indent level not double
;;(if (not (eq (car (car (cdr stack))) 'fun))
;; Removed it made multi clause fun's look to bad
- (setq off (* 2 erlang-indent-level)))) ;; )
+ (setq off (+ erlang-indent-level (if (not erlang-icr-indent)
+ erlang-indent-level
+ erlang-icr-indent)))))
(let ((base (erlang-indent-find-base stack indent-point off skip)))
;; Special cases
(goto-char indent-point)
diff --git a/lib/tools/emacs/erldoc.el b/lib/tools/emacs/erldoc.el
new file mode 100644
index 0000000000..cb355374d9
--- /dev/null
+++ b/lib/tools/emacs/erldoc.el
@@ -0,0 +1,508 @@
+;;; erldoc.el --- browse Erlang/OTP documentation -*- lexical-binding: t; -*-
+
+;; %CopyrightBegin%
+;;
+;; Copyright Ericsson AB 2016. All Rights Reserved.
+;;
+;; Licensed under the Apache License, Version 2.0 (the "License");
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
+;;
+;; http://www.apache.org/licenses/LICENSE-2.0
+;;
+;; Unless required by applicable law or agreed to in writing, software
+;; distributed under the License is distributed on an "AS IS" BASIS,
+;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;; See the License for the specific language governing permissions and
+;; limitations under the License.
+;;
+;; %CopyrightEnd%
+
+;;; Commentary:
+
+;; Crawl Erlang/OTP HTML documentation and generate lookup tables.
+;;
+;; This package depends on `cl-lib', `pcase' and
+;; `libxml-parse-html-region'; emacs 24+ compiled with libxml2 should
+;; work. On emacs 24.1 and 24.2 do `M-x package-install RET cl-lib
+;; RET' to install `cl-lib'.
+;;
+;; Please customise `erldoc-man-index' to point to your local OTP
+;; documentation.
+;;
+;; To use:
+;;
+;; (define-key help-map "u" 'erldoc-browse)
+;; (define-key help-map "t" 'erldoc-browse-topic)
+;; (define-key help-map "a" 'erldoc-apropos)
+;;
+;; Note: these commands trigger indexing OTP documentation on first
+;; run with cache to disk which may take 1-2 minutes.
+
+
+;;; Examples:
+
+;; 1. `M-x erldoc-browse RET erlang:integer_to_binary/2 RET' opens the
+;; `erlang' manual anchored on the entry for `integer_to_binary/2'.
+;;
+;; 2. `M-x erldoc-apropos RET first RET' list all MFAs matching
+;; substring `first'.
+;;
+;; 3. `M-x erldoc-browse-topic RET efficiency_guide#Introduction RET'
+;; opens chapter `Introduction' of the `Efficiency Guide' in the
+;; browser.
+
+;;; History:
+
+;; Written in December 2013 as a temporary solution to help me browse
+;; the rich Erlang/OTP documentation. Three years on I find myself
+;; still using it every day. - Leo (2016)
+
+;;; Code:
+
+(eval-when-compile (require 'url-parse))
+(require 'cl-lib)
+(require 'erlang)
+
+(eval-and-compile ;for emacs < 24.3
+ (or (fboundp 'user-error) (defalias 'user-error 'error)))
+
+(defgroup erldoc nil
+ "Browse Erlang document."
+ :group 'help)
+
+(defcustom erldoc-man-index "http://www.erlang.org/doc/man_index.html"
+ "The URL to the man_index.html page.
+Note it is advisable to customise this to a local URL for example
+`file:///usr/local/19.1/lib/erlang/doc/man_index.html' to speed
+up the indexing."
+ :type 'string
+ :group 'erldoc)
+
+(defcustom erldoc-verify-man-path nil
+ "If non-nil verify man path existence for `file://'."
+ :type 'boolean
+ :group 'erldoc)
+
+(defcustom erldoc-output-file (locate-user-emacs-file "cache/erldoc")
+ "File to store the parsed results."
+ :type 'file
+ :group 'erldoc)
+
+(defun erldoc-strip-string (s)
+ (let* ((re "[ \t\n\r\f\v\u00a0]+")
+ (from (if (string-match (concat "\\`" re) s) (match-end 0) 0))
+ (to (and (string-match (concat re "\\'") s) (match-beginning 0))))
+ (substring s from (and to (max to from)))))
+
+;; Note: don't know how to get the BASE-URL to
+;; `libxml-parse-html-region' to work.
+(defun erldoc-expand-url (url base-url)
+ (if (url-type (url-generic-parse-url url))
+ url
+ (let* ((base (url-generic-parse-url base-url))
+ (dir (directory-file-name (file-name-directory (url-filename base)))))
+ (setf (url-filename base) (expand-file-name url dir))
+ (url-recreate-url base))))
+
+(defun erldoc-parse-html (url)
+ (with-temp-buffer
+ (url-insert-file-contents url)
+ (libxml-parse-html-region (point-min) (point-max))))
+
+(defalias 'erldoc-dom-text-node-p #'stringp)
+
+(defun erldoc-dom-attributes (dom)
+ (and (not (erldoc-dom-text-node-p dom)) (cadr dom)))
+
+(defun erldoc-dom-get-attribute (dom attrib-name)
+ (cdr (assq attrib-name (erldoc-dom-attributes dom))))
+
+(defun erldoc-dom-children (dom)
+ (and (not (erldoc-dom-text-node-p dom)) (cddr dom)))
+
+(defun erldoc-dom-get-text (dom)
+ (let ((text (car (last (erldoc-dom-children dom)))))
+ (and (erldoc-dom-text-node-p text) text)))
+
+(defvar erldoc-dom-walk-parent nil)
+(defvar erldoc-dom-walk-siblings nil)
+
+(defun erldoc-dom-walk (dom k)
+ (funcall k dom)
+ (let ((erldoc-dom-walk-parent dom)
+ (erldoc-dom-walk-siblings (unless (erldoc-dom-text-node-p dom)
+ (cddr dom))))
+ (dolist (child erldoc-dom-walk-siblings)
+ (erldoc-dom-walk child k))))
+
+(defun erldoc-dom-get-element (dom element-name)
+ (catch 'return
+ (erldoc-dom-walk dom (lambda (d)
+ (when (eq (car-safe d) element-name)
+ (throw 'return d))))))
+
+(defun erldoc-dom-get-element-by-id (dom id)
+ (catch 'return
+ (erldoc-dom-walk dom (lambda (d)
+ (when (equal (erldoc-dom-get-attribute d 'id) id)
+ (throw 'return d))))))
+
+(defun erldoc-dom-get-elements-by-id (dom id)
+ (let (result)
+ (erldoc-dom-walk dom (lambda (d)
+ (when (equal (erldoc-dom-get-attribute d 'id) id)
+ (push d result))))
+ (nreverse result)))
+
+(defun erldoc-fix-path (url)
+ (if (and erldoc-verify-man-path
+ ;; Could only verify local files
+ (equal (url-type (url-generic-parse-url url)) "file"))
+ (let* ((obj (url-generic-parse-url url))
+ (new (car (file-expand-wildcards
+ (replace-regexp-in-string
+ "-[0-9]+\\(?:[.][0-9]+\\)*" "*"
+ (url-filename obj))))))
+ (or new (error "File %s does not exist" (url-filename obj)))
+ (setf (url-filename obj) new)
+ (url-recreate-url obj))
+ url))
+
+(defun erldoc-parse-man-index (url)
+ (let ((table (erldoc-dom-get-element (erldoc-parse-html url) 'table))
+ (mans))
+ (erldoc-dom-walk
+ table
+ (lambda (d)
+ (when (eq (car-safe d) 'a)
+ (let ((href (erldoc-dom-get-attribute d 'href)))
+ (when (and href (not (string-match-p "index\\.html\\'" href)))
+ (with-demoted-errors "erldoc-parse-man-index: %S"
+ (push (cons (erldoc-dom-get-text d)
+ (erldoc-fix-path (erldoc-expand-url href url)))
+ mans)))))))
+ (nreverse mans)))
+
+(defun erldoc-parse-man (man)
+ (let ((dom (erldoc-parse-html (cdr man)))
+ (table (make-hash-table :test #'equal)))
+ (erldoc-dom-walk
+ (erldoc-dom-get-element-by-id dom "loadscrollpos")
+ (lambda (d)
+ (let ((href (erldoc-dom-get-attribute d 'href)))
+ (when (and href (string-match "#" href))
+ (puthash (substring href (match-end 0))
+ (list (concat (car man) ":" (erldoc-strip-string
+ (erldoc-dom-get-text d)))
+ (erldoc-expand-url href (cdr man)))
+ table)))))
+ (let ((span-content
+ (lambda (span)
+ (let ((texts))
+ (erldoc-dom-walk span
+ (lambda (d)
+ (and (erldoc-dom-text-node-p d)
+ (push (erldoc-strip-string d) texts))))
+ (and texts (mapconcat 'identity (nreverse texts) " ")))))
+ entries)
+ (erldoc-dom-walk
+ dom
+ (lambda (d)
+ ;; Get the full function signature.
+ (when (and (eq (car-safe d) 'a)
+ (gethash (erldoc-dom-get-attribute d 'name) table))
+ (push (append (gethash (erldoc-dom-get-attribute d 'name) table)
+ (list (funcall span-content
+ (or (erldoc-dom-get-element d 'span)
+ (cadr (memq d erldoc-dom-walk-siblings))))))
+ entries))
+ ;; Get data types
+ (when (and (eq (car-safe d) 'a)
+ (string-prefix-p "type-"
+ (or (erldoc-dom-get-attribute d 'name) "")))
+ (push (list (concat (car man) ":" (funcall span-content d))
+ (concat (cdr man) "#" (erldoc-dom-get-attribute d 'name))
+ (funcall span-content erldoc-dom-walk-parent))
+ entries))))
+ entries)))
+
+(defun erldoc-parse-all (man-index output &optional json)
+ (let* ((output (expand-file-name output))
+ (table (make-hash-table :size 11503 :test #'equal))
+ (mans (erldoc-parse-man-index man-index))
+ (progress 1)
+ (reporter (make-progress-reporter "Parsing Erlang/OTP documentation"
+ progress (length mans)))
+ fails all)
+ (dolist (man mans)
+ (condition-case err
+ (push (erldoc-parse-man man) all)
+ (error (push (error-message-string err) fails)))
+ (accept-process-output nil 0.01)
+ (progress-reporter-update reporter (cl-incf progress)))
+ (when fails
+ (display-warning 'erldoc-parse-all
+ (format "\n\n%s" (mapconcat #'identity fails "\n"))
+ :error))
+ (progress-reporter-done reporter)
+ (mapc (lambda (x) (puthash (car x) (cdr x) table))
+ (apply #'nconc (nreverse all)))
+ (with-temp-buffer
+ (if (not json)
+ (pp table (current-buffer))
+ (eval-and-compile (require 'json))
+ (let ((json-encoding-pretty-print t))
+ (insert (json-encode table))))
+ (unless (file-directory-p (file-name-directory output))
+ (make-directory (file-name-directory output) t))
+ (write-region nil nil output nil nil nil 'ask))))
+
+(defun erldoc-otp-release ()
+ "Get the otp release version (as string) or nil if not found."
+ (let ((otp (erldoc-dom-get-text
+ (erldoc-dom-get-element
+ (erldoc-parse-html
+ (erldoc-expand-url "index.html" erldoc-man-index))
+ 'title))))
+ (and (string-match "[0-9.]+\\'" otp) (match-string 0 otp))))
+
+(defvar erldoc-browse-history nil)
+(defvar erldoc-lookup-table nil)
+
+(defun erldoc-lookup-table ()
+ (or erldoc-lookup-table
+ (progn
+ (unless (file-exists-p erldoc-output-file)
+ (let ((of (pcase (erldoc-otp-release)
+ (`nil erldoc-output-file)
+ (ver (concat erldoc-output-file "-" ver)))))
+ (unless (file-exists-p of)
+ (erldoc-parse-all erldoc-man-index of))
+ (unless (string= erldoc-output-file of)
+ (make-symbolic-link of erldoc-output-file))))
+ (setq erldoc-lookup-table
+ (with-temp-buffer
+ (insert-file-contents erldoc-output-file)
+ (read (current-buffer)))))))
+
+(defun erldoc-best-matches (mfa)
+ (pcase mfa
+ ((and `(,m ,f) (let a (erlang-get-function-arity)))
+ (let ((mfa (format "%s:%s/%s" m f a)))
+ (cond ((gethash mfa (erldoc-lookup-table)) (list mfa))
+ (m (all-completions (concat m ":" f "/") (erldoc-lookup-table)))
+ (t (let* ((mod (erlang-get-module))
+ (mf1 (and mod (concat mod ":" f "/")))
+ (mf2 (concat "erlang:" f "/"))
+ (re (concat ":" (regexp-quote f) "/")))
+ (or (and mf1 (all-completions mf1 (erldoc-lookup-table)))
+ (all-completions mf2 (erldoc-lookup-table))
+ (cl-loop for k being the hash-keys of (erldoc-lookup-table)
+ when (string-match-p re k)
+ collect k)))))))))
+
+;;;###autoload
+(defun erldoc-browse (mfa)
+ (interactive
+ (let ((default
+ ;; `erlang-mode-syntax-table' is lazily initialised.
+ (with-syntax-table (or erlang-mode-syntax-table (standard-syntax-table))
+ (ignore-errors
+ (erldoc-best-matches
+ (or (erlang-get-function-under-point)
+ (save-excursion
+ (goto-char (or (cadr (syntax-ppss)) (point)))
+ (erlang-get-function-under-point))))))))
+ (list (completing-read (format (if default "Function {%d %s} (default %s): "
+ "Function: ")
+ (length default)
+ (if (= (length default) 1) "guess" "guesses")
+ (car default))
+ (erldoc-lookup-table)
+ nil t nil 'erldoc-browse-history default))))
+ (or (stringp mfa)
+ (signal 'wrong-type-argument (list 'string mfa 'mfa)))
+ (browse-url (or (car (gethash mfa (erldoc-lookup-table)))
+ (user-error "No documentation for %s" mfa))))
+
+;;;###autoload
+(defun erldoc-apropos (pattern)
+ (interactive "sPattern: ")
+ (with-help-window (help-buffer)
+ (with-current-buffer standard-output
+ (princ (concat "Erldoc apropos pattern: " pattern "\n\n"))
+ (maphash (lambda (k v)
+ (when (string-match-p pattern k)
+ (insert-text-button k :type 'help-url
+ 'help-args (list (car v)))
+ (insert "\n")))
+ (erldoc-lookup-table)))))
+
+(defun erldoc-tokenize-signature (sig)
+ ;; Divide SIG into (MF ARGLIST RETTYPE)
+ (let ((from (if (string-match "\\`.+?(" sig)
+ (1- (match-end 0))
+ 0))
+ (to (and (string-match "\\s-*->\\s-*.*?\\'" sig) (match-beginning 0))))
+ (list (erldoc-strip-string (substring sig 0 from))
+ (erldoc-strip-string (substring sig from (and to (max from to))))
+ (and to (erldoc-strip-string (substring sig to))))))
+
+(defun erldoc-format-signature (mod fn)
+ (when (and mod fn (or erldoc-lookup-table
+ (file-exists-p erldoc-output-file)))
+ (let ((re (concat "\\`" mod ":" fn "/\\([0-9]+\\)\\'"))
+ (sigs))
+ (maphash (lambda (k v)
+ (when (string-match re k)
+ (push (cons (string-to-number (match-string 1 k))
+ (cdr (erldoc-tokenize-signature (cadr v))))
+ sigs)))
+ (erldoc-lookup-table))
+ (when sigs
+ ;; Mostly single return type but there are exceptions such as
+ ;; `beam_lib:chunks/2,3'.
+ (let ((single-rettype
+ (cl-reduce (lambda (x1 x2) (and x1 x2 (equal x1 x2) x1))
+ sigs :key #'cl-caddr))
+ (sigs (sort sigs #'car-less-than-car)))
+ (if single-rettype
+ (concat mod ":" fn (mapconcat #'cadr sigs " | ") " " single-rettype)
+ (mapconcat (lambda (x) (concat mod ":" fn (nth 1 x) " " (nth 2 x)))
+ sigs "\n")))))))
+
+;;;###autoload
+(defun erldoc-eldoc-function ()
+ "A function suitable for `eldoc-documentation-function'."
+ (save-excursion
+ (pcase (erlang-get-function-under-point)
+ (`(,_ nil) )
+ (`(nil ,fn) (erldoc-format-signature "erlang" fn))
+ (`(,mod ,fn) (erldoc-format-signature mod fn)))))
+
+(defun erldoc-parse-eeps-index ()
+ (let* ((url "http://www.erlang.org/eeps/")
+ (table (catch 'return
+ (erldoc-dom-walk (erldoc-parse-html url)
+ (lambda (d)
+ (and (eq (car-safe d) 'table)
+ (equal (erldoc-dom-get-attribute d 'summary)
+ "Numerical Index of EEPs")
+ (throw 'return d))))))
+ (fix-title (lambda (title)
+ (replace-regexp-in-string
+ "`` *" "" (replace-regexp-in-string " *``, *" " by " title))))
+ (result))
+ (erldoc-dom-walk
+ table (lambda (d)
+ (when (eq (car-safe d) 'a)
+ (push (cons (funcall fix-title (erldoc-dom-get-attribute d 'title))
+ (erldoc-expand-url
+ (erldoc-dom-get-attribute d 'href)
+ url))
+ result))))
+ (nreverse result)))
+
+(defvar erldoc-user-guides nil)
+
+(defvar erldoc-missing-user-guides
+ '("compiler" "hipe" "kernel" "os_mon" "parsetools" "typer")
+ "List of standard Erlang applications with no user guides.")
+
+;; Search in `code:lib_dir/0' using find LIB_DIR -type f -name
+;; '*_app.html'.
+(defvar erldoc-app-manuals '("crypto" "diameter" "erl_docgen"
+ "kernel" "observer" "os_mon"
+ "runtime_tools" "sasl" "snmp"
+ "ssl" "test_server"
+ ("ssh" . "SSH") ("stdlib" . "STDLIB")
+ ("hipe" . "HiPE") ("typer" . "TypEr"))
+ "List of applications that come with a manual.")
+
+(defun erldoc-user-guide-chapters (user-guide)
+ (pcase-let ((`(,name . ,url) user-guide))
+ (unless (member name erldoc-missing-user-guides)
+ (let ((chaps (erldoc-dom-get-elements-by-id
+ (erldoc-dom-get-element-by-id (erldoc-parse-html url) "leftnav")
+ "no")))
+ (or chaps (warn "erldoc-user-guide-chapters no chapters found for `%s'"
+ (cdr user-guide)))
+ (mapcar (lambda (li)
+ (cons (concat name "#" (erldoc-dom-get-attribute li 'title))
+ (erldoc-expand-url (erldoc-dom-get-attribute
+ (erldoc-dom-get-element li 'a) 'href)
+ url)))
+ chaps)))))
+
+(defun erldoc-user-guides-1 ()
+ (let ((url (erldoc-expand-url "applications.html" erldoc-man-index))
+ app-guides app-mans)
+ (erldoc-dom-walk
+ (erldoc-parse-html url)
+ (lambda (d)
+ (when (and (eq (car-safe d) 'a)
+ (not (string-match-p "\\`[0-9.]+\\'" (erldoc-dom-get-text d))))
+ (with-demoted-errors "erldoc-user-guides-1: %S"
+ (let ((name (erldoc-strip-string (erldoc-dom-get-text d)))
+ (index-page (erldoc-fix-path (erldoc-expand-url
+ (erldoc-dom-get-attribute d 'href) url))))
+ (push (cons name (if (member name erldoc-missing-user-guides)
+ index-page
+ (erldoc-expand-url "users_guide.html" index-page)))
+ app-guides)
+ ;; Collect application manuals.
+ (pcase (assoc name (mapcar (lambda (x) (if (consp x) x (cons x x)))
+ erldoc-app-manuals))
+ (`(,_ . ,manual)
+ (push (cons name
+ (erldoc-expand-url (format "%s_app.html" manual)
+ index-page))
+ app-mans))))))))
+ (list (nreverse app-guides)
+ (nreverse app-mans))))
+
+(defun erldoc-user-guides ()
+ (or erldoc-user-guides
+ (let ((file (concat erldoc-output-file "-topics")))
+ (unless (file-exists-p file)
+ (unless (file-directory-p (file-name-directory file))
+ (make-directory (file-name-directory file) t))
+ (with-temp-buffer
+ (pcase-let ((`(,guides ,mans) (erldoc-user-guides-1)))
+ (pp (append (cl-mapcan #'erldoc-user-guide-chapters
+ (append (mapcar
+ (lambda (dir)
+ (cons dir (erldoc-expand-url
+ (concat dir "/users_guide.html")
+ erldoc-man-index)))
+ '("design_principles"
+ "efficiency_guide"
+ "embedded"
+ "getting_started"
+ "installation_guide"
+ "oam"
+ "programming_examples"
+ "reference_manual"
+ "system_architecture_intro"
+ "system_principles"
+ "tutorial"))
+ guides))
+ (mapcar (lambda (man)
+ (pcase-let ((`(,name . ,url) man))
+ (cons (concat name " (App)") url)))
+ mans)
+ (erldoc-parse-eeps-index))
+ (current-buffer)))
+ (write-region nil nil file nil nil nil 'ask)))
+ (setq erldoc-user-guides (with-temp-buffer (insert-file-contents file)
+ (read (current-buffer)))))))
+
+;;;###autoload
+(defun erldoc-browse-topic (topic)
+ (interactive
+ (list (completing-read "User guide: " (erldoc-user-guides) nil t)))
+ (browse-url (cdr (assoc topic (erldoc-user-guides)))))
+
+(provide 'erldoc)
+;;; erldoc.el ends here
diff --git a/lib/tools/src/fprof.erl b/lib/tools/src/fprof.erl
index 1291a3e5ec..d1a4624419 100644
--- a/lib/tools/src/fprof.erl
+++ b/lib/tools/src/fprof.erl
@@ -1702,6 +1702,12 @@ trace_handler({trace_ts, Pid, send, _OtherPid, _Msg, TS} = Trace,
dump_stack(Dump, get(Pid), Trace),
TS;
%%
+%% send_to_non_existing_process
+trace_handler({trace_ts, Pid, send_to_non_existing_process, _OtherPid, _Msg, TS} = Trace,
+ _Table, _, Dump) ->
+ dump_stack(Dump, get(Pid), Trace),
+ TS;
+%%
%% 'receive'
trace_handler({trace_ts, Pid, 'receive', _Msg, TS} = Trace,
_Table, _, Dump) ->
diff --git a/lib/typer/src/typer.erl b/lib/typer/src/typer.erl
index 5c82750a21..6aee749741 100644
--- a/lib/typer/src/typer.erl
+++ b/lib/typer/src/typer.erl
@@ -1,8 +1,4 @@
%% -*- erlang-indent-level: 2 -*-
-%%-----------------------------------------------------------------------
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -15,9 +11,6 @@
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
%%-----------------------------------------------------------------------
%% File : typer.erl
diff --git a/lib/wx/api_gen/gl_gen.erl b/lib/wx/api_gen/gl_gen.erl
index 54635bdd2e..7e3766a43b 100644
--- a/lib/wx/api_gen/gl_gen.erl
+++ b/lib/wx/api_gen/gl_gen.erl
@@ -354,6 +354,7 @@ 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(list_binary, P) -> P#arg{alt=list_binary};
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}}}.
@@ -588,7 +589,7 @@ lookup(Name,[_|R],Def) ->
lookup(Name,R,Def);
lookup(_,[], Def) -> Def.
-setup_idx_binary(Name,Ext,_Opts) ->
+setup_idx_binary(Name,Ext, Opts) ->
FuncName = Name ++ Ext,
Func = #func{params=Args} = get(FuncName),
Id = next_id(function),
@@ -607,8 +608,7 @@ setup_idx_binary(Name,Ext,_Opts) ->
ok;
(_) -> ok
end, Args),
-
- case setup_idx_binary(Args, []) of
+ case setup_idx_binary_1(Args, []) of
ignore ->
put(FuncName, Func#func{id=Id}),
Name++Ext;
@@ -624,30 +624,41 @@ setup_idx_binary(Name,Ext,_Opts) ->
[FuncName,Extra]
end.
-setup_idx_binary([A=#arg{in=true,type=T=#type{base=idx_binary}}|R], Acc) ->
+setup_idx_binary_1([A=#arg{in=true,type=T=#type{base=idx_binary}}|R], Acc) ->
A1 = A#arg{type=T#type{base=guard_int,size=4}},
A2 = A#arg{type=T#type{base=binary}},
Head = reverse(Acc),
- case setup_idx_binary(R, []) of
+ case setup_idx_binary_1(R, []) of
ignore ->
{bin, Head ++ [A1|R], Head ++ [A2|R]};
{bin, R1,R2} ->
{bin, Head ++ [A1|R1], Head ++ [A2|R2]}
end;
-setup_idx_binary([A=#arg{in=true,type=T=#type{single={tuple,matrix}}}|R], Acc) ->
+setup_idx_binary_1([A=#arg{in=true,type=T=#type{base=int,size=4},alt=list_binary}|R], Acc) ->
+ A1 = A#arg{type=T#type{base=guard_int}},
+ A2 = A#arg{type=T#type{base=binary}},
+ Head = reverse(Acc),
+ case setup_idx_binary_1(R, []) of
+ ignore ->
+ {bin, Head ++ [A1|R], Head ++ [A2|R]};
+ {bin, R1,R2} ->
+ {bin, Head ++ [A1|R1], Head ++ [A2|R2]}
+ end;
+
+setup_idx_binary_1([A=#arg{in=true,type=T=#type{single={tuple,matrix}}}|R], Acc) ->
A1 = A#arg{type=T#type{single={tuple, matrix12}}},
A2 = A#arg{type=T#type{single={tuple, 16}}},
Head = reverse(Acc),
- case setup_idx_binary(R, []) of
+ case setup_idx_binary_1(R, []) of
ignore ->
{matrix, Head ++ [A1|R], Head ++ [A2|R]};
{matrix, R1,R2} ->
{matrix, Head ++ [A1|R1], Head ++ [A2|R2]}
end;
-setup_idx_binary([H|R],Acc) ->
- setup_idx_binary(R,[H|Acc]);
-setup_idx_binary([],_) -> ignore.
-
+setup_idx_binary_1([H|R],Acc) ->
+ setup_idx_binary_1(R,[H|Acc]);
+setup_idx_binary_1([],_) -> ignore.
+
is_equal(F1=#func{type=T1,params=A1},F2=#func{type=T2,params=A2}) ->
Equal = is_equal_type(T1,T2) andalso is_equal_args(A1,A2),
case Equal of
diff --git a/lib/wx/api_gen/gl_gen_c.erl b/lib/wx/api_gen/gl_gen_c.erl
index c6d4f3a520..53c194a315 100644
--- a/lib/wx/api_gen/gl_gen_c.erl
+++ b/lib/wx/api_gen/gl_gen_c.erl
@@ -123,20 +123,14 @@ 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}}) ->
+declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=string,size={Max,_}}}) ->
case is_integer(Max) of
- true ->
+ 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;~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
+ store_free(N)
end,
A;
declare_var(A=#arg{name=N,in=false,type=#type{base=binary,size={MaxSz, _}}}) ->
@@ -163,9 +157,9 @@ 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}}) ->
+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;
+ A;
declare_var(A=#arg{where=_}) ->
A.
@@ -194,9 +188,16 @@ decode_arg(P=#arg{where=erl},A) -> {P,A};
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) ->
+decode_arg(P=#arg{name=Name,alt=Alt,type=#type{name=Type,base=binary}},A0) ->
w(" ~s *~s = (~s *) bins[~p];~n", [Type,Name,Type,next_id(bin_count)]),
- {P, A0};
+ case Alt of
+ list_binary ->
+ A = align(4, A0),
+ w(" int * ~sLen = (int *) bp; bp += 4; (void) ~sLen;~n", [Name, Name]),
+ {P, A};
+ _ ->
+ {P, A0}
+ end;
decode_arg(P=#arg{name=Name,type=#type{name=Type,base=memory}},A0) ->
w(" ~s *~s = (~s *) bins[~p];~n", [Type,Name,Type,next_id(bin_count)]),
{P, A0};
@@ -217,7 +218,7 @@ decode_arg(P=#arg{name=Name,type=#type{size=Sz,single=list,name=Type}},A0) ->
A = align(max([Sz,4]),A0),
w(" int * ~sLen = (int *) bp; bp += ~p;~n", [Name, max([4,Sz])]),
w(" ~s * ~s = (~s *) bp; ", [Type,Name,Type]),
- w(" bp += (8-((*~sLen*~p+~p)%8))%8;~n", [Name,Sz,A]),
+ w(" bp += *~sLen*~p + (8-((*~sLen*~p+~p)%8))%8;~n", [Name,Sz,Name,Sz,A]),
{P, 0};
decode_arg(P=#arg{name=Name,type=#type{size=TSz,name=Type,single={tuple,undefined}}},A0) ->
A = align(TSz,A0),
diff --git a/lib/wx/api_gen/gl_gen_erl.erl b/lib/wx/api_gen/gl_gen_erl.erl
index 1f9407525d..3ad14825dd 100644
--- a/lib/wx/api_gen/gl_gen_erl.erl
+++ b/lib/wx/api_gen/gl_gen_erl.erl
@@ -496,6 +496,8 @@ doc_arg_type2(#type{base=string, single=list}) ->
"iolist()";
doc_arg_type2(T=#type{single={tuple,Sz}}) ->
"{" ++ args(fun doc_arg_type3/1, ",", lists:duplicate(Sz,T)) ++ "}";
+doc_arg_type2(#type{base=guard_int, single=list}) ->
+ "[integer()]|mem()";
doc_arg_type2(T=#type{single=list}) ->
"[" ++ doc_arg_type3(T) ++ "]";
doc_arg_type2(T=#type{single={list, _Max}}) ->
@@ -516,7 +518,9 @@ doc_arg_type3(#type{base=binary}) -> "binary()";
doc_arg_type3(#type{base=memory}) -> "mem()".
guard_test(As) ->
- Str = args(fun(#arg{name=N,type=#type{base=guard_int}}) ->
+ Str = args(fun(#arg{name=N,type=#type{base=guard_int, single=list}}) ->
+ " is_list("++erl_arg_name(N)++")";
+ (#arg{name=N,type=#type{base=guard_int}}) ->
" is_integer("++erl_arg_name(N)++")";
(_) ->
skip
@@ -526,6 +530,13 @@ guard_test(As) ->
Other -> " when " ++ Other
end.
+pre_marshal([#arg{name=N,in=true, type=#type{base=binary, single=list}=T, alt=list_binary}=A|R]) ->
+ w(" send_bin(~s),~n", [erl_arg_name(N)]),
+ w(" ~sLen = byte_size(if is_binary(~s) -> ~s; is_tuple(~s) -> element(2, ~s) end) div 4,~n",
+ [erl_arg_name(N),erl_arg_name(N), erl_arg_name(N), erl_arg_name(N), erl_arg_name(N)]),
+ Type = T#type{base=int, by_val=true, single=true, ref=undefined},
+ Arg=A#arg{name=N++"Len", where=both, type=Type},
+ [Arg|pre_marshal(R)];
pre_marshal([#arg{name=N,in=true,type=#type{base=binary}}|R]) ->
w(" send_bin(~s),~n", [erl_arg_name(N)]),
pre_marshal(R);
@@ -534,8 +545,18 @@ pre_marshal([#arg{name=N,type=#type{base=memory}}|R]) ->
pre_marshal(R);
pre_marshal([A=#arg{name=N,type=#type{base=string,single=list}}|R]) ->
%% With null terminations
- w(" ~sTemp = list_to_binary([[Str|[0]] || Str <- ~s ]),~n",
+ w(" ~sTemp = list_to_binary([[Str|[0]] || Str <- ~s ]),~n",
[erl_arg_name(N), erl_arg_name(N)]),
+ w(" ~sLen = length(~s),~n",[erl_arg_name(N), erl_arg_name(N)]),
+ [A|pre_marshal(R)];
+pre_marshal([A=#arg{name=N,type=#type{base=string,single=true,ref={pointer,1}}}|R]) ->
+ w(" ~sLen = length(~s),~n",[erl_arg_name(N), erl_arg_name(N)]),
+ [A|pre_marshal(R)];
+pre_marshal([A=#arg{name=N,type=#type{single=list}}|R]) ->
+ w(" ~sLen = length(~s),~n",[erl_arg_name(N), erl_arg_name(N)]),
+ [A|pre_marshal(R)];
+pre_marshal([A=#arg{name=N,type=#type{single={tuple_list,_}}}|R]) ->
+ w(" ~sLen = length(~s),~n",[erl_arg_name(N), erl_arg_name(N)]),
[A|pre_marshal(R)];
pre_marshal([A|R]) ->
[A|pre_marshal(R)];
@@ -587,9 +608,9 @@ marshal_arg(#type{size=BSz,name=Type,single={tuple,matrix12}},Name,A0) ->
align(BSz,16,A0,All);
marshal_arg(#type{size=Sz,name=Type,base=Base,single=list},Name,A0)
- when Base =:= float; Base =:= int ->
+ when Base =:= float; Base =:= int; Base =:= guard_int ->
KeepA = case Sz of 8 -> "0:32,"; _ -> "" end,
- Str0 = "(length("++Name++")):?GLuint,"++KeepA++"\n"
+ Str0 = Name++"Len:?GLuint,"++KeepA++"\n"
" (<< <<C:?"++Type++">> || C <- "++Name++">>)/binary",
{Str,Align} = align(max([Sz,4]),A0,Str0),
align_after(Sz,Align,0,1,Name,Str);
@@ -610,7 +631,7 @@ marshal_arg(#type{base=string,single=true,ref={pointer,1}},Name,A0) ->
marshal_arg(#type{base=string,single=list,ref={pointer,2}},Name,A0) ->
Str0 =
- "(length("++Name++")):?GLuint,"
+ Name++"Len:?GLuint,"
"(size("++Name ++ "Temp)):?GLuint,"
"(" ++ Name ++ "Temp)/binary",
{Str,A} = align(4,A0,Str0),
@@ -624,7 +645,7 @@ marshal_arg(#type{size=Sz,name=Type,single={tuple_list,TSz}},Name,A0) ->
TBin = args(fun(ElName) -> ElName ++ ":?" ++ Type end, ",", Names),
KeepA = case Sz of 8 -> "0:32,"; 4 -> "" end,
- Str0 = "(length("++Name++")):?GLuint,"++KeepA++"\n"
+ Str0 = Name++"Len:?GLuint,"++KeepA++"\n"
" (<< <<"++TBin++">> || {"++TTup++"} <- "++Name++">>)/binary",
align(Sz,A0,Str0);
@@ -660,19 +681,19 @@ align(8,_,7,Str) -> {"0:8," ++Str, 0}.
align_after(8,0,_Add,_Multiplier,_Name,Str) -> {Str,0};
align_after(4,0,Add,Mult,Name,Str) ->
Extra = extra_align(Add,Mult),
- Align = ",0:(((length("++Name++")"++Extra++") rem 2)*32)",
+ Align = ",0:((("++Name++"Len"++Extra++") rem 2)*32)",
{Str ++ Align,0};
align_after(4,4,Add,Mult,Name,Str) ->
Extra = extra_align(Add,Mult),
- Align = ",0:(((1+length("++Name++")"++Extra++") rem 2)*32)",
+ Align = ",0:(((1+"++Name++"Len"++Extra++") rem 2)*32)",
{Str ++ Align,0};
align_after(2,A,Add,Mult,Name,Str) when (A rem 2) =:= 0 ->
Extra = extra_align(A+Add*2,Mult),
- Align = ",0:((8-((length("++Name++")*2"++Extra++") rem 8)) rem 8)",
+ Align = ",0:((8-(("++Name++"Len*2"++Extra++") rem 8)) rem 8)",
{Str ++ Align,0};
align_after(1,A,Add,Mult,Name,Str) ->
Extra = extra_align(A+Add,Mult),
- Align = ",0:((8-((length("++Name++")"++Extra++") rem 8)) rem 8)",
+ Align = ",0:((8-(("++Name++"Len"++Extra++") rem 8)) rem 8)",
{Str ++ Align,0};
align_after(Sz,A,Add,Mult,Name,Str) ->
io:format("~p ~p with ~p ~p ~s~n, ~p", [Sz,A,Add,Mult,Name,Str]),
diff --git a/lib/wx/api_gen/glapi.conf b/lib/wx/api_gen/glapi.conf
index 59fa8f7727..57f30a3f7e 100644
--- a/lib/wx/api_gen/glapi.conf
+++ b/lib/wx/api_gen/glapi.conf
@@ -181,9 +181,9 @@
{"glLoadTransposeMatrix", {"m", {single,{tuple,matrix}}}}.
{"glMultTransposeMatrix", {"m",{single,{tuple,matrix}}}}.
-{"glMultiDrawArrays", [{"first", [in,{single,list}]},
- {"count", [in,{single,list}]},
- {"primcount", {c_only, {length,"first"}}}]}.
+{"glMultiDrawArrays", [{"first", [in,{single,list}, list_binary]},
+ {"count", [in,{single,list}, list_binary]},
+ {"primcount", {c_only, {length,"count"}}}]}.
{"glGenQueries", {"ids", {single,{list, "n", "n"}}}}.
{"glGetQueryiv", {"params", {single, true}}}.
diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl
index 0a0b1f9209..d4b6db8153 100644
--- a/lib/wx/api_gen/wx_gen_cpp.erl
+++ b/lib/wx/api_gen/wx_gen_cpp.erl
@@ -1316,7 +1316,8 @@ encode_events(Evs) ->
w(" } else {~n"),
w(" send_res = rt.send();~n"),
w(" if(cb->skip) event->Skip();~n"),
- w(" if(app->recurse_level < 1) {~n"),
+ #class{id=MouseId} = lists:keyfind("wxMouseEvent", #class.name, Evs),
+ w(" if(app->recurse_level < 1 && Etype->cID != ~p) {~n", [MouseId]),
w(" app->recurse_level++;~n"),
w(" app->dispatch_cmds();~n"),
w(" app->recurse_level--;~n"),
diff --git a/lib/wx/c_src/gen/gl_funcs.cpp b/lib/wx/c_src/gen/gl_funcs.cpp
index 4dd3ad44ef..bc8d5bbdca 100644
--- a/lib/wx/c_src/gen/gl_funcs.cpp
+++ b/lib/wx/c_src/gen/gl_funcs.cpp
@@ -815,7 +815,7 @@ case 5107: { // glCallList
}; break;
case 5108: { // glCallLists
int * listsLen = (int *) bp; bp += 4;
- GLuint * lists = (GLuint *) bp; bp += (8-((*listsLen*4+4)%8))%8;
+ GLuint * lists = (GLuint *) bp; bp += *listsLen*4 + (8-((*listsLen*4+4)%8))%8;
weglCallLists(*listsLen,GL_UNSIGNED_INT,lists);
}; break;
case 5109: { // glListBase
@@ -1866,7 +1866,7 @@ case 5271: { // glGenTextures
}; break;
case 5272: { // glDeleteTextures
int * texturesLen = (int *) bp; bp += 4;
- GLuint * textures = (GLuint *) bp; bp += (8-((*texturesLen*4+4)%8))%8;
+ GLuint * textures = (GLuint *) bp; bp += *texturesLen*4 + (8-((*texturesLen*4+4)%8))%8;
weglDeleteTextures(*texturesLen,textures);
}; break;
case 5273: { // glBindTexture
@@ -1876,14 +1876,14 @@ case 5273: { // glBindTexture
}; break;
case 5274: { // glPrioritizeTextures
int * texturesLen = (int *) bp; bp += 4;
- GLuint * textures = (GLuint *) bp; bp += (8-((*texturesLen*4+4)%8))%8;
+ GLuint * textures = (GLuint *) bp; bp += *texturesLen*4 + (8-((*texturesLen*4+4)%8))%8;
int * prioritiesLen = (int *) bp; bp += 4;
- GLclampf * priorities = (GLclampf *) bp; bp += (8-((*prioritiesLen*4+4)%8))%8;
+ GLclampf * priorities = (GLclampf *) bp; bp += *prioritiesLen*4 + (8-((*prioritiesLen*4+4)%8))%8;
weglPrioritizeTextures(*texturesLen,textures,priorities);
}; break;
case 5275: { // glAreTexturesResident
int * texturesLen = (int *) bp; bp += 4;
- GLuint * textures = (GLuint *) bp; bp += (8-((*texturesLen*4+4)%8))%8;
+ GLuint * textures = (GLuint *) bp; bp += *texturesLen*4 + (8-((*texturesLen*4+4)%8))%8;
GLboolean *residences;
residences = (GLboolean *) driver_alloc(sizeof(GLboolean) * *texturesLen);
GLboolean result = weglAreTexturesResident(*texturesLen,textures,residences);
@@ -2921,132 +2921,140 @@ case 5394: { // glBlendFuncSeparate
case 5395: { // glMultiDrawArrays
GLenum *mode = (GLenum *) bp; bp += 4;
int * firstLen = (int *) bp; bp += 4;
- GLint * first = (GLint *) bp; bp += (8-((*firstLen*4+0)%8))%8;
+ GLint * first = (GLint *) bp; bp += *firstLen*4 + (8-((*firstLen*4+0)%8))%8;
int * countLen = (int *) bp; bp += 4;
- GLsizei * count = (GLsizei *) bp; bp += (8-((*countLen*4+4)%8))%8;
- weglMultiDrawArrays(*mode,first,count,*firstLen);
+ GLsizei * count = (GLsizei *) bp; bp += *countLen*4 + (8-((*countLen*4+4)%8))%8;
+ weglMultiDrawArrays(*mode,first,count,*countLen);
}; break;
-case 5396: { // glPointParameterf
+case 5396: { // glMultiDrawArrays
+ GLenum *mode = (GLenum *) bp; bp += 4;
+ GLint *first = (GLint *) bins[0];
+ int * firstLen = (int *) bp; bp += 4; (void) firstLen;
+ GLsizei *count = (GLsizei *) bins[1];
+ int * countLen = (int *) bp; bp += 4; (void) countLen;
+ weglMultiDrawArrays(*mode,first,count,*countLen);
+}; break;
+case 5397: { // glPointParameterf
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat *param = (GLfloat *) bp; bp += 4;
weglPointParameterf(*pname,*param);
}; break;
-case 5397: { // glPointParameterfv
+case 5398: { // glPointParameterfv
GLenum *pname = (GLenum *) bp; bp += 4;
int *paramsLen = (int *) bp; bp += 4;
GLfloat *params = (GLfloat *) bp; bp += *paramsLen*4+((*paramsLen)+0)%2*4;
weglPointParameterfv(*pname,params);
}; break;
-case 5398: { // glPointParameteri
+case 5399: { // glPointParameteri
GLenum *pname = (GLenum *) bp; bp += 4;
GLint *param = (GLint *) bp; bp += 4;
weglPointParameteri(*pname,*param);
}; break;
-case 5399: { // glPointParameteriv
+case 5400: { // glPointParameteriv
GLenum *pname = (GLenum *) bp; bp += 4;
int *paramsLen = (int *) bp; bp += 4;
GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+0)%2*4;
weglPointParameteriv(*pname,params);
}; break;
-case 5400: { // glFogCoordfv
+case 5401: { // glFogCoordfv
GLfloat *coord = (GLfloat *) bp; bp += 4;
weglFogCoordfv(coord);
}; break;
-case 5401: { // glFogCoorddv
+case 5402: { // glFogCoorddv
GLdouble *coord = (GLdouble *) bp; bp += 8;
weglFogCoorddv(coord);
}; break;
-case 5402: { // glFogCoordPointer
+case 5403: { // glFogCoordPointer
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
GLvoid *pointer = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglFogCoordPointer(*type,*stride,pointer);
}; break;
-case 5403: { // glFogCoordPointer
+case 5404: { // glFogCoordPointer
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
GLvoid *pointer = (GLvoid *) bins[0];
weglFogCoordPointer(*type,*stride,pointer);
}; break;
-case 5404: { // glSecondaryColor3bv
+case 5405: { // glSecondaryColor3bv
GLbyte *v = (GLbyte *) bp; bp += 1;
weglSecondaryColor3bv(v);
}; break;
-case 5405: { // glSecondaryColor3dv
+case 5406: { // glSecondaryColor3dv
GLdouble *v = (GLdouble *) bp; bp += 8;
weglSecondaryColor3dv(v);
}; break;
-case 5406: { // glSecondaryColor3fv
+case 5407: { // glSecondaryColor3fv
GLfloat *v = (GLfloat *) bp; bp += 4;
weglSecondaryColor3fv(v);
}; break;
-case 5407: { // glSecondaryColor3iv
+case 5408: { // glSecondaryColor3iv
GLint *v = (GLint *) bp; bp += 4;
weglSecondaryColor3iv(v);
}; break;
-case 5408: { // glSecondaryColor3sv
+case 5409: { // glSecondaryColor3sv
GLshort *v = (GLshort *) bp; bp += 2;
weglSecondaryColor3sv(v);
}; break;
-case 5409: { // glSecondaryColor3ubv
+case 5410: { // glSecondaryColor3ubv
GLubyte *v = (GLubyte *) bp; bp += 1;
weglSecondaryColor3ubv(v);
}; break;
-case 5410: { // glSecondaryColor3uiv
+case 5411: { // glSecondaryColor3uiv
GLuint *v = (GLuint *) bp; bp += 4;
weglSecondaryColor3uiv(v);
}; break;
-case 5411: { // glSecondaryColor3usv
+case 5412: { // glSecondaryColor3usv
GLushort *v = (GLushort *) bp; bp += 2;
weglSecondaryColor3usv(v);
}; break;
-case 5412: { // glSecondaryColorPointer
+case 5413: { // glSecondaryColorPointer
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
GLvoid *pointer = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglSecondaryColorPointer(*size,*type,*stride,pointer);
}; break;
-case 5413: { // glSecondaryColorPointer
+case 5414: { // glSecondaryColorPointer
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLsizei *stride = (GLsizei *) bp; bp += 4;
GLvoid *pointer = (GLvoid *) bins[0];
weglSecondaryColorPointer(*size,*type,*stride,pointer);
}; break;
-case 5414: { // glWindowPos2dv
+case 5415: { // glWindowPos2dv
GLdouble *v = (GLdouble *) bp; bp += 8;
weglWindowPos2dv(v);
}; break;
-case 5415: { // glWindowPos2fv
+case 5416: { // glWindowPos2fv
GLfloat *v = (GLfloat *) bp; bp += 4;
weglWindowPos2fv(v);
}; break;
-case 5416: { // glWindowPos2iv
+case 5417: { // glWindowPos2iv
GLint *v = (GLint *) bp; bp += 4;
weglWindowPos2iv(v);
}; break;
-case 5417: { // glWindowPos2sv
+case 5418: { // glWindowPos2sv
GLshort *v = (GLshort *) bp; bp += 2;
weglWindowPos2sv(v);
}; break;
-case 5418: { // glWindowPos3dv
+case 5419: { // glWindowPos3dv
GLdouble *v = (GLdouble *) bp; bp += 8;
weglWindowPos3dv(v);
}; break;
-case 5419: { // glWindowPos3fv
+case 5420: { // glWindowPos3fv
GLfloat *v = (GLfloat *) bp; bp += 4;
weglWindowPos3fv(v);
}; break;
-case 5420: { // glWindowPos3iv
+case 5421: { // glWindowPos3iv
GLint *v = (GLint *) bp; bp += 4;
weglWindowPos3iv(v);
}; break;
-case 5421: { // glWindowPos3sv
+case 5422: { // glWindowPos3sv
GLshort *v = (GLshort *) bp; bp += 2;
weglWindowPos3sv(v);
}; break;
-case 5422: { // glGenQueries
+case 5423: { // glGenQueries
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *ids;
ids = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -3062,12 +3070,12 @@ case 5422: { // glGenQueries
driver_free(rt);
driver_free(ids);
}; break;
-case 5423: { // glDeleteQueries
+case 5424: { // glDeleteQueries
int * idsLen = (int *) bp; bp += 4;
- GLuint * ids = (GLuint *) bp; bp += (8-((*idsLen*4+4)%8))%8;
+ GLuint * ids = (GLuint *) bp; bp += *idsLen*4 + (8-((*idsLen*4+4)%8))%8;
weglDeleteQueries(*idsLen,ids);
}; break;
-case 5424: { // glIsQuery
+case 5425: { // glIsQuery
GLuint *id = (GLuint *) bp; bp += 4;
GLboolean result = weglIsQuery(*id);
int AP = 0; ErlDrvTermData rt[6];
@@ -3076,16 +3084,16 @@ case 5424: { // glIsQuery
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5425: { // glBeginQuery
+case 5426: { // glBeginQuery
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
weglBeginQuery(*target,*id);
}; break;
-case 5426: { // glEndQuery
+case 5427: { // glEndQuery
GLenum *target = (GLenum *) bp; bp += 4;
weglEndQuery(*target);
}; break;
-case 5427: { // glGetQueryiv
+case 5428: { // glGetQueryiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -3096,7 +3104,7 @@ case 5427: { // glGetQueryiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5428: { // glGetQueryObjectiv
+case 5429: { // glGetQueryObjectiv
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -3107,7 +3115,7 @@ case 5428: { // glGetQueryObjectiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5429: { // glGetQueryObjectuiv
+case 5430: { // glGetQueryObjectuiv
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint params[1] = {0};
@@ -3118,17 +3126,17 @@ case 5429: { // glGetQueryObjectuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5430: { // glBindBuffer
+case 5431: { // glBindBuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *buffer = (GLuint *) bp; bp += 4;
weglBindBuffer(*target,*buffer);
}; break;
-case 5431: { // glDeleteBuffers
+case 5432: { // glDeleteBuffers
int * buffersLen = (int *) bp; bp += 4;
- GLuint * buffers = (GLuint *) bp; bp += (8-((*buffersLen*4+4)%8))%8;
+ GLuint * buffers = (GLuint *) bp; bp += *buffersLen*4 + (8-((*buffersLen*4+4)%8))%8;
weglDeleteBuffers(*buffersLen,buffers);
}; break;
-case 5432: { // glGenBuffers
+case 5433: { // glGenBuffers
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *buffers;
buffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -3144,7 +3152,7 @@ case 5432: { // glGenBuffers
driver_free(rt);
driver_free(buffers);
}; break;
-case 5433: { // glIsBuffer
+case 5434: { // glIsBuffer
GLuint *buffer = (GLuint *) bp; bp += 4;
GLboolean result = weglIsBuffer(*buffer);
int AP = 0; ErlDrvTermData rt[6];
@@ -3153,7 +3161,7 @@ case 5433: { // glIsBuffer
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5434: { // glBufferData
+case 5435: { // glBufferData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
@@ -3161,7 +3169,7 @@ case 5434: { // glBufferData
GLenum *usage = (GLenum *) bp; bp += 4;
weglBufferData(*target,size,data,*usage);
}; break;
-case 5435: { // glBufferData
+case 5436: { // glBufferData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
@@ -3169,7 +3177,7 @@ case 5435: { // glBufferData
GLenum *usage = (GLenum *) bp; bp += 4;
weglBufferData(*target,size,data,*usage);
}; break;
-case 5436: { // glBufferSubData
+case 5437: { // glBufferSubData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
@@ -3177,7 +3185,7 @@ case 5436: { // glBufferSubData
GLvoid *data = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglBufferSubData(*target,offset,size,data);
}; break;
-case 5437: { // glBufferSubData
+case 5438: { // glBufferSubData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
@@ -3185,7 +3193,7 @@ case 5437: { // glBufferSubData
GLvoid *data = (GLvoid *) bins[0];
weglBufferSubData(*target,offset,size,data);
}; break;
-case 5438: { // glGetBufferSubData
+case 5439: { // glGetBufferSubData
GLenum *target = (GLenum *) bp; bp += 4;
bp += 4;
GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
@@ -3198,7 +3206,7 @@ case 5438: { // glGetBufferSubData
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5439: { // glGetBufferParameteriv
+case 5440: { // glGetBufferParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -3209,52 +3217,52 @@ case 5439: { // glGetBufferParameteriv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5440: { // glBlendEquationSeparate
+case 5441: { // glBlendEquationSeparate
GLenum *modeRGB = (GLenum *) bp; bp += 4;
GLenum *modeAlpha = (GLenum *) bp; bp += 4;
weglBlendEquationSeparate(*modeRGB,*modeAlpha);
}; break;
-case 5441: { // glDrawBuffers
+case 5442: { // glDrawBuffers
int * bufsLen = (int *) bp; bp += 4;
- GLenum * bufs = (GLenum *) bp; bp += (8-((*bufsLen*4+4)%8))%8;
+ GLenum * bufs = (GLenum *) bp; bp += *bufsLen*4 + (8-((*bufsLen*4+4)%8))%8;
weglDrawBuffers(*bufsLen,bufs);
}; break;
-case 5442: { // glStencilOpSeparate
+case 5443: { // glStencilOpSeparate
GLenum *face = (GLenum *) bp; bp += 4;
GLenum *sfail = (GLenum *) bp; bp += 4;
GLenum *dpfail = (GLenum *) bp; bp += 4;
GLenum *dppass = (GLenum *) bp; bp += 4;
weglStencilOpSeparate(*face,*sfail,*dpfail,*dppass);
}; break;
-case 5443: { // glStencilFuncSeparate
+case 5444: { // glStencilFuncSeparate
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(*face,*func,*ref,*mask);
}; break;
-case 5444: { // glStencilMaskSeparate
+case 5445: { // glStencilMaskSeparate
GLenum *face = (GLenum *) bp; bp += 4;
GLuint *mask = (GLuint *) bp; bp += 4;
weglStencilMaskSeparate(*face,*mask);
}; break;
-case 5445: { // glAttachShader
+case 5446: { // glAttachShader
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *shader = (GLuint *) bp; bp += 4;
weglAttachShader(*program,*shader);
}; break;
-case 5446: { // glBindAttribLocation
+case 5447: { // glBindAttribLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
weglBindAttribLocation(*program,*index,name);
}; break;
-case 5447: { // glCompileShader
+case 5448: { // glCompileShader
GLuint *shader = (GLuint *) bp; bp += 4;
weglCompileShader(*shader);
}; break;
-case 5448: { // glCreateProgram
+case 5449: { // glCreateProgram
GLuint result = weglCreateProgram();
int AP = 0; ErlDrvTermData rt[6];
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
@@ -3262,7 +3270,7 @@ case 5448: { // glCreateProgram
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5449: { // glCreateShader
+case 5450: { // glCreateShader
GLenum *type = (GLenum *) bp; bp += 4;
GLuint result = weglCreateShader(*type);
int AP = 0; ErlDrvTermData rt[6];
@@ -3271,28 +3279,28 @@ case 5449: { // glCreateShader
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5450: { // glDeleteProgram
+case 5451: { // glDeleteProgram
GLuint *program = (GLuint *) bp; bp += 4;
weglDeleteProgram(*program);
}; break;
-case 5451: { // glDeleteShader
+case 5452: { // glDeleteShader
GLuint *shader = (GLuint *) bp; bp += 4;
weglDeleteShader(*shader);
}; break;
-case 5452: { // glDetachShader
+case 5453: { // glDetachShader
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *shader = (GLuint *) bp; bp += 4;
weglDetachShader(*program,*shader);
}; break;
-case 5453: { // glDisableVertexAttribArray
+case 5454: { // glDisableVertexAttribArray
GLuint *index = (GLuint *) bp; bp += 4;
weglDisableVertexAttribArray(*index);
}; break;
-case 5454: { // glEnableVertexAttribArray
+case 5455: { // glEnableVertexAttribArray
GLuint *index = (GLuint *) bp; bp += 4;
weglEnableVertexAttribArray(*index);
}; break;
-case 5455: { // glGetActiveAttrib
+case 5456: { // glGetActiveAttrib
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -3312,7 +3320,7 @@ case 5455: { // glGetActiveAttrib
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5456: { // glGetActiveUniform
+case 5457: { // glGetActiveUniform
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -3332,7 +3340,7 @@ case 5456: { // glGetActiveUniform
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5457: { // glGetAttachedShaders
+case 5458: { // glGetAttachedShaders
GLuint *program = (GLuint *) bp; bp += 4;
GLsizei *maxCount = (GLsizei *) bp; bp += 4;
GLsizei count[1] = {0};
@@ -3350,7 +3358,7 @@ case 5457: { // glGetAttachedShaders
driver_free(rt);
driver_free(obj);
}; break;
-case 5458: { // glGetAttribLocation
+case 5459: { // glGetAttribLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
@@ -3361,7 +3369,7 @@ case 5458: { // glGetAttribLocation
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5459: { // glGetProgramiv
+case 5460: { // glGetProgramiv
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -3372,7 +3380,7 @@ case 5459: { // glGetProgramiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5460: { // glGetProgramInfoLog
+case 5461: { // glGetProgramInfoLog
GLuint *program = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -3386,7 +3394,7 @@ case 5460: { // glGetProgramInfoLog
driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
-case 5461: { // glGetShaderiv
+case 5462: { // glGetShaderiv
GLuint *shader = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -3397,7 +3405,7 @@ case 5461: { // glGetShaderiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5462: { // glGetShaderInfoLog
+case 5463: { // glGetShaderInfoLog
GLuint *shader = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -3411,7 +3419,7 @@ case 5462: { // glGetShaderInfoLog
driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
-case 5463: { // glGetShaderSource
+case 5464: { // glGetShaderSource
GLuint *shader = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -3425,7 +3433,7 @@ case 5463: { // glGetShaderSource
driver_send_term(port,caller,rt,AP);
driver_free(source);
}; break;
-case 5464: { // glGetUniformLocation
+case 5465: { // glGetUniformLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
@@ -3436,7 +3444,7 @@ case 5464: { // glGetUniformLocation
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5465: { // glGetUniformfv
+case 5466: { // glGetUniformfv
GLuint *program = (GLuint *) bp; bp += 4;
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};
@@ -3465,7 +3473,7 @@ case 5465: { // glGetUniformfv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5466: { // glGetUniformiv
+case 5467: { // glGetUniformiv
GLuint *program = (GLuint *) bp; bp += 4;
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};
@@ -3493,7 +3501,7 @@ case 5466: { // glGetUniformiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5467: { // glGetVertexAttribdv
+case 5468: { // glGetVertexAttribdv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLdouble params[4] = {0.0,0.0,0.0,0.0};
@@ -3509,7 +3517,7 @@ case 5467: { // glGetVertexAttribdv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5468: { // glGetVertexAttribfv
+case 5469: { // glGetVertexAttribfv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat params[4] = {0.0,0.0,0.0,0.0};
@@ -3526,7 +3534,7 @@ case 5468: { // glGetVertexAttribfv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5469: { // glGetVertexAttribiv
+case 5470: { // glGetVertexAttribiv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
@@ -3542,7 +3550,7 @@ case 5469: { // glGetVertexAttribiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5470: { // glIsProgram
+case 5471: { // glIsProgram
GLuint *program = (GLuint *) bp; bp += 4;
GLboolean result = weglIsProgram(*program);
int AP = 0; ErlDrvTermData rt[6];
@@ -3551,7 +3559,7 @@ case 5470: { // glIsProgram
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5471: { // glIsShader
+case 5472: { // glIsShader
GLuint *shader = (GLuint *) bp; bp += 4;
GLboolean result = weglIsShader(*shader);
int AP = 0; ErlDrvTermData rt[6];
@@ -3560,11 +3568,11 @@ case 5471: { // glIsShader
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5472: { // glLinkProgram
+case 5473: { // glLinkProgram
GLuint *program = (GLuint *) bp; bp += 4;
weglLinkProgram(*program);
}; break;
-case 5473: { // glShaderSource
+case 5474: { // glShaderSource
GLuint *shader = (GLuint *) bp; bp += 4;
int * stringLen = (int *) bp; bp += 4;
int * stringTotSize = (int *) bp; bp += 4;
@@ -3576,29 +3584,29 @@ case 5473: { // glShaderSource
weglShaderSource(*shader,*stringLen,(const GLchar **) string,NULL);
driver_free(string);
}; break;
-case 5474: { // glUseProgram
+case 5475: { // glUseProgram
GLuint *program = (GLuint *) bp; bp += 4;
weglUseProgram(*program);
}; break;
-case 5475: { // glUniform1f
+case 5476: { // glUniform1f
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
weglUniform1f(*location,*v0);
}; break;
-case 5476: { // glUniform2f
+case 5477: { // glUniform2f
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
GLfloat *v1 = (GLfloat *) bp; bp += 4;
weglUniform2f(*location,*v0,*v1);
}; break;
-case 5477: { // glUniform3f
+case 5478: { // glUniform3f
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
GLfloat *v1 = (GLfloat *) bp; bp += 4;
GLfloat *v2 = (GLfloat *) bp; bp += 4;
weglUniform3f(*location,*v0,*v1,*v2);
}; break;
-case 5478: { // glUniform4f
+case 5479: { // glUniform4f
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
GLfloat *v1 = (GLfloat *) bp; bp += 4;
@@ -3606,25 +3614,25 @@ case 5478: { // glUniform4f
GLfloat *v3 = (GLfloat *) bp; bp += 4;
weglUniform4f(*location,*v0,*v1,*v2,*v3);
}; break;
-case 5479: { // glUniform1i
+case 5480: { // glUniform1i
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
weglUniform1i(*location,*v0);
}; break;
-case 5480: { // glUniform2i
+case 5481: { // glUniform2i
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
GLint *v1 = (GLint *) bp; bp += 4;
weglUniform2i(*location,*v0,*v1);
}; break;
-case 5481: { // glUniform3i
+case 5482: { // glUniform3i
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
GLint *v1 = (GLint *) bp; bp += 4;
GLint *v2 = (GLint *) bp; bp += 4;
weglUniform3i(*location,*v0,*v1,*v2);
}; break;
-case 5482: { // glUniform4i
+case 5483: { // glUniform4i
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
GLint *v1 = (GLint *) bp; bp += 4;
@@ -3632,55 +3640,55 @@ case 5482: { // glUniform4i
GLint *v3 = (GLint *) bp; bp += 4;
weglUniform4i(*location,*v0,*v1,*v2,*v3);
}; break;
-case 5483: { // glUniform1fv
+case 5484: { // glUniform1fv
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 4;
- GLfloat * value = (GLfloat *) bp; bp += (8-((*valueLen*4+0)%8))%8;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*4 + (8-((*valueLen*4+0)%8))%8;
weglUniform1fv(*location,*valueLen,value);
}; break;
-case 5484: { // glUniform2fv
+case 5485: { // glUniform2fv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat * value = (GLfloat *) bp; bp += *valueLen*8;
weglUniform2fv(*location,*valueLen,value);
}; break;
-case 5485: { // glUniform3fv
+case 5486: { // glUniform3fv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat * value = (GLfloat *) bp; bp += *valueLen*12;
weglUniform3fv(*location,*valueLen,value);
}; break;
-case 5486: { // glUniform4fv
+case 5487: { // glUniform4fv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLfloat * value = (GLfloat *) bp; bp += *valueLen*16;
weglUniform4fv(*location,*valueLen,value);
}; break;
-case 5487: { // glUniform1iv
+case 5488: { // glUniform1iv
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 4;
- GLint * value = (GLint *) bp; bp += (8-((*valueLen*4+0)%8))%8;
+ GLint * value = (GLint *) bp; bp += *valueLen*4 + (8-((*valueLen*4+0)%8))%8;
weglUniform1iv(*location,*valueLen,value);
}; break;
-case 5488: { // glUniform2iv
+case 5489: { // glUniform2iv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint * value = (GLint *) bp; bp += *valueLen*8;
weglUniform2iv(*location,*valueLen,value);
}; break;
-case 5489: { // glUniform3iv
+case 5490: { // glUniform3iv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint * value = (GLint *) bp; bp += *valueLen*12;
weglUniform3iv(*location,*valueLen,value);
}; break;
-case 5490: { // glUniform4iv
+case 5491: { // glUniform4iv
GLint *location = (GLint *) bp; bp += 4;
int *valueLen = (int *) bp; bp += 4;
GLint * value = (GLint *) bp; bp += *valueLen*16;
weglUniform4iv(*location,*valueLen,value);
}; break;
-case 5491: { // glUniformMatrix2fv
+case 5492: { // glUniformMatrix2fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3688,7 +3696,7 @@ case 5491: { // glUniformMatrix2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*16;
weglUniformMatrix2fv(*location,*valueLen,*transpose,value);
}; break;
-case 5492: { // glUniformMatrix3fv
+case 5493: { // glUniformMatrix3fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3696,7 +3704,7 @@ case 5492: { // glUniformMatrix3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*36;
weglUniformMatrix3fv(*location,*valueLen,*transpose,value);
}; break;
-case 5493: { // glUniformMatrix4fv
+case 5494: { // glUniformMatrix4fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3704,130 +3712,130 @@ case 5493: { // glUniformMatrix4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*64;
weglUniformMatrix4fv(*location,*valueLen,*transpose,value);
}; break;
-case 5494: { // glValidateProgram
+case 5495: { // glValidateProgram
GLuint *program = (GLuint *) bp; bp += 4;
weglValidateProgram(*program);
}; break;
-case 5495: { // glVertexAttrib1dv
+case 5496: { // glVertexAttrib1dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttrib1dv(*index,v);
}; break;
-case 5496: { // glVertexAttrib1fv
+case 5497: { // glVertexAttrib1fv
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *v = (GLfloat *) bp; bp += 4;
weglVertexAttrib1fv(*index,v);
}; break;
-case 5497: { // glVertexAttrib1sv
+case 5498: { // glVertexAttrib1sv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort *v = (GLshort *) bp; bp += 2;
weglVertexAttrib1sv(*index,v);
}; break;
-case 5498: { // glVertexAttrib2dv
+case 5499: { // glVertexAttrib2dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttrib2dv(*index,v);
}; break;
-case 5499: { // glVertexAttrib2fv
+case 5500: { // glVertexAttrib2fv
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *v = (GLfloat *) bp; bp += 4;
weglVertexAttrib2fv(*index,v);
}; break;
-case 5500: { // glVertexAttrib2sv
+case 5501: { // glVertexAttrib2sv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort *v = (GLshort *) bp; bp += 2;
weglVertexAttrib2sv(*index,v);
}; break;
-case 5501: { // glVertexAttrib3dv
+case 5502: { // glVertexAttrib3dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttrib3dv(*index,v);
}; break;
-case 5502: { // glVertexAttrib3fv
+case 5503: { // glVertexAttrib3fv
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *v = (GLfloat *) bp; bp += 4;
weglVertexAttrib3fv(*index,v);
}; break;
-case 5503: { // glVertexAttrib3sv
+case 5504: { // glVertexAttrib3sv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort *v = (GLshort *) bp; bp += 2;
weglVertexAttrib3sv(*index,v);
}; break;
-case 5504: { // glVertexAttrib4Nbv
+case 5505: { // glVertexAttrib4Nbv
GLuint *index = (GLuint *) bp; bp += 4;
GLbyte * v = (GLbyte *) bp; bp += 4;
weglVertexAttrib4Nbv(*index,v);
}; break;
-case 5505: { // glVertexAttrib4Niv
+case 5506: { // glVertexAttrib4Niv
GLuint *index = (GLuint *) bp; bp += 4;
GLint * v = (GLint *) bp; bp += 16;
weglVertexAttrib4Niv(*index,v);
}; break;
-case 5506: { // glVertexAttrib4Nsv
+case 5507: { // glVertexAttrib4Nsv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort * v = (GLshort *) bp; bp += 8;
weglVertexAttrib4Nsv(*index,v);
}; break;
-case 5507: { // glVertexAttrib4Nubv
+case 5508: { // glVertexAttrib4Nubv
GLuint *index = (GLuint *) bp; bp += 4;
GLubyte * v = (GLubyte *) bp; bp += 4;
weglVertexAttrib4Nubv(*index,v);
}; break;
-case 5508: { // glVertexAttrib4Nuiv
+case 5509: { // glVertexAttrib4Nuiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint * v = (GLuint *) bp; bp += 16;
weglVertexAttrib4Nuiv(*index,v);
}; break;
-case 5509: { // glVertexAttrib4Nusv
+case 5510: { // glVertexAttrib4Nusv
GLuint *index = (GLuint *) bp; bp += 4;
GLushort * v = (GLushort *) bp; bp += 8;
weglVertexAttrib4Nusv(*index,v);
}; break;
-case 5510: { // glVertexAttrib4bv
+case 5511: { // glVertexAttrib4bv
GLuint *index = (GLuint *) bp; bp += 4;
GLbyte * v = (GLbyte *) bp; bp += 4;
weglVertexAttrib4bv(*index,v);
}; break;
-case 5511: { // glVertexAttrib4dv
+case 5512: { // glVertexAttrib4dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble * v = (GLdouble *) bp; bp += 32;
weglVertexAttrib4dv(*index,v);
}; break;
-case 5512: { // glVertexAttrib4fv
+case 5513: { // glVertexAttrib4fv
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat * v = (GLfloat *) bp; bp += 16;
weglVertexAttrib4fv(*index,v);
}; break;
-case 5513: { // glVertexAttrib4iv
+case 5514: { // glVertexAttrib4iv
GLuint *index = (GLuint *) bp; bp += 4;
GLint * v = (GLint *) bp; bp += 16;
weglVertexAttrib4iv(*index,v);
}; break;
-case 5514: { // glVertexAttrib4sv
+case 5515: { // glVertexAttrib4sv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort * v = (GLshort *) bp; bp += 8;
weglVertexAttrib4sv(*index,v);
}; break;
-case 5515: { // glVertexAttrib4ubv
+case 5516: { // glVertexAttrib4ubv
GLuint *index = (GLuint *) bp; bp += 4;
GLubyte * v = (GLubyte *) bp; bp += 4;
weglVertexAttrib4ubv(*index,v);
}; break;
-case 5516: { // glVertexAttrib4uiv
+case 5517: { // glVertexAttrib4uiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint * v = (GLuint *) bp; bp += 16;
weglVertexAttrib4uiv(*index,v);
}; break;
-case 5517: { // glVertexAttrib4usv
+case 5518: { // glVertexAttrib4usv
GLuint *index = (GLuint *) bp; bp += 4;
GLushort * v = (GLushort *) bp; bp += 8;
weglVertexAttrib4usv(*index,v);
}; break;
-case 5518: { // glVertexAttribPointer
+case 5519: { // glVertexAttribPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -3837,7 +3845,7 @@ case 5518: { // glVertexAttribPointer
GLvoid *pointer = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglVertexAttribPointer(*index,*size,*type,*normalized,*stride,pointer);
}; break;
-case 5519: { // glVertexAttribPointer
+case 5520: { // glVertexAttribPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -3847,7 +3855,7 @@ case 5519: { // glVertexAttribPointer
GLvoid *pointer = (GLvoid *) bins[0];
weglVertexAttribPointer(*index,*size,*type,*normalized,*stride,pointer);
}; break;
-case 5520: { // glUniformMatrix2x3fv
+case 5521: { // glUniformMatrix2x3fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3855,7 +3863,7 @@ case 5520: { // glUniformMatrix2x3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*24;
weglUniformMatrix2x3fv(*location,*valueLen,*transpose,value);
}; break;
-case 5521: { // glUniformMatrix3x2fv
+case 5522: { // glUniformMatrix3x2fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3863,7 +3871,7 @@ case 5521: { // glUniformMatrix3x2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*24;
weglUniformMatrix3x2fv(*location,*valueLen,*transpose,value);
}; break;
-case 5522: { // glUniformMatrix2x4fv
+case 5523: { // glUniformMatrix2x4fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3871,7 +3879,7 @@ case 5522: { // glUniformMatrix2x4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*32;
weglUniformMatrix2x4fv(*location,*valueLen,*transpose,value);
}; break;
-case 5523: { // glUniformMatrix4x2fv
+case 5524: { // glUniformMatrix4x2fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3879,7 +3887,7 @@ case 5523: { // glUniformMatrix4x2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*32;
weglUniformMatrix4x2fv(*location,*valueLen,*transpose,value);
}; break;
-case 5524: { // glUniformMatrix3x4fv
+case 5525: { // glUniformMatrix3x4fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3887,7 +3895,7 @@ case 5524: { // glUniformMatrix3x4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*48;
weglUniformMatrix3x4fv(*location,*valueLen,*transpose,value);
}; break;
-case 5525: { // glUniformMatrix4x3fv
+case 5526: { // glUniformMatrix4x3fv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -3895,7 +3903,7 @@ case 5525: { // glUniformMatrix4x3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*48;
weglUniformMatrix4x3fv(*location,*valueLen,*transpose,value);
}; break;
-case 5526: { // glColorMaski
+case 5527: { // glColorMaski
GLuint *index = (GLuint *) bp; bp += 4;
GLboolean *r = (GLboolean *) bp; bp += 1;
GLboolean *g = (GLboolean *) bp; bp += 1;
@@ -3903,7 +3911,7 @@ case 5526: { // glColorMaski
GLboolean *a = (GLboolean *) bp; bp += 1;
weglColorMaski(*index,*r,*g,*b,*a);
}; break;
-case 5527: { // glGetBooleani_v
+case 5528: { // glGetBooleani_v
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLboolean data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -3931,7 +3939,7 @@ case 5527: { // glGetBooleani_v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5528: { // glGetIntegeri_v
+case 5529: { // glGetIntegeri_v
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLint data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -3959,17 +3967,17 @@ case 5528: { // glGetIntegeri_v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5529: { // glEnablei
+case 5530: { // glEnablei
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
weglEnablei(*target,*index);
}; break;
-case 5530: { // glDisablei
+case 5531: { // glDisablei
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
weglDisablei(*target,*index);
}; break;
-case 5531: { // glIsEnabledi
+case 5532: { // glIsEnabledi
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLboolean result = weglIsEnabledi(*target,*index);
@@ -3979,14 +3987,14 @@ case 5531: { // glIsEnabledi
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5532: { // glBeginTransformFeedback
+case 5533: { // glBeginTransformFeedback
GLenum *primitiveMode = (GLenum *) bp; bp += 4;
weglBeginTransformFeedback(*primitiveMode);
}; break;
-case 5533: { // glEndTransformFeedback
+case 5534: { // glEndTransformFeedback
weglEndTransformFeedback();
}; break;
-case 5534: { // glBindBufferRange
+case 5535: { // glBindBufferRange
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *buffer = (GLuint *) bp; bp += 4;
@@ -3995,13 +4003,13 @@ case 5534: { // glBindBufferRange
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
weglBindBufferRange(*target,*index,*buffer,offset,size);
}; break;
-case 5535: { // glBindBufferBase
+case 5536: { // glBindBufferBase
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *buffer = (GLuint *) bp; bp += 4;
weglBindBufferBase(*target,*index,*buffer);
}; break;
-case 5536: { // glTransformFeedbackVaryings
+case 5537: { // glTransformFeedbackVaryings
GLuint *program = (GLuint *) bp; bp += 4;
int * varyingsLen = (int *) bp; bp += 4;
int * varyingsTotSize = (int *) bp; bp += 4;
@@ -4014,7 +4022,7 @@ case 5536: { // glTransformFeedbackVaryings
weglTransformFeedbackVaryings(*program,*varyingsLen,(const GLchar **) varyings,*bufferMode);
driver_free(varyings);
}; break;
-case 5537: { // glGetTransformFeedbackVarying
+case 5538: { // glGetTransformFeedbackVarying
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -4034,20 +4042,20 @@ case 5537: { // glGetTransformFeedbackVarying
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5538: { // glClampColor
+case 5539: { // glClampColor
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *clamp = (GLenum *) bp; bp += 4;
weglClampColor(*target,*clamp);
}; break;
-case 5539: { // glBeginConditionalRender
+case 5540: { // glBeginConditionalRender
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *mode = (GLenum *) bp; bp += 4;
weglBeginConditionalRender(*id,*mode);
}; break;
-case 5540: { // glEndConditionalRender
+case 5541: { // glEndConditionalRender
weglEndConditionalRender();
}; break;
-case 5541: { // glVertexAttribIPointer
+case 5542: { // glVertexAttribIPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -4055,7 +4063,7 @@ case 5541: { // glVertexAttribIPointer
GLvoid *pointer = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglVertexAttribIPointer(*index,*size,*type,*stride,pointer);
}; break;
-case 5542: { // glVertexAttribIPointer
+case 5543: { // glVertexAttribIPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -4063,7 +4071,7 @@ case 5542: { // glVertexAttribIPointer
GLvoid *pointer = (GLvoid *) bins[0];
weglVertexAttribIPointer(*index,*size,*type,*stride,pointer);
}; break;
-case 5543: { // glGetVertexAttribIiv
+case 5544: { // glGetVertexAttribIiv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
@@ -4079,7 +4087,7 @@ case 5543: { // glGetVertexAttribIiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5544: { // glGetVertexAttribIuiv
+case 5545: { // glGetVertexAttribIuiv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint params[4] = {0,0,0,0};
@@ -4095,67 +4103,67 @@ case 5544: { // glGetVertexAttribIuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5545: { // glVertexAttribI1iv
+case 5546: { // glVertexAttribI1iv
GLuint *index = (GLuint *) bp; bp += 4;
GLint *v = (GLint *) bp; bp += 4;
weglVertexAttribI1iv(*index,v);
}; break;
-case 5546: { // glVertexAttribI2iv
+case 5547: { // glVertexAttribI2iv
GLuint *index = (GLuint *) bp; bp += 4;
GLint *v = (GLint *) bp; bp += 4;
weglVertexAttribI2iv(*index,v);
}; break;
-case 5547: { // glVertexAttribI3iv
+case 5548: { // glVertexAttribI3iv
GLuint *index = (GLuint *) bp; bp += 4;
GLint *v = (GLint *) bp; bp += 4;
weglVertexAttribI3iv(*index,v);
}; break;
-case 5548: { // glVertexAttribI4iv
+case 5549: { // glVertexAttribI4iv
GLuint *index = (GLuint *) bp; bp += 4;
GLint * v = (GLint *) bp; bp += 16;
weglVertexAttribI4iv(*index,v);
}; break;
-case 5549: { // glVertexAttribI1uiv
+case 5550: { // glVertexAttribI1uiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *v = (GLuint *) bp; bp += 4;
weglVertexAttribI1uiv(*index,v);
}; break;
-case 5550: { // glVertexAttribI2uiv
+case 5551: { // glVertexAttribI2uiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *v = (GLuint *) bp; bp += 4;
weglVertexAttribI2uiv(*index,v);
}; break;
-case 5551: { // glVertexAttribI3uiv
+case 5552: { // glVertexAttribI3uiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *v = (GLuint *) bp; bp += 4;
weglVertexAttribI3uiv(*index,v);
}; break;
-case 5552: { // glVertexAttribI4uiv
+case 5553: { // glVertexAttribI4uiv
GLuint *index = (GLuint *) bp; bp += 4;
GLuint * v = (GLuint *) bp; bp += 16;
weglVertexAttribI4uiv(*index,v);
}; break;
-case 5553: { // glVertexAttribI4bv
+case 5554: { // glVertexAttribI4bv
GLuint *index = (GLuint *) bp; bp += 4;
GLbyte * v = (GLbyte *) bp; bp += 4;
weglVertexAttribI4bv(*index,v);
}; break;
-case 5554: { // glVertexAttribI4sv
+case 5555: { // glVertexAttribI4sv
GLuint *index = (GLuint *) bp; bp += 4;
GLshort * v = (GLshort *) bp; bp += 8;
weglVertexAttribI4sv(*index,v);
}; break;
-case 5555: { // glVertexAttribI4ubv
+case 5556: { // glVertexAttribI4ubv
GLuint *index = (GLuint *) bp; bp += 4;
GLubyte * v = (GLubyte *) bp; bp += 4;
weglVertexAttribI4ubv(*index,v);
}; break;
-case 5556: { // glVertexAttribI4usv
+case 5557: { // glVertexAttribI4usv
GLuint *index = (GLuint *) bp; bp += 4;
GLushort * v = (GLushort *) bp; bp += 8;
weglVertexAttribI4usv(*index,v);
}; break;
-case 5557: { // glGetUniformuiv
+case 5558: { // 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};
@@ -4183,14 +4191,14 @@ case 5557: { // glGetUniformuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5558: { // glBindFragDataLocation
+case 5559: { // glBindFragDataLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *color = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
weglBindFragDataLocation(*program,*color,name);
}; break;
-case 5559: { // glGetFragDataLocation
+case 5560: { // glGetFragDataLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
@@ -4201,25 +4209,25 @@ case 5559: { // glGetFragDataLocation
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5560: { // glUniform1ui
+case 5561: { // glUniform1ui
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
weglUniform1ui(*location,*v0);
}; break;
-case 5561: { // glUniform2ui
+case 5562: { // 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 5562: { // glUniform3ui
+case 5563: { // 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 5563: { // glUniform4ui
+case 5564: { // glUniform4ui
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
GLuint *v1 = (GLuint *) bp; bp += 4;
@@ -4227,45 +4235,45 @@ case 5563: { // glUniform4ui
GLuint *v3 = (GLuint *) bp; bp += 4;
weglUniform4ui(*location,*v0,*v1,*v2,*v3);
}; break;
-case 5564: { // glUniform1uiv
+case 5565: { // glUniform1uiv
GLint *location = (GLint *) bp; bp += 4;
int * valueLen = (int *) bp; bp += 4;
- GLuint * value = (GLuint *) bp; bp += (8-((*valueLen*4+0)%8))%8;
+ GLuint * value = (GLuint *) bp; bp += *valueLen*4 + (8-((*valueLen*4+0)%8))%8;
weglUniform1uiv(*location,*valueLen,value);
}; break;
-case 5565: { // glUniform2uiv
+case 5566: { // 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 5566: { // glUniform3uiv
+case 5567: { // 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 5567: { // glUniform4uiv
+case 5568: { // 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 5568: { // glTexParameterIiv
+case 5569: { // 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 5569: { // glTexParameterIuiv
+case 5570: { // 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 5570: { // glGetTexParameterIiv
+case 5571: { // glGetTexParameterIiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
@@ -4281,7 +4289,7 @@ case 5570: { // glGetTexParameterIiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5571: { // glGetTexParameterIuiv
+case 5572: { // glGetTexParameterIuiv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint params[4] = {0,0,0,0};
@@ -4297,35 +4305,35 @@ case 5571: { // glGetTexParameterIuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5572: { // glClearBufferiv
+case 5573: { // 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 5573: { // glClearBufferuiv
+case 5574: { // 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 5574: { // glClearBufferfv
+case 5575: { // 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 5575: { // glClearBufferfi
+case 5576: { // 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 5576: { // glGetStringi
+case 5577: { // glGetStringi
GLenum *name = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
const GLubyte * result = weglGetStringi(*name,*index);
@@ -4335,14 +4343,14 @@ case 5576: { // glGetStringi
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5577: { // glDrawArraysInstanced
+case 5578: { // glDrawArraysInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLint *first = (GLint *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawArraysInstanced(*mode,*first,*count,*primcount);
}; break;
-case 5578: { // glDrawElementsInstanced
+case 5579: { // glDrawElementsInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -4350,7 +4358,7 @@ case 5578: { // glDrawElementsInstanced
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawElementsInstanced(*mode,*count,*type,indices,*primcount);
}; break;
-case 5579: { // glDrawElementsInstanced
+case 5580: { // glDrawElementsInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -4358,17 +4366,17 @@ case 5579: { // glDrawElementsInstanced
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawElementsInstanced(*mode,*count,*type,indices,*primcount);
}; break;
-case 5580: { // glTexBuffer
+case 5581: { // glTexBuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
GLuint *buffer = (GLuint *) bp; bp += 4;
weglTexBuffer(*target,*internalformat,*buffer);
}; break;
-case 5581: { // glPrimitiveRestartIndex
+case 5582: { // glPrimitiveRestartIndex
GLuint *index = (GLuint *) bp; bp += 4;
weglPrimitiveRestartIndex(*index);
}; break;
-case 5582: { // glGetInteger64i_v
+case 5583: { // 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};
@@ -4396,7 +4404,7 @@ case 5582: { // glGetInteger64i_v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5583: { // glGetBufferParameteri64v
+case 5584: { // 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};
@@ -4424,40 +4432,40 @@ case 5583: { // glGetBufferParameteri64v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5584: { // glFramebufferTexture
+case 5585: { // 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
+case 5586: { // glVertexAttribDivisor
GLuint *index = (GLuint *) bp; bp += 4;
GLuint *divisor = (GLuint *) bp; bp += 4;
weglVertexAttribDivisor(*index,*divisor);
}; break;
-case 5586: { // glMinSampleShading
+case 5587: { // glMinSampleShading
GLclampf *value = (GLclampf *) bp; bp += 4;
weglMinSampleShading(*value);
}; break;
-case 5587: { // glBlendEquationi
+case 5588: { // glBlendEquationi
GLuint *buf = (GLuint *) bp; bp += 4;
GLenum *mode = (GLenum *) bp; bp += 4;
weglBlendEquationi(*buf,*mode);
}; break;
-case 5588: { // glBlendEquationSeparatei
+case 5589: { // 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
+case 5590: { // 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
+case 5591: { // glBlendFuncSeparatei
GLuint *buf = (GLuint *) bp; bp += 4;
GLenum *srcRGB = (GLenum *) bp; bp += 4;
GLenum *dstRGB = (GLenum *) bp; bp += 4;
@@ -4465,103 +4473,103 @@ case 5590: { // glBlendFuncSeparatei
GLenum *dstAlpha = (GLenum *) bp; bp += 4;
weglBlendFuncSeparatei(*buf,*srcRGB,*dstRGB,*srcAlpha,*dstAlpha);
}; break;
-case 5591: { // glLoadTransposeMatrixfARB
+case 5592: { // glLoadTransposeMatrixfARB
GLfloat * m = (GLfloat *) bp; bp += 64;
weglLoadTransposeMatrixfARB(m);
}; break;
-case 5592: { // glLoadTransposeMatrixdARB
+case 5593: { // glLoadTransposeMatrixdARB
GLdouble * m = (GLdouble *) bp; bp += 128;
weglLoadTransposeMatrixdARB(m);
}; break;
-case 5593: { // glMultTransposeMatrixfARB
+case 5594: { // glMultTransposeMatrixfARB
GLfloat * m = (GLfloat *) bp; bp += 64;
weglMultTransposeMatrixfARB(m);
}; break;
-case 5594: { // glMultTransposeMatrixdARB
+case 5595: { // glMultTransposeMatrixdARB
GLdouble * m = (GLdouble *) bp; bp += 128;
weglMultTransposeMatrixdARB(m);
}; break;
-case 5595: { // glWeightbvARB
+case 5596: { // glWeightbvARB
int * weightsLen = (int *) bp; bp += 4;
- GLbyte * weights = (GLbyte *) bp; bp += (8-((*weightsLen*1+4)%8))%8;
+ GLbyte * weights = (GLbyte *) bp; bp += *weightsLen*1 + (8-((*weightsLen*1+4)%8))%8;
weglWeightbvARB(*weightsLen,weights);
}; break;
-case 5596: { // glWeightsvARB
+case 5597: { // glWeightsvARB
int * weightsLen = (int *) bp; bp += 4;
- GLshort * weights = (GLshort *) bp; bp += (8-((*weightsLen*2+4)%8))%8;
+ GLshort * weights = (GLshort *) bp; bp += *weightsLen*2 + (8-((*weightsLen*2+4)%8))%8;
weglWeightsvARB(*weightsLen,weights);
}; break;
-case 5597: { // glWeightivARB
+case 5598: { // glWeightivARB
int * weightsLen = (int *) bp; bp += 4;
- GLint * weights = (GLint *) bp; bp += (8-((*weightsLen*4+4)%8))%8;
+ GLint * weights = (GLint *) bp; bp += *weightsLen*4 + (8-((*weightsLen*4+4)%8))%8;
weglWeightivARB(*weightsLen,weights);
}; break;
-case 5598: { // glWeightfvARB
+case 5599: { // glWeightfvARB
int * weightsLen = (int *) bp; bp += 4;
- GLfloat * weights = (GLfloat *) bp; bp += (8-((*weightsLen*4+4)%8))%8;
+ GLfloat * weights = (GLfloat *) bp; bp += *weightsLen*4 + (8-((*weightsLen*4+4)%8))%8;
weglWeightfvARB(*weightsLen,weights);
}; break;
-case 5599: { // glWeightdvARB
+case 5600: { // glWeightdvARB
int * weightsLen = (int *) bp; bp += 8;
- GLdouble * weights = (GLdouble *) bp; bp += (8-((*weightsLen*8+0)%8))%8;
+ GLdouble * weights = (GLdouble *) bp; bp += *weightsLen*8 + (8-((*weightsLen*8+0)%8))%8;
weglWeightdvARB(*weightsLen,weights);
}; break;
-case 5600: { // glWeightubvARB
+case 5601: { // glWeightubvARB
int * weightsLen = (int *) bp; bp += 4;
- GLubyte * weights = (GLubyte *) bp; bp += (8-((*weightsLen*1+4)%8))%8;
+ GLubyte * weights = (GLubyte *) bp; bp += *weightsLen*1 + (8-((*weightsLen*1+4)%8))%8;
weglWeightubvARB(*weightsLen,weights);
}; break;
-case 5601: { // glWeightusvARB
+case 5602: { // glWeightusvARB
int * weightsLen = (int *) bp; bp += 4;
- GLushort * weights = (GLushort *) bp; bp += (8-((*weightsLen*2+4)%8))%8;
+ GLushort * weights = (GLushort *) bp; bp += *weightsLen*2 + (8-((*weightsLen*2+4)%8))%8;
weglWeightusvARB(*weightsLen,weights);
}; break;
-case 5602: { // glWeightuivARB
+case 5603: { // glWeightuivARB
int * weightsLen = (int *) bp; bp += 4;
- GLuint * weights = (GLuint *) bp; bp += (8-((*weightsLen*4+4)%8))%8;
+ GLuint * weights = (GLuint *) bp; bp += *weightsLen*4 + (8-((*weightsLen*4+4)%8))%8;
weglWeightuivARB(*weightsLen,weights);
}; break;
-case 5603: { // glVertexBlendARB
+case 5604: { // glVertexBlendARB
GLint *count = (GLint *) bp; bp += 4;
weglVertexBlendARB(*count);
}; break;
-case 5604: { // glCurrentPaletteMatrixARB
+case 5605: { // glCurrentPaletteMatrixARB
GLint *index = (GLint *) bp; bp += 4;
weglCurrentPaletteMatrixARB(*index);
}; break;
-case 5605: { // glMatrixIndexubvARB
+case 5606: { // glMatrixIndexubvARB
int * indicesLen = (int *) bp; bp += 4;
- GLubyte * indices = (GLubyte *) bp; bp += (8-((*indicesLen*1+4)%8))%8;
+ GLubyte * indices = (GLubyte *) bp; bp += *indicesLen*1 + (8-((*indicesLen*1+4)%8))%8;
weglMatrixIndexubvARB(*indicesLen,indices);
}; break;
-case 5606: { // glMatrixIndexusvARB
+case 5607: { // glMatrixIndexusvARB
int * indicesLen = (int *) bp; bp += 4;
- GLushort * indices = (GLushort *) bp; bp += (8-((*indicesLen*2+4)%8))%8;
+ GLushort * indices = (GLushort *) bp; bp += *indicesLen*2 + (8-((*indicesLen*2+4)%8))%8;
weglMatrixIndexusvARB(*indicesLen,indices);
}; break;
-case 5607: { // glMatrixIndexuivARB
+case 5608: { // glMatrixIndexuivARB
int * indicesLen = (int *) bp; bp += 4;
- GLuint * indices = (GLuint *) bp; bp += (8-((*indicesLen*4+4)%8))%8;
+ GLuint * indices = (GLuint *) bp; bp += *indicesLen*4 + (8-((*indicesLen*4+4)%8))%8;
weglMatrixIndexuivARB(*indicesLen,indices);
}; break;
-case 5608: { // glProgramStringARB
+case 5609: { // glProgramStringARB
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *format = (GLenum *) bp; bp += 4;
GLvoid *string = (GLvoid *) bp;
int stringLen[1] = {(int)strlen((char *)string)}; bp += stringLen[0]+1+((8-((1+stringLen[0]+0)%8))%8);
weglProgramStringARB(*target,*format,*stringLen,string);
}; break;
-case 5609: { // glBindProgramARB
+case 5610: { // glBindProgramARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *program = (GLuint *) bp; bp += 4;
weglBindProgramARB(*target,*program);
}; break;
-case 5610: { // glDeleteProgramsARB
+case 5611: { // glDeleteProgramsARB
int * programsLen = (int *) bp; bp += 4;
- GLuint * programs = (GLuint *) bp; bp += (8-((*programsLen*4+4)%8))%8;
+ GLuint * programs = (GLuint *) bp; bp += *programsLen*4 + (8-((*programsLen*4+4)%8))%8;
weglDeleteProgramsARB(*programsLen,programs);
}; break;
-case 5611: { // glGenProgramsARB
+case 5612: { // glGenProgramsARB
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *programs;
programs = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -4577,7 +4585,7 @@ case 5611: { // glGenProgramsARB
driver_free(rt);
driver_free(programs);
}; break;
-case 5612: { // glProgramEnvParameter4dARB
+case 5613: { // glProgramEnvParameter4dARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
@@ -4586,13 +4594,13 @@ case 5612: { // glProgramEnvParameter4dARB
GLdouble *w = (GLdouble *) bp; bp += 8;
weglProgramEnvParameter4dARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5613: { // glProgramEnvParameter4dvARB
+case 5614: { // 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 5614: { // glProgramEnvParameter4fARB
+case 5615: { // glProgramEnvParameter4fARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *x = (GLfloat *) bp; bp += 4;
@@ -4601,13 +4609,13 @@ case 5614: { // glProgramEnvParameter4fARB
GLfloat *w = (GLfloat *) bp; bp += 4;
weglProgramEnvParameter4fARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5615: { // glProgramEnvParameter4fvARB
+case 5616: { // 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 5616: { // glProgramLocalParameter4dARB
+case 5617: { // glProgramLocalParameter4dARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
@@ -4616,13 +4624,13 @@ case 5616: { // glProgramLocalParameter4dARB
GLdouble *w = (GLdouble *) bp; bp += 8;
weglProgramLocalParameter4dARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5617: { // glProgramLocalParameter4dvARB
+case 5618: { // 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 5618: { // glProgramLocalParameter4fARB
+case 5619: { // glProgramLocalParameter4fARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *x = (GLfloat *) bp; bp += 4;
@@ -4631,13 +4639,13 @@ case 5618: { // glProgramLocalParameter4fARB
GLfloat *w = (GLfloat *) bp; bp += 4;
weglProgramLocalParameter4fARB(*target,*index,*x,*y,*z,*w);
}; break;
-case 5619: { // glProgramLocalParameter4fvARB
+case 5620: { // 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 5620: { // glGetProgramEnvParameterdvARB
+case 5621: { // glGetProgramEnvParameterdvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble params[4] = {0.0,0.0,0.0,0.0};
@@ -4653,7 +4661,7 @@ case 5620: { // glGetProgramEnvParameterdvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5621: { // glGetProgramEnvParameterfvARB
+case 5622: { // glGetProgramEnvParameterfvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat params[4] = {0.0,0.0,0.0,0.0};
@@ -4670,7 +4678,7 @@ case 5621: { // glGetProgramEnvParameterfvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5622: { // glGetProgramLocalParameterdvARB
+case 5623: { // glGetProgramLocalParameterdvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLdouble params[4] = {0.0,0.0,0.0,0.0};
@@ -4686,7 +4694,7 @@ case 5622: { // glGetProgramLocalParameterdvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5623: { // glGetProgramLocalParameterfvARB
+case 5624: { // glGetProgramLocalParameterfvARB
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat params[4] = {0.0,0.0,0.0,0.0};
@@ -4703,7 +4711,7 @@ case 5623: { // glGetProgramLocalParameterfvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5624: { // glGetProgramStringARB
+case 5625: { // glGetProgramStringARB
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLvoid *string = (GLvoid *) bins[0];
@@ -4714,7 +4722,7 @@ case 5624: { // glGetProgramStringARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5625: { // glGetBufferParameterivARB
+case 5626: { // 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};
@@ -4742,11 +4750,11 @@ case 5625: { // glGetBufferParameterivARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5626: { // glDeleteObjectARB
+case 5627: { // glDeleteObjectARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglDeleteObjectARB(obj);
}; break;
-case 5627: { // glGetHandleARB
+case 5628: { // glGetHandleARB
GLenum *pname = (GLenum *) bp; bp += 4;
GLhandleARB result = weglGetHandleARB(*pname);
int AP = 0; ErlDrvTermData rt[6];
@@ -4755,12 +4763,12 @@ case 5627: { // glGetHandleARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5628: { // glDetachObjectARB
+case 5629: { // glDetachObjectARB
GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLhandleARB attachedObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglDetachObjectARB(containerObj,attachedObj);
}; break;
-case 5629: { // glCreateShaderObjectARB
+case 5630: { // glCreateShaderObjectARB
GLenum *shaderType = (GLenum *) bp; bp += 4;
GLhandleARB result = weglCreateShaderObjectARB(*shaderType);
int AP = 0; ErlDrvTermData rt[6];
@@ -4769,7 +4777,7 @@ case 5629: { // glCreateShaderObjectARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5630: { // glShaderSourceARB
+case 5631: { // glShaderSourceARB
GLhandleARB shaderObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
int * stringLen = (int *) bp; bp += 4;
int * stringTotSize = (int *) bp; bp += 4;
@@ -4781,11 +4789,11 @@ case 5630: { // glShaderSourceARB
weglShaderSourceARB(shaderObj,*stringLen,(const GLchar **) string,NULL);
driver_free(string);
}; break;
-case 5631: { // glCompileShaderARB
+case 5632: { // glCompileShaderARB
GLhandleARB shaderObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglCompileShaderARB(shaderObj);
}; break;
-case 5632: { // glCreateProgramObjectARB
+case 5633: { // glCreateProgramObjectARB
GLhandleARB result = weglCreateProgramObjectARB();
int AP = 0; ErlDrvTermData rt[6];
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
@@ -4793,24 +4801,24 @@ case 5632: { // glCreateProgramObjectARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5633: { // glAttachObjectARB
+case 5634: { // glAttachObjectARB
GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglAttachObjectARB(containerObj,obj);
}; break;
-case 5634: { // glLinkProgramARB
+case 5635: { // glLinkProgramARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglLinkProgramARB(programObj);
}; break;
-case 5635: { // glUseProgramObjectARB
+case 5636: { // glUseProgramObjectARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglUseProgramObjectARB(programObj);
}; break;
-case 5636: { // glValidateProgramARB
+case 5637: { // glValidateProgramARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
weglValidateProgramARB(programObj);
}; break;
-case 5637: { // glGetObjectParameterfvARB
+case 5638: { // glGetObjectParameterfvARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat params[1] = {0.0};
@@ -4822,7 +4830,7 @@ case 5637: { // glGetObjectParameterfvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5638: { // glGetObjectParameterivARB
+case 5639: { // glGetObjectParameterivARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -4833,7 +4841,7 @@ case 5638: { // glGetObjectParameterivARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5639: { // glGetInfoLogARB
+case 5640: { // glGetInfoLogARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -4847,7 +4855,7 @@ case 5639: { // glGetInfoLogARB
driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
-case 5640: { // glGetAttachedObjectsARB
+case 5641: { // glGetAttachedObjectsARB
GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLsizei *maxCount = (GLsizei *) bp; bp += 4;
GLsizei count[1] = {0};
@@ -4865,7 +4873,7 @@ case 5640: { // glGetAttachedObjectsARB
driver_free(rt);
driver_free(obj);
}; break;
-case 5641: { // glGetUniformLocationARB
+case 5642: { // glGetUniformLocationARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
@@ -4876,7 +4884,7 @@ case 5641: { // glGetUniformLocationARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5642: { // glGetActiveUniformARB
+case 5643: { // glGetActiveUniformARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
@@ -4896,7 +4904,7 @@ case 5642: { // glGetActiveUniformARB
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5643: { // glGetUniformfvARB
+case 5644: { // 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};
@@ -4925,7 +4933,7 @@ case 5643: { // glGetUniformfvARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5644: { // glGetUniformivARB
+case 5645: { // 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};
@@ -4953,7 +4961,7 @@ case 5644: { // glGetUniformivARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5645: { // glGetShaderSourceARB
+case 5646: { // glGetShaderSourceARB
GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -4967,14 +4975,14 @@ case 5645: { // glGetShaderSourceARB
driver_send_term(port,caller,rt,AP);
driver_free(source);
}; break;
-case 5646: { // glBindAttribLocationARB
+case 5647: { // glBindAttribLocationARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLuint *index = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
weglBindAttribLocationARB(programObj,*index,name);
}; break;
-case 5647: { // glGetActiveAttribARB
+case 5648: { // glGetActiveAttribARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLuint *index = (GLuint *) bp; bp += 4;
GLsizei *maxLength = (GLsizei *) bp; bp += 4;
@@ -4994,7 +5002,7 @@ case 5647: { // glGetActiveAttribARB
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5648: { // glGetAttribLocationARB
+case 5649: { // glGetAttribLocationARB
GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
@@ -5005,7 +5013,7 @@ case 5648: { // glGetAttribLocationARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5649: { // glIsRenderbuffer
+case 5650: { // glIsRenderbuffer
GLuint *renderbuffer = (GLuint *) bp; bp += 4;
GLboolean result = weglIsRenderbuffer(*renderbuffer);
int AP = 0; ErlDrvTermData rt[6];
@@ -5014,17 +5022,17 @@ case 5649: { // glIsRenderbuffer
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5650: { // glBindRenderbuffer
+case 5651: { // glBindRenderbuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *renderbuffer = (GLuint *) bp; bp += 4;
weglBindRenderbuffer(*target,*renderbuffer);
}; break;
-case 5651: { // glDeleteRenderbuffers
+case 5652: { // glDeleteRenderbuffers
int * renderbuffersLen = (int *) bp; bp += 4;
- GLuint * renderbuffers = (GLuint *) bp; bp += (8-((*renderbuffersLen*4+4)%8))%8;
+ GLuint * renderbuffers = (GLuint *) bp; bp += *renderbuffersLen*4 + (8-((*renderbuffersLen*4+4)%8))%8;
weglDeleteRenderbuffers(*renderbuffersLen,renderbuffers);
}; break;
-case 5652: { // glGenRenderbuffers
+case 5653: { // glGenRenderbuffers
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *renderbuffers;
renderbuffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -5040,14 +5048,14 @@ case 5652: { // glGenRenderbuffers
driver_free(rt);
driver_free(renderbuffers);
}; break;
-case 5653: { // glRenderbufferStorage
+case 5654: { // 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 5654: { // glGetRenderbufferParameteriv
+case 5655: { // glGetRenderbufferParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -5058,7 +5066,7 @@ case 5654: { // glGetRenderbufferParameteriv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5655: { // glIsFramebuffer
+case 5656: { // glIsFramebuffer
GLuint *framebuffer = (GLuint *) bp; bp += 4;
GLboolean result = weglIsFramebuffer(*framebuffer);
int AP = 0; ErlDrvTermData rt[6];
@@ -5067,17 +5075,17 @@ case 5655: { // glIsFramebuffer
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5656: { // glBindFramebuffer
+case 5657: { // glBindFramebuffer
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *framebuffer = (GLuint *) bp; bp += 4;
weglBindFramebuffer(*target,*framebuffer);
}; break;
-case 5657: { // glDeleteFramebuffers
+case 5658: { // glDeleteFramebuffers
int * framebuffersLen = (int *) bp; bp += 4;
- GLuint * framebuffers = (GLuint *) bp; bp += (8-((*framebuffersLen*4+4)%8))%8;
+ GLuint * framebuffers = (GLuint *) bp; bp += *framebuffersLen*4 + (8-((*framebuffersLen*4+4)%8))%8;
weglDeleteFramebuffers(*framebuffersLen,framebuffers);
}; break;
-case 5658: { // glGenFramebuffers
+case 5659: { // glGenFramebuffers
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *framebuffers;
framebuffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -5093,7 +5101,7 @@ case 5658: { // glGenFramebuffers
driver_free(rt);
driver_free(framebuffers);
}; break;
-case 5659: { // glCheckFramebufferStatus
+case 5660: { // glCheckFramebufferStatus
GLenum *target = (GLenum *) bp; bp += 4;
GLenum result = weglCheckFramebufferStatus(*target);
int AP = 0; ErlDrvTermData rt[6];
@@ -5102,7 +5110,7 @@ case 5659: { // glCheckFramebufferStatus
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5660: { // glFramebufferTexture1D
+case 5661: { // glFramebufferTexture1D
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *textarget = (GLenum *) bp; bp += 4;
@@ -5110,7 +5118,7 @@ case 5660: { // glFramebufferTexture1D
GLint *level = (GLint *) bp; bp += 4;
weglFramebufferTexture1D(*target,*attachment,*textarget,*texture,*level);
}; break;
-case 5661: { // glFramebufferTexture2D
+case 5662: { // glFramebufferTexture2D
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *textarget = (GLenum *) bp; bp += 4;
@@ -5118,7 +5126,7 @@ case 5661: { // glFramebufferTexture2D
GLint *level = (GLint *) bp; bp += 4;
weglFramebufferTexture2D(*target,*attachment,*textarget,*texture,*level);
}; break;
-case 5662: { // glFramebufferTexture3D
+case 5663: { // glFramebufferTexture3D
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *textarget = (GLenum *) bp; bp += 4;
@@ -5127,14 +5135,14 @@ case 5662: { // glFramebufferTexture3D
GLint *zoffset = (GLint *) bp; bp += 4;
weglFramebufferTexture3D(*target,*attachment,*textarget,*texture,*level,*zoffset);
}; break;
-case 5663: { // glFramebufferRenderbuffer
+case 5664: { // 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 5664: { // glGetFramebufferAttachmentParameteriv
+case 5665: { // glGetFramebufferAttachmentParameteriv
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -5146,11 +5154,11 @@ case 5664: { // glGetFramebufferAttachmentParameteriv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5665: { // glGenerateMipmap
+case 5666: { // glGenerateMipmap
GLenum *target = (GLenum *) bp; bp += 4;
weglGenerateMipmap(*target);
}; break;
-case 5666: { // glBlitFramebuffer
+case 5667: { // glBlitFramebuffer
GLint *srcX0 = (GLint *) bp; bp += 4;
GLint *srcY0 = (GLint *) bp; bp += 4;
GLint *srcX1 = (GLint *) bp; bp += 4;
@@ -5163,7 +5171,7 @@ case 5666: { // glBlitFramebuffer
GLenum *filter = (GLenum *) bp; bp += 4;
weglBlitFramebuffer(*srcX0,*srcY0,*srcX1,*srcY1,*dstX0,*dstY0,*dstX1,*dstY1,*mask,*filter);
}; break;
-case 5667: { // glRenderbufferStorageMultisample
+case 5668: { // glRenderbufferStorageMultisample
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *samples = (GLsizei *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
@@ -5171,7 +5179,7 @@ case 5667: { // glRenderbufferStorageMultisample
GLsizei *height = (GLsizei *) bp; bp += 4;
weglRenderbufferStorageMultisample(*target,*samples,*internalformat,*width,*height);
}; break;
-case 5668: { // glFramebufferTextureLayer
+case 5669: { // glFramebufferTextureLayer
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLuint *texture = (GLuint *) bp; bp += 4;
@@ -5179,7 +5187,7 @@ case 5668: { // glFramebufferTextureLayer
GLint *layer = (GLint *) bp; bp += 4;
weglFramebufferTextureLayer(*target,*attachment,*texture,*level,*layer);
}; break;
-case 5669: { // glFramebufferTextureFaceARB
+case 5670: { // glFramebufferTextureFaceARB
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *attachment = (GLenum *) bp; bp += 4;
GLuint *texture = (GLuint *) bp; bp += 4;
@@ -5187,23 +5195,23 @@ case 5669: { // glFramebufferTextureFaceARB
GLenum *face = (GLenum *) bp; bp += 4;
weglFramebufferTextureFaceARB(*target,*attachment,*texture,*level,*face);
}; break;
-case 5670: { // glFlushMappedBufferRange
+case 5671: { // 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 5671: { // glBindVertexArray
+case 5672: { // glBindVertexArray
GLuint *array = (GLuint *) bp; bp += 4;
weglBindVertexArray(*array);
}; break;
-case 5672: { // glDeleteVertexArrays
+case 5673: { // glDeleteVertexArrays
int * arraysLen = (int *) bp; bp += 4;
- GLuint * arrays = (GLuint *) bp; bp += (8-((*arraysLen*4+4)%8))%8;
+ GLuint * arrays = (GLuint *) bp; bp += *arraysLen*4 + (8-((*arraysLen*4+4)%8))%8;
weglDeleteVertexArrays(*arraysLen,arrays);
}; break;
-case 5673: { // glGenVertexArrays
+case 5674: { // glGenVertexArrays
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *arrays;
arrays = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -5219,7 +5227,7 @@ case 5673: { // glGenVertexArrays
driver_free(rt);
driver_free(arrays);
}; break;
-case 5674: { // glIsVertexArray
+case 5675: { // glIsVertexArray
GLuint *array = (GLuint *) bp; bp += 4;
GLboolean result = weglIsVertexArray(*array);
int AP = 0; ErlDrvTermData rt[6];
@@ -5228,7 +5236,7 @@ case 5674: { // glIsVertexArray
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5675: { // glGetUniformIndices
+case 5676: { // glGetUniformIndices
GLuint *program = (GLuint *) bp; bp += 4;
int * uniformNamesLen = (int *) bp; bp += 4;
int * uniformNamesTotSize = (int *) bp; bp += 4;
@@ -5252,10 +5260,10 @@ case 5675: { // glGetUniformIndices
driver_free(uniformIndices);
driver_free(uniformNames);
}; break;
-case 5676: { // glGetActiveUniformsiv
+case 5677: { // glGetActiveUniformsiv
GLuint *program = (GLuint *) bp; bp += 4;
int * uniformIndicesLen = (int *) bp; bp += 4;
- GLuint * uniformIndices = (GLuint *) bp; bp += (8-((*uniformIndicesLen*4+0)%8))%8;
+ GLuint * uniformIndices = (GLuint *) bp; bp += *uniformIndicesLen*4 + (8-((*uniformIndicesLen*4+0)%8))%8;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint *params;
params = (GLint *) driver_alloc(sizeof(GLint) * *uniformIndicesLen);
@@ -5271,7 +5279,7 @@ case 5676: { // glGetActiveUniformsiv
driver_free(rt);
driver_free(params);
}; break;
-case 5677: { // glGetActiveUniformName
+case 5678: { // glGetActiveUniformName
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformIndex = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -5286,7 +5294,7 @@ case 5677: { // glGetActiveUniformName
driver_send_term(port,caller,rt,AP);
driver_free(uniformName);
}; break;
-case 5678: { // glGetUniformBlockIndex
+case 5679: { // glGetUniformBlockIndex
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *uniformBlockName = (GLchar *) bp;
int uniformBlockNameLen[1] = {(int)strlen((char *)uniformBlockName)}; bp += uniformBlockNameLen[0]+1+((8-((1+uniformBlockNameLen[0]+4)%8))%8);
@@ -5297,7 +5305,7 @@ case 5678: { // glGetUniformBlockIndex
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5679: { // glGetActiveUniformBlockiv
+case 5680: { // glGetActiveUniformBlockiv
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -5309,7 +5317,7 @@ case 5679: { // glGetActiveUniformBlockiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5680: { // glGetActiveUniformBlockName
+case 5681: { // glGetActiveUniformBlockName
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -5324,13 +5332,13 @@ case 5680: { // glGetActiveUniformBlockName
driver_send_term(port,caller,rt,AP);
driver_free(uniformBlockName);
}; break;
-case 5681: { // glUniformBlockBinding
+case 5682: { // 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 5682: { // glCopyBufferSubData
+case 5683: { // glCopyBufferSubData
GLenum *readTarget = (GLenum *) bp; bp += 4;
GLenum *writeTarget = (GLenum *) bp; bp += 4;
GLintptr readOffset = (GLintptr) * (GLuint64EXT *) bp; bp += 8;
@@ -5338,7 +5346,7 @@ case 5682: { // glCopyBufferSubData
GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8;
weglCopyBufferSubData(*readTarget,*writeTarget,readOffset,writeOffset,size);
}; break;
-case 5683: { // glDrawElementsBaseVertex
+case 5684: { // glDrawElementsBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -5346,7 +5354,7 @@ case 5683: { // glDrawElementsBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawElementsBaseVertex(*mode,*count,*type,indices,*basevertex);
}; break;
-case 5684: { // glDrawElementsBaseVertex
+case 5685: { // glDrawElementsBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -5354,7 +5362,7 @@ case 5684: { // glDrawElementsBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawElementsBaseVertex(*mode,*count,*type,indices,*basevertex);
}; break;
-case 5685: { // glDrawRangeElementsBaseVertex
+case 5686: { // glDrawRangeElementsBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *start = (GLuint *) bp; bp += 4;
GLuint *end = (GLuint *) bp; bp += 4;
@@ -5364,7 +5372,7 @@ case 5685: { // glDrawRangeElementsBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawRangeElementsBaseVertex(*mode,*start,*end,*count,*type,indices,*basevertex);
}; break;
-case 5686: { // glDrawRangeElementsBaseVertex
+case 5687: { // glDrawRangeElementsBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *start = (GLuint *) bp; bp += 4;
GLuint *end = (GLuint *) bp; bp += 4;
@@ -5374,7 +5382,7 @@ case 5686: { // glDrawRangeElementsBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawRangeElementsBaseVertex(*mode,*start,*end,*count,*type,indices,*basevertex);
}; break;
-case 5687: { // glDrawElementsInstancedBaseVertex
+case 5688: { // glDrawElementsInstancedBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -5383,7 +5391,7 @@ case 5687: { // glDrawElementsInstancedBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawElementsInstancedBaseVertex(*mode,*count,*type,indices,*primcount,*basevertex);
}; break;
-case 5688: { // glDrawElementsInstancedBaseVertex
+case 5689: { // glDrawElementsInstancedBaseVertex
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -5392,11 +5400,11 @@ case 5688: { // glDrawElementsInstancedBaseVertex
GLint *basevertex = (GLint *) bp; bp += 4;
weglDrawElementsInstancedBaseVertex(*mode,*count,*type,indices,*primcount,*basevertex);
}; break;
-case 5689: { // glProvokingVertex
+case 5690: { // glProvokingVertex
GLenum *mode = (GLenum *) bp; bp += 4;
weglProvokingVertex(*mode);
}; break;
-case 5690: { // glFenceSync
+case 5691: { // glFenceSync
GLenum *condition = (GLenum *) bp; bp += 4;
GLbitfield *flags = (GLbitfield *) bp; bp += 4;
GLsync result = weglFenceSync(*condition,*flags);
@@ -5406,7 +5414,7 @@ case 5690: { // glFenceSync
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5691: { // glIsSync
+case 5692: { // glIsSync
GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
GLboolean result = weglIsSync(sync);
int AP = 0; ErlDrvTermData rt[6];
@@ -5415,11 +5423,11 @@ case 5691: { // glIsSync
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5692: { // glDeleteSync
+case 5693: { // glDeleteSync
GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
weglDeleteSync(sync);
}; break;
-case 5693: { // glClientWaitSync
+case 5694: { // glClientWaitSync
GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
GLbitfield *flags = (GLbitfield *) bp; bp += 4;
bp += 4;
@@ -5431,14 +5439,14 @@ case 5693: { // glClientWaitSync
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5694: { // glWaitSync
+case 5695: { // 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
+case 5696: { // 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);
@@ -5465,7 +5473,7 @@ case 5695: { // glGetInteger64v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5696: { // glGetSynciv
+case 5697: { // glGetSynciv
GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8;
GLenum *pname = (GLenum *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -5484,7 +5492,7 @@ case 5696: { // glGetSynciv
driver_free(rt);
driver_free(values);
}; break;
-case 5697: { // glTexImage2DMultisample
+case 5698: { // glTexImage2DMultisample
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *samples = (GLsizei *) bp; bp += 4;
GLint *internalformat = (GLint *) bp; bp += 4;
@@ -5493,7 +5501,7 @@ case 5697: { // glTexImage2DMultisample
GLboolean *fixedsamplelocations = (GLboolean *) bp; bp += 1;
weglTexImage2DMultisample(*target,*samples,*internalformat,*width,*height,*fixedsamplelocations);
}; break;
-case 5698: { // glTexImage3DMultisample
+case 5699: { // glTexImage3DMultisample
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *samples = (GLsizei *) bp; bp += 4;
GLint *internalformat = (GLint *) bp; bp += 4;
@@ -5503,7 +5511,7 @@ case 5698: { // glTexImage3DMultisample
GLboolean *fixedsamplelocations = (GLboolean *) bp; bp += 1;
weglTexImage3DMultisample(*target,*samples,*internalformat,*width,*height,*depth,*fixedsamplelocations);
}; break;
-case 5699: { // glGetMultisamplefv
+case 5700: { // glGetMultisamplefv
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat val[2] = {0.0,0.0};
@@ -5518,12 +5526,12 @@ case 5699: { // glGetMultisamplefv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5700: { // glSampleMaski
+case 5701: { // glSampleMaski
GLuint *index = (GLuint *) bp; bp += 4;
GLbitfield *mask = (GLbitfield *) bp; bp += 4;
weglSampleMaski(*index,*mask);
}; break;
-case 5701: { // glNamedStringARB
+case 5702: { // glNamedStringARB
GLenum *type = (GLenum *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
@@ -5531,12 +5539,12 @@ case 5701: { // glNamedStringARB
int stringLen[1] = {(int)strlen((char *)string)}; bp += stringLen[0]+1+((8-((1+stringLen[0]+0)%8))%8);
weglNamedStringARB(*type,*nameLen,name,*stringLen,string);
}; break;
-case 5702: { // glDeleteNamedStringARB
+case 5703: { // glDeleteNamedStringARB
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
weglDeleteNamedStringARB(*nameLen,name);
}; break;
-case 5703: { // glCompileShaderIncludeARB
+case 5704: { // glCompileShaderIncludeARB
GLuint *shader = (GLuint *) bp; bp += 4;
int * pathLen = (int *) bp; bp += 4;
int * pathTotSize = (int *) bp; bp += 4;
@@ -5548,7 +5556,7 @@ case 5703: { // glCompileShaderIncludeARB
weglCompileShaderIncludeARB(*shader,*pathLen,(const GLchar **) path,NULL);
driver_free(path);
}; break;
-case 5704: { // glIsNamedStringARB
+case 5705: { // glIsNamedStringARB
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
GLboolean result = weglIsNamedStringARB(*nameLen,name);
@@ -5558,7 +5566,7 @@ case 5704: { // glIsNamedStringARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5705: { // glGetNamedStringARB
+case 5706: { // glGetNamedStringARB
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
@@ -5573,7 +5581,7 @@ case 5705: { // glGetNamedStringARB
driver_send_term(port,caller,rt,AP);
driver_free(string);
}; break;
-case 5706: { // glGetNamedStringivARB
+case 5707: { // glGetNamedStringivARB
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8);
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -5585,7 +5593,7 @@ case 5706: { // glGetNamedStringivARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5707: { // glBindFragDataLocationIndexed
+case 5708: { // glBindFragDataLocationIndexed
GLuint *program = (GLuint *) bp; bp += 4;
GLuint *colorNumber = (GLuint *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
@@ -5593,7 +5601,7 @@ case 5707: { // glBindFragDataLocationIndexed
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
weglBindFragDataLocationIndexed(*program,*colorNumber,*index,name);
}; break;
-case 5708: { // glGetFragDataIndex
+case 5709: { // glGetFragDataIndex
GLuint *program = (GLuint *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
int nameLen[1] = {(int)strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8);
@@ -5604,7 +5612,7 @@ case 5708: { // glGetFragDataIndex
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5709: { // glGenSamplers
+case 5710: { // glGenSamplers
GLsizei *count = (GLsizei *) bp; bp += 4;
GLuint *samplers;
samplers = (GLuint *) driver_alloc(sizeof(GLuint) * *count);
@@ -5620,12 +5628,12 @@ case 5709: { // glGenSamplers
driver_free(rt);
driver_free(samplers);
}; break;
-case 5710: { // glDeleteSamplers
+case 5711: { // glDeleteSamplers
int * samplersLen = (int *) bp; bp += 4;
- GLuint * samplers = (GLuint *) bp; bp += (8-((*samplersLen*4+4)%8))%8;
+ GLuint * samplers = (GLuint *) bp; bp += *samplersLen*4 + (8-((*samplersLen*4+4)%8))%8;
weglDeleteSamplers(*samplersLen,samplers);
}; break;
-case 5711: { // glIsSampler
+case 5712: { // glIsSampler
GLuint *sampler = (GLuint *) bp; bp += 4;
GLboolean result = weglIsSampler(*sampler);
int AP = 0; ErlDrvTermData rt[6];
@@ -5634,52 +5642,52 @@ case 5711: { // glIsSampler
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5712: { // glBindSampler
+case 5713: { // glBindSampler
GLuint *unit = (GLuint *) bp; bp += 4;
GLuint *sampler = (GLuint *) bp; bp += 4;
weglBindSampler(*unit,*sampler);
}; break;
-case 5713: { // glSamplerParameteri
+case 5714: { // 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
+case 5715: { // 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;
+ GLint * param = (GLint *) bp; bp += *paramLen*4 + (8-((*paramLen*4+4)%8))%8;
weglSamplerParameteriv(*sampler,*pname,param);
}; break;
-case 5715: { // glSamplerParameterf
+case 5716: { // 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
+case 5717: { // 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;
+ GLfloat * param = (GLfloat *) bp; bp += *paramLen*4 + (8-((*paramLen*4+4)%8))%8;
weglSamplerParameterfv(*sampler,*pname,param);
}; break;
-case 5717: { // glSamplerParameterIiv
+case 5718: { // 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;
+ GLint * param = (GLint *) bp; bp += *paramLen*4 + (8-((*paramLen*4+4)%8))%8;
weglSamplerParameterIiv(*sampler,*pname,param);
}; break;
-case 5718: { // glSamplerParameterIuiv
+case 5719: { // 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;
+ GLuint * param = (GLuint *) bp; bp += *paramLen*4 + (8-((*paramLen*4+4)%8))%8;
weglSamplerParameterIuiv(*sampler,*pname,param);
}; break;
-case 5719: { // glGetSamplerParameteriv
+case 5720: { // glGetSamplerParameteriv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
@@ -5695,7 +5703,7 @@ case 5719: { // glGetSamplerParameteriv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5720: { // glGetSamplerParameterIiv
+case 5721: { // glGetSamplerParameterIiv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[4] = {0,0,0,0};
@@ -5711,7 +5719,7 @@ case 5720: { // glGetSamplerParameterIiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5721: { // glGetSamplerParameterfv
+case 5722: { // glGetSamplerParameterfv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLfloat params[4] = {0.0,0.0,0.0,0.0};
@@ -5728,7 +5736,7 @@ case 5721: { // glGetSamplerParameterfv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5722: { // glGetSamplerParameterIuiv
+case 5723: { // glGetSamplerParameterIuiv
GLuint *sampler = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint params[4] = {0,0,0,0};
@@ -5744,12 +5752,12 @@ case 5722: { // glGetSamplerParameterIuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5723: { // glQueryCounter
+case 5724: { // glQueryCounter
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *target = (GLenum *) bp; bp += 4;
weglQueryCounter(*id,*target);
}; break;
-case 5724: { // glGetQueryObjecti64v
+case 5725: { // glGetQueryObjecti64v
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint64 params[1] = {0};
@@ -5760,7 +5768,7 @@ case 5724: { // glGetQueryObjecti64v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5725: { // glGetQueryObjectui64v
+case 5726: { // glGetQueryObjectui64v
GLuint *id = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLuint64 params[1] = {0};
@@ -5771,42 +5779,42 @@ case 5725: { // glGetQueryObjectui64v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5726: { // glDrawArraysIndirect
+case 5727: { // glDrawArraysIndirect
GLenum *mode = (GLenum *) bp; bp += 4;
GLvoid *indirect = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglDrawArraysIndirect(*mode,indirect);
}; break;
-case 5727: { // glDrawArraysIndirect
+case 5728: { // glDrawArraysIndirect
GLenum *mode = (GLenum *) bp; bp += 4;
GLvoid *indirect = (GLvoid *) bins[0];
weglDrawArraysIndirect(*mode,indirect);
}; break;
-case 5728: { // glDrawElementsIndirect
+case 5729: { // glDrawElementsIndirect
GLenum *mode = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLvoid *indirect = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglDrawElementsIndirect(*mode,*type,indirect);
}; break;
-case 5729: { // glDrawElementsIndirect
+case 5730: { // 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
+case 5731: { // glUniform1d
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
weglUniform1d(*location,*x);
}; break;
-case 5731: { // glUniform2d
+case 5732: { // 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
+case 5733: { // glUniform3d
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
@@ -5814,7 +5822,7 @@ case 5732: { // glUniform3d
GLdouble *z = (GLdouble *) bp; bp += 8;
weglUniform3d(*location,*x,*y,*z);
}; break;
-case 5733: { // glUniform4d
+case 5734: { // glUniform4d
GLint *location = (GLint *) bp; bp += 4;
bp += 4;
GLdouble *x = (GLdouble *) bp; bp += 8;
@@ -5823,35 +5831,35 @@ case 5733: { // glUniform4d
GLdouble *w = (GLdouble *) bp; bp += 8;
weglUniform4d(*location,*x,*y,*z,*w);
}; break;
-case 5734: { // glUniform1dv
+case 5735: { // 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;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*8 + (8-((*valueLen*8+0)%8))%8;
weglUniform1dv(*location,*valueLen,value);
}; break;
-case 5735: { // glUniform2dv
+case 5736: { // 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
+case 5737: { // 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
+case 5738: { // 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
+case 5739: { // glUniformMatrix2dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5859,7 +5867,7 @@ case 5738: { // glUniformMatrix2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*32;
weglUniformMatrix2dv(*location,*valueLen,*transpose,value);
}; break;
-case 5739: { // glUniformMatrix3dv
+case 5740: { // glUniformMatrix3dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5867,7 +5875,7 @@ case 5739: { // glUniformMatrix3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*72;
weglUniformMatrix3dv(*location,*valueLen,*transpose,value);
}; break;
-case 5740: { // glUniformMatrix4dv
+case 5741: { // glUniformMatrix4dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5875,7 +5883,7 @@ case 5740: { // glUniformMatrix4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*128;
weglUniformMatrix4dv(*location,*valueLen,*transpose,value);
}; break;
-case 5741: { // glUniformMatrix2x3dv
+case 5742: { // glUniformMatrix2x3dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5883,7 +5891,7 @@ case 5741: { // glUniformMatrix2x3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
weglUniformMatrix2x3dv(*location,*valueLen,*transpose,value);
}; break;
-case 5742: { // glUniformMatrix2x4dv
+case 5743: { // glUniformMatrix2x4dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5891,7 +5899,7 @@ case 5742: { // glUniformMatrix2x4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
weglUniformMatrix2x4dv(*location,*valueLen,*transpose,value);
}; break;
-case 5743: { // glUniformMatrix3x2dv
+case 5744: { // glUniformMatrix3x2dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5899,7 +5907,7 @@ case 5743: { // glUniformMatrix3x2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
weglUniformMatrix3x2dv(*location,*valueLen,*transpose,value);
}; break;
-case 5744: { // glUniformMatrix3x4dv
+case 5745: { // glUniformMatrix3x4dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5907,7 +5915,7 @@ case 5744: { // glUniformMatrix3x4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
weglUniformMatrix3x4dv(*location,*valueLen,*transpose,value);
}; break;
-case 5745: { // glUniformMatrix4x2dv
+case 5746: { // glUniformMatrix4x2dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5915,7 +5923,7 @@ case 5745: { // glUniformMatrix4x2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
weglUniformMatrix4x2dv(*location,*valueLen,*transpose,value);
}; break;
-case 5746: { // glUniformMatrix4x3dv
+case 5747: { // glUniformMatrix4x3dv
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
bp += 3;
@@ -5923,7 +5931,7 @@ case 5746: { // glUniformMatrix4x3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
weglUniformMatrix4x3dv(*location,*valueLen,*transpose,value);
}; break;
-case 5747: { // glGetUniformdv
+case 5748: { // 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};
@@ -5951,7 +5959,7 @@ case 5747: { // glGetUniformdv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5748: { // glGetSubroutineUniformLocation
+case 5749: { // glGetSubroutineUniformLocation
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
@@ -5963,7 +5971,7 @@ case 5748: { // glGetSubroutineUniformLocation
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5749: { // glGetSubroutineIndex
+case 5750: { // glGetSubroutineIndex
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLchar *name = (GLchar *) bp;
@@ -5975,7 +5983,7 @@ case 5749: { // glGetSubroutineIndex
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5750: { // glGetActiveSubroutineUniformName
+case 5751: { // glGetActiveSubroutineUniformName
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
@@ -5991,7 +5999,7 @@ case 5750: { // glGetActiveSubroutineUniformName
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5751: { // glGetActiveSubroutineName
+case 5752: { // glGetActiveSubroutineName
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
@@ -6007,13 +6015,13 @@ case 5751: { // glGetActiveSubroutineName
driver_send_term(port,caller,rt,AP);
driver_free(name);
}; break;
-case 5752: { // glUniformSubroutinesuiv
+case 5753: { // glUniformSubroutinesuiv
GLenum *shadertype = (GLenum *) bp; bp += 4;
int * indicesLen = (int *) bp; bp += 4;
- GLuint * indices = (GLuint *) bp; bp += (8-((*indicesLen*4+0)%8))%8;
+ GLuint * indices = (GLuint *) bp; bp += *indicesLen*4 + (8-((*indicesLen*4+0)%8))%8;
weglUniformSubroutinesuiv(*shadertype,*indicesLen,indices);
}; break;
-case 5753: { // glGetUniformSubroutineuiv
+case 5754: { // 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};
@@ -6041,7 +6049,7 @@ case 5753: { // glGetUniformSubroutineuiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5754: { // glGetProgramStageiv
+case 5755: { // glGetProgramStageiv
GLuint *program = (GLuint *) bp; bp += 4;
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -6053,28 +6061,28 @@ case 5754: { // glGetProgramStageiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5755: { // glPatchParameteri
+case 5756: { // glPatchParameteri
GLenum *pname = (GLenum *) bp; bp += 4;
GLint *value = (GLint *) bp; bp += 4;
weglPatchParameteri(*pname,*value);
}; break;
-case 5756: { // glPatchParameterfv
+case 5757: { // glPatchParameterfv
GLenum *pname = (GLenum *) bp; bp += 4;
int * valuesLen = (int *) bp; bp += 4;
- GLfloat * values = (GLfloat *) bp; bp += (8-((*valuesLen*4+0)%8))%8;
+ GLfloat * values = (GLfloat *) bp; bp += *valuesLen*4 + (8-((*valuesLen*4+0)%8))%8;
weglPatchParameterfv(*pname,values);
}; break;
-case 5757: { // glBindTransformFeedback
+case 5758: { // glBindTransformFeedback
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
weglBindTransformFeedback(*target,*id);
}; break;
-case 5758: { // glDeleteTransformFeedbacks
+case 5759: { // glDeleteTransformFeedbacks
int * idsLen = (int *) bp; bp += 4;
- GLuint * ids = (GLuint *) bp; bp += (8-((*idsLen*4+4)%8))%8;
+ GLuint * ids = (GLuint *) bp; bp += *idsLen*4 + (8-((*idsLen*4+4)%8))%8;
weglDeleteTransformFeedbacks(*idsLen,ids);
}; break;
-case 5759: { // glGenTransformFeedbacks
+case 5760: { // glGenTransformFeedbacks
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *ids;
ids = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -6090,7 +6098,7 @@ case 5759: { // glGenTransformFeedbacks
driver_free(rt);
driver_free(ids);
}; break;
-case 5760: { // glIsTransformFeedback
+case 5761: { // glIsTransformFeedback
GLuint *id = (GLuint *) bp; bp += 4;
GLboolean result = weglIsTransformFeedback(*id);
int AP = 0; ErlDrvTermData rt[6];
@@ -6099,35 +6107,35 @@ case 5760: { // glIsTransformFeedback
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5761: { // glPauseTransformFeedback
+case 5762: { // glPauseTransformFeedback
weglPauseTransformFeedback();
}; break;
-case 5762: { // glResumeTransformFeedback
+case 5763: { // glResumeTransformFeedback
weglResumeTransformFeedback();
}; break;
-case 5763: { // glDrawTransformFeedback
+case 5764: { // glDrawTransformFeedback
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
weglDrawTransformFeedback(*mode,*id);
}; break;
-case 5764: { // glDrawTransformFeedbackStream
+case 5765: { // 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
+case 5766: { // 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
+case 5767: { // glEndQueryIndexed
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
weglEndQueryIndexed(*target,*index);
}; break;
-case 5767: { // glGetQueryIndexediv
+case 5768: { // glGetQueryIndexediv
GLenum *target = (GLenum *) bp; bp += 4;
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -6139,18 +6147,18 @@ case 5767: { // glGetQueryIndexediv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5768: { // glReleaseShaderCompiler
+case 5769: { // glReleaseShaderCompiler
weglReleaseShaderCompiler();
}; break;
-case 5769: { // glShaderBinary
+case 5770: { // glShaderBinary
int * shadersLen = (int *) bp; bp += 4;
- GLuint * shaders = (GLuint *) bp; bp += (8-((*shadersLen*4+4)%8))%8;
+ GLuint * shaders = (GLuint *) bp; bp += *shadersLen*4 + (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
+case 5771: { // glGetShaderPrecisionFormat
GLenum *shadertype = (GLenum *) bp; bp += 4;
GLenum *precisiontype = (GLenum *) bp; bp += 4;
GLint range[2] = {0,0};
@@ -6167,16 +6175,16 @@ case 5770: { // glGetShaderPrecisionFormat
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5771: { // glDepthRangef
+case 5772: { // glDepthRangef
GLclampf *n = (GLclampf *) bp; bp += 4;
GLclampf *f = (GLclampf *) bp; bp += 4;
weglDepthRangef(*n,*f);
}; break;
-case 5772: { // glClearDepthf
+case 5773: { // glClearDepthf
GLclampf *d = (GLclampf *) bp; bp += 4;
weglClearDepthf(*d);
}; break;
-case 5773: { // glGetProgramBinary
+case 5774: { // glGetProgramBinary
GLuint *program = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -6192,31 +6200,31 @@ case 5773: { // glGetProgramBinary
driver_send_term(port,caller,rt,AP);
driver_free_binary(binary);
}; break;
-case 5774: { // glProgramBinary
+case 5775: { // 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
+case 5776: { // 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
+case 5777: { // 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
+case 5778: { // glActiveShaderProgram
GLuint *pipeline = (GLuint *) bp; bp += 4;
GLuint *program = (GLuint *) bp; bp += 4;
weglActiveShaderProgram(*pipeline,*program);
}; break;
-case 5778: { // glCreateShaderProgramv
+case 5779: { // glCreateShaderProgramv
GLenum *type = (GLenum *) bp; bp += 4;
int * stringsLen = (int *) bp; bp += 4;
int * stringsTotSize = (int *) bp; bp += 4;
@@ -6233,16 +6241,16 @@ case 5778: { // glCreateShaderProgramv
driver_send_term(port,caller,rt,AP);
driver_free(strings);
}; break;
-case 5779: { // glBindProgramPipeline
+case 5780: { // glBindProgramPipeline
GLuint *pipeline = (GLuint *) bp; bp += 4;
weglBindProgramPipeline(*pipeline);
}; break;
-case 5780: { // glDeleteProgramPipelines
+case 5781: { // glDeleteProgramPipelines
int * pipelinesLen = (int *) bp; bp += 4;
- GLuint * pipelines = (GLuint *) bp; bp += (8-((*pipelinesLen*4+4)%8))%8;
+ GLuint * pipelines = (GLuint *) bp; bp += *pipelinesLen*4 + (8-((*pipelinesLen*4+4)%8))%8;
weglDeleteProgramPipelines(*pipelinesLen,pipelines);
}; break;
-case 5781: { // glGenProgramPipelines
+case 5782: { // glGenProgramPipelines
GLsizei *n = (GLsizei *) bp; bp += 4;
GLuint *pipelines;
pipelines = (GLuint *) driver_alloc(sizeof(GLuint) * *n);
@@ -6258,7 +6266,7 @@ case 5781: { // glGenProgramPipelines
driver_free(rt);
driver_free(pipelines);
}; break;
-case 5782: { // glIsProgramPipeline
+case 5783: { // glIsProgramPipeline
GLuint *pipeline = (GLuint *) bp; bp += 4;
GLboolean result = weglIsProgramPipeline(*pipeline);
int AP = 0; ErlDrvTermData rt[6];
@@ -6267,7 +6275,7 @@ case 5782: { // glIsProgramPipeline
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5783: { // glGetProgramPipelineiv
+case 5784: { // glGetProgramPipelineiv
GLuint *pipeline = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLint params[1] = {0};
@@ -6278,115 +6286,115 @@ case 5783: { // glGetProgramPipelineiv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5784: { // glProgramUniform1i
+case 5785: { // 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
+case 5786: { // 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;
+ GLint * value = (GLint *) bp; bp += *valueLen*4 + (8-((*valueLen*4+4)%8))%8;
weglProgramUniform1iv(*program,*location,*valueLen,value);
}; break;
-case 5786: { // glProgramUniform1f
+case 5787: { // 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
+case 5788: { // 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;
+ GLfloat * value = (GLfloat *) bp; bp += *valueLen*4 + (8-((*valueLen*4+4)%8))%8;
weglProgramUniform1fv(*program,*location,*valueLen,value);
}; break;
-case 5788: { // glProgramUniform1d
+case 5789: { // 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
+case 5790: { // 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;
+ GLdouble * value = (GLdouble *) bp; bp += *valueLen*8 + (8-((*valueLen*8+0)%8))%8;
weglProgramUniform1dv(*program,*location,*valueLen,value);
}; break;
-case 5790: { // glProgramUniform1ui
+case 5791: { // 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
+case 5792: { // 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;
+ GLuint * value = (GLuint *) bp; bp += *valueLen*4 + (8-((*valueLen*4+4)%8))%8;
weglProgramUniform1uiv(*program,*location,*valueLen,value);
}; break;
-case 5792: { // glProgramUniform2i
+case 5793: { // 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
+case 5794: { // 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
+case 5795: { // 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
+case 5796: { // 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
+case 5797: { // 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
+case 5798: { // 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
+case 5799: { // 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
+case 5800: { // 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
+case 5801: { // glProgramUniform3i
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
@@ -6394,14 +6402,14 @@ case 5800: { // glProgramUniform3i
GLint *v2 = (GLint *) bp; bp += 4;
weglProgramUniform3i(*program,*location,*v0,*v1,*v2);
}; break;
-case 5801: { // glProgramUniform3iv
+case 5802: { // 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
+case 5803: { // glProgramUniform3f
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
@@ -6409,14 +6417,14 @@ case 5802: { // glProgramUniform3f
GLfloat *v2 = (GLfloat *) bp; bp += 4;
weglProgramUniform3f(*program,*location,*v0,*v1,*v2);
}; break;
-case 5803: { // glProgramUniform3fv
+case 5804: { // 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
+case 5805: { // glProgramUniform3d
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLdouble *v0 = (GLdouble *) bp; bp += 8;
@@ -6424,14 +6432,14 @@ case 5804: { // glProgramUniform3d
GLdouble *v2 = (GLdouble *) bp; bp += 8;
weglProgramUniform3d(*program,*location,*v0,*v1,*v2);
}; break;
-case 5805: { // glProgramUniform3dv
+case 5806: { // 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
+case 5807: { // glProgramUniform3ui
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
@@ -6439,14 +6447,14 @@ case 5806: { // glProgramUniform3ui
GLuint *v2 = (GLuint *) bp; bp += 4;
weglProgramUniform3ui(*program,*location,*v0,*v1,*v2);
}; break;
-case 5807: { // glProgramUniform3uiv
+case 5808: { // 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
+case 5809: { // glProgramUniform4i
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLint *v0 = (GLint *) bp; bp += 4;
@@ -6455,14 +6463,14 @@ case 5808: { // glProgramUniform4i
GLint *v3 = (GLint *) bp; bp += 4;
weglProgramUniform4i(*program,*location,*v0,*v1,*v2,*v3);
}; break;
-case 5809: { // glProgramUniform4iv
+case 5810: { // 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
+case 5811: { // glProgramUniform4f
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLfloat *v0 = (GLfloat *) bp; bp += 4;
@@ -6471,14 +6479,14 @@ case 5810: { // glProgramUniform4f
GLfloat *v3 = (GLfloat *) bp; bp += 4;
weglProgramUniform4f(*program,*location,*v0,*v1,*v2,*v3);
}; break;
-case 5811: { // glProgramUniform4fv
+case 5812: { // 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
+case 5813: { // glProgramUniform4d
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLdouble *v0 = (GLdouble *) bp; bp += 8;
@@ -6487,14 +6495,14 @@ case 5812: { // glProgramUniform4d
GLdouble *v3 = (GLdouble *) bp; bp += 8;
weglProgramUniform4d(*program,*location,*v0,*v1,*v2,*v3);
}; break;
-case 5813: { // glProgramUniform4dv
+case 5814: { // 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
+case 5815: { // glProgramUniform4ui
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLuint *v0 = (GLuint *) bp; bp += 4;
@@ -6503,14 +6511,14 @@ case 5814: { // glProgramUniform4ui
GLuint *v3 = (GLuint *) bp; bp += 4;
weglProgramUniform4ui(*program,*location,*v0,*v1,*v2,*v3);
}; break;
-case 5815: { // glProgramUniform4uiv
+case 5816: { // 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
+case 5817: { // glProgramUniformMatrix2fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6519,7 +6527,7 @@ case 5816: { // glProgramUniformMatrix2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*16;
weglProgramUniformMatrix2fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5817: { // glProgramUniformMatrix3fv
+case 5818: { // glProgramUniformMatrix3fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6528,7 +6536,7 @@ case 5817: { // glProgramUniformMatrix3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*36;
weglProgramUniformMatrix3fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5818: { // glProgramUniformMatrix4fv
+case 5819: { // glProgramUniformMatrix4fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6537,7 +6545,7 @@ case 5818: { // glProgramUniformMatrix4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*64;
weglProgramUniformMatrix4fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5819: { // glProgramUniformMatrix2dv
+case 5820: { // glProgramUniformMatrix2dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6546,7 +6554,7 @@ case 5819: { // glProgramUniformMatrix2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*32;
weglProgramUniformMatrix2dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5820: { // glProgramUniformMatrix3dv
+case 5821: { // glProgramUniformMatrix3dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6555,7 +6563,7 @@ case 5820: { // glProgramUniformMatrix3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*72;
weglProgramUniformMatrix3dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5821: { // glProgramUniformMatrix4dv
+case 5822: { // glProgramUniformMatrix4dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6564,7 +6572,7 @@ case 5821: { // glProgramUniformMatrix4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*128;
weglProgramUniformMatrix4dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5822: { // glProgramUniformMatrix2x3fv
+case 5823: { // glProgramUniformMatrix2x3fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6573,7 +6581,7 @@ case 5822: { // glProgramUniformMatrix2x3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*24;
weglProgramUniformMatrix2x3fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5823: { // glProgramUniformMatrix3x2fv
+case 5824: { // glProgramUniformMatrix3x2fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6582,7 +6590,7 @@ case 5823: { // glProgramUniformMatrix3x2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*24;
weglProgramUniformMatrix3x2fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5824: { // glProgramUniformMatrix2x4fv
+case 5825: { // glProgramUniformMatrix2x4fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6591,7 +6599,7 @@ case 5824: { // glProgramUniformMatrix2x4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*32;
weglProgramUniformMatrix2x4fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5825: { // glProgramUniformMatrix4x2fv
+case 5826: { // glProgramUniformMatrix4x2fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6600,7 +6608,7 @@ case 5825: { // glProgramUniformMatrix4x2fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*32;
weglProgramUniformMatrix4x2fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5826: { // glProgramUniformMatrix3x4fv
+case 5827: { // glProgramUniformMatrix3x4fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6609,7 +6617,7 @@ case 5826: { // glProgramUniformMatrix3x4fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*48;
weglProgramUniformMatrix3x4fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5827: { // glProgramUniformMatrix4x3fv
+case 5828: { // glProgramUniformMatrix4x3fv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6618,7 +6626,7 @@ case 5827: { // glProgramUniformMatrix4x3fv
GLfloat * value = (GLfloat *) bp; bp += *valueLen*48;
weglProgramUniformMatrix4x3fv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5828: { // glProgramUniformMatrix2x3dv
+case 5829: { // glProgramUniformMatrix2x3dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6627,7 +6635,7 @@ case 5828: { // glProgramUniformMatrix2x3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
weglProgramUniformMatrix2x3dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5829: { // glProgramUniformMatrix3x2dv
+case 5830: { // glProgramUniformMatrix3x2dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6636,7 +6644,7 @@ case 5829: { // glProgramUniformMatrix3x2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*48;
weglProgramUniformMatrix3x2dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5830: { // glProgramUniformMatrix2x4dv
+case 5831: { // glProgramUniformMatrix2x4dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6645,7 +6653,7 @@ case 5830: { // glProgramUniformMatrix2x4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
weglProgramUniformMatrix2x4dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5831: { // glProgramUniformMatrix4x2dv
+case 5832: { // glProgramUniformMatrix4x2dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6654,7 +6662,7 @@ case 5831: { // glProgramUniformMatrix4x2dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*64;
weglProgramUniformMatrix4x2dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5832: { // glProgramUniformMatrix3x4dv
+case 5833: { // glProgramUniformMatrix3x4dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6663,7 +6671,7 @@ case 5832: { // glProgramUniformMatrix3x4dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
weglProgramUniformMatrix3x4dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5833: { // glProgramUniformMatrix4x3dv
+case 5834: { // glProgramUniformMatrix4x3dv
GLuint *program = (GLuint *) bp; bp += 4;
GLint *location = (GLint *) bp; bp += 4;
GLboolean *transpose = (GLboolean *) bp; bp += 1;
@@ -6672,11 +6680,11 @@ case 5833: { // glProgramUniformMatrix4x3dv
GLdouble * value = (GLdouble *) bp; bp += *valueLen*96;
weglProgramUniformMatrix4x3dv(*program,*location,*valueLen,*transpose,value);
}; break;
-case 5834: { // glValidateProgramPipeline
+case 5835: { // glValidateProgramPipeline
GLuint *pipeline = (GLuint *) bp; bp += 4;
weglValidateProgramPipeline(*pipeline);
}; break;
-case 5835: { // glGetProgramPipelineInfoLog
+case 5836: { // glGetProgramPipelineInfoLog
GLuint *pipeline = (GLuint *) bp; bp += 4;
GLsizei *bufSize = (GLsizei *) bp; bp += 4;
GLsizei length[1] = {0};
@@ -6690,31 +6698,31 @@ case 5835: { // glGetProgramPipelineInfoLog
driver_send_term(port,caller,rt,AP);
driver_free(infoLog);
}; break;
-case 5836: { // glVertexAttribL1dv
+case 5837: { // glVertexAttribL1dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttribL1dv(*index,v);
}; break;
-case 5837: { // glVertexAttribL2dv
+case 5838: { // glVertexAttribL2dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttribL2dv(*index,v);
}; break;
-case 5838: { // glVertexAttribL3dv
+case 5839: { // glVertexAttribL3dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttribL3dv(*index,v);
}; break;
-case 5839: { // glVertexAttribL4dv
+case 5840: { // glVertexAttribL4dv
GLuint *index = (GLuint *) bp; bp += 4;
bp += 4;
GLdouble *v = (GLdouble *) bp; bp += 8;
weglVertexAttribL4dv(*index,v);
}; break;
-case 5840: { // glVertexAttribLPointer
+case 5841: { // glVertexAttribLPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6722,7 +6730,7 @@ case 5840: { // glVertexAttribLPointer
GLvoid *pointer = (GLvoid *) (ErlDrvSInt) * (int *) bp; bp += 4;
weglVertexAttribLPointer(*index,*size,*type,*stride,pointer);
}; break;
-case 5841: { // glVertexAttribLPointer
+case 5842: { // glVertexAttribLPointer
GLuint *index = (GLuint *) bp; bp += 4;
GLint *size = (GLint *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6730,7 +6738,7 @@ case 5841: { // glVertexAttribLPointer
GLvoid *pointer = (GLvoid *) bins[0];
weglVertexAttribLPointer(*index,*size,*type,*stride,pointer);
}; break;
-case 5842: { // glGetVertexAttribLdv
+case 5843: { // glGetVertexAttribLdv
GLuint *index = (GLuint *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
GLdouble params[4] = {0.0,0.0,0.0,0.0};
@@ -6746,13 +6754,13 @@ case 5842: { // glGetVertexAttribLdv
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5843: { // glViewportArrayv
+case 5844: { // 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
+case 5845: { // glViewportIndexedf
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat *x = (GLfloat *) bp; bp += 4;
GLfloat *y = (GLfloat *) bp; bp += 4;
@@ -6760,18 +6768,18 @@ case 5844: { // glViewportIndexedf
GLfloat *h = (GLfloat *) bp; bp += 4;
weglViewportIndexedf(*index,*x,*y,*w,*h);
}; break;
-case 5845: { // glViewportIndexedfv
+case 5846: { // glViewportIndexedfv
GLuint *index = (GLuint *) bp; bp += 4;
GLfloat * v = (GLfloat *) bp; bp += 16;
weglViewportIndexedfv(*index,v);
}; break;
-case 5846: { // glScissorArrayv
+case 5847: { // 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
+case 5848: { // glScissorIndexed
GLuint *index = (GLuint *) bp; bp += 4;
GLint *left = (GLint *) bp; bp += 4;
GLint *bottom = (GLint *) bp; bp += 4;
@@ -6779,26 +6787,26 @@ case 5847: { // glScissorIndexed
GLsizei *height = (GLsizei *) bp; bp += 4;
weglScissorIndexed(*index,*left,*bottom,*width,*height);
}; break;
-case 5848: { // glScissorIndexedv
+case 5849: { // glScissorIndexedv
GLuint *index = (GLuint *) bp; bp += 4;
GLint * v = (GLint *) bp; bp += 16;
weglScissorIndexedv(*index,v);
}; break;
-case 5849: { // glDepthRangeArrayv
+case 5850: { // 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
+case 5851: { // 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
+case 5852: { // 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};
@@ -6827,7 +6835,7 @@ case 5851: { // glGetFloati_v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5852: { // glGetDoublei_v
+case 5853: { // 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};
@@ -6855,16 +6863,16 @@ case 5852: { // glGetDoublei_v
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5853: { // glDebugMessageControlARB
+case 5854: { // 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;
+ GLuint * ids = (GLuint *) bp; bp += *idsLen*4 + (8-((*idsLen*4+0)%8))%8;
GLboolean *enabled = (GLboolean *) bp; bp += 1;
weglDebugMessageControlARB(*source,*type,*severity,*idsLen,ids,*enabled);
}; break;
-case 5854: { // glDebugMessageInsertARB
+case 5855: { // glDebugMessageInsertARB
GLenum *source = (GLenum *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
@@ -6873,7 +6881,7 @@ case 5854: { // glDebugMessageInsertARB
int bufLen[1] = {(int)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
+case 5856: { // glGetDebugMessageLogARB
GLuint *count = (GLuint *) bp; bp += 4;
GLsizei *bufsize = (GLsizei *) bp; bp += 4;
GLenum *sources;
@@ -6920,7 +6928,7 @@ case 5855: { // glGetDebugMessageLogARB
driver_free(types);
driver_free(sources);
}; break;
-case 5856: { // glGetGraphicsResetStatusARB
+case 5857: { // glGetGraphicsResetStatusARB
GLenum result = weglGetGraphicsResetStatusARB();
int AP = 0; ErlDrvTermData rt[6];
rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_");
@@ -6928,7 +6936,7 @@ case 5856: { // glGetGraphicsResetStatusARB
rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;
driver_send_term(port,caller,rt,AP);
}; break;
-case 5857: { // glDrawArraysInstancedBaseInstance
+case 5858: { // glDrawArraysInstancedBaseInstance
GLenum *mode = (GLenum *) bp; bp += 4;
GLint *first = (GLint *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
@@ -6936,7 +6944,7 @@ case 5857: { // glDrawArraysInstancedBaseInstance
GLuint *baseinstance = (GLuint *) bp; bp += 4;
weglDrawArraysInstancedBaseInstance(*mode,*first,*count,*primcount,*baseinstance);
}; break;
-case 5858: { // glDrawElementsInstancedBaseInstance
+case 5859: { // glDrawElementsInstancedBaseInstance
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6945,7 +6953,7 @@ case 5858: { // glDrawElementsInstancedBaseInstance
GLuint *baseinstance = (GLuint *) bp; bp += 4;
weglDrawElementsInstancedBaseInstance(*mode,*count,*type,indices,*primcount,*baseinstance);
}; break;
-case 5859: { // glDrawElementsInstancedBaseInstance
+case 5860: { // glDrawElementsInstancedBaseInstance
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6954,7 +6962,7 @@ case 5859: { // glDrawElementsInstancedBaseInstance
GLuint *baseinstance = (GLuint *) bp; bp += 4;
weglDrawElementsInstancedBaseInstance(*mode,*count,*type,indices,*primcount,*baseinstance);
}; break;
-case 5860: { // glDrawElementsInstancedBaseVertexBaseInstance
+case 5861: { // glDrawElementsInstancedBaseVertexBaseInstance
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6964,7 +6972,7 @@ case 5860: { // glDrawElementsInstancedBaseVertexBaseInstance
GLuint *baseinstance = (GLuint *) bp; bp += 4;
weglDrawElementsInstancedBaseVertexBaseInstance(*mode,*count,*type,indices,*primcount,*basevertex,*baseinstance);
}; break;
-case 5861: { // glDrawElementsInstancedBaseVertexBaseInstance
+case 5862: { // glDrawElementsInstancedBaseVertexBaseInstance
GLenum *mode = (GLenum *) bp; bp += 4;
GLsizei *count = (GLsizei *) bp; bp += 4;
GLenum *type = (GLenum *) bp; bp += 4;
@@ -6974,20 +6982,20 @@ case 5861: { // glDrawElementsInstancedBaseVertexBaseInstance
GLuint *baseinstance = (GLuint *) bp; bp += 4;
weglDrawElementsInstancedBaseVertexBaseInstance(*mode,*count,*type,indices,*primcount,*basevertex,*baseinstance);
}; break;
-case 5862: { // glDrawTransformFeedbackInstanced
+case 5863: { // glDrawTransformFeedbackInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawTransformFeedbackInstanced(*mode,*id,*primcount);
}; break;
-case 5863: { // glDrawTransformFeedbackStreamInstanced
+case 5864: { // glDrawTransformFeedbackStreamInstanced
GLenum *mode = (GLenum *) bp; bp += 4;
GLuint *id = (GLuint *) bp; bp += 4;
GLuint *stream = (GLuint *) bp; bp += 4;
GLsizei *primcount = (GLsizei *) bp; bp += 4;
weglDrawTransformFeedbackStreamInstanced(*mode,*id,*stream,*primcount);
}; break;
-case 5864: { // glGetInternalformativ
+case 5865: { // glGetInternalformativ
GLenum *target = (GLenum *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
GLenum *pname = (GLenum *) bp; bp += 4;
@@ -7006,7 +7014,7 @@ case 5864: { // glGetInternalformativ
driver_free(rt);
driver_free(params);
}; break;
-case 5865: { // glBindImageTexture
+case 5866: { // glBindImageTexture
GLuint *unit = (GLuint *) bp; bp += 4;
GLuint *texture = (GLuint *) bp; bp += 4;
GLint *level = (GLint *) bp; bp += 4;
@@ -7017,18 +7025,18 @@ case 5865: { // glBindImageTexture
GLenum *format = (GLenum *) bp; bp += 4;
weglBindImageTexture(*unit,*texture,*level,*layered,*layer,*access,*format);
}; break;
-case 5866: { // glMemoryBarrier
+case 5867: { // glMemoryBarrier
GLbitfield *barriers = (GLbitfield *) bp; bp += 4;
weglMemoryBarrier(*barriers);
}; break;
-case 5867: { // glTexStorage1D
+case 5868: { // glTexStorage1D
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *levels = (GLsizei *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
GLsizei *width = (GLsizei *) bp; bp += 4;
weglTexStorage1D(*target,*levels,*internalformat,*width);
}; break;
-case 5868: { // glTexStorage2D
+case 5869: { // glTexStorage2D
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *levels = (GLsizei *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
@@ -7036,7 +7044,7 @@ case 5868: { // glTexStorage2D
GLsizei *height = (GLsizei *) bp; bp += 4;
weglTexStorage2D(*target,*levels,*internalformat,*width,*height);
}; break;
-case 5869: { // glTexStorage3D
+case 5870: { // glTexStorage3D
GLenum *target = (GLenum *) bp; bp += 4;
GLsizei *levels = (GLsizei *) bp; bp += 4;
GLenum *internalformat = (GLenum *) bp; bp += 4;
@@ -7045,12 +7053,12 @@ case 5869: { // glTexStorage3D
GLsizei *depth = (GLsizei *) bp; bp += 4;
weglTexStorage3D(*target,*levels,*internalformat,*width,*height,*depth);
}; break;
-case 5870: { // glDepthBoundsEXT
+case 5871: { // glDepthBoundsEXT
GLclampd *zmin = (GLclampd *) bp; bp += 8;
GLclampd *zmax = (GLclampd *) bp; bp += 8;
weglDepthBoundsEXT(*zmin,*zmax);
}; break;
-case 5871: { // glStencilClearTagEXT
+case 5872: { // glStencilClearTagEXT
GLsizei *stencilTagBits = (GLsizei *) bp; bp += 4;
GLuint *stencilClearTag = (GLuint *) bp; bp += 4;
weglStencilClearTagEXT(*stencilTagBits,*stencilClearTag);
diff --git a/lib/wx/c_src/gen/wxe_events.cpp b/lib/wx/c_src/gen/wxe_events.cpp
index b6d3c2db18..01787c8a64 100644
--- a/lib/wx/c_src/gen/wxe_events.cpp
+++ b/lib/wx/c_src/gen/wxe_events.cpp
@@ -910,7 +910,7 @@ case 238: {// wxDropFilesEvent
} else {
send_res = rt.send();
if(cb->skip) event->Skip();
- if(app->recurse_level < 1) {
+ if(app->recurse_level < 1 && Etype->cID != 168) {
app->recurse_level++;
app->dispatch_cmds();
app->recurse_level--;
diff --git a/lib/wx/src/gen/gl.erl b/lib/wx/src/gen/gl.erl
index 3780cca651..4a178ea1e4 100644
--- a/lib/wx/src/gen/gl.erl
+++ b/lib/wx/src/gen/gl.erl
@@ -2953,8 +2953,9 @@ callList(List) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCallLists.xml">external</a> documentation.
-spec callLists(Lists) -> 'ok' when Lists :: [integer()].
callLists(Lists) ->
- cast(5108, <<(length(Lists)):?GLuint,
- (<< <<C:?GLuint>> || C <- Lists>>)/binary,0:(((1+length(Lists)) rem 2)*32)>>).
+ ListsLen = length(Lists),
+ cast(5108, <<ListsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Lists>>)/binary,0:(((1+ListsLen) rem 2)*32)>>).
%% @doc set the display-list base for
%%
@@ -6949,8 +6950,9 @@ genTextures(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTextures.xml">external</a> documentation.
-spec deleteTextures(Textures) -> 'ok' when Textures :: [integer()].
deleteTextures(Textures) ->
- cast(5272, <<(length(Textures)):?GLuint,
- (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32)>>).
+ TexturesLen = length(Textures),
+ cast(5272, <<TexturesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+TexturesLen) rem 2)*32)>>).
%% @doc Bind a named texture to a texturing target
%%
@@ -7030,9 +7032,11 @@ bindTexture(Target,Texture) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPrioritizeTextures.xml">external</a> documentation.
-spec prioritizeTextures(Textures, Priorities) -> 'ok' when Textures :: [integer()],Priorities :: [clamp()].
prioritizeTextures(Textures,Priorities) ->
- cast(5274, <<(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)>>).
+ TexturesLen = length(Textures),
+ PrioritiesLen = length(Priorities),
+ cast(5274, <<TexturesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+TexturesLen) rem 2)*32),PrioritiesLen:?GLuint,
+ (<< <<C:?GLclampf>> || C <- Priorities>>)/binary,0:(((1+PrioritiesLen) rem 2)*32)>>).
%% @doc Determine if textures are loaded in texture memory
%%
@@ -7056,8 +7060,9 @@ prioritizeTextures(Textures,Priorities) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAreTexturesResident.xml">external</a> documentation.
-spec areTexturesResident(Textures) -> {0|1,Residences :: [0|1]} when Textures :: [integer()].
areTexturesResident(Textures) ->
- call(5275, <<(length(Textures)):?GLuint,
- (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32)>>).
+ TexturesLen = length(Textures),
+ call(5275, <<TexturesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+TexturesLen) rem 2)*32)>>).
%% @doc Determine if a name corresponds to a texture
%%
@@ -9654,11 +9659,19 @@ blendFuncSeparate(SfactorRGB,DfactorRGB,SfactorAlpha,DfactorAlpha) ->
%%
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiDrawArrays.xml">external</a> documentation.
--spec multiDrawArrays(Mode, First, Count) -> 'ok' when Mode :: enum(),First :: [integer()],Count :: [integer()].
+-spec multiDrawArrays(Mode, First, Count) -> 'ok' when Mode :: enum(),First :: [integer()]|mem(),Count :: [integer()]|mem().
+multiDrawArrays(Mode,First,Count) when is_list(First), is_list(Count) ->
+ FirstLen = length(First),
+ CountLen = length(Count),
+ cast(5395, <<Mode:?GLenum,FirstLen:?GLuint,
+ (<< <<C:?GLint>> || C <- First>>)/binary,0:(((FirstLen) rem 2)*32),CountLen:?GLuint,
+ (<< <<C:?GLsizei>> || C <- Count>>)/binary,0:(((1+CountLen) rem 2)*32)>>);
multiDrawArrays(Mode,First,Count) ->
- 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)>>).
+ send_bin(First),
+ FirstLen = byte_size(if is_binary(First) -> First; is_tuple(First) -> element(2, First) end) div 4,
+ send_bin(Count),
+ CountLen = byte_size(if is_binary(Count) -> Count; is_tuple(Count) -> element(2, Count) end) div 4,
+ cast(5396, <<Mode:?GLenum,FirstLen:?GLint,CountLen:?GLsizei>>).
%% @doc Specify point parameters
%%
@@ -9675,26 +9688,26 @@ multiDrawArrays(Mode,First,Count) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml">external</a> documentation.
-spec pointParameterf(Pname, Param) -> 'ok' when Pname :: enum(),Param :: float().
pointParameterf(Pname,Param) ->
- cast(5396, <<Pname:?GLenum,Param:?GLfloat>>).
+ cast(5397, <<Pname:?GLenum,Param:?GLfloat>>).
%% @doc
%% See {@link pointParameterf/2}
-spec pointParameterfv(Pname, Params) -> 'ok' when Pname :: enum(),Params :: tuple().
pointParameterfv(Pname,Params) ->
- cast(5397, <<Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5398, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link pointParameterf/2}
-spec pointParameteri(Pname, Param) -> 'ok' when Pname :: enum(),Param :: integer().
pointParameteri(Pname,Param) ->
- cast(5398, <<Pname:?GLenum,Param:?GLint>>).
+ cast(5399, <<Pname:?GLenum,Param:?GLint>>).
%% @doc
%% See {@link pointParameterf/2}
-spec pointParameteriv(Pname, Params) -> 'ok' when Pname :: enum(),Params :: tuple().
pointParameteriv(Pname,Params) ->
- cast(5399, <<Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5400, <<Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>).
%% @doc Set the current fog coordinates
@@ -9706,7 +9719,7 @@ pointParameteriv(Pname,Params) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFogCoord.xml">external</a> documentation.
-spec fogCoordf(Coord) -> 'ok' when Coord :: float().
fogCoordf(Coord) ->
- cast(5400, <<Coord:?GLfloat>>).
+ cast(5401, <<Coord:?GLfloat>>).
%% @equiv fogCoordf(Coord)
-spec fogCoordfv(Coord) -> 'ok' when Coord :: {Coord :: float()}.
@@ -9716,7 +9729,7 @@ fogCoordfv({Coord}) -> fogCoordf(Coord).
%% See {@link fogCoordf/1}
-spec fogCoordd(Coord) -> 'ok' when Coord :: float().
fogCoordd(Coord) ->
- cast(5401, <<Coord:?GLdouble>>).
+ cast(5402, <<Coord:?GLdouble>>).
%% @equiv fogCoordd(Coord)
-spec fogCoorddv(Coord) -> 'ok' when Coord :: {Coord :: float()}.
@@ -9747,10 +9760,10 @@ fogCoorddv({Coord}) -> fogCoordd(Coord).
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFogCoordPointer.xml">external</a> documentation.
-spec fogCoordPointer(Type, Stride, Pointer) -> 'ok' when Type :: enum(),Stride :: integer(),Pointer :: offset()|mem().
fogCoordPointer(Type,Stride,Pointer) when is_integer(Pointer) ->
- cast(5402, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5403, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
fogCoordPointer(Type,Stride,Pointer) ->
send_bin(Pointer),
- cast(5403, <<Type:?GLenum,Stride:?GLsizei>>).
+ cast(5404, <<Type:?GLenum,Stride:?GLsizei>>).
%% @doc Set the current secondary color
%%
@@ -9784,7 +9797,7 @@ fogCoordPointer(Type,Stride,Pointer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation.
-spec secondaryColor3b(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3b(Red,Green,Blue) ->
- cast(5404, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>).
+ cast(5405, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>).
%% @equiv secondaryColor3b(Red,Green,Blue)
-spec secondaryColor3bv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9794,7 +9807,7 @@ secondaryColor3bv({Red,Green,Blue}) -> secondaryColor3b(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3d(Red, Green, Blue) -> 'ok' when Red :: float(),Green :: float(),Blue :: float().
secondaryColor3d(Red,Green,Blue) ->
- cast(5405, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>).
+ cast(5406, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>).
%% @equiv secondaryColor3d(Red,Green,Blue)
-spec secondaryColor3dv(V) -> 'ok' when V :: {Red :: float(),Green :: float(),Blue :: float()}.
@@ -9804,7 +9817,7 @@ secondaryColor3dv({Red,Green,Blue}) -> secondaryColor3d(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3f(Red, Green, Blue) -> 'ok' when Red :: float(),Green :: float(),Blue :: float().
secondaryColor3f(Red,Green,Blue) ->
- cast(5406, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>).
+ cast(5407, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>).
%% @equiv secondaryColor3f(Red,Green,Blue)
-spec secondaryColor3fv(V) -> 'ok' when V :: {Red :: float(),Green :: float(),Blue :: float()}.
@@ -9814,7 +9827,7 @@ secondaryColor3fv({Red,Green,Blue}) -> secondaryColor3f(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3i(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3i(Red,Green,Blue) ->
- cast(5407, <<Red:?GLint,Green:?GLint,Blue:?GLint>>).
+ cast(5408, <<Red:?GLint,Green:?GLint,Blue:?GLint>>).
%% @equiv secondaryColor3i(Red,Green,Blue)
-spec secondaryColor3iv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9824,7 +9837,7 @@ secondaryColor3iv({Red,Green,Blue}) -> secondaryColor3i(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3s(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3s(Red,Green,Blue) ->
- cast(5408, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>).
+ cast(5409, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>).
%% @equiv secondaryColor3s(Red,Green,Blue)
-spec secondaryColor3sv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9834,7 +9847,7 @@ secondaryColor3sv({Red,Green,Blue}) -> secondaryColor3s(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3ub(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3ub(Red,Green,Blue) ->
- cast(5409, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>).
+ cast(5410, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>).
%% @equiv secondaryColor3ub(Red,Green,Blue)
-spec secondaryColor3ubv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9844,7 +9857,7 @@ secondaryColor3ubv({Red,Green,Blue}) -> secondaryColor3ub(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3ui(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3ui(Red,Green,Blue) ->
- cast(5410, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>).
+ cast(5411, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>).
%% @equiv secondaryColor3ui(Red,Green,Blue)
-spec secondaryColor3uiv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9854,7 +9867,7 @@ secondaryColor3uiv({Red,Green,Blue}) -> secondaryColor3ui(Red,Green,Blue).
%% See {@link secondaryColor3b/3}
-spec secondaryColor3us(Red, Green, Blue) -> 'ok' when Red :: integer(),Green :: integer(),Blue :: integer().
secondaryColor3us(Red,Green,Blue) ->
- cast(5411, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>).
+ cast(5412, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>).
%% @equiv secondaryColor3us(Red,Green,Blue)
-spec secondaryColor3usv(V) -> 'ok' when V :: {Red :: integer(),Green :: integer(),Blue :: integer()}.
@@ -9887,10 +9900,10 @@ secondaryColor3usv({Red,Green,Blue}) -> secondaryColor3us(Red,Green,Blue).
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColorPointer.xml">external</a> documentation.
-spec secondaryColorPointer(Size, Type, Stride, Pointer) -> 'ok' when Size :: integer(),Type :: enum(),Stride :: integer(),Pointer :: offset()|mem().
secondaryColorPointer(Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- cast(5412, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5413, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
secondaryColorPointer(Size,Type,Stride,Pointer) ->
send_bin(Pointer),
- cast(5413, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+ cast(5414, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
%% @doc Specify the raster position in window coordinates for pixel operations
%%
@@ -9933,7 +9946,7 @@ secondaryColorPointer(Size,Type,Stride,Pointer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation.
-spec windowPos2d(X, Y) -> 'ok' when X :: float(),Y :: float().
windowPos2d(X,Y) ->
- cast(5414, <<X:?GLdouble,Y:?GLdouble>>).
+ cast(5415, <<X:?GLdouble,Y:?GLdouble>>).
%% @equiv windowPos2d(X,Y)
-spec windowPos2dv(V) -> 'ok' when V :: {X :: float(),Y :: float()}.
@@ -9943,7 +9956,7 @@ windowPos2dv({X,Y}) -> windowPos2d(X,Y).
%% See {@link windowPos2d/2}
-spec windowPos2f(X, Y) -> 'ok' when X :: float(),Y :: float().
windowPos2f(X,Y) ->
- cast(5415, <<X:?GLfloat,Y:?GLfloat>>).
+ cast(5416, <<X:?GLfloat,Y:?GLfloat>>).
%% @equiv windowPos2f(X,Y)
-spec windowPos2fv(V) -> 'ok' when V :: {X :: float(),Y :: float()}.
@@ -9953,7 +9966,7 @@ windowPos2fv({X,Y}) -> windowPos2f(X,Y).
%% See {@link windowPos2d/2}
-spec windowPos2i(X, Y) -> 'ok' when X :: integer(),Y :: integer().
windowPos2i(X,Y) ->
- cast(5416, <<X:?GLint,Y:?GLint>>).
+ cast(5417, <<X:?GLint,Y:?GLint>>).
%% @equiv windowPos2i(X,Y)
-spec windowPos2iv(V) -> 'ok' when V :: {X :: integer(),Y :: integer()}.
@@ -9963,7 +9976,7 @@ windowPos2iv({X,Y}) -> windowPos2i(X,Y).
%% See {@link windowPos2d/2}
-spec windowPos2s(X, Y) -> 'ok' when X :: integer(),Y :: integer().
windowPos2s(X,Y) ->
- cast(5417, <<X:?GLshort,Y:?GLshort>>).
+ cast(5418, <<X:?GLshort,Y:?GLshort>>).
%% @equiv windowPos2s(X,Y)
-spec windowPos2sv(V) -> 'ok' when V :: {X :: integer(),Y :: integer()}.
@@ -9973,7 +9986,7 @@ windowPos2sv({X,Y}) -> windowPos2s(X,Y).
%% See {@link windowPos2d/2}
-spec windowPos3d(X, Y, Z) -> 'ok' when X :: float(),Y :: float(),Z :: float().
windowPos3d(X,Y,Z) ->
- cast(5418, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5419, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @equiv windowPos3d(X,Y,Z)
-spec windowPos3dv(V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float()}.
@@ -9983,7 +9996,7 @@ windowPos3dv({X,Y,Z}) -> windowPos3d(X,Y,Z).
%% See {@link windowPos2d/2}
-spec windowPos3f(X, Y, Z) -> 'ok' when X :: float(),Y :: float(),Z :: float().
windowPos3f(X,Y,Z) ->
- cast(5419, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5420, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @equiv windowPos3f(X,Y,Z)
-spec windowPos3fv(V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float()}.
@@ -9993,7 +10006,7 @@ windowPos3fv({X,Y,Z}) -> windowPos3f(X,Y,Z).
%% See {@link windowPos2d/2}
-spec windowPos3i(X, Y, Z) -> 'ok' when X :: integer(),Y :: integer(),Z :: integer().
windowPos3i(X,Y,Z) ->
- cast(5420, <<X:?GLint,Y:?GLint,Z:?GLint>>).
+ cast(5421, <<X:?GLint,Y:?GLint,Z:?GLint>>).
%% @equiv windowPos3i(X,Y,Z)
-spec windowPos3iv(V) -> 'ok' when V :: {X :: integer(),Y :: integer(),Z :: integer()}.
@@ -10003,7 +10016,7 @@ windowPos3iv({X,Y,Z}) -> windowPos3i(X,Y,Z).
%% See {@link windowPos2d/2}
-spec windowPos3s(X, Y, Z) -> 'ok' when X :: integer(),Y :: integer(),Z :: integer().
windowPos3s(X,Y,Z) ->
- cast(5421, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>).
+ cast(5422, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>).
%% @equiv windowPos3s(X,Y,Z)
-spec windowPos3sv(V) -> 'ok' when V :: {X :: integer(),Y :: integer(),Z :: integer()}.
@@ -10024,7 +10037,7 @@ windowPos3sv({X,Y,Z}) -> windowPos3s(X,Y,Z).
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenQueries.xml">external</a> documentation.
-spec genQueries(N) -> [integer()] when N :: integer().
genQueries(N) ->
- call(5422, <<N:?GLsizei>>).
+ call(5423, <<N:?GLsizei>>).
%% @doc Delete named query objects
%%
@@ -10038,8 +10051,9 @@ genQueries(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteQueries.xml">external</a> documentation.
-spec deleteQueries(Ids) -> 'ok' when Ids :: [integer()].
deleteQueries(Ids) ->
- cast(5423, <<(length(Ids)):?GLuint,
- (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+length(Ids)) rem 2)*32)>>).
+ IdsLen = length(Ids),
+ cast(5424, <<IdsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+IdsLen) rem 2)*32)>>).
%% @doc Determine if a name corresponds to a query object
%%
@@ -10053,7 +10067,7 @@ deleteQueries(Ids) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsQuery.xml">external</a> documentation.
-spec isQuery(Id) -> 0|1 when Id :: integer().
isQuery(Id) ->
- call(5424, <<Id:?GLuint>>).
+ call(5425, <<Id:?GLuint>>).
%% @doc Delimit the boundaries of a query object
%%
@@ -10120,20 +10134,20 @@ isQuery(Id) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginQuery.xml">external</a> documentation.
-spec beginQuery(Target, Id) -> 'ok' when Target :: enum(),Id :: integer().
beginQuery(Target,Id) ->
- cast(5425, <<Target:?GLenum,Id:?GLuint>>).
+ cast(5426, <<Target:?GLenum,Id:?GLuint>>).
%% @doc
%% See {@link beginQuery/2}
-spec endQuery(Target) -> 'ok' when Target :: enum().
endQuery(Target) ->
- cast(5426, <<Target:?GLenum>>).
+ cast(5427, <<Target:?GLenum>>).
%% @doc glGetQuery
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQuery.xml">external</a> documentation.
-spec getQueryiv(Target, Pname) -> integer() when Target :: enum(),Pname :: enum().
getQueryiv(Target,Pname) ->
- call(5427, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5428, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc Return parameters of a query object
%%
@@ -10153,13 +10167,13 @@ getQueryiv(Target,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObject.xml">external</a> documentation.
-spec getQueryObjectiv(Id, Pname) -> integer() when Id :: integer(),Pname :: enum().
getQueryObjectiv(Id,Pname) ->
- call(5428, <<Id:?GLuint,Pname:?GLenum>>).
+ call(5429, <<Id:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link getQueryObjectiv/2}
-spec getQueryObjectuiv(Id, Pname) -> integer() when Id :: integer(),Pname :: enum().
getQueryObjectuiv(Id,Pname) ->
- call(5429, <<Id:?GLuint,Pname:?GLenum>>).
+ call(5430, <<Id:?GLuint,Pname:?GLenum>>).
%% @doc Bind a named buffer object
%%
@@ -10242,7 +10256,7 @@ getQueryObjectuiv(Id,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml">external</a> documentation.
-spec bindBuffer(Target, Buffer) -> 'ok' when Target :: enum(),Buffer :: integer().
bindBuffer(Target,Buffer) ->
- cast(5430, <<Target:?GLenum,Buffer:?GLuint>>).
+ cast(5431, <<Target:?GLenum,Buffer:?GLuint>>).
%% @doc Delete named buffer objects
%%
@@ -10257,8 +10271,9 @@ bindBuffer(Target,Buffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteBuffers.xml">external</a> documentation.
-spec deleteBuffers(Buffers) -> 'ok' when Buffers :: [integer()].
deleteBuffers(Buffers) ->
- cast(5431, <<(length(Buffers)):?GLuint,
- (<< <<C:?GLuint>> || C <- Buffers>>)/binary,0:(((1+length(Buffers)) rem 2)*32)>>).
+ BuffersLen = length(Buffers),
+ cast(5432, <<BuffersLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Buffers>>)/binary,0:(((1+BuffersLen) rem 2)*32)>>).
%% @doc Generate buffer object names
%%
@@ -10276,7 +10291,7 @@ deleteBuffers(Buffers) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenBuffers.xml">external</a> documentation.
-spec genBuffers(N) -> [integer()] when N :: integer().
genBuffers(N) ->
- call(5432, <<N:?GLsizei>>).
+ call(5433, <<N:?GLsizei>>).
%% @doc Determine if a name corresponds to a buffer object
%%
@@ -10291,7 +10306,7 @@ genBuffers(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsBuffer.xml">external</a> documentation.
-spec isBuffer(Buffer) -> 0|1 when Buffer :: integer().
isBuffer(Buffer) ->
- call(5433, <<Buffer:?GLuint>>).
+ call(5434, <<Buffer:?GLuint>>).
%% @doc Creates and initializes a buffer object's data store
%%
@@ -10329,10 +10344,10 @@ isBuffer(Buffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBufferData.xml">external</a> documentation.
-spec bufferData(Target, Size, Data, Usage) -> 'ok' when Target :: enum(),Size :: integer(),Data :: offset()|mem(),Usage :: enum().
bufferData(Target,Size,Data,Usage) when is_integer(Data) ->
- cast(5434, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Data:?GLuint,Usage:?GLenum>>);
+ cast(5435, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Data:?GLuint,Usage:?GLenum>>);
bufferData(Target,Size,Data,Usage) ->
send_bin(Data),
- cast(5435, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Usage:?GLenum>>).
+ cast(5436, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Usage:?GLenum>>).
%% @doc Updates a subset of a buffer object's data store
%%
@@ -10345,10 +10360,10 @@ bufferData(Target,Size,Data,Usage) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBufferSubData.xml">external</a> documentation.
-spec bufferSubData(Target, Offset, Size, Data) -> 'ok' when Target :: enum(),Offset :: integer(),Size :: integer(),Data :: offset()|mem().
bufferSubData(Target,Offset,Size,Data) when is_integer(Data) ->
- cast(5436, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr,Data:?GLuint>>);
+ cast(5437, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr,Data:?GLuint>>);
bufferSubData(Target,Offset,Size,Data) ->
send_bin(Data),
- cast(5437, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
+ cast(5438, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
%% @doc Returns a subset of a buffer object's data store
%%
@@ -10362,7 +10377,7 @@ bufferSubData(Target,Offset,Size,Data) ->
-spec getBufferSubData(Target, Offset, Size, Data) -> 'ok' when Target :: enum(),Offset :: integer(),Size :: integer(),Data :: mem().
getBufferSubData(Target,Offset,Size,Data) ->
send_bin(Data),
- call(5438, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
+ call(5439, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
%% @doc Return parameters of a buffer object
%%
@@ -10386,7 +10401,7 @@ getBufferSubData(Target,Offset,Size,Data) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameteriv.xml">external</a> documentation.
-spec getBufferParameteriv(Target, Pname) -> integer() when Target :: enum(),Pname :: enum().
getBufferParameteriv(Target,Pname) ->
- call(5439, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5440, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc Set the RGB blend equation and the alpha blend equation separately
%%
@@ -10428,7 +10443,7 @@ getBufferParameteriv(Target,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquationSeparate.xml">external</a> documentation.
-spec blendEquationSeparate(ModeRGB, ModeAlpha) -> 'ok' when ModeRGB :: enum(),ModeAlpha :: enum().
blendEquationSeparate(ModeRGB,ModeAlpha) ->
- cast(5440, <<ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
+ cast(5441, <<ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
%% @doc Specifies a list of color buffers to be drawn into
%%
@@ -10468,8 +10483,9 @@ blendEquationSeparate(ModeRGB,ModeAlpha) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawBuffers.xml">external</a> documentation.
-spec drawBuffers(Bufs) -> 'ok' when Bufs :: [enum()].
drawBuffers(Bufs) ->
- cast(5441, <<(length(Bufs)):?GLuint,
- (<< <<C:?GLenum>> || C <- Bufs>>)/binary,0:(((1+length(Bufs)) rem 2)*32)>>).
+ BufsLen = length(Bufs),
+ cast(5442, <<BufsLen:?GLuint,
+ (<< <<C:?GLenum>> || C <- Bufs>>)/binary,0:(((1+BufsLen) rem 2)*32)>>).
%% @doc Set front and/or back stencil test actions
%%
@@ -10530,7 +10546,7 @@ drawBuffers(Bufs) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilOpSeparate.xml">external</a> documentation.
-spec stencilOpSeparate(Face, Sfail, Dpfail, Dppass) -> 'ok' when Face :: enum(),Sfail :: enum(),Dpfail :: enum(),Dppass :: enum().
stencilOpSeparate(Face,Sfail,Dpfail,Dppass) ->
- cast(5442, <<Face:?GLenum,Sfail:?GLenum,Dpfail:?GLenum,Dppass:?GLenum>>).
+ cast(5443, <<Face:?GLenum,Sfail:?GLenum,Dpfail:?GLenum,Dppass:?GLenum>>).
%% @doc Set front and/or back function and reference value for stencil testing
%%
@@ -10593,7 +10609,7 @@ stencilOpSeparate(Face,Sfail,Dpfail,Dppass) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilFuncSeparate.xml">external</a> documentation.
-spec stencilFuncSeparate(Face, Func, Ref, Mask) -> 'ok' when Face :: enum(),Func :: enum(),Ref :: integer(),Mask :: integer().
stencilFuncSeparate(Face,Func,Ref,Mask) ->
- cast(5443, <<Face:?GLenum,Func:?GLenum,Ref:?GLint,Mask:?GLuint>>).
+ cast(5444, <<Face:?GLenum,Func:?GLenum,Ref:?GLint,Mask:?GLuint>>).
%% @doc Control the front and/or back writing of individual bits in the stencil planes
%%
@@ -10611,7 +10627,7 @@ stencilFuncSeparate(Face,Func,Ref,Mask) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilMaskSeparate.xml">external</a> documentation.
-spec stencilMaskSeparate(Face, Mask) -> 'ok' when Face :: enum(),Mask :: integer().
stencilMaskSeparate(Face,Mask) ->
- cast(5444, <<Face:?GLenum,Mask:?GLuint>>).
+ cast(5445, <<Face:?GLenum,Mask:?GLuint>>).
%% @doc Attaches a shader object to a program object
%%
@@ -10635,7 +10651,7 @@ stencilMaskSeparate(Face,Mask) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAttachShader.xml">external</a> documentation.
-spec attachShader(Program, Shader) -> 'ok' when Program :: integer(),Shader :: integer().
attachShader(Program,Shader) ->
- cast(5445, <<Program:?GLuint,Shader:?GLuint>>).
+ cast(5446, <<Program:?GLuint,Shader:?GLuint>>).
%% @doc Associates a generic vertex attribute index with a named attribute variable
%%
@@ -10672,7 +10688,8 @@ attachShader(Program,Shader) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocation.xml">external</a> documentation.
-spec bindAttribLocation(Program, Index, Name) -> 'ok' when Program :: integer(),Index :: integer(),Name :: string().
bindAttribLocation(Program,Index,Name) ->
- cast(5446, <<Program:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ cast(5447, <<Program:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc Compiles a shader object
%%
@@ -10692,7 +10709,7 @@ bindAttribLocation(Program,Index,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShader.xml">external</a> documentation.
-spec compileShader(Shader) -> 'ok' when Shader :: integer().
compileShader(Shader) ->
- cast(5447, <<Shader:?GLuint>>).
+ cast(5448, <<Shader:?GLuint>>).
%% @doc Creates a program object
%%
@@ -10715,7 +10732,7 @@ compileShader(Shader) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateProgram.xml">external</a> documentation.
-spec createProgram() -> integer().
createProgram() ->
- call(5448, <<>>).
+ call(5449, <<>>).
%% @doc Creates a shader object
%%
@@ -10738,7 +10755,7 @@ createProgram() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShader.xml">external</a> documentation.
-spec createShader(Type) -> integer() when Type :: enum().
createShader(Type) ->
- call(5449, <<Type:?GLenum>>).
+ call(5450, <<Type:?GLenum>>).
%% @doc Deletes a program object
%%
@@ -10759,7 +10776,7 @@ createShader(Type) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgram.xml">external</a> documentation.
-spec deleteProgram(Program) -> 'ok' when Program :: integer().
deleteProgram(Program) ->
- cast(5450, <<Program:?GLuint>>).
+ cast(5451, <<Program:?GLuint>>).
%% @doc Deletes a shader object
%%
@@ -10778,7 +10795,7 @@ deleteProgram(Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteShader.xml">external</a> documentation.
-spec deleteShader(Shader) -> 'ok' when Shader :: integer().
deleteShader(Shader) ->
- cast(5451, <<Shader:?GLuint>>).
+ cast(5452, <<Shader:?GLuint>>).
%% @doc Detaches a shader object from a program object to which it is attached
%%
@@ -10793,7 +10810,7 @@ deleteShader(Shader) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDetachShader.xml">external</a> documentation.
-spec detachShader(Program, Shader) -> 'ok' when Program :: integer(),Shader :: integer().
detachShader(Program,Shader) ->
- cast(5452, <<Program:?GLuint,Shader:?GLuint>>).
+ cast(5453, <<Program:?GLuint,Shader:?GLuint>>).
%% @doc Enable or disable a generic vertex attribute array
%%
@@ -10808,13 +10825,13 @@ detachShader(Program,Shader) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml">external</a> documentation.
-spec disableVertexAttribArray(Index) -> 'ok' when Index :: integer().
disableVertexAttribArray(Index) ->
- cast(5453, <<Index:?GLuint>>).
+ cast(5454, <<Index:?GLuint>>).
%% @doc
%% See {@link disableVertexAttribArray/1}
-spec enableVertexAttribArray(Index) -> 'ok' when Index :: integer().
enableVertexAttribArray(Index) ->
- cast(5454, <<Index:?GLuint>>).
+ cast(5455, <<Index:?GLuint>>).
%% @doc Returns information about an active attribute variable for the specified program object
%%
@@ -10872,7 +10889,7 @@ enableVertexAttribArray(Index) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveAttrib.xml">external</a> documentation.
-spec getActiveAttrib(Program, Index, BufSize) -> {Size :: integer(),Type :: enum(),Name :: string()} when Program :: integer(),Index :: integer(),BufSize :: integer().
getActiveAttrib(Program,Index,BufSize) ->
- call(5455, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
+ call(5456, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
%% @doc Returns information about an active uniform variable for the specified program object
%%
@@ -11019,7 +11036,7 @@ getActiveAttrib(Program,Index,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniform.xml">external</a> documentation.
-spec getActiveUniform(Program, Index, BufSize) -> {Size :: integer(),Type :: enum(),Name :: string()} when Program :: integer(),Index :: integer(),BufSize :: integer().
getActiveUniform(Program,Index,BufSize) ->
- call(5456, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
+ call(5457, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
%% @doc Returns the handles of the shader objects attached to a program object
%%
@@ -11039,7 +11056,7 @@ getActiveUniform(Program,Index,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttachedShaders.xml">external</a> documentation.
-spec getAttachedShaders(Program, MaxCount) -> [integer()] when Program :: integer(),MaxCount :: integer().
getAttachedShaders(Program,MaxCount) ->
- call(5457, <<Program:?GLuint,MaxCount:?GLsizei>>).
+ call(5458, <<Program:?GLuint,MaxCount:?GLsizei>>).
%% @doc Returns the location of an attribute variable
%%
@@ -11063,7 +11080,8 @@ getAttachedShaders(Program,MaxCount) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml">external</a> documentation.
-spec getAttribLocation(Program, Name) -> integer() when Program :: integer(),Name :: string().
getAttribLocation(Program,Name) ->
- call(5458, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5459, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc Returns a parameter from a program object
%%
@@ -11134,7 +11152,7 @@ getAttribLocation(Program,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgram.xml">external</a> documentation.
-spec getProgramiv(Program, Pname) -> integer() when Program :: integer(),Pname :: enum().
getProgramiv(Program,Pname) ->
- call(5459, <<Program:?GLuint,Pname:?GLenum>>).
+ call(5460, <<Program:?GLuint,Pname:?GLenum>>).
%% @doc Returns the information log for a program object
%%
@@ -11159,7 +11177,7 @@ getProgramiv(Program,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramInfoLog.xml">external</a> documentation.
-spec getProgramInfoLog(Program, BufSize) -> string() when Program :: integer(),BufSize :: integer().
getProgramInfoLog(Program,BufSize) ->
- call(5460, <<Program:?GLuint,BufSize:?GLsizei>>).
+ call(5461, <<Program:?GLuint,BufSize:?GLsizei>>).
%% @doc Returns a parameter from a shader object
%%
@@ -11190,7 +11208,7 @@ getProgramInfoLog(Program,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShader.xml">external</a> documentation.
-spec getShaderiv(Shader, Pname) -> integer() when Shader :: integer(),Pname :: enum().
getShaderiv(Shader,Pname) ->
- call(5461, <<Shader:?GLuint,Pname:?GLenum>>).
+ call(5462, <<Shader:?GLuint,Pname:?GLenum>>).
%% @doc Returns the information log for a shader object
%%
@@ -11213,7 +11231,7 @@ getShaderiv(Shader,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderInfoLog.xml">external</a> documentation.
-spec getShaderInfoLog(Shader, BufSize) -> string() when Shader :: integer(),BufSize :: integer().
getShaderInfoLog(Shader,BufSize) ->
- call(5462, <<Shader:?GLuint,BufSize:?GLsizei>>).
+ call(5463, <<Shader:?GLuint,BufSize:?GLsizei>>).
%% @doc Returns the source code string from a shader object
%%
@@ -11233,7 +11251,7 @@ getShaderInfoLog(Shader,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderSource.xml">external</a> documentation.
-spec getShaderSource(Shader, BufSize) -> string() when Shader :: integer(),BufSize :: integer().
getShaderSource(Shader,BufSize) ->
- call(5463, <<Shader:?GLuint,BufSize:?GLsizei>>).
+ call(5464, <<Shader:?GLuint,BufSize:?GLsizei>>).
%% @doc Returns the location of a uniform variable
%%
@@ -11266,7 +11284,8 @@ getShaderSource(Shader,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocation.xml">external</a> documentation.
-spec getUniformLocation(Program, Name) -> integer() when Program :: integer(),Name :: string().
getUniformLocation(Program,Name) ->
- call(5464, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5465, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc Returns the value of a uniform variable
%%
@@ -11292,13 +11311,13 @@ getUniformLocation(Program,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml">external</a> documentation.
-spec getUniformfv(Program, Location) -> matrix() when Program :: integer(),Location :: integer().
getUniformfv(Program,Location) ->
- call(5465, <<Program:?GLuint,Location:?GLint>>).
+ call(5466, <<Program:?GLuint,Location:?GLint>>).
%% @doc
%% See {@link getUniformfv/2}
-spec getUniformiv(Program, Location) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} when Program :: integer(),Location :: integer().
getUniformiv(Program,Location) ->
- call(5466, <<Program:?GLuint,Location:?GLint>>).
+ call(5467, <<Program:?GLuint,Location:?GLint>>).
%% @doc Return a generic vertex attribute parameter
%%
@@ -11365,19 +11384,19 @@ getUniformiv(Program,Location) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttrib.xml">external</a> documentation.
-spec getVertexAttribdv(Index, Pname) -> {float(),float(),float(),float()} when Index :: integer(),Pname :: enum().
getVertexAttribdv(Index,Pname) ->
- call(5467, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5468, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link getVertexAttribdv/2}
-spec getVertexAttribfv(Index, Pname) -> {float(),float(),float(),float()} when Index :: integer(),Pname :: enum().
getVertexAttribfv(Index,Pname) ->
- call(5468, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5469, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link getVertexAttribdv/2}
-spec getVertexAttribiv(Index, Pname) -> {integer(),integer(),integer(),integer()} when Index :: integer(),Pname :: enum().
getVertexAttribiv(Index,Pname) ->
- call(5469, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5470, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc Determines if a name corresponds to a program object
%%
@@ -11389,7 +11408,7 @@ getVertexAttribiv(Index,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsProgram.xml">external</a> documentation.
-spec isProgram(Program) -> 0|1 when Program :: integer().
isProgram(Program) ->
- call(5470, <<Program:?GLuint>>).
+ call(5471, <<Program:?GLuint>>).
%% @doc Determines if a name corresponds to a shader object
%%
@@ -11401,7 +11420,7 @@ isProgram(Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsShader.xml">external</a> documentation.
-spec isShader(Shader) -> 0|1 when Shader :: integer().
isShader(Shader) ->
- call(5471, <<Shader:?GLuint>>).
+ call(5472, <<Shader:?GLuint>>).
%% @doc Links a program object
%%
@@ -11521,7 +11540,7 @@ isShader(Shader) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgram.xml">external</a> documentation.
-spec linkProgram(Program) -> 'ok' when Program :: integer().
linkProgram(Program) ->
- cast(5472, <<Program:?GLuint>>).
+ cast(5473, <<Program:?GLuint>>).
%% @doc Replaces the source code in a shader object
%%
@@ -11539,8 +11558,9 @@ linkProgram(Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderSource.xml">external</a> documentation.
-spec shaderSource(Shader, String) -> 'ok' when Shader :: integer(),String :: iolist().
shaderSource(Shader,String) ->
- StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
- cast(5473, <<Shader:?GLuint,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+0) rem 8)) rem 8)>>).
+ StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
+ StringLen = length(String),
+ cast(5474, <<Shader:?GLuint,StringLen:?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+0) rem 8)) rem 8)>>).
%% @doc Installs a program object as part of current rendering state
%%
@@ -11581,7 +11601,7 @@ shaderSource(Shader,String) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgram.xml">external</a> documentation.
-spec useProgram(Program) -> 'ok' when Program :: integer().
useProgram(Program) ->
- cast(5474, <<Program:?GLuint>>).
+ cast(5475, <<Program:?GLuint>>).
%% @doc Specify the value of a uniform variable for the current program object
%%
@@ -11649,125 +11669,136 @@ useProgram(Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation.
-spec uniform1f(Location, V0) -> 'ok' when Location :: integer(),V0 :: float().
uniform1f(Location,V0) ->
- cast(5475, <<Location:?GLint,V0:?GLfloat>>).
+ cast(5476, <<Location:?GLint,V0:?GLfloat>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2f(Location, V0, V1) -> 'ok' when Location :: integer(),V0 :: float(),V1 :: float().
uniform2f(Location,V0,V1) ->
- cast(5476, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
+ cast(5477, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3f(Location, V0, V1, V2) -> 'ok' when Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float().
uniform3f(Location,V0,V1,V2) ->
- cast(5477, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
+ cast(5478, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4f(Location, V0, V1, V2, V3) -> 'ok' when Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float(),V3 :: float().
uniform4f(Location,V0,V1,V2,V3) ->
- cast(5478, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
+ cast(5479, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1i(Location, V0) -> 'ok' when Location :: integer(),V0 :: integer().
uniform1i(Location,V0) ->
- cast(5479, <<Location:?GLint,V0:?GLint>>).
+ cast(5480, <<Location:?GLint,V0:?GLint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2i(Location, V0, V1) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer().
uniform2i(Location,V0,V1) ->
- cast(5480, <<Location:?GLint,V0:?GLint,V1:?GLint>>).
+ cast(5481, <<Location:?GLint,V0:?GLint,V1:?GLint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3i(Location, V0, V1, V2) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer().
uniform3i(Location,V0,V1,V2) ->
- cast(5481, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
+ cast(5482, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4i(Location, V0, V1, V2, V3) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer(),V3 :: integer().
uniform4i(Location,V0,V1,V2,V3) ->
- cast(5482, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
+ cast(5483, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1fv(Location, Value) -> 'ok' when Location :: integer(),Value :: [float()].
uniform1fv(Location,Value) ->
- cast(5483, <<Location:?GLint,(length(Value)):?GLuint,
- (<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>).
+ ValueLen = length(Value),
+ cast(5484, <<Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2fv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float()}].
uniform2fv(Location,Value) ->
- cast(5484, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5485, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3fv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float(),float()}].
uniform3fv(Location,Value) ->
- cast(5485, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5486, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4fv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float(),float(),float()}].
uniform4fv(Location,Value) ->
- cast(5486, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5487, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1iv(Location, Value) -> 'ok' when Location :: integer(),Value :: [integer()].
uniform1iv(Location,Value) ->
- cast(5487, <<Location:?GLint,(length(Value)):?GLuint,
- (<< <<C:?GLint>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>).
+ ValueLen = length(Value),
+ cast(5488, <<Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLint>> || C <- Value>>)/binary,0:(((ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2iv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer()}].
uniform2iv(Location,Value) ->
- cast(5488, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5489, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3iv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer(),integer()}].
uniform3iv(Location,Value) ->
- cast(5489, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5490, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4iv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer(),integer(),integer()}].
uniform4iv(Location,Value) ->
- cast(5490, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5491, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float()}].
uniformMatrix2fv(Location,Transpose,Value) ->
- cast(5491, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5492, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix3fv(Location,Transpose,Value) ->
- cast(5492, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5493, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4fv(Location,Transpose,Value) ->
- cast(5493, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5494, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc Validates a program object
@@ -11795,7 +11826,7 @@ uniformMatrix4fv(Location,Transpose,Value) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgram.xml">external</a> documentation.
-spec validateProgram(Program) -> 'ok' when Program :: integer().
validateProgram(Program) ->
- cast(5494, <<Program:?GLuint>>).
+ cast(5495, <<Program:?GLuint>>).
%% @doc Specifies the value of a generic vertex attribute
%%
@@ -11870,7 +11901,7 @@ validateProgram(Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation.
-spec vertexAttrib1d(Index, X) -> 'ok' when Index :: integer(),X :: float().
vertexAttrib1d(Index,X) ->
- cast(5495, <<Index:?GLuint,0:32,X:?GLdouble>>).
+ cast(5496, <<Index:?GLuint,0:32,X:?GLdouble>>).
%% @equiv vertexAttrib1d(Index,X)
-spec vertexAttrib1dv(Index :: integer(),V) -> 'ok' when V :: {X :: float()}.
@@ -11880,7 +11911,7 @@ vertexAttrib1dv(Index,{X}) -> vertexAttrib1d(Index,X).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib1f(Index, X) -> 'ok' when Index :: integer(),X :: float().
vertexAttrib1f(Index,X) ->
- cast(5496, <<Index:?GLuint,X:?GLfloat>>).
+ cast(5497, <<Index:?GLuint,X:?GLfloat>>).
%% @equiv vertexAttrib1f(Index,X)
-spec vertexAttrib1fv(Index :: integer(),V) -> 'ok' when V :: {X :: float()}.
@@ -11890,7 +11921,7 @@ vertexAttrib1fv(Index,{X}) -> vertexAttrib1f(Index,X).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib1s(Index, X) -> 'ok' when Index :: integer(),X :: integer().
vertexAttrib1s(Index,X) ->
- cast(5497, <<Index:?GLuint,X:?GLshort>>).
+ cast(5498, <<Index:?GLuint,X:?GLshort>>).
%% @equiv vertexAttrib1s(Index,X)
-spec vertexAttrib1sv(Index :: integer(),V) -> 'ok' when V :: {X :: integer()}.
@@ -11900,7 +11931,7 @@ vertexAttrib1sv(Index,{X}) -> vertexAttrib1s(Index,X).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib2d(Index, X, Y) -> 'ok' when Index :: integer(),X :: float(),Y :: float().
vertexAttrib2d(Index,X,Y) ->
- cast(5498, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
+ cast(5499, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
%% @equiv vertexAttrib2d(Index,X,Y)
-spec vertexAttrib2dv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float()}.
@@ -11910,7 +11941,7 @@ vertexAttrib2dv(Index,{X,Y}) -> vertexAttrib2d(Index,X,Y).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib2f(Index, X, Y) -> 'ok' when Index :: integer(),X :: float(),Y :: float().
vertexAttrib2f(Index,X,Y) ->
- cast(5499, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat>>).
+ cast(5500, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat>>).
%% @equiv vertexAttrib2f(Index,X,Y)
-spec vertexAttrib2fv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float()}.
@@ -11920,7 +11951,7 @@ vertexAttrib2fv(Index,{X,Y}) -> vertexAttrib2f(Index,X,Y).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib2s(Index, X, Y) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer().
vertexAttrib2s(Index,X,Y) ->
- cast(5500, <<Index:?GLuint,X:?GLshort,Y:?GLshort>>).
+ cast(5501, <<Index:?GLuint,X:?GLshort,Y:?GLshort>>).
%% @equiv vertexAttrib2s(Index,X,Y)
-spec vertexAttrib2sv(Index :: integer(),V) -> 'ok' when V :: {X :: integer(),Y :: integer()}.
@@ -11930,7 +11961,7 @@ vertexAttrib2sv(Index,{X,Y}) -> vertexAttrib2s(Index,X,Y).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib3d(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float().
vertexAttrib3d(Index,X,Y,Z) ->
- cast(5501, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5502, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @equiv vertexAttrib3d(Index,X,Y,Z)
-spec vertexAttrib3dv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float()}.
@@ -11940,7 +11971,7 @@ vertexAttrib3dv(Index,{X,Y,Z}) -> vertexAttrib3d(Index,X,Y,Z).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib3f(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float().
vertexAttrib3f(Index,X,Y,Z) ->
- cast(5502, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
+ cast(5503, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>).
%% @equiv vertexAttrib3f(Index,X,Y,Z)
-spec vertexAttrib3fv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float()}.
@@ -11950,7 +11981,7 @@ vertexAttrib3fv(Index,{X,Y,Z}) -> vertexAttrib3f(Index,X,Y,Z).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib3s(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer().
vertexAttrib3s(Index,X,Y,Z) ->
- cast(5503, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort>>).
+ cast(5504, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort>>).
%% @equiv vertexAttrib3s(Index,X,Y,Z)
-spec vertexAttrib3sv(Index :: integer(),V) -> 'ok' when V :: {X :: integer(),Y :: integer(),Z :: integer()}.
@@ -11960,25 +11991,25 @@ vertexAttrib3sv(Index,{X,Y,Z}) -> vertexAttrib3s(Index,X,Y,Z).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Nbv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4Nbv(Index,{V1,V2,V3,V4}) ->
- cast(5504, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
+ cast(5505, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Niv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4Niv(Index,{V1,V2,V3,V4}) ->
- cast(5505, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ cast(5506, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Nsv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4Nsv(Index,{V1,V2,V3,V4}) ->
- cast(5506, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
+ cast(5507, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Nub(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer(),W :: integer().
vertexAttrib4Nub(Index,X,Y,Z,W) ->
- cast(5507, <<Index:?GLuint,X:?GLubyte,Y:?GLubyte,Z:?GLubyte,W:?GLubyte>>).
+ cast(5508, <<Index:?GLuint,X:?GLubyte,Y:?GLubyte,Z:?GLubyte,W:?GLubyte>>).
%% @equiv vertexAttrib4Nub(Index,X,Y,Z,W)
-spec vertexAttrib4Nubv(Index :: integer(),V) -> 'ok' when V :: {X :: integer(),Y :: integer(),Z :: integer(),W :: integer()}.
@@ -11988,25 +12019,25 @@ vertexAttrib4Nubv(Index,{X,Y,Z,W}) -> vertexAttrib4Nub(Index,X,Y,Z,W).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Nuiv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4Nuiv(Index,{V1,V2,V3,V4}) ->
- cast(5508, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
+ cast(5509, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4Nusv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4Nusv(Index,{V1,V2,V3,V4}) ->
- cast(5509, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
+ cast(5510, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4bv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4bv(Index,{V1,V2,V3,V4}) ->
- cast(5510, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
+ cast(5511, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4d(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
vertexAttrib4d(Index,X,Y,Z,W) ->
- cast(5511, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5512, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @equiv vertexAttrib4d(Index,X,Y,Z,W)
-spec vertexAttrib4dv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float(),W :: float()}.
@@ -12016,7 +12047,7 @@ vertexAttrib4dv(Index,{X,Y,Z,W}) -> vertexAttrib4d(Index,X,Y,Z,W).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4f(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
vertexAttrib4f(Index,X,Y,Z,W) ->
- cast(5512, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5513, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
%% @equiv vertexAttrib4f(Index,X,Y,Z,W)
-spec vertexAttrib4fv(Index :: integer(),V) -> 'ok' when V :: {X :: float(),Y :: float(),Z :: float(),W :: float()}.
@@ -12026,13 +12057,13 @@ vertexAttrib4fv(Index,{X,Y,Z,W}) -> vertexAttrib4f(Index,X,Y,Z,W).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4iv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4iv(Index,{V1,V2,V3,V4}) ->
- cast(5513, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ cast(5514, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4s(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer(),W :: integer().
vertexAttrib4s(Index,X,Y,Z,W) ->
- cast(5514, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
+ cast(5515, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>).
%% @equiv vertexAttrib4s(Index,X,Y,Z,W)
-spec vertexAttrib4sv(Index :: integer(),V) -> 'ok' when V :: {X :: integer(),Y :: integer(),Z :: integer(),W :: integer()}.
@@ -12042,19 +12073,19 @@ vertexAttrib4sv(Index,{X,Y,Z,W}) -> vertexAttrib4s(Index,X,Y,Z,W).
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4ubv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4ubv(Index,{V1,V2,V3,V4}) ->
- cast(5515, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
+ cast(5516, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4uiv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4uiv(Index,{V1,V2,V3,V4}) ->
- cast(5516, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
+ cast(5517, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttrib4usv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttrib4usv(Index,{V1,V2,V3,V4}) ->
- cast(5517, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
+ cast(5518, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
%% @doc Define an array of generic vertex attribute data
%%
@@ -12098,51 +12129,57 @@ vertexAttrib4usv(Index,{V1,V2,V3,V4}) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml">external</a> documentation.
-spec vertexAttribPointer(Index, Size, Type, Normalized, Stride, Pointer) -> 'ok' when Index :: integer(),Size :: integer(),Type :: enum(),Normalized :: 0|1,Stride :: integer(),Pointer :: offset()|mem().
vertexAttribPointer(Index,Size,Type,Normalized,Stride,Pointer) when is_integer(Pointer) ->
- cast(5518, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5519, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei,Pointer:?GLuint>>);
vertexAttribPointer(Index,Size,Type,Normalized,Stride,Pointer) ->
send_bin(Pointer),
- cast(5519, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei>>).
+ cast(5520, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2x3fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
uniformMatrix2x3fv(Location,Transpose,Value) ->
- cast(5520, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5521, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3x2fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
uniformMatrix3x2fv(Location,Transpose,Value) ->
- cast(5521, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5522, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2x4fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix2x4fv(Location,Transpose,Value) ->
- cast(5522, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5523, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4x2fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4x2fv(Location,Transpose,Value) ->
- cast(5523, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5524, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3x4fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix3x4fv(Location,Transpose,Value) ->
- cast(5524, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5525, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4x3fv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4x3fv(Location,Transpose,Value) ->
- cast(5525, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5526, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc glColorMaski
@@ -12150,39 +12187,39 @@ uniformMatrix4x3fv(Location,Transpose,Value) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorMaski.xml">external</a> documentation.
-spec colorMaski(Index, R, G, B, A) -> 'ok' when Index :: integer(),R :: 0|1,G :: 0|1,B :: 0|1,A :: 0|1.
colorMaski(Index,R,G,B,A) ->
- cast(5526, <<Index:?GLuint,R:?GLboolean,G:?GLboolean,B:?GLboolean,A:?GLboolean>>).
+ cast(5527, <<Index:?GLuint,R:?GLboolean,G:?GLboolean,B:?GLboolean,A:?GLboolean>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getBooleani_v(Target, Index) -> [0|1] when Target :: enum(),Index :: integer().
getBooleani_v(Target,Index) ->
- call(5527, <<Target:?GLenum,Index:?GLuint>>).
+ call(5528, <<Target:?GLenum,Index:?GLuint>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getIntegeri_v(Target, Index) -> [integer()] when Target :: enum(),Index :: integer().
getIntegeri_v(Target,Index) ->
- call(5528, <<Target:?GLenum,Index:?GLuint>>).
+ call(5529, <<Target:?GLenum,Index:?GLuint>>).
%% @doc
%% See {@link enable/1}
-spec enablei(Target, Index) -> 'ok' when Target :: enum(),Index :: integer().
enablei(Target,Index) ->
- cast(5529, <<Target:?GLenum,Index:?GLuint>>).
+ cast(5530, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glEnablei
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnablei.xml">external</a> documentation.
-spec disablei(Target, Index) -> 'ok' when Target :: enum(),Index :: integer().
disablei(Target,Index) ->
- cast(5530, <<Target:?GLenum,Index:?GLuint>>).
+ cast(5531, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glIsEnabledi
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsEnabledi.xml">external</a> documentation.
-spec isEnabledi(Target, Index) -> 0|1 when Target :: enum(),Index :: integer().
isEnabledi(Target,Index) ->
- call(5531, <<Target:?GLenum,Index:?GLuint>>).
+ call(5532, <<Target:?GLenum,Index:?GLuint>>).
%% @doc Start transform feedback operation
%%
@@ -12210,13 +12247,13 @@ isEnabledi(Target,Index) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginTransformFeedback.xml">external</a> documentation.
-spec beginTransformFeedback(PrimitiveMode) -> 'ok' when PrimitiveMode :: enum().
beginTransformFeedback(PrimitiveMode) ->
- cast(5532, <<PrimitiveMode:?GLenum>>).
+ cast(5533, <<PrimitiveMode:?GLenum>>).
%% @doc
%% See {@link beginTransformFeedback/1}
-spec endTransformFeedback() -> 'ok'.
endTransformFeedback() ->
- cast(5533, <<>>).
+ cast(5534, <<>>).
%% @doc Bind a range within a buffer object to an indexed buffer target
%%
@@ -12235,7 +12272,7 @@ endTransformFeedback() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBufferRange.xml">external</a> documentation.
-spec bindBufferRange(Target, Index, Buffer, Offset, Size) -> 'ok' when Target :: enum(),Index :: integer(),Buffer :: integer(),Offset :: integer(),Size :: integer().
bindBufferRange(Target,Index,Buffer,Offset,Size) ->
- cast(5534, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
+ cast(5535, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>).
%% @doc Bind a buffer object to an indexed buffer target
%%
@@ -12250,7 +12287,7 @@ bindBufferRange(Target,Index,Buffer,Offset,Size) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBufferBase.xml">external</a> documentation.
-spec bindBufferBase(Target, Index, Buffer) -> 'ok' when Target :: enum(),Index :: integer(),Buffer :: integer().
bindBufferBase(Target,Index,Buffer) ->
- cast(5535, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint>>).
+ cast(5536, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint>>).
%% @doc Specify values to record in transform feedback buffers
%%
@@ -12288,8 +12325,9 @@ bindBufferBase(Target,Index,Buffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTransformFeedbackVaryings.xml">external</a> documentation.
-spec transformFeedbackVaryings(Program, Varyings, BufferMode) -> 'ok' when Program :: integer(),Varyings :: iolist(),BufferMode :: enum().
transformFeedbackVaryings(Program,Varyings,BufferMode) ->
- VaryingsTemp = list_to_binary([[Str|[0]] || Str <- Varyings ]),
- cast(5536, <<Program:?GLuint,(length(Varyings)):?GLuint,(size(VaryingsTemp)):?GLuint,(VaryingsTemp)/binary,0:((8-((size(VaryingsTemp)+0) rem 8)) rem 8),BufferMode:?GLenum>>).
+ VaryingsTemp = list_to_binary([[Str|[0]] || Str <- Varyings ]),
+ VaryingsLen = length(Varyings),
+ cast(5537, <<Program:?GLuint,VaryingsLen:?GLuint,(size(VaryingsTemp)):?GLuint,(VaryingsTemp)/binary,0:((8-((size(VaryingsTemp)+0) rem 8)) rem 8),BufferMode:?GLenum>>).
%% @doc Retrieve information about varying variables selected for transform feedback
%%
@@ -12322,7 +12360,7 @@ transformFeedbackVaryings(Program,Varyings,BufferMode) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTransformFeedbackVarying.xml">external</a> documentation.
-spec getTransformFeedbackVarying(Program, Index, BufSize) -> {Size :: integer(),Type :: enum(),Name :: string()} when Program :: integer(),Index :: integer(),BufSize :: integer().
getTransformFeedbackVarying(Program,Index,BufSize) ->
- call(5537, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
+ call(5538, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>).
%% @doc specify whether data read via
%%
@@ -12337,7 +12375,7 @@ getTransformFeedbackVarying(Program,Index,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClampColor.xml">external</a> documentation.
-spec clampColor(Target, Clamp) -> 'ok' when Target :: enum(),Clamp :: enum().
clampColor(Target,Clamp) ->
- cast(5538, <<Target:?GLenum,Clamp:?GLenum>>).
+ cast(5539, <<Target:?GLenum,Clamp:?GLenum>>).
%% @doc Start conditional rendering
%%
@@ -12369,84 +12407,84 @@ clampColor(Target,Clamp) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginConditionalRender.xml">external</a> documentation.
-spec beginConditionalRender(Id, Mode) -> 'ok' when Id :: integer(),Mode :: enum().
beginConditionalRender(Id,Mode) ->
- cast(5539, <<Id:?GLuint,Mode:?GLenum>>).
+ cast(5540, <<Id:?GLuint,Mode:?GLenum>>).
%% @doc
%% See {@link beginConditionalRender/2}
-spec endConditionalRender() -> 'ok'.
endConditionalRender() ->
- cast(5540, <<>>).
+ cast(5541, <<>>).
%% @doc glVertexAttribIPointer
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribIPointer.xml">external</a> documentation.
-spec vertexAttribIPointer(Index, Size, Type, Stride, Pointer) -> 'ok' when Index :: integer(),Size :: integer(),Type :: enum(),Stride :: integer(),Pointer :: offset()|mem().
vertexAttribIPointer(Index,Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- cast(5541, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5542, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
vertexAttribIPointer(Index,Size,Type,Stride,Pointer) ->
send_bin(Pointer),
- cast(5542, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
+ cast(5543, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
%% @doc
%% See {@link getVertexAttribdv/2}
-spec getVertexAttribIiv(Index, Pname) -> {integer(),integer(),integer(),integer()} when Index :: integer(),Pname :: enum().
getVertexAttribIiv(Index,Pname) ->
- call(5543, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5544, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc glGetVertexAttribI
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttribI.xml">external</a> documentation.
-spec getVertexAttribIuiv(Index, Pname) -> {integer(),integer(),integer(),integer()} when Index :: integer(),Pname :: enum().
getVertexAttribIuiv(Index,Pname) ->
- call(5544, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5545, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI1i(Index, X) -> 'ok' when Index :: integer(),X :: integer().
vertexAttribI1i(Index,X) ->
- cast(5545, <<Index:?GLuint,X:?GLint>>).
+ cast(5546, <<Index:?GLuint,X:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI2i(Index, X, Y) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer().
vertexAttribI2i(Index,X,Y) ->
- cast(5546, <<Index:?GLuint,X:?GLint,Y:?GLint>>).
+ cast(5547, <<Index:?GLuint,X:?GLint,Y:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI3i(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer().
vertexAttribI3i(Index,X,Y,Z) ->
- cast(5547, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint>>).
+ cast(5548, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4i(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer(),W :: integer().
vertexAttribI4i(Index,X,Y,Z,W) ->
- cast(5548, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
+ cast(5549, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI1ui(Index, X) -> 'ok' when Index :: integer(),X :: integer().
vertexAttribI1ui(Index,X) ->
- cast(5549, <<Index:?GLuint,X:?GLuint>>).
+ cast(5550, <<Index:?GLuint,X:?GLuint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI2ui(Index, X, Y) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer().
vertexAttribI2ui(Index,X,Y) ->
- cast(5550, <<Index:?GLuint,X:?GLuint,Y:?GLuint>>).
+ cast(5551, <<Index:?GLuint,X:?GLuint,Y:?GLuint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI3ui(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer().
vertexAttribI3ui(Index,X,Y,Z) ->
- cast(5551, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint>>).
+ cast(5552, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4ui(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: integer(),Y :: integer(),Z :: integer(),W :: integer().
vertexAttribI4ui(Index,X,Y,Z,W) ->
- cast(5552, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint,W:?GLuint>>).
+ cast(5553, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint,W:?GLuint>>).
%% @equiv vertexAttribI1i(Index,X)
-spec vertexAttribI1iv(Index :: integer(),V) -> 'ok' when V :: {X :: integer()}.
@@ -12484,31 +12522,31 @@ vertexAttribI4uiv(Index,{X,Y,Z,W}) -> vertexAttribI4ui(Index,X,Y,Z,W).
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4bv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttribI4bv(Index,{V1,V2,V3,V4}) ->
- cast(5553, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
+ cast(5554, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4sv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttribI4sv(Index,{V1,V2,V3,V4}) ->
- cast(5554, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
+ cast(5555, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4ubv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttribI4ubv(Index,{V1,V2,V3,V4}) ->
- cast(5555, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
+ cast(5556, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>).
%% @doc
%% See {@link vertexAttrib1d/2}
-spec vertexAttribI4usv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
vertexAttribI4usv(Index,{V1,V2,V3,V4}) ->
- cast(5556, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
+ cast(5557, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>).
%% @doc
%% See {@link getUniformfv/2}
-spec getUniformuiv(Program, Location) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} when Program :: integer(),Location :: integer().
getUniformuiv(Program,Location) ->
- call(5557, <<Program:?GLuint,Location:?GLint>>).
+ call(5558, <<Program:?GLuint,Location:?GLint>>).
%% @doc Bind a user-defined varying out variable to a fragment shader color number
%%
@@ -12535,7 +12573,8 @@ getUniformuiv(Program,Location) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFragDataLocation.xml">external</a> documentation.
-spec bindFragDataLocation(Program, Color, Name) -> 'ok' when Program :: integer(),Color :: integer(),Name :: string().
bindFragDataLocation(Program,Color,Name) ->
- cast(5558, <<Program:?GLuint,Color:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ cast(5559, <<Program:?GLuint,Color:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc Query the bindings of color numbers to user-defined varying out variables
%%
@@ -12548,65 +12587,70 @@ bindFragDataLocation(Program,Color,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFragDataLocation.xml">external</a> documentation.
-spec getFragDataLocation(Program, Name) -> integer() when Program :: integer(),Name :: string().
getFragDataLocation(Program,Name) ->
- call(5559, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5560, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1ui(Location, V0) -> 'ok' when Location :: integer(),V0 :: integer().
uniform1ui(Location,V0) ->
- cast(5560, <<Location:?GLint,V0:?GLuint>>).
+ cast(5561, <<Location:?GLint,V0:?GLuint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2ui(Location, V0, V1) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer().
uniform2ui(Location,V0,V1) ->
- cast(5561, <<Location:?GLint,V0:?GLuint,V1:?GLuint>>).
+ cast(5562, <<Location:?GLint,V0:?GLuint,V1:?GLuint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3ui(Location, V0, V1, V2) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer().
uniform3ui(Location,V0,V1,V2) ->
- cast(5562, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
+ cast(5563, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4ui(Location, V0, V1, V2, V3) -> 'ok' when Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer(),V3 :: integer().
uniform4ui(Location,V0,V1,V2,V3) ->
- cast(5563, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
+ cast(5564, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1uiv(Location, Value) -> 'ok' when Location :: integer(),Value :: [integer()].
uniform1uiv(Location,Value) ->
- cast(5564, <<Location:?GLint,(length(Value)):?GLuint,
- (<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>).
+ ValueLen = length(Value),
+ cast(5565, <<Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2uiv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer()}].
uniform2uiv(Location,Value) ->
- cast(5565, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5566, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3uiv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer(),integer()}].
uniform3uiv(Location,Value) ->
- cast(5566, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5567, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4uiv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{integer(),integer(),integer(),integer()}].
uniform4uiv(Location,Value) ->
- cast(5567, <<Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5568, <<Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link texParameterf/3}
-spec texParameterIiv(Target, Pname, Params) -> 'ok' when Target :: enum(),Pname :: enum(),Params :: tuple().
texParameterIiv(Target,Pname,Params) ->
- cast(5568, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5569, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc glTexParameterI
@@ -12614,21 +12658,21 @@ texParameterIiv(Target,Pname,Params) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameterI.xml">external</a> documentation.
-spec texParameterIuiv(Target, Pname, Params) -> 'ok' when Target :: enum(),Pname :: enum(),Params :: tuple().
texParameterIuiv(Target,Pname,Params) ->
- cast(5569, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
+ cast(5570, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,
(<< <<C:?GLuint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>).
%% @doc
%% See {@link getTexParameterfv/2}
-spec getTexParameterIiv(Target, Pname) -> {integer(),integer(),integer(),integer()} when Target :: enum(),Pname :: enum().
getTexParameterIiv(Target,Pname) ->
- call(5570, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5571, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc glGetTexParameterI
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameterI.xml">external</a> documentation.
-spec getTexParameterIuiv(Target, Pname) -> {integer(),integer(),integer(),integer()} when Target :: enum(),Pname :: enum().
getTexParameterIuiv(Target,Pname) ->
- call(5571, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5572, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc Clear individual buffers of the currently bound draw framebuffer
%%
@@ -12661,21 +12705,21 @@ getTexParameterIuiv(Target,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBuffer.xml">external</a> documentation.
-spec clearBufferiv(Buffer, Drawbuffer, Value) -> 'ok' when Buffer :: enum(),Drawbuffer :: integer(),Value :: tuple().
clearBufferiv(Buffer,Drawbuffer,Value) ->
- cast(5572, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
+ cast(5573, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLint>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @doc
%% See {@link clearBufferiv/3}
-spec clearBufferuiv(Buffer, Drawbuffer, Value) -> 'ok' when Buffer :: enum(),Drawbuffer :: integer(),Value :: tuple().
clearBufferuiv(Buffer,Drawbuffer,Value) ->
- cast(5573, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
+ cast(5574, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLuint>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @doc
%% See {@link clearBufferiv/3}
-spec clearBufferfv(Buffer, Drawbuffer, Value) -> 'ok' when Buffer :: enum(),Drawbuffer :: integer(),Value :: tuple().
clearBufferfv(Buffer,Drawbuffer,Value) ->
- cast(5574, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
+ cast(5575, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint,
(<< <<C:?GLfloat>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>).
%% @doc glClearBufferfi
@@ -12683,30 +12727,30 @@ clearBufferfv(Buffer,Drawbuffer,Value) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBufferfi.xml">external</a> documentation.
-spec clearBufferfi(Buffer, Drawbuffer, Depth, Stencil) -> 'ok' when Buffer :: enum(),Drawbuffer :: integer(),Depth :: float(),Stencil :: integer().
clearBufferfi(Buffer,Drawbuffer,Depth,Stencil) ->
- cast(5575, <<Buffer:?GLenum,Drawbuffer:?GLint,Depth:?GLfloat,Stencil:?GLint>>).
+ cast(5576, <<Buffer:?GLenum,Drawbuffer:?GLint,Depth:?GLfloat,Stencil:?GLint>>).
%% @doc
%% See {@link getString/1}
-spec getStringi(Name, Index) -> string() when Name :: enum(),Index :: integer().
getStringi(Name,Index) ->
- call(5576, <<Name:?GLenum,Index:?GLuint>>).
+ call(5577, <<Name:?GLenum,Index:?GLuint>>).
%% @doc glDrawArraysInstance
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArraysInstance.xml">external</a> documentation.
-spec drawArraysInstanced(Mode, First, Count, Primcount) -> 'ok' when Mode :: enum(),First :: integer(),Count :: integer(),Primcount :: integer().
drawArraysInstanced(Mode,First,Count,Primcount) ->
- cast(5577, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei>>).
+ cast(5578, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei>>).
%% @doc glDrawElementsInstance
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstance.xml">external</a> documentation.
-spec drawElementsInstanced(Mode, Count, Type, Indices, Primcount) -> 'ok' when Mode :: enum(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Primcount :: integer().
drawElementsInstanced(Mode,Count,Type,Indices,Primcount) when is_integer(Indices) ->
- cast(5578, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei>>);
+ cast(5579, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei>>);
drawElementsInstanced(Mode,Count,Type,Indices,Primcount) ->
send_bin(Indices),
- cast(5579, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei>>).
+ cast(5580, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei>>).
%% @doc Attach the storage for a buffer object to the active buffer texture
%%
@@ -12774,7 +12818,7 @@ drawElementsInstanced(Mode,Count,Type,Indices,Primcount) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexBuffer.xml">external</a> documentation.
-spec texBuffer(Target, Internalformat, Buffer) -> 'ok' when Target :: enum(),Internalformat :: enum(),Buffer :: integer().
texBuffer(Target,Internalformat,Buffer) ->
- cast(5580, <<Target:?GLenum,Internalformat:?GLenum,Buffer:?GLuint>>).
+ cast(5581, <<Target:?GLenum,Internalformat:?GLenum,Buffer:?GLuint>>).
%% @doc Specify the primitive restart index
%%
@@ -12796,20 +12840,20 @@ texBuffer(Target,Internalformat,Buffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPrimitiveRestartIndex.xml">external</a> documentation.
-spec primitiveRestartIndex(Index) -> 'ok' when Index :: integer().
primitiveRestartIndex(Index) ->
- cast(5581, <<Index:?GLuint>>).
+ cast(5582, <<Index:?GLuint>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getInteger64i_v(Target, Index) -> [integer()] when Target :: enum(),Index :: integer().
getInteger64i_v(Target,Index) ->
- call(5582, <<Target:?GLenum,Index:?GLuint>>).
+ call(5583, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glGetBufferParameteri64v
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameteri64v.xml">external</a> documentation.
-spec getBufferParameteri64v(Target, Pname) -> [integer()] when Target :: enum(),Pname :: enum().
getBufferParameteri64v(Target,Pname) ->
- call(5583, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5584, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc Attach a level of a texture object as a logical buffer to the currently bound framebuffer object
%%
@@ -12866,7 +12910,7 @@ getBufferParameteri64v(Target,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTexture.xml">external</a> documentation.
-spec framebufferTexture(Target, Attachment, Texture, Level) -> 'ok' when Target :: enum(),Attachment :: enum(),Texture :: integer(),Level :: integer().
framebufferTexture(Target,Attachment,Texture,Level) ->
- cast(5584, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint>>).
+ cast(5585, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint>>).
%% @doc Modify the rate at which generic vertex attributes advance during instanced rendering
%%
@@ -12882,7 +12926,7 @@ framebufferTexture(Target,Attachment,Texture,Level) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribDivisor.xml">external</a> documentation.
-spec vertexAttribDivisor(Index, Divisor) -> 'ok' when Index :: integer(),Divisor :: integer().
vertexAttribDivisor(Index,Divisor) ->
- cast(5585, <<Index:?GLuint,Divisor:?GLuint>>).
+ cast(5586, <<Index:?GLuint,Divisor:?GLuint>>).
%% @doc Specifies minimum rate at which sample shaing takes place
%%
@@ -12903,107 +12947,112 @@ vertexAttribDivisor(Index,Divisor) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMinSampleShading.xml">external</a> documentation.
-spec minSampleShading(Value) -> 'ok' when Value :: clamp().
minSampleShading(Value) ->
- cast(5586, <<Value:?GLclampf>>).
+ cast(5587, <<Value:?GLclampf>>).
%% @doc
%% See {@link blendEquation/1}
-spec blendEquationi(Buf, Mode) -> 'ok' when Buf :: integer(),Mode :: enum().
blendEquationi(Buf,Mode) ->
- cast(5587, <<Buf:?GLuint,Mode:?GLenum>>).
+ cast(5588, <<Buf:?GLuint,Mode:?GLenum>>).
%% @doc
%% See {@link blendEquationSeparate/2}
-spec blendEquationSeparatei(Buf, ModeRGB, ModeAlpha) -> 'ok' when Buf :: integer(),ModeRGB :: enum(),ModeAlpha :: enum().
blendEquationSeparatei(Buf,ModeRGB,ModeAlpha) ->
- cast(5588, <<Buf:?GLuint,ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
+ cast(5589, <<Buf:?GLuint,ModeRGB:?GLenum,ModeAlpha:?GLenum>>).
%% @doc glBlendFunci
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunci.xml">external</a> documentation.
-spec blendFunci(Buf, Src, Dst) -> 'ok' when Buf :: integer(),Src :: enum(),Dst :: enum().
blendFunci(Buf,Src,Dst) ->
- cast(5589, <<Buf:?GLuint,Src:?GLenum,Dst:?GLenum>>).
+ cast(5590, <<Buf:?GLuint,Src:?GLenum,Dst:?GLenum>>).
%% @doc
%% See {@link blendFuncSeparate/4}
-spec blendFuncSeparatei(Buf, SrcRGB, DstRGB, SrcAlpha, DstAlpha) -> 'ok' when Buf :: integer(),SrcRGB :: enum(),DstRGB :: enum(),SrcAlpha :: enum(),DstAlpha :: enum().
blendFuncSeparatei(Buf,SrcRGB,DstRGB,SrcAlpha,DstAlpha) ->
- cast(5590, <<Buf:?GLuint,SrcRGB:?GLenum,DstRGB:?GLenum,SrcAlpha:?GLenum,DstAlpha:?GLenum>>).
+ cast(5591, <<Buf:?GLuint,SrcRGB:?GLenum,DstRGB:?GLenum,SrcAlpha:?GLenum,DstAlpha:?GLenum>>).
%% @doc glLoadTransposeMatrixARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrixARB.xml">external</a> documentation.
-spec loadTransposeMatrixfARB(M) -> 'ok' when M :: matrix().
loadTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- 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>>);
+ cast(5592, <<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}) ->
- 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>>).
+ cast(5592, <<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>>).
%% @doc glLoadTransposeMatrixARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrixARB.xml">external</a> documentation.
-spec loadTransposeMatrixdARB(M) -> 'ok' when M :: matrix().
loadTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- 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>>);
+ cast(5593, <<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}) ->
- 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>>).
+ cast(5593, <<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>>).
%% @doc glMultTransposeMatrixARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrixARB.xml">external</a> documentation.
-spec multTransposeMatrixfARB(M) -> 'ok' when M :: matrix().
multTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- 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>>);
+ cast(5594, <<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}) ->
- 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>>).
+ cast(5594, <<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>>).
%% @doc glMultTransposeMatrixARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrixARB.xml">external</a> documentation.
-spec multTransposeMatrixdARB(M) -> 'ok' when M :: matrix().
multTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) ->
- 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>>);
+ cast(5595, <<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}) ->
- 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>>).
+ cast(5595, <<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>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightbvARB(Weights) -> 'ok' when Weights :: [integer()].
weightbvARB(Weights) ->
- cast(5595, <<(length(Weights)):?GLuint,
- (<< <<C:?GLbyte>> || C <- Weights>>)/binary,0:((8-((length(Weights)+ 4) rem 8)) rem 8)>>).
+ WeightsLen = length(Weights),
+ cast(5596, <<WeightsLen:?GLuint,
+ (<< <<C:?GLbyte>> || C <- Weights>>)/binary,0:((8-((WeightsLen+ 4) rem 8)) rem 8)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightsvARB(Weights) -> 'ok' when Weights :: [integer()].
weightsvARB(Weights) ->
- cast(5596, <<(length(Weights)):?GLuint,
- (<< <<C:?GLshort>> || C <- Weights>>)/binary,0:((8-((length(Weights)*2+ 4) rem 8)) rem 8)>>).
+ WeightsLen = length(Weights),
+ cast(5597, <<WeightsLen:?GLuint,
+ (<< <<C:?GLshort>> || C <- Weights>>)/binary,0:((8-((WeightsLen*2+ 4) rem 8)) rem 8)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightivARB(Weights) -> 'ok' when Weights :: [integer()].
weightivARB(Weights) ->
- cast(5597, <<(length(Weights)):?GLuint,
- (<< <<C:?GLint>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>).
+ WeightsLen = length(Weights),
+ cast(5598, <<WeightsLen:?GLuint,
+ (<< <<C:?GLint>> || C <- Weights>>)/binary,0:(((1+WeightsLen) rem 2)*32)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightfvARB(Weights) -> 'ok' when Weights :: [float()].
weightfvARB(Weights) ->
- cast(5598, <<(length(Weights)):?GLuint,
- (<< <<C:?GLfloat>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>).
+ WeightsLen = length(Weights),
+ cast(5599, <<WeightsLen:?GLuint,
+ (<< <<C:?GLfloat>> || C <- Weights>>)/binary,0:(((1+WeightsLen) rem 2)*32)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightdvARB(Weights) -> 'ok' when Weights :: [float()].
weightdvARB(Weights) ->
- cast(5599, <<(length(Weights)):?GLuint,0:32,
+ WeightsLen = length(Weights),
+ cast(5600, <<WeightsLen:?GLuint,0:32,
(<< <<C:?GLdouble>> || C <- Weights>>)/binary>>).
%% @doc glWeightARB
@@ -13011,175 +13060,183 @@ weightdvARB(Weights) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightubvARB(Weights) -> 'ok' when Weights :: [integer()].
weightubvARB(Weights) ->
- cast(5600, <<(length(Weights)):?GLuint,
- (<< <<C:?GLubyte>> || C <- Weights>>)/binary,0:((8-((length(Weights)+ 4) rem 8)) rem 8)>>).
+ WeightsLen = length(Weights),
+ cast(5601, <<WeightsLen:?GLuint,
+ (<< <<C:?GLubyte>> || C <- Weights>>)/binary,0:((8-((WeightsLen+ 4) rem 8)) rem 8)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightusvARB(Weights) -> 'ok' when Weights :: [integer()].
weightusvARB(Weights) ->
- cast(5601, <<(length(Weights)):?GLuint,
- (<< <<C:?GLushort>> || C <- Weights>>)/binary,0:((8-((length(Weights)*2+ 4) rem 8)) rem 8)>>).
+ WeightsLen = length(Weights),
+ cast(5602, <<WeightsLen:?GLuint,
+ (<< <<C:?GLushort>> || C <- Weights>>)/binary,0:((8-((WeightsLen*2+ 4) rem 8)) rem 8)>>).
%% @doc glWeightARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation.
-spec weightuivARB(Weights) -> 'ok' when Weights :: [integer()].
weightuivARB(Weights) ->
- cast(5602, <<(length(Weights)):?GLuint,
- (<< <<C:?GLuint>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>).
+ WeightsLen = length(Weights),
+ cast(5603, <<WeightsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Weights>>)/binary,0:(((1+WeightsLen) rem 2)*32)>>).
%% @doc glVertexBlenARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexBlenARB.xml">external</a> documentation.
-spec vertexBlendARB(Count) -> 'ok' when Count :: integer().
vertexBlendARB(Count) ->
- cast(5603, <<Count:?GLint>>).
+ cast(5604, <<Count:?GLint>>).
%% @doc glCurrentPaletteMatrixARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCurrentPaletteMatrixARB.xml">external</a> documentation.
-spec currentPaletteMatrixARB(Index) -> 'ok' when Index :: integer().
currentPaletteMatrixARB(Index) ->
- cast(5604, <<Index:?GLint>>).
+ cast(5605, <<Index:?GLint>>).
%% @doc glMatrixIndexARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation.
-spec matrixIndexubvARB(Indices) -> 'ok' when Indices :: [integer()].
matrixIndexubvARB(Indices) ->
- cast(5605, <<(length(Indices)):?GLuint,
- (<< <<C:?GLubyte>> || C <- Indices>>)/binary,0:((8-((length(Indices)+ 4) rem 8)) rem 8)>>).
+ IndicesLen = length(Indices),
+ cast(5606, <<IndicesLen:?GLuint,
+ (<< <<C:?GLubyte>> || C <- Indices>>)/binary,0:((8-((IndicesLen+ 4) rem 8)) rem 8)>>).
%% @doc glMatrixIndexARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation.
-spec matrixIndexusvARB(Indices) -> 'ok' when Indices :: [integer()].
matrixIndexusvARB(Indices) ->
- cast(5606, <<(length(Indices)):?GLuint,
- (<< <<C:?GLushort>> || C <- Indices>>)/binary,0:((8-((length(Indices)*2+ 4) rem 8)) rem 8)>>).
+ IndicesLen = length(Indices),
+ cast(5607, <<IndicesLen:?GLuint,
+ (<< <<C:?GLushort>> || C <- Indices>>)/binary,0:((8-((IndicesLen*2+ 4) rem 8)) rem 8)>>).
%% @doc glMatrixIndexARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation.
-spec matrixIndexuivARB(Indices) -> 'ok' when Indices :: [integer()].
matrixIndexuivARB(Indices) ->
- cast(5607, <<(length(Indices)):?GLuint,
- (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((1+length(Indices)) rem 2)*32)>>).
+ IndicesLen = length(Indices),
+ cast(5608, <<IndicesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((1+IndicesLen) rem 2)*32)>>).
%% @doc glProgramStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramStringARB.xml">external</a> documentation.
-spec programStringARB(Target, Format, String) -> 'ok' when Target :: enum(),Format :: enum(),String :: string().
programStringARB(Target,Format,String) ->
- cast(5608, <<Target:?GLenum,Format:?GLenum,(list_to_binary([String|[0]]))/binary,0:((8-((length(String)+ 1) rem 8)) rem 8)>>).
+ StringLen = length(String),
+ cast(5609, <<Target:?GLenum,Format:?GLenum,(list_to_binary([String|[0]]))/binary,0:((8-((StringLen+ 1) rem 8)) rem 8)>>).
%% @doc glBindProgramARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindProgramARB.xml">external</a> documentation.
-spec bindProgramARB(Target, Program) -> 'ok' when Target :: enum(),Program :: integer().
bindProgramARB(Target,Program) ->
- cast(5609, <<Target:?GLenum,Program:?GLuint>>).
+ cast(5610, <<Target:?GLenum,Program:?GLuint>>).
%% @doc glDeleteProgramsARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgramsARB.xml">external</a> documentation.
-spec deleteProgramsARB(Programs) -> 'ok' when Programs :: [integer()].
deleteProgramsARB(Programs) ->
- cast(5610, <<(length(Programs)):?GLuint,
- (<< <<C:?GLuint>> || C <- Programs>>)/binary,0:(((1+length(Programs)) rem 2)*32)>>).
+ ProgramsLen = length(Programs),
+ cast(5611, <<ProgramsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Programs>>)/binary,0:(((1+ProgramsLen) rem 2)*32)>>).
%% @doc glGenProgramsARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenProgramsARB.xml">external</a> documentation.
-spec genProgramsARB(N) -> [integer()] when N :: integer().
genProgramsARB(N) ->
- call(5611, <<N:?GLsizei>>).
+ call(5612, <<N:?GLsizei>>).
%% @doc glProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
-spec programEnvParameter4dARB(Target, Index, X, Y, Z, W) -> 'ok' when Target :: enum(),Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
programEnvParameter4dARB(Target,Index,X,Y,Z,W) ->
- cast(5612, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5613, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @doc glProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
-spec programEnvParameter4dvARB(Target, Index, Params) -> 'ok' when Target :: enum(),Index :: integer(),Params :: {float(),float(),float(),float()}.
programEnvParameter4dvARB(Target,Index,{P1,P2,P3,P4}) ->
- cast(5613, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
+ cast(5614, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
%% @doc glProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
-spec programEnvParameter4fARB(Target, Index, X, Y, Z, W) -> 'ok' when Target :: enum(),Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
programEnvParameter4fARB(Target,Index,X,Y,Z,W) ->
- cast(5614, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5615, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
%% @doc glProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation.
-spec programEnvParameter4fvARB(Target, Index, Params) -> 'ok' when Target :: enum(),Index :: integer(),Params :: {float(),float(),float(),float()}.
programEnvParameter4fvARB(Target,Index,{P1,P2,P3,P4}) ->
- cast(5615, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
+ cast(5616, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
%% @doc glProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
-spec programLocalParameter4dARB(Target, Index, X, Y, Z, W) -> 'ok' when Target :: enum(),Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
programLocalParameter4dARB(Target,Index,X,Y,Z,W) ->
- cast(5616, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5617, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @doc glProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
-spec programLocalParameter4dvARB(Target, Index, Params) -> 'ok' when Target :: enum(),Index :: integer(),Params :: {float(),float(),float(),float()}.
programLocalParameter4dvARB(Target,Index,{P1,P2,P3,P4}) ->
- cast(5617, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
+ cast(5618, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>).
%% @doc glProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
-spec programLocalParameter4fARB(Target, Index, X, Y, Z, W) -> 'ok' when Target :: enum(),Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
programLocalParameter4fARB(Target,Index,X,Y,Z,W) ->
- cast(5618, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
+ cast(5619, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>).
%% @doc glProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation.
-spec programLocalParameter4fvARB(Target, Index, Params) -> 'ok' when Target :: enum(),Index :: integer(),Params :: {float(),float(),float(),float()}.
programLocalParameter4fvARB(Target,Index,{P1,P2,P3,P4}) ->
- cast(5619, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
+ cast(5620, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>).
%% @doc glGetProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramEnvParameterARB.xml">external</a> documentation.
-spec getProgramEnvParameterdvARB(Target, Index) -> {float(),float(),float(),float()} when Target :: enum(),Index :: integer().
getProgramEnvParameterdvARB(Target,Index) ->
- call(5620, <<Target:?GLenum,Index:?GLuint>>).
+ call(5621, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glGetProgramEnvParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramEnvParameterARB.xml">external</a> documentation.
-spec getProgramEnvParameterfvARB(Target, Index) -> {float(),float(),float(),float()} when Target :: enum(),Index :: integer().
getProgramEnvParameterfvARB(Target,Index) ->
- call(5621, <<Target:?GLenum,Index:?GLuint>>).
+ call(5622, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glGetProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramLocalParameterARB.xml">external</a> documentation.
-spec getProgramLocalParameterdvARB(Target, Index) -> {float(),float(),float(),float()} when Target :: enum(),Index :: integer().
getProgramLocalParameterdvARB(Target,Index) ->
- call(5622, <<Target:?GLenum,Index:?GLuint>>).
+ call(5623, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glGetProgramLocalParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramLocalParameterARB.xml">external</a> documentation.
-spec getProgramLocalParameterfvARB(Target, Index) -> {float(),float(),float(),float()} when Target :: enum(),Index :: integer().
getProgramLocalParameterfvARB(Target,Index) ->
- call(5623, <<Target:?GLenum,Index:?GLuint>>).
+ call(5624, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glGetProgramStringARB
%%
@@ -13187,176 +13244,180 @@ getProgramLocalParameterfvARB(Target,Index) ->
-spec getProgramStringARB(Target, Pname, String) -> 'ok' when Target :: enum(),Pname :: enum(),String :: mem().
getProgramStringARB(Target,Pname,String) ->
send_bin(String),
- call(5624, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5625, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc glGetBufferParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameterARB.xml">external</a> documentation.
-spec getBufferParameterivARB(Target, Pname) -> [integer()] when Target :: enum(),Pname :: enum().
getBufferParameterivARB(Target,Pname) ->
- call(5625, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5626, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc glDeleteObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteObjectARB.xml">external</a> documentation.
-spec deleteObjectARB(Obj) -> 'ok' when Obj :: integer().
deleteObjectARB(Obj) ->
- cast(5626, <<Obj:?GLhandleARB>>).
+ cast(5627, <<Obj:?GLhandleARB>>).
%% @doc glGetHandleARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetHandleARB.xml">external</a> documentation.
-spec getHandleARB(Pname) -> integer() when Pname :: enum().
getHandleARB(Pname) ->
- call(5627, <<Pname:?GLenum>>).
+ call(5628, <<Pname:?GLenum>>).
%% @doc glDetachObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDetachObjectARB.xml">external</a> documentation.
-spec detachObjectARB(ContainerObj, AttachedObj) -> 'ok' when ContainerObj :: integer(),AttachedObj :: integer().
detachObjectARB(ContainerObj,AttachedObj) ->
- cast(5628, <<ContainerObj:?GLhandleARB,AttachedObj:?GLhandleARB>>).
+ cast(5629, <<ContainerObj:?GLhandleARB,AttachedObj:?GLhandleARB>>).
%% @doc glCreateShaderObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShaderObjectARB.xml">external</a> documentation.
-spec createShaderObjectARB(ShaderType) -> integer() when ShaderType :: enum().
createShaderObjectARB(ShaderType) ->
- call(5629, <<ShaderType:?GLenum>>).
+ call(5630, <<ShaderType:?GLenum>>).
%% @doc glShaderSourceARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderSourceARB.xml">external</a> documentation.
-spec shaderSourceARB(ShaderObj, String) -> 'ok' when ShaderObj :: integer(),String :: iolist().
shaderSourceARB(ShaderObj,String) ->
- StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
- cast(5630, <<ShaderObj:?GLhandleARB,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+4) rem 8)) rem 8)>>).
+ StringTemp = list_to_binary([[Str|[0]] || Str <- String ]),
+ StringLen = length(String),
+ cast(5631, <<ShaderObj:?GLhandleARB,StringLen:?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+4) rem 8)) rem 8)>>).
%% @doc glCompileShaderARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShaderARB.xml">external</a> documentation.
-spec compileShaderARB(ShaderObj) -> 'ok' when ShaderObj :: integer().
compileShaderARB(ShaderObj) ->
- cast(5631, <<ShaderObj:?GLhandleARB>>).
+ cast(5632, <<ShaderObj:?GLhandleARB>>).
%% @doc glCreateProgramObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateProgramObjectARB.xml">external</a> documentation.
-spec createProgramObjectARB() -> integer().
createProgramObjectARB() ->
- call(5632, <<>>).
+ call(5633, <<>>).
%% @doc glAttachObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAttachObjectARB.xml">external</a> documentation.
-spec attachObjectARB(ContainerObj, Obj) -> 'ok' when ContainerObj :: integer(),Obj :: integer().
attachObjectARB(ContainerObj,Obj) ->
- cast(5633, <<ContainerObj:?GLhandleARB,Obj:?GLhandleARB>>).
+ cast(5634, <<ContainerObj:?GLhandleARB,Obj:?GLhandleARB>>).
%% @doc glLinkProgramARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgramARB.xml">external</a> documentation.
-spec linkProgramARB(ProgramObj) -> 'ok' when ProgramObj :: integer().
linkProgramARB(ProgramObj) ->
- cast(5634, <<ProgramObj:?GLhandleARB>>).
+ cast(5635, <<ProgramObj:?GLhandleARB>>).
%% @doc glUseProgramObjectARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgramObjectARB.xml">external</a> documentation.
-spec useProgramObjectARB(ProgramObj) -> 'ok' when ProgramObj :: integer().
useProgramObjectARB(ProgramObj) ->
- cast(5635, <<ProgramObj:?GLhandleARB>>).
+ cast(5636, <<ProgramObj:?GLhandleARB>>).
%% @doc glValidateProgramARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgramARB.xml">external</a> documentation.
-spec validateProgramARB(ProgramObj) -> 'ok' when ProgramObj :: integer().
validateProgramARB(ProgramObj) ->
- cast(5636, <<ProgramObj:?GLhandleARB>>).
+ cast(5637, <<ProgramObj:?GLhandleARB>>).
%% @doc glGetObjectParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetObjectParameterARB.xml">external</a> documentation.
-spec getObjectParameterfvARB(Obj, Pname) -> float() when Obj :: integer(),Pname :: enum().
getObjectParameterfvARB(Obj,Pname) ->
- call(5637, <<Obj:?GLhandleARB,Pname:?GLenum>>).
+ call(5638, <<Obj:?GLhandleARB,Pname:?GLenum>>).
%% @doc glGetObjectParameterARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetObjectParameterARB.xml">external</a> documentation.
-spec getObjectParameterivARB(Obj, Pname) -> integer() when Obj :: integer(),Pname :: enum().
getObjectParameterivARB(Obj,Pname) ->
- call(5638, <<Obj:?GLhandleARB,Pname:?GLenum>>).
+ call(5639, <<Obj:?GLhandleARB,Pname:?GLenum>>).
%% @doc glGetInfoLogARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetInfoLogARB.xml">external</a> documentation.
-spec getInfoLogARB(Obj, MaxLength) -> string() when Obj :: integer(),MaxLength :: integer().
getInfoLogARB(Obj,MaxLength) ->
- call(5639, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
+ call(5640, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
%% @doc glGetAttachedObjectsARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttachedObjectsARB.xml">external</a> documentation.
-spec getAttachedObjectsARB(ContainerObj, MaxCount) -> [integer()] when ContainerObj :: integer(),MaxCount :: integer().
getAttachedObjectsARB(ContainerObj,MaxCount) ->
- call(5640, <<ContainerObj:?GLhandleARB,MaxCount:?GLsizei>>).
+ call(5641, <<ContainerObj:?GLhandleARB,MaxCount:?GLsizei>>).
%% @doc glGetUniformLocationARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocationARB.xml">external</a> documentation.
-spec getUniformLocationARB(ProgramObj, Name) -> integer() when ProgramObj :: integer(),Name :: string().
getUniformLocationARB(ProgramObj,Name) ->
- call(5641, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5642, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc glGetActiveUniformARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformARB.xml">external</a> documentation.
-spec getActiveUniformARB(ProgramObj, Index, MaxLength) -> {Size :: integer(),Type :: enum(),Name :: string()} when ProgramObj :: integer(),Index :: integer(),MaxLength :: integer().
getActiveUniformARB(ProgramObj,Index,MaxLength) ->
- call(5642, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
+ call(5643, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
%% @doc glGetUniformARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformARB.xml">external</a> documentation.
-spec getUniformfvARB(ProgramObj, Location) -> matrix() when ProgramObj :: integer(),Location :: integer().
getUniformfvARB(ProgramObj,Location) ->
- call(5643, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
+ call(5644, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
%% @doc glGetUniformARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformARB.xml">external</a> documentation.
-spec getUniformivARB(ProgramObj, Location) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} when ProgramObj :: integer(),Location :: integer().
getUniformivARB(ProgramObj,Location) ->
- call(5644, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
+ call(5645, <<ProgramObj:?GLhandleARB,Location:?GLint>>).
%% @doc glGetShaderSourceARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderSourceARB.xml">external</a> documentation.
-spec getShaderSourceARB(Obj, MaxLength) -> string() when Obj :: integer(),MaxLength :: integer().
getShaderSourceARB(Obj,MaxLength) ->
- call(5645, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
+ call(5646, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>).
%% @doc glBindAttribLocationARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocationARB.xml">external</a> documentation.
-spec bindAttribLocationARB(ProgramObj, Index, Name) -> 'ok' when ProgramObj :: integer(),Index :: integer(),Name :: string().
bindAttribLocationARB(ProgramObj,Index,Name) ->
- cast(5646, <<ProgramObj:?GLhandleARB,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ cast(5647, <<ProgramObj:?GLhandleARB,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc glGetActiveAttribARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveAttribARB.xml">external</a> documentation.
-spec getActiveAttribARB(ProgramObj, Index, MaxLength) -> {Size :: integer(),Type :: enum(),Name :: string()} when ProgramObj :: integer(),Index :: integer(),MaxLength :: integer().
getActiveAttribARB(ProgramObj,Index,MaxLength) ->
- call(5647, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
+ call(5648, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>).
%% @doc glGetAttribLocationARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocationARB.xml">external</a> documentation.
-spec getAttribLocationARB(ProgramObj, Name) -> integer() when ProgramObj :: integer(),Name :: string().
getAttribLocationARB(ProgramObj,Name) ->
- call(5648, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5649, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc Determine if a name corresponds to a renderbuffer object
%%
@@ -13371,7 +13432,7 @@ getAttribLocationARB(ProgramObj,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsRenderbuffer.xml">external</a> documentation.
-spec isRenderbuffer(Renderbuffer) -> 0|1 when Renderbuffer :: integer().
isRenderbuffer(Renderbuffer) ->
- call(5649, <<Renderbuffer:?GLuint>>).
+ call(5650, <<Renderbuffer:?GLuint>>).
%% @doc Bind a renderbuffer to a renderbuffer target
%%
@@ -13384,7 +13445,7 @@ isRenderbuffer(Renderbuffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindRenderbuffer.xml">external</a> documentation.
-spec bindRenderbuffer(Target, Renderbuffer) -> 'ok' when Target :: enum(),Renderbuffer :: integer().
bindRenderbuffer(Target,Renderbuffer) ->
- cast(5650, <<Target:?GLenum,Renderbuffer:?GLuint>>).
+ cast(5651, <<Target:?GLenum,Renderbuffer:?GLuint>>).
%% @doc Delete renderbuffer objects
%%
@@ -13406,8 +13467,9 @@ bindRenderbuffer(Target,Renderbuffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteRenderbuffers.xml">external</a> documentation.
-spec deleteRenderbuffers(Renderbuffers) -> 'ok' when Renderbuffers :: [integer()].
deleteRenderbuffers(Renderbuffers) ->
- cast(5651, <<(length(Renderbuffers)):?GLuint,
- (<< <<C:?GLuint>> || C <- Renderbuffers>>)/binary,0:(((1+length(Renderbuffers)) rem 2)*32)>>).
+ RenderbuffersLen = length(Renderbuffers),
+ cast(5652, <<RenderbuffersLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Renderbuffers>>)/binary,0:(((1+RenderbuffersLen) rem 2)*32)>>).
%% @doc Generate renderbuffer object names
%%
@@ -13425,7 +13487,7 @@ deleteRenderbuffers(Renderbuffers) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenRenderbuffers.xml">external</a> documentation.
-spec genRenderbuffers(N) -> [integer()] when N :: integer().
genRenderbuffers(N) ->
- call(5652, <<N:?GLsizei>>).
+ call(5653, <<N:?GLsizei>>).
%% @doc Establish data storage, format and dimensions of a renderbuffer object's image
%%
@@ -13446,7 +13508,7 @@ genRenderbuffers(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRenderbufferStorage.xml">external</a> documentation.
-spec renderbufferStorage(Target, Internalformat, Width, Height) -> 'ok' when Target :: enum(),Internalformat :: enum(),Width :: integer(),Height :: integer().
renderbufferStorage(Target,Internalformat,Width,Height) ->
- cast(5653, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5654, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
%% @doc Retrieve information about a bound renderbuffer object
%%
@@ -13474,7 +13536,7 @@ renderbufferStorage(Target,Internalformat,Width,Height) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetRenderbufferParameter.xml">external</a> documentation.
-spec getRenderbufferParameteriv(Target, Pname) -> integer() when Target :: enum(),Pname :: enum().
getRenderbufferParameteriv(Target,Pname) ->
- call(5654, <<Target:?GLenum,Pname:?GLenum>>).
+ call(5655, <<Target:?GLenum,Pname:?GLenum>>).
%% @doc Determine if a name corresponds to a framebuffer object
%%
@@ -13488,7 +13550,7 @@ getRenderbufferParameteriv(Target,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsFramebuffer.xml">external</a> documentation.
-spec isFramebuffer(Framebuffer) -> 0|1 when Framebuffer :: integer().
isFramebuffer(Framebuffer) ->
- call(5655, <<Framebuffer:?GLuint>>).
+ call(5656, <<Framebuffer:?GLuint>>).
%% @doc Bind a framebuffer to a framebuffer target
%%
@@ -13506,7 +13568,7 @@ isFramebuffer(Framebuffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFramebuffer.xml">external</a> documentation.
-spec bindFramebuffer(Target, Framebuffer) -> 'ok' when Target :: enum(),Framebuffer :: integer().
bindFramebuffer(Target,Framebuffer) ->
- cast(5656, <<Target:?GLenum,Framebuffer:?GLuint>>).
+ cast(5657, <<Target:?GLenum,Framebuffer:?GLuint>>).
%% @doc Delete framebuffer objects
%%
@@ -13521,8 +13583,9 @@ bindFramebuffer(Target,Framebuffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteFramebuffers.xml">external</a> documentation.
-spec deleteFramebuffers(Framebuffers) -> 'ok' when Framebuffers :: [integer()].
deleteFramebuffers(Framebuffers) ->
- cast(5657, <<(length(Framebuffers)):?GLuint,
- (<< <<C:?GLuint>> || C <- Framebuffers>>)/binary,0:(((1+length(Framebuffers)) rem 2)*32)>>).
+ FramebuffersLen = length(Framebuffers),
+ cast(5658, <<FramebuffersLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Framebuffers>>)/binary,0:(((1+FramebuffersLen) rem 2)*32)>>).
%% @doc Generate framebuffer object names
%%
@@ -13540,7 +13603,7 @@ deleteFramebuffers(Framebuffers) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenFramebuffers.xml">external</a> documentation.
-spec genFramebuffers(N) -> [integer()] when N :: integer().
genFramebuffers(N) ->
- call(5658, <<N:?GLsizei>>).
+ call(5659, <<N:?GLsizei>>).
%% @doc Check the completeness status of a framebuffer
%%
@@ -13591,25 +13654,25 @@ genFramebuffers(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCheckFramebufferStatus.xml">external</a> documentation.
-spec checkFramebufferStatus(Target) -> enum() when Target :: enum().
checkFramebufferStatus(Target) ->
- call(5659, <<Target:?GLenum>>).
+ call(5660, <<Target:?GLenum>>).
%% @doc
%% See {@link framebufferTexture/4}
-spec framebufferTexture1D(Target, Attachment, Textarget, Texture, Level) -> 'ok' when Target :: enum(),Attachment :: enum(),Textarget :: enum(),Texture :: integer(),Level :: integer().
framebufferTexture1D(Target,Attachment,Textarget,Texture,Level) ->
- cast(5660, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
+ cast(5661, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
%% @doc
%% See {@link framebufferTexture/4}
-spec framebufferTexture2D(Target, Attachment, Textarget, Texture, Level) -> 'ok' when Target :: enum(),Attachment :: enum(),Textarget :: enum(),Texture :: integer(),Level :: integer().
framebufferTexture2D(Target,Attachment,Textarget,Texture,Level) ->
- cast(5661, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
+ cast(5662, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>).
%% @doc
%% See {@link framebufferTexture/4}
-spec framebufferTexture3D(Target, Attachment, Textarget, Texture, Level, Zoffset) -> 'ok' when Target :: enum(),Attachment :: enum(),Textarget :: enum(),Texture :: integer(),Level :: integer(),Zoffset :: integer().
framebufferTexture3D(Target,Attachment,Textarget,Texture,Level,Zoffset) ->
- cast(5662, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint,Zoffset:?GLint>>).
+ cast(5663, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint,Zoffset:?GLint>>).
%% @doc Attach a renderbuffer as a logical buffer to the currently bound framebuffer object
%%
@@ -13641,7 +13704,7 @@ framebufferTexture3D(Target,Attachment,Textarget,Texture,Level,Zoffset) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferRenderbuffer.xml">external</a> documentation.
-spec framebufferRenderbuffer(Target, Attachment, Renderbuffertarget, Renderbuffer) -> 'ok' when Target :: enum(),Attachment :: enum(),Renderbuffertarget :: enum(),Renderbuffer :: integer().
framebufferRenderbuffer(Target,Attachment,Renderbuffertarget,Renderbuffer) ->
- cast(5663, <<Target:?GLenum,Attachment:?GLenum,Renderbuffertarget:?GLenum,Renderbuffer:?GLuint>>).
+ cast(5664, <<Target:?GLenum,Attachment:?GLenum,Renderbuffertarget:?GLenum,Renderbuffer:?GLuint>>).
%% @doc Retrieve information about attachments of a bound framebuffer object
%%
@@ -13737,7 +13800,7 @@ framebufferRenderbuffer(Target,Attachment,Renderbuffertarget,Renderbuffer) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFramebufferAttachmentParameter.xml">external</a> documentation.
-spec getFramebufferAttachmentParameteriv(Target, Attachment, Pname) -> integer() when Target :: enum(),Attachment :: enum(),Pname :: enum().
getFramebufferAttachmentParameteriv(Target,Attachment,Pname) ->
- call(5664, <<Target:?GLenum,Attachment:?GLenum,Pname:?GLenum>>).
+ call(5665, <<Target:?GLenum,Attachment:?GLenum,Pname:?GLenum>>).
%% @doc Generate mipmaps for a specified texture target
%%
@@ -13757,7 +13820,7 @@ getFramebufferAttachmentParameteriv(Target,Attachment,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenerateMipmap.xml">external</a> documentation.
-spec generateMipmap(Target) -> 'ok' when Target :: enum().
generateMipmap(Target) ->
- cast(5665, <<Target:?GLenum>>).
+ cast(5666, <<Target:?GLenum>>).
%% @doc Copy a block of pixels from the read framebuffer to the draw framebuffer
%%
@@ -13799,7 +13862,7 @@ generateMipmap(Target) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlitFramebuffer.xml">external</a> documentation.
-spec blitFramebuffer(SrcX0, SrcY0, SrcX1, SrcY1, DstX0, DstY0, DstX1, DstY1, Mask, Filter) -> 'ok' when SrcX0 :: integer(),SrcY0 :: integer(),SrcX1 :: integer(),SrcY1 :: integer(),DstX0 :: integer(),DstY0 :: integer(),DstX1 :: integer(),DstY1 :: integer(),Mask :: integer(),Filter :: enum().
blitFramebuffer(SrcX0,SrcY0,SrcX1,SrcY1,DstX0,DstY0,DstX1,DstY1,Mask,Filter) ->
- cast(5666, <<SrcX0:?GLint,SrcY0:?GLint,SrcX1:?GLint,SrcY1:?GLint,DstX0:?GLint,DstY0:?GLint,DstX1:?GLint,DstY1:?GLint,Mask:?GLbitfield,Filter:?GLenum>>).
+ cast(5667, <<SrcX0:?GLint,SrcY0:?GLint,SrcX1:?GLint,SrcY1:?GLint,DstX0:?GLint,DstY0:?GLint,DstX1:?GLint,DstY1:?GLint,Mask:?GLbitfield,Filter:?GLenum>>).
%% @doc Establish data storage, format, dimensions and sample count of a renderbuffer object's image
%%
@@ -13823,19 +13886,19 @@ blitFramebuffer(SrcX0,SrcY0,SrcX1,SrcY1,DstX0,DstY0,DstX1,DstY1,Mask,Filter) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRenderbufferStorageMultisample.xml">external</a> documentation.
-spec renderbufferStorageMultisample(Target, Samples, Internalformat, Width, Height) -> 'ok' when Target :: enum(),Samples :: integer(),Internalformat :: enum(),Width :: integer(),Height :: integer().
renderbufferStorageMultisample(Target,Samples,Internalformat,Width,Height) ->
- cast(5667, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5668, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
%% @doc
%% See {@link framebufferTexture/4}
-spec framebufferTextureLayer(Target, Attachment, Texture, Level, Layer) -> 'ok' when Target :: enum(),Attachment :: enum(),Texture :: integer(),Level :: integer(),Layer :: integer().
framebufferTextureLayer(Target,Attachment,Texture,Level,Layer) ->
- cast(5668, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Layer:?GLint>>).
+ cast(5669, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Layer:?GLint>>).
%% @doc
%% See {@link framebufferTexture/4}
-spec framebufferTextureFaceARB(Target, Attachment, Texture, Level, Face) -> 'ok' when Target :: enum(),Attachment :: enum(),Texture :: integer(),Level :: integer(),Face :: enum().
framebufferTextureFaceARB(Target,Attachment,Texture,Level,Face) ->
- cast(5669, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Face:?GLenum>>).
+ cast(5670, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Face:?GLenum>>).
%% @doc Indicate modifications to a range of a mapped buffer
%%
@@ -13849,7 +13912,7 @@ framebufferTextureFaceARB(Target,Attachment,Texture,Level,Face) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFlushMappedBufferRange.xml">external</a> documentation.
-spec flushMappedBufferRange(Target, Offset, Length) -> 'ok' when Target :: enum(),Offset :: integer(),Length :: integer().
flushMappedBufferRange(Target,Offset,Length) ->
- cast(5670, <<Target:?GLenum,0:32,Offset:?GLintptr,Length:?GLsizeiptr>>).
+ cast(5671, <<Target:?GLenum,0:32,Offset:?GLintptr,Length:?GLsizeiptr>>).
%% @doc Bind a vertex array object
%%
@@ -13864,7 +13927,7 @@ flushMappedBufferRange(Target,Offset,Length) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindVertexArray.xml">external</a> documentation.
-spec bindVertexArray(Array) -> 'ok' when Array :: integer().
bindVertexArray(Array) ->
- cast(5671, <<Array:?GLuint>>).
+ cast(5672, <<Array:?GLuint>>).
%% @doc Delete vertex array objects
%%
@@ -13877,8 +13940,9 @@ bindVertexArray(Array) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteVertexArrays.xml">external</a> documentation.
-spec deleteVertexArrays(Arrays) -> 'ok' when Arrays :: [integer()].
deleteVertexArrays(Arrays) ->
- cast(5672, <<(length(Arrays)):?GLuint,
- (<< <<C:?GLuint>> || C <- Arrays>>)/binary,0:(((1+length(Arrays)) rem 2)*32)>>).
+ ArraysLen = length(Arrays),
+ cast(5673, <<ArraysLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Arrays>>)/binary,0:(((1+ArraysLen) rem 2)*32)>>).
%% @doc Generate vertex array object names
%%
@@ -13896,7 +13960,7 @@ deleteVertexArrays(Arrays) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenVertexArrays.xml">external</a> documentation.
-spec genVertexArrays(N) -> [integer()] when N :: integer().
genVertexArrays(N) ->
- call(5673, <<N:?GLsizei>>).
+ call(5674, <<N:?GLsizei>>).
%% @doc Determine if a name corresponds to a vertex array object
%%
@@ -13910,7 +13974,7 @@ genVertexArrays(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsVertexArray.xml">external</a> documentation.
-spec isVertexArray(Array) -> 0|1 when Array :: integer().
isVertexArray(Array) ->
- call(5674, <<Array:?GLuint>>).
+ call(5675, <<Array:?GLuint>>).
%% @doc Retrieve the index of a named uniform block
%%
@@ -13937,16 +14001,18 @@ isVertexArray(Array) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformIndices.xml">external</a> documentation.
-spec getUniformIndices(Program, UniformNames) -> [integer()] when Program :: integer(),UniformNames :: iolist().
getUniformIndices(Program,UniformNames) ->
- UniformNamesTemp = list_to_binary([[Str|[0]] || Str <- UniformNames ]),
- call(5675, <<Program:?GLuint,(length(UniformNames)):?GLuint,(size(UniformNamesTemp)):?GLuint,(UniformNamesTemp)/binary,0:((8-((size(UniformNamesTemp)+0) rem 8)) rem 8)>>).
+ UniformNamesTemp = list_to_binary([[Str|[0]] || Str <- UniformNames ]),
+ UniformNamesLen = length(UniformNames),
+ call(5676, <<Program:?GLuint,UniformNamesLen:?GLuint,(size(UniformNamesTemp)):?GLuint,(UniformNamesTemp)/binary,0:((8-((size(UniformNamesTemp)+0) rem 8)) rem 8)>>).
%% @doc glGetActiveUniforms
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniforms.xml">external</a> documentation.
-spec getActiveUniformsiv(Program, UniformIndices, Pname) -> [integer()] when Program :: integer(),UniformIndices :: [integer()],Pname :: enum().
getActiveUniformsiv(Program,UniformIndices,Pname) ->
- call(5676, <<Program:?GLuint,(length(UniformIndices)):?GLuint,
- (<< <<C:?GLuint>> || C <- UniformIndices>>)/binary,0:(((length(UniformIndices)) rem 2)*32),Pname:?GLenum>>).
+ UniformIndicesLen = length(UniformIndices),
+ call(5677, <<Program:?GLuint,UniformIndicesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- UniformIndices>>)/binary,0:(((UniformIndicesLen) rem 2)*32),Pname:?GLenum>>).
%% @doc Query the name of an active uniform
%%
@@ -13975,7 +14041,7 @@ getActiveUniformsiv(Program,UniformIndices,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformName.xml">external</a> documentation.
-spec getActiveUniformName(Program, UniformIndex, BufSize) -> string() when Program :: integer(),UniformIndex :: integer(),BufSize :: integer().
getActiveUniformName(Program,UniformIndex,BufSize) ->
- call(5677, <<Program:?GLuint,UniformIndex:?GLuint,BufSize:?GLsizei>>).
+ call(5678, <<Program:?GLuint,UniformIndex:?GLuint,BufSize:?GLsizei>>).
%% @doc Retrieve the index of a named uniform block
%%
@@ -13999,7 +14065,8 @@ getActiveUniformName(Program,UniformIndex,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformBlockIndex.xml">external</a> documentation.
-spec getUniformBlockIndex(Program, UniformBlockName) -> integer() when Program :: integer(),UniformBlockName :: string().
getUniformBlockIndex(Program,UniformBlockName) ->
- call(5678, <<Program:?GLuint,(list_to_binary([UniformBlockName|[0]]))/binary,0:((8-((length(UniformBlockName)+ 5) rem 8)) rem 8)>>).
+ UniformBlockNameLen = length(UniformBlockName),
+ call(5679, <<Program:?GLuint,(list_to_binary([UniformBlockName|[0]]))/binary,0:((8-((UniformBlockNameLen+ 5) rem 8)) rem 8)>>).
%% @doc Query information about an active uniform block
%%
@@ -14052,7 +14119,7 @@ getUniformBlockIndex(Program,UniformBlockName) ->
-spec getActiveUniformBlockiv(Program, UniformBlockIndex, Pname, Params) -> 'ok' when Program :: integer(),UniformBlockIndex :: integer(),Pname :: enum(),Params :: mem().
getActiveUniformBlockiv(Program,UniformBlockIndex,Pname,Params) ->
send_bin(Params),
- call(5679, <<Program:?GLuint,UniformBlockIndex:?GLuint,Pname:?GLenum>>).
+ call(5680, <<Program:?GLuint,UniformBlockIndex:?GLuint,Pname:?GLenum>>).
%% @doc Retrieve the name of an active uniform block
%%
@@ -14081,7 +14148,7 @@ getActiveUniformBlockiv(Program,UniformBlockIndex,Pname,Params) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformBlockName.xml">external</a> documentation.
-spec getActiveUniformBlockName(Program, UniformBlockIndex, BufSize) -> string() when Program :: integer(),UniformBlockIndex :: integer(),BufSize :: integer().
getActiveUniformBlockName(Program,UniformBlockIndex,BufSize) ->
- call(5680, <<Program:?GLuint,UniformBlockIndex:?GLuint,BufSize:?GLsizei>>).
+ call(5681, <<Program:?GLuint,UniformBlockIndex:?GLuint,BufSize:?GLsizei>>).
%% @doc Assign a binding point to an active uniform block
%%
@@ -14101,7 +14168,7 @@ getActiveUniformBlockName(Program,UniformBlockIndex,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformBlockBinding.xml">external</a> documentation.
-spec uniformBlockBinding(Program, UniformBlockIndex, UniformBlockBinding) -> 'ok' when Program :: integer(),UniformBlockIndex :: integer(),UniformBlockBinding :: integer().
uniformBlockBinding(Program,UniformBlockIndex,UniformBlockBinding) ->
- cast(5681, <<Program:?GLuint,UniformBlockIndex:?GLuint,UniformBlockBinding:?GLuint>>).
+ cast(5682, <<Program:?GLuint,UniformBlockIndex:?GLuint,UniformBlockBinding:?GLuint>>).
%% @doc Copy part of the data store of a buffer object to the data store of another buffer object
%%
@@ -14127,7 +14194,7 @@ uniformBlockBinding(Program,UniformBlockIndex,UniformBlockBinding) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyBufferSubData.xml">external</a> documentation.
-spec copyBufferSubData(ReadTarget, WriteTarget, ReadOffset, WriteOffset, Size) -> 'ok' when ReadTarget :: enum(),WriteTarget :: enum(),ReadOffset :: integer(),WriteOffset :: integer(),Size :: integer().
copyBufferSubData(ReadTarget,WriteTarget,ReadOffset,WriteOffset,Size) ->
- cast(5682, <<ReadTarget:?GLenum,WriteTarget:?GLenum,ReadOffset:?GLintptr,WriteOffset:?GLintptr,Size:?GLsizeiptr>>).
+ cast(5683, <<ReadTarget:?GLenum,WriteTarget:?GLenum,ReadOffset:?GLintptr,WriteOffset:?GLintptr,Size:?GLsizeiptr>>).
%% @doc Render primitives from array data with a per-element offset
%%
@@ -14141,10 +14208,10 @@ copyBufferSubData(ReadTarget,WriteTarget,ReadOffset,WriteOffset,Size) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsBaseVertex.xml">external</a> documentation.
-spec drawElementsBaseVertex(Mode, Count, Type, Indices, Basevertex) -> 'ok' when Mode :: enum(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Basevertex :: integer().
drawElementsBaseVertex(Mode,Count,Type,Indices,Basevertex) when is_integer(Indices) ->
- cast(5683, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Basevertex:?GLint>>);
+ cast(5684, <<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>>).
+ cast(5685, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Basevertex:?GLint>>).
%% @doc Render primitives from array data with a per-element offset
%%
@@ -14163,10 +14230,10 @@ drawElementsBaseVertex(Mode,Count,Type,Indices,Basevertex) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawRangeElementsBaseVertex.xml">external</a> documentation.
-spec drawRangeElementsBaseVertex(Mode, Start, End, Count, Type, Indices, Basevertex) -> 'ok' when Mode :: enum(),Start :: integer(),End :: integer(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Basevertex :: integer().
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>>);
+ cast(5686, <<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>>).
+ cast(5687, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Basevertex:?GLint>>).
%% @doc Render multiple instances of a set of primitives from array data with a per-element offset
%%
@@ -14180,10 +14247,10 @@ drawRangeElementsBaseVertex(Mode,Start,End,Count,Type,Indices,Basevertex) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstancedBaseVertex.xml">external</a> documentation.
-spec drawElementsInstancedBaseVertex(Mode, Count, Type, Indices, Primcount, Basevertex) -> 'ok' when Mode :: enum(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Primcount :: integer(),Basevertex :: integer().
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>>);
+ cast(5688, <<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>>).
+ cast(5689, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Basevertex:?GLint>>).
%% @doc Specifiy the vertex to be used as the source of data for flat shaded varyings
%%
@@ -14217,7 +14284,7 @@ drawElementsInstancedBaseVertex(Mode,Count,Type,Indices,Primcount,Basevertex) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProvokingVertex.xml">external</a> documentation.
-spec provokingVertex(Mode) -> 'ok' when Mode :: enum().
provokingVertex(Mode) ->
- cast(5689, <<Mode:?GLenum>>).
+ cast(5690, <<Mode:?GLenum>>).
%% @doc Create a new sync object and insert it into the GL command stream
%%
@@ -14241,7 +14308,7 @@ provokingVertex(Mode) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFenceSync.xml">external</a> documentation.
-spec fenceSync(Condition, Flags) -> integer() when Condition :: enum(),Flags :: integer().
fenceSync(Condition,Flags) ->
- call(5690, <<Condition:?GLenum,Flags:?GLbitfield>>).
+ call(5691, <<Condition:?GLenum,Flags:?GLbitfield>>).
%% @doc Determine if a name corresponds to a sync object
%%
@@ -14252,7 +14319,7 @@ fenceSync(Condition,Flags) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsSync.xml">external</a> documentation.
-spec isSync(Sync) -> 0|1 when Sync :: integer().
isSync(Sync) ->
- call(5691, <<Sync:?GLsync>>).
+ call(5692, <<Sync:?GLsync>>).
%% @doc Delete a sync object
%%
@@ -14269,7 +14336,7 @@ isSync(Sync) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteSync.xml">external</a> documentation.
-spec deleteSync(Sync) -> 'ok' when Sync :: integer().
deleteSync(Sync) ->
- cast(5692, <<Sync:?GLsync>>).
+ cast(5693, <<Sync:?GLsync>>).
%% @doc Block and wait for a sync object to become signaled
%%
@@ -14295,7 +14362,7 @@ deleteSync(Sync) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClientWaitSync.xml">external</a> documentation.
-spec clientWaitSync(Sync, Flags, Timeout) -> enum() when Sync :: integer(),Flags :: integer(),Timeout :: integer().
clientWaitSync(Sync,Flags,Timeout) ->
- call(5693, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>).
+ call(5694, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>).
%% @doc Instruct the GL server to block until the specified sync object becomes signaled
%%
@@ -14317,13 +14384,13 @@ clientWaitSync(Sync,Flags,Timeout) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWaitSync.xml">external</a> documentation.
-spec waitSync(Sync, Flags, Timeout) -> 'ok' when Sync :: integer(),Flags :: integer(),Timeout :: integer().
waitSync(Sync,Flags,Timeout) ->
- cast(5694, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>).
+ cast(5695, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getInteger64v(Pname) -> [integer()] when Pname :: enum().
getInteger64v(Pname) ->
- call(5695, <<Pname:?GLenum>>).
+ call(5696, <<Pname:?GLenum>>).
%% @doc Query the properties of a sync object
%%
@@ -14358,7 +14425,7 @@ getInteger64v(Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSync.xml">external</a> documentation.
-spec getSynciv(Sync, Pname, BufSize) -> [integer()] when Sync :: integer(),Pname :: enum(),BufSize :: integer().
getSynciv(Sync,Pname,BufSize) ->
- call(5696, <<Sync:?GLsync,Pname:?GLenum,BufSize:?GLsizei>>).
+ call(5697, <<Sync:?GLsync,Pname:?GLenum,BufSize:?GLsizei>>).
%% @doc Establish the data storage, format, dimensions, and number of samples of a multisample texture's image
%%
@@ -14386,7 +14453,7 @@ getSynciv(Sync,Pname,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2DMultisample.xml">external</a> documentation.
-spec texImage2DMultisample(Target, Samples, Internalformat, Width, Height, Fixedsamplelocations) -> 'ok' when Target :: enum(),Samples :: integer(),Internalformat :: integer(),Width :: integer(),Height :: integer(),Fixedsamplelocations :: 0|1.
texImage2DMultisample(Target,Samples,Internalformat,Width,Height,Fixedsamplelocations) ->
- cast(5697, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Fixedsamplelocations:?GLboolean>>).
+ cast(5698, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Fixedsamplelocations:?GLboolean>>).
%% @doc Establish the data storage, format, dimensions, and number of samples of a multisample texture's image
%%
@@ -14414,7 +14481,7 @@ texImage2DMultisample(Target,Samples,Internalformat,Width,Height,Fixedsampleloca
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3DMultisample.xml">external</a> documentation.
-spec texImage3DMultisample(Target, Samples, Internalformat, Width, Height, Depth, Fixedsamplelocations) -> 'ok' when Target :: enum(),Samples :: integer(),Internalformat :: integer(),Width :: integer(),Height :: integer(),Depth :: integer(),Fixedsamplelocations :: 0|1.
texImage3DMultisample(Target,Samples,Internalformat,Width,Height,Depth,Fixedsamplelocations) ->
- cast(5698, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Fixedsamplelocations:?GLboolean>>).
+ cast(5699, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Fixedsamplelocations:?GLboolean>>).
%% @doc Retrieve the location of a sample
%%
@@ -14432,7 +14499,7 @@ texImage3DMultisample(Target,Samples,Internalformat,Width,Height,Depth,Fixedsamp
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMultisample.xml">external</a> documentation.
-spec getMultisamplefv(Pname, Index) -> {float(),float()} when Pname :: enum(),Index :: integer().
getMultisamplefv(Pname,Index) ->
- call(5699, <<Pname:?GLenum,Index:?GLuint>>).
+ call(5700, <<Pname:?GLenum,Index:?GLuint>>).
%% @doc Set the value of a sub-word of the sample mask
%%
@@ -14447,57 +14514,65 @@ getMultisamplefv(Pname,Index) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSampleMaski.xml">external</a> documentation.
-spec sampleMaski(Index, Mask) -> 'ok' when Index :: integer(),Mask :: integer().
sampleMaski(Index,Mask) ->
- cast(5700, <<Index:?GLuint,Mask:?GLbitfield>>).
+ cast(5701, <<Index:?GLuint,Mask:?GLbitfield>>).
%% @doc glNamedStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNamedStringARB.xml">external</a> documentation.
-spec namedStringARB(Type, Name, String) -> 'ok' when Type :: enum(),Name :: string(),String :: string().
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)>>).
+ NameLen = length(Name),
+ StringLen = length(String),
+ cast(5702, <<Type:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8),(list_to_binary([String|[0]]))/binary,0:((8-((StringLen+ 1) rem 8)) rem 8)>>).
%% @doc glDeleteNamedStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteNamedStringARB.xml">external</a> documentation.
-spec deleteNamedStringARB(Name) -> 'ok' when Name :: string().
deleteNamedStringARB(Name) ->
- cast(5702, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ cast(5703, <<(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc glCompileShaderIncludeARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShaderIncludeARB.xml">external</a> documentation.
-spec compileShaderIncludeARB(Shader, Path) -> 'ok' when Shader :: integer(),Path :: iolist().
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)>>).
+ PathTemp = list_to_binary([[Str|[0]] || Str <- Path ]),
+ PathLen = length(Path),
+ cast(5704, <<Shader:?GLuint,PathLen:?GLuint,(size(PathTemp)):?GLuint,(PathTemp)/binary,0:((8-((size(PathTemp)+0) rem 8)) rem 8)>>).
%% @doc glIsNamedStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsNamedStringARB.xml">external</a> documentation.
-spec isNamedStringARB(Name) -> 0|1 when Name :: string().
isNamedStringARB(Name) ->
- call(5704, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5705, <<(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc glGetNamedStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetNamedStringARB.xml">external</a> documentation.
-spec getNamedStringARB(Name, BufSize) -> string() when Name :: string(),BufSize :: integer().
getNamedStringARB(Name,BufSize) ->
- call(5705, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8),BufSize:?GLsizei>>).
+ NameLen = length(Name),
+ call(5706, <<(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8),BufSize:?GLsizei>>).
%% @doc glGetNamedStringARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetNamedStringARB.xml">external</a> documentation.
-spec getNamedStringivARB(Name, Pname) -> integer() when Name :: string(),Pname :: enum().
getNamedStringivARB(Name,Pname) ->
- call(5706, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8),Pname:?GLenum>>).
+ NameLen = length(Name),
+ call(5707, <<(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8),Pname:?GLenum>>).
%% @doc glBindFragDataLocationIndexe
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFragDataLocationIndexe.xml">external</a> documentation.
-spec bindFragDataLocationIndexed(Program, ColorNumber, Index, Name) -> 'ok' when Program :: integer(),ColorNumber :: integer(),Index :: integer(),Name :: string().
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)>>).
+ NameLen = length(Name),
+ cast(5708, <<Program:?GLuint,ColorNumber:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc Query the bindings of color indices to user-defined varying out variables
%%
@@ -14508,7 +14583,8 @@ bindFragDataLocationIndexed(Program,ColorNumber,Index,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFragDataIndex.xml">external</a> documentation.
-spec getFragDataIndex(Program, Name) -> integer() when Program :: integer(),Name :: string().
getFragDataIndex(Program,Name) ->
- call(5708, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>).
+ NameLen = length(Name),
+ call(5709, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 5) rem 8)) rem 8)>>).
%% @doc Generate sampler object names
%%
@@ -14526,7 +14602,7 @@ getFragDataIndex(Program,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenSamplers.xml">external</a> documentation.
-spec genSamplers(Count) -> [integer()] when Count :: integer().
genSamplers(Count) ->
- call(5709, <<Count:?GLsizei>>).
+ call(5710, <<Count:?GLsizei>>).
%% @doc Delete named sampler objects
%%
@@ -14539,8 +14615,9 @@ genSamplers(Count) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteSamplers.xml">external</a> documentation.
-spec deleteSamplers(Samplers) -> 'ok' when Samplers :: [integer()].
deleteSamplers(Samplers) ->
- cast(5710, <<(length(Samplers)):?GLuint,
- (<< <<C:?GLuint>> || C <- Samplers>>)/binary,0:(((1+length(Samplers)) rem 2)*32)>>).
+ SamplersLen = length(Samplers),
+ cast(5711, <<SamplersLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Samplers>>)/binary,0:(((1+SamplersLen) rem 2)*32)>>).
%% @doc Determine if a name corresponds to a sampler object
%%
@@ -14553,7 +14630,7 @@ deleteSamplers(Samplers) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsSampler.xml">external</a> documentation.
-spec isSampler(Sampler) -> 0|1 when Sampler :: integer().
isSampler(Sampler) ->
- call(5711, <<Sampler:?GLuint>>).
+ call(5712, <<Sampler:?GLuint>>).
%% @doc Bind a named sampler to a texturing target
%%
@@ -14570,7 +14647,7 @@ isSampler(Sampler) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindSampler.xml">external</a> documentation.
-spec bindSampler(Unit, Sampler) -> 'ok' when Unit :: integer(),Sampler :: integer().
bindSampler(Unit,Sampler) ->
- cast(5712, <<Unit:?GLuint,Sampler:?GLuint>>).
+ cast(5713, <<Unit:?GLuint,Sampler:?GLuint>>).
%% @doc Set sampler parameters
%%
@@ -14716,42 +14793,46 @@ bindSampler(Unit,Sampler) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameter.xml">external</a> documentation.
-spec samplerParameteri(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: integer().
samplerParameteri(Sampler,Pname,Param) ->
- cast(5713, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLint>>).
+ cast(5714, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLint>>).
%% @doc
%% See {@link samplerParameteri/3}
-spec samplerParameteriv(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: [integer()].
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)>>).
+ ParamLen = length(Param),
+ cast(5715, <<Sampler:?GLuint,Pname:?GLenum,ParamLen:?GLuint,
+ (<< <<C:?GLint>> || C <- Param>>)/binary,0:(((1+ParamLen) rem 2)*32)>>).
%% @doc
%% See {@link samplerParameteri/3}
-spec samplerParameterf(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: float().
samplerParameterf(Sampler,Pname,Param) ->
- cast(5715, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLfloat>>).
+ cast(5716, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLfloat>>).
%% @doc
%% See {@link samplerParameteri/3}
-spec samplerParameterfv(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: [float()].
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)>>).
+ ParamLen = length(Param),
+ cast(5717, <<Sampler:?GLuint,Pname:?GLenum,ParamLen:?GLuint,
+ (<< <<C:?GLfloat>> || C <- Param>>)/binary,0:(((1+ParamLen) rem 2)*32)>>).
%% @doc
%% See {@link samplerParameteri/3}
-spec samplerParameterIiv(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: [integer()].
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)>>).
+ ParamLen = length(Param),
+ cast(5718, <<Sampler:?GLuint,Pname:?GLenum,ParamLen:?GLuint,
+ (<< <<C:?GLint>> || C <- Param>>)/binary,0:(((1+ParamLen) rem 2)*32)>>).
%% @doc glSamplerParameterI
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameterI.xml">external</a> documentation.
-spec samplerParameterIuiv(Sampler, Pname, Param) -> 'ok' when Sampler :: integer(),Pname :: enum(),Param :: [integer()].
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)>>).
+ ParamLen = length(Param),
+ cast(5719, <<Sampler:?GLuint,Pname:?GLenum,ParamLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Param>>)/binary,0:(((1+ParamLen) rem 2)*32)>>).
%% @doc Return sampler parameter values
%%
@@ -14798,26 +14879,26 @@ samplerParameterIuiv(Sampler,Pname,Param) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameter.xml">external</a> documentation.
-spec getSamplerParameteriv(Sampler, Pname) -> [integer()] when Sampler :: integer(),Pname :: enum().
getSamplerParameteriv(Sampler,Pname) ->
- call(5719, <<Sampler:?GLuint,Pname:?GLenum>>).
+ call(5720, <<Sampler:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link getSamplerParameteriv/2}
-spec getSamplerParameterIiv(Sampler, Pname) -> [integer()] when Sampler :: integer(),Pname :: enum().
getSamplerParameterIiv(Sampler,Pname) ->
- call(5720, <<Sampler:?GLuint,Pname:?GLenum>>).
+ call(5721, <<Sampler:?GLuint,Pname:?GLenum>>).
%% @doc
%% See {@link getSamplerParameteriv/2}
-spec getSamplerParameterfv(Sampler, Pname) -> [float()] when Sampler :: integer(),Pname :: enum().
getSamplerParameterfv(Sampler,Pname) ->
- call(5721, <<Sampler:?GLuint,Pname:?GLenum>>).
+ call(5722, <<Sampler:?GLuint,Pname:?GLenum>>).
%% @doc glGetSamplerParameterI
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameterI.xml">external</a> documentation.
-spec getSamplerParameterIuiv(Sampler, Pname) -> [integer()] when Sampler :: integer(),Pname :: enum().
getSamplerParameterIuiv(Sampler,Pname) ->
- call(5722, <<Sampler:?GLuint,Pname:?GLenum>>).
+ call(5723, <<Sampler:?GLuint,Pname:?GLenum>>).
%% @doc Record the GL time into a query object after all previous commands have reached the GL server but have not yet necessarily executed.
%%
@@ -14832,21 +14913,21 @@ getSamplerParameterIuiv(Sampler,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glQueryCounter.xml">external</a> documentation.
-spec queryCounter(Id, Target) -> 'ok' when Id :: integer(),Target :: enum().
queryCounter(Id,Target) ->
- cast(5723, <<Id:?GLuint,Target:?GLenum>>).
+ cast(5724, <<Id:?GLuint,Target:?GLenum>>).
%% @doc glGetQueryObjecti64v
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObjecti64v.xml">external</a> documentation.
-spec getQueryObjecti64v(Id, Pname) -> integer() when Id :: integer(),Pname :: enum().
getQueryObjecti64v(Id,Pname) ->
- call(5724, <<Id:?GLuint,Pname:?GLenum>>).
+ call(5725, <<Id:?GLuint,Pname:?GLenum>>).
%% @doc glGetQueryObjectui64v
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObjectui64v.xml">external</a> documentation.
-spec getQueryObjectui64v(Id, Pname) -> integer() when Id :: integer(),Pname :: enum().
getQueryObjectui64v(Id,Pname) ->
- call(5725, <<Id:?GLuint,Pname:?GLenum>>).
+ call(5726, <<Id:?GLuint,Pname:?GLenum>>).
%% @doc Render primitives from array data, taking parameters from memory
%%
@@ -14876,10 +14957,10 @@ getQueryObjectui64v(Id,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArraysIndirect.xml">external</a> documentation.
-spec drawArraysIndirect(Mode, Indirect) -> 'ok' when Mode :: enum(),Indirect :: offset()|mem().
drawArraysIndirect(Mode,Indirect) when is_integer(Indirect) ->
- cast(5726, <<Mode:?GLenum,Indirect:?GLuint>>);
+ cast(5727, <<Mode:?GLenum,Indirect:?GLuint>>);
drawArraysIndirect(Mode,Indirect) ->
send_bin(Indirect),
- cast(5727, <<Mode:?GLenum>>).
+ cast(5728, <<Mode:?GLenum>>).
%% @doc Render indexed primitives from array data, taking parameters from memory
%%
@@ -14916,131 +14997,144 @@ drawArraysIndirect(Mode,Indirect) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsIndirect.xml">external</a> documentation.
-spec drawElementsIndirect(Mode, Type, Indirect) -> 'ok' when Mode :: enum(),Type :: enum(),Indirect :: offset()|mem().
drawElementsIndirect(Mode,Type,Indirect) when is_integer(Indirect) ->
- cast(5728, <<Mode:?GLenum,Type:?GLenum,Indirect:?GLuint>>);
+ cast(5729, <<Mode:?GLenum,Type:?GLenum,Indirect:?GLuint>>);
drawElementsIndirect(Mode,Type,Indirect) ->
send_bin(Indirect),
- cast(5729, <<Mode:?GLenum,Type:?GLenum>>).
+ cast(5730, <<Mode:?GLenum,Type:?GLenum>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1d(Location, X) -> 'ok' when Location :: integer(),X :: float().
uniform1d(Location,X) ->
- cast(5730, <<Location:?GLint,0:32,X:?GLdouble>>).
+ cast(5731, <<Location:?GLint,0:32,X:?GLdouble>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2d(Location, X, Y) -> 'ok' when Location :: integer(),X :: float(),Y :: float().
uniform2d(Location,X,Y) ->
- cast(5731, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble>>).
+ cast(5732, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3d(Location, X, Y, Z) -> 'ok' when Location :: integer(),X :: float(),Y :: float(),Z :: float().
uniform3d(Location,X,Y,Z) ->
- cast(5732, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5733, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4d(Location, X, Y, Z, W) -> 'ok' when Location :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
uniform4d(Location,X,Y,Z,W) ->
- cast(5733, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5734, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform1dv(Location, Value) -> 'ok' when Location :: integer(),Value :: [float()].
uniform1dv(Location,Value) ->
- cast(5734, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5735, <<Location:?GLint,0:32,ValueLen:?GLuint,0:32,
(<< <<C:?GLdouble>> || C <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform2dv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float()}].
uniform2dv(Location,Value) ->
- cast(5735, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5736, <<Location:?GLint,0:32,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform3dv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float(),float()}].
uniform3dv(Location,Value) ->
- cast(5736, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5737, <<Location:?GLint,0:32,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniform4dv(Location, Value) -> 'ok' when Location :: integer(),Value :: [{float(),float(),float(),float()}].
uniform4dv(Location,Value) ->
- cast(5737, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5738, <<Location:?GLint,0:32,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float()}].
uniformMatrix2dv(Location,Transpose,Value) ->
- cast(5738, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5739, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix3dv(Location,Transpose,Value) ->
- cast(5739, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5740, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4dv(Location,Transpose,Value) ->
- cast(5740, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5741, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2x3dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
uniformMatrix2x3dv(Location,Transpose,Value) ->
- cast(5741, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5742, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix2x4dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix2x4dv(Location,Transpose,Value) ->
- cast(5742, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5743, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3x2dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
uniformMatrix3x2dv(Location,Transpose,Value) ->
- cast(5743, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5744, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix3x4dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix3x4dv(Location,Transpose,Value) ->
- cast(5744, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5745, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4x2dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4x2dv(Location,Transpose,Value) ->
- cast(5745, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5746, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link uniform1f/2}
-spec uniformMatrix4x3dv(Location, Transpose, Value) -> 'ok' when Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
uniformMatrix4x3dv(Location,Transpose,Value) ->
- cast(5746, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5747, <<Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link getUniformfv/2}
-spec getUniformdv(Program, Location) -> matrix() when Program :: integer(),Location :: integer().
getUniformdv(Program,Location) ->
- call(5747, <<Program:?GLuint,Location:?GLint>>).
+ call(5748, <<Program:?GLuint,Location:?GLint>>).
%% @doc Retrieve the location of a subroutine uniform of a given shader stage within a program
%%
@@ -15059,7 +15153,8 @@ getUniformdv(Program,Location) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSubroutineUniformLocation.xml">external</a> documentation.
-spec getSubroutineUniformLocation(Program, Shadertype, Name) -> integer() when Program :: integer(),Shadertype :: enum(),Name :: string().
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)>>).
+ NameLen = length(Name),
+ call(5749, <<Program:?GLuint,Shadertype:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc Retrieve the index of a subroutine uniform of a given shader stage within a program
%%
@@ -15079,7 +15174,8 @@ getSubroutineUniformLocation(Program,Shadertype,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSubroutineIndex.xml">external</a> documentation.
-spec getSubroutineIndex(Program, Shadertype, Name) -> integer() when Program :: integer(),Shadertype :: enum(),Name :: string().
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)>>).
+ NameLen = length(Name),
+ call(5750, <<Program:?GLuint,Shadertype:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((NameLen+ 1) rem 8)) rem 8)>>).
%% @doc Query the name of an active shader subroutine uniform
%%
@@ -15100,7 +15196,7 @@ getSubroutineIndex(Program,Shadertype,Name) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveSubroutineUniformName.xml">external</a> documentation.
-spec getActiveSubroutineUniformName(Program, Shadertype, Index, Bufsize) -> string() when Program :: integer(),Shadertype :: enum(),Index :: integer(),Bufsize :: integer().
getActiveSubroutineUniformName(Program,Shadertype,Index,Bufsize) ->
- call(5750, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>).
+ call(5751, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>).
%% @doc Query the name of an active shader subroutine
%%
@@ -15118,7 +15214,7 @@ getActiveSubroutineUniformName(Program,Shadertype,Index,Bufsize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveSubroutineName.xml">external</a> documentation.
-spec getActiveSubroutineName(Program, Shadertype, Index, Bufsize) -> string() when Program :: integer(),Shadertype :: enum(),Index :: integer(),Bufsize :: integer().
getActiveSubroutineName(Program,Shadertype,Index,Bufsize) ->
- call(5751, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>).
+ call(5752, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>).
%% @doc Load active subroutine uniforms
%%
@@ -15132,8 +15228,9 @@ getActiveSubroutineName(Program,Shadertype,Index,Bufsize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformSubroutines.xml">external</a> documentation.
-spec uniformSubroutinesuiv(Shadertype, Indices) -> 'ok' when Shadertype :: enum(),Indices :: [integer()].
uniformSubroutinesuiv(Shadertype,Indices) ->
- cast(5752, <<Shadertype:?GLenum,(length(Indices)):?GLuint,
- (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((length(Indices)) rem 2)*32)>>).
+ IndicesLen = length(Indices),
+ cast(5753, <<Shadertype:?GLenum,IndicesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((IndicesLen) rem 2)*32)>>).
%% @doc Retrieve the value of a subroutine uniform of a given shader stage of the current program
%%
@@ -15146,7 +15243,7 @@ uniformSubroutinesuiv(Shadertype,Indices) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformSubroutine.xml">external</a> documentation.
-spec getUniformSubroutineuiv(Shadertype, Location) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} when Shadertype :: enum(),Location :: integer().
getUniformSubroutineuiv(Shadertype,Location) ->
- call(5753, <<Shadertype:?GLenum,Location:?GLint>>).
+ call(5754, <<Shadertype:?GLenum,Location:?GLint>>).
%% @doc Retrieve properties of a program object corresponding to a specified shader stage
%%
@@ -15178,7 +15275,7 @@ getUniformSubroutineuiv(Shadertype,Location) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramStage.xml">external</a> documentation.
-spec getProgramStageiv(Program, Shadertype, Pname) -> integer() when Program :: integer(),Shadertype :: enum(),Pname :: enum().
getProgramStageiv(Program,Shadertype,Pname) ->
- call(5754, <<Program:?GLuint,Shadertype:?GLenum,Pname:?GLenum>>).
+ call(5755, <<Program:?GLuint,Shadertype:?GLenum,Pname:?GLenum>>).
%% @doc Specifies the parameters for patch primitives
%%
@@ -15205,14 +15302,15 @@ getProgramStageiv(Program,Shadertype,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPatchParameter.xml">external</a> documentation.
-spec patchParameteri(Pname, Value) -> 'ok' when Pname :: enum(),Value :: integer().
patchParameteri(Pname,Value) ->
- cast(5755, <<Pname:?GLenum,Value:?GLint>>).
+ cast(5756, <<Pname:?GLenum,Value:?GLint>>).
%% @doc
%% See {@link patchParameteri/2}
-spec patchParameterfv(Pname, Values) -> 'ok' when Pname :: enum(),Values :: [float()].
patchParameterfv(Pname,Values) ->
- cast(5756, <<Pname:?GLenum,(length(Values)):?GLuint,
- (<< <<C:?GLfloat>> || C <- Values>>)/binary,0:(((length(Values)) rem 2)*32)>>).
+ ValuesLen = length(Values),
+ cast(5757, <<Pname:?GLenum,ValuesLen:?GLuint,
+ (<< <<C:?GLfloat>> || C <- Values>>)/binary,0:(((ValuesLen) rem 2)*32)>>).
%% @doc Bind a transform feedback object
%%
@@ -15235,7 +15333,7 @@ patchParameterfv(Pname,Values) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindTransformFeedback.xml">external</a> documentation.
-spec bindTransformFeedback(Target, Id) -> 'ok' when Target :: enum(),Id :: integer().
bindTransformFeedback(Target,Id) ->
- cast(5757, <<Target:?GLenum,Id:?GLuint>>).
+ cast(5758, <<Target:?GLenum,Id:?GLuint>>).
%% @doc Delete transform feedback objects
%%
@@ -15248,8 +15346,9 @@ bindTransformFeedback(Target,Id) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTransformFeedbacks.xml">external</a> documentation.
-spec deleteTransformFeedbacks(Ids) -> 'ok' when Ids :: [integer()].
deleteTransformFeedbacks(Ids) ->
- cast(5758, <<(length(Ids)):?GLuint,
- (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+length(Ids)) rem 2)*32)>>).
+ IdsLen = length(Ids),
+ cast(5759, <<IdsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+IdsLen) rem 2)*32)>>).
%% @doc Reserve transform feedback object names
%%
@@ -15260,7 +15359,7 @@ deleteTransformFeedbacks(Ids) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenTransformFeedbacks.xml">external</a> documentation.
-spec genTransformFeedbacks(N) -> [integer()] when N :: integer().
genTransformFeedbacks(N) ->
- call(5759, <<N:?GLsizei>>).
+ call(5760, <<N:?GLsizei>>).
%% @doc Determine if a name corresponds to a transform feedback object
%%
@@ -15275,7 +15374,7 @@ genTransformFeedbacks(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsTransformFeedback.xml">external</a> documentation.
-spec isTransformFeedback(Id) -> 0|1 when Id :: integer().
isTransformFeedback(Id) ->
- call(5760, <<Id:?GLuint>>).
+ call(5761, <<Id:?GLuint>>).
%% @doc Pause transform feedback operations
%%
@@ -15288,7 +15387,7 @@ isTransformFeedback(Id) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPauseTransformFeedback.xml">external</a> documentation.
-spec pauseTransformFeedback() -> 'ok'.
pauseTransformFeedback() ->
- cast(5761, <<>>).
+ cast(5762, <<>>).
%% @doc Resume transform feedback operations
%%
@@ -15301,7 +15400,7 @@ pauseTransformFeedback() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glResumeTransformFeedback.xml">external</a> documentation.
-spec resumeTransformFeedback() -> 'ok'.
resumeTransformFeedback() ->
- cast(5762, <<>>).
+ cast(5763, <<>>).
%% @doc Render primitives using a count derived from a transform feedback object
%%
@@ -15315,7 +15414,7 @@ resumeTransformFeedback() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedback.xml">external</a> documentation.
-spec drawTransformFeedback(Mode, Id) -> 'ok' when Mode :: enum(),Id :: integer().
drawTransformFeedback(Mode,Id) ->
- cast(5763, <<Mode:?GLenum,Id:?GLuint>>).
+ cast(5764, <<Mode:?GLenum,Id:?GLuint>>).
%% @doc Render primitives using a count derived from a specifed stream of a transform feedback object
%%
@@ -15333,14 +15432,14 @@ drawTransformFeedback(Mode,Id) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedbackStream.xml">external</a> documentation.
-spec drawTransformFeedbackStream(Mode, Id, Stream) -> 'ok' when Mode :: enum(),Id :: integer(),Stream :: integer().
drawTransformFeedbackStream(Mode,Id,Stream) ->
- cast(5764, <<Mode:?GLenum,Id:?GLuint,Stream:?GLuint>>).
+ cast(5765, <<Mode:?GLenum,Id:?GLuint,Stream:?GLuint>>).
%% @doc glBeginQueryIndexe
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginQueryIndexe.xml">external</a> documentation.
-spec beginQueryIndexed(Target, Index, Id) -> 'ok' when Target :: enum(),Index :: integer(),Id :: integer().
beginQueryIndexed(Target,Index,Id) ->
- cast(5765, <<Target:?GLenum,Index:?GLuint,Id:?GLuint>>).
+ cast(5766, <<Target:?GLenum,Index:?GLuint,Id:?GLuint>>).
%% @doc Delimit the boundaries of a query object on an indexed target
%%
@@ -15417,7 +15516,7 @@ beginQueryIndexed(Target,Index,Id) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginQueryIndexed.xml">external</a> documentation.
-spec endQueryIndexed(Target, Index) -> 'ok' when Target :: enum(),Index :: integer().
endQueryIndexed(Target,Index) ->
- cast(5766, <<Target:?GLenum,Index:?GLuint>>).
+ cast(5767, <<Target:?GLenum,Index:?GLuint>>).
%% @doc Return parameters of an indexed query object target
%%
@@ -15435,7 +15534,7 @@ endQueryIndexed(Target,Index) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryIndexed.xml">external</a> documentation.
-spec getQueryIndexediv(Target, Index, Pname) -> integer() when Target :: enum(),Index :: integer(),Pname :: enum().
getQueryIndexediv(Target,Index,Pname) ->
- call(5767, <<Target:?GLenum,Index:?GLuint,Pname:?GLenum>>).
+ call(5768, <<Target:?GLenum,Index:?GLuint,Pname:?GLenum>>).
%% @doc Release resources consumed by the implementation's shader compiler
%%
@@ -15447,7 +15546,7 @@ getQueryIndexediv(Target,Index,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glReleaseShaderCompiler.xml">external</a> documentation.
-spec releaseShaderCompiler() -> 'ok'.
releaseShaderCompiler() ->
- cast(5768, <<>>).
+ cast(5769, <<>>).
%% @doc Load pre-compiled shader binaries
%%
@@ -15469,9 +15568,10 @@ releaseShaderCompiler() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderBinary.xml">external</a> documentation.
-spec shaderBinary(Shaders, Binaryformat, Binary) -> 'ok' when Shaders :: [integer()],Binaryformat :: enum(),Binary :: binary().
shaderBinary(Shaders,Binaryformat,Binary) ->
+ ShadersLen = length(Shaders),
send_bin(Binary),
- cast(5769, <<(length(Shaders)):?GLuint,
- (<< <<C:?GLuint>> || C <- Shaders>>)/binary,0:(((1+length(Shaders)) rem 2)*32),Binaryformat:?GLenum>>).
+ cast(5770, <<ShadersLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Shaders>>)/binary,0:(((1+ShadersLen) rem 2)*32),Binaryformat:?GLenum>>).
%% @doc Retrieve the range and precision for numeric formats supported by the shader compiler
%%
@@ -15496,20 +15596,20 @@ shaderBinary(Shaders,Binaryformat,Binary) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderPrecisionFormat.xml">external</a> documentation.
-spec getShaderPrecisionFormat(Shadertype, Precisiontype) -> {Range :: {integer(),integer()},Precision :: integer()} when Shadertype :: enum(),Precisiontype :: enum().
getShaderPrecisionFormat(Shadertype,Precisiontype) ->
- call(5770, <<Shadertype:?GLenum,Precisiontype:?GLenum>>).
+ call(5771, <<Shadertype:?GLenum,Precisiontype:?GLenum>>).
%% @doc
%% See {@link depthRange/2}
-spec depthRangef(N, F) -> 'ok' when N :: clamp(),F :: clamp().
depthRangef(N,F) ->
- cast(5771, <<N:?GLclampf,F:?GLclampf>>).
+ cast(5772, <<N:?GLclampf,F:?GLclampf>>).
%% @doc glClearDepthf
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearDepthf.xml">external</a> documentation.
-spec clearDepthf(D) -> 'ok' when D :: clamp().
clearDepthf(D) ->
- cast(5772, <<D:?GLclampf>>).
+ cast(5773, <<D:?GLclampf>>).
%% @doc Return a binary representation of a program object's compiled and linked executable source
%%
@@ -15530,7 +15630,7 @@ clearDepthf(D) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramBinary.xml">external</a> documentation.
-spec getProgramBinary(Program, BufSize) -> {BinaryFormat :: enum(),Binary :: binary()} when Program :: integer(),BufSize :: integer().
getProgramBinary(Program,BufSize) ->
- call(5773, <<Program:?GLuint,BufSize:?GLsizei>>).
+ call(5774, <<Program:?GLuint,BufSize:?GLsizei>>).
%% @doc Load a program object with a program binary
%%
@@ -15558,7 +15658,7 @@ getProgramBinary(Program,BufSize) ->
-spec programBinary(Program, BinaryFormat, Binary) -> 'ok' when Program :: integer(),BinaryFormat :: enum(),Binary :: binary().
programBinary(Program,BinaryFormat,Binary) ->
send_bin(Binary),
- cast(5774, <<Program:?GLuint,BinaryFormat:?GLenum>>).
+ cast(5775, <<Program:?GLuint,BinaryFormat:?GLenum>>).
%% @doc Specify a parameter for a program object
%%
@@ -15583,7 +15683,7 @@ programBinary(Program,BinaryFormat,Binary) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramParameter.xml">external</a> documentation.
-spec programParameteri(Program, Pname, Value) -> 'ok' when Program :: integer(),Pname :: enum(),Value :: integer().
programParameteri(Program,Pname,Value) ->
- cast(5775, <<Program:?GLuint,Pname:?GLenum,Value:?GLint>>).
+ cast(5776, <<Program:?GLuint,Pname:?GLenum,Value:?GLint>>).
%% @doc Bind stages of a program object to a program pipeline
%%
@@ -15608,7 +15708,7 @@ programParameteri(Program,Pname,Value) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgramStages.xml">external</a> documentation.
-spec useProgramStages(Pipeline, Stages, Program) -> 'ok' when Pipeline :: integer(),Stages :: integer(),Program :: integer().
useProgramStages(Pipeline,Stages,Program) ->
- cast(5776, <<Pipeline:?GLuint,Stages:?GLbitfield,Program:?GLuint>>).
+ cast(5777, <<Pipeline:?GLuint,Stages:?GLbitfield,Program:?GLuint>>).
%% @doc Set the active program object for a program pipeline object
%%
@@ -15620,15 +15720,16 @@ useProgramStages(Pipeline,Stages,Program) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glActiveShaderProgram.xml">external</a> documentation.
-spec activeShaderProgram(Pipeline, Program) -> 'ok' when Pipeline :: integer(),Program :: integer().
activeShaderProgram(Pipeline,Program) ->
- cast(5777, <<Pipeline:?GLuint,Program:?GLuint>>).
+ cast(5778, <<Pipeline:?GLuint,Program:?GLuint>>).
%% @doc glCreateShaderProgramv
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShaderProgramv.xml">external</a> documentation.
-spec createShaderProgramv(Type, Strings) -> integer() when Type :: enum(),Strings :: iolist().
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)>>).
+ StringsTemp = list_to_binary([[Str|[0]] || Str <- Strings ]),
+ StringsLen = length(Strings),
+ call(5779, <<Type:?GLenum,StringsLen:?GLuint,(size(StringsTemp)):?GLuint,(StringsTemp)/binary,0:((8-((size(StringsTemp)+0) rem 8)) rem 8)>>).
%% @doc Bind a program pipeline to the current context
%%
@@ -15650,7 +15751,7 @@ createShaderProgramv(Type,Strings) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindProgramPipeline.xml">external</a> documentation.
-spec bindProgramPipeline(Pipeline) -> 'ok' when Pipeline :: integer().
bindProgramPipeline(Pipeline) ->
- cast(5779, <<Pipeline:?GLuint>>).
+ cast(5780, <<Pipeline:?GLuint>>).
%% @doc Delete program pipeline objects
%%
@@ -15664,8 +15765,9 @@ bindProgramPipeline(Pipeline) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgramPipelines.xml">external</a> documentation.
-spec deleteProgramPipelines(Pipelines) -> 'ok' when Pipelines :: [integer()].
deleteProgramPipelines(Pipelines) ->
- cast(5780, <<(length(Pipelines)):?GLuint,
- (<< <<C:?GLuint>> || C <- Pipelines>>)/binary,0:(((1+length(Pipelines)) rem 2)*32)>>).
+ PipelinesLen = length(Pipelines),
+ cast(5781, <<PipelinesLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Pipelines>>)/binary,0:(((1+PipelinesLen) rem 2)*32)>>).
%% @doc Reserve program pipeline object names
%%
@@ -15676,7 +15778,7 @@ deleteProgramPipelines(Pipelines) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenProgramPipelines.xml">external</a> documentation.
-spec genProgramPipelines(N) -> [integer()] when N :: integer().
genProgramPipelines(N) ->
- call(5781, <<N:?GLsizei>>).
+ call(5782, <<N:?GLsizei>>).
%% @doc Determine if a name corresponds to a program pipeline object
%%
@@ -15691,7 +15793,7 @@ genProgramPipelines(N) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsProgramPipeline.xml">external</a> documentation.
-spec isProgramPipeline(Pipeline) -> 0|1 when Pipeline :: integer().
isProgramPipeline(Pipeline) ->
- call(5782, <<Pipeline:?GLuint>>).
+ call(5783, <<Pipeline:?GLuint>>).
%% @doc Retrieve properties of a program pipeline object
%%
@@ -15729,7 +15831,7 @@ isProgramPipeline(Pipeline) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramPipeline.xml">external</a> documentation.
-spec getProgramPipelineiv(Pipeline, Pname) -> integer() when Pipeline :: integer(),Pname :: enum().
getProgramPipelineiv(Pipeline,Pname) ->
- call(5783, <<Pipeline:?GLuint,Pname:?GLenum>>).
+ call(5784, <<Pipeline:?GLuint,Pname:?GLenum>>).
%% @doc Specify the value of a uniform variable for a specified program object
%%
@@ -15796,334 +15898,368 @@ getProgramPipelineiv(Pipeline,Pname) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation.
-spec programUniform1i(Program, Location, V0) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer().
programUniform1i(Program,Location,V0) ->
- cast(5784, <<Program:?GLuint,Location:?GLint,V0:?GLint>>).
+ cast(5785, <<Program:?GLuint,Location:?GLint,V0:?GLint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1iv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [integer()].
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)>>).
+ ValueLen = length(Value),
+ cast(5786, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLint>> || C <- Value>>)/binary,0:(((1+ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1f(Program, Location, V0) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float().
programUniform1f(Program,Location,V0) ->
- cast(5786, <<Program:?GLuint,Location:?GLint,V0:?GLfloat>>).
+ cast(5787, <<Program:?GLuint,Location:?GLint,V0:?GLfloat>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1fv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [float()].
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)>>).
+ ValueLen = length(Value),
+ cast(5788, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((1+ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1d(Program, Location, V0) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float().
programUniform1d(Program,Location,V0) ->
- cast(5788, <<Program:?GLuint,Location:?GLint,V0:?GLdouble>>).
+ cast(5789, <<Program:?GLuint,Location:?GLint,V0:?GLdouble>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1dv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [float()].
programUniform1dv(Program,Location,Value) ->
- cast(5789, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5790, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,0:32,
(<< <<C:?GLdouble>> || C <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1ui(Program, Location, V0) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer().
programUniform1ui(Program,Location,V0) ->
- cast(5790, <<Program:?GLuint,Location:?GLint,V0:?GLuint>>).
+ cast(5791, <<Program:?GLuint,Location:?GLint,V0:?GLuint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform1uiv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [integer()].
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)>>).
+ ValueLen = length(Value),
+ cast(5792, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((1+ValueLen) rem 2)*32)>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2i(Program, Location, V0, V1) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer().
programUniform2i(Program,Location,V0,V1) ->
- cast(5792, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint>>).
+ cast(5793, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2iv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer()}].
programUniform2iv(Program,Location,Value) ->
- cast(5793, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5794, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2f(Program, Location, V0, V1) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float().
programUniform2f(Program,Location,V0,V1) ->
- cast(5794, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
+ cast(5795, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2fv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float()}].
programUniform2fv(Program,Location,Value) ->
- cast(5795, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5796, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2d(Program, Location, V0, V1) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float().
programUniform2d(Program,Location,V0,V1) ->
- cast(5796, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble>>).
+ cast(5797, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2dv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float()}].
programUniform2dv(Program,Location,Value) ->
- cast(5797, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5798, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2ui(Program, Location, V0, V1) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer().
programUniform2ui(Program,Location,V0,V1) ->
- cast(5798, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint>>).
+ cast(5799, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform2uiv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer()}].
programUniform2uiv(Program,Location,Value) ->
- cast(5799, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5800, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint>> || {V1,V2} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3i(Program, Location, V0, V1, V2) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer().
programUniform3i(Program,Location,V0,V1,V2) ->
- cast(5800, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
+ cast(5801, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3iv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer(),integer()}].
programUniform3iv(Program,Location,Value) ->
- cast(5801, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5802, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3f(Program, Location, V0, V1, V2) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float().
programUniform3f(Program,Location,V0,V1,V2) ->
- cast(5802, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
+ cast(5803, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3fv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float(),float()}].
programUniform3fv(Program,Location,Value) ->
- cast(5803, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5804, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3d(Program, Location, V0, V1, V2) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float().
programUniform3d(Program,Location,V0,V1,V2) ->
- cast(5804, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble>>).
+ cast(5805, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3dv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float(),float()}].
programUniform3dv(Program,Location,Value) ->
- cast(5805, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5806, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3ui(Program, Location, V0, V1, V2) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer().
programUniform3ui(Program,Location,V0,V1,V2) ->
- cast(5806, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
+ cast(5807, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform3uiv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer(),integer()}].
programUniform3uiv(Program,Location,Value) ->
- cast(5807, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5808, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint>> || {V1,V2,V3} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4i(Program, Location, V0, V1, V2, V3) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer(),V3 :: integer().
programUniform4i(Program,Location,V0,V1,V2,V3) ->
- cast(5808, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
+ cast(5809, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4iv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer(),integer(),integer()}].
programUniform4iv(Program,Location,Value) ->
- cast(5809, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5810, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4f(Program, Location, V0, V1, V2, V3) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float(),V3 :: float().
programUniform4f(Program,Location,V0,V1,V2,V3) ->
- cast(5810, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
+ cast(5811, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4fv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float(),float(),float()}].
programUniform4fv(Program,Location,Value) ->
- cast(5811, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5812, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4d(Program, Location, V0, V1, V2, V3) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: float(),V1 :: float(),V2 :: float(),V3 :: float().
programUniform4d(Program,Location,V0,V1,V2,V3) ->
- cast(5812, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>>).
+ cast(5813, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4dv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{float(),float(),float(),float()}].
programUniform4dv(Program,Location,Value) ->
- cast(5813, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5814, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4ui(Program, Location, V0, V1, V2, V3) -> 'ok' when Program :: integer(),Location :: integer(),V0 :: integer(),V1 :: integer(),V2 :: integer(),V3 :: integer().
programUniform4ui(Program,Location,V0,V1,V2,V3) ->
- cast(5814, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
+ cast(5815, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniform4uiv(Program, Location, Value) -> 'ok' when Program :: integer(),Location :: integer(),Value :: [{integer(),integer(),integer(),integer()}].
programUniform4uiv(Program,Location,Value) ->
- cast(5815, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5816, <<Program:?GLuint,Location:?GLint,ValueLen:?GLuint,
(<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float()}].
programUniformMatrix2fv(Program,Location,Transpose,Value) ->
- cast(5816, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5817, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix3fv(Program,Location,Transpose,Value) ->
- cast(5817, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5818, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4fv(Program,Location,Transpose,Value) ->
- cast(5818, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5819, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float()}].
programUniformMatrix2dv(Program,Location,Transpose,Value) ->
- cast(5819, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5820, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix3dv(Program,Location,Transpose,Value) ->
- cast(5820, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5821, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4dv(Program,Location,Transpose,Value) ->
- cast(5821, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5822, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2x3fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
programUniformMatrix2x3fv(Program,Location,Transpose,Value) ->
- cast(5822, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5823, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3x2fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
programUniformMatrix3x2fv(Program,Location,Transpose,Value) ->
- cast(5823, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5824, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2x4fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix2x4fv(Program,Location,Transpose,Value) ->
- cast(5824, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5825, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4x2fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4x2fv(Program,Location,Transpose,Value) ->
- cast(5825, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5826, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3x4fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix3x4fv(Program,Location,Transpose,Value) ->
- cast(5826, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5827, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4x3fv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4x3fv(Program,Location,Transpose,Value) ->
- cast(5827, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,
+ ValueLen = length(Value),
+ cast(5828, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2x3dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
programUniformMatrix2x3dv(Program,Location,Transpose,Value) ->
- cast(5828, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5829, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3x2dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float()}].
programUniformMatrix3x2dv(Program,Location,Transpose,Value) ->
- cast(5829, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5830, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?GLuint,0:32,
(<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix2x4dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix2x4dv(Program,Location,Transpose,Value) ->
- cast(5830, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5831, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4x2dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4x2dv(Program,Location,Transpose,Value) ->
- cast(5831, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5832, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix3x4dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix3x4dv(Program,Location,Transpose,Value) ->
- cast(5832, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5833, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?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>>).
%% @doc
%% See {@link programUniform1i/3}
-spec programUniformMatrix4x3dv(Program, Location, Transpose, Value) -> 'ok' when Program :: integer(),Location :: integer(),Transpose :: 0|1,Value :: [{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}].
programUniformMatrix4x3dv(Program,Location,Transpose,Value) ->
- cast(5833, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32,
+ ValueLen = length(Value),
+ cast(5834, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,ValueLen:?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>>).
%% @doc Validate a program pipeline object against current GL state
@@ -16144,7 +16280,7 @@ programUniformMatrix4x3dv(Program,Location,Transpose,Value) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgramPipeline.xml">external</a> documentation.
-spec validateProgramPipeline(Pipeline) -> 'ok' when Pipeline :: integer().
validateProgramPipeline(Pipeline) ->
- cast(5834, <<Pipeline:?GLuint>>).
+ cast(5835, <<Pipeline:?GLuint>>).
%% @doc Retrieve the info log string from a program pipeline object
%%
@@ -16161,35 +16297,35 @@ validateProgramPipeline(Pipeline) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramPipelineInfoLog.xml">external</a> documentation.
-spec getProgramPipelineInfoLog(Pipeline, BufSize) -> string() when Pipeline :: integer(),BufSize :: integer().
getProgramPipelineInfoLog(Pipeline,BufSize) ->
- call(5835, <<Pipeline:?GLuint,BufSize:?GLsizei>>).
+ call(5836, <<Pipeline:?GLuint,BufSize:?GLsizei>>).
%% @doc glVertexAttribL
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
-spec vertexAttribL1d(Index, X) -> 'ok' when Index :: integer(),X :: float().
vertexAttribL1d(Index,X) ->
- cast(5836, <<Index:?GLuint,0:32,X:?GLdouble>>).
+ cast(5837, <<Index:?GLuint,0:32,X:?GLdouble>>).
%% @doc glVertexAttribL
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
-spec vertexAttribL2d(Index, X, Y) -> 'ok' when Index :: integer(),X :: float(),Y :: float().
vertexAttribL2d(Index,X,Y) ->
- cast(5837, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
+ cast(5838, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>).
%% @doc glVertexAttribL
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
-spec vertexAttribL3d(Index, X, Y, Z) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float().
vertexAttribL3d(Index,X,Y,Z) ->
- cast(5838, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
+ cast(5839, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>).
%% @doc glVertexAttribL
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation.
-spec vertexAttribL4d(Index, X, Y, Z, W) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),Z :: float(),W :: float().
vertexAttribL4d(Index,X,Y,Z,W) ->
- cast(5839, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
+ cast(5840, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>).
%% @equiv vertexAttribL1d(Index,X)
-spec vertexAttribL1dv(Index :: integer(),V) -> 'ok' when V :: {X :: float()}.
@@ -16212,24 +16348,25 @@ vertexAttribL4dv(Index,{X,Y,Z,W}) -> vertexAttribL4d(Index,X,Y,Z,W).
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribLPointer.xml">external</a> documentation.
-spec vertexAttribLPointer(Index, Size, Type, Stride, Pointer) -> 'ok' when Index :: integer(),Size :: integer(),Type :: enum(),Stride :: integer(),Pointer :: offset()|mem().
vertexAttribLPointer(Index,Size,Type,Stride,Pointer) when is_integer(Pointer) ->
- cast(5840, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>);
+ cast(5841, <<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>>).
+ cast(5842, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>).
%% @doc glGetVertexAttribL
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttribL.xml">external</a> documentation.
-spec getVertexAttribLdv(Index, Pname) -> {float(),float(),float(),float()} when Index :: integer(),Pname :: enum().
getVertexAttribLdv(Index,Pname) ->
- call(5842, <<Index:?GLuint,Pname:?GLenum>>).
+ call(5843, <<Index:?GLuint,Pname:?GLenum>>).
%% @doc glViewportArrayv
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewportArrayv.xml">external</a> documentation.
-spec viewportArrayv(First, V) -> 'ok' when First :: integer(),V :: [{float(),float(),float(),float()}].
viewportArrayv(First,V) ->
- cast(5843, <<First:?GLuint,(length(V)):?GLuint,
+ VLen = length(V),
+ cast(5844, <<First:?GLuint,VLen:?GLuint,
(<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- V>>)/binary>>).
%% @doc Set a specified viewport
@@ -16269,20 +16406,21 @@ viewportArrayv(First,V) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewportIndexed.xml">external</a> documentation.
-spec viewportIndexedf(Index, X, Y, W, H) -> 'ok' when Index :: integer(),X :: float(),Y :: float(),W :: float(),H :: float().
viewportIndexedf(Index,X,Y,W,H) ->
- cast(5844, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,W:?GLfloat,H:?GLfloat>>).
+ cast(5845, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,W:?GLfloat,H:?GLfloat>>).
%% @doc
%% See {@link viewportIndexedf/5}
-spec viewportIndexedfv(Index, V) -> 'ok' when Index :: integer(),V :: {float(),float(),float(),float()}.
viewportIndexedfv(Index,{V1,V2,V3,V4}) ->
- cast(5845, <<Index:?GLuint,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>>).
+ cast(5846, <<Index:?GLuint,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>>).
%% @doc glScissorArrayv
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorArrayv.xml">external</a> documentation.
-spec scissorArrayv(First, V) -> 'ok' when First :: integer(),V :: [{integer(),integer(),integer(),integer()}].
scissorArrayv(First,V) ->
- cast(5846, <<First:?GLuint,(length(V)):?GLuint,
+ VLen = length(V),
+ cast(5847, <<First:?GLuint,VLen:?GLuint,
(<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- V>>)/binary>>).
%% @doc glScissorIndexe
@@ -16290,21 +16428,22 @@ scissorArrayv(First,V) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorIndexe.xml">external</a> documentation.
-spec scissorIndexed(Index, Left, Bottom, Width, Height) -> 'ok' when Index :: integer(),Left :: integer(),Bottom :: integer(),Width :: integer(),Height :: integer().
scissorIndexed(Index,Left,Bottom,Width,Height) ->
- cast(5847, <<Index:?GLuint,Left:?GLint,Bottom:?GLint,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5848, <<Index:?GLuint,Left:?GLint,Bottom:?GLint,Width:?GLsizei,Height:?GLsizei>>).
%% @doc glScissorIndexe
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorIndexe.xml">external</a> documentation.
-spec scissorIndexedv(Index, V) -> 'ok' when Index :: integer(),V :: {integer(),integer(),integer(),integer()}.
scissorIndexedv(Index,{V1,V2,V3,V4}) ->
- cast(5848, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
+ cast(5849, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>).
%% @doc glDepthRangeArrayv
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRangeArrayv.xml">external</a> documentation.
-spec depthRangeArrayv(First, V) -> 'ok' when First :: integer(),V :: [{clamp(),clamp()}].
depthRangeArrayv(First,V) ->
- cast(5849, <<First:?GLuint,0:32,(length(V)):?GLuint,0:32,
+ VLen = length(V),
+ cast(5850, <<First:?GLuint,0:32,VLen:?GLuint,0:32,
(<< <<V1:?GLclampd,V2:?GLclampd>> || {V1,V2} <- V>>)/binary>>).
%% @doc glDepthRangeIndexe
@@ -16312,48 +16451,50 @@ depthRangeArrayv(First,V) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRangeIndexe.xml">external</a> documentation.
-spec depthRangeIndexed(Index, N, F) -> 'ok' when Index :: integer(),N :: clamp(),F :: clamp().
depthRangeIndexed(Index,N,F) ->
- cast(5850, <<Index:?GLuint,0:32,N:?GLclampd,F:?GLclampd>>).
+ cast(5851, <<Index:?GLuint,0:32,N:?GLclampd,F:?GLclampd>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getFloati_v(Target, Index) -> [float()] when Target :: enum(),Index :: integer().
getFloati_v(Target,Index) ->
- call(5851, <<Target:?GLenum,Index:?GLuint>>).
+ call(5852, <<Target:?GLenum,Index:?GLuint>>).
%% @doc
%% See {@link getBooleanv/1}
-spec getDoublei_v(Target, Index) -> [float()] when Target :: enum(),Index :: integer().
getDoublei_v(Target,Index) ->
- call(5852, <<Target:?GLenum,Index:?GLuint>>).
+ call(5853, <<Target:?GLenum,Index:?GLuint>>).
%% @doc glDebugMessageControlARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDebugMessageControlARB.xml">external</a> documentation.
-spec debugMessageControlARB(Source, Type, Severity, Ids, Enabled) -> 'ok' when Source :: enum(),Type :: enum(),Severity :: enum(),Ids :: [integer()],Enabled :: 0|1.
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>>).
+ IdsLen = length(Ids),
+ cast(5854, <<Source:?GLenum,Type:?GLenum,Severity:?GLenum,IdsLen:?GLuint,
+ (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((IdsLen) rem 2)*32),Enabled:?GLboolean>>).
%% @doc glDebugMessageInsertARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDebugMessageInsertARB.xml">external</a> documentation.
-spec debugMessageInsertARB(Source, Type, Id, Severity, Buf) -> 'ok' when Source :: enum(),Type :: enum(),Id :: integer(),Severity :: enum(),Buf :: string().
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)>>).
+ BufLen = length(Buf),
+ cast(5855, <<Source:?GLenum,Type:?GLenum,Id:?GLuint,Severity:?GLenum,(list_to_binary([Buf|[0]]))/binary,0:((8-((BufLen+ 1) rem 8)) rem 8)>>).
%% @doc glGetDebugMessageLogARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetDebugMessageLogARB.xml">external</a> documentation.
-spec getDebugMessageLogARB(Count, Bufsize) -> {integer(),Sources :: [enum()],Types :: [enum()],Ids :: [integer()],Severities :: [enum()],MessageLog :: [string()]} when Count :: integer(),Bufsize :: integer().
getDebugMessageLogARB(Count,Bufsize) ->
- call(5855, <<Count:?GLuint,Bufsize:?GLsizei>>).
+ call(5856, <<Count:?GLuint,Bufsize:?GLsizei>>).
%% @doc glGetGraphicsResetStatusARB
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetGraphicsResetStatusARB.xml">external</a> documentation.
-spec getGraphicsResetStatusARB() -> enum().
getGraphicsResetStatusARB() ->
- call(5856, <<>>).
+ call(5857, <<>>).
%% @doc Draw multiple instances of a range of elements with offset applied to instanced attributes
%%
@@ -16376,7 +16517,7 @@ getGraphicsResetStatusARB() ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArraysInstancedBaseInstance.xml">external</a> documentation.
-spec drawArraysInstancedBaseInstance(Mode, First, Count, Primcount, Baseinstance) -> 'ok' when Mode :: enum(),First :: integer(),Count :: integer(),Primcount :: integer(),Baseinstance :: integer().
drawArraysInstancedBaseInstance(Mode,First,Count,Primcount,Baseinstance) ->
- cast(5857, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei,Baseinstance:?GLuint>>).
+ cast(5858, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei,Baseinstance:?GLuint>>).
%% @doc Draw multiple instances of a set of elements with offset applied to instanced attributes
%%
@@ -16399,10 +16540,10 @@ drawArraysInstancedBaseInstance(Mode,First,Count,Primcount,Baseinstance) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstancedBaseInstance.xml">external</a> documentation.
-spec drawElementsInstancedBaseInstance(Mode, Count, Type, Indices, Primcount, Baseinstance) -> 'ok' when Mode :: enum(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Primcount :: integer(),Baseinstance :: integer().
drawElementsInstancedBaseInstance(Mode,Count,Type,Indices,Primcount,Baseinstance) when is_integer(Indices) ->
- cast(5858, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Baseinstance:?GLuint>>);
+ cast(5859, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Baseinstance:?GLuint>>);
drawElementsInstancedBaseInstance(Mode,Count,Type,Indices,Primcount,Baseinstance) ->
send_bin(Indices),
- cast(5859, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Baseinstance:?GLuint>>).
+ cast(5860, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Baseinstance:?GLuint>>).
%% @doc Render multiple instances of a set of primitives from array data with a per-element offset
%%
@@ -16423,31 +16564,31 @@ drawElementsInstancedBaseInstance(Mode,Count,Type,Indices,Primcount,Baseinstance
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstancedBaseVertexBaseInstance.xml">external</a> documentation.
-spec drawElementsInstancedBaseVertexBaseInstance(Mode, Count, Type, Indices, Primcount, Basevertex, Baseinstance) -> 'ok' when Mode :: enum(),Count :: integer(),Type :: enum(),Indices :: offset()|mem(),Primcount :: integer(),Basevertex :: integer(),Baseinstance :: integer().
drawElementsInstancedBaseVertexBaseInstance(Mode,Count,Type,Indices,Primcount,Basevertex,Baseinstance) when is_integer(Indices) ->
- cast(5860, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Basevertex:?GLint,Baseinstance:?GLuint>>);
+ cast(5861, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Basevertex:?GLint,Baseinstance:?GLuint>>);
drawElementsInstancedBaseVertexBaseInstance(Mode,Count,Type,Indices,Primcount,Basevertex,Baseinstance) ->
send_bin(Indices),
- cast(5861, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Basevertex:?GLint,Baseinstance:?GLuint>>).
+ cast(5862, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Basevertex:?GLint,Baseinstance:?GLuint>>).
%% @doc glDrawTransformFeedbackInstance
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedbackInstance.xml">external</a> documentation.
-spec drawTransformFeedbackInstanced(Mode, Id, Primcount) -> 'ok' when Mode :: enum(),Id :: integer(),Primcount :: integer().
drawTransformFeedbackInstanced(Mode,Id,Primcount) ->
- cast(5862, <<Mode:?GLenum,Id:?GLuint,Primcount:?GLsizei>>).
+ cast(5863, <<Mode:?GLenum,Id:?GLuint,Primcount:?GLsizei>>).
%% @doc glDrawTransformFeedbackStreamInstance
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedbackStreamInstance.xml">external</a> documentation.
-spec drawTransformFeedbackStreamInstanced(Mode, Id, Stream, Primcount) -> 'ok' when Mode :: enum(),Id :: integer(),Stream :: integer(),Primcount :: integer().
drawTransformFeedbackStreamInstanced(Mode,Id,Stream,Primcount) ->
- cast(5863, <<Mode:?GLenum,Id:?GLuint,Stream:?GLuint,Primcount:?GLsizei>>).
+ cast(5864, <<Mode:?GLenum,Id:?GLuint,Stream:?GLuint,Primcount:?GLsizei>>).
%% @doc glGetInternalformat
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetInternalformat.xml">external</a> documentation.
-spec getInternalformativ(Target, Internalformat, Pname, BufSize) -> [integer()] when Target :: enum(),Internalformat :: enum(),Pname :: enum(),BufSize :: integer().
getInternalformativ(Target,Internalformat,Pname,BufSize) ->
- call(5864, <<Target:?GLenum,Internalformat:?GLenum,Pname:?GLenum,BufSize:?GLsizei>>).
+ call(5865, <<Target:?GLenum,Internalformat:?GLenum,Pname:?GLenum,BufSize:?GLsizei>>).
%% @doc Bind a level of a texture to an image unit
%%
@@ -16509,7 +16650,7 @@ getInternalformativ(Target,Internalformat,Pname,BufSize) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindImageTexture.xml">external</a> documentation.
-spec bindImageTexture(Unit, Texture, Level, Layered, Layer, Access, Format) -> 'ok' when Unit :: integer(),Texture :: integer(),Level :: integer(),Layered :: 0|1,Layer :: integer(),Access :: enum(),Format :: enum().
bindImageTexture(Unit,Texture,Level,Layered,Layer,Access,Format) ->
- cast(5865, <<Unit:?GLuint,Texture:?GLuint,Level:?GLint,Layered:?GLboolean,0:24,Layer:?GLint,Access:?GLenum,Format:?GLenum>>).
+ cast(5866, <<Unit:?GLuint,Texture:?GLuint,Level:?GLint,Layered:?GLboolean,0:24,Layer:?GLint,Access:?GLenum,Format:?GLenum>>).
%% @doc Defines a barrier ordering memory transactions
%%
@@ -16636,7 +16777,7 @@ bindImageTexture(Unit,Texture,Level,Layered,Layer,Access,Format) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMemoryBarrier.xml">external</a> documentation.
-spec memoryBarrier(Barriers) -> 'ok' when Barriers :: integer().
memoryBarrier(Barriers) ->
- cast(5866, <<Barriers:?GLbitfield>>).
+ cast(5867, <<Barriers:?GLbitfield>>).
%% @doc Simultaneously specify storage for all levels of a one-dimensional texture
%%
@@ -16669,7 +16810,7 @@ memoryBarrier(Barriers) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexStorage1D.xml">external</a> documentation.
-spec texStorage1D(Target, Levels, Internalformat, Width) -> 'ok' when Target :: enum(),Levels :: integer(),Internalformat :: enum(),Width :: integer().
texStorage1D(Target,Levels,Internalformat,Width) ->
- cast(5867, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei>>).
+ cast(5868, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei>>).
%% @doc Simultaneously specify storage for all levels of a two-dimensional or one-dimensional array texture
%%
@@ -16714,7 +16855,7 @@ texStorage1D(Target,Levels,Internalformat,Width) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexStorage2D.xml">external</a> documentation.
-spec texStorage2D(Target, Levels, Internalformat, Width, Height) -> 'ok' when Target :: enum(),Levels :: integer(),Internalformat :: enum(),Width :: integer(),Height :: integer().
texStorage2D(Target,Levels,Internalformat,Width,Height) ->
- cast(5868, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
+ cast(5869, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>).
%% @doc Simultaneously specify storage for all levels of a three-dimensional, two-dimensional array or cube-map array texture
%%
@@ -16757,19 +16898,19 @@ texStorage2D(Target,Levels,Internalformat,Width,Height) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexStorage3D.xml">external</a> documentation.
-spec texStorage3D(Target, Levels, Internalformat, Width, Height, Depth) -> 'ok' when Target :: enum(),Levels :: integer(),Internalformat :: enum(),Width :: integer(),Height :: integer(),Depth :: integer().
texStorage3D(Target,Levels,Internalformat,Width,Height,Depth) ->
- cast(5869, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei>>).
+ cast(5870, <<Target:?GLenum,Levels:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei>>).
%% @doc glDepthBoundsEXT
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthBoundsEXT.xml">external</a> documentation.
-spec depthBoundsEXT(Zmin, Zmax) -> 'ok' when Zmin :: clamp(),Zmax :: clamp().
depthBoundsEXT(Zmin,Zmax) ->
- cast(5870, <<Zmin:?GLclampd,Zmax:?GLclampd>>).
+ cast(5871, <<Zmin:?GLclampd,Zmax:?GLclampd>>).
%% @doc glStencilClearTagEXT
%%
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilClearTagEXT.xml">external</a> documentation.
-spec stencilClearTagEXT(StencilTagBits, StencilClearTag) -> 'ok' when StencilTagBits :: integer(),StencilClearTag :: integer().
stencilClearTagEXT(StencilTagBits,StencilClearTag) ->
- cast(5871, <<StencilTagBits:?GLsizei,StencilClearTag:?GLuint>>).
+ cast(5872, <<StencilTagBits:?GLsizei,StencilClearTag:?GLuint>>).
diff --git a/lib/wx/src/gen/glu.erl b/lib/wx/src/gen/glu.erl
index 47d9a83999..f641f41262 100644
--- a/lib/wx/src/gen/glu.erl
+++ b/lib/wx/src/gen/glu.erl
@@ -334,7 +334,9 @@ build3DMipmaps(Target,InternalFormat,Width,Height,Depth,Format,Type,Data) ->
%% See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluCheckExtension.xml">external</a> documentation.
-spec checkExtension(ExtName, ExtString) -> 0|1 when ExtName :: string(),ExtString :: string().
checkExtension(ExtName,ExtString) ->
- 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)>>).
+ ExtNameLen = length(ExtName),
+ ExtStringLen = length(ExtString),
+ call(5016, <<(list_to_binary([ExtName|[0]]))/binary,0:((8-((ExtNameLen+ 1) rem 8)) rem 8),(list_to_binary([ExtString|[0]]))/binary,0:((8-((ExtStringLen+ 1) rem 8)) rem 8)>>).
%% @doc Draw a cylinder
%%
diff --git a/lib/xmerl/notes.html b/lib/xmerl/notes.html
deleted file mode 100644
index 43610a37fa..0000000000
--- a/lib/xmerl/notes.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<HTML>
-<HEAD>
- <TITLE>xmerl Release Notes</TITLE>
- <style type="text/css">
-<!--
- body { background: white; margin: 3em }
-
- body { font-family: Verdana, Arial, Helvetica, sans-serif }
- h1 h2 h3 h4 { font-family: Verdana, Arial, Helvetica, sans-serif }
- h1 { font-size: 48 }
- p li { font-family: Verdana, Arial, Helvetica, sans-serif }
--->
- </style>
-</HEAD>
-
-<BODY BGCOLOR="#FFFFFF">
-
-<CENTER><H1>xmerl Release Notes</H1></CENTER>
-
-<h2>xmerl 1.0</h2>
-
-
-<p>
-There are also release notes for
-<a href="notes_history.html">older versions</a>.
-
-</body>
-</html>
diff --git a/lib/xmerl/xmerl.pub b/lib/xmerl/xmerl.pub
deleted file mode 100644
index 29a81bbde2..0000000000
--- a/lib/xmerl/xmerl.pub
+++ /dev/null
@@ -1,19 +0,0 @@
-{name, "xmerl"}.
-{vsn, {0,18}}.
-{summary, "XML processing tools"}.
-{author, "Ulf Wiger, Johan Blom, Richard Carlsson, Mickael Remond", "[email protected]", "20020307"}.
-{keywords, ["xml", "html"]}.
-{needs, [{compiler, "3.0"}]}.
-{abstract,
- "Implements a set of tools for processing XML documents, as well as "
- "working with XML-like structures in Erlang. The main attraction so far "
- "is a single-pass, highly customizable XML processor. Other components are "
- "an export/translation facility and an XPATH query engine. "
- "This version fixes a few bugs in the scanner, and improves HTML export. "
- "The latest version can be found at http://sowap.sourceforge.net/ "
- "Note that this is still very much a beta product."}.
-
-
-
-
-
diff --git a/otp_versions.table b/otp_versions.table
index 1378f6afea..793f7bcd28 100644
--- a/otp_versions.table
+++ b/otp_versions.table
@@ -1,3 +1,4 @@
+OTP-19.1.6 : erts-8.1.1 # asn1-4.0.4 common_test-1.12.3 compiler-7.0.2 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.1 debugger-4.2.1 dialyzer-3.0.2 diameter-1.12.1 edoc-0.8 eldap-1.2.2 erl_docgen-0.6 erl_interface-3.9.1 et-1.6 eunit-2.3.1 gs-1.6.2 hipe-3.15.2 ic-4.4.2 inets-6.3.3 jinterface-1.7.1 kernel-5.1 megaco-3.18.1 mnesia-4.14.1 observer-2.2.2 odbc-2.11.3 orber-3.8.2 os_mon-2.4.1 otp_mibs-1.1.1 parsetools-2.1.3 percept-0.9 public_key-1.2 reltool-0.7.2 runtime_tools-1.10.1 sasl-3.0.1 snmp-5.2.4 ssh-4.3.6 ssl-8.0.3 stdlib-3.1 syntax_tools-2.1 tools-2.8.6 typer-0.9.11 wx-1.7.1 xmerl-1.3.12 :
OTP-19.1.5 : ssh-4.3.6 # asn1-4.0.4 common_test-1.12.3 compiler-7.0.2 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.1 debugger-4.2.1 dialyzer-3.0.2 diameter-1.12.1 edoc-0.8 eldap-1.2.2 erl_docgen-0.6 erl_interface-3.9.1 erts-8.1 et-1.6 eunit-2.3.1 gs-1.6.2 hipe-3.15.2 ic-4.4.2 inets-6.3.3 jinterface-1.7.1 kernel-5.1 megaco-3.18.1 mnesia-4.14.1 observer-2.2.2 odbc-2.11.3 orber-3.8.2 os_mon-2.4.1 otp_mibs-1.1.1 parsetools-2.1.3 percept-0.9 public_key-1.2 reltool-0.7.2 runtime_tools-1.10.1 sasl-3.0.1 snmp-5.2.4 ssl-8.0.3 stdlib-3.1 syntax_tools-2.1 tools-2.8.6 typer-0.9.11 wx-1.7.1 xmerl-1.3.12 :
OTP-19.1.4 : ssh-4.3.5 # asn1-4.0.4 common_test-1.12.3 compiler-7.0.2 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.1 debugger-4.2.1 dialyzer-3.0.2 diameter-1.12.1 edoc-0.8 eldap-1.2.2 erl_docgen-0.6 erl_interface-3.9.1 erts-8.1 et-1.6 eunit-2.3.1 gs-1.6.2 hipe-3.15.2 ic-4.4.2 inets-6.3.3 jinterface-1.7.1 kernel-5.1 megaco-3.18.1 mnesia-4.14.1 observer-2.2.2 odbc-2.11.3 orber-3.8.2 os_mon-2.4.1 otp_mibs-1.1.1 parsetools-2.1.3 percept-0.9 public_key-1.2 reltool-0.7.2 runtime_tools-1.10.1 sasl-3.0.1 snmp-5.2.4 ssl-8.0.3 stdlib-3.1 syntax_tools-2.1 tools-2.8.6 typer-0.9.11 wx-1.7.1 xmerl-1.3.12 :
OTP-19.1.3 : ssh-4.3.4 # asn1-4.0.4 common_test-1.12.3 compiler-7.0.2 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.1 cosTime-1.2.2 cosTransactions-1.3.2 crypto-3.7.1 debugger-4.2.1 dialyzer-3.0.2 diameter-1.12.1 edoc-0.8 eldap-1.2.2 erl_docgen-0.6 erl_interface-3.9.1 erts-8.1 et-1.6 eunit-2.3.1 gs-1.6.2 hipe-3.15.2 ic-4.4.2 inets-6.3.3 jinterface-1.7.1 kernel-5.1 megaco-3.18.1 mnesia-4.14.1 observer-2.2.2 odbc-2.11.3 orber-3.8.2 os_mon-2.4.1 otp_mibs-1.1.1 parsetools-2.1.3 percept-0.9 public_key-1.2 reltool-0.7.2 runtime_tools-1.10.1 sasl-3.0.1 snmp-5.2.4 ssl-8.0.3 stdlib-3.1 syntax_tools-2.1 tools-2.8.6 typer-0.9.11 wx-1.7.1 xmerl-1.3.12 :
diff --git a/system/COPYRIGHT b/system/COPYRIGHT
index ef76b66f6b..ed06dcf69c 100644
--- a/system/COPYRIGHT
+++ b/system/COPYRIGHT
@@ -22,6 +22,17 @@ limitations under the License.
%CopyrightEnd%
---------------------------------------------------------------------------
+[stdlib, compiler]
+
+* assert.hrl is Copyright (C) 2004-1016 Richard Carlsson, Mickaël Rémond
+* array.erl is Copyright (C) 2006-2016 Richard Carlsson and Ericsson AB
+* gb_trees.erl is Copyright (C) 1999-2001 Sven-Olof Nyström, Richard Carlsson
+* gb_sets.erl is Copyright (C) 1999-2001 Richard Carlsson, Sven-Olof Nyström
+* proplists.erl is Copyright (C) 2000-2003 Richard Carlsson
+* cerl{_trees,_clauses}.erl are Copyright (C) 1999-2002 Richard Carlsson
+* cerl_inline.erl is Copyright (C) 1999-2002 Richard Carlsson
+
+---------------------------------------------------------------------------
[PCRE]
PCRE LICENCE
@@ -190,32 +201,108 @@ terms specified in this license.
*/
---------------------------------------------------------------------------
+[dialyzer]
+
+%% Copyright 1997-2016 Tobias Lindahl, Stavros Aronis, Kostis Sagonas,
+%% Richard Carlsson, et al.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+---------------------------------------------------------------------------
+[typer]
+
+%% Copyright 2006-2016 Bingwen He, Tobias Lindahl, Kostis Sagonas
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+---------------------------------------------------------------------------
+[hipe]
+
+%% Copyright 1997-2016 Erik Stenman (Johansson), Kostis Sagonas,
+%% Richard Carlsson, Tobias Lindahl, Per Gustafsson, et al.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+---------------------------------------------------------------------------
[edoc, syntax_tools]
-%% =====================================================================
-%% This library is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU Lesser General Public License as
-%% published by the Free Software Foundation; either version 2 of the
-%% License, or (at your option) any later version.
+%% Copyright 1997-2016 Richard Carlsson <[email protected]>
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% This library is distributed in the hope that it will be useful, but
-%% WITHOUT ANY WARRANTY; without even the implied warranty of
-%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%% Lesser General Public License for more details.
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
+
+---------------------------------------------------------------------------
+[eunit]
+
+%% Copyright 2004-2016 Richard Carlsson <[email protected]>,
+%% Mickaël Rémond <[email protected]>
%%
-%% You should have received a copy of the GNU Lesser General Public
-%% License along with this library; if not, write to the Free Software
-%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-%% USA
+%% Licensed under the Apache License, Version 2.0 (the "License"); you may
+%% not use this file except in compliance with the License. You may obtain
+%% a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
%%
-%% $Id$
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
%%
-%% @copyright 2001-2003 Richard Carlsson
-%% @author Richard Carlsson <[email protected]>
-%% [http://www.csd.uu.se/~richardc/]
-%% @version {@vsn}
-%% @end
-%% =====================================================================
+%% Alternatively, you may use this file under the terms of the GNU Lesser
+%% General Public License (the "LGPL") as published by the Free Software
+%% Foundation; either version 2.1, or (at your option) any later version.
+%% If you wish to allow use of your version of this file only under the
+%% terms of the LGPL, you should delete the provisions above and replace
+%% them with the notice and other provisions required by the LGPL; see
+%% <http://www.gnu.org/licenses/>. If you do not delete the provisions
+%% above, a recipient may use your version of this file under the terms of
+%% either the Apache License or the LGPL.
---------------------------------------------------------------------------
[leex]
@@ -269,3 +356,4 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---------------------------------------------------------------------------
+[typer] \ No newline at end of file
diff --git a/system/doc/design_principles/applications.xml b/system/doc/design_principles/applications.xml
index 0a1b65ea8e..c673fde07e 100644
--- a/system/doc/design_principles/applications.xml
+++ b/system/doc/design_principles/applications.xml
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>Applications</title>
@@ -172,31 +172,136 @@ ch_app:stop([])</code>
</section>
<section>
- <marker id="app_dir"></marker>
- <title>Directory Structure</title>
- <p>When packaging code using <c>systools</c>, the code for each
- application is placed in a separate directory,
- <c>lib/Application-Vsn</c>, where <c>Vsn</c> is the version number.</p>
- <p>This can be useful to know, even if <c>systools</c> is not used,
- since Erlang/OTP is packaged according to the OTP principles
- and thus comes with this directory structure. The code server
- (see the <c>code(3)</c> manual page in Kernel) automatically
- uses code from
- the directory with the highest version number, if more than one
- version of an application is present.</p>
- <p>The application directory structure can also be used in the
- development environment. The version number can then
- be omitted from the name.</p>
- <p>The application directory has the following sub-directories:</p>
- <list type="bulleted">
- <item><c>src</c> - Contains the Erlang source code.</item>
- <item><c>ebin</c> - Contains the Erlang object code, the
- <c>beam</c> files. The <c>.app</c> file is also placed here.</item>
- <item><c>priv</c> - Used for application specific files. For
- example, C executables are placed here. The function
- <c>code:priv_dir/1</c> is to be used to access this directory.</item>
- <item><c>include</c> - Used for include files.</item>
- </list>
+ <marker id="app_dir"></marker>
+ <title>Directory Structure</title>
+ <p>When packaging code using <c>systools</c>, the code for each
+ application is placed in a separate directory,
+ <c>lib/Application-Vsn</c>, where <c>Vsn</c> is the version number.</p>
+ <p>This can be useful to know, even if <c>systools</c> is not used,
+ since Erlang/OTP is packaged according to the OTP principles
+ and thus comes with a specific directory structure. The code server
+ (see the <seealso marker="kernel:code"><c>code(3)</c></seealso> manual
+ page in Kernel) automatically uses code from
+ the directory with the highest version number, if more than one
+ version of an application is present.</p>
+ <section>
+ <title>Directory Structure guidelines for a Development Environment</title>
+ <p>Any directory structure for development will suffice as long as the released directory structure
+ adhere to the <seealso marker="#app_dir_released">description below</seealso>,
+ but it is encouraged that the same directory structure
+ also be used in a development environment. The version number should be omitted from the
+ application directory name since this is an artifact of the release step.
+ </p>
+ <p> Some sub-directories are <em>required</em>. Some sub-directories are <em>optional</em>, meaning that it should
+ only be used if the application itself requires it. Finally, some sub-directories are <em>recommended</em>,
+ meaning it is encouraged that it is used and used as described here. For example, both documentation
+ and tests are encouraged to exist in an application for it to be deemed a proper OTP application.</p>
+<code type="none">
+ ─ ${application}
+   ├── doc
+ │   ├── internal
+ │   ├── examples
+ │   └── src
+   ├── include
+   ├── priv
+   ├── src
+ │   └── ${application}.app.src
+   └── test
+</code>
+ <list type="bulleted">
+ <item><c>src</c> - Required. Contains the Erlang source code, the source of the <c>.app</c> file
+ and internal include files used by the application itself. Additional sub-directories within
+ <c>src</c> can be used as namespaces to organize source files. These directories should never
+ be deeper than one level.</item>
+ <item><c>priv</c> - Optional. Used for application specific files. </item>
+ <item><c>include</c> - Optional. Used for public include files that must be reachable from
+ other applications.</item>
+ <item><c>doc</c> - Recommended. Any source documentation should be placed in sub-directories here.</item>
+ <item><c>doc/internal</c> - Recommended. Any documentation that describes implementation details about
+ this application, not intended for publication, should be placed here.</item>
+ <item><c>doc/examples</c> - Recommended. Source code for examples on how to use this application should
+ be placed here. It is encouraged that examples are sourced to the public documentation from
+ this directory.</item>
+ <item><c>doc/src</c> - Recommended. All source files for documentation, such as Markdown, AsciiDoc or
+ XML-files, should be placed here.</item>
+ <item><c>test</c> - Recommended. All files regarding tests, such as test suites and test specifications,
+ should be placed here. </item>
+ </list>
+
+ <p>Other directories in the development environment may be needed. If source code from languages other
+ than Erlang is used, for instance C-code for NIFs, that code should be placed in a separate directory.
+ By convention it is recommended to prefix such directories with the language name, for example
+ <c>c_src</c> for C, <c>java_src</c> for Java or <c>go_src</c> for Go. Directories with <c>_src</c>
+ suffix indicates that it is a part of the application and the compilation step. The final build artifacts
+ should target the <c>priv/lib</c> or <c>priv/bin</c> directories.</p>
+ <p>The <c>priv</c> directory holds assets that the application needs during runtime. Executables should
+ reside in <c>priv/bin</c> and dynamically-linked libraries should reside in <c>priv/lib</c>. Other assets
+ are free to reside within the <c>priv</c> directory but it is recommended it does so in a structured manner.</p>
+ <p>Source files from other languages that generate Erlang code, such as ASN.1 or Mibs, should be placed
+ in directories, at the top level or in <c>src</c>, with the same name as the source language, for example
+ <c>asn1</c> and <c>mibs</c>. Build artifacts should be placed in their respective language directory,
+ such as <c>src</c> for Erlang code or <c>java_src</c> for Java code.</p>
+ <p>The <c>.app</c> file for release may reside in the <c>ebin</c>-directory in a development environment
+ but it is encouraged that this is an artifact of the build step. By convention a <c>.app.src</c> file
+ is used, which resides in the <c>src</c> directory. This file is nearly identical as the
+ <c>.app</c> file but certain fields may be replaced during the build step, such as the application version.</p>
+ <p>Directory names should not be capitalized.</p>
+ <p>It is encouraged to omit empty directories.</p>
+
+ </section>
+
+ <section>
+ <marker id="app_dir_released"></marker>
+ <title>Directory Structure for a Released System</title>
+ <p>A released application must follow a certain structure.
+ </p>
+<code type="none">
+ ─ ${application}-${version}
+   ├── bin
+   ├── doc
+ │   ├── html
+ │   ├── man[1-9]
+ │   ├── pdf
+ │   ├── internal
+ │   └── examples
+   ├── ebin
+ │   └── ${application}.app
+   ├── include
+   ├── priv
+ │   ├── lib
+ │   └── bin
+   └── src
+</code>
+ <list type="bulleted">
+ <item><c>src</c> - Optional. Contains the Erlang source code and internal include files
+ used by the application itself. This directory is no longer required in a released application.</item>
+ <item><c>ebin</c> - Required. Contains the Erlang object code, the <c>beam</c> files.
+ The <c>.app</c> file must also be placed here.</item>
+ <item><c>priv</c> - Optional. Used for application specific files. <c>code:priv_dir/1</c>
+ is to be used to access this directory.</item>
+ <item><c>priv/lib</c> - Recommended. Any shared-object files that are used by the application,
+ such as NIFs or linked-in-drivers, should be placed here.</item>
+ <item><c>priv/bin</c> - Recommended. Any executable that is used by the application,
+ such as port-programs, should be placed here.</item>
+ <item><c>include</c> - Optional. Used for public include files that must be reachable from
+ other applications.</item>
+ <item><c>bin</c> - Optional. Any executable that is a product of the application,
+ such as escripts or shell-scripts, should be placed here.</item>
+ <item><c>doc</c> - Optional. Any released documentation should be placed in
+ sub-directories here.</item>
+ <item><c>doc/man1</c> - Recommended. Man pages for Application executables.</item>
+ <item><c>doc/man3</c> - Recommended. Man pages for module APIs.</item>
+ <item><c>doc/man6</c> - Recommended. Man pages for Application overview.</item>
+ <item><c>doc/html</c> - Optional. HTML pages for the entire Application.</item>
+ <item><c>doc/pdf</c> - Optional. PDF documentation for the entire Application.</item>
+ </list>
+
+ <p>The <c>src</c> directory could be useful to release for debugging purposes but is not required.
+ The <c>include</c> directory should only be released if the applications has public include files.</p>
+ <p>The only documentation that is recommended to be released in this way are the man pages. HTML and PDF
+ will normally be distributed in some other manner.</p>
+ <p>It is encouraged to omit empty directories.</p>
+ </section>
</section>
<section>
@@ -381,4 +486,3 @@ application:start(Application, Type)</code>
<c>shutdown</c>, not <c>normal</c>.</p>
</section>
</chapter>
-
diff --git a/system/doc/design_principles/statem.xml b/system/doc/design_principles/statem.xml
index bece95e6b8..f627145f9f 100644
--- a/system/doc/design_principles/statem.xml
+++ b/system/doc/design_principles/statem.xml
@@ -1015,17 +1015,24 @@ open(cast, {button,_}, Data) ->
...
]]></code>
<p>
- The fact that a postponed event is only retried after a state change
- translates into a requirement on the event and state space.
- If you have a choice between storing a state data item
- in the <c>State</c> or in the <c>Data</c>:
- if a change in the item value affects which events that
- are handled, then this item is to be part of the state.
- </p>
- <p>
- You want to avoid that you maybe much later decide
- to postpone an event in one state and by misfortune it is never retried,
- as the code only changes the <c>Data</c> but not the <c>State</c>.
+ Since a postponed event is only retried after a state change,
+ you have to think about where to keep a state data item.
+ You can keep it in the server <c>Data</c>
+ or in the <c>State</c> itself,
+ for example by having two more or less identical states
+ to keep a boolean value, or by using a complex state with
+ <seealso marker="#Callback Modes">callback mode</seealso>
+ <seealso marker="stdlib:gen_statem#type-callback_mode"><c>handle_event_function</c></seealso>.
+ If a change in the value changes the set of events that is handled,
+ then the value should be kept in the State.
+ Otherwise no postponed events will be retried
+ since only the server Data changes.
+ </p>
+ <p>
+ This is not important if you do not postpone events.
+ But if you later decide to start postponing some events,
+ then the design flaw of not having separate states
+ when they should be, might become a hard to find bug.
</p>
<section>
diff --git a/system/doc/design_principles/sup_princ.xml b/system/doc/design_principles/sup_princ.xml
index 0a24e97950..c24177d842 100644
--- a/system/doc/design_principles/sup_princ.xml
+++ b/system/doc/design_principles/sup_princ.xml
@@ -163,7 +163,9 @@ SupFlags = #{strategy => Strategy, ...}</code>
SupFlags = #{intensity => MaxR, period => MaxT, ...}</code>
<p>If more than <c>MaxR</c> number of restarts occur in the last
<c>MaxT</c> seconds, the supervisor terminates all the child
- processes and then itself.</p>
+ processes and then itself.
+ The termination reason for the supervisor itself in that case will be
+ <c>shutdown</c>.</p>
<p>When the supervisor terminates, then the next higher-level
supervisor takes some action. It either restarts the terminated
supervisor or terminates itself.</p>